UNPKG

@rudderstack/analytics-js

Version:
598 lines (554 loc) 408 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.rudderanalytics = {})); })(this, (function (exports) { 'use strict'; function _isPlaceholder(a){return a!=null&&typeof a==='object'&&a['@@functional/placeholder']===true;} /** * Optimized internal one-arity curry function. * * @private * @category Function * @param {Function} fn The function to curry. * @return {Function} The curried function. */function _curry1(fn){return function f1(a){if(arguments.length===0||_isPlaceholder(a)){return f1;}else {return fn.apply(this,arguments);}};} /** * Optimized internal two-arity curry function. * * @private * @category Function * @param {Function} fn The function to curry. * @return {Function} The curried function. */function _curry2(fn){return function f2(a,b){switch(arguments.length){case 0:return f2;case 1:return _isPlaceholder(a)?f2:_curry1(function(_b){return fn(a,_b);});default:return _isPlaceholder(a)&&_isPlaceholder(b)?f2:_isPlaceholder(a)?_curry1(function(_a){return fn(_a,b);}):_isPlaceholder(b)?_curry1(function(_b){return fn(a,_b);}):fn(a,b);}};} /** * Optimized internal three-arity curry function. * * @private * @category Function * @param {Function} fn The function to curry. * @return {Function} The curried function. */function _curry3(fn){return function f3(a,b,c){switch(arguments.length){case 0:return f3;case 1:return _isPlaceholder(a)?f3:_curry2(function(_b,_c){return fn(a,_b,_c);});case 2:return _isPlaceholder(a)&&_isPlaceholder(b)?f3:_isPlaceholder(a)?_curry2(function(_a,_c){return fn(_a,b,_c);}):_isPlaceholder(b)?_curry2(function(_b,_c){return fn(a,_b,_c);}):_curry1(function(_c){return fn(a,b,_c);});default:return _isPlaceholder(a)&&_isPlaceholder(b)&&_isPlaceholder(c)?f3:_isPlaceholder(a)&&_isPlaceholder(b)?_curry2(function(_a,_b){return fn(_a,_b,c);}):_isPlaceholder(a)&&_isPlaceholder(c)?_curry2(function(_a,_c){return fn(_a,b,_c);}):_isPlaceholder(b)&&_isPlaceholder(c)?_curry2(function(_b,_c){return fn(a,_b,_c);}):_isPlaceholder(a)?_curry1(function(_a){return fn(_a,b,c);}):_isPlaceholder(b)?_curry1(function(_b){return fn(a,_b,c);}):_isPlaceholder(c)?_curry1(function(_c){return fn(a,b,_c);}):fn(a,b,c);}};} function _has(prop,obj){return Object.prototype.hasOwnProperty.call(obj,prop);} /** * Gives a single-word string description of the (native) type of a value, * returning such answers as 'Object', 'Number', 'Array', or 'Null'. Does not * attempt to distinguish user Object types any further, reporting them all as * 'Object'. * * @func * @memberOf R * @since v0.8.0 * @category Type * @sig * -> String * @param {*} val The value to test * @return {String} * @example * * R.type({}); //=> "Object" * R.type(1); //=> "Number" * R.type(false); //=> "Boolean" * R.type('s'); //=> "String" * R.type(null); //=> "Null" * R.type([]); //=> "Array" * R.type(/[A-z]/); //=> "RegExp" * R.type(() => {}); //=> "Function" * R.type(async () => {}); //=> "AsyncFunction" * R.type(undefined); //=> "Undefined" * R.type(BigInt(123)); //=> "BigInt" */var type=/*#__PURE__*/_curry1(function type(val){return val===null?'Null':val===undefined?'Undefined':Object.prototype.toString.call(val).slice(8,-1);}); function _isObject(x){return Object.prototype.toString.call(x)==='[object Object]';} /** * Determine if the passed argument is an integer. * * @private * @param {*} n * @category Type * @return {Boolean} */const _isInteger = Number.isInteger||function _isInteger(n){return n<<0===n;}; function _nth(offset,list){var idx=offset<0?list.length+offset:offset;return list[idx];} function _cloneRegExp(pattern){return new RegExp(pattern.source,pattern.flags?pattern.flags:(pattern.global?'g':'')+(pattern.ignoreCase?'i':'')+(pattern.multiline?'m':'')+(pattern.sticky?'y':'')+(pattern.unicode?'u':'')+(pattern.dotAll?'s':''));} /** * Copies an object. * * @private * @param {*} value The value to be copied * @param {Boolean} deep Whether or not to perform deep cloning. * @return {*} The copied value. */function _clone(value,deep,map){map||(map=new _ObjectMap());// this avoids the slower switch with a quick if decision removing some milliseconds in each run. if(_isPrimitive(value)){return value;}var copy=function copy(copiedValue){// Check for circular and same references on the object graph and return its corresponding clone. var cachedCopy=map.get(value);if(cachedCopy){return cachedCopy;}map.set(value,copiedValue);for(var key in value){if(Object.prototype.hasOwnProperty.call(value,key)){copiedValue[key]=_clone(value[key],true,map);}}return copiedValue;};switch(type(value)){case 'Object':return copy(Object.create(Object.getPrototypeOf(value)));case 'Array':return copy(Array(value.length));case 'Date':return new Date(value.valueOf());case 'RegExp':return _cloneRegExp(value);case 'Int8Array':case 'Uint8Array':case 'Uint8ClampedArray':case 'Int16Array':case 'Uint16Array':case 'Int32Array':case 'Uint32Array':case 'Float32Array':case 'Float64Array':case 'BigInt64Array':case 'BigUint64Array':return value.slice();default:return value;}}function _isPrimitive(param){var type=typeof param;return param==null||type!='object'&&type!='function';}var _ObjectMap=/*#__PURE__*/function(){function _ObjectMap(){this.map={};this.length=0;}_ObjectMap.prototype.set=function(key,value){var hashedKey=this.hash(key);var bucket=this.map[hashedKey];if(!bucket){this.map[hashedKey]=bucket=[];}bucket.push([key,value]);this.length+=1;};_ObjectMap.prototype.hash=function(key){var hashedKey=[];for(var value in key){hashedKey.push(Object.prototype.toString.call(key[value]));}return hashedKey.join();};_ObjectMap.prototype.get=function(key){/** * depending on the number of objects to be cloned is faster to just iterate over the items in the map just because the hash function is so costly, * on my tests this number is 180, anything above that using the hash function is faster. */if(this.length<=180){for(var p in this.map){var bucket=this.map[p];for(var i=0;i<bucket.length;i+=1){var element=bucket[i];if(element[0]===key){return element[1];}}}return;}var hashedKey=this.hash(key);var bucket=this.map[hashedKey];if(!bucket){return;}for(var i=0;i<bucket.length;i+=1){var element=bucket[i];if(element[0]===key){return element[1];}}};return _ObjectMap;}(); /** * Creates a deep copy of the source that can be used in place of the source * object without retaining any references to it. * The source object may contain (nested) `Array`s and `Object`s, * `Number`s, `String`s, `Boolean`s and `Date`s. * `Function`s are assigned by reference rather than copied. * * Dispatches to a `clone` method if present. * * Note that if the source object has multiple nodes that share a reference, * the returned object will have the same structure, but the references will * be pointed to the location within the cloned value. * * @func * @memberOf R * @since v0.1.0 * @category Object * @sig {*} -> {*} * @param {*} value The object or array to clone * @return {*} A deeply cloned copy of `val` * @example * * const objects = [{}, {}, {}]; * const objectsClone = R.clone(objects); * objects === objectsClone; //=> false * objects[0] === objectsClone[0]; //=> false */var clone=/*#__PURE__*/_curry1(function clone(value){return value!=null&&typeof value.clone==='function'?value.clone():_clone(value);}); function _path(pathAr,obj){var val=obj;for(var i=0;i<pathAr.length;i+=1){if(val==null){return undefined;}var p=pathAr[i];if(_isInteger(p)){val=_nth(p,val);}else {val=val[p];}}return val;} /** * Creates a new object with the own properties of the two provided objects. If * a key exists in both objects, the provided function is applied to the key * and the values associated with the key in each object, with the result being * used as the value associated with the key in the returned object. * * @func * @memberOf R * @since v0.19.0 * @category Object * @sig ((String, a, a) -> a) -> {a} -> {a} -> {a} * @param {Function} fn * @param {Object} l * @param {Object} r * @return {Object} * @see R.mergeDeepWithKey, R.mergeWith * @example * * let concatValues = (k, l, r) => k == 'values' ? R.concat(l, r) : r * R.mergeWithKey(concatValues, * { a: true, thing: 'foo', values: [10, 20] }, * { b: true, thing: 'bar', values: [15, 35] }); * //=> { a: true, b: true, thing: 'bar', values: [10, 20, 15, 35] } * @symb R.mergeWithKey(f, { x: 1, y: 2 }, { y: 5, z: 3 }) = { x: 1, y: f('y', 2, 5), z: 3 } */var mergeWithKey=/*#__PURE__*/_curry3(function mergeWithKey(fn,l,r){var result={};var k;l=l||{};r=r||{};for(k in l){if(_has(k,l)){result[k]=_has(k,r)?fn(k,l[k],r[k]):l[k];}}for(k in r){if(_has(k,r)&&!_has(k,result)){result[k]=r[k];}}return result;}); /** * Creates a new object with the own properties of the two provided objects. * If a key exists in both objects: * - and both associated values are also objects then the values will be * recursively merged. * - otherwise the provided function is applied to the key and associated values * using the resulting value as the new value associated with the key. * If a key only exists in one object, the value will be associated with the key * of the resulting object. * * @func * @memberOf R * @since v0.24.0 * @category Object * @sig ((String, a, a) -> a) -> {a} -> {a} -> {a} * @param {Function} fn * @param {Object} lObj * @param {Object} rObj * @return {Object} * @see R.mergeWithKey, R.mergeDeepWith * @example * * let concatValues = (k, l, r) => k == 'values' ? R.concat(l, r) : r * R.mergeDeepWithKey(concatValues, * { a: true, c: { thing: 'foo', values: [10, 20] }}, * { b: true, c: { thing: 'bar', values: [15, 35] }}); * //=> { a: true, b: true, c: { thing: 'bar', values: [10, 20, 15, 35] }} */var mergeDeepWithKey=/*#__PURE__*/_curry3(function mergeDeepWithKey(fn,lObj,rObj){return mergeWithKey(function(k,lVal,rVal){if(_isObject(lVal)&&_isObject(rVal)){return mergeDeepWithKey(fn,lVal,rVal);}else {return fn(k,lVal,rVal);}},lObj,rObj);}); /** * Creates a new object with the own properties of the two provided objects. * If a key exists in both objects: * - and both associated values are also objects then the values will be * recursively merged. * - otherwise the provided function is applied to associated values using the * resulting value as the new value associated with the key. * If a key only exists in one object, the value will be associated with the key * of the resulting object. * * @func * @memberOf R * @since v0.24.0 * @category Object * @sig ((a, a) -> a) -> {a} -> {a} -> {a} * @param {Function} fn * @param {Object} lObj * @param {Object} rObj * @return {Object} * @see R.mergeWith, R.mergeDeepWithKey * @example * * R.mergeDeepWith(R.concat, * { a: true, c: { values: [10, 20] }}, * { b: true, c: { values: [15, 35] }}); * //=> { a: true, b: true, c: { values: [10, 20, 15, 35] }} */var mergeDeepWith=/*#__PURE__*/_curry3(function mergeDeepWith(fn,lObj,rObj){return mergeDeepWithKey(function(k,lVal,rVal){return fn(lVal,rVal);},lObj,rObj);}); /** * Retrieves the value at a given path. The nodes of the path can be arbitrary strings or non-negative integers. * For anything else, the value is unspecified. Integer paths are meant to index arrays, strings are meant for objects. * * @func * @memberOf R * @since v0.2.0 * @category Object * @typedefn Idx = String | Int | Symbol * @sig [Idx] -> {a} -> a | Undefined * @sig Idx = String | NonNegativeInt * @param {Array} path The path to use. * @param {Object} obj The object or array to retrieve the nested property from. * @return {*} The data at `path`. * @see R.prop, R.nth, R.assocPath, R.dissocPath * @example * * R.path(['a', 'b'], {a: {b: 2}}); //=> 2 * R.path(['a', 'b'], {c: {b: 2}}); //=> undefined * R.path(['a', 'b', 0], {a: {b: [1, 2, 3]}}); //=> 1 * R.path(['a', 'b', -2], {a: {b: [1, 2, 3]}}); //=> 2 * R.path([2], {'2': 2}); //=> 2 * R.path([-2], {'-2': 'a'}); //=> undefined */var path=/*#__PURE__*/_curry2(_path); /** * Returns a partial copy of an object containing only the keys that satisfy * the supplied predicate. * * @func * @memberOf R * @since v0.8.0 * @category Object * @sig ((v, k) -> Boolean) -> {k: v} -> {k: v} * @param {Function} pred A predicate to determine whether or not a key * should be included on the output object. * @param {Object} obj The object to copy from * @return {Object} A new object with only properties that satisfy `pred` * on it. * @see R.pick, R.filter * @example * * const isUpperCase = (val, key) => key.toUpperCase() === key; * R.pickBy(isUpperCase, {a: 1, b: 2, A: 3, B: 4}); //=> {A: 3, B: 4} */var pickBy=/*#__PURE__*/_curry2(function pickBy(test,obj){var result={};for(var prop in obj){if(test(obj[prop],prop,obj)){result[prop]=obj[prop];}}return result;}); /** * A function to check given value is a function * @param value input value * @returns boolean */const isFunction=value=>typeof value==='function'&&Boolean(value.constructor&&value.call&&value.apply);/** * A function to check given value is a string * @param value input value * @returns boolean */const isString=value=>typeof value==='string';/** * A function to check given value is null or not * @param value input value * @returns boolean */const isNull=value=>value===null;/** * A function to check given value is undefined * @param value input value * @returns boolean */const isUndefined=value=>typeof value==='undefined';/** * A function to check given value is null or undefined * @param value input value * @returns boolean */const isNullOrUndefined=value=>isNull(value)||isUndefined(value);/** * Checks if the input is a BigInt * @param value input value * @returns True if the input is a BigInt */const isBigInt=value=>typeof value==='bigint';/** * A function to check given value is defined * @param value input value * @returns boolean */const isDefined=value=>!isUndefined(value);/** * A function to check given value is defined and not null * @param value input value * @returns boolean */const isDefinedAndNotNull=value=>!isNullOrUndefined(value);/** * A function to check given value is defined and not null * @param value input value * @returns boolean */const isDefinedNotNullAndNotEmptyString=value=>isDefinedAndNotNull(value)&&value!=='';/** * Determines if the input is of type error * @param value input value * @returns true if the input is of type error else false */const isTypeOfError=value=>{switch(Object.prototype.toString.call(value)){case '[object Error]':case '[object Exception]':case '[object DOMException]':return true;default:return value instanceof Error;}};/** * A function to check given value is a boolean * @param value input value * @returns boolean */const isBoolean=value=>typeof value==='boolean'; const getValueByPath=(obj,keyPath)=>{const pathParts=keyPath.split('.');return path(pathParts,obj);};const hasValueByPath=(obj,path)=>Boolean(getValueByPath(obj,path));const isObject=value=>typeof value==='object';/** * Checks if the input is an object literal or built-in object type and not null * @param value Input value * @returns true if the input is an object and not null */const isObjectAndNotNull=value=>!isNull(value)&&isObject(value)&&!Array.isArray(value);/** * Checks if the input is an object literal and not null * @param value Input value * @returns true if the input is an object and not null */const isObjectLiteralAndNotNull=value=>!isNull(value)&&Object.prototype.toString.call(value)==='[object Object]';/** * Merges two arrays deeply, right-to-left * In the case of conflicts, the right array's values replace the left array's values in the * same index position * @param leftValue - The left array * @param rightValue - The right array * @returns The merged array */const mergeDeepRightObjectArrays=(leftValue,rightValue)=>{if(!Array.isArray(leftValue)||!Array.isArray(rightValue)){return clone(rightValue);}const mergedArray=clone(leftValue);rightValue.forEach((value,index)=>{mergedArray[index]=Array.isArray(value)||isObjectAndNotNull(value)?// eslint-disable-next-line @typescript-eslint/no-use-before-define mergeDeepRight(mergedArray[index],value):value;});return mergedArray;};/** * Merges two objects deeply, right-to-left. * In the case of conflicts, the right object's values take precedence. * For arrays, the right array's values replace the left array's values in the * same index position keeping the remaining left array's values in the resultant array. * @param leftObject - The left object * @param rightObject - The right object * @returns The merged object */const mergeDeepRight=(leftObject,rightObject)=>mergeDeepWith(mergeDeepRightObjectArrays,leftObject,rightObject);/** Checks if the input is a non-empty object literal type and not undefined or null * @param value input any * @returns boolean */const isNonEmptyObject=value=>isObjectLiteralAndNotNull(value)&&Object.keys(value).length>0;/** * A utility to recursively remove undefined values from an object * @param obj input object * @returns a new object */const removeUndefinedValues=obj=>{const result=pickBy(isDefined,obj);Object.keys(result).forEach(key=>{const value=result[key];if(isObjectLiteralAndNotNull(value)){result[key]=removeUndefinedValues(value);}});return result;};/** * A utility to recursively remove undefined and null values from an object * @param obj input object * @returns a new object */const removeUndefinedAndNullValues=obj=>{const result=pickBy(isDefinedAndNotNull,obj);Object.keys(result).forEach(key=>{const value=result[key];if(isObjectLiteralAndNotNull(value)){result[key]=removeUndefinedAndNullValues(value);}});return result;};/** * Normalizes an object by removing undefined and null values. * @param val - The value to normalize * @returns The normalized object, or undefined if input is not a non-empty object * @example * getNormalizedObjectValue({ a: 1, b: null, c: undefined }) // returns { a: 1 } * getNormalizedObjectValue({}) // returns undefined * getNormalizedObjectValue(null) // returns undefined */const getNormalizedObjectValue=val=>{if(!isNonEmptyObject(val)){return undefined;}return removeUndefinedAndNullValues(val);};/** * Normalizes a value to a boolean, with support for a default value * @param val Input value * @param defVal Default value * @returns Returns the input value if it is a boolean, otherwise returns the default value * @example * getNormalizedBooleanValue(true, false) // returns true */const getNormalizedBooleanValue=(val,defVal)=>typeof val==='boolean'?val:defVal; const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeLeadingPeriod=value=>value.replace(/^\.+/,'');/** * A function to convert values to string * @param val input value * @returns stringified value */const tryStringify=val=>{let retVal=val;if(!isString(val)&&!isNullOrUndefined(val)){try{retVal=JSON.stringify(val);}catch(e){retVal=null;}}return retVal;};// The following text encoding and decoding is done before base64 encoding to prevent // https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem /** * Converts a base64 encoded string to bytes array * @param base64Str base64 encoded string * @returns bytes array */const base64ToBytes=base64Str=>{const binString=globalThis.atob(base64Str);const bytes=binString.split('').map(char=>char.charCodeAt(0));return new Uint8Array(bytes);};/** * Converts a bytes array to base64 encoded string * @param bytes bytes array to be converted to base64 * @returns base64 encoded string */const bytesToBase64=bytes=>{const binString=Array.from(bytes,x=>String.fromCodePoint(x)).join('');return globalThis.btoa(binString);};/** * Encodes a string to base64 even with unicode characters * @param value input string * @returns base64 encoded string */const toBase64=value=>bytesToBase64(new TextEncoder().encode(value));/** * Decodes a base64 encoded string * @param value base64 encoded string * @returns decoded string */const fromBase64=value=>new TextDecoder().decode(base64ToBytes(value)); // if yes make them null instead of omitting in overloaded cases /* * Normalise the overloaded arguments of the page call facade */const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const payload={category:category,name:name,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.category=category;payload.name=name;payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.category=category;payload.name=name;payload.properties=undefined;payload.options=undefined;payload.callback=properties;}if(isFunction(name)){payload.category=category;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=name;}if(isFunction(category)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=category;}if(isObjectLiteralAndNotNull(category)){payload.name=undefined;payload.category=undefined;payload.properties=category;if(!isFunction(name)){payload.options=name;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(name)){payload.name=undefined;payload.properties=name;if(!isFunction(properties)){payload.options=properties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name, // use it as name and set category to undefined if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// Rest of the code is just to clean up undefined values // and set some proper defaults // Also, to clone the incoming object type arguments if(!isDefined(payload.category)){payload.category=undefined;}if(!isDefined(payload.name)){payload.name=undefined;}payload.properties=payload.properties?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}const nameForProperties=isString(payload.name)?payload.name:payload.properties.name;const categoryForProperties=isString(payload.category)?payload.category:payload.properties.category;// add name and category to properties payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/* * Normalise the overloaded arguments of the track call facade */const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const payload={name:event,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.properties=undefined;payload.options=undefined;payload.callback=properties;}// Rest of the code is just to clean up undefined values // and set some proper defaults // Also, to clone the incoming object type arguments payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/* * Normalise the overloaded arguments of the identify call facade */const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const payload={userId:userId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.userId=userId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.userId=userId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(userId)||isNull(userId)){// Explicitly set null to prevent resetting the existing value // in the Analytics class payload.userId=null;payload.traits=userId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values // and set some proper defaults // Also, to clone the incoming object type arguments payload.userId=tryStringify(payload.userId);if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone(payload.traits);}else {payload.traits=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/* * Normalise the overloaded arguments of the alias call facade */const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const payload={to,from:from,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.to=to;payload.from=from;payload.options=undefined;payload.callback=options;}if(isFunction(from)){payload.to=to;payload.from=undefined;payload.options=undefined;payload.callback=from;}else if(isObjectLiteralAndNotNull(from)||isNull(from)){payload.to=to;payload.from=undefined;payload.options=from;}// Rest of the code is just to clean up undefined values // and set some proper defaults // Also, to clone the incoming object type arguments if(isDefined(payload.to)){payload.to=tryStringify(payload.to);}if(isDefined(payload.from)){payload.from=tryStringify(payload.from);}else {payload.from=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/* * Normalise the overloaded arguments of the group call facade */const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const payload={groupId:groupId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.groupId=groupId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.groupId=groupId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(groupId)||isNull(groupId)){// Explicitly set null to prevent resetting the existing value // in the Analytics class payload.groupId=null;payload.traits=groupId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values // and set some proper defaults // Also, to clone the incoming object type arguments payload.groupId=tryStringify(payload.groupId);if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone(payload.traits);}else {payload.traits=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;}; /** * Represents the options parameter for anonymousId *//** * Represents the beacon queue options parameter in loadOptions type *//** * Represents the queue options parameter in loadOptions type *//** * Represents the destinations queue options parameter in loadOptions type */let PageLifecycleEvents=/*#__PURE__*/function(PageLifecycleEvents){PageLifecycleEvents["UNLOADED"]="Page Unloaded";return PageLifecycleEvents;}({});/** * Represents the source configuration override options for destinations *//** * Represents the options parameter in the load API */ const API_SUFFIX='API';const CAPABILITIES_MANAGER='CapabilitiesManager';const CONFIG_MANAGER='ConfigManager';const EVENT_MANAGER='EventManager';const PLUGINS_MANAGER='PluginsManager';const USER_SESSION_MANAGER='UserSessionManager';const ERROR_HANDLER='ErrorHandler';const PLUGIN_ENGINE='PluginEngine';const STORE_MANAGER='StoreManager';const READY_API=`Ready${API_SUFFIX}`;const LOAD_API=`Load${API_SUFFIX}`;const HTTP_CLIENT='HttpClient';const RSA='RudderStackAnalytics';const ANALYTICS_CORE='AnalyticsCore'; function random(len){return crypto.getRandomValues(new Uint8Array(len));} var SIZE=4096,HEX$1=[],IDX$1=0,BUFFER$1;for(;IDX$1<256;IDX$1++){HEX$1[IDX$1]=(IDX$1+256).toString(16).substring(1);}function v4$1(){if(!BUFFER$1||IDX$1+16>SIZE){BUFFER$1=random(SIZE);IDX$1=0;}var i=0,tmp,out='';for(;i<16;i++){tmp=BUFFER$1[IDX$1+i];if(i==6)out+=HEX$1[tmp&15|64];else if(i==8)out+=HEX$1[tmp&63|128];else out+=HEX$1[tmp];if(i&1&&i>1&&i<11)out+='-';}IDX$1+=16;return out;} var IDX=256,HEX=[],BUFFER;while(IDX--)HEX[IDX]=(IDX+256).toString(16).substring(1);function v4(){var i=0,num,out='';if(!BUFFER||IDX+16>256){BUFFER=Array(i=256);while(i--)BUFFER[i]=256*Math.random()|0;i=IDX=0;}for(;i<16;i++){num=BUFFER[IDX+i];if(i==6)out+=HEX[num&15|64];else if(i==8)out+=HEX[num&63|128];else out+=HEX[num];if(i&1&&i>1&&i<11)out+='-';}IDX++;return out;} const hasCrypto$1=()=>!isNullOrUndefined(globalThis.crypto)&&isFunction(globalThis.crypto.getRandomValues); const generateUUID=()=>{if(hasCrypto$1()){return v4$1();}return v4();}; const onPageLeave=callback=>{// To ensure the callback is only called once even if more than one events // are fired at once. let pageLeft=false;let isAccessible=false;function handleOnLeave(){if(pageLeft){return;}pageLeft=true;callback(isAccessible);// Reset pageLeft on the next tick // to ensure callback executes for other listeners // when closing an inactive browser tab. setTimeout(()=>{pageLeft=false;},0);}// Catches the unloading of the page (e.g., closing the tab or navigating away). // Includes user actions like clicking a link, entering a new URL, // refreshing the page, or closing the browser tab // Note that 'pagehide' is not supported in IE. // So, this is a fallback. globalThis.addEventListener('beforeunload',()=>{isAccessible=false;handleOnLeave();});globalThis.addEventListener('blur',()=>{isAccessible=true;handleOnLeave();});globalThis.addEventListener('focus',()=>{pageLeft=false;});// Catches the page being hidden, including scenarios like closing the tab. document.addEventListener('pagehide',()=>{isAccessible=document.visibilityState==='hidden';handleOnLeave();});// Catches visibility changes, such as switching tabs or minimizing the browser. document.addEventListener('visibilitychange',()=>{isAccessible=true;if(document.visibilityState==='hidden'){handleOnLeave();}else {pageLeft=false;}});}; const getFormattedTimestamp=date=>date.toISOString();/** * To get the current timestamp in ISO string format * @returns ISO formatted timestamp string */const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date()); const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts`;const SCRIPT_LOAD_ERROR=(id,url,ev)=>`Unable to load (${isString(ev)?ev:ev.type}) the script with the id "${id}" from URL "${url}"`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}"`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;const COOKIE_DATA_ENCODING_ERROR=`Failed to encode the cookie data.`; const JSON_STRINGIFY='JSONStringify';const BIG_INT_PLACEHOLDER='[BigInt]';const CIRCULAR_REFERENCE_PLACEHOLDER='[Circular Reference]';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context // eslint-disable-next-line func-names return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent. // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore-next-line while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return CIRCULAR_REFERENCE_PLACEHOLDER;}ancestors.push(value);return value;};};/** * Utility method for JSON stringify object excluding null values & circular references * * @param {*} value input * @param {boolean} excludeNull if it should exclude nul or not * @param {function} logger optional logger methods for warning * @returns string */const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects // Using a regular function to use `this` for the parent context return function replacer(key,value){if(isBigInt(value)){return BIG_INT_PLACEHOLDER;// Replace BigInt values }// `this` is the object that value is contained in, i.e., its direct parent. // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore-next-line while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain }// Check for circular references (if the value is already in the ancestors) if(ancestors.includes(value)){return CIRCULAR_REFERENCE_PLACEHOLDER;}// Add current value to ancestors ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements // eslint-disable-next-line no-restricted-syntax for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/** * Recursively traverses an object similar to JSON.stringify, * sanitizing BigInts and circular references * @param value Input object * @param logger Logger instance * @returns Sanitized value */const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;}; const MANUAL_ERROR_IDENTIFIER='[SDK DISPATCHED ERROR]';const getStacktrace=err=>{const{stack,stacktrace,'opera#sourceloc':operaSourceloc}=err;const stackString=stack??stacktrace??operaSourceloc;if(!!stackString&&typeof stackString==='string'){return stackString;}return undefined;};/** * Get mutated error with issue prepended to error message * @param err Original error * @param issue Issue to prepend to error message * @returns Instance of Error with message prepended with issue */const getMutatedError=(err,issue)=>{if(!isTypeOfError(err)){return new Error(`${issue}: ${stringifyWithoutCircular(err)}`);}try{// Preserve the specific error type (TypeError, ReferenceError, etc.) const ErrorConstructor=err.constructor;const newError=new ErrorConstructor(`${issue}: ${err.message}`);// Preserve stack trace const stack=getStacktrace(err);if(stack){newError.stack=stack;}// Preserve any other enumerable properties Object.getOwnPropertyNames(err).forEach(key=>{if(key!=='message'&&key!=='stack'&&key!=='name'){try{newError[key]=err[key];}catch{// Ignore if property is not writable }}});return newError;}catch{return new Error(`${issue}: ${stringifyWithoutCircular(err)}`);}};const dispatchErrorEvent=error=>{if(isTypeOfError(error)){const errStack=getStacktrace(error);if(errStack){const{stack,stacktrace,'opera#sourceloc':operaSourceloc}=error;switch(errStack){case stack:// eslint-disable-next-line no-param-reassign error.stack=`${stack}\n${MANUAL_ERROR_IDENTIFIER}`;break;case stacktrace:// eslint-disable-next-line no-param-reassign error.stacktrace=`${stacktrace}\n${MANUAL_ERROR_IDENTIFIER}`;break;case operaSourceloc:default:// eslint-disable-next-line no-param-reassign error['opera#sourceloc']=`${operaSourceloc}\n${MANUAL_ERROR_IDENTIFIER}`;break;}}}globalThis.dispatchEvent(new ErrorEvent('error',{error,bubbles:true,cancelable:true,composed:true}));}; const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.23.0';const APP_NAMESPACE='com.rudderlabs.javascript';const MODULE_TYPE='npm';const ADBLOCK_PAGE_CATEGORY='RudderJS-Initiated';const ADBLOCK_PAGE_NAME='ad-block page request';const ADBLOCK_PAGE_PATH='/ad-blocked';const GLOBAL_PRELOAD_BUFFER='preloadedEventsBuffer';const CONSENT_TRACK_EVENT_NAME='Consent Management Interaction'; const QUERY_PARAM_TRAIT_PREFIX='ajs_trait_';const QUERY_PARAM_PROPERTY_PREFIX='ajs_prop_';const QUERY_PARAM_ANONYMOUS_ID_KEY='ajs_aid';const QUERY_PARAM_USER_ID_KEY='ajs_uid';const QUERY_PARAM_TRACK_EVENT_NAME_KEY='ajs_event'; const DEFAULT_XHR_TIMEOUT_MS=10*1000;// 10 seconds const DEFAULT_COOKIE_MAX_AGE_MS=31536000*1000;// 1 year const DEFAULT_SESSION_CUT_OFF_DURATION_MS=12*60*60*1000;// 12 hours const DEFAULT_SESSION_TIMEOUT_MS=30*60*1000;// 30 minutes const MIN_SESSION_TIMEOUT_MS=10*1000;// 10 seconds const DEFAULT_DATA_PLANE_EVENTS_BUFFER_TIMEOUT_MS=10*1000;// 10 seconds const DEBOUNCED_TIMEOUT_MS=250;// 250 milliseconds /** * Create globally accessible RudderStackGlobals object */const createExposedGlobals=(analyticsInstanceId='app')=>{if(!globalThis.RudderStackGlobals){globalThis.RudderStackGlobals={};}if(!globalThis.RudderStackGlobals[analyticsInstanceId]){globalThis.RudderStackGlobals[analyticsInstanceId]={};}};/** * Add move values to globally accessible RudderStackGlobals object per analytics instance */const setExposedGlobal=(keyName,value,analyticsInstanceId='app')=>{createExposedGlobals(analyticsInstanceId);globalThis.RudderStackGlobals[analyticsInstanceId][keyName]=value;};/** * Get values from globally accessible RudderStackGlobals object by analytics instance */const getExposedGlobal=(keyName,analyticsInstanceId='app')=>{createExposedGlobals(analyticsInstanceId);return globalThis.RudderStackGlobals[analyticsInstanceId][keyName];};function debounce(func,thisArg,delay=DEBOUNCED_TIMEOUT_MS){let timeoutId;return (...args)=>{globalThis.clearTimeout(timeoutId);timeoutId=globalThis.setTimeout(()=>{func.apply(thisArg,args);},delay);};} /** * Parse query string params into object values for keys that start with a defined prefix */const getEventDataFromQueryString=(params,dataTypeNamePrefix)=>{const data={};params.forEach((value,key)=>{if(key.startsWith(dataTypeNamePrefix)){// remove prefix from key name const dataKey=key.substring(dataTypeNamePrefix.length);// add new key value pair in generated object data[dataKey]=params.get(key);}});return data;};/** * Parse query string into preload buffer events & push into existing array before any other events */const retrieveEventsFromQueryString=(argumentsArray=[])=>{// Mapping for trait and properties values based on key prefix const eventArgumentToQueryParamMap={trait:QUERY_PARAM_TRAIT_PREFIX,properties:QUERY_PARAM_PROPERTY_PREFIX};const queryObject=new URLSearchParams(globalThis.location.search);// Add track events with name and properties if(queryObject.get(QUERY_PARAM_TRACK_EVENT_NAME_KEY)){argumentsArray.unshift(['track',queryObject.get(QUERY_PARAM_TRACK_EVENT_NAME_KEY),getEventDataFromQueryString(queryObject,eventArgumentToQueryParamMap.properties)]);}// Set userId and user traits if(queryObject.get(QUERY_PARAM_USER_ID_KEY)){argumentsArray.unshift(['identify',queryObject.get(QUERY_PARAM_USER_ID_KEY),getEventDataFromQueryString(queryObject,eventArgumentToQueryParamMap.trait)]);}// Set anonymousID if(queryObject.get(QUERY_PARAM_ANONYMOUS_ID_KEY)){argumentsArray.unshift(['setAnonymousId',queryObject.get(QUERY_PARAM_ANONYMOUS_ID_KEY)]);}};/** * Retrieve an existing buffered load method call and remove from the existing array */const getPreloadedLoadEvent=preloadedEventsArray=>{const loadMethodName='load';let loadEvent=[];/** * Iterate the buffered API calls until we find load call and process it separately */let i=0;while(i<preloadedEventsArray.length){if(preloadedEventsArray[i]&&preloadedEventsArray[i][0]===loadMethodName){loadEvent=clone(preloadedEventsArray[i]);preloadedEventsArray.splice(i,1);break;}i+=1;}return loadEvent;};/** * Promote consent events to the top of the preloaded events array * @param preloadedEventsArray Preloaded events array * @returns None */const promotePreloadedConsentEventsToTop=preloadedEventsArray=>{const consentMethodName='consent';const consentEvents=preloadedEventsArray.filter(bufferedEvent=>bufferedEvent[0]===consentMethodName);const nonConsentEvents=preloadedEventsArray.filter(bufferedEvent=>bufferedEvent[0]!==consentMethodName);// Remove all elements and add consent events first followed by non consent events // eslint-disable-next-line unicorn/no-useless-spread preloadedEventsArray.splice(0,preloadedEventsArray.length,...consentEvents,...nonConsentEvents);};/** * Retrieve any existing events that were triggered before SDK load and enqueue in buffer */const retrievePreloadBufferEvents=instance=>{const preloadedEventsArray=getExposedGlobal(GLOBAL_PRELOAD_BUFFER)||[];// Get events that are pre-populated via query string params retrieveEventsFromQueryString(preloadedEventsArray);// Enqueue the non load events in the buffer of the global rudder analytics singleton if(preloadedEventsArray.length>0){instance.enqueuePreloadBufferEvents(preloadedEventsArray);setExposedGlobal(GLOBAL_PRELOAD_BUFFER,[]);}};const consumePreloadBufferedEvent=(event,analyticsInstance)=>{const methodName=event.shift();let callOptions;if(isFunction(analyticsInstance[methodName])){switch(methodName){case 'page':callOptions=pageArgumentsToCallOptions(...event);break;case 'track':callOptions=trackArgumentsToCallOptions(...event);break;case 'identify':callOptions=identifyArgumentsToCallOptions(...event);break;case 'alias':callOptions=aliasArgumentsToCallOptions(...event);break;case 'group':callOptions=groupArgumentsToCallOptions(...event);break;default:analyticsInstance[methodName](...event);break;}if(callOptions){analyticsInstance[methodName](callOptions);}}}; const DEFAULT_EXT_SRC_LOAD_TIMEOUT_MS=10*1000;// 10 seconds const EXTERNAL_SOURCE_LOAD_ORIGIN='RS_JS_SDK'; /** * Create the DOM element to load a script marked as RS SDK originated * * @param {*} url The URL of the script to be loaded * @param {*} id ID for the script tag * @param {*} async Whether to load the script in async mode. Defaults to `true` [optional] * @param {*} onload callback to invoke onload [optional] * @param {*} onerror callback to invoke onerror [optional] * @param {*} extraAttributes key/value pair with html attributes to add in html tag [optional] * * @returns HTMLScriptElement */const createScriptElement=(url,id,async=true,onload=null,onerror=null,extraAttributes={})=>{const scriptElement=document.createElement('script');scriptElement.type='text/javascript';scriptElement.onload=onload;scriptElement.onerror=onerror;scriptElement.src=url;scriptElement.id=id;scriptElement.async=async;Object.keys(extraAttributes).forEach(attributeName=>{scriptElement.setAttribute(attributeName,extraAttributes[attributeName]);});scriptElement.setAttribute('data-loader',EXTERNAL_SOURCE_LOAD_ORIGIN);return scriptElement;};/** * Add script DOM element to DOM * * @param {*} newScriptElement the script element to add * * @returns */const insertScript=newScriptElement=>{// First try to add it to the head const headElements=document.getElementsByTagName('head');if(headElements.length>0){headElements[0]?.insertBefore(newScriptElement,headElements[0]?.firstChild);return;}// Else wise add it before the first script tag const scriptElements=document.getElementsByTagName('script');if(scriptElements.length>0&&scriptElements[0]?.parentNode){scriptElements[0]?.parentNode.insertBefore(newScriptElement,scriptElements[0]);return;}// Create a new head element and add the script as fallback const headElement=document.createElement('head');headElement.appendChild(newScriptElement);const htmlElement=document.getElementsByTagName('html')[0];htmlElement?.insertBefore(headElement,htmlElement.firstChild);};/** * Loads external js file as a script html tag * * @param {*} url The URL of the script to be loaded * @param {*} id ID for the script tag * @param {*} timeout loading timeout * @param {*} async Whether to load the script in async mode. Defaults to `true` [optional] * @param {*} extraAttributes key/value pair with html attributes to add in html tag [optional] * * @returns */const jsFileLoader=(url,id,timeout,async=true,extraAttributes)=>new Promise((resolve,reject)=>{const scriptExists=document.getElementById(id);if(scriptExists){reject(new Error(SCRIPT_ALREADY_EXISTS_ERROR(id)));}try{let timeoutID;const onload=()=>{globalThis.clearTimeout(timeoutID);resolve(id);};const onerror=ev=>{globalThis.clearTimeout(timeoutID);reject(new Error(SCRIPT_LOAD_ERROR(id,url,ev)));};// Create the DOM element to load the script and add it to the DOM insertScript(createScriptElement(url,id,async,onload,onerror,extraAttributes));// Reject on timeout timeoutID=globalThis.setTimeout(()=>{reject(new Error(SCRIPT_LOAD_TIMEOUT_ERROR(id,url,timeout)));},timeout);}catch(err){reject(getMutatedError(err,SCRIPT_LOAD_ERROR(id,url,'unknown')));}}); /** * Service to load external resources/files */class ExternalSrcLoader{constructor(logger,timeout=DEFAULT_EXT_SRC_LOAD_TIMEOUT_MS){this.logger=logger;this.timeout=timeout;}/** * Load external resource of type javascript */loadJSFile(config){const{url,id,timeout,async,callback,extraAttributes}=config;const isFireAndForget=!isFunction(callback);jsFileLoader(url,id,timeout||this.timeout,async,extraAttributes).then(id=>{if(!isFireAndForget){callback(id);}}).catch(err=>{if(!isFireAndForget){callback(id,err);}});}} var i=Symbol.for("preact-signals");function t(){if(!(s>1)){var i,t=false;while(void 0!==h){var r=h;h=void 0;f++;while(void 0!==r){var o=r.o;r.o=void 0;r.f&=-3;if(!(8&r.f)&&c(r))try{r.c();}catch(r){if(!t){i=r;t=true;}}r=o;}}f=0;s--;if(t)throw i;}else s--;}function r(i){if(s>0)return i();s++;try{return i();}finally{t();}}var o=void 0;function n(i){var t=o;o=void 0;try{return i();}finally{o=t;}}var h=void 0,s=0,f=0,v=0;function e(i){if(void 0!==o){var t=i.n;if(void 0===t||t.t!==o){t={i:0,S:i,p:o.s,n:void 0,t:o,e:void 0,x:void 0,r:t};if(void 0!==o.s)o.s.n=t;o.s=t;i.n=t;if(32&o.f)i.S(t);return t;}else if(-1===t.i){t.i=0;if(void 0!==t.n){t.n.p=t.p;if(void 0!==t.p)t.p.n=t.n;t.p=o.s;t.n=void 0;o.s.n=t;o.s=t;}return t;}}}function u(i,t){this.v=i;this.i=0;this.n=void 0;this.t=void 0;this.W=null==t?void 0:t.watched;this.Z=null==t?void 0:t.unwatched;}u.prototype.brand=i;u.prototype.h=function(){return true;};u.prototype.S=function(i){var t=this,r=this.t;if(r!==i&&void 0===i.e){i.x=r;this.t=i;if(void 0!==r)r.e=i;else n(function(){var i;null==(i=t.W)||i.call(t);});}};u.prototype.U=function(i){var t=this;if(void 0!==this.t){var r=i.e,o=i.x;if(void 0!==r){r.x=o;i.e=void 0;}if(void 0!==o){o.e=r;i.x=void 0;}if(i===this.t){this.t=o;if(void 0===o)n(function(){var i;null==(i=t.Z)||i.call(t);});}}};u.prototype.subscribe=function(i){var t=this;return E(function(){var r=t.value,n=o;o=void 0;try{i(r);}finally{o=n;}});};u.prototype.valueOf=function(){return this.value;};u.prototype.toString=function(){return this.value+"";};u.prototype.toJSON=function(){return this.value;};u.prototype.peek=function(){var i=o;o=void 0;try{return this.value;}finally{o=i;}};Object.defineProperty(u.prototype,"value",{get:function(){var i=e(this);if(void 0!==i)i.i=this.i;return this.v;},set:function(i){if(i!==this.v){if(f>100)throw new Error("Cycle detected");this.v=i;this.i++;v++;s++;try{for(var r=this.t;void 0!==r;r=r.x)r.t.N();}finally{t();}}}});function d$1(i,t){return new u(i,t);}function c(i){for(var t=i.s;void 0!==t;t=t.n)if(t.S.i!==t.i||!t.S.h()||t.S.i!==t.i)return true;return false;}function a(i){for(var t=i.s;void 0!==t;t=t.n){var r=t.S.n;if(void 0!==r)t.r=r;t.S.n=t;t.i=-1;if(void 0===t.n){i.s=t;break;}}}function l(i){var t=i.s,r=void