Icard/angular-clarity-master(work.../node_modules/ngx-captcha/fesm2020/ngx-captcha.mjs

713 lines
28 KiB
JavaScript
Raw Permalink Normal View History

2024-07-16 14:55:36 +00:00
import * as i0 from '@angular/core';
import { Injectable, EventEmitter, InjectFlags, Directive, Input, Output, forwardRef, Component, ViewChild, NgModule } from '@angular/core';
import { NgControl, NG_VALUE_ACCESSOR } from '@angular/forms';
import { CommonModule } from '@angular/common';
class ScriptService {
constructor(zone) {
this.zone = zone;
this.scriptElemId = "ngx-catpcha-script";
/**
* Name of the global google recaptcha script
*/
this.windowGrecaptcha = "grecaptcha";
/**
* Name of enterpise property in the global google recaptcha script
*/
this.windowGrecaptchaEnterprise = "enterprise";
/**
* Name of the global callback
*/
this.windowOnLoadCallbackProperty = "ngx_captcha_onload_callback";
/**
* Name of the global callback for enterprise
*/
this.windowOnLoadEnterpriseCallbackProperty = "ngx_captcha_onload_enterprise_callback";
this.globalDomain = "recaptcha.net";
this.defaultDomain = "google.com";
this.enterpriseApi = "enterprise.js";
this.defaultApi = "api.js";
}
registerCaptchaScript(config, render, onLoad, language) {
if (this.grecaptchaScriptLoaded(config.useEnterprise)) {
// recaptcha script is already loaded
// just call the callback
if (config.useEnterprise) {
this.zone.run(() => {
onLoad(window[this.windowGrecaptcha][this.windowGrecaptchaEnterprise]);
});
}
else {
this.zone.run(() => {
onLoad(window[this.windowGrecaptcha]);
});
}
return;
}
// we need to patch the callback through global variable, otherwise callback is not accessible
// note: https://github.com/Enngage/ngx-captcha/issues/2
if (config.useEnterprise) {
window[this.getCallbackName(true)] = ((() => this.zone.run(onLoad.bind(this, window[this.windowGrecaptcha][this.windowGrecaptchaEnterprise]))));
}
else {
window[this.getCallbackName(false)] = ((() => this.zone.run(onLoad.bind(this, window[this.windowGrecaptcha]))));
}
// prepare script elem
const scriptElem = document.createElement("script");
scriptElem.id = this.scriptElemId;
scriptElem.innerHTML = "";
scriptElem.src = this.getCaptchaScriptUrl(config, render, language);
scriptElem.async = true;
scriptElem.defer = true;
// add script to header
document.getElementsByTagName("head")[0].appendChild(scriptElem);
}
cleanup() {
const elem = document.getElementById(this.scriptElemId);
if (elem) {
elem.remove();
}
window[this.getCallbackName()] = undefined;
window[this.windowGrecaptcha] = undefined;
}
/**
* Indicates if google recaptcha script is available and ready to be used
*/
grecaptchaScriptLoaded(useEnterprise) {
if (!window[this.getCallbackName(useEnterprise)] ||
!window[this.windowGrecaptcha]) {
return false;
}
else if (useEnterprise &&
window[this.windowGrecaptcha][this.windowGrecaptchaEnterprise]) {
return true;
// if only enterprise script is loaded we need to check some v3's method
}
else if (window[this.windowGrecaptcha].execute) {
return true;
}
return false;
}
/**
* Gets global callback name
* @param useEnterprise Optional flag for enterprise script
* @private
*/
getCallbackName(useEnterprise) {
return useEnterprise
? this.windowOnLoadEnterpriseCallbackProperty
: this.windowOnLoadCallbackProperty;
}
/**
* Gets language param used in script url
*/
getLanguageParam(hl) {
if (!hl) {
return "";
}
return `&hl=${hl}`;
}
/**
* Url to google api script
*/
getCaptchaScriptUrl(config, render, language) {
const domain = config.useGlobalDomain
? this.globalDomain
: this.defaultDomain;
const api = config.useEnterprise ? this.enterpriseApi : this.defaultApi;
const callback = this.getCallbackName(config.useEnterprise);
return `https://www.${domain}/recaptcha/${api}?onload=${callback}&render=${render}${this.getLanguageParam(language)}`;
}
}
/** @nocollapse */ ScriptService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ScriptService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
/** @nocollapse */ ScriptService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ScriptService, providedIn: "root" });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ScriptService, decorators: [{
type: Injectable,
args: [{
providedIn: "root",
}]
}], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
class BaseReCaptchaComponentDirective {
constructor(renderer, zone, injector, scriptService) {
this.renderer = renderer;
this.zone = zone;
this.injector = injector;
this.scriptService = scriptService;
/**
* Prefix of the captcha element
*/
this.captchaElemPrefix = "ngx_captcha_id_";
this.setupCaptcha = true;
/**
* Indicates if global domain 'recaptcha.net' should be used instead of default domain ('google.com')
*/
this.useGlobalDomain = false;
this.useEnterprise = false;
/**
* Type
*/
this.type = "image";
/**
* Tab index
*/
this.tabIndex = 0;
/**
* Called when captcha receives successful response.
* Captcha response token is passed to event.
*/
this.success = new EventEmitter();
/**
* Called when captcha is loaded. Event receives id of the captcha
*/
this.load = new EventEmitter();
/**
* Called when captcha is reset.
*/
this.reset = new EventEmitter();
/**
* Called when captcha is loaded & ready. I.e. when you need to execute captcha on component load.
*/
this.ready = new EventEmitter();
/**
* Error callback
*/
this.error = new EventEmitter();
/**
* Expired callback
*/
this.expire = new EventEmitter();
/**
* Indicates if captcha should be set on load
*/
this.setupAfterLoad = false;
/**
* If enabled, captcha will reset after receiving success response. This is useful
* when invisible captcha need to be resolved multiple times on same page
*/
this.resetCaptchaAfterSuccess = false;
/**
* Required by ControlValueAccessor
*/
this.onChange = (val) => { };
this.onTouched = (val) => { };
/**
* Indicates if captcha is loaded
*/
this.isLoaded = false;
}
ngAfterViewInit() {
this.control = this.injector.get(NgControl, undefined, InjectFlags.Optional)?.control;
}
ngAfterViewChecked() {
if (this.setupCaptcha) {
this.setupCaptcha = false;
this.setupComponent();
}
}
ngOnChanges(changes) {
// cleanup scripts if language changed because they need to be reloaded
if (changes && changes.hl) {
// cleanup scripts when language changes
if (!changes.hl.firstChange &&
changes.hl.currentValue !== changes.hl.previousValue) {
this.scriptService.cleanup();
}
}
if (changes && changes.useGlobalDomain) {
// cleanup scripts when domain changes
if (!changes.useGlobalDomain.firstChange &&
changes.useGlobalDomain.currentValue !==
changes.useGlobalDomain.previousValue) {
this.scriptService.cleanup();
}
}
this.setupCaptcha = true;
}
/**
* Gets captcha response as per reCaptcha docs
*/
getResponse() {
return this.reCaptchaApi.getResponse(this.captchaId);
}
/**
* Gets Id of captcha widget
*/
getCaptchaId() {
return this.captchaId;
}
/**
* Resets captcha
*/
resetCaptcha() {
this.zone.run(() => {
// reset captcha using Google js api
this.reCaptchaApi.reset();
// required due to forms
this.onChange(undefined);
this.onTouched(undefined);
// trigger reset event
this.reset.next();
});
}
/**
* Gets last submitted captcha response
*/
getCurrentResponse() {
return this.currentResponse;
}
/**
* Reload captcha. Useful when properties (i.e. theme) changed and captcha need to reflect them
*/
reloadCaptcha() {
this.setupComponent();
}
ensureCaptchaElem(captchaElemId) {
const captchaElem = document.getElementById(captchaElemId);
if (!captchaElem) {
throw Error(`Captcha element with id '${captchaElemId}' was not found`);
}
// assign captcha alem
this.captchaElem = captchaElem;
}
/**
* Responsible for instantiating captcha element
*/
renderReCaptcha() {
// run outside angular zone due to timeout issues when testing
// details: https://github.com/Enngage/ngx-captcha/issues/26
this.zone.runOutsideAngular(() => {
// to fix reCAPTCHA placeholder element must be an element or id
// https://github.com/Enngage/ngx-captcha/issues/96
setTimeout(() => {
this.captchaId = this.reCaptchaApi.render(this.captchaElemId, this.getCaptchaProperties());
this.ready.next();
}, 0);
});
}
/**
* Called when captcha receives response
* @param callback Callback
*/
handleCallback(callback) {
this.currentResponse = callback;
this.success.next(callback);
this.zone.run(() => {
this.onChange(callback);
this.onTouched(callback);
});
if (this.resetCaptchaAfterSuccess) {
this.resetCaptcha();
}
}
getPseudoUniqueNumber() {
return new Date().getUTCMilliseconds() + Math.floor(Math.random() * 9999);
}
setupComponent() {
// captcha specific setup
this.captchaSpecificSetup();
// create captcha wrapper
this.createAndSetCaptchaElem();
this.scriptService.registerCaptchaScript({
useGlobalDomain: this.useGlobalDomain,
useEnterprise: this.useEnterprise,
}, "explicit", (grecaptcha) => {
this.onloadCallback(grecaptcha);
}, this.hl);
}
/**
* Called when google's recaptcha script is ready
*/
onloadCallback(grecapcha) {
// assign reference to reCaptcha Api once its loaded
this.reCaptchaApi = grecapcha;
if (!this.reCaptchaApi) {
throw Error(`ReCaptcha Api was not initialized correctly`);
}
// loaded flag
this.isLoaded = true;
// fire load event
this.load.next();
// render captcha
this.renderReCaptcha();
// setup component if it was flagged as such
if (this.setupAfterLoad) {
this.setupAfterLoad = false;
this.setupComponent();
}
}
generateNewElemId() {
return this.captchaElemPrefix + this.getPseudoUniqueNumber();
}
createAndSetCaptchaElem() {
// generate new captcha id
this.captchaElemId = this.generateNewElemId();
if (!this.captchaElemId) {
throw Error(`Captcha elem Id is not set`);
}
if (!this.captchaWrapperElem) {
throw Error(`Captcha DOM element is not initialized`);
}
// remove old html
this.captchaWrapperElem.nativeElement.innerHTML = "";
// create new wrapper for captcha
const newElem = this.renderer.createElement("div");
newElem.id = this.captchaElemId;
this.renderer.appendChild(this.captchaWrapperElem.nativeElement, newElem);
// when use captcha in cdk stepper then throwing error Captcha element with id 'ngx_captcha_id_XXXX' not found
// to fix it checking ensureCaptchaElem in timeout so that its check in next call and its able to find element
setTimeout(() => {
// update captcha elem
if (this.captchaElemId) {
this.ensureCaptchaElem(this.captchaElemId);
}
}, 0);
}
/**
* To be aligned with the ControlValueAccessor interface we need to implement this method
* However as we don't want to update the recaptcha, this doesn't need to be implemented
*/
writeValue(obj) { }
/**
* This method helps us tie together recaptcha and our formControl values
*/
registerOnChange(fn) {
this.onChange = fn;
}
/**
* At some point we might be interested whether the user has touched our component
*/
registerOnTouched(fn) {
this.onTouched = fn;
}
/**
* Handles error callback
*/
handleErrorCallback() {
this.zone.run(() => {
this.onChange(undefined);
this.onTouched(undefined);
});
this.error.next();
}
/**
* Handles expired callback
*/
handleExpireCallback() {
this.expire.next();
// reset captcha on expire callback
this.resetCaptcha();
}
}
/** @nocollapse */ BaseReCaptchaComponentDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: BaseReCaptchaComponentDirective, deps: [{ token: i0.Renderer2 }, { token: i0.NgZone }, { token: i0.Injector }, { token: ScriptService }], target: i0.ɵɵFactoryTarget.Directive });
/** @nocollapse */ BaseReCaptchaComponentDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.4", type: BaseReCaptchaComponentDirective, inputs: { siteKey: "siteKey", useGlobalDomain: "useGlobalDomain", useEnterprise: "useEnterprise", type: "type", hl: "hl", tabIndex: "tabIndex" }, outputs: { success: "success", load: "load", reset: "reset", ready: "ready", error: "error", expire: "expire" }, usesOnChanges: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: BaseReCaptchaComponentDirective, decorators: [{
type: Directive
}], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.NgZone }, { type: i0.Injector }, { type: ScriptService }]; }, propDecorators: { siteKey: [{
type: Input
}], useGlobalDomain: [{
type: Input
}], useEnterprise: [{
type: Input
}], type: [{
type: Input
}], hl: [{
type: Input
}], tabIndex: [{
type: Input
}], success: [{
type: Output
}], load: [{
type: Output
}], reset: [{
type: Output
}], ready: [{
type: Output
}], error: [{
type: Output
}], expire: [{
type: Output
}] } });
var ReCaptchaType;
(function (ReCaptchaType) {
ReCaptchaType[ReCaptchaType["InvisibleReCaptcha"] = 0] = "InvisibleReCaptcha";
ReCaptchaType[ReCaptchaType["ReCaptcha2"] = 1] = "ReCaptcha2";
})(ReCaptchaType || (ReCaptchaType = {}));
class InvisibleReCaptchaComponent extends BaseReCaptchaComponentDirective {
constructor(renderer, zone, injector, scriptService) {
super(renderer, zone, injector, scriptService);
this.renderer = renderer;
this.zone = zone;
this.injector = injector;
this.scriptService = scriptService;
/**
* This size representing invisible captcha
*/
this.size = 'invisible';
/**
* Theme
*/
this.theme = 'light';
/**
* Badge
*/
this.badge = 'bottomright';
this.recaptchaType = ReCaptchaType.InvisibleReCaptcha;
}
ngOnChanges(changes) {
super.ngOnChanges(changes);
}
/**
* Programatically invoke the reCAPTCHA check. Used if the invisible reCAPTCHA is on a div instead of a button.
*/
execute() {
// execute captcha
this.zone.runOutsideAngular(() => this.reCaptchaApi.execute(this.captchaId));
}
captchaSpecificSetup() {
}
/**
* Gets reCaptcha properties
*/
getCaptchaProperties() {
return {
'sitekey': this.siteKey,
'callback': (response) => this.zone.run(() => this.handleCallback(response)),
'expired-callback': () => this.zone.run(() => this.handleExpireCallback()),
'error-callback': () => this.zone.run(() => this.handleErrorCallback()),
'badge': this.badge,
'type': this.type,
'tabindex': this.tabIndex,
'size': this.size,
'theme': this.theme
};
}
}
/** @nocollapse */ InvisibleReCaptchaComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: InvisibleReCaptchaComponent, deps: [{ token: i0.Renderer2 }, { token: i0.NgZone }, { token: i0.Injector }, { token: ScriptService }], target: i0.ɵɵFactoryTarget.Component });
/** @nocollapse */ InvisibleReCaptchaComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: InvisibleReCaptchaComponent, selector: "ngx-invisible-recaptcha", inputs: { theme: "theme", badge: "badge" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef((() => InvisibleReCaptchaComponent)),
multi: true,
}
], viewQueries: [{ propertyName: "captchaWrapperElem", first: true, predicate: ["captchaWrapperElem"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `
<div #captchaWrapperElem></div>`, isInline: true });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: InvisibleReCaptchaComponent, decorators: [{
type: Component,
args: [{
selector: 'ngx-invisible-recaptcha',
template: `
<div #captchaWrapperElem></div>`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef((() => InvisibleReCaptchaComponent)),
multi: true,
}
]
}]
}], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.NgZone }, { type: i0.Injector }, { type: ScriptService }]; }, propDecorators: { theme: [{
type: Input
}], badge: [{
type: Input
}], captchaWrapperElem: [{
type: ViewChild,
args: ['captchaWrapperElem', { static: false }]
}] } });
class ReCaptcha2Component extends BaseReCaptchaComponentDirective {
constructor(renderer, zone, injector, scriptService) {
super(renderer, zone, injector, scriptService);
this.renderer = renderer;
this.zone = zone;
this.injector = injector;
this.scriptService = scriptService;
/**
* Name of the global expire callback
*/
this.windowOnErrorCallbackProperty = 'ngx_captcha_error_callback';
/**
* Name of the global error callback
*/
this.windowOnExpireCallbackProperty = 'ngx_captcha_expire_callback';
/**
* Theme
*/
this.theme = 'light';
/**
* Size
*/
this.size = 'normal';
this.recaptchaType = ReCaptchaType.ReCaptcha2;
}
ngOnChanges(changes) {
super.ngOnChanges(changes);
}
ngOnDestroy() {
window[this.windowOnErrorCallbackProperty] = {};
window[this.windowOnExpireCallbackProperty] = {};
}
captchaSpecificSetup() {
this.registerCallbacks();
}
/**
* Gets reCaptcha properties
*/
getCaptchaProperties() {
return {
'sitekey': this.siteKey,
'callback': (response) => this.zone.run(() => this.handleCallback(response)),
'expired-callback': () => this.zone.run(() => this.handleExpireCallback()),
'error-callback': () => this.zone.run(() => this.handleErrorCallback()),
'theme': this.theme,
'type': this.type,
'size': this.size,
'tabindex': this.tabIndex
};
}
/**
* Registers global callbacks
*/
registerCallbacks() {
window[this.windowOnErrorCallbackProperty] = super.handleErrorCallback.bind(this);
window[this.windowOnExpireCallbackProperty] = super.handleExpireCallback.bind(this);
}
}
/** @nocollapse */ ReCaptcha2Component.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ReCaptcha2Component, deps: [{ token: i0.Renderer2 }, { token: i0.NgZone }, { token: i0.Injector }, { token: ScriptService }], target: i0.ɵɵFactoryTarget.Component });
/** @nocollapse */ ReCaptcha2Component.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: ReCaptcha2Component, selector: "ngx-recaptcha2", inputs: { theme: "theme", size: "size" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef((() => ReCaptcha2Component)),
multi: true,
}
], viewQueries: [{ propertyName: "captchaWrapperElem", first: true, predicate: ["captchaWrapperElem"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `
<div #captchaWrapperElem></div>`, isInline: true });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ReCaptcha2Component, decorators: [{
type: Component,
args: [{
selector: 'ngx-recaptcha2',
template: `
<div #captchaWrapperElem></div>`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef((() => ReCaptcha2Component)),
multi: true,
}
]
}]
}], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.NgZone }, { type: i0.Injector }, { type: ScriptService }]; }, propDecorators: { theme: [{
type: Input
}], size: [{
type: Input
}], captchaWrapperElem: [{
type: ViewChild,
args: ['captchaWrapperElem', { static: false }]
}] } });
class ReCaptchaV3Service {
constructor(scriptService, zone) {
this.scriptService = scriptService;
this.zone = zone;
}
/**
* Executes reCaptcha v3/Enterprise with given action and passes token via callback. You need to verify
* this callback in your backend to get meaningful results.
*
* For more information see https://developers.google.com/recaptcha/docs/v3
* For enterprise see https://cloud.google.com/recaptcha-enterprise/docs
*
* @param siteKey Site key found in your google admin panel
* @param action Action to log
* @param callback Callback function to to handle token
* @param config Optional configuration like useGlobalDomain to be provided
* @param errorCallback Optional Callback function to handle errors
*/
execute(siteKey, action, callback, config, errorCallback) {
this.executeAsPromise(siteKey, action, config)
.then(callback)
.catch((error) => errorCallback ? errorCallback(error) : console.error(error));
}
/**
* Executes reCaptcha v3/Enterprise with given action and returns token via Promise. You need to verify
* this token in your backend to get meaningful results.
*
* For more information see https://developers.google.com/recaptcha/docs/v3
* For enterprise see https://cloud.google.com/recaptcha-enterprise/docs
*
* @param siteKey Site key found in your google admin panel
* @param action Action to log
* @param config Optional configuration like useGlobalDomain to be provided
*/
executeAsPromise(siteKey, action, config) {
return new Promise((resolve, reject) => {
const configuration = config || {};
const onRegister = (grecaptcha) => {
this.zone.runOutsideAngular(() => {
try {
grecaptcha
.execute(siteKey, { action })
.then((token) => this.zone.run(() => resolve(token)));
}
catch (error) {
reject(error);
}
});
};
this.scriptService.registerCaptchaScript(configuration, siteKey, onRegister);
});
}
}
/** @nocollapse */ ReCaptchaV3Service.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ReCaptchaV3Service, deps: [{ token: ScriptService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
/** @nocollapse */ ReCaptchaV3Service.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ReCaptchaV3Service, providedIn: "root" });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ReCaptchaV3Service, decorators: [{
type: Injectable,
args: [{
providedIn: "root",
}]
}], ctorParameters: function () { return [{ type: ScriptService }, { type: i0.NgZone }]; } });
class NgxCaptchaModule {
}
/** @nocollapse */ NgxCaptchaModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: NgxCaptchaModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
/** @nocollapse */ NgxCaptchaModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.0.4", ngImport: i0, type: NgxCaptchaModule, declarations: [ReCaptcha2Component,
InvisibleReCaptchaComponent], imports: [CommonModule], exports: [ReCaptcha2Component,
InvisibleReCaptchaComponent] });
/** @nocollapse */ NgxCaptchaModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: NgxCaptchaModule, providers: [
ScriptService,
ReCaptchaV3Service
], imports: [CommonModule] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: NgxCaptchaModule, decorators: [{
type: NgModule,
args: [{
imports: [
CommonModule
],
declarations: [
ReCaptcha2Component,
InvisibleReCaptchaComponent
],
providers: [
ScriptService,
ReCaptchaV3Service
],
exports: [
ReCaptcha2Component,
InvisibleReCaptchaComponent
]
}]
}] });
/*
* Public API
*/
/**
* Generated bundle index. Do not edit.
*/
export { BaseReCaptchaComponentDirective, InvisibleReCaptchaComponent, NgxCaptchaModule, ReCaptcha2Component, ReCaptchaType, ReCaptchaV3Service, ScriptService };
//# sourceMappingURL=ngx-captcha.mjs.map