@posthog/browser-common
Advanced tools
| type SDKDistChannel = 'npm' | 'cdn'; | ||
| declare const Config: { | ||
| DEBUG: boolean; | ||
| LIB_VERSION: string; | ||
| LIB_NAME: string; | ||
| SDK_DIST_CHANNEL?: SDKDistChannel; | ||
| JS_SDK_VERSION: string; | ||
| }; | ||
| export default Config; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| default: ()=>__WEBPACK_DEFAULT_EXPORT__ | ||
| }); | ||
| const packageVersion = "0.2.0"; | ||
| const Config = { | ||
| DEBUG: false, | ||
| LIB_VERSION: packageVersion, | ||
| LIB_NAME: 'browser-common', | ||
| JS_SDK_VERSION: packageVersion | ||
| }; | ||
| const __WEBPACK_DEFAULT_EXPORT__ = Config; | ||
| exports["default"] = __webpack_exports__["default"]; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "default" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| const packageVersion = "0.2.0"; | ||
| const Config = { | ||
| DEBUG: false, | ||
| LIB_VERSION: packageVersion, | ||
| LIB_NAME: 'browser-common', | ||
| JS_SDK_VERSION: packageVersion | ||
| }; | ||
| const config = Config; | ||
| export { config as default }; |
| export declare const TOOLBAR_ID = "__POSTHOG_TOOLBAR__"; | ||
| export declare const TOOLBAR_CONTAINER_CLASS = "toolbar-global-fade-container"; | ||
| export declare const SDK_DIST_CHANNEL = "$sdk_dist_channel"; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| SDK_DIST_CHANNEL: ()=>SDK_DIST_CHANNEL, | ||
| TOOLBAR_CONTAINER_CLASS: ()=>TOOLBAR_CONTAINER_CLASS, | ||
| TOOLBAR_ID: ()=>TOOLBAR_ID | ||
| }); | ||
| const TOOLBAR_ID = '__POSTHOG_TOOLBAR__'; | ||
| const TOOLBAR_CONTAINER_CLASS = 'toolbar-global-fade-container'; | ||
| const SDK_DIST_CHANNEL = '$sdk_dist_channel'; | ||
| exports.SDK_DIST_CHANNEL = __webpack_exports__.SDK_DIST_CHANNEL; | ||
| exports.TOOLBAR_CONTAINER_CLASS = __webpack_exports__.TOOLBAR_CONTAINER_CLASS; | ||
| exports.TOOLBAR_ID = __webpack_exports__.TOOLBAR_ID; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "SDK_DIST_CHANNEL", | ||
| "TOOLBAR_CONTAINER_CLASS", | ||
| "TOOLBAR_ID" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| const TOOLBAR_ID = '__POSTHOG_TOOLBAR__'; | ||
| const TOOLBAR_CONTAINER_CLASS = 'toolbar-global-fade-container'; | ||
| const SDK_DIST_CHANNEL = '$sdk_dist_channel'; | ||
| export { SDK_DIST_CHANNEL, TOOLBAR_CONTAINER_CLASS, TOOLBAR_ID }; |
| export {}; |
| var __webpack_exports__ = {}; | ||
| if ('function' != typeof Array.prototype.at) Object.defineProperty(Array.prototype, 'at', { | ||
| value: function(index) { | ||
| const len = this.length; | ||
| let relativeIndex = Math.trunc(index) || 0; | ||
| if (relativeIndex < 0) relativeIndex += len; | ||
| return relativeIndex < 0 || relativeIndex >= len ? void 0 : this[relativeIndex]; | ||
| }, | ||
| writable: true, | ||
| enumerable: false, | ||
| configurable: true | ||
| }); | ||
| for(var __webpack_i__ in __webpack_exports__)exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| if ('function' != typeof Array.prototype.at) Object.defineProperty(Array.prototype, 'at', { | ||
| value: function(index) { | ||
| const len = this.length; | ||
| let relativeIndex = Math.trunc(index) || 0; | ||
| if (relativeIndex < 0) relativeIndex += len; | ||
| return relativeIndex < 0 || relativeIndex >= len ? void 0 : this[relativeIndex]; | ||
| }, | ||
| writable: true, | ||
| enumerable: false, | ||
| configurable: true | ||
| }); |
| import type { AutocaptureConfig, PostHogConfig, Properties } from '@posthog/types'; | ||
| import { type UrlTargetingInstance } from './url-targeting-utils'; | ||
| export declare const MAX_DOM_ANCESTOR_DEPTH = 1000; | ||
| export declare function splitClassString(s: string): string[]; | ||
| export declare function getClassNames(el: Element): string[]; | ||
| export declare function makeSafeText(s: string | null | undefined): string | null; | ||
| export declare function getSafeText(el: Element): string; | ||
| export declare function getEventTarget(e: Event): Element | null; | ||
| export declare const autocaptureCompatibleElements: string[]; | ||
| export declare function getParentElement(curEl: Element): Element | false; | ||
| export declare const DEFAULT_CONTENT_IGNORELIST_WITH_STEPPERS: string[]; | ||
| export declare function shouldCaptureDeadClick(el: Element | null, _config: PostHogConfig['capture_dead_clicks']): boolean; | ||
| export declare function isTextSelectionTarget(el: Element | null): boolean; | ||
| export declare function shouldCaptureRageclick(el: Element | null, _config: PostHogConfig['rageclick']): boolean; | ||
| export declare function shouldSkipDeadClick(el: Element | null): boolean; | ||
| export declare function shouldCaptureDomEvent(el: Element, event: Event, autocaptureConfig?: AutocaptureConfig | undefined, captureOnAnyElement?: boolean, allowedEventTypes?: string[], instance?: UrlTargetingInstance): boolean; | ||
| export declare function shouldCaptureElement(el: Element): boolean; | ||
| export declare function isSensitiveElement(el: Element): boolean; | ||
| export declare function shouldCaptureValue(value: string, anchorRegexes?: boolean): boolean; | ||
| export declare function isAngularStyleAttr(attributeName: string): boolean; | ||
| export declare function getDirectAndNestedSpanText(target: Element): string; | ||
| export declare function getNestedSpanText(target: Element): string; | ||
| export declare function getElementsChainString(elements: Properties[]): string; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| isTextSelectionTarget: ()=>isTextSelectionTarget, | ||
| shouldCaptureRageclick: ()=>shouldCaptureRageclick, | ||
| shouldCaptureValue: ()=>shouldCaptureValue, | ||
| splitClassString: ()=>splitClassString, | ||
| shouldCaptureDomEvent: ()=>shouldCaptureDomEvent, | ||
| getEventTarget: ()=>getEventTarget, | ||
| getNestedSpanText: ()=>getNestedSpanText, | ||
| isAngularStyleAttr: ()=>isAngularStyleAttr, | ||
| getSafeText: ()=>getSafeText, | ||
| isSensitiveElement: ()=>isSensitiveElement, | ||
| shouldSkipDeadClick: ()=>shouldSkipDeadClick, | ||
| autocaptureCompatibleElements: ()=>autocaptureCompatibleElements, | ||
| makeSafeText: ()=>makeSafeText, | ||
| shouldCaptureDeadClick: ()=>shouldCaptureDeadClick, | ||
| getClassNames: ()=>getClassNames, | ||
| getDirectAndNestedSpanText: ()=>getDirectAndNestedSpanText, | ||
| getParentElement: ()=>getParentElement, | ||
| shouldCaptureElement: ()=>shouldCaptureElement, | ||
| MAX_DOM_ANCESTOR_DEPTH: ()=>MAX_DOM_ANCESTOR_DEPTH, | ||
| DEFAULT_CONTENT_IGNORELIST_WITH_STEPPERS: ()=>DEFAULT_CONTENT_IGNORELIST_WITH_STEPPERS, | ||
| getElementsChainString: ()=>getElementsChainString | ||
| }); | ||
| const external_general_utils_js_namespaceObject = require("./general-utils.js"); | ||
| const core_namespaceObject = require("@posthog/core"); | ||
| const external_logger_js_namespaceObject = require("./logger.js"); | ||
| const external_globals_js_namespaceObject = require("./globals.js"); | ||
| const external_url_targeting_utils_js_namespaceObject = require("./url-targeting-utils.js"); | ||
| const external_element_utils_js_namespaceObject = require("./element-utils.js"); | ||
| const MAX_DOM_ANCESTOR_DEPTH = 1000; | ||
| function splitClassString(s) { | ||
| return s ? (0, core_namespaceObject.trim)(s).split(/\s+/) : []; | ||
| } | ||
| function checkForURLMatches(urlsList, instance) { | ||
| const url = (0, external_url_targeting_utils_js_namespaceObject.getTargetingUrl)(instance); | ||
| return !!(url && urlsList && urlsList.some((regex)=>url.match(regex))); | ||
| } | ||
| function getClassNames(el) { | ||
| let className = ''; | ||
| switch(typeof el.className){ | ||
| case 'string': | ||
| className = el.className; | ||
| break; | ||
| case 'object': | ||
| className = (el.className && 'baseVal' in el.className ? el.className.baseVal : null) || el.getAttribute('class') || ''; | ||
| break; | ||
| default: | ||
| className = ''; | ||
| } | ||
| return splitClassString(className); | ||
| } | ||
| function makeSafeText(s) { | ||
| if ((0, core_namespaceObject.isNullish)(s)) return null; | ||
| return (0, core_namespaceObject.trim)(s).split(/(\s+)/).filter((s)=>shouldCaptureValue(s)).join('').replace(/[\r\n]/g, ' ').replace(/[ ]+/g, ' ').substring(0, 255); | ||
| } | ||
| function getSafeText(el) { | ||
| let elText = ''; | ||
| if (shouldCaptureElement(el) && !isSensitiveElement(el) && el.childNodes && el.childNodes.length) (0, external_general_utils_js_namespaceObject.each)(el.childNodes, function(child) { | ||
| if ((0, external_element_utils_js_namespaceObject.isTextNode)(child) && child.textContent) elText += makeSafeText(child.textContent) ?? ''; | ||
| }); | ||
| return (0, core_namespaceObject.trim)(elText); | ||
| } | ||
| function getEventTarget(e) { | ||
| if ((0, core_namespaceObject.isUndefined)(e.target)) return e.srcElement || null; | ||
| if (e.target?.shadowRoot) return e.composedPath()[0] || null; | ||
| return e.target || null; | ||
| } | ||
| const autocaptureCompatibleElements = [ | ||
| 'a', | ||
| 'button', | ||
| 'form', | ||
| 'input', | ||
| 'select', | ||
| 'textarea', | ||
| 'label' | ||
| ]; | ||
| function checkIfElementTreePassesElementAllowList(elements, autocaptureConfig) { | ||
| const allowlist = autocaptureConfig?.element_allowlist; | ||
| if ((0, core_namespaceObject.isUndefined)(allowlist)) return true; | ||
| for (const el of elements)if (allowlist.some((elementType)=>el.tagName.toLowerCase() === elementType)) return true; | ||
| return false; | ||
| } | ||
| function elementMatchesCSSSelector(el, selector) { | ||
| const matches = el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector; | ||
| try { | ||
| return matches ? matches.call(el, selector) : false; | ||
| } catch { | ||
| return false; | ||
| } | ||
| } | ||
| function checkIfElementsMatchCSSSelector(elements, selectorList) { | ||
| if ((0, core_namespaceObject.isUndefined)(selectorList)) return true; | ||
| for (const el of elements)if (selectorList.some((selector)=>elementMatchesCSSSelector(el, selector))) return true; | ||
| return false; | ||
| } | ||
| function getParentElement(curEl) { | ||
| const parentNode = curEl.parentNode; | ||
| if (!parentNode || !(0, external_element_utils_js_namespaceObject.isElementNode)(parentNode)) return false; | ||
| return parentNode; | ||
| } | ||
| const DEFAULT_AUTOCAPTURE_IGNORE_LIST = [ | ||
| '.ph-no-autocapture', | ||
| '[data-ph-no-autocapture]' | ||
| ]; | ||
| const DEFAULT_CONTENT_IGNORELIST = [ | ||
| 'next', | ||
| 'previous', | ||
| 'prev', | ||
| '>', | ||
| '<' | ||
| ]; | ||
| const DEFAULT_CONTENT_IGNORELIST_WITH_STEPPERS = [ | ||
| ...DEFAULT_CONTENT_IGNORELIST, | ||
| '+', | ||
| '-', | ||
| "\u2212", | ||
| "\u2013" | ||
| ]; | ||
| const MAX_CONTENT_IGNORELIST_ENTRIES = 10; | ||
| const matchesContentKeyword = (text, keyword)=>/[a-z0-9]/i.test(keyword) ? text.includes(keyword) : text === keyword; | ||
| function shouldIgnoreByContent(contentIgnorelist, elementsWithText) { | ||
| if (false === contentIgnorelist || (0, core_namespaceObject.isUndefined)(contentIgnorelist)) return false; | ||
| let keywords; | ||
| if (true === contentIgnorelist) keywords = DEFAULT_CONTENT_IGNORELIST; | ||
| else { | ||
| if (!(0, core_namespaceObject.isArray)(contentIgnorelist)) return false; | ||
| if (contentIgnorelist.length > MAX_CONTENT_IGNORELIST_ENTRIES) { | ||
| external_logger_js_namespaceObject.logger.error(`[PostHog] content_ignorelist array cannot exceed ${MAX_CONTENT_IGNORELIST_ENTRIES} items. Use css_selector_ignorelist for more complex matching.`); | ||
| return false; | ||
| } | ||
| keywords = contentIgnorelist.map((k)=>k.toLowerCase()); | ||
| } | ||
| return elementsWithText.some(({ safeText, ariaLabel })=>keywords.some((keyword)=>matchesContentKeyword(safeText, keyword) || matchesContentKeyword(ariaLabel, keyword))); | ||
| } | ||
| const DEFAULT_DEAD_CLICK_IGNORE_LIST = [ | ||
| '.ph-no-deadclick', | ||
| '.ph-no-capture' | ||
| ]; | ||
| function shouldCaptureDeadClick(el, _config) { | ||
| if (!external_globals_js_namespaceObject.window || cannotCheckForAutocapture(el)) return false; | ||
| const selectorIgnoreList = (0, core_namespaceObject.isBoolean)(_config) ? DEFAULT_DEAD_CLICK_IGNORE_LIST : _config?.css_selector_ignorelist ?? DEFAULT_DEAD_CLICK_IGNORE_LIST; | ||
| const { targetElementList } = getElementAndParentsForElement(el, false); | ||
| return !checkIfElementsMatchCSSSelector(targetElementList, selectorIgnoreList); | ||
| } | ||
| const DEFAULT_RAGE_CLICK_IGNORE_LIST = [ | ||
| '.ph-no-rageclick', | ||
| '.ph-no-capture' | ||
| ]; | ||
| const TEXT_SELECTION_INPUT_TYPES = [ | ||
| '', | ||
| 'text', | ||
| 'search', | ||
| 'email', | ||
| 'password', | ||
| 'url', | ||
| 'tel', | ||
| 'number' | ||
| ]; | ||
| function isContentEditableTarget(el) { | ||
| if (el.isContentEditable) return true; | ||
| const contentEditable = el.getAttribute?.('contenteditable'); | ||
| return 'true' === contentEditable || '' === contentEditable; | ||
| } | ||
| function isTextSelectionTarget(el) { | ||
| if (!el || !(0, external_element_utils_js_namespaceObject.isElementNode)(el)) return false; | ||
| if ((0, external_element_utils_js_namespaceObject.isTag)(el, 'textarea')) return true; | ||
| if ((0, external_element_utils_js_namespaceObject.isTag)(el, 'input')) return (0, core_namespaceObject.includes)(TEXT_SELECTION_INPUT_TYPES, (el.getAttribute('type') || '').toLowerCase()); | ||
| return isContentEditableTarget(el); | ||
| } | ||
| function shouldCaptureRageclick(el, _config) { | ||
| if (!external_globals_js_namespaceObject.window || cannotCheckForAutocapture(el)) return false; | ||
| let selectorIgnoreList; | ||
| let contentIgnorelist; | ||
| let ignoreTextSelection; | ||
| if ((0, core_namespaceObject.isBoolean)(_config)) { | ||
| selectorIgnoreList = _config ? DEFAULT_RAGE_CLICK_IGNORE_LIST : false; | ||
| contentIgnorelist = void 0; | ||
| ignoreTextSelection = false; | ||
| } else { | ||
| selectorIgnoreList = _config?.css_selector_ignorelist ?? DEFAULT_RAGE_CLICK_IGNORE_LIST; | ||
| contentIgnorelist = _config?.content_ignorelist; | ||
| ignoreTextSelection = _config?.ignore_text_selection ?? false; | ||
| } | ||
| if (false === selectorIgnoreList) return false; | ||
| if (ignoreTextSelection && isTextSelectionTarget(el)) return false; | ||
| const { targetElementList } = getElementAndParentsForElement(el, false); | ||
| const elementsWithText = targetElementList.map((element)=>({ | ||
| safeText: getSafeText(element).toLowerCase(), | ||
| ariaLabel: element.getAttribute('aria-label')?.toLowerCase().trim() || '' | ||
| })); | ||
| if (shouldIgnoreByContent(contentIgnorelist, elementsWithText)) return false; | ||
| return !checkIfElementsMatchCSSSelector(targetElementList, selectorIgnoreList); | ||
| } | ||
| const cannotCheckForAutocapture = (el)=>!el || (0, external_element_utils_js_namespaceObject.isTag)(el, 'html') || !(0, external_element_utils_js_namespaceObject.isElementNode)(el); | ||
| const getElementAndParentsForElement = (el, captureOnAnyElement)=>{ | ||
| if (!external_globals_js_namespaceObject.window || cannotCheckForAutocapture(el)) return { | ||
| parentIsUsefulElement: false, | ||
| targetElementList: [] | ||
| }; | ||
| let parentIsUsefulElement = false; | ||
| const targetElementList = [ | ||
| el | ||
| ]; | ||
| let curEl = el; | ||
| while(curEl.parentNode && !(0, external_element_utils_js_namespaceObject.isTag)(curEl, 'body')){ | ||
| if ((0, external_element_utils_js_namespaceObject.isShadowRoot)(curEl.parentNode)) { | ||
| targetElementList.push(curEl.parentNode.host); | ||
| curEl = curEl.parentNode.host; | ||
| continue; | ||
| } | ||
| const parentNode = getParentElement(curEl); | ||
| if (!parentNode) break; | ||
| if (captureOnAnyElement || autocaptureCompatibleElements.indexOf(parentNode.tagName.toLowerCase()) > -1) parentIsUsefulElement = true; | ||
| else try { | ||
| const compStyles = external_globals_js_namespaceObject.window.getComputedStyle(parentNode); | ||
| if (compStyles && 'pointer' === compStyles.getPropertyValue('cursor')) parentIsUsefulElement = true; | ||
| } catch {} | ||
| targetElementList.push(parentNode); | ||
| curEl = parentNode; | ||
| } | ||
| return { | ||
| parentIsUsefulElement, | ||
| targetElementList | ||
| }; | ||
| }; | ||
| function shouldSkipDeadClick(el) { | ||
| if (!external_globals_js_namespaceObject.window || cannotCheckForAutocapture(el)) return false; | ||
| const { targetElementList } = getElementAndParentsForElement(el, false); | ||
| return targetElementList.some((node)=>(0, external_element_utils_js_namespaceObject.isTag)(node, 'a')); | ||
| } | ||
| function shouldCaptureDomEvent(el, event, autocaptureConfig, captureOnAnyElement, allowedEventTypes, instance) { | ||
| if (!external_globals_js_namespaceObject.window || cannotCheckForAutocapture(el)) return false; | ||
| if (autocaptureConfig?.url_allowlist) { | ||
| if (!checkForURLMatches(autocaptureConfig.url_allowlist, instance)) return false; | ||
| } | ||
| if (autocaptureConfig?.url_ignorelist) { | ||
| if (checkForURLMatches(autocaptureConfig.url_ignorelist, instance)) return false; | ||
| } | ||
| if (autocaptureConfig?.dom_event_allowlist) { | ||
| const allowlist = autocaptureConfig.dom_event_allowlist; | ||
| if (allowlist && !allowlist.some((eventType)=>event.type === eventType)) return false; | ||
| } | ||
| const { parentIsUsefulElement, targetElementList } = getElementAndParentsForElement(el, captureOnAnyElement); | ||
| if (!checkIfElementTreePassesElementAllowList(targetElementList, autocaptureConfig)) return false; | ||
| if (!checkIfElementsMatchCSSSelector(targetElementList, autocaptureConfig?.css_selector_allowlist)) return false; | ||
| const selectorIgnoreList = autocaptureConfig?.css_selector_ignorelist ?? DEFAULT_AUTOCAPTURE_IGNORE_LIST; | ||
| if (checkIfElementsMatchCSSSelector(targetElementList, selectorIgnoreList)) return false; | ||
| try { | ||
| const compStyles = external_globals_js_namespaceObject.window.getComputedStyle(el); | ||
| if (compStyles && 'pointer' === compStyles.getPropertyValue('cursor') && 'click' === event.type) return true; | ||
| } catch {} | ||
| const tag = el.tagName.toLowerCase(); | ||
| switch(tag){ | ||
| case 'html': | ||
| return false; | ||
| case 'form': | ||
| return (allowedEventTypes || [ | ||
| 'submit' | ||
| ]).indexOf(event.type) >= 0; | ||
| case 'input': | ||
| case 'select': | ||
| case 'textarea': | ||
| return (allowedEventTypes || [ | ||
| 'change', | ||
| 'click' | ||
| ]).indexOf(event.type) >= 0; | ||
| default: | ||
| if (parentIsUsefulElement) return (allowedEventTypes || [ | ||
| 'click' | ||
| ]).indexOf(event.type) >= 0; | ||
| return (allowedEventTypes || [ | ||
| 'click' | ||
| ]).indexOf(event.type) >= 0 && (autocaptureCompatibleElements.indexOf(tag) > -1 || 'true' === el.getAttribute('contenteditable')); | ||
| } | ||
| } | ||
| function shouldCaptureElement(el) { | ||
| const seen = new Set(); | ||
| let depth = 0; | ||
| for(let curEl = el; curEl.parentNode && !(0, external_element_utils_js_namespaceObject.isTag)(curEl, 'body'); curEl = curEl.parentNode){ | ||
| if (depth++ >= MAX_DOM_ANCESTOR_DEPTH || seen.has(curEl)) return false; | ||
| seen.add(curEl); | ||
| const classes = getClassNames(curEl); | ||
| if ((0, core_namespaceObject.includes)(classes, 'ph-sensitive') || (0, core_namespaceObject.includes)(classes, 'ph-no-capture')) return false; | ||
| } | ||
| if ((0, core_namespaceObject.includes)(getClassNames(el), 'ph-include')) return true; | ||
| const type = el.type || ''; | ||
| if ((0, core_namespaceObject.isString)(type)) switch(type.toLowerCase()){ | ||
| case 'hidden': | ||
| return false; | ||
| case 'password': | ||
| return false; | ||
| } | ||
| const name = el.name || el.id || ''; | ||
| if ((0, core_namespaceObject.isString)(name)) { | ||
| const sensitiveNameRegex = /^cc|cardnum|ccnum|creditcard|csc|cvc|cvv|exp|pass|pwd|routing|seccode|securitycode|securitynum|socialsec|socsec|ssn/i; | ||
| if (sensitiveNameRegex.test(name.replace(/[^a-zA-Z0-9]/g, ''))) return false; | ||
| } | ||
| return true; | ||
| } | ||
| function isSensitiveElement(el) { | ||
| const allowedInputTypes = [ | ||
| 'button', | ||
| 'checkbox', | ||
| 'submit', | ||
| 'reset' | ||
| ]; | ||
| if ((0, external_element_utils_js_namespaceObject.isTag)(el, 'input') && !allowedInputTypes.includes(el.type) || (0, external_element_utils_js_namespaceObject.isTag)(el, 'select') || (0, external_element_utils_js_namespaceObject.isTag)(el, 'textarea') || 'true' === el.getAttribute('contenteditable')) return true; | ||
| return false; | ||
| } | ||
| const coreCCPattern = "(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11})"; | ||
| const anchoredCCRegex = new RegExp(`^(?:${coreCCPattern})$`); | ||
| const unanchoredCCRegex = new RegExp(coreCCPattern); | ||
| const coreSSNPattern = "\\d{3}-?\\d{2}-?\\d{4}"; | ||
| const anchoredSSNRegex = new RegExp(`^(${coreSSNPattern})$`); | ||
| const unanchoredSSNRegex = new RegExp(`(${coreSSNPattern})`); | ||
| function shouldCaptureValue(value, anchorRegexes = true) { | ||
| if ((0, core_namespaceObject.isNullish)(value)) return false; | ||
| if ((0, core_namespaceObject.isString)(value)) { | ||
| value = (0, core_namespaceObject.trim)(value); | ||
| const ccRegex = anchorRegexes ? anchoredCCRegex : unanchoredCCRegex; | ||
| if (ccRegex.test((value || '').replace(/[- ]/g, ''))) return false; | ||
| const ssnRegex = anchorRegexes ? anchoredSSNRegex : unanchoredSSNRegex; | ||
| if (ssnRegex.test(value)) return false; | ||
| } | ||
| return true; | ||
| } | ||
| function isAngularStyleAttr(attributeName) { | ||
| if ((0, core_namespaceObject.isString)(attributeName)) return '_ngcontent' === attributeName.substring(0, 10) || '_nghost' === attributeName.substring(0, 7); | ||
| return false; | ||
| } | ||
| function getDirectAndNestedSpanText(target) { | ||
| let text = getSafeText(target); | ||
| text = `${text} ${getNestedSpanText(target)}`.trim(); | ||
| return shouldCaptureValue(text) ? text : ''; | ||
| } | ||
| function getNestedSpanText(target) { | ||
| let text = ''; | ||
| if (target && target.childNodes && target.childNodes.length) (0, external_general_utils_js_namespaceObject.each)(target.childNodes, function(child) { | ||
| if (child && child.tagName?.toLowerCase() === 'span') try { | ||
| const spanText = getSafeText(child); | ||
| text = `${text} ${spanText}`.trim(); | ||
| if (child.childNodes && child.childNodes.length) text = `${text} ${getNestedSpanText(child)}`.trim(); | ||
| } catch (e) { | ||
| external_logger_js_namespaceObject.logger.error('[AutoCapture]', e); | ||
| } | ||
| }); | ||
| return text; | ||
| } | ||
| function getElementsChainString(elements) { | ||
| return elementsToString(extractElements(elements)); | ||
| } | ||
| function escapeQuotes(input) { | ||
| return input.replace(/"|\\"/g, '\\"'); | ||
| } | ||
| function elementsToString(elements) { | ||
| const ret = elements.map((element)=>{ | ||
| let el_string = ''; | ||
| if (element.tag_name) el_string += element.tag_name; | ||
| if (element.attr_class) { | ||
| element.attr_class.sort(); | ||
| for (const single_class of element.attr_class)el_string += `.${single_class.replace(/"/g, '')}`; | ||
| } | ||
| const attributes = { | ||
| ...element.text ? { | ||
| text: element.text | ||
| } : {}, | ||
| 'nth-child': element.nth_child ?? 0, | ||
| 'nth-of-type': element.nth_of_type ?? 0, | ||
| ...element.href ? { | ||
| href: element.href | ||
| } : {}, | ||
| ...element.attr_id ? { | ||
| attr_id: element.attr_id | ||
| } : {}, | ||
| ...element.attributes | ||
| }; | ||
| const sortedAttributes = {}; | ||
| (0, external_general_utils_js_namespaceObject.entries)(attributes).sort(([a], [b])=>a.localeCompare(b)).forEach(([key, value])=>sortedAttributes[escapeQuotes(key.toString())] = escapeQuotes(value.toString())); | ||
| el_string += ':'; | ||
| el_string += (0, external_general_utils_js_namespaceObject.entries)(sortedAttributes).map(([key, value])=>`${key}="${value}"`).join(''); | ||
| return el_string; | ||
| }); | ||
| return ret.join(';'); | ||
| } | ||
| function extractElements(elements) { | ||
| return elements.map((el)=>{ | ||
| const attributes = {}; | ||
| const response = { | ||
| text: el['$el_text']?.slice(0, 400), | ||
| tag_name: el['tag_name'], | ||
| href: el['attr__href']?.slice(0, 2048), | ||
| attr_class: extractAttrClass(el), | ||
| attr_id: el['attr__id'], | ||
| nth_child: el['nth_child'], | ||
| nth_of_type: el['nth_of_type'], | ||
| attributes | ||
| }; | ||
| (0, external_general_utils_js_namespaceObject.entries)(el).filter(([key])=>0 === key.indexOf('attr__')).forEach(([key, value])=>response.attributes[key] = value); | ||
| return response; | ||
| }); | ||
| } | ||
| function extractAttrClass(el) { | ||
| const attr_class = el['attr__class']; | ||
| if (!attr_class) return; | ||
| if ((0, core_namespaceObject.isArray)(attr_class)) return attr_class; | ||
| return splitClassString(attr_class); | ||
| } | ||
| exports.DEFAULT_CONTENT_IGNORELIST_WITH_STEPPERS = __webpack_exports__.DEFAULT_CONTENT_IGNORELIST_WITH_STEPPERS; | ||
| exports.MAX_DOM_ANCESTOR_DEPTH = __webpack_exports__.MAX_DOM_ANCESTOR_DEPTH; | ||
| exports.autocaptureCompatibleElements = __webpack_exports__.autocaptureCompatibleElements; | ||
| exports.getClassNames = __webpack_exports__.getClassNames; | ||
| exports.getDirectAndNestedSpanText = __webpack_exports__.getDirectAndNestedSpanText; | ||
| exports.getElementsChainString = __webpack_exports__.getElementsChainString; | ||
| exports.getEventTarget = __webpack_exports__.getEventTarget; | ||
| exports.getNestedSpanText = __webpack_exports__.getNestedSpanText; | ||
| exports.getParentElement = __webpack_exports__.getParentElement; | ||
| exports.getSafeText = __webpack_exports__.getSafeText; | ||
| exports.isAngularStyleAttr = __webpack_exports__.isAngularStyleAttr; | ||
| exports.isSensitiveElement = __webpack_exports__.isSensitiveElement; | ||
| exports.isTextSelectionTarget = __webpack_exports__.isTextSelectionTarget; | ||
| exports.makeSafeText = __webpack_exports__.makeSafeText; | ||
| exports.shouldCaptureDeadClick = __webpack_exports__.shouldCaptureDeadClick; | ||
| exports.shouldCaptureDomEvent = __webpack_exports__.shouldCaptureDomEvent; | ||
| exports.shouldCaptureElement = __webpack_exports__.shouldCaptureElement; | ||
| exports.shouldCaptureRageclick = __webpack_exports__.shouldCaptureRageclick; | ||
| exports.shouldCaptureValue = __webpack_exports__.shouldCaptureValue; | ||
| exports.shouldSkipDeadClick = __webpack_exports__.shouldSkipDeadClick; | ||
| exports.splitClassString = __webpack_exports__.splitClassString; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "DEFAULT_CONTENT_IGNORELIST_WITH_STEPPERS", | ||
| "MAX_DOM_ANCESTOR_DEPTH", | ||
| "autocaptureCompatibleElements", | ||
| "getClassNames", | ||
| "getDirectAndNestedSpanText", | ||
| "getElementsChainString", | ||
| "getEventTarget", | ||
| "getNestedSpanText", | ||
| "getParentElement", | ||
| "getSafeText", | ||
| "isAngularStyleAttr", | ||
| "isSensitiveElement", | ||
| "isTextSelectionTarget", | ||
| "makeSafeText", | ||
| "shouldCaptureDeadClick", | ||
| "shouldCaptureDomEvent", | ||
| "shouldCaptureElement", | ||
| "shouldCaptureRageclick", | ||
| "shouldCaptureValue", | ||
| "shouldSkipDeadClick", | ||
| "splitClassString" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| import { each, entries } from "./general-utils.mjs"; | ||
| import { includes, isArray, isBoolean, isNullish, isString, isUndefined, trim } from "@posthog/core"; | ||
| import { logger } from "./logger.mjs"; | ||
| import { window as external_globals_mjs_window } from "./globals.mjs"; | ||
| import { getTargetingUrl } from "./url-targeting-utils.mjs"; | ||
| import { isElementNode, isShadowRoot, isTag, isTextNode } from "./element-utils.mjs"; | ||
| const MAX_DOM_ANCESTOR_DEPTH = 1000; | ||
| function splitClassString(s) { | ||
| return s ? trim(s).split(/\s+/) : []; | ||
| } | ||
| function checkForURLMatches(urlsList, instance) { | ||
| const url = getTargetingUrl(instance); | ||
| return !!(url && urlsList && urlsList.some((regex)=>url.match(regex))); | ||
| } | ||
| function getClassNames(el) { | ||
| let className = ''; | ||
| switch(typeof el.className){ | ||
| case 'string': | ||
| className = el.className; | ||
| break; | ||
| case 'object': | ||
| className = (el.className && 'baseVal' in el.className ? el.className.baseVal : null) || el.getAttribute('class') || ''; | ||
| break; | ||
| default: | ||
| className = ''; | ||
| } | ||
| return splitClassString(className); | ||
| } | ||
| function makeSafeText(s) { | ||
| if (isNullish(s)) return null; | ||
| return trim(s).split(/(\s+)/).filter((s)=>shouldCaptureValue(s)).join('').replace(/[\r\n]/g, ' ').replace(/[ ]+/g, ' ').substring(0, 255); | ||
| } | ||
| function getSafeText(el) { | ||
| let elText = ''; | ||
| if (shouldCaptureElement(el) && !isSensitiveElement(el) && el.childNodes && el.childNodes.length) each(el.childNodes, function(child) { | ||
| if (isTextNode(child) && child.textContent) elText += makeSafeText(child.textContent) ?? ''; | ||
| }); | ||
| return trim(elText); | ||
| } | ||
| function getEventTarget(e) { | ||
| if (isUndefined(e.target)) return e.srcElement || null; | ||
| if (e.target?.shadowRoot) return e.composedPath()[0] || null; | ||
| return e.target || null; | ||
| } | ||
| const autocaptureCompatibleElements = [ | ||
| 'a', | ||
| 'button', | ||
| 'form', | ||
| 'input', | ||
| 'select', | ||
| 'textarea', | ||
| 'label' | ||
| ]; | ||
| function checkIfElementTreePassesElementAllowList(elements, autocaptureConfig) { | ||
| const allowlist = autocaptureConfig?.element_allowlist; | ||
| if (isUndefined(allowlist)) return true; | ||
| for (const el of elements)if (allowlist.some((elementType)=>el.tagName.toLowerCase() === elementType)) return true; | ||
| return false; | ||
| } | ||
| function elementMatchesCSSSelector(el, selector) { | ||
| const matches = el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector; | ||
| try { | ||
| return matches ? matches.call(el, selector) : false; | ||
| } catch { | ||
| return false; | ||
| } | ||
| } | ||
| function checkIfElementsMatchCSSSelector(elements, selectorList) { | ||
| if (isUndefined(selectorList)) return true; | ||
| for (const el of elements)if (selectorList.some((selector)=>elementMatchesCSSSelector(el, selector))) return true; | ||
| return false; | ||
| } | ||
| function getParentElement(curEl) { | ||
| const parentNode = curEl.parentNode; | ||
| if (!parentNode || !isElementNode(parentNode)) return false; | ||
| return parentNode; | ||
| } | ||
| const DEFAULT_AUTOCAPTURE_IGNORE_LIST = [ | ||
| '.ph-no-autocapture', | ||
| '[data-ph-no-autocapture]' | ||
| ]; | ||
| const DEFAULT_CONTENT_IGNORELIST = [ | ||
| 'next', | ||
| 'previous', | ||
| 'prev', | ||
| '>', | ||
| '<' | ||
| ]; | ||
| const DEFAULT_CONTENT_IGNORELIST_WITH_STEPPERS = [ | ||
| ...DEFAULT_CONTENT_IGNORELIST, | ||
| '+', | ||
| '-', | ||
| "\u2212", | ||
| "\u2013" | ||
| ]; | ||
| const MAX_CONTENT_IGNORELIST_ENTRIES = 10; | ||
| const matchesContentKeyword = (text, keyword)=>/[a-z0-9]/i.test(keyword) ? text.includes(keyword) : text === keyword; | ||
| function shouldIgnoreByContent(contentIgnorelist, elementsWithText) { | ||
| if (false === contentIgnorelist || isUndefined(contentIgnorelist)) return false; | ||
| let keywords; | ||
| if (true === contentIgnorelist) keywords = DEFAULT_CONTENT_IGNORELIST; | ||
| else { | ||
| if (!isArray(contentIgnorelist)) return false; | ||
| if (contentIgnorelist.length > MAX_CONTENT_IGNORELIST_ENTRIES) { | ||
| logger.error(`[PostHog] content_ignorelist array cannot exceed ${MAX_CONTENT_IGNORELIST_ENTRIES} items. Use css_selector_ignorelist for more complex matching.`); | ||
| return false; | ||
| } | ||
| keywords = contentIgnorelist.map((k)=>k.toLowerCase()); | ||
| } | ||
| return elementsWithText.some(({ safeText, ariaLabel })=>keywords.some((keyword)=>matchesContentKeyword(safeText, keyword) || matchesContentKeyword(ariaLabel, keyword))); | ||
| } | ||
| const DEFAULT_DEAD_CLICK_IGNORE_LIST = [ | ||
| '.ph-no-deadclick', | ||
| '.ph-no-capture' | ||
| ]; | ||
| function shouldCaptureDeadClick(el, _config) { | ||
| if (!external_globals_mjs_window || cannotCheckForAutocapture(el)) return false; | ||
| const selectorIgnoreList = isBoolean(_config) ? DEFAULT_DEAD_CLICK_IGNORE_LIST : _config?.css_selector_ignorelist ?? DEFAULT_DEAD_CLICK_IGNORE_LIST; | ||
| const { targetElementList } = getElementAndParentsForElement(el, false); | ||
| return !checkIfElementsMatchCSSSelector(targetElementList, selectorIgnoreList); | ||
| } | ||
| const DEFAULT_RAGE_CLICK_IGNORE_LIST = [ | ||
| '.ph-no-rageclick', | ||
| '.ph-no-capture' | ||
| ]; | ||
| const TEXT_SELECTION_INPUT_TYPES = [ | ||
| '', | ||
| 'text', | ||
| 'search', | ||
| 'email', | ||
| 'password', | ||
| 'url', | ||
| 'tel', | ||
| 'number' | ||
| ]; | ||
| function isContentEditableTarget(el) { | ||
| if (el.isContentEditable) return true; | ||
| const contentEditable = el.getAttribute?.('contenteditable'); | ||
| return 'true' === contentEditable || '' === contentEditable; | ||
| } | ||
| function isTextSelectionTarget(el) { | ||
| if (!el || !isElementNode(el)) return false; | ||
| if (isTag(el, 'textarea')) return true; | ||
| if (isTag(el, 'input')) return includes(TEXT_SELECTION_INPUT_TYPES, (el.getAttribute('type') || '').toLowerCase()); | ||
| return isContentEditableTarget(el); | ||
| } | ||
| function shouldCaptureRageclick(el, _config) { | ||
| if (!external_globals_mjs_window || cannotCheckForAutocapture(el)) return false; | ||
| let selectorIgnoreList; | ||
| let contentIgnorelist; | ||
| let ignoreTextSelection; | ||
| if (isBoolean(_config)) { | ||
| selectorIgnoreList = _config ? DEFAULT_RAGE_CLICK_IGNORE_LIST : false; | ||
| contentIgnorelist = void 0; | ||
| ignoreTextSelection = false; | ||
| } else { | ||
| selectorIgnoreList = _config?.css_selector_ignorelist ?? DEFAULT_RAGE_CLICK_IGNORE_LIST; | ||
| contentIgnorelist = _config?.content_ignorelist; | ||
| ignoreTextSelection = _config?.ignore_text_selection ?? false; | ||
| } | ||
| if (false === selectorIgnoreList) return false; | ||
| if (ignoreTextSelection && isTextSelectionTarget(el)) return false; | ||
| const { targetElementList } = getElementAndParentsForElement(el, false); | ||
| const elementsWithText = targetElementList.map((element)=>({ | ||
| safeText: getSafeText(element).toLowerCase(), | ||
| ariaLabel: element.getAttribute('aria-label')?.toLowerCase().trim() || '' | ||
| })); | ||
| if (shouldIgnoreByContent(contentIgnorelist, elementsWithText)) return false; | ||
| return !checkIfElementsMatchCSSSelector(targetElementList, selectorIgnoreList); | ||
| } | ||
| const cannotCheckForAutocapture = (el)=>!el || isTag(el, 'html') || !isElementNode(el); | ||
| const getElementAndParentsForElement = (el, captureOnAnyElement)=>{ | ||
| if (!external_globals_mjs_window || cannotCheckForAutocapture(el)) return { | ||
| parentIsUsefulElement: false, | ||
| targetElementList: [] | ||
| }; | ||
| let parentIsUsefulElement = false; | ||
| const targetElementList = [ | ||
| el | ||
| ]; | ||
| let curEl = el; | ||
| while(curEl.parentNode && !isTag(curEl, 'body')){ | ||
| if (isShadowRoot(curEl.parentNode)) { | ||
| targetElementList.push(curEl.parentNode.host); | ||
| curEl = curEl.parentNode.host; | ||
| continue; | ||
| } | ||
| const parentNode = getParentElement(curEl); | ||
| if (!parentNode) break; | ||
| if (captureOnAnyElement || autocaptureCompatibleElements.indexOf(parentNode.tagName.toLowerCase()) > -1) parentIsUsefulElement = true; | ||
| else try { | ||
| const compStyles = external_globals_mjs_window.getComputedStyle(parentNode); | ||
| if (compStyles && 'pointer' === compStyles.getPropertyValue('cursor')) parentIsUsefulElement = true; | ||
| } catch {} | ||
| targetElementList.push(parentNode); | ||
| curEl = parentNode; | ||
| } | ||
| return { | ||
| parentIsUsefulElement, | ||
| targetElementList | ||
| }; | ||
| }; | ||
| function shouldSkipDeadClick(el) { | ||
| if (!external_globals_mjs_window || cannotCheckForAutocapture(el)) return false; | ||
| const { targetElementList } = getElementAndParentsForElement(el, false); | ||
| return targetElementList.some((node)=>isTag(node, 'a')); | ||
| } | ||
| function shouldCaptureDomEvent(el, event, autocaptureConfig, captureOnAnyElement, allowedEventTypes, instance) { | ||
| if (!external_globals_mjs_window || cannotCheckForAutocapture(el)) return false; | ||
| if (autocaptureConfig?.url_allowlist) { | ||
| if (!checkForURLMatches(autocaptureConfig.url_allowlist, instance)) return false; | ||
| } | ||
| if (autocaptureConfig?.url_ignorelist) { | ||
| if (checkForURLMatches(autocaptureConfig.url_ignorelist, instance)) return false; | ||
| } | ||
| if (autocaptureConfig?.dom_event_allowlist) { | ||
| const allowlist = autocaptureConfig.dom_event_allowlist; | ||
| if (allowlist && !allowlist.some((eventType)=>event.type === eventType)) return false; | ||
| } | ||
| const { parentIsUsefulElement, targetElementList } = getElementAndParentsForElement(el, captureOnAnyElement); | ||
| if (!checkIfElementTreePassesElementAllowList(targetElementList, autocaptureConfig)) return false; | ||
| if (!checkIfElementsMatchCSSSelector(targetElementList, autocaptureConfig?.css_selector_allowlist)) return false; | ||
| const selectorIgnoreList = autocaptureConfig?.css_selector_ignorelist ?? DEFAULT_AUTOCAPTURE_IGNORE_LIST; | ||
| if (checkIfElementsMatchCSSSelector(targetElementList, selectorIgnoreList)) return false; | ||
| try { | ||
| const compStyles = external_globals_mjs_window.getComputedStyle(el); | ||
| if (compStyles && 'pointer' === compStyles.getPropertyValue('cursor') && 'click' === event.type) return true; | ||
| } catch {} | ||
| const tag = el.tagName.toLowerCase(); | ||
| switch(tag){ | ||
| case 'html': | ||
| return false; | ||
| case 'form': | ||
| return (allowedEventTypes || [ | ||
| 'submit' | ||
| ]).indexOf(event.type) >= 0; | ||
| case 'input': | ||
| case 'select': | ||
| case 'textarea': | ||
| return (allowedEventTypes || [ | ||
| 'change', | ||
| 'click' | ||
| ]).indexOf(event.type) >= 0; | ||
| default: | ||
| if (parentIsUsefulElement) return (allowedEventTypes || [ | ||
| 'click' | ||
| ]).indexOf(event.type) >= 0; | ||
| return (allowedEventTypes || [ | ||
| 'click' | ||
| ]).indexOf(event.type) >= 0 && (autocaptureCompatibleElements.indexOf(tag) > -1 || 'true' === el.getAttribute('contenteditable')); | ||
| } | ||
| } | ||
| function shouldCaptureElement(el) { | ||
| const seen = new Set(); | ||
| let depth = 0; | ||
| for(let curEl = el; curEl.parentNode && !isTag(curEl, 'body'); curEl = curEl.parentNode){ | ||
| if (depth++ >= MAX_DOM_ANCESTOR_DEPTH || seen.has(curEl)) return false; | ||
| seen.add(curEl); | ||
| const classes = getClassNames(curEl); | ||
| if (includes(classes, 'ph-sensitive') || includes(classes, 'ph-no-capture')) return false; | ||
| } | ||
| if (includes(getClassNames(el), 'ph-include')) return true; | ||
| const type = el.type || ''; | ||
| if (isString(type)) switch(type.toLowerCase()){ | ||
| case 'hidden': | ||
| return false; | ||
| case 'password': | ||
| return false; | ||
| } | ||
| const name = el.name || el.id || ''; | ||
| if (isString(name)) { | ||
| const sensitiveNameRegex = /^cc|cardnum|ccnum|creditcard|csc|cvc|cvv|exp|pass|pwd|routing|seccode|securitycode|securitynum|socialsec|socsec|ssn/i; | ||
| if (sensitiveNameRegex.test(name.replace(/[^a-zA-Z0-9]/g, ''))) return false; | ||
| } | ||
| return true; | ||
| } | ||
| function isSensitiveElement(el) { | ||
| const allowedInputTypes = [ | ||
| 'button', | ||
| 'checkbox', | ||
| 'submit', | ||
| 'reset' | ||
| ]; | ||
| if (isTag(el, 'input') && !allowedInputTypes.includes(el.type) || isTag(el, 'select') || isTag(el, 'textarea') || 'true' === el.getAttribute('contenteditable')) return true; | ||
| return false; | ||
| } | ||
| const coreCCPattern = "(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11})"; | ||
| const anchoredCCRegex = new RegExp(`^(?:${coreCCPattern})$`); | ||
| const unanchoredCCRegex = new RegExp(coreCCPattern); | ||
| const coreSSNPattern = "\\d{3}-?\\d{2}-?\\d{4}"; | ||
| const anchoredSSNRegex = new RegExp(`^(${coreSSNPattern})$`); | ||
| const unanchoredSSNRegex = new RegExp(`(${coreSSNPattern})`); | ||
| function shouldCaptureValue(value, anchorRegexes = true) { | ||
| if (isNullish(value)) return false; | ||
| if (isString(value)) { | ||
| value = trim(value); | ||
| const ccRegex = anchorRegexes ? anchoredCCRegex : unanchoredCCRegex; | ||
| if (ccRegex.test((value || '').replace(/[- ]/g, ''))) return false; | ||
| const ssnRegex = anchorRegexes ? anchoredSSNRegex : unanchoredSSNRegex; | ||
| if (ssnRegex.test(value)) return false; | ||
| } | ||
| return true; | ||
| } | ||
| function isAngularStyleAttr(attributeName) { | ||
| if (isString(attributeName)) return '_ngcontent' === attributeName.substring(0, 10) || '_nghost' === attributeName.substring(0, 7); | ||
| return false; | ||
| } | ||
| function getDirectAndNestedSpanText(target) { | ||
| let text = getSafeText(target); | ||
| text = `${text} ${getNestedSpanText(target)}`.trim(); | ||
| return shouldCaptureValue(text) ? text : ''; | ||
| } | ||
| function getNestedSpanText(target) { | ||
| let text = ''; | ||
| if (target && target.childNodes && target.childNodes.length) each(target.childNodes, function(child) { | ||
| if (child && child.tagName?.toLowerCase() === 'span') try { | ||
| const spanText = getSafeText(child); | ||
| text = `${text} ${spanText}`.trim(); | ||
| if (child.childNodes && child.childNodes.length) text = `${text} ${getNestedSpanText(child)}`.trim(); | ||
| } catch (e) { | ||
| logger.error('[AutoCapture]', e); | ||
| } | ||
| }); | ||
| return text; | ||
| } | ||
| function getElementsChainString(elements) { | ||
| return elementsToString(extractElements(elements)); | ||
| } | ||
| function escapeQuotes(input) { | ||
| return input.replace(/"|\\"/g, '\\"'); | ||
| } | ||
| function elementsToString(elements) { | ||
| const ret = elements.map((element)=>{ | ||
| let el_string = ''; | ||
| if (element.tag_name) el_string += element.tag_name; | ||
| if (element.attr_class) { | ||
| element.attr_class.sort(); | ||
| for (const single_class of element.attr_class)el_string += `.${single_class.replace(/"/g, '')}`; | ||
| } | ||
| const attributes = { | ||
| ...element.text ? { | ||
| text: element.text | ||
| } : {}, | ||
| 'nth-child': element.nth_child ?? 0, | ||
| 'nth-of-type': element.nth_of_type ?? 0, | ||
| ...element.href ? { | ||
| href: element.href | ||
| } : {}, | ||
| ...element.attr_id ? { | ||
| attr_id: element.attr_id | ||
| } : {}, | ||
| ...element.attributes | ||
| }; | ||
| const sortedAttributes = {}; | ||
| entries(attributes).sort(([a], [b])=>a.localeCompare(b)).forEach(([key, value])=>sortedAttributes[escapeQuotes(key.toString())] = escapeQuotes(value.toString())); | ||
| el_string += ':'; | ||
| el_string += entries(sortedAttributes).map(([key, value])=>`${key}="${value}"`).join(''); | ||
| return el_string; | ||
| }); | ||
| return ret.join(';'); | ||
| } | ||
| function extractElements(elements) { | ||
| return elements.map((el)=>{ | ||
| const attributes = {}; | ||
| const response = { | ||
| text: el['$el_text']?.slice(0, 400), | ||
| tag_name: el['tag_name'], | ||
| href: el['attr__href']?.slice(0, 2048), | ||
| attr_class: extractAttrClass(el), | ||
| attr_id: el['attr__id'], | ||
| nth_child: el['nth_child'], | ||
| nth_of_type: el['nth_of_type'], | ||
| attributes | ||
| }; | ||
| entries(el).filter(([key])=>0 === key.indexOf('attr__')).forEach(([key, value])=>response.attributes[key] = value); | ||
| return response; | ||
| }); | ||
| } | ||
| function extractAttrClass(el) { | ||
| const attr_class = el['attr__class']; | ||
| if (!attr_class) return; | ||
| if (isArray(attr_class)) return attr_class; | ||
| return splitClassString(attr_class); | ||
| } | ||
| export { DEFAULT_CONTENT_IGNORELIST_WITH_STEPPERS, MAX_DOM_ANCESTOR_DEPTH, autocaptureCompatibleElements, getClassNames, getDirectAndNestedSpanText, getElementsChainString, getEventTarget, getNestedSpanText, getParentElement, getSafeText, isAngularStyleAttr, isSensitiveElement, isTextSelectionTarget, makeSafeText, shouldCaptureDeadClick, shouldCaptureDomEvent, shouldCaptureElement, shouldCaptureRageclick, shouldCaptureValue, shouldSkipDeadClick, splitClassString }; |
| export { DEFAULT_BLOCKED_UA_STRS, isBlockedUA } from '@posthog/core'; | ||
| export interface NavigatorUAData { | ||
| brands?: { | ||
| brand: string; | ||
| version: string; | ||
| }[]; | ||
| platform?: string; | ||
| getHighEntropyValues?: (hints: string[]) => Promise<{ | ||
| model?: string; | ||
| }>; | ||
| } | ||
| declare global { | ||
| interface Navigator { | ||
| userAgentData?: NavigatorUAData; | ||
| } | ||
| } | ||
| export declare const isLikelyBot: (navigator: Navigator | undefined, customBlockedUserAgents: string[]) => boolean; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| DEFAULT_BLOCKED_UA_STRS: ()=>core_namespaceObject.DEFAULT_BLOCKED_UA_STRS, | ||
| isBlockedUA: ()=>core_namespaceObject.isBlockedUA, | ||
| isLikelyBot: ()=>isLikelyBot | ||
| }); | ||
| const core_namespaceObject = require("@posthog/core"); | ||
| const isLikelyBot = function(navigator, customBlockedUserAgents) { | ||
| if (!navigator) return false; | ||
| const ua = navigator.userAgent; | ||
| if (ua) { | ||
| if ((0, core_namespaceObject.isBlockedUA)(ua, customBlockedUserAgents)) return true; | ||
| } | ||
| try { | ||
| const uaData = navigator?.userAgentData; | ||
| if (uaData?.brands && uaData.brands.some((brandObj)=>(0, core_namespaceObject.isBlockedUA)(brandObj?.brand, customBlockedUserAgents))) return true; | ||
| } catch {} | ||
| return !!navigator.webdriver; | ||
| }; | ||
| exports.DEFAULT_BLOCKED_UA_STRS = __webpack_exports__.DEFAULT_BLOCKED_UA_STRS; | ||
| exports.isBlockedUA = __webpack_exports__.isBlockedUA; | ||
| exports.isLikelyBot = __webpack_exports__.isLikelyBot; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "DEFAULT_BLOCKED_UA_STRS", | ||
| "isBlockedUA", | ||
| "isLikelyBot" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| import { DEFAULT_BLOCKED_UA_STRS, isBlockedUA } from "@posthog/core"; | ||
| const isLikelyBot = function(navigator, customBlockedUserAgents) { | ||
| if (!navigator) return false; | ||
| const ua = navigator.userAgent; | ||
| if (ua) { | ||
| if (isBlockedUA(ua, customBlockedUserAgents)) return true; | ||
| } | ||
| try { | ||
| const uaData = navigator?.userAgentData; | ||
| if (uaData?.brands && uaData.brands.some((brandObj)=>isBlockedUA(brandObj?.brand, customBlockedUserAgents))) return true; | ||
| } catch {} | ||
| return !!navigator.webdriver; | ||
| }; | ||
| export { DEFAULT_BLOCKED_UA_STRS, isBlockedUA, isLikelyBot }; |
| export declare const getCookieValue: (name: string) => string | null | undefined; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| getCookieValue: ()=>getCookieValue | ||
| }); | ||
| const external_globals_js_namespaceObject = require("./globals.js"); | ||
| const getCookieValue = (name)=>{ | ||
| if (!external_globals_js_namespaceObject.document) return; | ||
| try { | ||
| const nameEQ = name + '='; | ||
| const cookies = external_globals_js_namespaceObject.document.cookie.split(';').filter((cookie)=>cookie.length); | ||
| for(let i = 0; i < cookies.length; i++){ | ||
| let cookie = cookies[i]; | ||
| while(' ' == cookie.charAt(0))cookie = cookie.substring(1, cookie.length); | ||
| if (0 === cookie.indexOf(nameEQ)) return decodeURIComponent(cookie.substring(nameEQ.length, cookie.length)); | ||
| } | ||
| } catch {} | ||
| return null; | ||
| }; | ||
| exports.getCookieValue = __webpack_exports__.getCookieValue; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "getCookieValue" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| import { document as external_globals_mjs_document } from "./globals.mjs"; | ||
| const getCookieValue = (name)=>{ | ||
| if (!external_globals_mjs_document) return; | ||
| try { | ||
| const nameEQ = name + '='; | ||
| const cookies = external_globals_mjs_document.cookie.split(';').filter((cookie)=>cookie.length); | ||
| for(let i = 0; i < cookies.length; i++){ | ||
| let cookie = cookies[i]; | ||
| while(' ' == cookie.charAt(0))cookie = cookie.substring(1, cookie.length); | ||
| if (0 === cookie.indexOf(nameEQ)) return decodeURIComponent(cookie.substring(nameEQ.length, cookie.length)); | ||
| } | ||
| } catch {} | ||
| return null; | ||
| }; | ||
| export { getCookieValue }; |
| /** | ||
| * Reads the hardware model from `navigator.userAgentData.getHighEntropyValues(['model'])`. | ||
| * | ||
| * Only meaningful on Android Chromium — `undefined` on Safari/Firefox and an empty string on desktop | ||
| * (both treated as absent). A Permissions-Policy block rejects with `NotAllowedError`, which we catch | ||
| * and return `undefined`. | ||
| */ | ||
| export declare function getDeviceModel(): Promise<string | undefined>; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| getDeviceModel: ()=>getDeviceModel | ||
| }); | ||
| const core_namespaceObject = require("@posthog/core"); | ||
| const external_globals_js_namespaceObject = require("./globals.js"); | ||
| const external_logger_js_namespaceObject = require("./logger.js"); | ||
| async function getDeviceModel() { | ||
| const uaData = external_globals_js_namespaceObject.navigator?.userAgentData; | ||
| if (!uaData?.getHighEntropyValues) return; | ||
| try { | ||
| const hints = await uaData.getHighEntropyValues([ | ||
| 'model' | ||
| ]); | ||
| const model = hints?.model; | ||
| return (0, core_namespaceObject.isString)(model) && model.length > 0 ? model : void 0; | ||
| } catch (e) { | ||
| external_logger_js_namespaceObject.logger.info('Unable to resolve $device_model from userAgentData.getHighEntropyValues', e); | ||
| return; | ||
| } | ||
| } | ||
| exports.getDeviceModel = __webpack_exports__.getDeviceModel; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "getDeviceModel" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| import { isString } from "@posthog/core"; | ||
| import { navigator as external_globals_mjs_navigator } from "./globals.mjs"; | ||
| import { logger } from "./logger.mjs"; | ||
| async function getDeviceModel() { | ||
| const uaData = external_globals_mjs_navigator?.userAgentData; | ||
| if (!uaData?.getHighEntropyValues) return; | ||
| try { | ||
| const hints = await uaData.getHighEntropyValues([ | ||
| 'model' | ||
| ]); | ||
| const model = hints?.model; | ||
| return isString(model) && model.length > 0 ? model : void 0; | ||
| } catch (e) { | ||
| logger.info('Unable to resolve $device_model from userAgentData.getHighEntropyValues', e); | ||
| return; | ||
| } | ||
| } | ||
| export { getDeviceModel }; |
| export declare function isElementInToolbar(el: EventTarget | null): boolean; | ||
| export declare function isElementNode(el: Node | Element | undefined | null): el is Element; | ||
| export declare function isTag(el: Element | undefined | null, tag: string): el is HTMLElement; | ||
| export declare function isTextNode(el: Element | undefined | null): el is HTMLElement; | ||
| export declare function isShadowRoot(el: Node | ParentNode | undefined | null): el is ShadowRoot; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| isTag: ()=>isTag, | ||
| isElementInToolbar: ()=>isElementInToolbar, | ||
| isShadowRoot: ()=>isShadowRoot, | ||
| isTextNode: ()=>isTextNode, | ||
| isElementNode: ()=>isElementNode | ||
| }); | ||
| const external_constants_js_namespaceObject = require("../constants.js"); | ||
| const NODE_TYPE_ELEMENT = 1; | ||
| const NODE_TYPE_TEXT = 3; | ||
| const NODE_TYPE_DOCUMENT_FRAGMENT = 11; | ||
| function isElementInToolbar(el) { | ||
| if (el instanceof Element) return el.id === external_constants_js_namespaceObject.TOOLBAR_ID || !!el.closest?.('.' + external_constants_js_namespaceObject.TOOLBAR_CONTAINER_CLASS); | ||
| return false; | ||
| } | ||
| function isElementNode(el) { | ||
| return !!el && el.nodeType === NODE_TYPE_ELEMENT; | ||
| } | ||
| function isTag(el, tag) { | ||
| return !!el && !!el.tagName && el.tagName.toLowerCase() === tag.toLowerCase(); | ||
| } | ||
| function isTextNode(el) { | ||
| return !!el && el.nodeType === NODE_TYPE_TEXT; | ||
| } | ||
| function isShadowRoot(el) { | ||
| return !!el && el.nodeType === NODE_TYPE_DOCUMENT_FRAGMENT && isElementNode(el.host); | ||
| } | ||
| exports.isElementInToolbar = __webpack_exports__.isElementInToolbar; | ||
| exports.isElementNode = __webpack_exports__.isElementNode; | ||
| exports.isShadowRoot = __webpack_exports__.isShadowRoot; | ||
| exports.isTag = __webpack_exports__.isTag; | ||
| exports.isTextNode = __webpack_exports__.isTextNode; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "isElementInToolbar", | ||
| "isElementNode", | ||
| "isShadowRoot", | ||
| "isTag", | ||
| "isTextNode" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| import { TOOLBAR_CONTAINER_CLASS, TOOLBAR_ID } from "../constants.mjs"; | ||
| const NODE_TYPE_ELEMENT = 1; | ||
| const NODE_TYPE_TEXT = 3; | ||
| const NODE_TYPE_DOCUMENT_FRAGMENT = 11; | ||
| function isElementInToolbar(el) { | ||
| if (el instanceof Element) return el.id === TOOLBAR_ID || !!el.closest?.('.' + TOOLBAR_CONTAINER_CLASS); | ||
| return false; | ||
| } | ||
| function isElementNode(el) { | ||
| return !!el && el.nodeType === NODE_TYPE_ELEMENT; | ||
| } | ||
| function isTag(el, tag) { | ||
| return !!el && !!el.tagName && el.tagName.toLowerCase() === tag.toLowerCase(); | ||
| } | ||
| function isTextNode(el) { | ||
| return !!el && el.nodeType === NODE_TYPE_TEXT; | ||
| } | ||
| function isShadowRoot(el) { | ||
| return !!el && el.nodeType === NODE_TYPE_DOCUMENT_FRAGMENT && isElementNode(el.host); | ||
| } | ||
| export { isElementInToolbar, isElementNode, isShadowRoot, isTag, isTextNode }; |
| export declare function extractHref(elementsChain: string): string; | ||
| export declare function extractTexts(elementsChain: string): string[]; | ||
| export declare function matchString(value: string | undefined | null, pattern: string, matching: 'exact' | 'contains' | 'regex'): boolean; | ||
| export declare function matchTexts(texts: string[], pattern: string, matching: 'exact' | 'contains' | 'regex'): boolean; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| matchString: ()=>matchString, | ||
| extractHref: ()=>extractHref, | ||
| extractTexts: ()=>extractTexts, | ||
| matchTexts: ()=>matchTexts | ||
| }); | ||
| const core_namespaceObject = require("@posthog/core"); | ||
| function extractHref(elementsChain) { | ||
| const match = elementsChain.match(/(?::|")href="(.*?)"/); | ||
| return match ? match[1] : ''; | ||
| } | ||
| function extractTexts(elementsChain) { | ||
| const texts = []; | ||
| const regex = /(?::|")text="(.*?)"/g; | ||
| let match; | ||
| while(!(0, core_namespaceObject.isNullish)(match = regex.exec(elementsChain)))if (!texts.includes(match[1])) texts.push(match[1]); | ||
| return texts; | ||
| } | ||
| function matchString(value, pattern, matching) { | ||
| if ((0, core_namespaceObject.isNullish)(value)) return false; | ||
| switch(matching){ | ||
| case 'exact': | ||
| return value === pattern; | ||
| case 'contains': | ||
| { | ||
| const likePattern = pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/_/g, '.').replace(/%/g, '.*'); | ||
| return new RegExp(likePattern, 'i').test(value); | ||
| } | ||
| case 'regex': | ||
| try { | ||
| return new RegExp(pattern).test(value); | ||
| } catch { | ||
| return false; | ||
| } | ||
| default: | ||
| return false; | ||
| } | ||
| } | ||
| function matchTexts(texts, pattern, matching) { | ||
| return texts.some((text)=>matchString(text, pattern, matching)); | ||
| } | ||
| exports.extractHref = __webpack_exports__.extractHref; | ||
| exports.extractTexts = __webpack_exports__.extractTexts; | ||
| exports.matchString = __webpack_exports__.matchString; | ||
| exports.matchTexts = __webpack_exports__.matchTexts; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "extractHref", | ||
| "extractTexts", | ||
| "matchString", | ||
| "matchTexts" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| import { isNullish } from "@posthog/core"; | ||
| function extractHref(elementsChain) { | ||
| const match = elementsChain.match(/(?::|")href="(.*?)"/); | ||
| return match ? match[1] : ''; | ||
| } | ||
| function extractTexts(elementsChain) { | ||
| const texts = []; | ||
| const regex = /(?::|")text="(.*?)"/g; | ||
| let match; | ||
| while(!isNullish(match = regex.exec(elementsChain)))if (!texts.includes(match[1])) texts.push(match[1]); | ||
| return texts; | ||
| } | ||
| function matchString(value, pattern, matching) { | ||
| if (isNullish(value)) return false; | ||
| switch(matching){ | ||
| case 'exact': | ||
| return value === pattern; | ||
| case 'contains': | ||
| { | ||
| const likePattern = pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/_/g, '.').replace(/%/g, '.*'); | ||
| return new RegExp(likePattern, 'i').test(value); | ||
| } | ||
| case 'regex': | ||
| try { | ||
| return new RegExp(pattern).test(value); | ||
| } catch { | ||
| return false; | ||
| } | ||
| default: | ||
| return false; | ||
| } | ||
| } | ||
| function matchTexts(texts, pattern, matching) { | ||
| return texts.some((text)=>matchString(text, pattern, matching)); | ||
| } | ||
| export { extractHref, extractTexts, matchString, matchTexts }; |
| /** | ||
| * UTF-8 safe base64 encoding. | ||
| * Uses encodeURIComponent to handle Unicode, then converts percent-encoded bytes | ||
| * back to characters that btoa can handle. | ||
| */ | ||
| export declare function _base64Encode(data: null): null; | ||
| export declare function _base64Encode(data: undefined): undefined; | ||
| export declare function _base64Encode(data: string): string; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| _base64Encode: ()=>_base64Encode | ||
| }); | ||
| function _base64Encode(data) { | ||
| if (!data) return data; | ||
| return btoa(encodeURIComponent(data).replace(/%([0-9A-F]{2})/g, (_, p1)=>String.fromCharCode(parseInt(p1, 16)))); | ||
| } | ||
| exports._base64Encode = __webpack_exports__._base64Encode; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "_base64Encode" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| function _base64Encode(data) { | ||
| if (!data) return data; | ||
| return btoa(encodeURIComponent(data).replace(/%([0-9A-F]{2})/g, (_, p1)=>String.fromCharCode(parseInt(p1, 16)))); | ||
| } | ||
| export { _base64Encode }; |
| import type { Properties } from '@posthog/types'; | ||
| import type { BrowserDetectionHints } from '@posthog/core'; | ||
| export declare const PERSONAL_DATA_CAMPAIGN_PARAMS: string[]; | ||
| export declare const CAMPAIGN_PARAMS: string[]; | ||
| export declare const EVENT_TO_PERSON_PROPERTIES: string[]; | ||
| export declare const MASKED = "<masked>"; | ||
| export declare const COOKIE_CAMPAIGN_PARAMS: string[]; | ||
| export declare function getCampaignParams(customTrackedParams?: string[], maskPersonalDataProperties?: boolean, customPersonalDataProperties?: string[] | undefined): Record<string, string>; | ||
| export declare function getSearchInfo(): Record<string, any>; | ||
| export declare function getBrowserLanguage(): string | undefined; | ||
| export declare function getBrowserLanguagePrefix(): string | undefined; | ||
| export declare function getReferrer(): string; | ||
| export declare function getReferringDomain(): string; | ||
| export declare function getReferrerInfo(): Record<string, any>; | ||
| export declare function getPersonInfo(maskPersonalDataProperties?: boolean, customPersonalDataProperties?: string[], disableCaptureUrlHashes?: boolean): { | ||
| r: string; | ||
| u: string | undefined; | ||
| }; | ||
| export declare function getPersonPropsFromInfo(info: Record<string, any>, disableCaptureUrlHashes?: boolean): Record<string, any>; | ||
| export declare function getInitialPersonPropsFromInfo(info: Record<string, any>, disableCaptureUrlHashes?: boolean): Record<string, any>; | ||
| export declare function getTimezone(): string | undefined; | ||
| export declare function getTimezoneOffset(): number | undefined; | ||
| export declare function getBrowserDetectionHints(): BrowserDetectionHints; | ||
| export declare function getEventProperties(maskPersonalDataProperties?: boolean, customPersonalDataProperties?: string[], detectGoogleSearchApp?: boolean, disableCaptureUrlHashes?: boolean): Properties; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.n = (module)=>{ | ||
| var getter = module && module.__esModule ? ()=>module['default'] : ()=>module; | ||
| __webpack_require__.d(getter, { | ||
| a: getter | ||
| }); | ||
| return getter; | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| getCampaignParams: ()=>getCampaignParams, | ||
| getReferrerInfo: ()=>getReferrerInfo, | ||
| getEventProperties: ()=>getEventProperties, | ||
| getPersonPropsFromInfo: ()=>getPersonPropsFromInfo, | ||
| COOKIE_CAMPAIGN_PARAMS: ()=>COOKIE_CAMPAIGN_PARAMS, | ||
| getReferrer: ()=>getReferrer, | ||
| getReferringDomain: ()=>getReferringDomain, | ||
| getTimezone: ()=>getTimezone, | ||
| getBrowserDetectionHints: ()=>getBrowserDetectionHints, | ||
| getBrowserLanguagePrefix: ()=>getBrowserLanguagePrefix, | ||
| getInitialPersonPropsFromInfo: ()=>getInitialPersonPropsFromInfo, | ||
| MASKED: ()=>MASKED, | ||
| getPersonInfo: ()=>getPersonInfo, | ||
| CAMPAIGN_PARAMS: ()=>CAMPAIGN_PARAMS, | ||
| getBrowserLanguage: ()=>getBrowserLanguage, | ||
| PERSONAL_DATA_CAMPAIGN_PARAMS: ()=>PERSONAL_DATA_CAMPAIGN_PARAMS, | ||
| getSearchInfo: ()=>getSearchInfo, | ||
| getTimezoneOffset: ()=>getTimezoneOffset, | ||
| EVENT_TO_PERSON_PROPERTIES: ()=>EVENT_TO_PERSON_PROPERTIES | ||
| }); | ||
| const external_request_utils_js_namespaceObject = require("./request-utils.js"); | ||
| const core_namespaceObject = require("@posthog/core"); | ||
| const external_config_js_namespaceObject = require("../config.js"); | ||
| var external_config_js_default = /*#__PURE__*/ __webpack_require__.n(external_config_js_namespaceObject); | ||
| const external_constants_js_namespaceObject = require("../constants.js"); | ||
| const external_general_utils_js_namespaceObject = require("./general-utils.js"); | ||
| const external_globals_js_namespaceObject = require("./globals.js"); | ||
| const external_cookie_utils_js_namespaceObject = require("./cookie-utils.js"); | ||
| const URL_REGEX_PREFIX = 'https?://(.*)'; | ||
| const PERSONAL_DATA_CAMPAIGN_PARAMS = [ | ||
| 'gclid', | ||
| 'gclsrc', | ||
| 'dclid', | ||
| 'gbraid', | ||
| 'wbraid', | ||
| 'fbclid', | ||
| 'msclkid', | ||
| 'twclid', | ||
| 'li_fat_id', | ||
| 'igshid', | ||
| 'ttclid', | ||
| 'rdt_cid', | ||
| 'epik', | ||
| 'qclid', | ||
| 'sccid', | ||
| 'irclid', | ||
| '_kx' | ||
| ]; | ||
| const CAMPAIGN_PARAMS = [ | ||
| 'utm_source', | ||
| 'utm_medium', | ||
| 'utm_campaign', | ||
| 'utm_content', | ||
| 'utm_term', | ||
| 'gad_source', | ||
| 'mc_cid', | ||
| ...PERSONAL_DATA_CAMPAIGN_PARAMS | ||
| ]; | ||
| const EVENT_TO_PERSON_PROPERTIES = [ | ||
| '$app_build', | ||
| '$app_name', | ||
| '$app_namespace', | ||
| '$app_version', | ||
| '$browser', | ||
| '$browser_version', | ||
| '$device_type', | ||
| '$current_url', | ||
| '$pathname', | ||
| '$os', | ||
| '$os_name', | ||
| '$os_version', | ||
| '$referring_domain', | ||
| '$referrer', | ||
| '$screen_height', | ||
| '$screen_width', | ||
| '$viewport_height', | ||
| '$viewport_width', | ||
| '$raw_user_agent' | ||
| ]; | ||
| const MASKED = '<masked>'; | ||
| const COOKIE_CAMPAIGN_PARAMS = [ | ||
| 'li_fat_id' | ||
| ]; | ||
| function getCampaignParams(customTrackedParams, maskPersonalDataProperties, customPersonalDataProperties) { | ||
| if (!external_globals_js_namespaceObject.document) return {}; | ||
| const paramsToMask = maskPersonalDataProperties ? [ | ||
| ...PERSONAL_DATA_CAMPAIGN_PARAMS, | ||
| ...customPersonalDataProperties || [] | ||
| ] : []; | ||
| const urlCampaignParams = _getCampaignParamsFromUrl((0, external_request_utils_js_namespaceObject.maskQueryParams)(external_globals_js_namespaceObject.document.URL, paramsToMask, MASKED), customTrackedParams); | ||
| const cookieCampaignParams = _getCampaignParamsFromCookie(); | ||
| return (0, external_general_utils_js_namespaceObject.extend)(cookieCampaignParams, urlCampaignParams); | ||
| } | ||
| function _getCampaignParamsFromUrl(url, customParams) { | ||
| const campaign_keywords = CAMPAIGN_PARAMS.concat(customParams || []); | ||
| const params = {}; | ||
| (0, external_general_utils_js_namespaceObject.each)(campaign_keywords, function(kwkey) { | ||
| const kw = (0, external_request_utils_js_namespaceObject.getQueryParam)(url, kwkey); | ||
| params[kwkey] = kw ? kw : null; | ||
| }); | ||
| return params; | ||
| } | ||
| function _getCampaignParamsFromCookie() { | ||
| const params = {}; | ||
| (0, external_general_utils_js_namespaceObject.each)(COOKIE_CAMPAIGN_PARAMS, function(kwkey) { | ||
| const kw = (0, external_cookie_utils_js_namespaceObject.getCookieValue)(kwkey); | ||
| params[kwkey] = kw ? kw : null; | ||
| }); | ||
| return params; | ||
| } | ||
| function _getSearchEngine(referrer) { | ||
| if (!referrer) return null; | ||
| if (0 === referrer.search(URL_REGEX_PREFIX + 'google.([^/?]*)')) return 'google'; | ||
| if (0 === referrer.search(URL_REGEX_PREFIX + 'bing.com')) return 'bing'; | ||
| if (0 === referrer.search(URL_REGEX_PREFIX + 'yahoo.com')) return 'yahoo'; | ||
| if (0 === referrer.search(URL_REGEX_PREFIX + 'duckduckgo.com')) return 'duckduckgo'; | ||
| else return null; | ||
| } | ||
| function _getSearchInfoFromReferrer(referrer) { | ||
| const search = _getSearchEngine(referrer); | ||
| const param = 'yahoo' != search ? 'q' : 'p'; | ||
| const ret = {}; | ||
| if (!(0, core_namespaceObject.isNull)(search)) { | ||
| ret['$search_engine'] = search; | ||
| const keyword = external_globals_js_namespaceObject.document ? (0, external_request_utils_js_namespaceObject.getQueryParam)(external_globals_js_namespaceObject.document.referrer, param) : ''; | ||
| if (keyword.length) ret['ph_keyword'] = keyword; | ||
| } | ||
| return ret; | ||
| } | ||
| function getSearchInfo() { | ||
| const referrer = external_globals_js_namespaceObject.document?.referrer; | ||
| if (!referrer) return {}; | ||
| return _getSearchInfoFromReferrer(referrer); | ||
| } | ||
| function getBrowserLanguage() { | ||
| return navigator.language || navigator.userLanguage; | ||
| } | ||
| function getBrowserLanguagePrefix() { | ||
| const lang = getBrowserLanguage(); | ||
| return 'string' == typeof lang ? lang.split('-')[0] : void 0; | ||
| } | ||
| const DIRECT = '$direct'; | ||
| function getReferrer() { | ||
| return external_globals_js_namespaceObject.document?.referrer || DIRECT; | ||
| } | ||
| function getReferringDomain() { | ||
| if (!external_globals_js_namespaceObject.document?.referrer) return DIRECT; | ||
| return (0, external_request_utils_js_namespaceObject.convertToURL)(external_globals_js_namespaceObject.document.referrer)?.host || DIRECT; | ||
| } | ||
| function getReferrerInfo() { | ||
| return { | ||
| $referrer: getReferrer(), | ||
| $referring_domain: getReferringDomain() | ||
| }; | ||
| } | ||
| function getPersonInfo(maskPersonalDataProperties, customPersonalDataProperties, disableCaptureUrlHashes = false) { | ||
| const paramsToMask = maskPersonalDataProperties ? [ | ||
| ...PERSONAL_DATA_CAMPAIGN_PARAMS, | ||
| ...customPersonalDataProperties || [] | ||
| ] : []; | ||
| const href = disableCaptureUrlHashes ? (0, core_namespaceObject.stripUrlHash)(external_globals_js_namespaceObject.location?.href) : external_globals_js_namespaceObject.location?.href; | ||
| const url = href?.substring(0, 1000); | ||
| return { | ||
| r: getReferrer().substring(0, 1000), | ||
| u: url ? (0, external_request_utils_js_namespaceObject.maskQueryParams)(url, paramsToMask, MASKED) : void 0 | ||
| }; | ||
| } | ||
| function getPersonPropsFromInfo(info, disableCaptureUrlHashes = false) { | ||
| const { r: referrer, u } = info; | ||
| const url = disableCaptureUrlHashes ? (0, core_namespaceObject.stripUrlHash)(u) : u; | ||
| const referring_domain = null == referrer ? void 0 : referrer == DIRECT ? DIRECT : (0, external_request_utils_js_namespaceObject.convertToURL)(referrer)?.host; | ||
| const props = { | ||
| $referrer: referrer, | ||
| $referring_domain: referring_domain | ||
| }; | ||
| if (url) { | ||
| props['$current_url'] = url; | ||
| const location = (0, external_request_utils_js_namespaceObject.convertToURL)(url); | ||
| props['$host'] = location?.host; | ||
| props['$pathname'] = location?.pathname; | ||
| const campaignParams = _getCampaignParamsFromUrl(url); | ||
| (0, external_general_utils_js_namespaceObject.extend)(props, campaignParams); | ||
| } | ||
| if (referrer) { | ||
| const searchInfo = _getSearchInfoFromReferrer(referrer); | ||
| (0, external_general_utils_js_namespaceObject.extend)(props, searchInfo); | ||
| } | ||
| return props; | ||
| } | ||
| function getInitialPersonPropsFromInfo(info, disableCaptureUrlHashes = false) { | ||
| const personProps = getPersonPropsFromInfo(info, disableCaptureUrlHashes); | ||
| const props = {}; | ||
| (0, external_general_utils_js_namespaceObject.each)(personProps, function(val, key) { | ||
| props[`$initial_${(0, core_namespaceObject.stripLeadingDollar)(key)}`] = val; | ||
| }); | ||
| return props; | ||
| } | ||
| function getTimezone() { | ||
| try { | ||
| return Intl.DateTimeFormat().resolvedOptions().timeZone; | ||
| } catch { | ||
| return; | ||
| } | ||
| } | ||
| function getTimezoneOffset() { | ||
| try { | ||
| return new Date().getTimezoneOffset(); | ||
| } catch { | ||
| return; | ||
| } | ||
| } | ||
| function getBrowserDetectionHints() { | ||
| const nav = 'undefined' != typeof navigator ? navigator : void 0; | ||
| return nav?.brave ? { | ||
| brave: true | ||
| } : {}; | ||
| } | ||
| function getEventProperties(maskPersonalDataProperties, customPersonalDataProperties, detectGoogleSearchApp, disableCaptureUrlHashes = false) { | ||
| if (!external_globals_js_namespaceObject.userAgent) return {}; | ||
| const paramsToMask = maskPersonalDataProperties ? [ | ||
| ...PERSONAL_DATA_CAMPAIGN_PARAMS, | ||
| ...customPersonalDataProperties || [] | ||
| ] : []; | ||
| const [os_name, os_version] = (0, core_namespaceObject.detectOS)(external_globals_js_namespaceObject.userAgent); | ||
| const browserHints = getBrowserDetectionHints(); | ||
| const browserOptions = {}; | ||
| if (!(0, core_namespaceObject.isUndefined)(detectGoogleSearchApp)) browserOptions.detectGoogleSearchApp = detectGoogleSearchApp; | ||
| const deviceOptions = {}; | ||
| const userAgentDataPlatform = navigator?.userAgentData?.platform; | ||
| const maxTouchPoints = navigator?.maxTouchPoints; | ||
| const screenWidth = external_globals_js_namespaceObject.window?.screen?.width; | ||
| const screenHeight = external_globals_js_namespaceObject.window?.screen?.height; | ||
| const devicePixelRatio = external_globals_js_namespaceObject.window?.devicePixelRatio; | ||
| if (!(0, core_namespaceObject.isUndefined)(userAgentDataPlatform)) deviceOptions.userAgentDataPlatform = userAgentDataPlatform; | ||
| if (!(0, core_namespaceObject.isUndefined)(maxTouchPoints)) deviceOptions.maxTouchPoints = maxTouchPoints; | ||
| if (!(0, core_namespaceObject.isUndefined)(screenWidth)) deviceOptions.screenWidth = screenWidth; | ||
| if (!(0, core_namespaceObject.isUndefined)(screenHeight)) deviceOptions.screenHeight = screenHeight; | ||
| if (!(0, core_namespaceObject.isUndefined)(devicePixelRatio)) deviceOptions.devicePixelRatio = devicePixelRatio; | ||
| const properties = (0, external_general_utils_js_namespaceObject.extend)((0, external_general_utils_js_namespaceObject.stripEmptyProperties)({ | ||
| $os: os_name, | ||
| $os_version: os_version, | ||
| $browser: (0, core_namespaceObject.detectBrowser)(external_globals_js_namespaceObject.userAgent, navigator.vendor, browserHints, browserOptions), | ||
| $device: (0, core_namespaceObject.detectDevice)(external_globals_js_namespaceObject.userAgent), | ||
| $device_type: (0, core_namespaceObject.detectDeviceType)(external_globals_js_namespaceObject.userAgent, deviceOptions), | ||
| $timezone: getTimezone(), | ||
| $timezone_offset: getTimezoneOffset() | ||
| }), { | ||
| $current_url: (0, external_request_utils_js_namespaceObject.maskQueryParams)(disableCaptureUrlHashes ? (0, core_namespaceObject.stripUrlHash)(external_globals_js_namespaceObject.location?.href) : external_globals_js_namespaceObject.location?.href, paramsToMask, MASKED), | ||
| $host: external_globals_js_namespaceObject.location?.host, | ||
| $pathname: external_globals_js_namespaceObject.location?.pathname, | ||
| $raw_user_agent: external_globals_js_namespaceObject.userAgent.length > 1000 ? external_globals_js_namespaceObject.userAgent.substring(0, 997) + '...' : external_globals_js_namespaceObject.userAgent, | ||
| $browser_version: (0, core_namespaceObject.detectBrowserVersion)(external_globals_js_namespaceObject.userAgent, navigator.vendor, browserHints, browserOptions), | ||
| $browser_language: getBrowserLanguage(), | ||
| $browser_language_prefix: getBrowserLanguagePrefix(), | ||
| $screen_height: external_globals_js_namespaceObject.window?.screen.height, | ||
| $screen_width: external_globals_js_namespaceObject.window?.screen.width, | ||
| $viewport_height: external_globals_js_namespaceObject.window?.innerHeight, | ||
| $viewport_width: external_globals_js_namespaceObject.window?.innerWidth, | ||
| $lib: external_config_js_default().LIB_NAME, | ||
| $lib_version: external_config_js_default().LIB_VERSION, | ||
| $insert_id: Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10), | ||
| $time: Date.now() / 1000 | ||
| }); | ||
| if (external_config_js_default().SDK_DIST_CHANNEL) properties[external_constants_js_namespaceObject.SDK_DIST_CHANNEL] = external_config_js_default().SDK_DIST_CHANNEL; | ||
| return properties; | ||
| } | ||
| exports.CAMPAIGN_PARAMS = __webpack_exports__.CAMPAIGN_PARAMS; | ||
| exports.COOKIE_CAMPAIGN_PARAMS = __webpack_exports__.COOKIE_CAMPAIGN_PARAMS; | ||
| exports.EVENT_TO_PERSON_PROPERTIES = __webpack_exports__.EVENT_TO_PERSON_PROPERTIES; | ||
| exports.MASKED = __webpack_exports__.MASKED; | ||
| exports.PERSONAL_DATA_CAMPAIGN_PARAMS = __webpack_exports__.PERSONAL_DATA_CAMPAIGN_PARAMS; | ||
| exports.getBrowserDetectionHints = __webpack_exports__.getBrowserDetectionHints; | ||
| exports.getBrowserLanguage = __webpack_exports__.getBrowserLanguage; | ||
| exports.getBrowserLanguagePrefix = __webpack_exports__.getBrowserLanguagePrefix; | ||
| exports.getCampaignParams = __webpack_exports__.getCampaignParams; | ||
| exports.getEventProperties = __webpack_exports__.getEventProperties; | ||
| exports.getInitialPersonPropsFromInfo = __webpack_exports__.getInitialPersonPropsFromInfo; | ||
| exports.getPersonInfo = __webpack_exports__.getPersonInfo; | ||
| exports.getPersonPropsFromInfo = __webpack_exports__.getPersonPropsFromInfo; | ||
| exports.getReferrer = __webpack_exports__.getReferrer; | ||
| exports.getReferrerInfo = __webpack_exports__.getReferrerInfo; | ||
| exports.getReferringDomain = __webpack_exports__.getReferringDomain; | ||
| exports.getSearchInfo = __webpack_exports__.getSearchInfo; | ||
| exports.getTimezone = __webpack_exports__.getTimezone; | ||
| exports.getTimezoneOffset = __webpack_exports__.getTimezoneOffset; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "CAMPAIGN_PARAMS", | ||
| "COOKIE_CAMPAIGN_PARAMS", | ||
| "EVENT_TO_PERSON_PROPERTIES", | ||
| "MASKED", | ||
| "PERSONAL_DATA_CAMPAIGN_PARAMS", | ||
| "getBrowserDetectionHints", | ||
| "getBrowserLanguage", | ||
| "getBrowserLanguagePrefix", | ||
| "getCampaignParams", | ||
| "getEventProperties", | ||
| "getInitialPersonPropsFromInfo", | ||
| "getPersonInfo", | ||
| "getPersonPropsFromInfo", | ||
| "getReferrer", | ||
| "getReferrerInfo", | ||
| "getReferringDomain", | ||
| "getSearchInfo", | ||
| "getTimezone", | ||
| "getTimezoneOffset" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| import { convertToURL, getQueryParam, maskQueryParams } from "./request-utils.mjs"; | ||
| import { detectBrowser, detectBrowserVersion, detectDevice, detectDeviceType, detectOS, isNull, isUndefined, stripLeadingDollar, stripUrlHash } from "@posthog/core"; | ||
| import config from "../config.mjs"; | ||
| import { SDK_DIST_CHANNEL } from "../constants.mjs"; | ||
| import { each, extend, stripEmptyProperties } from "./general-utils.mjs"; | ||
| import { document as external_globals_mjs_document, location as external_globals_mjs_location, userAgent, window as external_globals_mjs_window } from "./globals.mjs"; | ||
| import { getCookieValue } from "./cookie-utils.mjs"; | ||
| const URL_REGEX_PREFIX = 'https?://(.*)'; | ||
| const PERSONAL_DATA_CAMPAIGN_PARAMS = [ | ||
| 'gclid', | ||
| 'gclsrc', | ||
| 'dclid', | ||
| 'gbraid', | ||
| 'wbraid', | ||
| 'fbclid', | ||
| 'msclkid', | ||
| 'twclid', | ||
| 'li_fat_id', | ||
| 'igshid', | ||
| 'ttclid', | ||
| 'rdt_cid', | ||
| 'epik', | ||
| 'qclid', | ||
| 'sccid', | ||
| 'irclid', | ||
| '_kx' | ||
| ]; | ||
| const CAMPAIGN_PARAMS = [ | ||
| 'utm_source', | ||
| 'utm_medium', | ||
| 'utm_campaign', | ||
| 'utm_content', | ||
| 'utm_term', | ||
| 'gad_source', | ||
| 'mc_cid', | ||
| ...PERSONAL_DATA_CAMPAIGN_PARAMS | ||
| ]; | ||
| const EVENT_TO_PERSON_PROPERTIES = [ | ||
| '$app_build', | ||
| '$app_name', | ||
| '$app_namespace', | ||
| '$app_version', | ||
| '$browser', | ||
| '$browser_version', | ||
| '$device_type', | ||
| '$current_url', | ||
| '$pathname', | ||
| '$os', | ||
| '$os_name', | ||
| '$os_version', | ||
| '$referring_domain', | ||
| '$referrer', | ||
| '$screen_height', | ||
| '$screen_width', | ||
| '$viewport_height', | ||
| '$viewport_width', | ||
| '$raw_user_agent' | ||
| ]; | ||
| const MASKED = '<masked>'; | ||
| const COOKIE_CAMPAIGN_PARAMS = [ | ||
| 'li_fat_id' | ||
| ]; | ||
| function getCampaignParams(customTrackedParams, maskPersonalDataProperties, customPersonalDataProperties) { | ||
| if (!external_globals_mjs_document) return {}; | ||
| const paramsToMask = maskPersonalDataProperties ? [ | ||
| ...PERSONAL_DATA_CAMPAIGN_PARAMS, | ||
| ...customPersonalDataProperties || [] | ||
| ] : []; | ||
| const urlCampaignParams = _getCampaignParamsFromUrl(maskQueryParams(external_globals_mjs_document.URL, paramsToMask, MASKED), customTrackedParams); | ||
| const cookieCampaignParams = _getCampaignParamsFromCookie(); | ||
| return extend(cookieCampaignParams, urlCampaignParams); | ||
| } | ||
| function _getCampaignParamsFromUrl(url, customParams) { | ||
| const campaign_keywords = CAMPAIGN_PARAMS.concat(customParams || []); | ||
| const params = {}; | ||
| each(campaign_keywords, function(kwkey) { | ||
| const kw = getQueryParam(url, kwkey); | ||
| params[kwkey] = kw ? kw : null; | ||
| }); | ||
| return params; | ||
| } | ||
| function _getCampaignParamsFromCookie() { | ||
| const params = {}; | ||
| each(COOKIE_CAMPAIGN_PARAMS, function(kwkey) { | ||
| const kw = getCookieValue(kwkey); | ||
| params[kwkey] = kw ? kw : null; | ||
| }); | ||
| return params; | ||
| } | ||
| function _getSearchEngine(referrer) { | ||
| if (!referrer) return null; | ||
| if (0 === referrer.search(URL_REGEX_PREFIX + 'google.([^/?]*)')) return 'google'; | ||
| if (0 === referrer.search(URL_REGEX_PREFIX + 'bing.com')) return 'bing'; | ||
| if (0 === referrer.search(URL_REGEX_PREFIX + 'yahoo.com')) return 'yahoo'; | ||
| if (0 === referrer.search(URL_REGEX_PREFIX + 'duckduckgo.com')) return 'duckduckgo'; | ||
| else return null; | ||
| } | ||
| function _getSearchInfoFromReferrer(referrer) { | ||
| const search = _getSearchEngine(referrer); | ||
| const param = 'yahoo' != search ? 'q' : 'p'; | ||
| const ret = {}; | ||
| if (!isNull(search)) { | ||
| ret['$search_engine'] = search; | ||
| const keyword = external_globals_mjs_document ? getQueryParam(external_globals_mjs_document.referrer, param) : ''; | ||
| if (keyword.length) ret['ph_keyword'] = keyword; | ||
| } | ||
| return ret; | ||
| } | ||
| function getSearchInfo() { | ||
| const referrer = external_globals_mjs_document?.referrer; | ||
| if (!referrer) return {}; | ||
| return _getSearchInfoFromReferrer(referrer); | ||
| } | ||
| function getBrowserLanguage() { | ||
| return navigator.language || navigator.userLanguage; | ||
| } | ||
| function getBrowserLanguagePrefix() { | ||
| const lang = getBrowserLanguage(); | ||
| return 'string' == typeof lang ? lang.split('-')[0] : void 0; | ||
| } | ||
| const DIRECT = '$direct'; | ||
| function getReferrer() { | ||
| return external_globals_mjs_document?.referrer || DIRECT; | ||
| } | ||
| function getReferringDomain() { | ||
| if (!external_globals_mjs_document?.referrer) return DIRECT; | ||
| return convertToURL(external_globals_mjs_document.referrer)?.host || DIRECT; | ||
| } | ||
| function getReferrerInfo() { | ||
| return { | ||
| $referrer: getReferrer(), | ||
| $referring_domain: getReferringDomain() | ||
| }; | ||
| } | ||
| function getPersonInfo(maskPersonalDataProperties, customPersonalDataProperties, disableCaptureUrlHashes = false) { | ||
| const paramsToMask = maskPersonalDataProperties ? [ | ||
| ...PERSONAL_DATA_CAMPAIGN_PARAMS, | ||
| ...customPersonalDataProperties || [] | ||
| ] : []; | ||
| const href = disableCaptureUrlHashes ? stripUrlHash(external_globals_mjs_location?.href) : external_globals_mjs_location?.href; | ||
| const url = href?.substring(0, 1000); | ||
| return { | ||
| r: getReferrer().substring(0, 1000), | ||
| u: url ? maskQueryParams(url, paramsToMask, MASKED) : void 0 | ||
| }; | ||
| } | ||
| function getPersonPropsFromInfo(info, disableCaptureUrlHashes = false) { | ||
| const { r: referrer, u } = info; | ||
| const url = disableCaptureUrlHashes ? stripUrlHash(u) : u; | ||
| const referring_domain = null == referrer ? void 0 : referrer == DIRECT ? DIRECT : convertToURL(referrer)?.host; | ||
| const props = { | ||
| $referrer: referrer, | ||
| $referring_domain: referring_domain | ||
| }; | ||
| if (url) { | ||
| props['$current_url'] = url; | ||
| const location = convertToURL(url); | ||
| props['$host'] = location?.host; | ||
| props['$pathname'] = location?.pathname; | ||
| const campaignParams = _getCampaignParamsFromUrl(url); | ||
| extend(props, campaignParams); | ||
| } | ||
| if (referrer) { | ||
| const searchInfo = _getSearchInfoFromReferrer(referrer); | ||
| extend(props, searchInfo); | ||
| } | ||
| return props; | ||
| } | ||
| function getInitialPersonPropsFromInfo(info, disableCaptureUrlHashes = false) { | ||
| const personProps = getPersonPropsFromInfo(info, disableCaptureUrlHashes); | ||
| const props = {}; | ||
| each(personProps, function(val, key) { | ||
| props[`$initial_${stripLeadingDollar(key)}`] = val; | ||
| }); | ||
| return props; | ||
| } | ||
| function getTimezone() { | ||
| try { | ||
| return Intl.DateTimeFormat().resolvedOptions().timeZone; | ||
| } catch { | ||
| return; | ||
| } | ||
| } | ||
| function getTimezoneOffset() { | ||
| try { | ||
| return new Date().getTimezoneOffset(); | ||
| } catch { | ||
| return; | ||
| } | ||
| } | ||
| function getBrowserDetectionHints() { | ||
| const nav = 'undefined' != typeof navigator ? navigator : void 0; | ||
| return nav?.brave ? { | ||
| brave: true | ||
| } : {}; | ||
| } | ||
| function getEventProperties(maskPersonalDataProperties, customPersonalDataProperties, detectGoogleSearchApp, disableCaptureUrlHashes = false) { | ||
| if (!userAgent) return {}; | ||
| const paramsToMask = maskPersonalDataProperties ? [ | ||
| ...PERSONAL_DATA_CAMPAIGN_PARAMS, | ||
| ...customPersonalDataProperties || [] | ||
| ] : []; | ||
| const [os_name, os_version] = detectOS(userAgent); | ||
| const browserHints = getBrowserDetectionHints(); | ||
| const browserOptions = {}; | ||
| if (!isUndefined(detectGoogleSearchApp)) browserOptions.detectGoogleSearchApp = detectGoogleSearchApp; | ||
| const deviceOptions = {}; | ||
| const userAgentDataPlatform = navigator?.userAgentData?.platform; | ||
| const maxTouchPoints = navigator?.maxTouchPoints; | ||
| const screenWidth = external_globals_mjs_window?.screen?.width; | ||
| const screenHeight = external_globals_mjs_window?.screen?.height; | ||
| const devicePixelRatio = external_globals_mjs_window?.devicePixelRatio; | ||
| if (!isUndefined(userAgentDataPlatform)) deviceOptions.userAgentDataPlatform = userAgentDataPlatform; | ||
| if (!isUndefined(maxTouchPoints)) deviceOptions.maxTouchPoints = maxTouchPoints; | ||
| if (!isUndefined(screenWidth)) deviceOptions.screenWidth = screenWidth; | ||
| if (!isUndefined(screenHeight)) deviceOptions.screenHeight = screenHeight; | ||
| if (!isUndefined(devicePixelRatio)) deviceOptions.devicePixelRatio = devicePixelRatio; | ||
| const properties = extend(stripEmptyProperties({ | ||
| $os: os_name, | ||
| $os_version: os_version, | ||
| $browser: detectBrowser(userAgent, navigator.vendor, browserHints, browserOptions), | ||
| $device: detectDevice(userAgent), | ||
| $device_type: detectDeviceType(userAgent, deviceOptions), | ||
| $timezone: getTimezone(), | ||
| $timezone_offset: getTimezoneOffset() | ||
| }), { | ||
| $current_url: maskQueryParams(disableCaptureUrlHashes ? stripUrlHash(external_globals_mjs_location?.href) : external_globals_mjs_location?.href, paramsToMask, MASKED), | ||
| $host: external_globals_mjs_location?.host, | ||
| $pathname: external_globals_mjs_location?.pathname, | ||
| $raw_user_agent: userAgent.length > 1000 ? userAgent.substring(0, 997) + '...' : userAgent, | ||
| $browser_version: detectBrowserVersion(userAgent, navigator.vendor, browserHints, browserOptions), | ||
| $browser_language: getBrowserLanguage(), | ||
| $browser_language_prefix: getBrowserLanguagePrefix(), | ||
| $screen_height: external_globals_mjs_window?.screen.height, | ||
| $screen_width: external_globals_mjs_window?.screen.width, | ||
| $viewport_height: external_globals_mjs_window?.innerHeight, | ||
| $viewport_width: external_globals_mjs_window?.innerWidth, | ||
| $lib: config.LIB_NAME, | ||
| $lib_version: config.LIB_VERSION, | ||
| $insert_id: Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10), | ||
| $time: Date.now() / 1000 | ||
| }); | ||
| if (config.SDK_DIST_CHANNEL) properties[SDK_DIST_CHANNEL] = config.SDK_DIST_CHANNEL; | ||
| return properties; | ||
| } | ||
| export { CAMPAIGN_PARAMS, COOKIE_CAMPAIGN_PARAMS, EVENT_TO_PERSON_PROPERTIES, MASKED, PERSONAL_DATA_CAMPAIGN_PARAMS, getBrowserDetectionHints, getBrowserLanguage, getBrowserLanguagePrefix, getCampaignParams, getEventProperties, getInitialPersonPropsFromInfo, getPersonInfo, getPersonPropsFromInfo, getReferrer, getReferrerInfo, getReferringDomain, getSearchInfo, getTimezone, getTimezoneOffset }; |
| import type { PostHogConfig, Properties } from '@posthog/types'; | ||
| export declare function find<T>(value: T[], predicate: (value: T) => boolean): T | undefined; | ||
| export declare function eachArray<E = any>(obj: E[] | null | undefined, iterator: (value: E, key: number) => void): void; | ||
| export declare function each(obj: any, iterator: (value: any, key: any) => void): void; | ||
| export declare const extend: (obj: Record<string, any>, ...args: Record<string, any>[]) => Record<string, any>; | ||
| /** | ||
| * Object.entries() polyfill | ||
| * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries | ||
| */ | ||
| export declare function entries<T = any>(obj: Record<string, T>): [string, T][]; | ||
| export declare const trySafe: <T>(fn: () => T) => T | undefined; | ||
| export declare const safewrap: <F extends (...args: any[]) => any = (...args: any[]) => any>(f: F) => F; | ||
| export declare const safewrapClass: (klass: Function, functions: string[]) => void; | ||
| export declare const stripEmptyProperties: (p: Properties) => Properties; | ||
| export declare function _copyAndTruncateStrings<T extends Record<string, any> = Record<string, any>>(object: T, maxStringLength: number): T; | ||
| export declare function isCrossDomainCookie(documentLocation: Location | undefined): boolean; | ||
| export declare function addEventListener(element: Window | Document | Element | undefined, event: string, callback: EventListener, options?: AddEventListenerOptions): void; | ||
| /** | ||
| * Helper to migrate deprecated config fields to new field names with appropriate warnings | ||
| * @param config - The config object to check | ||
| * @param newField - The new field name to use | ||
| * @param oldField - The deprecated field name to check for | ||
| * @param defaultValue - The default value if neither field is set | ||
| * @param loggerInstance - Optional logger instance for deprecation warnings | ||
| * @returns The value to use (new field takes precedence over old field) | ||
| */ | ||
| export declare function migrateConfigField<T>(config: Record<string, any>, newField: string, oldField: string, defaultValue: T, loggerInstance?: { | ||
| warn: (message: string) => void; | ||
| }): T; | ||
| export declare function isToolbarInstance(config: Pick<PostHogConfig, 'name'>): boolean; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| find: ()=>find, | ||
| migrateConfigField: ()=>migrateConfigField, | ||
| each: ()=>each, | ||
| entries: ()=>entries, | ||
| safewrap: ()=>safewrap, | ||
| eachArray: ()=>eachArray, | ||
| safewrapClass: ()=>safewrapClass, | ||
| isCrossDomainCookie: ()=>isCrossDomainCookie, | ||
| _copyAndTruncateStrings: ()=>_copyAndTruncateStrings, | ||
| addEventListener: ()=>addEventListener, | ||
| extend: ()=>extend, | ||
| stripEmptyProperties: ()=>stripEmptyProperties, | ||
| isToolbarInstance: ()=>isToolbarInstance, | ||
| trySafe: ()=>trySafe | ||
| }); | ||
| const core_namespaceObject = require("@posthog/core"); | ||
| const external_logger_js_namespaceObject = require("./logger.js"); | ||
| function find(value, predicate) { | ||
| for(let i = 0; i < value.length; i++)if (predicate(value[i])) return value[i]; | ||
| } | ||
| function eachArray(obj, iterator) { | ||
| if ((0, core_namespaceObject.isArray)(obj)) obj.forEach(iterator); | ||
| } | ||
| function each(obj, iterator) { | ||
| if ((0, core_namespaceObject.isNullish)(obj)) return; | ||
| if ((0, core_namespaceObject.isArray)(obj)) return void obj.forEach(iterator); | ||
| if ((0, core_namespaceObject.isFormData)(obj)) return void obj.forEach((val, key)=>iterator(val, key)); | ||
| for(const key in obj)if (core_namespaceObject.hasOwnProperty.call(obj, key)) iterator(obj[key], key); | ||
| } | ||
| const extend = function(obj, ...args) { | ||
| for (const source of args)for(const prop in source)if (void 0 !== source[prop]) obj[prop] = source[prop]; | ||
| return obj; | ||
| }; | ||
| function entries(obj) { | ||
| const ownProps = Object.keys(obj); | ||
| let i = ownProps.length; | ||
| const resArray = new Array(i); | ||
| while(i--)resArray[i] = [ | ||
| ownProps[i], | ||
| obj[ownProps[i]] | ||
| ]; | ||
| return resArray; | ||
| } | ||
| const trySafe = function(fn) { | ||
| try { | ||
| return fn(); | ||
| } catch { | ||
| return; | ||
| } | ||
| }; | ||
| const safewrap = function(f) { | ||
| return function(...args) { | ||
| try { | ||
| return f.apply(this, args); | ||
| } catch (e) { | ||
| external_logger_js_namespaceObject.logger.critical('Implementation error. Please turn on debug mode and open a ticket on https://app.posthog.com/home#panel=support%3Asupport%3A.'); | ||
| external_logger_js_namespaceObject.logger.critical(e); | ||
| } | ||
| }; | ||
| }; | ||
| const safewrapClass = function(klass, functions) { | ||
| for(let i = 0; i < functions.length; i++)klass.prototype[functions[i]] = safewrap(klass.prototype[functions[i]]); | ||
| }; | ||
| const stripEmptyProperties = function(p) { | ||
| const ret = {}; | ||
| each(p, function(v, k) { | ||
| if ((0, core_namespaceObject.isString)(v) && v.length > 0 || (0, core_namespaceObject.isNumber)(v)) ret[k] = v; | ||
| }); | ||
| return ret; | ||
| }; | ||
| function deepCircularCopy(value, customizer) { | ||
| const COPY_IN_PROGRESS_SET = new Set(); | ||
| function internalDeepCircularCopy(value, key) { | ||
| if (value !== Object(value)) return customizer ? customizer(value, key) : value; | ||
| if (COPY_IN_PROGRESS_SET.has(value)) return; | ||
| COPY_IN_PROGRESS_SET.add(value); | ||
| let result; | ||
| if ((0, core_namespaceObject.isArray)(value)) { | ||
| result = []; | ||
| eachArray(value, (it)=>{ | ||
| result.push(internalDeepCircularCopy(it)); | ||
| }); | ||
| } else { | ||
| const copy = {}; | ||
| each(value, (val, key)=>{ | ||
| if (!COPY_IN_PROGRESS_SET.has(val)) copy[key] = internalDeepCircularCopy(val, key); | ||
| }); | ||
| result = copy; | ||
| } | ||
| return result; | ||
| } | ||
| return internalDeepCircularCopy(value); | ||
| } | ||
| function _copyAndTruncateStrings(object, maxStringLength) { | ||
| return deepCircularCopy(object, (value)=>{ | ||
| if ((0, core_namespaceObject.isString)(value)) return value.slice(0, maxStringLength); | ||
| return value; | ||
| }); | ||
| } | ||
| const EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE = [ | ||
| 'herokuapp.com', | ||
| 'vercel.app', | ||
| 'netlify.app' | ||
| ]; | ||
| function isCrossDomainCookie(documentLocation) { | ||
| const hostname = documentLocation?.hostname; | ||
| if (!(0, core_namespaceObject.isString)(hostname)) return false; | ||
| const lastTwoParts = hostname.split('.').slice(-2).join('.'); | ||
| for (const excluded of EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE)if (lastTwoParts === excluded) return false; | ||
| return true; | ||
| } | ||
| function addEventListener(element, event, callback, options) { | ||
| const { capture = false, passive = true } = options ?? {}; | ||
| element?.addEventListener(event, callback, { | ||
| capture, | ||
| passive | ||
| }); | ||
| } | ||
| function migrateConfigField(config, newField, oldField, defaultValue, loggerInstance) { | ||
| const hasNewField = newField in config && !(0, core_namespaceObject.isNullish)(config[newField]); | ||
| const hasOldField = oldField in config && !(0, core_namespaceObject.isNullish)(config[oldField]); | ||
| if (hasNewField) return config[newField]; | ||
| if (hasOldField) { | ||
| if (loggerInstance) loggerInstance.warn(`Config field '${oldField}' is deprecated. Please use '${newField}' instead. The old field will be removed in a future major version.`); | ||
| return config[oldField]; | ||
| } | ||
| return defaultValue; | ||
| } | ||
| const TOOLBAR_INTERNAL_INSTANCE_NAME = 'ph_toolbar_internal'; | ||
| function isToolbarInstance(config) { | ||
| return config.name === TOOLBAR_INTERNAL_INSTANCE_NAME; | ||
| } | ||
| exports._copyAndTruncateStrings = __webpack_exports__._copyAndTruncateStrings; | ||
| exports.addEventListener = __webpack_exports__.addEventListener; | ||
| exports.each = __webpack_exports__.each; | ||
| exports.eachArray = __webpack_exports__.eachArray; | ||
| exports.entries = __webpack_exports__.entries; | ||
| exports.extend = __webpack_exports__.extend; | ||
| exports.find = __webpack_exports__.find; | ||
| exports.isCrossDomainCookie = __webpack_exports__.isCrossDomainCookie; | ||
| exports.isToolbarInstance = __webpack_exports__.isToolbarInstance; | ||
| exports.migrateConfigField = __webpack_exports__.migrateConfigField; | ||
| exports.safewrap = __webpack_exports__.safewrap; | ||
| exports.safewrapClass = __webpack_exports__.safewrapClass; | ||
| exports.stripEmptyProperties = __webpack_exports__.stripEmptyProperties; | ||
| exports.trySafe = __webpack_exports__.trySafe; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "_copyAndTruncateStrings", | ||
| "addEventListener", | ||
| "each", | ||
| "eachArray", | ||
| "entries", | ||
| "extend", | ||
| "find", | ||
| "isCrossDomainCookie", | ||
| "isToolbarInstance", | ||
| "migrateConfigField", | ||
| "safewrap", | ||
| "safewrapClass", | ||
| "stripEmptyProperties", | ||
| "trySafe" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| import { hasOwnProperty as core_hasOwnProperty, isArray, isFormData, isNullish, isNumber, isString } from "@posthog/core"; | ||
| import { logger } from "./logger.mjs"; | ||
| function find(value, predicate) { | ||
| for(let i = 0; i < value.length; i++)if (predicate(value[i])) return value[i]; | ||
| } | ||
| function eachArray(obj, iterator) { | ||
| if (isArray(obj)) obj.forEach(iterator); | ||
| } | ||
| function each(obj, iterator) { | ||
| if (isNullish(obj)) return; | ||
| if (isArray(obj)) return void obj.forEach(iterator); | ||
| if (isFormData(obj)) return void obj.forEach((val, key)=>iterator(val, key)); | ||
| for(const key in obj)if (core_hasOwnProperty.call(obj, key)) iterator(obj[key], key); | ||
| } | ||
| const extend = function(obj, ...args) { | ||
| for (const source of args)for(const prop in source)if (void 0 !== source[prop]) obj[prop] = source[prop]; | ||
| return obj; | ||
| }; | ||
| function entries(obj) { | ||
| const ownProps = Object.keys(obj); | ||
| let i = ownProps.length; | ||
| const resArray = new Array(i); | ||
| while(i--)resArray[i] = [ | ||
| ownProps[i], | ||
| obj[ownProps[i]] | ||
| ]; | ||
| return resArray; | ||
| } | ||
| const trySafe = function(fn) { | ||
| try { | ||
| return fn(); | ||
| } catch { | ||
| return; | ||
| } | ||
| }; | ||
| const safewrap = function(f) { | ||
| return function(...args) { | ||
| try { | ||
| return f.apply(this, args); | ||
| } catch (e) { | ||
| logger.critical('Implementation error. Please turn on debug mode and open a ticket on https://app.posthog.com/home#panel=support%3Asupport%3A.'); | ||
| logger.critical(e); | ||
| } | ||
| }; | ||
| }; | ||
| const safewrapClass = function(klass, functions) { | ||
| for(let i = 0; i < functions.length; i++)klass.prototype[functions[i]] = safewrap(klass.prototype[functions[i]]); | ||
| }; | ||
| const stripEmptyProperties = function(p) { | ||
| const ret = {}; | ||
| each(p, function(v, k) { | ||
| if (isString(v) && v.length > 0 || isNumber(v)) ret[k] = v; | ||
| }); | ||
| return ret; | ||
| }; | ||
| function deepCircularCopy(value, customizer) { | ||
| const COPY_IN_PROGRESS_SET = new Set(); | ||
| function internalDeepCircularCopy(value, key) { | ||
| if (value !== Object(value)) return customizer ? customizer(value, key) : value; | ||
| if (COPY_IN_PROGRESS_SET.has(value)) return; | ||
| COPY_IN_PROGRESS_SET.add(value); | ||
| let result; | ||
| if (isArray(value)) { | ||
| result = []; | ||
| eachArray(value, (it)=>{ | ||
| result.push(internalDeepCircularCopy(it)); | ||
| }); | ||
| } else { | ||
| const copy = {}; | ||
| each(value, (val, key)=>{ | ||
| if (!COPY_IN_PROGRESS_SET.has(val)) copy[key] = internalDeepCircularCopy(val, key); | ||
| }); | ||
| result = copy; | ||
| } | ||
| return result; | ||
| } | ||
| return internalDeepCircularCopy(value); | ||
| } | ||
| function _copyAndTruncateStrings(object, maxStringLength) { | ||
| return deepCircularCopy(object, (value)=>{ | ||
| if (isString(value)) return value.slice(0, maxStringLength); | ||
| return value; | ||
| }); | ||
| } | ||
| const EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE = [ | ||
| 'herokuapp.com', | ||
| 'vercel.app', | ||
| 'netlify.app' | ||
| ]; | ||
| function isCrossDomainCookie(documentLocation) { | ||
| const hostname = documentLocation?.hostname; | ||
| if (!isString(hostname)) return false; | ||
| const lastTwoParts = hostname.split('.').slice(-2).join('.'); | ||
| for (const excluded of EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE)if (lastTwoParts === excluded) return false; | ||
| return true; | ||
| } | ||
| function addEventListener(element, event, callback, options) { | ||
| const { capture = false, passive = true } = options ?? {}; | ||
| element?.addEventListener(event, callback, { | ||
| capture, | ||
| passive | ||
| }); | ||
| } | ||
| function migrateConfigField(config, newField, oldField, defaultValue, loggerInstance) { | ||
| const hasNewField = newField in config && !isNullish(config[newField]); | ||
| const hasOldField = oldField in config && !isNullish(config[oldField]); | ||
| if (hasNewField) return config[newField]; | ||
| if (hasOldField) { | ||
| if (loggerInstance) loggerInstance.warn(`Config field '${oldField}' is deprecated. Please use '${newField}' instead. The old field will be removed in a future major version.`); | ||
| return config[oldField]; | ||
| } | ||
| return defaultValue; | ||
| } | ||
| const TOOLBAR_INTERNAL_INSTANCE_NAME = 'ph_toolbar_internal'; | ||
| function isToolbarInstance(config) { | ||
| return config.name === TOOLBAR_INTERNAL_INSTANCE_NAME; | ||
| } | ||
| export { _copyAndTruncateStrings, addEventListener, each, eachArray, entries, extend, find, isCrossDomainCookie, isToolbarInstance, migrateConfigField, safewrap, safewrapClass, stripEmptyProperties, trySafe }; |
| declare const win: (Window & typeof globalThis) | undefined; | ||
| export declare const navigator: Navigator | undefined; | ||
| export declare const document: Document | undefined; | ||
| export declare const location: Location | undefined; | ||
| export declare const fetch: typeof globalThis.fetch | undefined; | ||
| export declare const XMLHttpRequest: { | ||
| new (): XMLHttpRequest; | ||
| prototype: XMLHttpRequest; | ||
| readonly UNSENT: 0; | ||
| readonly OPENED: 1; | ||
| readonly HEADERS_RECEIVED: 2; | ||
| readonly LOADING: 3; | ||
| readonly DONE: 4; | ||
| } | undefined; | ||
| export declare const AbortController: { | ||
| new (): AbortController; | ||
| prototype: AbortController; | ||
| } | undefined; | ||
| export declare const CompressionStream: { | ||
| new (format: CompressionFormat): CompressionStream; | ||
| prototype: CompressionStream; | ||
| } | undefined; | ||
| export declare const userAgent: string | undefined; | ||
| export declare function isBrowserOnline(): boolean; | ||
| export { win as window }; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| AbortController: ()=>AbortController, | ||
| CompressionStream: ()=>CompressionStream, | ||
| XMLHttpRequest: ()=>XMLHttpRequest, | ||
| document: ()=>document, | ||
| fetch: ()=>fetch, | ||
| isBrowserOnline: ()=>isBrowserOnline, | ||
| location: ()=>location, | ||
| navigator: ()=>navigator, | ||
| userAgent: ()=>userAgent, | ||
| window: ()=>win | ||
| }); | ||
| const win = 'undefined' != typeof window ? window : void 0; | ||
| const global = 'undefined' != typeof globalThis ? globalThis : win; | ||
| const navigator = global?.navigator; | ||
| const document = global?.document; | ||
| const location = global?.location; | ||
| const fetch = global?.fetch; | ||
| const XMLHttpRequest = global?.XMLHttpRequest && 'withCredentials' in new global.XMLHttpRequest() ? global.XMLHttpRequest : void 0; | ||
| const AbortController = global?.AbortController; | ||
| const CompressionStream = global?.CompressionStream; | ||
| const userAgent = navigator?.userAgent; | ||
| function isBrowserOnline() { | ||
| return !!(win && false !== win.navigator.onLine); | ||
| } | ||
| exports.AbortController = __webpack_exports__.AbortController; | ||
| exports.CompressionStream = __webpack_exports__.CompressionStream; | ||
| exports.XMLHttpRequest = __webpack_exports__.XMLHttpRequest; | ||
| exports.document = __webpack_exports__.document; | ||
| exports.fetch = __webpack_exports__.fetch; | ||
| exports.isBrowserOnline = __webpack_exports__.isBrowserOnline; | ||
| exports.location = __webpack_exports__.location; | ||
| exports.navigator = __webpack_exports__.navigator; | ||
| exports.userAgent = __webpack_exports__.userAgent; | ||
| exports.window = __webpack_exports__.window; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "AbortController", | ||
| "CompressionStream", | ||
| "XMLHttpRequest", | ||
| "document", | ||
| "fetch", | ||
| "isBrowserOnline", | ||
| "location", | ||
| "navigator", | ||
| "userAgent", | ||
| "window" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| const win = 'undefined' != typeof window ? window : void 0; | ||
| const global = 'undefined' != typeof globalThis ? globalThis : win; | ||
| const globals_navigator = global?.navigator; | ||
| const globals_document = global?.document; | ||
| const globals_location = global?.location; | ||
| const fetch = global?.fetch; | ||
| const XMLHttpRequest = global?.XMLHttpRequest && 'withCredentials' in new global.XMLHttpRequest() ? global.XMLHttpRequest : void 0; | ||
| const AbortController = global?.AbortController; | ||
| const CompressionStream = global?.CompressionStream; | ||
| const userAgent = globals_navigator?.userAgent; | ||
| function isBrowserOnline() { | ||
| return !!(win && false !== win.navigator.onLine); | ||
| } | ||
| export { AbortController, CompressionStream, XMLHttpRequest, globals_document as document, fetch, isBrowserOnline, globals_location as location, globals_navigator as navigator, userAgent, win as window }; |
| import type { Logger } from '@posthog/types'; | ||
| export type CreateLoggerOptions = { | ||
| debugEnabled?: boolean; | ||
| }; | ||
| export type PosthogJsLogger = Omit<Logger, 'createLogger' | 'debug' | 'info' | 'warn' | 'error' | 'trace' | 'fatal'> & { | ||
| _log: (level: 'debug' | 'log' | 'warn' | 'error', ...args: any[]) => void; | ||
| debug: (...args: any[]) => void; | ||
| info: (...args: any[]) => void; | ||
| warn: (...args: any[]) => void; | ||
| error: (...args: any[]) => void; | ||
| critical: (...args: any[]) => void; | ||
| uninitializedWarning: (methodName: string) => void; | ||
| createLogger: (prefix: string, options?: CreateLoggerOptions) => PosthogJsLogger; | ||
| }; | ||
| export declare const logger: PosthogJsLogger; | ||
| export declare const createLogger: (prefix: string, options?: CreateLoggerOptions) => PosthogJsLogger; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.n = (module)=>{ | ||
| var getter = module && module.__esModule ? ()=>module['default'] : ()=>module; | ||
| __webpack_require__.d(getter, { | ||
| a: getter | ||
| }); | ||
| return getter; | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| logger: ()=>logger_logger, | ||
| createLogger: ()=>createLogger | ||
| }); | ||
| const external_config_js_namespaceObject = require("../config.js"); | ||
| var external_config_js_default = /*#__PURE__*/ __webpack_require__.n(external_config_js_namespaceObject); | ||
| const core_namespaceObject = require("@posthog/core"); | ||
| const external_globals_js_namespaceObject = require("./globals.js"); | ||
| const _createLogger = (prefix, { debugEnabled } = {})=>{ | ||
| const logger = { | ||
| _log: (level, ...args)=>{ | ||
| if (external_globals_js_namespaceObject.window && (external_config_js_default().DEBUG || external_globals_js_namespaceObject.window.POSTHOG_DEBUG || debugEnabled) && !(0, core_namespaceObject.isUndefined)(external_globals_js_namespaceObject.window.console) && external_globals_js_namespaceObject.window.console) { | ||
| const consoleLog = '__rrweb_original__' in external_globals_js_namespaceObject.window.console[level] ? external_globals_js_namespaceObject.window.console[level]['__rrweb_original__'] : external_globals_js_namespaceObject.window.console[level]; | ||
| consoleLog(prefix, ...args); | ||
| } | ||
| }, | ||
| debug: (...args)=>{ | ||
| logger._log('debug', ...args); | ||
| }, | ||
| info: (...args)=>{ | ||
| logger._log('log', ...args); | ||
| }, | ||
| warn: (...args)=>{ | ||
| logger._log('warn', ...args); | ||
| }, | ||
| error: (...args)=>{ | ||
| logger._log('error', ...args); | ||
| }, | ||
| critical: (...args)=>{ | ||
| console.error(prefix, ...args); | ||
| }, | ||
| uninitializedWarning: (methodName)=>{ | ||
| logger.error(`You must initialize PostHog before calling ${methodName}`); | ||
| }, | ||
| createLogger: (additionalPrefix, options)=>_createLogger(`${prefix} ${additionalPrefix}`, options) | ||
| }; | ||
| return logger; | ||
| }; | ||
| const logger_logger = _createLogger('[PostHog.js]'); | ||
| const createLogger = logger_logger.createLogger; | ||
| exports.createLogger = __webpack_exports__.createLogger; | ||
| exports.logger = __webpack_exports__.logger; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "createLogger", | ||
| "logger" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| import config from "../config.mjs"; | ||
| import { isUndefined } from "@posthog/core"; | ||
| import { window as external_globals_mjs_window } from "./globals.mjs"; | ||
| const _createLogger = (prefix, { debugEnabled } = {})=>{ | ||
| const logger = { | ||
| _log: (level, ...args)=>{ | ||
| if (external_globals_mjs_window && (config.DEBUG || external_globals_mjs_window.POSTHOG_DEBUG || debugEnabled) && !isUndefined(external_globals_mjs_window.console) && external_globals_mjs_window.console) { | ||
| const consoleLog = '__rrweb_original__' in external_globals_mjs_window.console[level] ? external_globals_mjs_window.console[level]['__rrweb_original__'] : external_globals_mjs_window.console[level]; | ||
| consoleLog(prefix, ...args); | ||
| } | ||
| }, | ||
| debug: (...args)=>{ | ||
| logger._log('debug', ...args); | ||
| }, | ||
| info: (...args)=>{ | ||
| logger._log('log', ...args); | ||
| }, | ||
| warn: (...args)=>{ | ||
| logger._log('warn', ...args); | ||
| }, | ||
| error: (...args)=>{ | ||
| logger._log('error', ...args); | ||
| }, | ||
| critical: (...args)=>{ | ||
| console.error(prefix, ...args); | ||
| }, | ||
| uninitializedWarning: (methodName)=>{ | ||
| logger.error(`You must initialize PostHog before calling ${methodName}`); | ||
| }, | ||
| createLogger: (additionalPrefix, options)=>_createLogger(`${prefix} ${additionalPrefix}`, options) | ||
| }; | ||
| return logger; | ||
| }; | ||
| const logger_logger = _createLogger('[PostHog.js]'); | ||
| const createLogger = logger_logger.createLogger; | ||
| export { createLogger, logger_logger as logger }; |
| import { type PropertyMatchType } from './property-utils'; | ||
| export declare function doesDeviceTypeMatch(deviceTypes?: string[], matchType?: PropertyMatchType): boolean; | ||
| export declare function hasPeriodPassed(periodDays?: number, lastSeenDate?: string | Date | null): boolean; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| hasPeriodPassed: ()=>hasPeriodPassed, | ||
| doesDeviceTypeMatch: ()=>doesDeviceTypeMatch | ||
| }); | ||
| const core_namespaceObject = require("@posthog/core"); | ||
| const external_globals_js_namespaceObject = require("./globals.js"); | ||
| const external_property_utils_js_namespaceObject = require("./property-utils.js"); | ||
| function doesDeviceTypeMatch(deviceTypes, matchType) { | ||
| if (!deviceTypes || 0 === deviceTypes.length) return true; | ||
| if (!external_globals_js_namespaceObject.userAgent) return false; | ||
| const deviceType = (0, core_namespaceObject.detectDeviceType)(external_globals_js_namespaceObject.userAgent, { | ||
| userAgentDataPlatform: external_globals_js_namespaceObject.navigator?.userAgentData?.platform, | ||
| maxTouchPoints: external_globals_js_namespaceObject.navigator?.maxTouchPoints, | ||
| screenWidth: external_globals_js_namespaceObject.window?.screen?.width, | ||
| screenHeight: external_globals_js_namespaceObject.window?.screen?.height, | ||
| devicePixelRatio: external_globals_js_namespaceObject.window?.devicePixelRatio | ||
| }); | ||
| return external_property_utils_js_namespaceObject.propertyComparisons[matchType ?? 'icontains'](deviceTypes, [ | ||
| deviceType | ||
| ]); | ||
| } | ||
| function hasPeriodPassed(periodDays, lastSeenDate) { | ||
| if (!periodDays || !lastSeenDate) return true; | ||
| const date = 'string' == typeof lastSeenDate ? new Date(lastSeenDate) : lastSeenDate; | ||
| const now = new Date(); | ||
| const diffMs = Math.abs(now.getTime() - date.getTime()); | ||
| const diffDays = Math.ceil(diffMs / 86400000); | ||
| return diffDays > periodDays; | ||
| } | ||
| exports.doesDeviceTypeMatch = __webpack_exports__.doesDeviceTypeMatch; | ||
| exports.hasPeriodPassed = __webpack_exports__.hasPeriodPassed; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "doesDeviceTypeMatch", | ||
| "hasPeriodPassed" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| import { detectDeviceType } from "@posthog/core"; | ||
| import { navigator as external_globals_mjs_navigator, userAgent, window as external_globals_mjs_window } from "./globals.mjs"; | ||
| import { propertyComparisons } from "./property-utils.mjs"; | ||
| function doesDeviceTypeMatch(deviceTypes, matchType) { | ||
| if (!deviceTypes || 0 === deviceTypes.length) return true; | ||
| if (!userAgent) return false; | ||
| const deviceType = detectDeviceType(userAgent, { | ||
| userAgentDataPlatform: external_globals_mjs_navigator?.userAgentData?.platform, | ||
| maxTouchPoints: external_globals_mjs_navigator?.maxTouchPoints, | ||
| screenWidth: external_globals_mjs_window?.screen?.width, | ||
| screenHeight: external_globals_mjs_window?.screen?.height, | ||
| devicePixelRatio: external_globals_mjs_window?.devicePixelRatio | ||
| }); | ||
| return propertyComparisons[matchType ?? 'icontains'](deviceTypes, [ | ||
| deviceType | ||
| ]); | ||
| } | ||
| function hasPeriodPassed(periodDays, lastSeenDate) { | ||
| if (!periodDays || !lastSeenDate) return true; | ||
| const date = 'string' == typeof lastSeenDate ? new Date(lastSeenDate) : lastSeenDate; | ||
| const now = new Date(); | ||
| const diffMs = Math.abs(now.getTime() - date.getTime()); | ||
| const diffDays = Math.ceil(diffMs / 86400000); | ||
| return diffDays > periodDays; | ||
| } | ||
| export { doesDeviceTypeMatch, hasPeriodPassed }; |
| import type { Properties } from '@posthog/types'; | ||
| export type PropertyMatchType = 'exact' | 'is_not' | 'regex' | 'not_regex' | 'icontains' | 'not_icontains'; | ||
| export type PropertyOperator = PropertyMatchType | 'gt' | 'lt'; | ||
| export type PropertyFilters = { | ||
| [propertyName: string]: { | ||
| values: string[]; | ||
| operator: PropertyOperator; | ||
| }; | ||
| }; | ||
| export interface SessionRecordingTriggerPropertyFilter { | ||
| key: string; | ||
| value?: string | number | boolean | (string | number | boolean)[] | null; | ||
| operator?: PropertyOperator | null; | ||
| type?: string | null; | ||
| } | ||
| export declare function getPersonPropertiesHash(distinct_id: string, userPropertiesToSet?: Properties, userPropertiesToSetOnce?: Properties): string; | ||
| export declare const propertyComparisons: Record<PropertyOperator, (targets: string[], values: string[]) => boolean>; | ||
| /** | ||
| * Evaluate trigger property filters (WHERE clauses) against event and person properties. | ||
| * All filters must match (implicit AND). Returns true if no filters are present. | ||
| */ | ||
| export declare function matchTriggerPropertyFilters(filters: SessionRecordingTriggerPropertyFilter[] | undefined, eventProperties: Properties | undefined, personProperties: Properties | undefined): boolean; | ||
| export declare function matchPropertyFilters(propertyFilters: PropertyFilters | undefined, eventProperties: Properties | undefined): boolean; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| matchPropertyFilters: ()=>matchPropertyFilters, | ||
| propertyComparisons: ()=>propertyComparisons, | ||
| getPersonPropertiesHash: ()=>getPersonPropertiesHash, | ||
| matchTriggerPropertyFilters: ()=>matchTriggerPropertyFilters | ||
| }); | ||
| const core_namespaceObject = require("@posthog/core"); | ||
| const external_request_utils_js_namespaceObject = require("./request-utils.js"); | ||
| const external_regex_utils_js_namespaceObject = require("./regex-utils.js"); | ||
| function getPersonPropertiesHash(distinct_id, userPropertiesToSet, userPropertiesToSetOnce) { | ||
| return (0, external_request_utils_js_namespaceObject.jsonStringify)({ | ||
| distinct_id, | ||
| userPropertiesToSet, | ||
| userPropertiesToSetOnce | ||
| }); | ||
| } | ||
| const propertyComparisons = { | ||
| exact: (targets, values)=>values.some((value)=>targets.some((target)=>value === target)), | ||
| is_not: (targets, values)=>values.every((value)=>targets.every((target)=>value !== target)), | ||
| regex: (targets, values)=>values.some((value)=>targets.some((target)=>(0, external_regex_utils_js_namespaceObject.isMatchingRegex)(value, target))), | ||
| not_regex: (targets, values)=>values.every((value)=>targets.every((target)=>!(0, external_regex_utils_js_namespaceObject.isMatchingRegex)(value, target))), | ||
| icontains: (targets, values)=>values.map(toLowerCase).some((value)=>targets.map(toLowerCase).some((target)=>value.includes(target))), | ||
| not_icontains: (targets, values)=>values.map(toLowerCase).every((value)=>targets.map(toLowerCase).every((target)=>!value.includes(target))), | ||
| gt: (targets, values)=>values.some((value)=>{ | ||
| const numValue = parseFloat(value); | ||
| return !isNaN(numValue) && targets.some((t)=>numValue > parseFloat(t)); | ||
| }), | ||
| lt: (targets, values)=>values.some((value)=>{ | ||
| const numValue = parseFloat(value); | ||
| return !isNaN(numValue) && targets.some((t)=>numValue < parseFloat(t)); | ||
| }) | ||
| }; | ||
| const toLowerCase = (v)=>v.toLowerCase(); | ||
| const NEGATIVE_OPERATORS = new Set([ | ||
| 'is_not', | ||
| 'not_icontains', | ||
| 'not_regex' | ||
| ]); | ||
| function matchTriggerPropertyFilters(filters, eventProperties, personProperties) { | ||
| if (!filters || 0 === filters.length) return true; | ||
| return filters.every((filter)=>{ | ||
| const source = 'person' === filter.type ? personProperties : eventProperties; | ||
| const propertyValue = source?.[filter.key]; | ||
| const operator = filter.operator || 'exact'; | ||
| if ((0, core_namespaceObject.isUndefined)(propertyValue) || (0, core_namespaceObject.isNull)(propertyValue)) return NEGATIVE_OPERATORS.has(operator); | ||
| const comparisonFunction = propertyComparisons[operator]; | ||
| if (!comparisonFunction) return false; | ||
| if ((0, core_namespaceObject.isUndefined)(filter.value) || (0, core_namespaceObject.isNull)(filter.value)) return false; | ||
| const targetValues = (0, core_namespaceObject.isArray)(filter.value) ? filter.value.map(String) : [ | ||
| String(filter.value) | ||
| ]; | ||
| const actualValues = (0, core_namespaceObject.isArray)(propertyValue) ? propertyValue.map(String) : [ | ||
| String(propertyValue) | ||
| ]; | ||
| return comparisonFunction(targetValues, actualValues); | ||
| }); | ||
| } | ||
| function matchPropertyFilters(propertyFilters, eventProperties) { | ||
| if (!propertyFilters) return true; | ||
| return Object.entries(propertyFilters).every(([propertyName, filter])=>{ | ||
| const eventPropertyValue = eventProperties?.[propertyName]; | ||
| if ((0, core_namespaceObject.isUndefined)(eventPropertyValue) || (0, core_namespaceObject.isNull)(eventPropertyValue)) return false; | ||
| const eventValues = [ | ||
| String(eventPropertyValue) | ||
| ]; | ||
| const comparisonFunction = propertyComparisons[filter.operator]; | ||
| if (!comparisonFunction) return false; | ||
| return comparisonFunction(filter.values, eventValues); | ||
| }); | ||
| } | ||
| exports.getPersonPropertiesHash = __webpack_exports__.getPersonPropertiesHash; | ||
| exports.matchPropertyFilters = __webpack_exports__.matchPropertyFilters; | ||
| exports.matchTriggerPropertyFilters = __webpack_exports__.matchTriggerPropertyFilters; | ||
| exports.propertyComparisons = __webpack_exports__.propertyComparisons; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "getPersonPropertiesHash", | ||
| "matchPropertyFilters", | ||
| "matchTriggerPropertyFilters", | ||
| "propertyComparisons" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| import { isArray, isNull, isUndefined } from "@posthog/core"; | ||
| import { jsonStringify } from "./request-utils.mjs"; | ||
| import { isMatchingRegex } from "./regex-utils.mjs"; | ||
| function getPersonPropertiesHash(distinct_id, userPropertiesToSet, userPropertiesToSetOnce) { | ||
| return jsonStringify({ | ||
| distinct_id, | ||
| userPropertiesToSet, | ||
| userPropertiesToSetOnce | ||
| }); | ||
| } | ||
| const propertyComparisons = { | ||
| exact: (targets, values)=>values.some((value)=>targets.some((target)=>value === target)), | ||
| is_not: (targets, values)=>values.every((value)=>targets.every((target)=>value !== target)), | ||
| regex: (targets, values)=>values.some((value)=>targets.some((target)=>isMatchingRegex(value, target))), | ||
| not_regex: (targets, values)=>values.every((value)=>targets.every((target)=>!isMatchingRegex(value, target))), | ||
| icontains: (targets, values)=>values.map(toLowerCase).some((value)=>targets.map(toLowerCase).some((target)=>value.includes(target))), | ||
| not_icontains: (targets, values)=>values.map(toLowerCase).every((value)=>targets.map(toLowerCase).every((target)=>!value.includes(target))), | ||
| gt: (targets, values)=>values.some((value)=>{ | ||
| const numValue = parseFloat(value); | ||
| return !isNaN(numValue) && targets.some((t)=>numValue > parseFloat(t)); | ||
| }), | ||
| lt: (targets, values)=>values.some((value)=>{ | ||
| const numValue = parseFloat(value); | ||
| return !isNaN(numValue) && targets.some((t)=>numValue < parseFloat(t)); | ||
| }) | ||
| }; | ||
| const toLowerCase = (v)=>v.toLowerCase(); | ||
| const NEGATIVE_OPERATORS = new Set([ | ||
| 'is_not', | ||
| 'not_icontains', | ||
| 'not_regex' | ||
| ]); | ||
| function matchTriggerPropertyFilters(filters, eventProperties, personProperties) { | ||
| if (!filters || 0 === filters.length) return true; | ||
| return filters.every((filter)=>{ | ||
| const source = 'person' === filter.type ? personProperties : eventProperties; | ||
| const propertyValue = source?.[filter.key]; | ||
| const operator = filter.operator || 'exact'; | ||
| if (isUndefined(propertyValue) || isNull(propertyValue)) return NEGATIVE_OPERATORS.has(operator); | ||
| const comparisonFunction = propertyComparisons[operator]; | ||
| if (!comparisonFunction) return false; | ||
| if (isUndefined(filter.value) || isNull(filter.value)) return false; | ||
| const targetValues = isArray(filter.value) ? filter.value.map(String) : [ | ||
| String(filter.value) | ||
| ]; | ||
| const actualValues = isArray(propertyValue) ? propertyValue.map(String) : [ | ||
| String(propertyValue) | ||
| ]; | ||
| return comparisonFunction(targetValues, actualValues); | ||
| }); | ||
| } | ||
| function matchPropertyFilters(propertyFilters, eventProperties) { | ||
| if (!propertyFilters) return true; | ||
| return Object.entries(propertyFilters).every(([propertyName, filter])=>{ | ||
| const eventPropertyValue = eventProperties?.[propertyName]; | ||
| if (isUndefined(eventPropertyValue) || isNull(eventPropertyValue)) return false; | ||
| const eventValues = [ | ||
| String(eventPropertyValue) | ||
| ]; | ||
| const comparisonFunction = propertyComparisons[filter.operator]; | ||
| if (!comparisonFunction) return false; | ||
| return comparisonFunction(filter.values, eventValues); | ||
| }); | ||
| } | ||
| export { getPersonPropertiesHash, matchPropertyFilters, matchTriggerPropertyFilters, propertyComparisons }; |
| interface NativeImplementationsCache { | ||
| MutationObserver: typeof MutationObserver; | ||
| } | ||
| type BrowserWindow = Window & typeof globalThis; | ||
| export declare function getNativeImplementation<T extends keyof NativeImplementationsCache>(name: T, assignableWindow: BrowserWindow): NativeImplementationsCache[T]; | ||
| export declare function getNativeMutationObserverImplementation(assignableWindow: BrowserWindow): typeof MutationObserver; | ||
| export {}; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| getNativeImplementation: ()=>getNativeImplementation, | ||
| getNativeMutationObserverImplementation: ()=>getNativeMutationObserverImplementation | ||
| }); | ||
| const core_namespaceObject = require("@posthog/core"); | ||
| const external_logger_js_namespaceObject = require("./logger.js"); | ||
| const external_type_utils_js_namespaceObject = require("./type-utils.js"); | ||
| const cachedImplementations = {}; | ||
| function getNativeImplementation(name, assignableWindow) { | ||
| const cached = cachedImplementations[name]; | ||
| if (cached) return cached; | ||
| let impl = assignableWindow[name]; | ||
| if ((0, core_namespaceObject.isNativeFunction)(impl) && !(0, external_type_utils_js_namespaceObject.isAngularZonePresent)()) return cachedImplementations[name] = impl.bind(assignableWindow); | ||
| const document = assignableWindow.document; | ||
| if (document && (0, core_namespaceObject.isFunction)(document.createElement)) try { | ||
| const sandbox = document.createElement('iframe'); | ||
| sandbox.hidden = true; | ||
| document.head.appendChild(sandbox); | ||
| const contentWindow = sandbox.contentWindow; | ||
| if (contentWindow && contentWindow[name]) impl = contentWindow[name]; | ||
| document.head.removeChild(sandbox); | ||
| } catch (e) { | ||
| external_logger_js_namespaceObject.logger.warn(`Could not create sandbox iframe for ${name} check, bailing to assignableWindow.${name}: `, e); | ||
| } | ||
| if (!impl || !(0, core_namespaceObject.isFunction)(impl)) return impl; | ||
| return cachedImplementations[name] = impl.bind(assignableWindow); | ||
| } | ||
| function getNativeMutationObserverImplementation(assignableWindow) { | ||
| return getNativeImplementation('MutationObserver', assignableWindow); | ||
| } | ||
| exports.getNativeImplementation = __webpack_exports__.getNativeImplementation; | ||
| exports.getNativeMutationObserverImplementation = __webpack_exports__.getNativeMutationObserverImplementation; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "getNativeImplementation", | ||
| "getNativeMutationObserverImplementation" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| import { isFunction, isNativeFunction } from "@posthog/core"; | ||
| import { logger } from "./logger.mjs"; | ||
| import { isAngularZonePresent } from "./type-utils.mjs"; | ||
| const cachedImplementations = {}; | ||
| function getNativeImplementation(name, assignableWindow) { | ||
| const cached = cachedImplementations[name]; | ||
| if (cached) return cached; | ||
| let impl = assignableWindow[name]; | ||
| if (isNativeFunction(impl) && !isAngularZonePresent()) return cachedImplementations[name] = impl.bind(assignableWindow); | ||
| const document = assignableWindow.document; | ||
| if (document && isFunction(document.createElement)) try { | ||
| const sandbox = document.createElement('iframe'); | ||
| sandbox.hidden = true; | ||
| document.head.appendChild(sandbox); | ||
| const contentWindow = sandbox.contentWindow; | ||
| if (contentWindow && contentWindow[name]) impl = contentWindow[name]; | ||
| document.head.removeChild(sandbox); | ||
| } catch (e) { | ||
| logger.warn(`Could not create sandbox iframe for ${name} check, bailing to assignableWindow.${name}: `, e); | ||
| } | ||
| if (!impl || !isFunction(impl)) return impl; | ||
| return cachedImplementations[name] = impl.bind(assignableWindow); | ||
| } | ||
| function getNativeMutationObserverImplementation(assignableWindow) { | ||
| return getNativeImplementation('MutationObserver', assignableWindow); | ||
| } | ||
| export { getNativeImplementation, getNativeMutationObserverImplementation }; |
| export declare const isValidRegex: (str: string) => boolean; | ||
| export declare const isMatchingRegex: (value: string, pattern: string) => boolean; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| isMatchingRegex: ()=>isMatchingRegex, | ||
| isValidRegex: ()=>isValidRegex | ||
| }); | ||
| const isValidRegex = function(str) { | ||
| try { | ||
| new RegExp(str); | ||
| } catch { | ||
| return false; | ||
| } | ||
| return true; | ||
| }; | ||
| const isMatchingRegex = function(value, pattern) { | ||
| if (!isValidRegex(pattern)) return false; | ||
| try { | ||
| return new RegExp(pattern).test(value); | ||
| } catch { | ||
| return false; | ||
| } | ||
| }; | ||
| exports.isMatchingRegex = __webpack_exports__.isMatchingRegex; | ||
| exports.isValidRegex = __webpack_exports__.isValidRegex; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "isMatchingRegex", | ||
| "isValidRegex" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| const isValidRegex = function(str) { | ||
| try { | ||
| new RegExp(str); | ||
| } catch { | ||
| return false; | ||
| } | ||
| return true; | ||
| }; | ||
| const isMatchingRegex = function(value, pattern) { | ||
| if (!isValidRegex(pattern)) return false; | ||
| try { | ||
| return new RegExp(pattern).test(value); | ||
| } catch { | ||
| return false; | ||
| } | ||
| }; | ||
| export { isMatchingRegex, isValidRegex }; |
| export declare const jsonStringify: (data: any, space?: string | number) => string; | ||
| /** | ||
| * IE11 doesn't support `new URL` | ||
| * so we can create an anchor element and use that to parse the URL | ||
| * there's a lot of overlap between HTMLHyperlinkElementUtils and URL | ||
| * meaning useful properties like `pathname` are available on both | ||
| */ | ||
| export declare const convertToURL: (url: string) => HTMLAnchorElement | null; | ||
| export declare const formDataToQuery: (formdata: Record<string, any> | FormData, arg_separator?: string) => string; | ||
| export declare const getQueryParam: (url: string, param: string) => string; | ||
| export declare const maskQueryParams: <T extends string | undefined>(url: T, maskedParams: string[] | undefined, mask: string) => T extends string ? string : undefined; | ||
| export declare const _getHashParam: (hash: string, param: string) => string | null; | ||
| export declare const isLocalhost: () => boolean; | ||
| export declare const isStatusZeroFailureCircuitBreakerTripped: (consecutiveStatusZeroFailures: number, maxConsecutiveStatusZeroFailures: number) => boolean; | ||
| export declare const updateStatusZeroFailureCount: (statusCode: number, consecutiveStatusZeroFailures: number, maxConsecutiveStatusZeroFailures: number, onCircuitBreakerTripped: () => void) => number; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| jsonStringify: ()=>jsonStringify, | ||
| formDataToQuery: ()=>formDataToQuery, | ||
| getQueryParam: ()=>getQueryParam, | ||
| _getHashParam: ()=>_getHashParam, | ||
| convertToURL: ()=>convertToURL, | ||
| isLocalhost: ()=>isLocalhost, | ||
| updateStatusZeroFailureCount: ()=>updateStatusZeroFailureCount, | ||
| isStatusZeroFailureCircuitBreakerTripped: ()=>isStatusZeroFailureCircuitBreakerTripped, | ||
| maskQueryParams: ()=>maskQueryParams | ||
| }); | ||
| const core_namespaceObject = require("@posthog/core"); | ||
| const external_general_utils_js_namespaceObject = require("./general-utils.js"); | ||
| const external_globals_js_namespaceObject = require("./globals.js"); | ||
| const external_logger_js_namespaceObject = require("./logger.js"); | ||
| const localDomains = [ | ||
| 'localhost', | ||
| '127.0.0.1' | ||
| ]; | ||
| const jsonStringify = (data, space)=>{ | ||
| try { | ||
| return JSON.stringify(data, (_, value)=>'bigint' == typeof value ? value.toString() : value, space); | ||
| } catch { | ||
| return (0, core_namespaceObject.safeJsonStringify)(data); | ||
| } | ||
| }; | ||
| const convertToURL = (url)=>{ | ||
| const location = external_globals_js_namespaceObject.document?.createElement('a'); | ||
| if ((0, core_namespaceObject.isUndefined)(location)) return null; | ||
| location.href = url; | ||
| return location; | ||
| }; | ||
| const formDataToQuery = function(formdata, arg_separator = '&') { | ||
| let use_val; | ||
| let use_key; | ||
| const tph_arr = []; | ||
| (0, external_general_utils_js_namespaceObject.each)(formdata, function(val, key) { | ||
| if ((0, core_namespaceObject.isUndefined)(val) || (0, core_namespaceObject.isUndefined)(key) || 'undefined' === key) return; | ||
| use_val = encodeURIComponent((0, core_namespaceObject.isFile)(val) ? val.name : val.toString()); | ||
| use_key = encodeURIComponent(key); | ||
| tph_arr[tph_arr.length] = use_key + '=' + use_val; | ||
| }); | ||
| return tph_arr.join(arg_separator); | ||
| }; | ||
| const getQueryParam = function(url, param) { | ||
| const withoutHash = url.split('#')[0] || ''; | ||
| const queryParams = withoutHash.split(/\?(.*)/)[1] || ''; | ||
| const cleanedQueryParams = queryParams.replace(/^\?+/g, ''); | ||
| const queryParts = cleanedQueryParams.split('&'); | ||
| let keyValuePair; | ||
| for(let i = 0; i < queryParts.length; i++){ | ||
| const parts = queryParts[i].split('='); | ||
| if (parts[0] === param) { | ||
| keyValuePair = parts; | ||
| break; | ||
| } | ||
| } | ||
| if (!(0, core_namespaceObject.isArray)(keyValuePair) || keyValuePair.length < 2) return ''; | ||
| { | ||
| let result = keyValuePair[1]; | ||
| try { | ||
| result = decodeURIComponent(result); | ||
| } catch { | ||
| external_logger_js_namespaceObject.logger.error('Skipping decoding for malformed query param: ' + result); | ||
| } | ||
| return result.replace(/\+/g, ' '); | ||
| } | ||
| }; | ||
| const maskQueryParams = function(url, maskedParams, mask) { | ||
| if (!url || !maskedParams || !maskedParams.length) return url; | ||
| const splitHash = url.split('#'); | ||
| const withoutHash = splitHash[0] || ''; | ||
| const hash = splitHash[1]; | ||
| const splitQuery = withoutHash.split('?'); | ||
| const queryString = splitQuery[1]; | ||
| const urlWithoutQueryAndHash = splitQuery[0]; | ||
| const queryParts = (queryString || '').split('&'); | ||
| const paramStrings = []; | ||
| for(let i = 0; i < queryParts.length; i++){ | ||
| const keyValuePair = queryParts[i].split('='); | ||
| if ((0, core_namespaceObject.isArray)(keyValuePair)) if (maskedParams.includes(keyValuePair[0])) paramStrings.push(keyValuePair[0] + '=' + mask); | ||
| else paramStrings.push(queryParts[i]); | ||
| } | ||
| let result = urlWithoutQueryAndHash; | ||
| if (null != queryString) result += '?' + paramStrings.join('&'); | ||
| if (null != hash) result += '#' + hash; | ||
| return result; | ||
| }; | ||
| const _getHashParam = function(hash, param) { | ||
| const matches = hash.match(new RegExp(param + '=([^&]*)')); | ||
| return matches ? matches[1] : null; | ||
| }; | ||
| const isLocalhost = ()=>localDomains.includes(external_globals_js_namespaceObject.location.hostname); | ||
| const isStatusZeroFailureCircuitBreakerTripped = (consecutiveStatusZeroFailures, maxConsecutiveStatusZeroFailures)=>consecutiveStatusZeroFailures >= maxConsecutiveStatusZeroFailures && (0, external_globals_js_namespaceObject.isBrowserOnline)(); | ||
| const updateStatusZeroFailureCount = (statusCode, consecutiveStatusZeroFailures, maxConsecutiveStatusZeroFailures, onCircuitBreakerTripped)=>{ | ||
| if (0 === statusCode) { | ||
| if ((0, external_globals_js_namespaceObject.isBrowserOnline)()) { | ||
| const updatedConsecutiveStatusZeroFailures = consecutiveStatusZeroFailures + 1; | ||
| if (updatedConsecutiveStatusZeroFailures === maxConsecutiveStatusZeroFailures) onCircuitBreakerTripped(); | ||
| return updatedConsecutiveStatusZeroFailures; | ||
| } | ||
| return consecutiveStatusZeroFailures; | ||
| } | ||
| return 0; | ||
| }; | ||
| exports._getHashParam = __webpack_exports__._getHashParam; | ||
| exports.convertToURL = __webpack_exports__.convertToURL; | ||
| exports.formDataToQuery = __webpack_exports__.formDataToQuery; | ||
| exports.getQueryParam = __webpack_exports__.getQueryParam; | ||
| exports.isLocalhost = __webpack_exports__.isLocalhost; | ||
| exports.isStatusZeroFailureCircuitBreakerTripped = __webpack_exports__.isStatusZeroFailureCircuitBreakerTripped; | ||
| exports.jsonStringify = __webpack_exports__.jsonStringify; | ||
| exports.maskQueryParams = __webpack_exports__.maskQueryParams; | ||
| exports.updateStatusZeroFailureCount = __webpack_exports__.updateStatusZeroFailureCount; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "_getHashParam", | ||
| "convertToURL", | ||
| "formDataToQuery", | ||
| "getQueryParam", | ||
| "isLocalhost", | ||
| "isStatusZeroFailureCircuitBreakerTripped", | ||
| "jsonStringify", | ||
| "maskQueryParams", | ||
| "updateStatusZeroFailureCount" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| import { isArray, isFile, isUndefined, safeJsonStringify } from "@posthog/core"; | ||
| import { each } from "./general-utils.mjs"; | ||
| import { document as external_globals_mjs_document, isBrowserOnline, location as external_globals_mjs_location } from "./globals.mjs"; | ||
| import { logger } from "./logger.mjs"; | ||
| const localDomains = [ | ||
| 'localhost', | ||
| '127.0.0.1' | ||
| ]; | ||
| const jsonStringify = (data, space)=>{ | ||
| try { | ||
| return JSON.stringify(data, (_, value)=>'bigint' == typeof value ? value.toString() : value, space); | ||
| } catch { | ||
| return safeJsonStringify(data); | ||
| } | ||
| }; | ||
| const convertToURL = (url)=>{ | ||
| const location = external_globals_mjs_document?.createElement('a'); | ||
| if (isUndefined(location)) return null; | ||
| location.href = url; | ||
| return location; | ||
| }; | ||
| const formDataToQuery = function(formdata, arg_separator = '&') { | ||
| let use_val; | ||
| let use_key; | ||
| const tph_arr = []; | ||
| each(formdata, function(val, key) { | ||
| if (isUndefined(val) || isUndefined(key) || 'undefined' === key) return; | ||
| use_val = encodeURIComponent(isFile(val) ? val.name : val.toString()); | ||
| use_key = encodeURIComponent(key); | ||
| tph_arr[tph_arr.length] = use_key + '=' + use_val; | ||
| }); | ||
| return tph_arr.join(arg_separator); | ||
| }; | ||
| const getQueryParam = function(url, param) { | ||
| const withoutHash = url.split('#')[0] || ''; | ||
| const queryParams = withoutHash.split(/\?(.*)/)[1] || ''; | ||
| const cleanedQueryParams = queryParams.replace(/^\?+/g, ''); | ||
| const queryParts = cleanedQueryParams.split('&'); | ||
| let keyValuePair; | ||
| for(let i = 0; i < queryParts.length; i++){ | ||
| const parts = queryParts[i].split('='); | ||
| if (parts[0] === param) { | ||
| keyValuePair = parts; | ||
| break; | ||
| } | ||
| } | ||
| if (!isArray(keyValuePair) || keyValuePair.length < 2) return ''; | ||
| { | ||
| let result = keyValuePair[1]; | ||
| try { | ||
| result = decodeURIComponent(result); | ||
| } catch { | ||
| logger.error('Skipping decoding for malformed query param: ' + result); | ||
| } | ||
| return result.replace(/\+/g, ' '); | ||
| } | ||
| }; | ||
| const maskQueryParams = function(url, maskedParams, mask) { | ||
| if (!url || !maskedParams || !maskedParams.length) return url; | ||
| const splitHash = url.split('#'); | ||
| const withoutHash = splitHash[0] || ''; | ||
| const hash = splitHash[1]; | ||
| const splitQuery = withoutHash.split('?'); | ||
| const queryString = splitQuery[1]; | ||
| const urlWithoutQueryAndHash = splitQuery[0]; | ||
| const queryParts = (queryString || '').split('&'); | ||
| const paramStrings = []; | ||
| for(let i = 0; i < queryParts.length; i++){ | ||
| const keyValuePair = queryParts[i].split('='); | ||
| if (isArray(keyValuePair)) if (maskedParams.includes(keyValuePair[0])) paramStrings.push(keyValuePair[0] + '=' + mask); | ||
| else paramStrings.push(queryParts[i]); | ||
| } | ||
| let result = urlWithoutQueryAndHash; | ||
| if (null != queryString) result += '?' + paramStrings.join('&'); | ||
| if (null != hash) result += '#' + hash; | ||
| return result; | ||
| }; | ||
| const _getHashParam = function(hash, param) { | ||
| const matches = hash.match(new RegExp(param + '=([^&]*)')); | ||
| return matches ? matches[1] : null; | ||
| }; | ||
| const isLocalhost = ()=>localDomains.includes(external_globals_mjs_location.hostname); | ||
| const isStatusZeroFailureCircuitBreakerTripped = (consecutiveStatusZeroFailures, maxConsecutiveStatusZeroFailures)=>consecutiveStatusZeroFailures >= maxConsecutiveStatusZeroFailures && isBrowserOnline(); | ||
| const updateStatusZeroFailureCount = (statusCode, consecutiveStatusZeroFailures, maxConsecutiveStatusZeroFailures, onCircuitBreakerTripped)=>{ | ||
| if (0 === statusCode) { | ||
| if (isBrowserOnline()) { | ||
| const updatedConsecutiveStatusZeroFailures = consecutiveStatusZeroFailures + 1; | ||
| if (updatedConsecutiveStatusZeroFailures === maxConsecutiveStatusZeroFailures) onCircuitBreakerTripped(); | ||
| return updatedConsecutiveStatusZeroFailures; | ||
| } | ||
| return consecutiveStatusZeroFailures; | ||
| } | ||
| return 0; | ||
| }; | ||
| export { _getHashParam, convertToURL, formDataToQuery, getQueryParam, isLocalhost, isStatusZeroFailureCircuitBreakerTripped, jsonStringify, maskQueryParams, updateStatusZeroFailureCount }; |
| export declare class SimpleEventEmitter { | ||
| private _events; | ||
| on(event: string, listener: (...args: any[]) => void): () => void; | ||
| emit(event: string, payload: any): void; | ||
| } |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| SimpleEventEmitter: ()=>SimpleEventEmitter | ||
| }); | ||
| class SimpleEventEmitter { | ||
| on(event, listener) { | ||
| if (!this._events[event]) this._events[event] = []; | ||
| this._events[event].push(listener); | ||
| return ()=>{ | ||
| this._events[event] = this._events[event].filter((x)=>x !== listener); | ||
| }; | ||
| } | ||
| emit(event, payload) { | ||
| for (const listener of this._events[event] || [])listener(payload); | ||
| for (const listener of this._events['*'] || [])listener(event, payload); | ||
| } | ||
| constructor(){ | ||
| this._events = {}; | ||
| } | ||
| } | ||
| exports.SimpleEventEmitter = __webpack_exports__.SimpleEventEmitter; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "SimpleEventEmitter" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| class SimpleEventEmitter { | ||
| on(event, listener) { | ||
| if (!this._events[event]) this._events[event] = []; | ||
| this._events[event].push(listener); | ||
| return ()=>{ | ||
| this._events[event] = this._events[event].filter((x)=>x !== listener); | ||
| }; | ||
| } | ||
| emit(event, payload) { | ||
| for (const listener of this._events[event] || [])listener(payload); | ||
| for (const listener of this._events['*'] || [])listener(event, payload); | ||
| } | ||
| constructor(){ | ||
| this._events = {}; | ||
| } | ||
| } | ||
| export { SimpleEventEmitter }; |
| export type StylesheetPreparer = (stylesheet: HTMLStyleElement) => HTMLStyleElement | null; | ||
| export type StylesheetPreparationContext = StylesheetPreparer | { | ||
| config?: { | ||
| prepare_external_dependency_stylesheet?: StylesheetPreparer; | ||
| }; | ||
| }; | ||
| export declare const prepareStylesheet: (document: Document, innerText: string, context?: StylesheetPreparationContext) => HTMLStyleElement | null; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| prepareStylesheet: ()=>prepareStylesheet | ||
| }); | ||
| const core_namespaceObject = require("@posthog/core"); | ||
| const external_logger_js_namespaceObject = require("./logger.js"); | ||
| const logger = (0, external_logger_js_namespaceObject.createLogger)('[Stylesheet Loader]'); | ||
| const getStylesheetPreparer = (context)=>{ | ||
| if ((0, core_namespaceObject.isFunction)(context)) return context; | ||
| return context?.config?.prepare_external_dependency_stylesheet; | ||
| }; | ||
| const prepareStylesheet = (document, innerText, context)=>{ | ||
| let stylesheet = document.createElement('style'); | ||
| stylesheet.innerText = innerText; | ||
| const prepareExternalDependencyStylesheet = getStylesheetPreparer(context); | ||
| if (prepareExternalDependencyStylesheet) stylesheet = prepareExternalDependencyStylesheet(stylesheet); | ||
| if (!stylesheet) { | ||
| logger.error('prepare_external_dependency_stylesheet returned null'); | ||
| return null; | ||
| } | ||
| return stylesheet; | ||
| }; | ||
| exports.prepareStylesheet = __webpack_exports__.prepareStylesheet; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "prepareStylesheet" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| import { isFunction } from "@posthog/core"; | ||
| import { createLogger } from "./logger.mjs"; | ||
| const logger = createLogger('[Stylesheet Loader]'); | ||
| const getStylesheetPreparer = (context)=>{ | ||
| if (isFunction(context)) return context; | ||
| return context?.config?.prepare_external_dependency_stylesheet; | ||
| }; | ||
| const prepareStylesheet = (document, innerText, context)=>{ | ||
| let stylesheet = document.createElement('style'); | ||
| stylesheet.innerText = innerText; | ||
| const prepareExternalDependencyStylesheet = getStylesheetPreparer(context); | ||
| if (prepareExternalDependencyStylesheet) stylesheet = prepareExternalDependencyStylesheet(stylesheet); | ||
| if (!stylesheet) { | ||
| logger.error('prepare_external_dependency_stylesheet returned null'); | ||
| return null; | ||
| } | ||
| return stylesheet; | ||
| }; | ||
| export { prepareStylesheet }; |
| export declare const isAngularZonePresent: () => boolean; | ||
| export declare const isDocument: (x: unknown) => x is Document; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| isAngularZonePresent: ()=>isAngularZonePresent, | ||
| isDocument: ()=>isDocument | ||
| }); | ||
| const external_globals_js_namespaceObject = require("./globals.js"); | ||
| const isAngularZonePresent = ()=>!!external_globals_js_namespaceObject.window?.Zone; | ||
| const isDocument = (x)=>'undefined' != typeof Document && x instanceof Document; | ||
| exports.isAngularZonePresent = __webpack_exports__.isAngularZonePresent; | ||
| exports.isDocument = __webpack_exports__.isDocument; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "isAngularZonePresent", | ||
| "isDocument" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| import { window as external_globals_mjs_window } from "./globals.mjs"; | ||
| const isAngularZonePresent = ()=>!!external_globals_mjs_window?.Zone; | ||
| const isDocument = (x)=>'undefined' != typeof Document && x instanceof Document; | ||
| export { isAngularZonePresent, isDocument }; |
| import type { PostHogConfig } from '@posthog/types'; | ||
| export type UrlTargetingInstance = { | ||
| config: Pick<PostHogConfig, 'get_current_url'>; | ||
| }; | ||
| /** | ||
| * Applies the `get_current_url` config hook to an already-resolved URL. Returns `defaultUrl` | ||
| * unchanged when no override is configured, or if the override throws or returns a | ||
| * non-string/empty value. | ||
| * | ||
| * Use this when the caller already has its own URL source (e.g. web experiments read | ||
| * `window.location` via a mockable indirection); otherwise prefer `getTargetingUrl`. | ||
| */ | ||
| export declare function applyUrlTargetingOverride(instance: UrlTargetingInstance | undefined, defaultUrl: string): string; | ||
| /** | ||
| * Resolves the URL used for client-side URL targeting: session replay URL triggers, the | ||
| * session replay URL blocklist, survey URL conditions, product tour URL conditions, and web | ||
| * experiment URL conditions. | ||
| * | ||
| * Defaults to `window.location.href`, but honors the `get_current_url` config hook so apps | ||
| * that rewrite their URL (e.g. Electron/desktop builds, or `$current_url` rewrites in | ||
| * `before_send`) can make targeting match the logical URL instead of the raw browser URL. | ||
| * | ||
| * Returns `undefined` when there is no URL available (e.g. non-browser environments). | ||
| * | ||
| * Called on every rrweb event by the replay URL triggers/blocklist, so a configured | ||
| * `get_current_url` override should stay cheap. | ||
| */ | ||
| export declare function getTargetingUrl(instance: UrlTargetingInstance | undefined): string | undefined; |
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| getTargetingUrl: ()=>getTargetingUrl, | ||
| applyUrlTargetingOverride: ()=>applyUrlTargetingOverride | ||
| }); | ||
| const core_namespaceObject = require("@posthog/core"); | ||
| const external_globals_js_namespaceObject = require("./globals.js"); | ||
| const external_logger_js_namespaceObject = require("./logger.js"); | ||
| function applyUrlTargetingOverride(instance, defaultUrl) { | ||
| const override = instance?.config?.get_current_url; | ||
| if (!(0, core_namespaceObject.isFunction)(override)) return defaultUrl; | ||
| try { | ||
| const result = override(defaultUrl); | ||
| return (0, core_namespaceObject.isString)(result) && result ? result : defaultUrl; | ||
| } catch (e) { | ||
| external_logger_js_namespaceObject.logger.error('Error in get_current_url, falling back to window.location.href', e); | ||
| return defaultUrl; | ||
| } | ||
| } | ||
| function getTargetingUrl(instance) { | ||
| const defaultUrl = external_globals_js_namespaceObject.window?.location?.href; | ||
| return (0, core_namespaceObject.isUndefined)(defaultUrl) ? void 0 : applyUrlTargetingOverride(instance, defaultUrl); | ||
| } | ||
| exports.applyUrlTargetingOverride = __webpack_exports__.applyUrlTargetingOverride; | ||
| exports.getTargetingUrl = __webpack_exports__.getTargetingUrl; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "applyUrlTargetingOverride", | ||
| "getTargetingUrl" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| import { isFunction, isString, isUndefined } from "@posthog/core"; | ||
| import { window as external_globals_mjs_window } from "./globals.mjs"; | ||
| import { logger } from "./logger.mjs"; | ||
| function applyUrlTargetingOverride(instance, defaultUrl) { | ||
| const override = instance?.config?.get_current_url; | ||
| if (!isFunction(override)) return defaultUrl; | ||
| try { | ||
| const result = override(defaultUrl); | ||
| return isString(result) && result ? result : defaultUrl; | ||
| } catch (e) { | ||
| logger.error('Error in get_current_url, falling back to window.location.href', e); | ||
| return defaultUrl; | ||
| } | ||
| } | ||
| function getTargetingUrl(instance) { | ||
| const defaultUrl = external_globals_mjs_window?.location?.href; | ||
| return isUndefined(defaultUrl) ? void 0 : applyUrlTargetingOverride(instance, defaultUrl); | ||
| } | ||
| export { applyUrlTargetingOverride, getTargetingUrl }; |
| /** | ||
| * uuidv7: An experimental implementation of the proposed UUID Version 7 | ||
| * | ||
| * @license Apache-2.0 | ||
| * @copyright 2021-2023 LiosK | ||
| * @packageDocumentation | ||
| * | ||
| * from https://github.com/LiosK/uuidv7/blob/e501462ea3d23241de13192ceae726956f9b3b7d/src/index.ts | ||
| */ | ||
| /** Represents a UUID as a 16-byte byte array. */ | ||
| export declare class UUID { | ||
| readonly bytes: Readonly<Uint8Array>; | ||
| /** @param bytes - The 16-byte byte array representation. */ | ||
| constructor(bytes: Readonly<Uint8Array>); | ||
| /** | ||
| * Builds a byte array from UUIDv7 field values. | ||
| * | ||
| * @param unixTsMs - A 48-bit `unix_ts_ms` field value. | ||
| * @param randA - A 12-bit `rand_a` field value. | ||
| * @param randBHi - The higher 30 bits of 62-bit `rand_b` field value. | ||
| * @param randBLo - The lower 32 bits of 62-bit `rand_b` field value. | ||
| */ | ||
| static fromFieldsV7(unixTsMs: number, randA: number, randBHi: number, randBLo: number): UUID; | ||
| /** @returns The 8-4-4-4-12 canonical hexadecimal string representation. */ | ||
| toString(): string; | ||
| /** Creates an object from `this`. */ | ||
| clone(): UUID; | ||
| /** Returns true if `this` is equivalent to `other`. */ | ||
| equals(other: UUID): boolean; | ||
| /** | ||
| * Returns a negative integer, zero, or positive integer if `this` is less | ||
| * than, equal to, or greater than `other`, respectively. | ||
| */ | ||
| compareTo(other: UUID): number; | ||
| } | ||
| /** | ||
| * Generates a UUIDv7 string. | ||
| * | ||
| * @returns The 8-4-4-4-12 canonical hexadecimal string representation | ||
| * ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"). | ||
| */ | ||
| export declare const uuidv7: () => string; | ||
| export declare const uuid7ToTimestampMs: (uuid: string) => number; |
| /*! For license information please see uuidv7.js.LICENSE.txt */ | ||
| "use strict"; | ||
| var __webpack_require__ = {}; | ||
| (()=>{ | ||
| __webpack_require__.d = (exports1, definition)=>{ | ||
| for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { | ||
| enumerable: true, | ||
| get: definition[key] | ||
| }); | ||
| }; | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); | ||
| })(); | ||
| (()=>{ | ||
| __webpack_require__.r = (exports1)=>{ | ||
| if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { | ||
| value: 'Module' | ||
| }); | ||
| Object.defineProperty(exports1, '__esModule', { | ||
| value: true | ||
| }); | ||
| }; | ||
| })(); | ||
| var __webpack_exports__ = {}; | ||
| __webpack_require__.r(__webpack_exports__); | ||
| __webpack_require__.d(__webpack_exports__, { | ||
| uuid7ToTimestampMs: ()=>uuid7ToTimestampMs, | ||
| UUID: ()=>UUID, | ||
| uuidv7: ()=>uuidv7 | ||
| }); | ||
| const external_globals_js_namespaceObject = require("./globals.js"); | ||
| const core_namespaceObject = require("@posthog/core"); | ||
| /** | ||
| * uuidv7: An experimental implementation of the proposed UUID Version 7 | ||
| * | ||
| * @license Apache-2.0 | ||
| * @copyright 2021-2023 LiosK | ||
| * @packageDocumentation | ||
| * | ||
| * from https://github.com/LiosK/uuidv7/blob/e501462ea3d23241de13192ceae726956f9b3b7d/src/index.ts | ||
| */ if (!Math.trunc) Math.trunc = function(v) { | ||
| return v < 0 ? Math.ceil(v) : Math.floor(v); | ||
| }; | ||
| if (!Number.isInteger) Number.isInteger = function(value) { | ||
| return (0, core_namespaceObject.isNumber)(value) && isFinite(value) && Math.floor(value) === value; | ||
| }; | ||
| class UUID { | ||
| constructor(bytes){ | ||
| this.bytes = bytes; | ||
| if (16 !== bytes.length) throw new TypeError('not 128-bit length'); | ||
| } | ||
| static fromFieldsV7(unixTsMs, randA, randBHi, randBLo) { | ||
| if (!Number.isInteger(unixTsMs) || !Number.isInteger(randA) || !Number.isInteger(randBHi) || !Number.isInteger(randBLo) || unixTsMs < 0 || randA < 0 || randBHi < 0 || randBLo < 0 || unixTsMs > 0xffffffffffff || randA > 0xfff || randBHi > 0x3fffffff || randBLo > 0xffffffff) throw new RangeError('invalid field value'); | ||
| const bytes = new Uint8Array(16); | ||
| bytes[0] = unixTsMs / 2 ** 40; | ||
| bytes[1] = unixTsMs / 2 ** 32; | ||
| bytes[2] = unixTsMs / 2 ** 24; | ||
| bytes[3] = unixTsMs / 2 ** 16; | ||
| bytes[4] = unixTsMs / 256; | ||
| bytes[5] = unixTsMs; | ||
| bytes[6] = 0x70 | randA >>> 8; | ||
| bytes[7] = randA; | ||
| bytes[8] = 0x80 | randBHi >>> 24; | ||
| bytes[9] = randBHi >>> 16; | ||
| bytes[10] = randBHi >>> 8; | ||
| bytes[11] = randBHi; | ||
| bytes[12] = randBLo >>> 24; | ||
| bytes[13] = randBLo >>> 16; | ||
| bytes[14] = randBLo >>> 8; | ||
| bytes[15] = randBLo; | ||
| return new UUID(bytes); | ||
| } | ||
| toString() { | ||
| let text = ''; | ||
| for(let i = 0; i < this.bytes.length; i++){ | ||
| text = text + (this.bytes[i] >>> 4).toString(16) + (0xf & this.bytes[i]).toString(16); | ||
| if (3 === i || 5 === i || 7 === i || 9 === i) text += '-'; | ||
| } | ||
| if (36 !== text.length) throw new Error('Invalid UUIDv7 was generated'); | ||
| return text; | ||
| } | ||
| clone() { | ||
| return new UUID(this.bytes.slice(0)); | ||
| } | ||
| equals(other) { | ||
| return 0 === this.compareTo(other); | ||
| } | ||
| compareTo(other) { | ||
| for(let i = 0; i < 16; i++){ | ||
| const diff = this.bytes[i] - other.bytes[i]; | ||
| if (0 !== diff) return Math.sign(diff); | ||
| } | ||
| return 0; | ||
| } | ||
| } | ||
| class V7Generator { | ||
| generate() { | ||
| const value = this.generateOrAbort(); | ||
| if (!(0, core_namespaceObject.isUndefined)(value)) return value; | ||
| { | ||
| this._timestamp = 0; | ||
| const valueAfterReset = this.generateOrAbort(); | ||
| if ((0, core_namespaceObject.isUndefined)(valueAfterReset)) throw new Error('Could not generate UUID after timestamp reset'); | ||
| return valueAfterReset; | ||
| } | ||
| } | ||
| generateOrAbort() { | ||
| const MAX_COUNTER = 0x3ffffffffff; | ||
| const ROLLBACK_ALLOWANCE = 10000; | ||
| const ts = Date.now(); | ||
| if (ts > this._timestamp) { | ||
| this._timestamp = ts; | ||
| this._resetCounter(); | ||
| } else { | ||
| if (!(ts + ROLLBACK_ALLOWANCE > this._timestamp)) return; | ||
| this._counter++; | ||
| if (this._counter > MAX_COUNTER) { | ||
| this._timestamp++; | ||
| this._resetCounter(); | ||
| } | ||
| } | ||
| return UUID.fromFieldsV7(this._timestamp, Math.trunc(this._counter / 2 ** 30), this._counter & 2 ** 30 - 1, this._random.nextUint32()); | ||
| } | ||
| _resetCounter() { | ||
| this._counter = 0x400 * this._random.nextUint32() + (0x3ff & this._random.nextUint32()); | ||
| } | ||
| constructor(){ | ||
| this._timestamp = 0; | ||
| this._counter = 0; | ||
| this._random = new DefaultRandom(); | ||
| } | ||
| } | ||
| let getRandomValues = (buffer)=>{ | ||
| if ('undefined' != typeof UUIDV7_DENY_WEAK_RNG && UUIDV7_DENY_WEAK_RNG) throw new Error('no cryptographically strong RNG available'); | ||
| for(let i = 0; i < buffer.length; i++)buffer[i] = 0x10000 * Math.trunc(0x10000 * Math.random()) + Math.trunc(0x10000 * Math.random()); | ||
| return buffer; | ||
| }; | ||
| if (external_globals_js_namespaceObject.window && !(0, core_namespaceObject.isUndefined)(external_globals_js_namespaceObject.window.crypto) && crypto.getRandomValues) getRandomValues = (buffer)=>crypto.getRandomValues(buffer); | ||
| class DefaultRandom { | ||
| nextUint32() { | ||
| if (this._cursor >= this._buffer.length) { | ||
| getRandomValues(this._buffer); | ||
| this._cursor = 0; | ||
| } | ||
| return this._buffer[this._cursor++]; | ||
| } | ||
| constructor(){ | ||
| this._buffer = new Uint32Array(8); | ||
| this._cursor = 1 / 0; | ||
| } | ||
| } | ||
| let defaultGenerator; | ||
| const uuidv7 = ()=>uuidv7obj().toString(); | ||
| const uuidv7obj = ()=>(defaultGenerator || (defaultGenerator = new V7Generator())).generate(); | ||
| const uuid7ToTimestampMs = (uuid)=>{ | ||
| const hex = uuid.replace(/-/g, ''); | ||
| if (32 !== hex.length) throw new Error('Not a valid UUID'); | ||
| if ('7' !== hex[12]) throw new Error('Not a UUIDv7'); | ||
| return parseInt(hex.substring(0, 12), 16); | ||
| }; | ||
| exports.UUID = __webpack_exports__.UUID; | ||
| exports.uuid7ToTimestampMs = __webpack_exports__.uuid7ToTimestampMs; | ||
| exports.uuidv7 = __webpack_exports__.uuidv7; | ||
| for(var __webpack_i__ in __webpack_exports__)if (-1 === [ | ||
| "UUID", | ||
| "uuid7ToTimestampMs", | ||
| "uuidv7" | ||
| ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; | ||
| Object.defineProperty(exports, '__esModule', { | ||
| value: true | ||
| }); |
| /** | ||
| * uuidv7: An experimental implementation of the proposed UUID Version 7 | ||
| * | ||
| * @license Apache-2.0 | ||
| * @copyright 2021-2023 LiosK | ||
| * @packageDocumentation | ||
| * | ||
| * from https://github.com/LiosK/uuidv7/blob/e501462ea3d23241de13192ceae726956f9b3b7d/src/index.ts | ||
| */ |
| /*! For license information please see uuidv7.mjs.LICENSE.txt */ | ||
| import { window as external_globals_mjs_window } from "./globals.mjs"; | ||
| import { isNumber, isUndefined } from "@posthog/core"; | ||
| /** | ||
| * uuidv7: An experimental implementation of the proposed UUID Version 7 | ||
| * | ||
| * @license Apache-2.0 | ||
| * @copyright 2021-2023 LiosK | ||
| * @packageDocumentation | ||
| * | ||
| * from https://github.com/LiosK/uuidv7/blob/e501462ea3d23241de13192ceae726956f9b3b7d/src/index.ts | ||
| */ if (!Math.trunc) Math.trunc = function(v) { | ||
| return v < 0 ? Math.ceil(v) : Math.floor(v); | ||
| }; | ||
| if (!Number.isInteger) Number.isInteger = function(value) { | ||
| return isNumber(value) && isFinite(value) && Math.floor(value) === value; | ||
| }; | ||
| class UUID { | ||
| constructor(bytes){ | ||
| this.bytes = bytes; | ||
| if (16 !== bytes.length) throw new TypeError('not 128-bit length'); | ||
| } | ||
| static fromFieldsV7(unixTsMs, randA, randBHi, randBLo) { | ||
| if (!Number.isInteger(unixTsMs) || !Number.isInteger(randA) || !Number.isInteger(randBHi) || !Number.isInteger(randBLo) || unixTsMs < 0 || randA < 0 || randBHi < 0 || randBLo < 0 || unixTsMs > 0xffffffffffff || randA > 0xfff || randBHi > 0x3fffffff || randBLo > 0xffffffff) throw new RangeError('invalid field value'); | ||
| const bytes = new Uint8Array(16); | ||
| bytes[0] = unixTsMs / 2 ** 40; | ||
| bytes[1] = unixTsMs / 2 ** 32; | ||
| bytes[2] = unixTsMs / 2 ** 24; | ||
| bytes[3] = unixTsMs / 2 ** 16; | ||
| bytes[4] = unixTsMs / 256; | ||
| bytes[5] = unixTsMs; | ||
| bytes[6] = 0x70 | randA >>> 8; | ||
| bytes[7] = randA; | ||
| bytes[8] = 0x80 | randBHi >>> 24; | ||
| bytes[9] = randBHi >>> 16; | ||
| bytes[10] = randBHi >>> 8; | ||
| bytes[11] = randBHi; | ||
| bytes[12] = randBLo >>> 24; | ||
| bytes[13] = randBLo >>> 16; | ||
| bytes[14] = randBLo >>> 8; | ||
| bytes[15] = randBLo; | ||
| return new UUID(bytes); | ||
| } | ||
| toString() { | ||
| let text = ''; | ||
| for(let i = 0; i < this.bytes.length; i++){ | ||
| text = text + (this.bytes[i] >>> 4).toString(16) + (0xf & this.bytes[i]).toString(16); | ||
| if (3 === i || 5 === i || 7 === i || 9 === i) text += '-'; | ||
| } | ||
| if (36 !== text.length) throw new Error('Invalid UUIDv7 was generated'); | ||
| return text; | ||
| } | ||
| clone() { | ||
| return new UUID(this.bytes.slice(0)); | ||
| } | ||
| equals(other) { | ||
| return 0 === this.compareTo(other); | ||
| } | ||
| compareTo(other) { | ||
| for(let i = 0; i < 16; i++){ | ||
| const diff = this.bytes[i] - other.bytes[i]; | ||
| if (0 !== diff) return Math.sign(diff); | ||
| } | ||
| return 0; | ||
| } | ||
| } | ||
| class V7Generator { | ||
| generate() { | ||
| const value = this.generateOrAbort(); | ||
| if (!isUndefined(value)) return value; | ||
| { | ||
| this._timestamp = 0; | ||
| const valueAfterReset = this.generateOrAbort(); | ||
| if (isUndefined(valueAfterReset)) throw new Error('Could not generate UUID after timestamp reset'); | ||
| return valueAfterReset; | ||
| } | ||
| } | ||
| generateOrAbort() { | ||
| const MAX_COUNTER = 0x3ffffffffff; | ||
| const ROLLBACK_ALLOWANCE = 10000; | ||
| const ts = Date.now(); | ||
| if (ts > this._timestamp) { | ||
| this._timestamp = ts; | ||
| this._resetCounter(); | ||
| } else { | ||
| if (!(ts + ROLLBACK_ALLOWANCE > this._timestamp)) return; | ||
| this._counter++; | ||
| if (this._counter > MAX_COUNTER) { | ||
| this._timestamp++; | ||
| this._resetCounter(); | ||
| } | ||
| } | ||
| return UUID.fromFieldsV7(this._timestamp, Math.trunc(this._counter / 2 ** 30), this._counter & 2 ** 30 - 1, this._random.nextUint32()); | ||
| } | ||
| _resetCounter() { | ||
| this._counter = 0x400 * this._random.nextUint32() + (0x3ff & this._random.nextUint32()); | ||
| } | ||
| constructor(){ | ||
| this._timestamp = 0; | ||
| this._counter = 0; | ||
| this._random = new DefaultRandom(); | ||
| } | ||
| } | ||
| let getRandomValues = (buffer)=>{ | ||
| if ('undefined' != typeof UUIDV7_DENY_WEAK_RNG && UUIDV7_DENY_WEAK_RNG) throw new Error('no cryptographically strong RNG available'); | ||
| for(let i = 0; i < buffer.length; i++)buffer[i] = 0x10000 * Math.trunc(0x10000 * Math.random()) + Math.trunc(0x10000 * Math.random()); | ||
| return buffer; | ||
| }; | ||
| if (external_globals_mjs_window && !isUndefined(external_globals_mjs_window.crypto) && crypto.getRandomValues) getRandomValues = (buffer)=>crypto.getRandomValues(buffer); | ||
| class DefaultRandom { | ||
| nextUint32() { | ||
| if (this._cursor >= this._buffer.length) { | ||
| getRandomValues(this._buffer); | ||
| this._cursor = 0; | ||
| } | ||
| return this._buffer[this._cursor++]; | ||
| } | ||
| constructor(){ | ||
| this._buffer = new Uint32Array(8); | ||
| this._cursor = 1 / 0; | ||
| } | ||
| } | ||
| let defaultGenerator; | ||
| const uuidv7 = ()=>uuidv7obj().toString(); | ||
| const uuidv7obj = ()=>(defaultGenerator || (defaultGenerator = new V7Generator())).generate(); | ||
| const uuid7ToTimestampMs = (uuid)=>{ | ||
| const hex = uuid.replace(/-/g, ''); | ||
| if (32 !== hex.length) throw new Error('Not a valid UUID'); | ||
| if ('7' !== hex[12]) throw new Error('Not a UUIDv7'); | ||
| return parseInt(hex.substring(0, 12), 16); | ||
| }; | ||
| export { UUID, uuid7ToTimestampMs, uuidv7 }; |
| /** | ||
| * uuidv7: An experimental implementation of the proposed UUID Version 7 | ||
| * | ||
| * @license Apache-2.0 | ||
| * @copyright 2021-2023 LiosK | ||
| * @packageDocumentation | ||
| * | ||
| * from https://github.com/LiosK/uuidv7/blob/e501462ea3d23241de13192ceae726956f9b3b7d/src/index.ts | ||
| */ |
+37
-3
| { | ||
| "name": "@posthog/browser-common", | ||
| "version": "0.1.0", | ||
| "version": "0.2.0", | ||
| "description": "Internal shared browser utilities and extension primitives for PostHog Browser SDKs", | ||
@@ -11,3 +11,8 @@ "license": "MIT", | ||
| }, | ||
| "sideEffects": false, | ||
| "sideEffects": [ | ||
| "./dist/utils/array-at-polyfill.js", | ||
| "./dist/utils/array-at-polyfill.mjs", | ||
| "./dist/utils/uuidv7.js", | ||
| "./dist/utils/uuidv7.mjs" | ||
| ], | ||
| "files": [ | ||
@@ -20,2 +25,15 @@ "dist", | ||
| "types": "dist/index.d.ts", | ||
| "typesVersions": { | ||
| "*": { | ||
| "config": [ | ||
| "dist/config.d.ts" | ||
| ], | ||
| "constants": [ | ||
| "dist/constants.d.ts" | ||
| ], | ||
| "utils/*": [ | ||
| "dist/utils/*.d.ts" | ||
| ] | ||
| } | ||
| }, | ||
| "exports": { | ||
@@ -26,6 +44,22 @@ ".": { | ||
| "import": "./dist/index.mjs" | ||
| }, | ||
| "./config": { | ||
| "types": "./dist/config.d.ts", | ||
| "require": "./dist/config.js", | ||
| "import": "./dist/config.mjs" | ||
| }, | ||
| "./constants": { | ||
| "types": "./dist/constants.d.ts", | ||
| "require": "./dist/constants.js", | ||
| "import": "./dist/constants.mjs" | ||
| }, | ||
| "./utils/*": { | ||
| "types": "./dist/utils/*.d.ts", | ||
| "require": "./dist/utils/*.js", | ||
| "import": "./dist/utils/*.mjs" | ||
| } | ||
| }, | ||
| "dependencies": { | ||
| "@posthog/core": "^1.43.1" | ||
| "@posthog/core": "^1.44.0", | ||
| "@posthog/types": "^1.397.1" | ||
| }, | ||
@@ -32,0 +66,0 @@ "devDependencies": { |
+17
-4
@@ -104,2 +104,14 @@ # @posthog/browser-common | ||
| ## Utilities | ||
| Reusable browser utilities are exposed through `utils/*` subpaths, but they are | ||
| intentionally not re-exported from the package root or a utility barrel. Import | ||
| the exact file you need so lazy extension bundles do not pull in unrelated | ||
| helpers: | ||
| ```ts | ||
| import { createLogger } from '@posthog/browser-common/utils/logger' | ||
| import { formDataToQuery } from '@posthog/browser-common/utils/request-utils' | ||
| ``` | ||
| ## Authoring | ||
@@ -116,5 +128,6 @@ | ||
| Early and internal. The package currently defines the extension contract and | ||
| the shared `Publisher` helper. Additional shared runtime helpers — key-value | ||
| stores, the registry implementation, and a test `Client` — will land alongside | ||
| the first ported extension. | ||
| Early and internal. The package currently defines the extension contract, the | ||
| shared `Publisher` helper, and directly imported browser utilities under | ||
| `utils/*` subpaths. Additional shared runtime helpers — key-value stores, the | ||
| registry implementation, and a test `Client` — will land alongside the first | ||
| ported extension. |
-353
| Copyright 2020 Posthog / Hiberly, Inc. | ||
| Copyright 2015 Mixpanel, Inc. | ||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||
| you may not use this work except in compliance with the License. | ||
| You may obtain a copy of the License below, or at: | ||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
| Unless required by applicable law or agreed to in writing, software | ||
| distributed under the License is distributed on an "AS IS" BASIS, | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| See the License for the specific language governing permissions and | ||
| limitations under the License. | ||
| Apache License | ||
| Version 2.0, January 2004 | ||
| http://www.apache.org/licenses/ | ||
| TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||
| 1. Definitions. | ||
| "License" shall mean the terms and conditions for use, reproduction, | ||
| and distribution as defined by Sections 1 through 9 of this document. | ||
| "Licensor" shall mean the copyright owner or entity authorized by | ||
| the copyright owner that is granting the License. | ||
| "Legal Entity" shall mean the union of the acting entity and all | ||
| other entities that control, are controlled by, or are under common | ||
| control with that entity. For the purposes of this definition, | ||
| "control" means (i) the power, direct or indirect, to cause the | ||
| direction or management of such entity, whether by contract or | ||
| otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||
| outstanding shares, or (iii) beneficial ownership of such entity. | ||
| "You" (or "Your") shall mean an individual or Legal Entity | ||
| exercising permissions granted by this License. | ||
| "Source" form shall mean the preferred form for making modifications, | ||
| including but not limited to software source code, documentation | ||
| source, and configuration files. | ||
| "Object" form shall mean any form resulting from mechanical | ||
| transformation or translation of a Source form, including but | ||
| not limited to compiled object code, generated documentation, | ||
| and conversions to other media types. | ||
| "Work" shall mean the work of authorship, whether in Source or | ||
| Object form, made available under the License, as indicated by a | ||
| copyright notice that is included in or attached to the work | ||
| (an example is provided in the Appendix below). | ||
| "Derivative Works" shall mean any work, whether in Source or Object | ||
| form, that is based on (or derived from) the Work and for which the | ||
| editorial revisions, annotations, elaborations, or other modifications | ||
| represent, as a whole, an original work of authorship. For the purposes | ||
| of this License, Derivative Works shall not include works that remain | ||
| separable from, or merely link (or bind by name) to the interfaces of, | ||
| the Work and Derivative Works thereof. | ||
| "Contribution" shall mean any work of authorship, including | ||
| the original version of the Work and any modifications or additions | ||
| to that Work or Derivative Works thereof, that is intentionally | ||
| submitted to Licensor for inclusion in the Work by the copyright owner | ||
| or by an individual or Legal Entity authorized to submit on behalf of | ||
| the copyright owner. For the purposes of this definition, "submitted" | ||
| means any form of electronic, verbal, or written communication sent | ||
| to the Licensor or its representatives, including but not limited to | ||
| communication on electronic mailing lists, source code control systems, | ||
| and issue tracking systems that are managed by, or on behalf of, the | ||
| Licensor for the purpose of discussing and improving the Work, but | ||
| excluding communication that is conspicuously marked or otherwise | ||
| designated in writing by the copyright owner as "Not a Contribution." | ||
| "Contributor" shall mean Licensor and any individual or Legal Entity | ||
| on behalf of whom a Contribution has been received by Licensor and | ||
| subsequently incorporated within the Work. | ||
| 2. Grant of Copyright License. Subject to the terms and conditions of | ||
| this License, each Contributor hereby grants to You a perpetual, | ||
| worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||
| copyright license to reproduce, prepare Derivative Works of, | ||
| publicly display, publicly perform, sublicense, and distribute the | ||
| Work and such Derivative Works in Source or Object form. | ||
| 3. Grant of Patent License. Subject to the terms and conditions of | ||
| this License, each Contributor hereby grants to You a perpetual, | ||
| worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||
| (except as stated in this section) patent license to make, have made, | ||
| use, offer to sell, sell, import, and otherwise transfer the Work, | ||
| where such license applies only to those patent claims licensable | ||
| by such Contributor that are necessarily infringed by their | ||
| Contribution(s) alone or by combination of their Contribution(s) | ||
| with the Work to which such Contribution(s) was submitted. If You | ||
| institute patent litigation against any entity (including a | ||
| cross-claim or counterclaim in a lawsuit) alleging that the Work | ||
| or a Contribution incorporated within the Work constitutes direct | ||
| or contributory patent infringement, then any patent licenses | ||
| granted to You under this License for that Work shall terminate | ||
| as of the date such litigation is filed. | ||
| 4. Redistribution. You may reproduce and distribute copies of the | ||
| Work or Derivative Works thereof in any medium, with or without | ||
| modifications, and in Source or Object form, provided that You | ||
| meet the following conditions: | ||
| (a) You must give any other recipients of the Work or | ||
| Derivative Works a copy of this License; and | ||
| (b) You must cause any modified files to carry prominent notices | ||
| stating that You changed the files; and | ||
| (c) You must retain, in the Source form of any Derivative Works | ||
| that You distribute, all copyright, patent, trademark, and | ||
| attribution notices from the Source form of the Work, | ||
| excluding those notices that do not pertain to any part of | ||
| the Derivative Works; and | ||
| (d) If the Work includes a "NOTICE" text file as part of its | ||
| distribution, then any Derivative Works that You distribute must | ||
| include a readable copy of the attribution notices contained | ||
| within such NOTICE file, excluding those notices that do not | ||
| pertain to any part of the Derivative Works, in at least one | ||
| of the following places: within a NOTICE text file distributed | ||
| as part of the Derivative Works; within the Source form or | ||
| documentation, if provided along with the Derivative Works; or, | ||
| within a display generated by the Derivative Works, if and | ||
| wherever such third-party notices normally appear. The contents | ||
| of the NOTICE file are for informational purposes only and | ||
| do not modify the License. You may add Your own attribution | ||
| notices within Derivative Works that You distribute, alongside | ||
| or as an addendum to the NOTICE text from the Work, provided | ||
| that such additional attribution notices cannot be construed | ||
| as modifying the License. | ||
| You may add Your own copyright statement to Your modifications and | ||
| may provide additional or different license terms and conditions | ||
| for use, reproduction, or distribution of Your modifications, or | ||
| for any such Derivative Works as a whole, provided Your use, | ||
| reproduction, and distribution of the Work otherwise complies with | ||
| the conditions stated in this License. | ||
| 5. Submission of Contributions. Unless You explicitly state otherwise, | ||
| any Contribution intentionally submitted for inclusion in the Work | ||
| by You to the Licensor shall be under the terms and conditions of | ||
| this License, without any additional terms or conditions. | ||
| Notwithstanding the above, nothing herein shall supersede or modify | ||
| the terms of any separate license agreement you may have executed | ||
| with Licensor regarding such Contributions. | ||
| 6. Trademarks. This License does not grant permission to use the trade | ||
| names, trademarks, service marks, or product names of the Licensor, | ||
| except as required for reasonable and customary use in describing the | ||
| origin of the Work and reproducing the content of the NOTICE file. | ||
| 7. Disclaimer of Warranty. Unless required by applicable law or | ||
| agreed to in writing, Licensor provides the Work (and each | ||
| Contributor provides its Contributions) on an "AS IS" BASIS, | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
| implied, including, without limitation, any warranties or conditions | ||
| of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||
| PARTICULAR PURPOSE. You are solely responsible for determining the | ||
| appropriateness of using or redistributing the Work and assume any | ||
| risks associated with Your exercise of permissions under this License. | ||
| 8. Limitation of Liability. In no event and under no legal theory, | ||
| whether in tort (including negligence), contract, or otherwise, | ||
| unless required by applicable law (such as deliberate and grossly | ||
| negligent acts) or agreed to in writing, shall any Contributor be | ||
| liable to You for damages, including any direct, indirect, special, | ||
| incidental, or consequential damages of any character arising as a | ||
| result of this License or out of the use or inability to use the | ||
| Work (including but not limited to damages for loss of goodwill, | ||
| work stoppage, computer failure or malfunction, or any and all | ||
| other commercial damages or losses), even if such Contributor | ||
| has been advised of the possibility of such damages. | ||
| 9. Accepting Warranty or Additional Liability. While redistributing | ||
| the Work or Derivative Works thereof, You may choose to offer, | ||
| and charge a fee for, acceptance of support, warranty, indemnity, | ||
| or other liability obligations and/or rights consistent with this | ||
| License. However, in accepting such obligations, You may act only | ||
| on Your own behalf and on Your sole responsibility, not on behalf | ||
| of any other Contributor, and only if You agree to indemnify, | ||
| defend, and hold each Contributor harmless for any liability | ||
| incurred by, or claims asserted against, such Contributor by reason | ||
| of your accepting any such warranty or additional liability. | ||
| END OF TERMS AND CONDITIONS | ||
| APPENDIX: How to apply the Apache License to your work. | ||
| To apply the Apache License to your work, attach the following | ||
| boilerplate notice, with the fields enclosed by brackets "[]" | ||
| replaced with your own identifying information. (Don't include | ||
| the brackets!) The text should be enclosed in the appropriate | ||
| comment syntax for the file format. We also recommend that a | ||
| file or class name and description of purpose be included on the | ||
| same "printed page" as the copyright notice for easier | ||
| identification within third-party archives. | ||
| Copyright [yyyy] [name of copyright owner] | ||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||
| you may not use this file except in compliance with the License. | ||
| You may obtain a copy of the License at | ||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
| Unless required by applicable law or agreed to in writing, software | ||
| distributed under the License is distributed on an "AS IS" BASIS, | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| See the License for the specific language governing permissions and | ||
| limitations under the License. | ||
| --- | ||
| Some files in this codebase contain code from getsentry/sentry-javascript. | ||
| In such cases it is explicitly stated in the file header. This license only applies to the relevant code in such cases. | ||
| MIT License | ||
| Copyright (c) 2012 Functional Software, Inc. dba Sentry | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
| this software and associated documentation files (the "Software"), to deal in | ||
| the Software without restriction, including without limitation the rights to | ||
| use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||
| of the Software, and to permit persons to whom the Software is furnished to do | ||
| so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. | ||
| --- | ||
| Some files in this codebase contain code from getsentry/sentry-react-native. | ||
| In such cases it is explicitly stated in the file header. This license only applies to the relevant code in such cases. | ||
| The MIT License (MIT) | ||
| Copyright (c) 2017 Sentry | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. | ||
| --- | ||
| Some files in this codebase contain code from facebook/metro by Meta Platforms, Inc. and affiliates. | ||
| In such cases it is explicitly stated in the file header. This license only applies to the relevant code in such cases. | ||
| MIT License | ||
| Copyright (c) Meta Platforms, Inc. and affiliates. | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. | ||
| --- | ||
| Some files in this codebase contain code from expo/expo by 650 Industries, Inc. (aka Expo). | ||
| In such cases it is explicitly stated in the file header. This license only applies to the relevant code in such cases. | ||
| The MIT License (MIT) | ||
| Copyright (c) 2015-present 650 Industries, Inc. (aka Expo) | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. | ||
| --- | ||
| Some files in this codebase contain code from agentcathq/agentcat-typescript-sdk (formerly MCPCat/mcpcat-typescript-sdk). | ||
| In such cases it is explicitly stated in the file header. This license only applies to the relevant code in such cases. | ||
| MIT License | ||
| Copyright (c) 2025 AgentCat, Inc. (formerly MCPcat) | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Network access
Supply chain riskThis module accesses the network.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
204422
355.56%97
304.17%4605
810.08%132
10.92%2
100%1
Infinity%12
1100%+ Added
Updated