posthog-js 1.316.0 → 1.317.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/all-external-dependencies.js +1 -1
  2. package/dist/all-external-dependencies.js.map +1 -1
  3. package/dist/array.full.es5.js +1 -1
  4. package/dist/array.full.es5.js.map +1 -1
  5. package/dist/array.full.js +1 -1
  6. package/dist/array.full.js.map +1 -1
  7. package/dist/array.full.no-external.js +1 -1
  8. package/dist/array.full.no-external.js.map +1 -1
  9. package/dist/array.js +1 -1
  10. package/dist/array.no-external.js +1 -1
  11. package/dist/customizations.full.js +1 -1
  12. package/dist/element-inference.d.ts +21 -0
  13. package/dist/element-inference.js +2 -0
  14. package/dist/element-inference.js.map +1 -0
  15. package/dist/lazy-recorder.js +1 -1
  16. package/dist/main.js +1 -1
  17. package/dist/main.js.map +1 -1
  18. package/dist/module.d.ts +12 -0
  19. package/dist/module.full.d.ts +12 -0
  20. package/dist/module.full.js +1 -1
  21. package/dist/module.full.js.map +1 -1
  22. package/dist/module.full.no-external.d.ts +12 -0
  23. package/dist/module.full.no-external.js +1 -1
  24. package/dist/module.full.no-external.js.map +1 -1
  25. package/dist/module.js +1 -1
  26. package/dist/module.js.map +1 -1
  27. package/dist/module.no-external.d.ts +12 -0
  28. package/dist/module.no-external.js +1 -1
  29. package/dist/module.no-external.js.map +1 -1
  30. package/dist/posthog-recorder.js +1 -1
  31. package/dist/product-tours-preview.d.ts +12 -0
  32. package/dist/product-tours-preview.js +1 -1
  33. package/dist/product-tours-preview.js.map +1 -1
  34. package/dist/product-tours.js +1 -1
  35. package/dist/product-tours.js.map +1 -1
  36. package/dist/src/entrypoints/element-inference.es.d.ts +1 -0
  37. package/dist/src/entrypoints/product-tours.d.ts +2 -0
  38. package/dist/src/extensions/product-tours/element-inference.d.ts +30 -0
  39. package/dist/src/extensions/product-tours/index.d.ts +2 -0
  40. package/dist/src/extensions/product-tours/product-tours-utils.d.ts +2 -1
  41. package/dist/src/extensions/surveys.d.ts +2 -2
  42. package/dist/src/posthog-product-tours-types.d.ts +7 -0
  43. package/dist/src/utils/survey-branching.d.ts +11 -0
  44. package/dist/src/utils/survey-url-prefill.d.ts +7 -5
  45. package/dist/surveys-preview.d.ts +18 -1
  46. package/dist/surveys-preview.js +1 -1
  47. package/dist/surveys-preview.js.map +1 -1
  48. package/dist/surveys.js +1 -1
  49. package/dist/surveys.js.map +1 -1
  50. package/lib/package.json +5 -1
  51. package/lib/src/entrypoints/element-inference.es.d.ts +1 -0
  52. package/lib/src/entrypoints/element-inference.es.js +8 -0
  53. package/lib/src/entrypoints/element-inference.es.js.map +1 -0
  54. package/lib/src/entrypoints/product-tours.d.ts +2 -0
  55. package/lib/src/entrypoints/product-tours.js +5 -0
  56. package/lib/src/entrypoints/product-tours.js.map +1 -1
  57. package/lib/src/extensions/product-tours/components/ProductTourTooltip.js +5 -2
  58. package/lib/src/extensions/product-tours/components/ProductTourTooltip.js.map +1 -1
  59. package/lib/src/extensions/product-tours/components/ProductTourTooltipInner.js +1 -1
  60. package/lib/src/extensions/product-tours/components/ProductTourTooltipInner.js.map +1 -1
  61. package/lib/src/extensions/product-tours/element-inference.d.ts +30 -0
  62. package/lib/src/extensions/product-tours/element-inference.js +296 -0
  63. package/lib/src/extensions/product-tours/element-inference.js.map +1 -0
  64. package/lib/src/extensions/product-tours/index.d.ts +2 -0
  65. package/lib/src/extensions/product-tours/index.js +4 -1
  66. package/lib/src/extensions/product-tours/index.js.map +1 -1
  67. package/lib/src/extensions/product-tours/preview.js +1 -1
  68. package/lib/src/extensions/product-tours/preview.js.map +1 -1
  69. package/lib/src/extensions/product-tours/product-tours-utils.d.ts +2 -1
  70. package/lib/src/extensions/product-tours/product-tours-utils.js +12 -0
  71. package/lib/src/extensions/product-tours/product-tours-utils.js.map +1 -1
  72. package/lib/src/extensions/product-tours/product-tours.js +15 -31
  73. package/lib/src/extensions/product-tours/product-tours.js.map +1 -1
  74. package/lib/src/extensions/surveys.d.ts +2 -2
  75. package/lib/src/extensions/surveys.js +5 -94
  76. package/lib/src/extensions/surveys.js.map +1 -1
  77. package/lib/src/posthog-product-tours-types.d.ts +7 -0
  78. package/lib/src/posthog-product-tours-types.js.map +1 -1
  79. package/lib/src/utils/survey-branching.d.ts +11 -0
  80. package/lib/src/utils/survey-branching.js +106 -0
  81. package/lib/src/utils/survey-branching.js.map +1 -0
  82. package/lib/src/utils/survey-url-prefill.d.ts +7 -5
  83. package/lib/src/utils/survey-url-prefill.js +30 -18
  84. package/lib/src/utils/survey-url-prefill.js.map +1 -1
  85. package/lib/tsconfig.tsbuildinfo +1 -1
  86. package/package.json +7 -3
@@ -1 +1 @@
1
- {"version":3,"file":"module.js","sources":["../src/utils/globals.ts","../src/config.ts","../../core/dist/utils/bot-detection.mjs","../../core/dist/types.mjs","../../core/dist/utils/string-utils.mjs","../../core/dist/utils/type-utils.mjs","../../core/dist/utils/number-utils.mjs","../../core/dist/utils/bucketed-rate-limiter.mjs","../../core/dist/utils/user-agent-utils.mjs","../../core/dist/error-tracking/chunk-ids.mjs","../../core/dist/utils/index.mjs","../../core/dist/error-tracking/error-properties-builder.mjs","../../core/dist/error-tracking/parsers/base.mjs","../../core/dist/error-tracking/parsers/safari.mjs","../../core/dist/error-tracking/parsers/chrome.mjs","../../core/dist/error-tracking/parsers/gecko.mjs","../../core/dist/error-tracking/parsers/index.mjs","../../core/dist/error-tracking/coercers/dom-exception-coercer.mjs","../../core/dist/error-tracking/coercers/error-coercer.mjs","../../core/dist/error-tracking/coercers/error-event-coercer.mjs","../../core/dist/error-tracking/coercers/string-coercer.mjs","../../core/dist/error-tracking/types.mjs","../../core/dist/error-tracking/coercers/utils.mjs","../../core/dist/error-tracking/coercers/object-coercer.mjs","../../core/dist/error-tracking/coercers/event-coercer.mjs","../../core/dist/error-tracking/coercers/primitive-coercer.mjs","../../core/dist/error-tracking/coercers/promise-rejection-event.mjs","../src/utils/logger.ts","../src/entrypoints/external-scripts-loader.ts","../src/utils/index.ts","../src/constants.ts","../src/utils/element-utils.ts","../src/autocapture-utils.ts","../src/extensions/rageclick.ts","../src/utils/request-utils.ts","../src/autocapture.ts","../src/uuidv7.ts","../src/storage.ts","../src/consent.ts","../src/extensions/dead-clicks-autocapture.ts","../src/extensions/exception-autocapture/index.ts","../src/extensions/replay/rrweb-plugins/patch.ts","../src/extensions/history-autocapture.ts","../src/extensions/segment-integration.ts","../src/extensions/sentry-integration.ts","../src/extensions/toolbar.ts","../src/extensions/tracing-headers.ts","../src/utils/event-utils.ts","../src/extensions/web-vitals/index.ts","../src/heatmaps.ts","../src/page-view.ts","../src/types.ts","../../../node_modules/.pnpm/fflate@0.4.8/node_modules/fflate/esm/browser.js","../src/utils/encode-utils.ts","../src/request.ts","../src/utils/regex-utils.ts","../src/utils/property-utils.ts","../src/posthog-exceptions.ts","../src/posthog-featureflags.ts","../src/posthog-persistence.ts","../src/posthog-product-tours.ts","../src/posthog-surveys-types.ts","../src/utils/survey-utils.ts","../src/utils/simple-event-emitter.ts","../src/utils/elements-chain-utils.ts","../src/extensions/surveys/action-matcher.ts","../src/utils/event-receiver.ts","../src/utils/survey-event-receiver.ts","../src/posthog-surveys.ts","../src/extensions/conversations/posthog-conversations.ts","../src/rate-limiter.ts","../src/remote-config.ts","../src/request-queue.ts","../src/retry-queue.ts","../src/scroll-manager.ts","../src/session-props.ts","../src/sessionid.ts","../src/site-apps.ts","../src/utils/blocked-uas.ts","../src/utils/request-router.ts","../src/web-experiments.ts","../src/extensions/external-integration.ts","../src/extensions/replay/external/triggerMatching.ts","../src/extensions/replay/session-recording.ts","../src/posthog-core.ts","../src/posthog-product-tours-types.ts","../src/entrypoints/module.no-external.es.ts"],"sourcesContent":["import type { PostHog } from '../posthog-core'\nimport { SessionIdManager } from '../sessionid'\nimport {\n DeadClicksAutoCaptureConfig,\n ExternalIntegrationKind,\n Properties,\n RemoteConfig,\n SiteAppLoader,\n SessionStartReason,\n} from '../types'\nimport type {\n ConversationsRemoteConfig,\n GetMessagesResponse,\n GetTicketsOptions,\n GetTicketsResponse,\n MarkAsReadResponse,\n SendMessageResponse,\n UserProvidedTraits,\n} from '../posthog-conversations-types'\n// only importing types here, so won't affect the bundle\n// eslint-disable-next-line posthog-js/no-external-replay-imports\nimport type { SessionRecordingStatus, TriggerType } from '../extensions/replay/external/triggerMatching'\nimport { eventWithTime } from '../extensions/replay/types/rrweb-types'\nimport { ErrorTracking } from '@posthog/core'\n\n/*\n * Global helpers to protect access to browser globals in a way that is safer for different targets\n * like DOM, SSR, Web workers etc.\n *\n * NOTE: Typically we want the \"window\" but globalThis works for both the typical browser context as\n * well as other contexts such as the web worker context. Window is still exported for any bits that explicitly require it.\n * If in doubt - export the global you need from this file and use that as an optional value. This way the code path is forced\n * to handle the case where the global is not available.\n */\n\n// eslint-disable-next-line no-restricted-globals\nconst win: (Window & typeof globalThis) | undefined = typeof window !== 'undefined' ? window : undefined\n\nexport type AssignableWindow = Window &\n typeof globalThis & {\n /*\n * Main PostHog instance\n */\n posthog: any\n\n /*\n * This is our contract between (potentially) lazily loaded extensions and the SDK\n */\n __PosthogExtensions__?: PostHogExtensions\n\n /**\n * When loading remote config, we assign it to this global configuration\n * for ease of sharing it with the rest of the SDK\n */\n _POSTHOG_REMOTE_CONFIG?: Record<\n string,\n {\n config: RemoteConfig\n siteApps: SiteAppLoader[]\n }\n >\n\n /**\n * If this is set on the window, our logger will log to the console\n * for ease of debugging. Used for testing purposes only.\n *\n * @see {Config.DEBUG} from config.ts\n */\n POSTHOG_DEBUG: any\n\n // Exposed by the browser\n doNotTrack: any\n\n // See entrypoints/customizations.full.ts\n posthogCustomizations: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/exception-autocapture.ts\n *\n * @deprecated use `__PosthogExtensions__.errorWrappingFunctions` instead\n */\n posthogErrorWrappingFunctions: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/posthog-recorder.ts\n *\n * @deprecated use `__PosthogExtensions__.rrweb` instead\n */\n rrweb: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/posthog-recorder.ts\n *\n * @deprecated use `__PosthogExtensions__.rrwebConsoleRecord` instead\n */\n rrwebConsoleRecord: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/posthog-recorder.ts\n *\n * @deprecated use `__PosthogExtensions__.getRecordNetworkPlugin` instead\n */\n getRecordNetworkPlugin: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/web-vitals.ts\n *\n * @deprecated use `__PosthogExtensions__.postHogWebVitalsCallbacks` instead\n */\n postHogWebVitalsCallbacks: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/tracing-headers.ts\n *\n * @deprecated use `__PosthogExtensions__.postHogTracingHeadersPatchFns` instead\n */\n postHogTracingHeadersPatchFns: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/surveys.ts\n *\n * @deprecated use `__PosthogExtensions__.generateSurveys` instead\n */\n extendPostHogWithSurveys: any\n\n /*\n * These are used to handle our toolbar state.\n * @see {Toolbar} from extensions/toolbar.ts\n */\n ph_load_toolbar: any\n ph_load_editor: any\n ph_toolbar_state: any\n } & Record<`__$$ph_site_app_${string}`, any>\n\n/**\n * This is our contract between (potentially) lazily loaded extensions and the SDK\n * changes to this interface can be breaking changes for users of the SDK\n */\n\nexport type ExternalExtensionKind = 'intercom-integration' | 'crisp-chat-integration'\n\nexport type PostHogExtensionKind =\n | 'toolbar'\n | 'exception-autocapture'\n | 'web-vitals'\n | 'recorder'\n | 'lazy-recorder'\n | 'tracing-headers'\n | 'surveys'\n | 'conversations'\n | 'product-tours'\n | 'dead-clicks-autocapture'\n | 'remote-config'\n | ExternalExtensionKind\n\nexport interface LazyLoadedSessionRecordingInterface {\n start: (startReason?: SessionStartReason) => void\n stop: () => void\n sessionId: string\n status: SessionRecordingStatus\n onRRwebEmit: (rawEvent: eventWithTime) => void\n log: (message: string, level: 'log' | 'warn' | 'error') => void\n sdkDebugProperties: Properties\n overrideLinkedFlag: () => void\n overrideSampling: () => void\n overrideTrigger: (triggerType: TriggerType) => void\n isStarted: boolean\n tryAddCustomEvent(tag: string, payload: any): boolean\n}\n\nexport interface LazyLoadedDeadClicksAutocaptureInterface {\n start: (observerTarget: Node) => void\n stop: () => void\n}\n\nexport interface LazyLoadedConversationsInterface {\n // Widget control\n show: () => void\n hide: () => void\n isVisible: () => boolean\n\n // Lifecycle\n reset: () => void\n\n // API methods\n sendMessage: (message: string, userTraits?: UserProvidedTraits, newTicket?: boolean) => Promise<SendMessageResponse>\n getMessages: (ticketId?: string, after?: string) => Promise<GetMessagesResponse>\n markAsRead: (ticketId?: string) => Promise<MarkAsReadResponse>\n getTickets: (options?: GetTicketsOptions) => Promise<GetTicketsResponse>\n getCurrentTicketId: () => string | null\n getWidgetSessionId: () => string\n}\n\ninterface PostHogExtensions {\n loadExternalDependency?: (\n posthog: PostHog,\n kind: PostHogExtensionKind,\n callback: (error?: string | Event, event?: Event) => void\n ) => void\n\n loadSiteApp?: (posthog: PostHog, appUrl: string, callback: (error?: string | Event, event?: Event) => void) => void\n\n errorWrappingFunctions?: {\n wrapOnError: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void\n wrapUnhandledRejection: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void\n wrapConsoleError: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void\n }\n rrweb?: { record: any; version: string }\n rrwebPlugins?: { getRecordConsolePlugin: any; getRecordNetworkPlugin?: any }\n generateSurveys?: (posthog: PostHog, isSurveysEnabled: boolean) => any | undefined\n generateProductTours?: (posthog: PostHog, isEnabled: boolean) => any | undefined\n postHogWebVitalsCallbacks?: {\n onLCP: (metric: any) => void\n onCLS: (metric: any) => void\n onFCP: (metric: any) => void\n onINP: (metric: any) => void\n }\n tracingHeadersPatchFns?: {\n _patchFetch: (hostnames: string[], distinctId: string, sessionManager?: SessionIdManager) => () => void\n _patchXHR: (hostnames: string[], distinctId: string, sessionManager?: SessionIdManager) => () => void\n }\n initDeadClicksAutocapture?: (\n ph: PostHog,\n config: DeadClicksAutoCaptureConfig\n ) => LazyLoadedDeadClicksAutocaptureInterface\n integrations?: {\n [K in ExternalIntegrationKind]?: { start: (posthog: PostHog) => void; stop: () => void }\n }\n initSessionRecording?: (ph: PostHog) => LazyLoadedSessionRecordingInterface\n initConversations?: (config: ConversationsRemoteConfig, posthog: PostHog) => LazyLoadedConversationsInterface\n}\n\nconst global: typeof globalThis | undefined = typeof globalThis !== 'undefined' ? globalThis : win\n\n// React Native polyfills for posthog-js compatibility\nif (typeof self === 'undefined') {\n ;(global as any).self = global\n}\nif (typeof File === 'undefined') {\n ;(global as any).File = function () {}\n}\n\nexport const ArrayProto = Array.prototype\nexport const nativeForEach = ArrayProto.forEach\nexport const nativeIndexOf = ArrayProto.indexOf\n\nexport const navigator = global?.navigator\nexport const document = global?.document\nexport const location = global?.location\nexport const fetch = global?.fetch\nexport const XMLHttpRequest =\n global?.XMLHttpRequest && 'withCredentials' in new global.XMLHttpRequest() ? global.XMLHttpRequest : undefined\nexport const AbortController = global?.AbortController\nexport const userAgent = navigator?.userAgent\nexport const assignableWindow: AssignableWindow = win ?? ({} as any)\n\nexport { win as window }\n","import packageInfo from '../package.json'\n\n// overridden in posthog-core,\n// e.g. Config.DEBUG = Config.DEBUG || instance.config.debug\nconst Config = {\n DEBUG: false,\n LIB_VERSION: packageInfo.version,\n}\n\nexport default Config\n","const DEFAULT_BLOCKED_UA_STRS = [\n 'amazonbot',\n 'amazonproductbot',\n 'app.hypefactors.com',\n 'applebot',\n 'archive.org_bot',\n 'awariobot',\n 'backlinksextendedbot',\n 'baiduspider',\n 'bingbot',\n 'bingpreview',\n 'chrome-lighthouse',\n 'dataforseobot',\n 'deepscan',\n 'duckduckbot',\n 'facebookexternal',\n 'facebookcatalog',\n 'http://yandex.com/bots',\n 'hubspot',\n 'ia_archiver',\n 'leikibot',\n 'linkedinbot',\n 'meta-externalagent',\n 'mj12bot',\n 'msnbot',\n 'nessus',\n 'petalbot',\n 'pinterest',\n 'prerender',\n 'rogerbot',\n 'screaming frog',\n 'sebot-wa',\n 'sitebulb',\n 'slackbot',\n 'slurp',\n 'trendictionbot',\n 'turnitin',\n 'twitterbot',\n 'vercel-screenshot',\n 'vercelbot',\n 'yahoo! slurp',\n 'yandexbot',\n 'zoombot',\n 'bot.htm',\n 'bot.php',\n '(bot;',\n 'bot/',\n 'crawler',\n 'ahrefsbot',\n 'ahrefssiteaudit',\n 'semrushbot',\n 'siteauditbot',\n 'splitsignalbot',\n 'gptbot',\n 'oai-searchbot',\n 'chatgpt-user',\n 'perplexitybot',\n 'better uptime bot',\n 'sentryuptimebot',\n 'uptimerobot',\n 'headlesschrome',\n 'cypress',\n 'google-hoteladsverifier',\n 'adsbot-google',\n 'apis-google',\n 'duplexweb-google',\n 'feedfetcher-google',\n 'google favicon',\n 'google web preview',\n 'google-read-aloud',\n 'googlebot',\n 'googleother',\n 'google-cloudvertexbot',\n 'googleweblight',\n 'mediapartners-google',\n 'storebot-google',\n 'google-inspectiontool',\n 'bytespider'\n];\nconst isBlockedUA = function(ua, customBlockedUserAgents = []) {\n if (!ua) return false;\n const uaLower = ua.toLowerCase();\n return DEFAULT_BLOCKED_UA_STRS.concat(customBlockedUserAgents).some((blockedUA)=>{\n const blockedUaLower = blockedUA.toLowerCase();\n return -1 !== uaLower.indexOf(blockedUaLower);\n });\n};\nexport { DEFAULT_BLOCKED_UA_STRS, isBlockedUA };\n","var types_PostHogPersistedProperty = /*#__PURE__*/ function(PostHogPersistedProperty) {\n PostHogPersistedProperty[\"AnonymousId\"] = \"anonymous_id\";\n PostHogPersistedProperty[\"DistinctId\"] = \"distinct_id\";\n PostHogPersistedProperty[\"Props\"] = \"props\";\n PostHogPersistedProperty[\"FeatureFlagDetails\"] = \"feature_flag_details\";\n PostHogPersistedProperty[\"FeatureFlags\"] = \"feature_flags\";\n PostHogPersistedProperty[\"FeatureFlagPayloads\"] = \"feature_flag_payloads\";\n PostHogPersistedProperty[\"BootstrapFeatureFlagDetails\"] = \"bootstrap_feature_flag_details\";\n PostHogPersistedProperty[\"BootstrapFeatureFlags\"] = \"bootstrap_feature_flags\";\n PostHogPersistedProperty[\"BootstrapFeatureFlagPayloads\"] = \"bootstrap_feature_flag_payloads\";\n PostHogPersistedProperty[\"OverrideFeatureFlags\"] = \"override_feature_flags\";\n PostHogPersistedProperty[\"Queue\"] = \"queue\";\n PostHogPersistedProperty[\"OptedOut\"] = \"opted_out\";\n PostHogPersistedProperty[\"SessionId\"] = \"session_id\";\n PostHogPersistedProperty[\"SessionStartTimestamp\"] = \"session_start_timestamp\";\n PostHogPersistedProperty[\"SessionLastTimestamp\"] = \"session_timestamp\";\n PostHogPersistedProperty[\"PersonProperties\"] = \"person_properties\";\n PostHogPersistedProperty[\"GroupProperties\"] = \"group_properties\";\n PostHogPersistedProperty[\"InstalledAppBuild\"] = \"installed_app_build\";\n PostHogPersistedProperty[\"InstalledAppVersion\"] = \"installed_app_version\";\n PostHogPersistedProperty[\"SessionReplay\"] = \"session_replay\";\n PostHogPersistedProperty[\"SurveyLastSeenDate\"] = \"survey_last_seen_date\";\n PostHogPersistedProperty[\"SurveysSeen\"] = \"surveys_seen\";\n PostHogPersistedProperty[\"Surveys\"] = \"surveys\";\n PostHogPersistedProperty[\"RemoteConfig\"] = \"remote_config\";\n PostHogPersistedProperty[\"FlagsEndpointWasHit\"] = \"flags_endpoint_was_hit\";\n return PostHogPersistedProperty;\n}({});\nvar types_Compression = /*#__PURE__*/ function(Compression) {\n Compression[\"GZipJS\"] = \"gzip-js\";\n Compression[\"Base64\"] = \"base64\";\n return Compression;\n}({});\nvar types_SurveyPosition = /*#__PURE__*/ function(SurveyPosition) {\n SurveyPosition[\"TopLeft\"] = \"top_left\";\n SurveyPosition[\"TopCenter\"] = \"top_center\";\n SurveyPosition[\"TopRight\"] = \"top_right\";\n SurveyPosition[\"MiddleLeft\"] = \"middle_left\";\n SurveyPosition[\"MiddleCenter\"] = \"middle_center\";\n SurveyPosition[\"MiddleRight\"] = \"middle_right\";\n SurveyPosition[\"Left\"] = \"left\";\n SurveyPosition[\"Right\"] = \"right\";\n SurveyPosition[\"Center\"] = \"center\";\n return SurveyPosition;\n}({});\nvar types_SurveyWidgetType = /*#__PURE__*/ function(SurveyWidgetType) {\n SurveyWidgetType[\"Button\"] = \"button\";\n SurveyWidgetType[\"Tab\"] = \"tab\";\n SurveyWidgetType[\"Selector\"] = \"selector\";\n return SurveyWidgetType;\n}({});\nvar types_SurveyType = /*#__PURE__*/ function(SurveyType) {\n SurveyType[\"Popover\"] = \"popover\";\n SurveyType[\"API\"] = \"api\";\n SurveyType[\"Widget\"] = \"widget\";\n SurveyType[\"ExternalSurvey\"] = \"external_survey\";\n return SurveyType;\n}({});\nvar types_SurveyQuestionDescriptionContentType = /*#__PURE__*/ function(SurveyQuestionDescriptionContentType) {\n SurveyQuestionDescriptionContentType[\"Html\"] = \"html\";\n SurveyQuestionDescriptionContentType[\"Text\"] = \"text\";\n return SurveyQuestionDescriptionContentType;\n}({});\nvar types_SurveyRatingDisplay = /*#__PURE__*/ function(SurveyRatingDisplay) {\n SurveyRatingDisplay[\"Number\"] = \"number\";\n SurveyRatingDisplay[\"Emoji\"] = \"emoji\";\n return SurveyRatingDisplay;\n}({});\nvar types_SurveyQuestionType = /*#__PURE__*/ function(SurveyQuestionType) {\n SurveyQuestionType[\"Open\"] = \"open\";\n SurveyQuestionType[\"MultipleChoice\"] = \"multiple_choice\";\n SurveyQuestionType[\"SingleChoice\"] = \"single_choice\";\n SurveyQuestionType[\"Rating\"] = \"rating\";\n SurveyQuestionType[\"Link\"] = \"link\";\n return SurveyQuestionType;\n}({});\nvar types_SurveyQuestionBranchingType = /*#__PURE__*/ function(SurveyQuestionBranchingType) {\n SurveyQuestionBranchingType[\"NextQuestion\"] = \"next_question\";\n SurveyQuestionBranchingType[\"End\"] = \"end\";\n SurveyQuestionBranchingType[\"ResponseBased\"] = \"response_based\";\n SurveyQuestionBranchingType[\"SpecificQuestion\"] = \"specific_question\";\n return SurveyQuestionBranchingType;\n}({});\nvar types_SurveyMatchType = /*#__PURE__*/ function(SurveyMatchType) {\n SurveyMatchType[\"Regex\"] = \"regex\";\n SurveyMatchType[\"NotRegex\"] = \"not_regex\";\n SurveyMatchType[\"Exact\"] = \"exact\";\n SurveyMatchType[\"IsNot\"] = \"is_not\";\n SurveyMatchType[\"Icontains\"] = \"icontains\";\n SurveyMatchType[\"NotIcontains\"] = \"not_icontains\";\n return SurveyMatchType;\n}({});\nvar types_ActionStepStringMatching = /*#__PURE__*/ function(ActionStepStringMatching) {\n ActionStepStringMatching[\"Contains\"] = \"contains\";\n ActionStepStringMatching[\"Exact\"] = \"exact\";\n ActionStepStringMatching[\"Regex\"] = \"regex\";\n return ActionStepStringMatching;\n}({});\nconst knownUnsafeEditableEvent = [\n '$snapshot',\n '$pageview',\n '$pageleave',\n '$set',\n 'survey dismissed',\n 'survey sent',\n 'survey shown',\n '$identify',\n '$groupidentify',\n '$create_alias',\n '$$client_ingestion_warning',\n '$web_experiment_applied',\n '$feature_enrollment_update',\n '$feature_flag_called'\n];\nexport { types_ActionStepStringMatching as ActionStepStringMatching, types_Compression as Compression, types_PostHogPersistedProperty as PostHogPersistedProperty, types_SurveyMatchType as SurveyMatchType, types_SurveyPosition as SurveyPosition, types_SurveyQuestionBranchingType as SurveyQuestionBranchingType, types_SurveyQuestionDescriptionContentType as SurveyQuestionDescriptionContentType, types_SurveyQuestionType as SurveyQuestionType, types_SurveyRatingDisplay as SurveyRatingDisplay, types_SurveyType as SurveyType, types_SurveyWidgetType as SurveyWidgetType, knownUnsafeEditableEvent };\n","function includes(str, needle) {\n return -1 !== str.indexOf(needle);\n}\nconst trim = function(str) {\n return str.trim();\n};\nconst stripLeadingDollar = function(s) {\n return s.replace(/^\\$/, '');\n};\nfunction isDistinctIdStringLike(value) {\n return [\n 'distinct_id',\n 'distinctid'\n ].includes(value.toLowerCase());\n}\nexport { includes, isDistinctIdStringLike, stripLeadingDollar, trim };\n","import { knownUnsafeEditableEvent } from \"../types.mjs\";\nimport { includes } from \"./string-utils.mjs\";\nconst nativeIsArray = Array.isArray;\nconst ObjProto = Object.prototype;\nconst type_utils_hasOwnProperty = ObjProto.hasOwnProperty;\nconst type_utils_toString = ObjProto.toString;\nconst isArray = nativeIsArray || function(obj) {\n return '[object Array]' === type_utils_toString.call(obj);\n};\nconst isFunction = (x)=>'function' == typeof x;\nconst isNativeFunction = (x)=>isFunction(x) && -1 !== x.toString().indexOf('[native code]');\nconst isObject = (x)=>x === Object(x) && !isArray(x);\nconst isEmptyObject = (x)=>{\n if (isObject(x)) {\n for(const key in x)if (type_utils_hasOwnProperty.call(x, key)) return false;\n return true;\n }\n return false;\n};\nconst isUndefined = (x)=>void 0 === x;\nconst isString = (x)=>'[object String]' == type_utils_toString.call(x);\nconst isEmptyString = (x)=>isString(x) && 0 === x.trim().length;\nconst isNull = (x)=>null === x;\nconst isNullish = (x)=>isUndefined(x) || isNull(x);\nconst isNumber = (x)=>'[object Number]' == type_utils_toString.call(x);\nconst isBoolean = (x)=>'[object Boolean]' === type_utils_toString.call(x);\nconst isFormData = (x)=>x instanceof FormData;\nconst isFile = (x)=>x instanceof File;\nconst isPlainError = (x)=>x instanceof Error;\nconst isKnownUnsafeEditableEvent = (x)=>includes(knownUnsafeEditableEvent, x);\nfunction isPrimitive(value) {\n return null === value || 'object' != typeof value;\n}\nfunction isBuiltin(candidate, className) {\n return Object.prototype.toString.call(candidate) === `[object ${className}]`;\n}\nfunction isError(candidate) {\n switch(Object.prototype.toString.call(candidate)){\n case '[object Error]':\n case '[object Exception]':\n case '[object DOMException]':\n case '[object DOMError]':\n case '[object WebAssembly.Exception]':\n return true;\n default:\n return isInstanceOf(candidate, Error);\n }\n}\nfunction isErrorEvent(event) {\n return isBuiltin(event, 'ErrorEvent');\n}\nfunction isEvent(candidate) {\n return !isUndefined(Event) && isInstanceOf(candidate, Event);\n}\nfunction isPlainObject(candidate) {\n return isBuiltin(candidate, 'Object');\n}\nfunction isInstanceOf(candidate, base) {\n try {\n return candidate instanceof base;\n } catch {\n return false;\n }\n}\nconst yesLikeValues = [\n true,\n 'true',\n 1,\n '1',\n 'yes'\n];\nconst isYesLike = (val)=>includes(yesLikeValues, val);\nconst noLikeValues = [\n false,\n 'false',\n 0,\n '0',\n 'no'\n];\nconst isNoLike = (val)=>includes(noLikeValues, val);\nexport { type_utils_hasOwnProperty as hasOwnProperty, isArray, isBoolean, isBuiltin, isEmptyObject, isEmptyString, isError, isErrorEvent, isEvent, isFile, isFormData, isFunction, isKnownUnsafeEditableEvent, isNativeFunction, isNoLike, isNull, isNullish, isNumber, isObject, isPlainError, isPlainObject, isPrimitive, isString, isUndefined, isYesLike, noLikeValues, yesLikeValues };\n","import { isNumber } from \"./type-utils.mjs\";\nfunction clampToRange(value, min, max, logger, fallbackValue) {\n if (min > max) {\n logger.warn('min cannot be greater than max.');\n min = max;\n }\n if (isNumber(value)) if (value > max) {\n logger.warn(' cannot be greater than max: ' + max + '. Using max value instead.');\n return max;\n } else {\n if (!(value < min)) return value;\n logger.warn(' cannot be less than min: ' + min + '. Using min value instead.');\n return min;\n }\n logger.warn(' must be a number. using max or fallback. max: ' + max + ', fallback: ' + fallbackValue);\n return clampToRange(fallbackValue || max, min, max, logger);\n}\nexport { clampToRange };\n","import { clampToRange } from \"./number-utils.mjs\";\nconst ONE_DAY_IN_MS = 86400000;\nclass BucketedRateLimiter {\n constructor(options){\n this._buckets = {};\n this._onBucketRateLimited = options._onBucketRateLimited;\n this._bucketSize = clampToRange(options.bucketSize, 0, 100, options._logger);\n this._refillRate = clampToRange(options.refillRate, 0, this._bucketSize, options._logger);\n this._refillInterval = clampToRange(options.refillInterval, 0, ONE_DAY_IN_MS, options._logger);\n }\n _applyRefill(bucket, now) {\n const elapsedMs = now - bucket.lastAccess;\n const refillIntervals = Math.floor(elapsedMs / this._refillInterval);\n if (refillIntervals > 0) {\n const tokensToAdd = refillIntervals * this._refillRate;\n bucket.tokens = Math.min(bucket.tokens + tokensToAdd, this._bucketSize);\n bucket.lastAccess = bucket.lastAccess + refillIntervals * this._refillInterval;\n }\n }\n consumeRateLimit(key) {\n const now = Date.now();\n const keyStr = String(key);\n let bucket = this._buckets[keyStr];\n if (bucket) this._applyRefill(bucket, now);\n else {\n bucket = {\n tokens: this._bucketSize,\n lastAccess: now\n };\n this._buckets[keyStr] = bucket;\n }\n if (0 === bucket.tokens) return true;\n bucket.tokens--;\n if (0 === bucket.tokens) this._onBucketRateLimited?.(key);\n return 0 === bucket.tokens;\n }\n stop() {\n this._buckets = {};\n }\n}\nexport { BucketedRateLimiter };\n","import { includes } from \"./string-utils.mjs\";\nimport { isFunction, isUndefined } from \"./type-utils.mjs\";\nconst FACEBOOK = 'Facebook';\nconst MOBILE = 'Mobile';\nconst IOS = 'iOS';\nconst ANDROID = 'Android';\nconst TABLET = 'Tablet';\nconst ANDROID_TABLET = ANDROID + ' ' + TABLET;\nconst IPAD = 'iPad';\nconst APPLE = 'Apple';\nconst APPLE_WATCH = APPLE + ' Watch';\nconst SAFARI = 'Safari';\nconst BLACKBERRY = 'BlackBerry';\nconst SAMSUNG = 'Samsung';\nconst SAMSUNG_BROWSER = SAMSUNG + 'Browser';\nconst SAMSUNG_INTERNET = SAMSUNG + ' Internet';\nconst CHROME = 'Chrome';\nconst CHROME_OS = CHROME + ' OS';\nconst CHROME_IOS = CHROME + ' ' + IOS;\nconst INTERNET_EXPLORER = 'Internet Explorer';\nconst INTERNET_EXPLORER_MOBILE = INTERNET_EXPLORER + ' ' + MOBILE;\nconst OPERA = 'Opera';\nconst OPERA_MINI = OPERA + ' Mini';\nconst EDGE = 'Edge';\nconst MICROSOFT_EDGE = 'Microsoft ' + EDGE;\nconst FIREFOX = 'Firefox';\nconst FIREFOX_IOS = FIREFOX + ' ' + IOS;\nconst NINTENDO = 'Nintendo';\nconst PLAYSTATION = 'PlayStation';\nconst XBOX = 'Xbox';\nconst ANDROID_MOBILE = ANDROID + ' ' + MOBILE;\nconst MOBILE_SAFARI = MOBILE + ' ' + SAFARI;\nconst WINDOWS = 'Windows';\nconst WINDOWS_PHONE = WINDOWS + ' Phone';\nconst NOKIA = 'Nokia';\nconst OUYA = 'Ouya';\nconst GENERIC = 'Generic';\nconst GENERIC_MOBILE = GENERIC + ' ' + MOBILE.toLowerCase();\nconst GENERIC_TABLET = GENERIC + ' ' + TABLET.toLowerCase();\nconst KONQUEROR = 'Konqueror';\nconst BROWSER_VERSION_REGEX_SUFFIX = '(\\\\d+(\\\\.\\\\d+)?)';\nconst DEFAULT_BROWSER_VERSION_REGEX = new RegExp('Version/' + BROWSER_VERSION_REGEX_SUFFIX);\nconst XBOX_REGEX = new RegExp(XBOX, 'i');\nconst PLAYSTATION_REGEX = new RegExp(PLAYSTATION + ' \\\\w+', 'i');\nconst NINTENDO_REGEX = new RegExp(NINTENDO + ' \\\\w+', 'i');\nconst BLACKBERRY_REGEX = new RegExp(BLACKBERRY + '|PlayBook|BB10', 'i');\nconst windowsVersionMap = {\n 'NT3.51': 'NT 3.11',\n 'NT4.0': 'NT 4.0',\n '5.0': '2000',\n '5.1': 'XP',\n '5.2': 'XP',\n '6.0': 'Vista',\n '6.1': '7',\n '6.2': '8',\n '6.3': '8.1',\n '6.4': '10',\n '10.0': '10'\n};\nfunction isSafari(userAgent) {\n return includes(userAgent, SAFARI) && !includes(userAgent, CHROME) && !includes(userAgent, ANDROID);\n}\nconst safariCheck = (ua, vendor)=>vendor && includes(vendor, APPLE) || isSafari(ua);\nconst detectBrowser = function(user_agent, vendor) {\n vendor = vendor || '';\n if (includes(user_agent, ' OPR/') && includes(user_agent, 'Mini')) return OPERA_MINI;\n if (includes(user_agent, ' OPR/')) return OPERA;\n if (BLACKBERRY_REGEX.test(user_agent)) return BLACKBERRY;\n if (includes(user_agent, 'IE' + MOBILE) || includes(user_agent, 'WPDesktop')) return INTERNET_EXPLORER_MOBILE;\n if (includes(user_agent, SAMSUNG_BROWSER)) return SAMSUNG_INTERNET;\n else if (includes(user_agent, EDGE) || includes(user_agent, 'Edg/')) return MICROSOFT_EDGE;\n else if (includes(user_agent, 'FBIOS')) return FACEBOOK + ' ' + MOBILE;\n else if (includes(user_agent, 'UCWEB') || includes(user_agent, 'UCBrowser')) return 'UC Browser';\n else if (includes(user_agent, 'CriOS')) return CHROME_IOS;\n else if (includes(user_agent, 'CrMo')) return CHROME;\n else if (includes(user_agent, CHROME)) return CHROME;\n else if (includes(user_agent, ANDROID) && includes(user_agent, SAFARI)) return ANDROID_MOBILE;\n else if (includes(user_agent, 'FxiOS')) return FIREFOX_IOS;\n else if (includes(user_agent.toLowerCase(), KONQUEROR.toLowerCase())) return KONQUEROR;\n else if (safariCheck(user_agent, vendor)) return includes(user_agent, MOBILE) ? MOBILE_SAFARI : SAFARI;\n else if (includes(user_agent, FIREFOX)) return FIREFOX;\n else if (includes(user_agent, 'MSIE') || includes(user_agent, 'Trident/')) return INTERNET_EXPLORER;\n else if (includes(user_agent, 'Gecko')) return FIREFOX;\n return '';\n};\nconst versionRegexes = {\n [INTERNET_EXPLORER_MOBILE]: [\n new RegExp('rv:' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [MICROSOFT_EDGE]: [\n new RegExp(EDGE + '?\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [CHROME]: [\n new RegExp('(' + CHROME + '|CrMo)\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [CHROME_IOS]: [\n new RegExp('CriOS\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n 'UC Browser': [\n new RegExp('(UCBrowser|UCWEB)\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [SAFARI]: [\n DEFAULT_BROWSER_VERSION_REGEX\n ],\n [MOBILE_SAFARI]: [\n DEFAULT_BROWSER_VERSION_REGEX\n ],\n [OPERA]: [\n new RegExp('(' + OPERA + '|OPR)\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [FIREFOX]: [\n new RegExp(FIREFOX + '\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [FIREFOX_IOS]: [\n new RegExp('FxiOS\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [KONQUEROR]: [\n new RegExp('Konqueror[:/]?' + BROWSER_VERSION_REGEX_SUFFIX, 'i')\n ],\n [BLACKBERRY]: [\n new RegExp(BLACKBERRY + ' ' + BROWSER_VERSION_REGEX_SUFFIX),\n DEFAULT_BROWSER_VERSION_REGEX\n ],\n [ANDROID_MOBILE]: [\n new RegExp('android\\\\s' + BROWSER_VERSION_REGEX_SUFFIX, 'i')\n ],\n [SAMSUNG_INTERNET]: [\n new RegExp(SAMSUNG_BROWSER + '\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [INTERNET_EXPLORER]: [\n new RegExp('(rv:|MSIE )' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n Mozilla: [\n new RegExp('rv:' + BROWSER_VERSION_REGEX_SUFFIX)\n ]\n};\nconst detectBrowserVersion = function(userAgent, vendor) {\n const browser = detectBrowser(userAgent, vendor);\n const regexes = versionRegexes[browser];\n if (isUndefined(regexes)) return null;\n for(let i = 0; i < regexes.length; i++){\n const regex = regexes[i];\n const matches = userAgent.match(regex);\n if (matches) return parseFloat(matches[matches.length - 2]);\n }\n return null;\n};\nconst osMatchers = [\n [\n new RegExp(XBOX + '; ' + XBOX + ' (.*?)[);]', 'i'),\n (match)=>[\n XBOX,\n match && match[1] || ''\n ]\n ],\n [\n new RegExp(NINTENDO, 'i'),\n [\n NINTENDO,\n ''\n ]\n ],\n [\n new RegExp(PLAYSTATION, 'i'),\n [\n PLAYSTATION,\n ''\n ]\n ],\n [\n BLACKBERRY_REGEX,\n [\n BLACKBERRY,\n ''\n ]\n ],\n [\n new RegExp(WINDOWS, 'i'),\n (_, user_agent)=>{\n if (/Phone/.test(user_agent) || /WPDesktop/.test(user_agent)) return [\n WINDOWS_PHONE,\n ''\n ];\n if (new RegExp(MOBILE).test(user_agent) && !/IEMobile\\b/.test(user_agent)) return [\n WINDOWS + ' ' + MOBILE,\n ''\n ];\n const match = /Windows NT ([0-9.]+)/i.exec(user_agent);\n if (match && match[1]) {\n const version = match[1];\n let osVersion = windowsVersionMap[version] || '';\n if (/arm/i.test(user_agent)) osVersion = 'RT';\n return [\n WINDOWS,\n osVersion\n ];\n }\n return [\n WINDOWS,\n ''\n ];\n }\n ],\n [\n /((iPhone|iPad|iPod).*?OS (\\d+)_(\\d+)_?(\\d+)?|iPhone)/,\n (match)=>{\n if (match && match[3]) {\n const versionParts = [\n match[3],\n match[4],\n match[5] || '0'\n ];\n return [\n IOS,\n versionParts.join('.')\n ];\n }\n return [\n IOS,\n ''\n ];\n }\n ],\n [\n /(watch.*\\/(\\d+\\.\\d+\\.\\d+)|watch os,(\\d+\\.\\d+),)/i,\n (match)=>{\n let version = '';\n if (match && match.length >= 3) version = isUndefined(match[2]) ? match[3] : match[2];\n return [\n 'watchOS',\n version\n ];\n }\n ],\n [\n new RegExp('(' + ANDROID + ' (\\\\d+)\\\\.(\\\\d+)\\\\.?(\\\\d+)?|' + ANDROID + ')', 'i'),\n (match)=>{\n if (match && match[2]) {\n const versionParts = [\n match[2],\n match[3],\n match[4] || '0'\n ];\n return [\n ANDROID,\n versionParts.join('.')\n ];\n }\n return [\n ANDROID,\n ''\n ];\n }\n ],\n [\n /Mac OS X (\\d+)[_.](\\d+)[_.]?(\\d+)?/i,\n (match)=>{\n const result = [\n 'Mac OS X',\n ''\n ];\n if (match && match[1]) {\n const versionParts = [\n match[1],\n match[2],\n match[3] || '0'\n ];\n result[1] = versionParts.join('.');\n }\n return result;\n }\n ],\n [\n /Mac/i,\n [\n 'Mac OS X',\n ''\n ]\n ],\n [\n /CrOS/,\n [\n CHROME_OS,\n ''\n ]\n ],\n [\n /Linux|debian/i,\n [\n 'Linux',\n ''\n ]\n ]\n];\nconst detectOS = function(user_agent) {\n for(let i = 0; i < osMatchers.length; i++){\n const [rgex, resultOrFn] = osMatchers[i];\n const match = rgex.exec(user_agent);\n const result = match && (isFunction(resultOrFn) ? resultOrFn(match, user_agent) : resultOrFn);\n if (result) return result;\n }\n return [\n '',\n ''\n ];\n};\nconst detectDevice = function(user_agent) {\n if (NINTENDO_REGEX.test(user_agent)) return NINTENDO;\n if (PLAYSTATION_REGEX.test(user_agent)) return PLAYSTATION;\n if (XBOX_REGEX.test(user_agent)) return XBOX;\n if (new RegExp(OUYA, 'i').test(user_agent)) return OUYA;\n if (new RegExp('(' + WINDOWS_PHONE + '|WPDesktop)', 'i').test(user_agent)) return WINDOWS_PHONE;\n else if (/iPad/.test(user_agent)) return IPAD;\n else if (/iPod/.test(user_agent)) return 'iPod Touch';\n else if (/iPhone/.test(user_agent)) return 'iPhone';\n else if (/(watch)(?: ?os[,/]|\\d,\\d\\/)[\\d.]+/i.test(user_agent)) return APPLE_WATCH;\n else if (BLACKBERRY_REGEX.test(user_agent)) return BLACKBERRY;\n else if (/(kobo)\\s(ereader|touch)/i.test(user_agent)) return 'Kobo';\n else if (new RegExp(NOKIA, 'i').test(user_agent)) return NOKIA;\n else if (/(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\\))/i.test(user_agent) || /(kf[a-z]+)( bui|\\)).+silk\\//i.test(user_agent)) return 'Kindle Fire';\n else if (/(Android|ZTE)/i.test(user_agent)) if (!(!new RegExp(MOBILE).test(user_agent) || /(9138B|TB782B|Nexus [97]|pixel c|HUAWEISHT|BTV|noble nook|smart ultra 6)/i.test(user_agent))) return ANDROID;\n else {\n if (/pixel[\\daxl ]{1,6}/i.test(user_agent) && !/pixel c/i.test(user_agent) || /(huaweimed-al00|tah-|APA|SM-G92|i980|zte|U304AA)/i.test(user_agent) || /lmy47v/i.test(user_agent) && !/QTAQZ3/i.test(user_agent)) return ANDROID;\n return ANDROID_TABLET;\n }\n else if (new RegExp('(pda|' + MOBILE + ')', 'i').test(user_agent)) return GENERIC_MOBILE;\n else if (new RegExp(TABLET, 'i').test(user_agent) && !new RegExp(TABLET + ' pc', 'i').test(user_agent)) return GENERIC_TABLET;\n else return '';\n};\nconst detectDeviceType = function(user_agent) {\n const device = detectDevice(user_agent);\n if (device === IPAD || device === ANDROID_TABLET || 'Kobo' === device || 'Kindle Fire' === device || device === GENERIC_TABLET) return TABLET;\n if (device === NINTENDO || device === XBOX || device === PLAYSTATION || device === OUYA) return 'Console';\n if (device === APPLE_WATCH) return 'Wearable';\n if (device) return MOBILE;\n return 'Desktop';\n};\nexport { detectBrowser, detectBrowserVersion, detectDevice, detectDeviceType, detectOS };\n","let parsedStackResults;\nlet lastKeysCount;\nlet cachedFilenameChunkIds;\nfunction getFilenameToChunkIdMap(stackParser) {\n const chunkIdMap = globalThis._posthogChunkIds;\n if (!chunkIdMap) return;\n const chunkIdKeys = Object.keys(chunkIdMap);\n if (cachedFilenameChunkIds && chunkIdKeys.length === lastKeysCount) return cachedFilenameChunkIds;\n lastKeysCount = chunkIdKeys.length;\n cachedFilenameChunkIds = chunkIdKeys.reduce((acc, stackKey)=>{\n if (!parsedStackResults) parsedStackResults = {};\n const result = parsedStackResults[stackKey];\n if (result) acc[result[0]] = result[1];\n else {\n const parsedStack = stackParser(stackKey);\n for(let i = parsedStack.length - 1; i >= 0; i--){\n const stackFrame = parsedStack[i];\n const filename = stackFrame?.filename;\n const chunkId = chunkIdMap[stackKey];\n if (filename && chunkId) {\n acc[filename] = chunkId;\n parsedStackResults[stackKey] = [\n filename,\n chunkId\n ];\n break;\n }\n }\n }\n return acc;\n }, {});\n return cachedFilenameChunkIds;\n}\nexport { getFilenameToChunkIdMap };\n","export * from \"./bot-detection.mjs\";\nexport * from \"./bucketed-rate-limiter.mjs\";\nexport * from \"./number-utils.mjs\";\nexport * from \"./string-utils.mjs\";\nexport * from \"./type-utils.mjs\";\nexport * from \"./promise-queue.mjs\";\nexport * from \"./logger.mjs\";\nexport * from \"./user-agent-utils.mjs\";\nconst STRING_FORMAT = 'utf8';\nfunction assert(truthyValue, message) {\n if (!truthyValue || 'string' != typeof truthyValue || isEmpty(truthyValue)) throw new Error(message);\n}\nfunction isEmpty(truthyValue) {\n if (0 === truthyValue.trim().length) return true;\n return false;\n}\nfunction removeTrailingSlash(url) {\n return url?.replace(/\\/+$/, '');\n}\nasync function retriable(fn, props) {\n let lastError = null;\n for(let i = 0; i < props.retryCount + 1; i++){\n if (i > 0) await new Promise((r)=>setTimeout(r, props.retryDelay));\n try {\n const res = await fn();\n return res;\n } catch (e) {\n lastError = e;\n if (!props.retryCheck(e)) throw e;\n }\n }\n throw lastError;\n}\nfunction currentTimestamp() {\n return new Date().getTime();\n}\nfunction currentISOTime() {\n return new Date().toISOString();\n}\nfunction safeSetTimeout(fn, timeout) {\n const t = setTimeout(fn, timeout);\n t?.unref && t?.unref();\n return t;\n}\nconst isPromise = (obj)=>obj && 'function' == typeof obj.then;\nconst isError = (x)=>x instanceof Error;\nfunction getFetch() {\n return 'undefined' != typeof fetch ? fetch : void 0 !== globalThis.fetch ? globalThis.fetch : void 0;\n}\nfunction allSettled(promises) {\n return Promise.all(promises.map((p)=>(p ?? Promise.resolve()).then((value)=>({\n status: 'fulfilled',\n value\n }), (reason)=>({\n status: 'rejected',\n reason\n }))));\n}\nexport { STRING_FORMAT, allSettled, assert, currentISOTime, currentTimestamp, getFetch, isError, isPromise, removeTrailingSlash, retriable, safeSetTimeout };\n","import { isArray } from \"../utils/index.mjs\";\nimport { getFilenameToChunkIdMap } from \"./chunk-ids.mjs\";\nconst MAX_CAUSE_RECURSION = 4;\nclass ErrorPropertiesBuilder {\n constructor(coercers, stackParser, modifiers = []){\n this.coercers = coercers;\n this.stackParser = stackParser;\n this.modifiers = modifiers;\n }\n buildFromUnknown(input, hint = {}) {\n const providedMechanism = hint && hint.mechanism;\n const mechanism = providedMechanism || {\n handled: true,\n type: 'generic'\n };\n const coercingContext = this.buildCoercingContext(mechanism, hint, 0);\n const exceptionWithCause = coercingContext.apply(input);\n const parsingContext = this.buildParsingContext();\n const exceptionWithStack = this.parseStacktrace(exceptionWithCause, parsingContext);\n const exceptionList = this.convertToExceptionList(exceptionWithStack, mechanism);\n return {\n $exception_list: exceptionList,\n $exception_level: 'error'\n };\n }\n async modifyFrames(exceptionList) {\n for (const exc of exceptionList)if (exc.stacktrace && exc.stacktrace.frames && isArray(exc.stacktrace.frames)) exc.stacktrace.frames = await this.applyModifiers(exc.stacktrace.frames);\n return exceptionList;\n }\n coerceFallback(ctx) {\n return {\n type: 'Error',\n value: 'Unknown error',\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n parseStacktrace(err, ctx) {\n let cause;\n if (null != err.cause) cause = this.parseStacktrace(err.cause, ctx);\n let stack;\n if ('' != err.stack && null != err.stack) stack = this.applyChunkIds(this.stackParser(err.stack, err.synthetic ? 1 : 0), ctx.chunkIdMap);\n return {\n ...err,\n cause,\n stack\n };\n }\n applyChunkIds(frames, chunkIdMap) {\n return frames.map((frame)=>{\n if (frame.filename && chunkIdMap) frame.chunk_id = chunkIdMap[frame.filename];\n return frame;\n });\n }\n applyCoercers(input, ctx) {\n for (const adapter of this.coercers)if (adapter.match(input)) return adapter.coerce(input, ctx);\n return this.coerceFallback(ctx);\n }\n async applyModifiers(frames) {\n let newFrames = frames;\n for (const modifier of this.modifiers)newFrames = await modifier(newFrames);\n return newFrames;\n }\n convertToExceptionList(exceptionWithStack, mechanism) {\n const currentException = {\n type: exceptionWithStack.type,\n value: exceptionWithStack.value,\n mechanism: {\n type: mechanism.type ?? 'generic',\n handled: mechanism.handled ?? true,\n synthetic: exceptionWithStack.synthetic ?? false\n }\n };\n if (exceptionWithStack.stack) currentException.stacktrace = {\n type: 'raw',\n frames: exceptionWithStack.stack\n };\n const exceptionList = [\n currentException\n ];\n if (null != exceptionWithStack.cause) exceptionList.push(...this.convertToExceptionList(exceptionWithStack.cause, {\n ...mechanism,\n handled: true\n }));\n return exceptionList;\n }\n buildParsingContext() {\n const context = {\n chunkIdMap: getFilenameToChunkIdMap(this.stackParser)\n };\n return context;\n }\n buildCoercingContext(mechanism, hint, depth = 0) {\n const coerce = (input, depth)=>{\n if (!(depth <= MAX_CAUSE_RECURSION)) return;\n {\n const ctx = this.buildCoercingContext(mechanism, hint, depth);\n return this.applyCoercers(input, ctx);\n }\n };\n const context = {\n ...hint,\n syntheticException: 0 == depth ? hint.syntheticException : void 0,\n mechanism,\n apply: (input)=>coerce(input, depth),\n next: (input)=>coerce(input, depth + 1)\n };\n return context;\n }\n}\nexport { ErrorPropertiesBuilder };\n","import { isUndefined } from \"../../utils/index.mjs\";\nconst UNKNOWN_FUNCTION = '?';\nfunction createFrame(platform, filename, func, lineno, colno) {\n const frame = {\n platform,\n filename,\n function: '<anonymous>' === func ? UNKNOWN_FUNCTION : func,\n in_app: true\n };\n if (!isUndefined(lineno)) frame.lineno = lineno;\n if (!isUndefined(colno)) frame.colno = colno;\n return frame;\n}\nexport { UNKNOWN_FUNCTION, createFrame };\n","import { UNKNOWN_FUNCTION } from \"./base.mjs\";\nconst extractSafariExtensionDetails = (func, filename)=>{\n const isSafariExtension = -1 !== func.indexOf('safari-extension');\n const isSafariWebExtension = -1 !== func.indexOf('safari-web-extension');\n return isSafariExtension || isSafariWebExtension ? [\n -1 !== func.indexOf('@') ? func.split('@')[0] : UNKNOWN_FUNCTION,\n isSafariExtension ? `safari-extension:${filename}` : `safari-web-extension:${filename}`\n ] : [\n func,\n filename\n ];\n};\nexport { extractSafariExtensionDetails };\n","import { UNKNOWN_FUNCTION, createFrame } from \"./base.mjs\";\nimport { extractSafariExtensionDetails } from \"./safari.mjs\";\nconst chromeRegexNoFnName = /^\\s*at (\\S+?)(?::(\\d+))(?::(\\d+))\\s*$/i;\nconst chromeRegex = /^\\s*at (?:(.+?\\)(?: \\[.+\\])?|.*?) ?\\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\\/)?.*?)(?::(\\d+))?(?::(\\d+))?\\)?\\s*$/i;\nconst chromeEvalRegex = /\\((\\S*)(?::(\\d+))(?::(\\d+))\\)/;\nconst chromeStackLineParser = (line, platform)=>{\n const noFnParts = chromeRegexNoFnName.exec(line);\n if (noFnParts) {\n const [, filename, line, col] = noFnParts;\n return createFrame(platform, filename, UNKNOWN_FUNCTION, +line, +col);\n }\n const parts = chromeRegex.exec(line);\n if (parts) {\n const isEval = parts[2] && 0 === parts[2].indexOf('eval');\n if (isEval) {\n const subMatch = chromeEvalRegex.exec(parts[2]);\n if (subMatch) {\n parts[2] = subMatch[1];\n parts[3] = subMatch[2];\n parts[4] = subMatch[3];\n }\n }\n const [func, filename] = extractSafariExtensionDetails(parts[1] || UNKNOWN_FUNCTION, parts[2]);\n return createFrame(platform, filename, func, parts[3] ? +parts[3] : void 0, parts[4] ? +parts[4] : void 0);\n }\n};\nexport { chromeStackLineParser };\n","import { UNKNOWN_FUNCTION, createFrame } from \"./base.mjs\";\nimport { extractSafariExtensionDetails } from \"./safari.mjs\";\nconst geckoREgex = /^\\s*(.*?)(?:\\((.*?)\\))?(?:^|@)?((?:[-a-z]+)?:\\/.*?|\\[native code\\]|[^@]*(?:bundle|\\d+\\.js)|\\/[\\w\\-. /=]+)(?::(\\d+))?(?::(\\d+))?\\s*$/i;\nconst geckoEvalRegex = /(\\S+) line (\\d+)(?: > eval line \\d+)* > eval/i;\nconst geckoStackLineParser = (line, platform)=>{\n const parts = geckoREgex.exec(line);\n if (parts) {\n const isEval = parts[3] && parts[3].indexOf(' > eval') > -1;\n if (isEval) {\n const subMatch = geckoEvalRegex.exec(parts[3]);\n if (subMatch) {\n parts[1] = parts[1] || 'eval';\n parts[3] = subMatch[1];\n parts[4] = subMatch[2];\n parts[5] = '';\n }\n }\n let filename = parts[3];\n let func = parts[1] || UNKNOWN_FUNCTION;\n [func, filename] = extractSafariExtensionDetails(func, filename);\n return createFrame(platform, filename, func, parts[4] ? +parts[4] : void 0, parts[5] ? +parts[5] : void 0);\n }\n};\nexport { geckoStackLineParser };\n","import { UNKNOWN_FUNCTION } from \"./base.mjs\";\nimport { chromeStackLineParser } from \"./chrome.mjs\";\nimport { geckoStackLineParser } from \"./gecko.mjs\";\nimport { winjsStackLineParser } from \"./winjs.mjs\";\nimport { opera10StackLineParser, opera11StackLineParser } from \"./opera.mjs\";\nimport { nodeStackLineParser } from \"./node.mjs\";\nconst WEBPACK_ERROR_REGEXP = /\\(error: (.*)\\)/;\nconst STACKTRACE_FRAME_LIMIT = 50;\nfunction reverseAndStripFrames(stack) {\n if (!stack.length) return [];\n const localStack = Array.from(stack);\n localStack.reverse();\n return localStack.slice(0, STACKTRACE_FRAME_LIMIT).map((frame)=>({\n ...frame,\n filename: frame.filename || getLastStackFrame(localStack).filename,\n function: frame.function || UNKNOWN_FUNCTION\n }));\n}\nfunction getLastStackFrame(arr) {\n return arr[arr.length - 1] || {};\n}\nfunction createDefaultStackParser() {\n return createStackParser(\"web:javascript\", chromeStackLineParser, geckoStackLineParser);\n}\nfunction createStackParser(platform, ...parsers) {\n return (stack, skipFirstLines = 0)=>{\n const frames = [];\n const lines = stack.split('\\n');\n for(let i = skipFirstLines; i < lines.length; i++){\n const line = lines[i];\n if (line.length > 1024) continue;\n const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, '$1') : line;\n if (!cleanedLine.match(/\\S*Error: /)) {\n for (const parser of parsers){\n const frame = parser(cleanedLine, platform);\n if (frame) {\n frames.push(frame);\n break;\n }\n }\n if (frames.length >= STACKTRACE_FRAME_LIMIT) break;\n }\n }\n return reverseAndStripFrames(frames);\n };\n}\nexport { chromeStackLineParser, createDefaultStackParser, createStackParser, geckoStackLineParser, nodeStackLineParser, opera10StackLineParser, opera11StackLineParser, reverseAndStripFrames, winjsStackLineParser };\n","import { isBuiltin, isString } from \"../../utils/index.mjs\";\nclass DOMExceptionCoercer {\n match(err) {\n return this.isDOMException(err) || this.isDOMError(err);\n }\n coerce(err, ctx) {\n const hasStack = isString(err.stack);\n return {\n type: this.getType(err),\n value: this.getValue(err),\n stack: hasStack ? err.stack : void 0,\n cause: err.cause ? ctx.next(err.cause) : void 0,\n synthetic: false\n };\n }\n getType(candidate) {\n return this.isDOMError(candidate) ? 'DOMError' : 'DOMException';\n }\n getValue(err) {\n const name = err.name || (this.isDOMError(err) ? 'DOMError' : 'DOMException');\n const message = err.message ? `${name}: ${err.message}` : name;\n return message;\n }\n isDOMException(err) {\n return isBuiltin(err, 'DOMException');\n }\n isDOMError(err) {\n return isBuiltin(err, 'DOMError');\n }\n}\nexport { DOMExceptionCoercer };\n","import { isPlainError } from \"../../utils/index.mjs\";\nclass ErrorCoercer {\n match(err) {\n return isPlainError(err);\n }\n coerce(err, ctx) {\n return {\n type: this.getType(err),\n value: this.getMessage(err, ctx),\n stack: this.getStack(err),\n cause: err.cause ? ctx.next(err.cause) : void 0,\n synthetic: false\n };\n }\n getType(err) {\n return err.name || err.constructor.name;\n }\n getMessage(err, _ctx) {\n const message = err.message;\n if (message.error && 'string' == typeof message.error.message) return String(message.error.message);\n return String(message);\n }\n getStack(err) {\n return err.stacktrace || err.stack || void 0;\n }\n}\nexport { ErrorCoercer };\n","import { isErrorEvent } from \"../../utils/index.mjs\";\nclass ErrorEventCoercer {\n constructor(){}\n match(err) {\n return isErrorEvent(err) && void 0 != err.error;\n }\n coerce(err, ctx) {\n const exceptionLike = ctx.apply(err.error);\n if (!exceptionLike) return {\n type: 'ErrorEvent',\n value: err.message,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n return exceptionLike;\n }\n}\nexport { ErrorEventCoercer };\n","const ERROR_TYPES_PATTERN = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;\nclass StringCoercer {\n match(input) {\n return 'string' == typeof input;\n }\n coerce(input, ctx) {\n const [type, value] = this.getInfos(input);\n return {\n type: type ?? 'Error',\n value: value ?? input,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n getInfos(candidate) {\n let type = 'Error';\n let value = candidate;\n const groups = candidate.match(ERROR_TYPES_PATTERN);\n if (groups) {\n type = groups[1];\n value = groups[2];\n }\n return [\n type,\n value\n ];\n }\n}\nexport { StringCoercer };\n","const severityLevels = [\n 'fatal',\n 'error',\n 'warning',\n 'log',\n 'info',\n 'debug'\n];\nexport { severityLevels };\n","function truncate(str, max = 0) {\n if ('string' != typeof str || 0 === max) return str;\n return str.length <= max ? str : `${str.slice(0, max)}...`;\n}\nfunction extractExceptionKeysForMessage(err, maxLength = 40) {\n const keys = Object.keys(err);\n keys.sort();\n if (!keys.length) return '[object has no keys]';\n for(let i = keys.length; i > 0; i--){\n const serialized = keys.slice(0, i).join(', ');\n if (!(serialized.length > maxLength)) {\n if (i === keys.length) return serialized;\n return serialized.length <= maxLength ? serialized : `${serialized.slice(0, maxLength)}...`;\n }\n }\n return '';\n}\nexport { extractExceptionKeysForMessage, truncate };\n","import { isEmptyString, isError, isEvent, isString } from \"../../utils/index.mjs\";\nimport { severityLevels } from \"../types.mjs\";\nimport { extractExceptionKeysForMessage } from \"./utils.mjs\";\nclass ObjectCoercer {\n match(candidate) {\n return 'object' == typeof candidate && null !== candidate;\n }\n coerce(candidate, ctx) {\n const errorProperty = this.getErrorPropertyFromObject(candidate);\n if (errorProperty) return ctx.apply(errorProperty);\n return {\n type: this.getType(candidate),\n value: this.getValue(candidate),\n stack: ctx.syntheticException?.stack,\n level: this.isSeverityLevel(candidate.level) ? candidate.level : 'error',\n synthetic: true\n };\n }\n getType(err) {\n return isEvent(err) ? err.constructor.name : 'Error';\n }\n getValue(err) {\n if ('name' in err && 'string' == typeof err.name) {\n let message = `'${err.name}' captured as exception`;\n if ('message' in err && 'string' == typeof err.message) message += ` with message: '${err.message}'`;\n return message;\n }\n if ('message' in err && 'string' == typeof err.message) return err.message;\n const className = this.getObjectClassName(err);\n const keys = extractExceptionKeysForMessage(err);\n return `${className && 'Object' !== className ? `'${className}'` : 'Object'} captured as exception with keys: ${keys}`;\n }\n isSeverityLevel(x) {\n return isString(x) && !isEmptyString(x) && severityLevels.indexOf(x) >= 0;\n }\n getErrorPropertyFromObject(obj) {\n for(const prop in obj)if (Object.prototype.hasOwnProperty.call(obj, prop)) {\n const value = obj[prop];\n if (isError(value)) return value;\n }\n }\n getObjectClassName(obj) {\n try {\n const prototype = Object.getPrototypeOf(obj);\n return prototype ? prototype.constructor.name : void 0;\n } catch (e) {\n return;\n }\n }\n}\nexport { ObjectCoercer };\n","import { isEvent } from \"../../utils/index.mjs\";\nimport { extractExceptionKeysForMessage } from \"./utils.mjs\";\nclass EventCoercer {\n match(err) {\n return isEvent(err);\n }\n coerce(evt, ctx) {\n const constructorName = evt.constructor.name;\n return {\n type: constructorName,\n value: `${constructorName} captured as exception with keys: ${extractExceptionKeysForMessage(evt)}`,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n}\nexport { EventCoercer };\n","import { isPrimitive } from \"../../utils/index.mjs\";\nclass PrimitiveCoercer {\n match(candidate) {\n return isPrimitive(candidate);\n }\n coerce(value, ctx) {\n return {\n type: 'Error',\n value: `Primitive value captured as exception: ${String(value)}`,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n}\nexport { PrimitiveCoercer };\n","import { isBuiltin, isPrimitive } from \"../../utils/index.mjs\";\nclass PromiseRejectionEventCoercer {\n match(err) {\n return isBuiltin(err, 'PromiseRejectionEvent');\n }\n coerce(err, ctx) {\n const reason = this.getUnhandledRejectionReason(err);\n if (isPrimitive(reason)) return {\n type: 'UnhandledRejection',\n value: `Non-Error promise rejection captured with value: ${String(reason)}`,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n return ctx.apply(reason);\n }\n getUnhandledRejectionReason(error) {\n if (isPrimitive(error)) return error;\n try {\n if ('reason' in error) return error.reason;\n if ('detail' in error && 'reason' in error.detail) return error.detail.reason;\n } catch {}\n return error;\n }\n}\nexport { PromiseRejectionEventCoercer };\n","import Config from '../config'\nimport { isUndefined } from '@posthog/core'\nimport { assignableWindow, window } from './globals'\nimport type { Logger } from '@posthog/core'\n\ntype CreateLoggerOptions = {\n debugEnabled?: boolean\n}\n\ntype PosthogJsLogger = Omit<Logger, 'createLogger'> & {\n _log: (level: 'log' | 'warn' | 'error', ...args: any[]) => void\n uninitializedWarning: (methodName: string) => void\n createLogger: (prefix: string, options?: CreateLoggerOptions) => PosthogJsLogger\n}\n\nconst _createLogger = (prefix: string, { debugEnabled }: CreateLoggerOptions = {}): PosthogJsLogger => {\n const logger: PosthogJsLogger = {\n _log: (level: 'log' | 'warn' | 'error', ...args: any[]) => {\n if (\n window &&\n (Config.DEBUG || assignableWindow.POSTHOG_DEBUG || debugEnabled) &&\n !isUndefined(window.console) &&\n window.console\n ) {\n const consoleLog =\n '__rrweb_original__' in window.console[level]\n ? (window.console[level] as any)['__rrweb_original__']\n : window.console[level]\n\n // eslint-disable-next-line no-console\n consoleLog(prefix, ...args)\n }\n },\n\n info: (...args: any[]) => {\n logger._log('log', ...args)\n },\n\n warn: (...args: any[]) => {\n logger._log('warn', ...args)\n },\n\n error: (...args: any[]) => {\n logger._log('error', ...args)\n },\n\n critical: (...args: any[]) => {\n // Critical errors are always logged to the console\n // eslint-disable-next-line no-console\n console.error(prefix, ...args)\n },\n\n uninitializedWarning: (methodName: string) => {\n logger.error(`You must initialize PostHog before calling ${methodName}`)\n },\n\n createLogger: (additionalPrefix: string, options?: CreateLoggerOptions) =>\n _createLogger(`${prefix} ${additionalPrefix}`, options),\n }\n return logger\n}\n\nexport const logger = _createLogger('[PostHog.js]')\n\nexport const createLogger = logger.createLogger\n","import type { PostHog } from '../posthog-core'\nimport { assignableWindow, document, PostHogExtensionKind } from '../utils/globals'\nimport { createLogger } from '../utils/logger'\n\nconst logger = createLogger('[ExternalScriptsLoader]')\n\nconst loadScript = (posthog: PostHog, url: string, callback: (error?: string | Event, event?: Event) => void) => {\n if (posthog.config.disable_external_dependency_loading) {\n logger.warn(`${url} was requested but loading of external scripts is disabled.`)\n return callback('Loading of external scripts is disabled')\n }\n\n // If we add a script more than once then the browser will parse and execute it\n // So, even if idempotent we waste parsing and processing time\n const existingScripts = document?.querySelectorAll('script')\n if (existingScripts) {\n for (let i = 0; i < existingScripts.length; i++) {\n if (existingScripts[i].src === url) {\n const alreadyExistingScriptTag = existingScripts[i]\n\n if ((alreadyExistingScriptTag as any).__posthog_loading_callback_fired) {\n // script already exists and fired its load event,\n // we call the callback again, they need to be idempotent\n return callback()\n }\n\n // eslint-disable-next-line posthog-js/no-add-event-listener\n alreadyExistingScriptTag.addEventListener('load', (event) => {\n // it hasn't already loaded\n // we probably called loadScript twice in quick succession,\n // so we attach a callback to the onload event\n ;(alreadyExistingScriptTag as any).__posthog_loading_callback_fired = true\n callback(undefined, event)\n })\n alreadyExistingScriptTag.onerror = (error) => callback(error)\n\n return // and finish processing here\n }\n }\n }\n\n const addScript = () => {\n if (!document) {\n return callback('document not found')\n }\n let scriptTag: HTMLScriptElement | null = document.createElement('script')\n scriptTag.type = 'text/javascript'\n scriptTag.crossOrigin = 'anonymous'\n scriptTag.src = url\n scriptTag.onload = (event) => {\n // mark the script as having had its callback fired, so we can avoid double-calling it\n ;(scriptTag as any).__posthog_loading_callback_fired = true\n callback(undefined, event)\n }\n scriptTag.onerror = (error) => callback(error)\n\n if (posthog.config.prepare_external_dependency_script) {\n scriptTag = posthog.config.prepare_external_dependency_script(scriptTag)\n }\n\n if (!scriptTag) {\n return callback('prepare_external_dependency_script returned null')\n }\n\n const scripts = document.querySelectorAll('body > script')\n if (scripts.length > 0) {\n scripts[0].parentNode?.insertBefore(scriptTag, scripts[0])\n } else {\n // In exceptional situations this call might load before the DOM is fully ready.\n document.body.appendChild(scriptTag)\n }\n }\n\n if (document?.body) {\n addScript()\n } else {\n // Inlining this because we don't care about `passive: true` here\n // and this saves us ~3% of the bundle size\n // eslint-disable-next-line posthog-js/no-add-event-listener\n document?.addEventListener('DOMContentLoaded', addScript)\n }\n}\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nassignableWindow.__PosthogExtensions__.loadExternalDependency = (\n posthog: PostHog,\n kind: PostHogExtensionKind,\n callback: (error?: string | Event, event?: Event) => void\n): void => {\n let scriptUrlToLoad = `/static/${kind}.js` + `?v=${posthog.version}`\n\n if (kind === 'remote-config') {\n scriptUrlToLoad = `/array/${posthog.config.token}/config.js`\n }\n\n if (kind === 'toolbar') {\n // toolbar.js is served from the PostHog CDN, this has a TTL of 24 hours.\n // the toolbar asset includes a rotating \"token\" that is valid for 5 minutes.\n const fiveMinutesInMillis = 5 * 60 * 1000\n // this ensures that we bust the cache periodically\n const timestampToNearestFiveMinutes = Math.floor(Date.now() / fiveMinutesInMillis) * fiveMinutesInMillis\n\n scriptUrlToLoad = `${scriptUrlToLoad}&t=${timestampToNearestFiveMinutes}`\n }\n const url = posthog.requestRouter.endpointFor('assets', scriptUrlToLoad)\n\n loadScript(posthog, url, callback)\n}\n\nassignableWindow.__PosthogExtensions__.loadSiteApp = (\n posthog: PostHog,\n url: string,\n callback: (error?: string | Event, event?: Event) => void\n): void => {\n const scriptUrl = posthog.requestRouter.endpointFor('api', url)\n\n loadScript(posthog, scriptUrl, callback)\n}\n","import { Breaker, Properties } from '../types'\nimport { nativeForEach, nativeIndexOf } from './globals'\nimport { logger } from './logger'\nimport { isFormData, isNull, isNullish, isNumber, isString, isUndefined, hasOwnProperty, isArray } from '@posthog/core'\n\nconst breaker: Breaker = {}\n\nexport function eachArray<E = any>(\n obj: E[] | null | undefined,\n iterator: (value: E, key: number) => void | Breaker,\n thisArg?: any\n): void {\n if (isArray(obj)) {\n if (nativeForEach && obj.forEach === nativeForEach) {\n obj.forEach(iterator, thisArg)\n } else if ('length' in obj && obj.length === +obj.length) {\n for (let i = 0, l = obj.length; i < l; i++) {\n if (i in obj && iterator.call(thisArg, obj[i], i) === breaker) {\n return\n }\n }\n }\n }\n}\n\n/**\n * @param {*=} obj\n * @param {function(...*)=} iterator\n * @param {Object=} thisArg\n */\nexport function each(obj: any, iterator: (value: any, key: any) => void | Breaker, thisArg?: any): void {\n if (isNullish(obj)) {\n return\n }\n if (isArray(obj)) {\n return eachArray(obj, iterator, thisArg)\n }\n if (isFormData(obj)) {\n for (const pair of obj.entries()) {\n if (iterator.call(thisArg, pair[1], pair[0]) === breaker) {\n return\n }\n }\n return\n }\n for (const key in obj) {\n if (hasOwnProperty.call(obj, key)) {\n if (iterator.call(thisArg, obj[key], key) === breaker) {\n return\n }\n }\n }\n}\n\nexport const extend = function (obj: Record<string, any>, ...args: Record<string, any>[]): Record<string, any> {\n eachArray(args, function (source) {\n for (const prop in source) {\n if (source[prop] !== void 0) {\n obj[prop] = source[prop]\n }\n }\n })\n return obj\n}\n\nexport const extendArray = function <T>(obj: T[], ...args: T[][]): T[] {\n eachArray(args, function (source) {\n eachArray(source, function (item) {\n obj.push(item)\n })\n })\n return obj\n}\n\nexport const include = function (\n obj: null | string | Array<any> | Record<string, any>,\n target: any\n): boolean | Breaker {\n let found = false\n if (isNull(obj)) {\n return found\n }\n if (nativeIndexOf && obj.indexOf === nativeIndexOf) {\n return obj.indexOf(target) != -1\n }\n each(obj, function (value) {\n if (found || (found = value === target)) {\n return breaker\n }\n return\n })\n return found\n}\n\n/**\n * Object.entries() polyfill\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries\n */\nexport function entries<T = any>(obj: Record<string, T>): [string, T][] {\n const ownProps = Object.keys(obj)\n let i = ownProps.length\n const resArray = new Array(i) // preallocate the Array\n\n while (i--) {\n resArray[i] = [ownProps[i], obj[ownProps[i]]]\n }\n return resArray\n}\n\nexport const trySafe = function <T>(fn: () => T): T | undefined {\n try {\n return fn()\n } catch {\n return undefined\n }\n}\n\nexport const safewrap = function <F extends (...args: any[]) => any = (...args: any[]) => any>(f: F): F {\n return function (...args) {\n try {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return f.apply(this, args)\n } catch (e) {\n logger.critical(\n 'Implementation error. Please turn on debug mode and open a ticket on https://app.posthog.com/home#panel=support%3Asupport%3A.'\n )\n logger.critical(e)\n }\n } as F\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport const safewrapClass = function (klass: Function, functions: string[]): void {\n for (let i = 0; i < functions.length; i++) {\n klass.prototype[functions[i]] = safewrap(klass.prototype[functions[i]])\n }\n}\n\nexport const stripEmptyProperties = function (p: Properties): Properties {\n const ret: Properties = {}\n each(p, function (v, k) {\n if ((isString(v) && v.length > 0) || isNumber(v)) {\n ret[k] = v\n }\n })\n return ret\n}\n\n/**\n * Deep copies an object.\n * It handles cycles by replacing all references to them with `undefined`\n * Also supports customizing native values\n *\n * @param value\n * @param customizer\n * @returns {{}|undefined|*}\n */\nfunction deepCircularCopy<T extends Record<string, any> = Record<string, any>>(\n value: T,\n customizer?: <K extends keyof T = keyof T>(value: T[K], key?: K) => T[K]\n): T | undefined {\n const COPY_IN_PROGRESS_SET = new Set()\n\n function internalDeepCircularCopy(value: T, key?: string): T | undefined {\n if (value !== Object(value)) return customizer ? customizer(value as any, key) : value // primitive value\n\n if (COPY_IN_PROGRESS_SET.has(value)) return undefined\n COPY_IN_PROGRESS_SET.add(value)\n let result: T\n\n if (isArray(value)) {\n result = [] as any as T\n eachArray(value, (it) => {\n result.push(internalDeepCircularCopy(it))\n })\n } else {\n result = {} as T\n each(value, (val, key) => {\n if (!COPY_IN_PROGRESS_SET.has(val)) {\n ;(result as any)[key] = internalDeepCircularCopy(val, key)\n }\n })\n }\n return result\n }\n return internalDeepCircularCopy(value)\n}\n\nexport function _copyAndTruncateStrings<T extends Record<string, any> = Record<string, any>>(\n object: T,\n maxStringLength: number | null\n): T {\n return deepCircularCopy(object, (value: any) => {\n if (isString(value) && !isNull(maxStringLength)) {\n return (value as string).slice(0, maxStringLength)\n }\n return value\n }) as T\n}\n\n// NOTE: Update PostHogConfig docs if you change this list\n// We will not try to catch all bullets here, but we should make an effort to catch the most common ones\n// You should be highly against adding more to this list, because ultimately customers can configure\n// their `cross_subdomain_cookie` setting to anything they want.\nconst EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE = ['herokuapp.com', 'vercel.app', 'netlify.app']\nexport function isCrossDomainCookie(documentLocation: Location | undefined) {\n const hostname = documentLocation?.hostname\n\n if (!isString(hostname)) {\n return false\n }\n // split and slice isn't a great way to match arbitrary domains,\n // but it's good enough for ensuring we only match herokuapp.com when it is the TLD\n // for the hostname\n const lastTwoParts = hostname.split('.').slice(-2).join('.')\n\n for (const excluded of EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE) {\n if (lastTwoParts === excluded) {\n return false\n }\n }\n\n return true\n}\n\nexport function find<T>(value: T[], predicate: (value: T) => boolean): T | undefined {\n for (let i = 0; i < value.length; i++) {\n if (predicate(value[i])) {\n return value[i]\n }\n }\n return undefined\n}\n\n// Use this instead of element.addEventListener to avoid eslint errors\n// this properly implements the default options for passive event listeners\nexport function addEventListener(\n element: Window | Document | Element | undefined,\n event: string,\n callback: EventListener,\n options?: AddEventListenerOptions\n): void {\n const { capture = false, passive = true } = options ?? {}\n\n // This is the only place where we are allowed to call this function\n // because the whole idea is that we should be calling this instead of the built-in one\n // eslint-disable-next-line posthog-js/no-add-event-listener\n element?.addEventListener(event, callback, { capture, passive })\n}\n\n/**\n * Helper to migrate deprecated config fields to new field names with appropriate warnings\n * @param config - The config object to check\n * @param newField - The new field name to use\n * @param oldField - The deprecated field name to check for\n * @param defaultValue - The default value if neither field is set\n * @param loggerInstance - Optional logger instance for deprecation warnings\n * @returns The value to use (new field takes precedence over old field)\n */\nexport function migrateConfigField<T>(\n config: Record<string, any>,\n newField: string,\n oldField: string,\n defaultValue: T,\n loggerInstance?: { warn: (message: string) => void }\n): T {\n const hasNewField = newField in config && !isUndefined(config[newField])\n const hasOldField = oldField in config && !isUndefined(config[oldField])\n\n if (hasNewField) {\n return config[newField]\n }\n\n if (hasOldField) {\n if (loggerInstance) {\n loggerInstance.warn(\n `Config field '${oldField}' is deprecated. Please use '${newField}' instead. ` +\n `The old field will be removed in a future major version.`\n )\n }\n return config[oldField]\n }\n\n return defaultValue\n}\n","/*\n * Constants\n */\n\n/* PROPERTY KEYS */\n\n// This key is deprecated, but we want to check for it to see whether aliasing is allowed.\nexport const PEOPLE_DISTINCT_ID_KEY = '$people_distinct_id'\nexport const DISTINCT_ID = 'distinct_id'\nexport const DEVICE_ID = '$device_id'\nexport const ALIAS_ID_KEY = '__alias'\nexport const CAMPAIGN_IDS_KEY = '__cmpns'\nexport const EVENT_TIMERS_KEY = '__timers'\nexport const AUTOCAPTURE_DISABLED_SERVER_SIDE = '$autocapture_disabled_server_side'\nexport const HEATMAPS_ENABLED_SERVER_SIDE = '$heatmaps_enabled_server_side'\nexport const EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE = '$exception_capture_enabled_server_side'\nexport const ERROR_TRACKING_SUPPRESSION_RULES = '$error_tracking_suppression_rules'\nexport const ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS = '$error_tracking_capture_extension_exceptions'\nexport const WEB_VITALS_ENABLED_SERVER_SIDE = '$web_vitals_enabled_server_side'\nexport const DEAD_CLICKS_ENABLED_SERVER_SIDE = '$dead_clicks_enabled_server_side'\nexport const PRODUCT_TOURS_ENABLED_SERVER_SIDE = '$product_tours_enabled_server_side'\nexport const WEB_VITALS_ALLOWED_METRICS = '$web_vitals_allowed_metrics'\nexport const SESSION_RECORDING_REMOTE_CONFIG = '$session_recording_remote_config'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_ENABLED_SERVER_SIDE = '$session_recording_enabled_server_side'\n// @deprecated can be removed along with eager loaded replay\nexport const CONSOLE_LOG_RECORDING_ENABLED_SERVER_SIDE = '$console_log_recording_enabled_server_side'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_NETWORK_PAYLOAD_CAPTURE = '$session_recording_network_payload_capture'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_MASKING = '$session_recording_masking'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_CANVAS_RECORDING = '$session_recording_canvas_recording'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_SAMPLE_RATE = '$replay_sample_rate'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_MINIMUM_DURATION = '$replay_minimum_duration'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_SCRIPT_CONFIG = '$replay_script_config'\nexport const SESSION_RECORDING_OVERRIDE_SAMPLING = '$replay_override_sampling'\nexport const SESSION_RECORDING_OVERRIDE_LINKED_FLAG = '$replay_override_linked_flag'\nexport const SESSION_RECORDING_OVERRIDE_URL_TRIGGER = '$replay_override_url_trigger'\nexport const SESSION_RECORDING_OVERRIDE_EVENT_TRIGGER = '$replay_override_event_trigger'\nexport const SESSION_ID = '$sesid'\nexport const SESSION_RECORDING_IS_SAMPLED = '$session_is_sampled'\nexport const SESSION_RECORDING_PAST_MINIMUM_DURATION = '$session_past_minimum_duration'\nexport const SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION = '$session_recording_url_trigger_activated_session'\nexport const SESSION_RECORDING_EVENT_TRIGGER_ACTIVATED_SESSION = '$session_recording_event_trigger_activated_session'\nexport const ENABLED_FEATURE_FLAGS = '$enabled_feature_flags'\nexport const PERSISTENCE_EARLY_ACCESS_FEATURES = '$early_access_features'\nexport const PERSISTENCE_FEATURE_FLAG_DETAILS = '$feature_flag_details'\nexport const STORED_PERSON_PROPERTIES_KEY = '$stored_person_properties'\nexport const STORED_GROUP_PROPERTIES_KEY = '$stored_group_properties'\nexport const SURVEYS = '$surveys'\nexport const SURVEYS_ACTIVATED = '$surveys_activated'\nexport const PRODUCT_TOURS_ACTIVATED = '$product_tours_activated'\nexport const CONVERSATIONS = '$conversations'\nexport const FLAG_CALL_REPORTED = '$flag_call_reported'\nexport const USER_STATE = '$user_state'\nexport const CLIENT_SESSION_PROPS = '$client_session_props'\nexport const CAPTURE_RATE_LIMIT = '$capture_rate_limit'\n\n/** @deprecated Delete this when INITIAL_PERSON_INFO has been around for long enough to ignore backwards compat */\nexport const INITIAL_CAMPAIGN_PARAMS = '$initial_campaign_params'\n/** @deprecated Delete this when INITIAL_PERSON_INFO has been around for long enough to ignore backwards compat */\nexport const INITIAL_REFERRER_INFO = '$initial_referrer_info'\nexport const INITIAL_PERSON_INFO = '$initial_person_info'\nexport const ENABLE_PERSON_PROCESSING = '$epp'\nexport const TOOLBAR_ID = '__POSTHOG_TOOLBAR__'\nexport const TOOLBAR_CONTAINER_CLASS = 'toolbar-global-fade-container'\n\n/**\n * PREVIEW - MAY CHANGE WITHOUT WARNING - DO NOT USE IN PRODUCTION\n * Sentinel value for distinct id, device id, session id. Signals that the server should generate the value\n * */\nexport const COOKIELESS_SENTINEL_VALUE = '$posthog_cookieless'\nexport const COOKIELESS_MODE_FLAG_PROPERTY = '$cookieless_mode'\n\nexport const WEB_EXPERIMENTS = '$web_experiments'\n\n// These are properties that are reserved and will not be automatically included in events\nexport const PERSISTENCE_RESERVED_PROPERTIES = [\n PEOPLE_DISTINCT_ID_KEY,\n ALIAS_ID_KEY,\n CAMPAIGN_IDS_KEY,\n EVENT_TIMERS_KEY,\n SESSION_RECORDING_ENABLED_SERVER_SIDE,\n HEATMAPS_ENABLED_SERVER_SIDE,\n SESSION_ID,\n ENABLED_FEATURE_FLAGS,\n ERROR_TRACKING_SUPPRESSION_RULES,\n USER_STATE,\n PERSISTENCE_EARLY_ACCESS_FEATURES,\n PERSISTENCE_FEATURE_FLAG_DETAILS,\n STORED_GROUP_PROPERTIES_KEY,\n STORED_PERSON_PROPERTIES_KEY,\n SURVEYS,\n FLAG_CALL_REPORTED,\n CLIENT_SESSION_PROPS,\n CAPTURE_RATE_LIMIT,\n INITIAL_CAMPAIGN_PARAMS,\n INITIAL_REFERRER_INFO,\n ENABLE_PERSON_PROCESSING,\n INITIAL_PERSON_INFO,\n // Conversations keys (defined in lazy-loaded extension)\n '$conversations_widget_session_id',\n '$conversations_ticket_id',\n '$conversations_widget_state',\n '$conversations_user_traits',\n]\n\nexport const SURVEYS_REQUEST_TIMEOUT_MS = 10000\n","import { TOOLBAR_CONTAINER_CLASS, TOOLBAR_ID } from '../constants'\n\nexport function isElementInToolbar(el: EventTarget | null): boolean {\n if (el instanceof Element) {\n // closest isn't available in IE11, but we'll polyfill when bundling\n return el.id === TOOLBAR_ID || !!el.closest?.('.' + TOOLBAR_CONTAINER_CLASS)\n }\n return false\n}\n\n/*\n * Check whether an element has nodeType Node.ELEMENT_NODE\n * @param {Element} el - element to check\n * @returns {boolean} whether el is of the correct nodeType\n */\nexport function isElementNode(el: Node | Element | undefined | null): el is Element {\n return !!el && el.nodeType === 1 // Node.ELEMENT_NODE - use integer constant for browser portability\n}\n\n/*\n * Check whether an element is of a given tag type.\n * Due to potential reference discrepancies (such as the webcomponents.js polyfill),\n * we want to match tagNames instead of specific references because something like\n * element === document.body won't always work because element might not be a native\n * element.\n * @param {Element} el - element to check\n * @param {string} tag - tag name (e.g., \"div\")\n * @returns {boolean} whether el is of the given tag type\n */\nexport function isTag(el: Element | undefined | null, tag: string): el is HTMLElement {\n return !!el && !!el.tagName && el.tagName.toLowerCase() === tag.toLowerCase()\n}\n\n/*\n * Check whether an element has nodeType Node.TEXT_NODE\n * @param {Element} el - element to check\n * @returns {boolean} whether el is of the correct nodeType\n */\nexport function isTextNode(el: Element | undefined | null): el is HTMLElement {\n return !!el && el.nodeType === 3 // Node.TEXT_NODE - use integer constant for browser portability\n}\n\n/*\n * Check whether an element has nodeType Node.DOCUMENT_FRAGMENT_NODE\n * @param {Element} el - element to check\n * @returns {boolean} whether el is of the correct nodeType\n */\nexport function isDocumentFragment(el: Element | ParentNode | undefined | null): el is DocumentFragment {\n return !!el && el.nodeType === 11 // Node.DOCUMENT_FRAGMENT_NODE - use integer constant for browser portability\n}\n","import { AutocaptureConfig, PostHogConfig, Properties } from './types'\nimport { each, entries } from './utils'\n\nimport { isNullish, isString, isUndefined, isArray, isBoolean } from '@posthog/core'\nimport { logger } from './utils/logger'\nimport { window } from './utils/globals'\nimport { isDocumentFragment, isElementNode, isTag, isTextNode } from './utils/element-utils'\nimport { includes, trim } from '@posthog/core'\n\nexport function splitClassString(s: string): string[] {\n return s ? trim(s).split(/\\s+/) : []\n}\n\nfunction checkForURLMatches(urlsList: (string | RegExp)[]): boolean {\n const url = window?.location.href\n return !!(url && urlsList && urlsList.some((regex) => url.match(regex)))\n}\n\n/*\n * Get the className of an element, accounting for edge cases where element.className is an object\n *\n * Because this is a string it can contain unexpected characters\n * So, this method safely splits the className and returns that array.\n */\nexport function getClassNames(el: Element): string[] {\n let className = ''\n switch (typeof el.className) {\n case 'string':\n className = el.className\n break\n // TODO: when is this ever used?\n case 'object': // handle cases where className might be SVGAnimatedString or some other type\n className =\n (el.className && 'baseVal' in el.className ? (el.className as any).baseVal : null) ||\n el.getAttribute('class') ||\n ''\n break\n default:\n className = ''\n }\n\n return splitClassString(className)\n}\n\nexport function makeSafeText(s: string | null | undefined): string | null {\n if (isNullish(s)) {\n return null\n }\n\n return (\n trim(s)\n // scrub potentially sensitive values\n .split(/(\\s+)/)\n .filter((s) => shouldCaptureValue(s))\n .join('')\n // normalize whitespace\n .replace(/[\\r\\n]/g, ' ')\n .replace(/[ ]+/g, ' ')\n // truncate\n .substring(0, 255)\n )\n}\n\n/*\n * Get the direct text content of an element, protecting against sensitive data collection.\n * Concats textContent of each of the element's text node children; this avoids potential\n * collection of sensitive data that could happen if we used element.textContent and the\n * element had sensitive child elements, since element.textContent includes child content.\n * Scrubs values that look like they could be sensitive (i.e. cc or ssn number).\n * @param {Element} el - element to get the text of\n * @returns {string} the element's direct text content\n */\nexport function getSafeText(el: Element): string {\n let elText = ''\n\n if (shouldCaptureElement(el) && !isSensitiveElement(el) && el.childNodes && el.childNodes.length) {\n each(el.childNodes, function (child) {\n if (isTextNode(child) && child.textContent) {\n elText += makeSafeText(child.textContent) ?? ''\n }\n })\n }\n\n return trim(elText)\n}\n\nexport function getEventTarget(e: Event): Element | null {\n // https://developer.mozilla.org/en-US/docs/Web/API/Event/target#Compatibility_notes\n if (isUndefined(e.target)) {\n return (e.srcElement as Element) || null\n } else {\n if ((e.target as HTMLElement)?.shadowRoot) {\n return (e.composedPath()[0] as Element) || null\n }\n return (e.target as Element) || null\n }\n}\n\nexport const autocaptureCompatibleElements = ['a', 'button', 'form', 'input', 'select', 'textarea', 'label']\n\n/*\n if there is no config, then all elements are allowed\n if there is a config, and there is an allow list, then only elements in the allow list are allowed\n assumes that some other code is checking this element's parents\n */\nfunction checkIfElementTreePassesElementAllowList(\n elements: Element[],\n autocaptureConfig: AutocaptureConfig | undefined\n): boolean {\n const allowlist = autocaptureConfig?.element_allowlist\n if (isUndefined(allowlist)) {\n // everything is allowed, when there is no allow list\n return true\n }\n\n // check each element in the tree\n // if any of the elements are in the allow list, then the tree is allowed\n for (const el of elements) {\n if (allowlist.some((elementType) => el.tagName.toLowerCase() === elementType)) {\n return true\n }\n }\n\n // otherwise there is an allow list and this element tree didn't match it\n return false\n}\n\n/*\n if there is no selector list (i.e. it is undefined), then any elements matches\n if there is an empty list, then no elements match\n if there is a selector list, then check it against each element provided\n */\nfunction checkIfElementsMatchCSSSelector(elements: Element[], selectorList: string[] | undefined): boolean {\n if (isUndefined(selectorList)) {\n // everything is allowed, when there is no selector list\n return true\n }\n\n for (const el of elements) {\n if (selectorList.some((selector) => el.matches(selector))) {\n return true\n }\n }\n\n return false\n}\n\nexport function getParentElement(curEl: Element): Element | false {\n const parentNode = curEl.parentNode\n if (!parentNode || !isElementNode(parentNode)) return false\n return parentNode\n}\n\nconst DEFAULT_CONTENT_IGNORELIST = ['next', 'previous', 'prev', '>', '<']\nconst MAX_CONTENT_IGNORELIST_ENTRIES = 10\n\ninterface ElementWithText {\n safeText: string\n ariaLabel: string\n}\n\nfunction shouldIgnoreByContent(\n contentIgnorelist: boolean | string[] | undefined,\n elementsWithText: ElementWithText[]\n): boolean {\n if (contentIgnorelist === false || isUndefined(contentIgnorelist)) {\n return false\n }\n\n let keywords: string[]\n if (contentIgnorelist === true) {\n keywords = DEFAULT_CONTENT_IGNORELIST\n } else if (isArray(contentIgnorelist)) {\n if (contentIgnorelist.length > MAX_CONTENT_IGNORELIST_ENTRIES) {\n logger.error(\n `[PostHog] content_ignorelist array cannot exceed ${MAX_CONTENT_IGNORELIST_ENTRIES} items. Use css_selector_ignorelist for more complex matching.`\n )\n return false\n }\n keywords = contentIgnorelist.map((k) => k.toLowerCase())\n } else {\n return false\n }\n\n return elementsWithText.some(({ safeText, ariaLabel }) => {\n return keywords.some((keyword) => safeText.includes(keyword) || ariaLabel.includes(keyword))\n })\n}\n\n// autocapture check will already filter for ph-no-capture,\n// but we include it here to protect against future changes accidentally removing that check\nconst DEFAULT_RAGE_CLICK_IGNORE_LIST = ['.ph-no-rageclick', '.ph-no-capture']\nexport function shouldCaptureRageclick(el: Element | null, _config: PostHogConfig['rageclick']) {\n if (!window || cannotCheckForAutocapture(el)) {\n return false\n }\n\n let selectorIgnoreList: string[] | boolean\n let contentIgnorelist: boolean | string[] | undefined\n if (isBoolean(_config)) {\n selectorIgnoreList = _config ? DEFAULT_RAGE_CLICK_IGNORE_LIST : false\n // For backward compatibility, don't enable content filtering for rageclick: true\n contentIgnorelist = undefined\n } else {\n selectorIgnoreList = _config?.css_selector_ignorelist ?? DEFAULT_RAGE_CLICK_IGNORE_LIST\n contentIgnorelist = _config?.content_ignorelist\n }\n\n if (selectorIgnoreList === false) {\n return false\n }\n\n // Traverse DOM once and cache element data to avoid redundant calls to getSafeText\n const { targetElementList } = getElementAndParentsForElement(el, false)\n const elementsWithText: ElementWithText[] = targetElementList.map((element) => ({\n safeText: getSafeText(element).toLowerCase(),\n ariaLabel: element.getAttribute('aria-label')?.toLowerCase().trim() || '',\n }))\n\n if (shouldIgnoreByContent(contentIgnorelist, elementsWithText)) {\n return false\n }\n\n // we don't capture if we match the ignore list\n return !checkIfElementsMatchCSSSelector(targetElementList, selectorIgnoreList)\n}\n\nconst cannotCheckForAutocapture = (el: Element | null) => {\n return !el || isTag(el, 'html') || !isElementNode(el)\n}\n\nconst getElementAndParentsForElement = (el: Element, captureOnAnyElement: false | true | undefined) => {\n if (!window || cannotCheckForAutocapture(el)) {\n return { parentIsUsefulElement: false, targetElementList: [] }\n }\n\n let parentIsUsefulElement = false\n const targetElementList: Element[] = [el]\n let curEl: Element = el\n while (curEl.parentNode && !isTag(curEl, 'body')) {\n // If element is a shadow root, we skip it\n if (isDocumentFragment(curEl.parentNode)) {\n targetElementList.push((curEl.parentNode as any).host)\n curEl = (curEl.parentNode as any).host\n continue\n }\n const parentNode = getParentElement(curEl)\n if (!parentNode) break\n if (captureOnAnyElement || autocaptureCompatibleElements.indexOf(parentNode.tagName.toLowerCase()) > -1) {\n parentIsUsefulElement = true\n } else {\n const compStyles = window.getComputedStyle(parentNode)\n if (compStyles && compStyles.getPropertyValue('cursor') === 'pointer') {\n parentIsUsefulElement = true\n }\n }\n\n targetElementList.push(parentNode)\n curEl = parentNode\n }\n return { parentIsUsefulElement, targetElementList }\n}\n\n/*\n * Check whether a DOM event should be \"captured\" or if it may contain sensitive data\n * using a variety of heuristics.\n * @param {Element} el - element to check\n * @param {Event} event - event to check\n * @param {Object} autocaptureConfig - autocapture config\n * @param {boolean} captureOnAnyElement - whether to capture on any element, clipboard autocapture doesn't restrict to \"clickable\" elements\n * @param {string[]} allowedEventTypes - event types to capture, normally just 'click', but some autocapture types react to different events, some elements have fixed events (e.g., form has \"submit\")\n * @returns {boolean} whether the event should be captured\n */\nexport function shouldCaptureDomEvent(\n el: Element,\n event: Event,\n autocaptureConfig: AutocaptureConfig | undefined = undefined,\n captureOnAnyElement?: boolean,\n allowedEventTypes?: string[]\n): boolean {\n if (!window || cannotCheckForAutocapture(el)) {\n return false\n }\n\n if (autocaptureConfig?.url_allowlist) {\n // if the current URL is not in the allow list, don't capture\n if (!checkForURLMatches(autocaptureConfig.url_allowlist)) {\n return false\n }\n }\n\n if (autocaptureConfig?.url_ignorelist) {\n // if the current URL is in the ignore list, don't capture\n if (checkForURLMatches(autocaptureConfig.url_ignorelist)) {\n return false\n }\n }\n\n if (autocaptureConfig?.dom_event_allowlist) {\n const allowlist = autocaptureConfig.dom_event_allowlist\n if (allowlist && !allowlist.some((eventType) => event.type === eventType)) {\n return false\n }\n }\n\n const { parentIsUsefulElement, targetElementList } = getElementAndParentsForElement(el, captureOnAnyElement)\n\n if (!checkIfElementTreePassesElementAllowList(targetElementList, autocaptureConfig)) {\n return false\n }\n\n if (!checkIfElementsMatchCSSSelector(targetElementList, autocaptureConfig?.css_selector_allowlist)) {\n return false\n }\n\n const compStyles = window.getComputedStyle(el)\n if (compStyles && compStyles.getPropertyValue('cursor') === 'pointer' && event.type === 'click') {\n return true\n }\n\n const tag = el.tagName.toLowerCase()\n switch (tag) {\n case 'html':\n return false\n case 'form':\n return (allowedEventTypes || ['submit']).indexOf(event.type) >= 0\n case 'input':\n case 'select':\n case 'textarea':\n return (allowedEventTypes || ['change', 'click']).indexOf(event.type) >= 0\n default:\n if (parentIsUsefulElement) return (allowedEventTypes || ['click']).indexOf(event.type) >= 0\n return (\n (allowedEventTypes || ['click']).indexOf(event.type) >= 0 &&\n (autocaptureCompatibleElements.indexOf(tag) > -1 || el.getAttribute('contenteditable') === 'true')\n )\n }\n}\n\n/*\n * Check whether a DOM element should be \"captured\" or if it may contain sensitive data\n * using a variety of heuristics.\n * @param {Element} el - element to check\n * @returns {boolean} whether the element should be captured\n */\nexport function shouldCaptureElement(el: Element): boolean {\n for (let curEl = el; curEl.parentNode && !isTag(curEl, 'body'); curEl = curEl.parentNode as Element) {\n const classes = getClassNames(curEl)\n if (includes(classes, 'ph-sensitive') || includes(classes, 'ph-no-capture')) {\n return false\n }\n }\n\n if (includes(getClassNames(el), 'ph-include')) {\n return true\n }\n\n // don't include hidden or password fields\n const type = (el as HTMLInputElement).type || ''\n if (isString(type)) {\n // it's possible for el.type to be a DOM element if el is a form with a child input[name=\"type\"]\n switch (type.toLowerCase()) {\n case 'hidden':\n return false\n case 'password':\n return false\n }\n }\n\n // filter out data from fields that look like sensitive fields\n const name = (el as HTMLInputElement).name || el.id || ''\n // See https://github.com/posthog/posthog-js/issues/165\n // Under specific circumstances a bug caused .replace to be called on a DOM element\n // instead of a string, removing the element from the page. Ensure this issue is mitigated.\n if (isString(name)) {\n // it's possible for el.name or el.id to be a DOM element if el is a form with a child input[name=\"name\"]\n const sensitiveNameRegex =\n /^cc|cardnum|ccnum|creditcard|csc|cvc|cvv|exp|pass|pwd|routing|seccode|securitycode|securitynum|socialsec|socsec|ssn/i\n if (sensitiveNameRegex.test(name.replace(/[^a-zA-Z0-9]/g, ''))) {\n return false\n }\n }\n\n return true\n}\n\n/*\n * Check whether a DOM element is 'sensitive' and we should only capture limited data\n * @param {Element} el - element to check\n * @returns {boolean} whether the element should be captured\n */\nexport function isSensitiveElement(el: Element): boolean {\n // don't send data from inputs or similar elements since there will always be\n // a risk of clientside javascript placing sensitive data in attributes\n const allowedInputTypes = ['button', 'checkbox', 'submit', 'reset']\n if (\n (isTag(el, 'input') && !allowedInputTypes.includes((el as HTMLInputElement).type)) ||\n isTag(el, 'select') ||\n isTag(el, 'textarea') ||\n el.getAttribute('contenteditable') === 'true'\n ) {\n return true\n }\n return false\n}\n\n// Define the core pattern for matching credit card numbers\nconst 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})`\n// Create the Anchored version of the regex by adding '^' at the start and '$' at the end\nconst anchoredCCRegex = new RegExp(`^(?:${coreCCPattern})$`)\n// The Unanchored version is essentially the core pattern, usable as is for partial matches\nconst unanchoredCCRegex = new RegExp(coreCCPattern)\n\n// Define the core pattern for matching SSNs with optional dashes\nconst coreSSNPattern = `\\\\d{3}-?\\\\d{2}-?\\\\d{4}`\n// Create the Anchored version of the regex by adding '^' at the start and '$' at the end\nconst anchoredSSNRegex = new RegExp(`^(${coreSSNPattern})$`)\n// The Unanchored version is essentially the core pattern itself, usable for partial matches\nconst unanchoredSSNRegex = new RegExp(`(${coreSSNPattern})`)\n\n/*\n * Check whether a string value should be \"captured\" or if it may contain sensitive data\n * using a variety of heuristics.\n * @param {string} value - string value to check\n * @param {boolean} anchorRegexes - whether to anchor the regexes to the start and end of the string\n * @returns {boolean} whether the element should be captured\n */\nexport function shouldCaptureValue(value: string, anchorRegexes = true): boolean {\n if (isNullish(value)) {\n return false\n }\n\n if (isString(value)) {\n value = trim(value)\n\n // check to see if input value looks like a credit card number\n // see: https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch04s20.html\n const ccRegex = anchorRegexes ? anchoredCCRegex : unanchoredCCRegex\n if (ccRegex.test((value || '').replace(/[- ]/g, ''))) {\n return false\n }\n\n // check to see if input value looks like a social security number\n const ssnRegex = anchorRegexes ? anchoredSSNRegex : unanchoredSSNRegex\n if (ssnRegex.test(value)) {\n return false\n }\n }\n\n return true\n}\n\n/*\n * Check whether an attribute name is an Angular style attr (either _ngcontent or _nghost)\n * These update on each build and lead to noise in the element chain\n * More details on the attributes here: https://angular.io/guide/view-encapsulation\n * @param {string} attributeName - string value to check\n * @returns {boolean} whether the element is an angular tag\n */\nexport function isAngularStyleAttr(attributeName: string): boolean {\n if (isString(attributeName)) {\n return attributeName.substring(0, 10) === '_ngcontent' || attributeName.substring(0, 7) === '_nghost'\n }\n return false\n}\n\n/*\n * Iterate through children of a target element looking for span tags\n * and return the text content of the span tags, separated by spaces,\n * along with the direct text content of the target element\n * @param {Element} target - element to check\n * @returns {string} text content of the target element and its child span tags\n */\nexport function getDirectAndNestedSpanText(target: Element): string {\n let text = getSafeText(target)\n text = `${text} ${getNestedSpanText(target)}`.trim()\n return shouldCaptureValue(text) ? text : ''\n}\n\n/*\n * Iterate through children of a target element looking for span tags\n * and return the text content of the span tags, separated by spaces\n * @param {Element} target - element to check\n * @returns {string} text content of span tags\n */\nexport function getNestedSpanText(target: Element): string {\n let text = ''\n if (target && target.childNodes && target.childNodes.length) {\n each(target.childNodes, function (child) {\n if (child && child.tagName?.toLowerCase() === 'span') {\n try {\n const spanText = getSafeText(child)\n text = `${text} ${spanText}`.trim()\n\n if (child.childNodes && child.childNodes.length) {\n text = `${text} ${getNestedSpanText(child)}`.trim()\n }\n } catch (e) {\n logger.error('[AutoCapture]', e)\n }\n }\n })\n }\n return text\n}\n\n/*\nBack in the day storing events in Postgres we use Elements for autocapture events.\nNow we're using elements_chain. We used to do this parsing/processing during ingestion.\nThis code is just copied over from ingestion, but we should optimize it\nto create elements_chain string directly.\n*/\nexport function getElementsChainString(elements: Properties[]): string {\n return elementsToString(extractElements(elements))\n}\n\n// This interface is called 'Element' in plugin-scaffold https://github.com/PostHog/plugin-scaffold/blob/b07d3b879796ecc7e22deb71bf627694ba05386b/src/types.ts#L200\n// However 'Element' is a DOM Element when run in the browser, so we have to rename it\ninterface PHElement {\n text?: string\n tag_name?: string\n href?: string\n attr_id?: string\n attr_class?: string[]\n nth_child?: number\n nth_of_type?: number\n attributes?: Record<string, any>\n event_id?: number\n order?: number\n group_id?: number\n}\n\nfunction escapeQuotes(input: string): string {\n return input.replace(/\"|\\\\\"/g, '\\\\\"')\n}\n\nfunction elementsToString(elements: PHElement[]): string {\n const ret = elements.map((element) => {\n let el_string = ''\n if (element.tag_name) {\n el_string += element.tag_name\n }\n if (element.attr_class) {\n element.attr_class.sort()\n for (const single_class of element.attr_class) {\n el_string += `.${single_class.replace(/\"/g, '')}`\n }\n }\n const attributes: Record<string, any> = {\n ...(element.text ? { text: element.text } : {}),\n 'nth-child': element.nth_child ?? 0,\n 'nth-of-type': element.nth_of_type ?? 0,\n ...(element.href ? { href: element.href } : {}),\n ...(element.attr_id ? { attr_id: element.attr_id } : {}),\n ...element.attributes,\n }\n const sortedAttributes: Record<string, any> = {}\n entries(attributes)\n .sort(([a], [b]) => a.localeCompare(b))\n .forEach(\n ([key, value]) => (sortedAttributes[escapeQuotes(key.toString())] = escapeQuotes(value.toString()))\n )\n el_string += ':'\n el_string += entries(sortedAttributes)\n .map(([key, value]) => `${key}=\"${value}\"`)\n .join('')\n return el_string\n })\n return ret.join(';')\n}\n\nfunction extractElements(elements: Properties[]): PHElement[] {\n return elements.map((el) => {\n const response = {\n text: el['$el_text']?.slice(0, 400),\n tag_name: el['tag_name'],\n href: el['attr__href']?.slice(0, 2048),\n attr_class: extractAttrClass(el),\n attr_id: el['attr__id'],\n nth_child: el['nth_child'],\n nth_of_type: el['nth_of_type'],\n attributes: {} as { [id: string]: any },\n }\n\n entries(el)\n .filter(([key]) => key.indexOf('attr__') === 0)\n .forEach(([key, value]) => (response.attributes[key] = value))\n return response\n })\n}\n\nfunction extractAttrClass(el: Properties): PHElement['attr_class'] {\n const attr_class = el['attr__class']\n if (!attr_class) {\n return undefined\n } else if (isArray(attr_class)) {\n return attr_class\n } else {\n return splitClassString(attr_class)\n }\n}\n","// Naive rage click implementation: If mouse has not moved further than thresholdPx\n// over clickCount clicks with max timeoutMs between clicks, it's\n// counted as a rage click\n\nimport { isObject } from '@posthog/core'\nimport { RageclickConfig } from '../types'\n\nconst DEFAULT_THRESHOLD_PX = 30\nconst DEFAULT_TIMEOUT_MS = 1000\nconst DEFAULT_CLICK_COUNT = 3\n\nexport default class RageClick {\n clicks: { x: number; y: number; timestamp: number }[]\n\n thresholdPx: number\n timeoutMs: number\n clickCount: number\n disabled: boolean\n\n constructor(rageclickConfig: RageclickConfig | boolean) {\n this.disabled = rageclickConfig === false\n const conf = isObject(rageclickConfig) ? rageclickConfig : {}\n\n this.thresholdPx = conf.threshold_px || DEFAULT_THRESHOLD_PX\n this.timeoutMs = conf.timeout_ms || DEFAULT_TIMEOUT_MS\n this.clickCount = conf.click_count || DEFAULT_CLICK_COUNT\n\n this.clicks = []\n }\n\n isRageClick(x: number, y: number, timestamp: number): boolean {\n if (this.disabled) {\n return false\n }\n\n const lastClick = this.clicks[this.clicks.length - 1]\n if (\n lastClick &&\n Math.abs(x - lastClick.x) + Math.abs(y - lastClick.y) < this.thresholdPx &&\n timestamp - lastClick.timestamp < this.timeoutMs\n ) {\n this.clicks.push({ x, y, timestamp })\n\n if (this.clicks.length === this.clickCount) {\n return true\n }\n } else {\n this.clicks = [{ x, y, timestamp }]\n }\n\n return false\n }\n}\n","import { each } from './'\n\nimport { isArray, isFile, isUndefined } from '@posthog/core'\nimport { logger } from './logger'\nimport { document } from './globals'\n\nconst localDomains = ['localhost', '127.0.0.1']\n\n/**\n * IE11 doesn't support `new URL`\n * so we can create an anchor element and use that to parse the URL\n * there's a lot of overlap between HTMLHyperlinkElementUtils and URL\n * meaning useful properties like `pathname` are available on both\n */\nexport const convertToURL = (url: string): HTMLAnchorElement | null => {\n const location = document?.createElement('a')\n if (isUndefined(location)) {\n return null\n }\n\n location.href = url\n return location\n}\n\nexport const formDataToQuery = function (formdata: Record<string, any> | FormData, arg_separator = '&'): string {\n let use_val: string\n let use_key: string\n const tph_arr: string[] = []\n\n each(formdata, function (val: File | string | undefined, key: string | undefined) {\n // the key might be literally the string undefined for e.g. if {undefined: 'something'}\n if (isUndefined(val) || isUndefined(key) || key === 'undefined') {\n return\n }\n\n use_val = encodeURIComponent(isFile(val) ? val.name : val.toString())\n use_key = encodeURIComponent(key)\n tph_arr[tph_arr.length] = use_key + '=' + use_val\n })\n\n return tph_arr.join(arg_separator)\n}\n\n// NOTE: Once we get rid of IE11/op_mini we can start using URLSearchParams\nexport const getQueryParam = function (url: string, param: string): string {\n const withoutHash: string = url.split('#')[0] || ''\n\n // Split only on the first ? to sort problem out for those with multiple ?s\n // and then remove them\n const queryParams: string = withoutHash.split(/\\?(.*)/)[1] || ''\n const cleanedQueryParams = queryParams.replace(/^\\?+/g, '')\n\n const queryParts = cleanedQueryParams.split('&')\n let keyValuePair\n\n for (let i = 0; i < queryParts.length; i++) {\n const parts = queryParts[i].split('=')\n if (parts[0] === param) {\n keyValuePair = parts\n break\n }\n }\n\n if (!isArray(keyValuePair) || keyValuePair.length < 2) {\n return ''\n } else {\n let result = keyValuePair[1]\n try {\n result = decodeURIComponent(result)\n } catch {\n logger.error('Skipping decoding for malformed query param: ' + result)\n }\n return result.replace(/\\+/g, ' ')\n }\n}\n\n// replace any query params in the url with the provided mask value. Tries to keep the URL as instant as possible,\n// including preserving malformed text in most cases\nexport const maskQueryParams = function <T extends string | undefined>(\n url: T,\n maskedParams: string[] | undefined,\n mask: string\n): T extends string ? string : undefined {\n if (!url || !maskedParams || !maskedParams.length) {\n return url as any\n }\n\n const splitHash = url.split('#')\n const withoutHash: string = splitHash[0] || ''\n const hash = splitHash[1]\n\n const splitQuery: string[] = withoutHash.split('?')\n const queryString: string = splitQuery[1]\n const urlWithoutQueryAndHash: string = splitQuery[0]\n const queryParts = (queryString || '').split('&')\n\n // use an array of strings rather than an object to preserve ordering and duplicates\n const paramStrings: string[] = []\n\n for (let i = 0; i < queryParts.length; i++) {\n const keyValuePair = queryParts[i].split('=')\n if (!isArray(keyValuePair)) {\n continue\n } else if (maskedParams.includes(keyValuePair[0])) {\n paramStrings.push(keyValuePair[0] + '=' + mask)\n } else {\n paramStrings.push(queryParts[i])\n }\n }\n\n let result = urlWithoutQueryAndHash\n if (queryString != null) {\n result += '?' + paramStrings.join('&')\n }\n if (hash != null) {\n result += '#' + hash\n }\n\n return result as any\n}\n\nexport const _getHashParam = function (hash: string, param: string): string | null {\n const matches = hash.match(new RegExp(param + '=([^&]*)'))\n return matches ? matches[1] : null\n}\n\nexport const isLocalhost = (): boolean => {\n return localDomains.includes(location.hostname)\n}\n","import { addEventListener, each, extend } from './utils'\nimport {\n autocaptureCompatibleElements,\n getClassNames,\n getDirectAndNestedSpanText,\n getElementsChainString,\n getEventTarget,\n getSafeText,\n isAngularStyleAttr,\n isSensitiveElement,\n makeSafeText,\n shouldCaptureDomEvent,\n shouldCaptureElement,\n shouldCaptureRageclick,\n shouldCaptureValue,\n splitClassString,\n} from './autocapture-utils'\n\nimport RageClick from './extensions/rageclick'\nimport { AutocaptureConfig, EventName, Properties, RemoteConfig } from './types'\nimport { PostHog } from './posthog-core'\nimport { AUTOCAPTURE_DISABLED_SERVER_SIDE } from './constants'\n\nimport { isBoolean, isFunction, isNull, isObject } from '@posthog/core'\nimport { createLogger } from './utils/logger'\nimport { document, window } from './utils/globals'\nimport { convertToURL } from './utils/request-utils'\nimport { isDocumentFragment, isElementNode, isTag, isTextNode } from './utils/element-utils'\nimport { includes } from '@posthog/core'\n\nconst COPY_AUTOCAPTURE_EVENT = '$copy_autocapture'\n\nconst logger = createLogger('[AutoCapture]')\n\nfunction limitText(length: number, text: string): string {\n if (text.length > length) {\n return text.slice(0, length) + '...'\n }\n return text\n}\n\nexport function getAugmentPropertiesFromElement(elem: Element): Properties {\n const shouldCaptureEl = shouldCaptureElement(elem)\n if (!shouldCaptureEl) {\n return {}\n }\n\n const props: Properties = {}\n\n each(elem.attributes, function (attr: Attr) {\n if (attr.name && attr.name.indexOf('data-ph-capture-attribute') === 0) {\n const propertyKey = attr.name.replace('data-ph-capture-attribute-', '')\n const propertyValue = attr.value\n if (propertyKey && propertyValue && shouldCaptureValue(propertyValue)) {\n props[propertyKey] = propertyValue\n }\n }\n })\n\n return props\n}\n\nexport function previousElementSibling(el: Element): Element | null {\n if (el.previousElementSibling) {\n return el.previousElementSibling\n }\n let _el: Element | null = el\n do {\n _el = _el.previousSibling as Element | null // resolves to ChildNode->Node, which is Element's parent class\n } while (_el && !isElementNode(_el))\n return _el\n}\n\nexport function getDefaultProperties(eventType: string): Properties {\n return {\n $event_type: eventType,\n $ce_version: 1,\n }\n}\n\nexport function getPropertiesFromElement(\n elem: Element,\n maskAllAttributes: boolean,\n maskText: boolean,\n elementAttributeIgnorelist: string[] | undefined\n): Properties {\n const tag_name = elem.tagName.toLowerCase()\n const props: Properties = {\n tag_name: tag_name,\n }\n if (autocaptureCompatibleElements.indexOf(tag_name) > -1 && !maskText) {\n if (tag_name.toLowerCase() === 'a' || tag_name.toLowerCase() === 'button') {\n props['$el_text'] = limitText(1024, getDirectAndNestedSpanText(elem))\n } else {\n props['$el_text'] = limitText(1024, getSafeText(elem))\n }\n }\n\n const classes = getClassNames(elem)\n if (classes.length > 0)\n props['classes'] = classes.filter(function (c) {\n return c !== ''\n })\n\n // capture the deny list here because this not-a-class class makes it tricky to use this.config in the function below\n each(elem.attributes, function (attr: Attr) {\n // Only capture attributes we know are safe\n if (isSensitiveElement(elem) && ['name', 'id', 'class', 'aria-label'].indexOf(attr.name) === -1) return\n\n if (elementAttributeIgnorelist?.includes(attr.name)) return\n\n if (!maskAllAttributes && shouldCaptureValue(attr.value) && !isAngularStyleAttr(attr.name)) {\n let value = attr.value\n if (attr.name === 'class') {\n // html attributes can _technically_ contain linebreaks,\n // but we're very intolerant of them in the class string,\n // so we strip them.\n value = splitClassString(value).join(' ')\n }\n props['attr__' + attr.name] = limitText(1024, value)\n }\n })\n\n let nthChild = 1\n let nthOfType = 1\n let currentElem: Element | null = elem\n while ((currentElem = previousElementSibling(currentElem))) {\n // eslint-disable-line no-cond-assign\n nthChild++\n if (currentElem.tagName === elem.tagName) {\n nthOfType++\n }\n }\n props['nth_child'] = nthChild\n props['nth_of_type'] = nthOfType\n\n return props\n}\n\nexport function autocapturePropertiesForElement(\n target: Element,\n {\n e,\n maskAllElementAttributes,\n maskAllText,\n elementAttributeIgnoreList,\n elementsChainAsString,\n }: {\n e: Event\n maskAllElementAttributes: boolean\n maskAllText: boolean\n elementAttributeIgnoreList?: string[] | undefined\n elementsChainAsString: boolean\n }\n): { props: Properties; explicitNoCapture?: boolean } {\n const targetElementList = [target]\n let curEl = target\n while (curEl.parentNode && !isTag(curEl, 'body')) {\n if (isDocumentFragment(curEl.parentNode)) {\n targetElementList.push((curEl.parentNode as any).host)\n curEl = (curEl.parentNode as any).host\n continue\n }\n targetElementList.push(curEl.parentNode as Element)\n curEl = curEl.parentNode as Element\n }\n\n const elementsJson: Properties[] = []\n const autocaptureAugmentProperties: Properties = {}\n let href: string | false = false\n let explicitNoCapture = false\n\n each(targetElementList, (el) => {\n const shouldCaptureEl = shouldCaptureElement(el)\n\n // if the element or a parent element is an anchor tag\n // include the href as a property\n if (el.tagName.toLowerCase() === 'a') {\n href = el.getAttribute('href')\n href = shouldCaptureEl && href && shouldCaptureValue(href) && href\n }\n\n // allow users to programmatically prevent capturing of elements by adding class 'ph-no-capture'\n const classes = getClassNames(el)\n if (includes(classes, 'ph-no-capture')) {\n explicitNoCapture = true\n }\n\n elementsJson.push(\n getPropertiesFromElement(el, maskAllElementAttributes, maskAllText, elementAttributeIgnoreList)\n )\n\n const augmentProperties = getAugmentPropertiesFromElement(el)\n extend(autocaptureAugmentProperties, augmentProperties)\n })\n\n if (explicitNoCapture) {\n return { props: {}, explicitNoCapture }\n }\n\n if (!maskAllText) {\n // if the element is a button or anchor tag get the span text from any\n // children and include it as/with the text property on the parent element\n if (target.tagName.toLowerCase() === 'a' || target.tagName.toLowerCase() === 'button') {\n elementsJson[0]['$el_text'] = getDirectAndNestedSpanText(target)\n } else {\n elementsJson[0]['$el_text'] = getSafeText(target)\n }\n }\n\n let externalHref: string | undefined\n if (href) {\n elementsJson[0]['attr__href'] = href\n const hrefHost = convertToURL(href)?.host\n const locationHost = window?.location?.host\n if (hrefHost && locationHost && hrefHost !== locationHost) {\n externalHref = href\n }\n }\n\n const props = extend(\n getDefaultProperties(e.type),\n // Sending \"$elements\" is deprecated. Only one client on US cloud uses this.\n !elementsChainAsString ? { $elements: elementsJson } : {},\n // Always send $elements_chain, as it's needed downstream in site app filtering\n { $elements_chain: getElementsChainString(elementsJson) },\n elementsJson[0]?.['$el_text'] ? { $el_text: elementsJson[0]?.['$el_text'] } : {},\n externalHref && e.type === 'click' ? { $external_click_url: externalHref } : {},\n autocaptureAugmentProperties\n )\n\n return { props }\n}\n\nexport class Autocapture {\n instance: PostHog\n _initialized: boolean = false\n _isDisabledServerSide: boolean | null = null\n _elementSelectors: Set<string> | null\n rageclicks: RageClick\n _elementsChainAsString = false\n\n constructor(instance: PostHog) {\n this.instance = instance\n this.rageclicks = new RageClick(instance.config.rageclick)\n this._elementSelectors = null\n }\n\n private get _config(): AutocaptureConfig {\n const config = isObject(this.instance.config.autocapture) ? this.instance.config.autocapture : {}\n // precompile the regex\n config.url_allowlist = config.url_allowlist?.map((url) => new RegExp(url))\n config.url_ignorelist = config.url_ignorelist?.map((url) => new RegExp(url))\n return config\n }\n\n _addDomEventHandlers(): void {\n if (!this.isBrowserSupported()) {\n logger.info('Disabling Automatic Event Collection because this browser is not supported')\n return\n }\n\n if (!window || !document) {\n return\n }\n\n const handler = (e: Event) => {\n e = e || window?.event\n try {\n this._captureEvent(e)\n } catch (error) {\n logger.error('Failed to capture event', error)\n }\n }\n\n addEventListener(document, 'submit', handler, { capture: true })\n addEventListener(document, 'change', handler, { capture: true })\n addEventListener(document, 'click', handler, { capture: true })\n\n if (this._config.capture_copied_text) {\n const copiedTextHandler = (e: Event) => {\n e = e || window?.event\n this._captureEvent(e, COPY_AUTOCAPTURE_EVENT)\n }\n\n addEventListener(document, 'copy', copiedTextHandler, { capture: true })\n addEventListener(document, 'cut', copiedTextHandler, { capture: true })\n }\n }\n\n public startIfEnabled() {\n if (this.isEnabled && !this._initialized) {\n this._addDomEventHandlers()\n this._initialized = true\n }\n }\n\n public onRemoteConfig(response: RemoteConfig) {\n if (response.elementsChainAsString) {\n this._elementsChainAsString = response.elementsChainAsString\n }\n\n if (this.instance.persistence) {\n this.instance.persistence.register({\n [AUTOCAPTURE_DISABLED_SERVER_SIDE]: !!response['autocapture_opt_out'],\n })\n }\n // store this in-memory in case persistence is disabled\n this._isDisabledServerSide = !!response['autocapture_opt_out']\n this.startIfEnabled()\n }\n\n public setElementSelectors(selectors: Set<string>): void {\n this._elementSelectors = selectors\n }\n\n public getElementSelectors(element: Element | null): string[] | null {\n const elementSelectors: string[] = []\n\n this._elementSelectors?.forEach((selector) => {\n const matchedElements = document?.querySelectorAll(selector)\n matchedElements?.forEach((matchedElement: Element) => {\n if (element === matchedElement) {\n elementSelectors.push(selector)\n }\n })\n })\n\n return elementSelectors\n }\n\n public get isEnabled(): boolean {\n const persistedServerDisabled = this.instance.persistence?.props[AUTOCAPTURE_DISABLED_SERVER_SIDE]\n const memoryDisabled = this._isDisabledServerSide\n\n if (isNull(memoryDisabled) && !isBoolean(persistedServerDisabled) && !this.instance._shouldDisableFlags()) {\n // We only enable if we know that the server has not disabled it (unless /flags is disabled)\n return false\n }\n\n const disabledServer = this._isDisabledServerSide ?? !!persistedServerDisabled\n const disabledClient = !this.instance.config.autocapture\n return !disabledClient && !disabledServer\n }\n\n private _captureEvent(e: Event, eventName: EventName = '$autocapture'): boolean | void {\n if (!this.isEnabled) {\n return\n }\n\n /*** Don't mess with this code without running IE8 tests on it ***/\n let target = getEventTarget(e)\n if (isTextNode(target)) {\n // defeat Safari bug (see: http://www.quirksmode.org/js/events_properties.html)\n target = (target.parentNode || null) as Element | null\n }\n\n if (eventName === '$autocapture' && e.type === 'click' && e instanceof MouseEvent) {\n if (\n !!this.instance.config.rageclick &&\n this.rageclicks?.isRageClick(e.clientX, e.clientY, e.timeStamp || new Date().getTime())\n ) {\n if (shouldCaptureRageclick(target, this.instance.config.rageclick)) {\n this._captureEvent(e, '$rageclick')\n }\n }\n }\n\n const isCopyAutocapture = eventName === COPY_AUTOCAPTURE_EVENT\n if (\n target &&\n shouldCaptureDomEvent(\n target,\n e,\n this._config,\n // mostly this method cares about the target element, but in the case of copy events,\n // we want some of the work this check does without insisting on the target element's type\n isCopyAutocapture,\n // we also don't want to restrict copy checks to clicks,\n // so we pass that knowledge in here, rather than add the logic inside the check\n isCopyAutocapture ? ['copy', 'cut'] : undefined\n )\n ) {\n const { props, explicitNoCapture } = autocapturePropertiesForElement(target, {\n e,\n maskAllElementAttributes: this.instance.config.mask_all_element_attributes,\n maskAllText: this.instance.config.mask_all_text,\n elementAttributeIgnoreList: this._config.element_attribute_ignorelist,\n elementsChainAsString: this._elementsChainAsString,\n })\n\n if (explicitNoCapture) {\n return false\n }\n\n const elementSelectors = this.getElementSelectors(target)\n if (elementSelectors && elementSelectors.length > 0) {\n props['$element_selectors'] = elementSelectors\n }\n\n if (eventName === COPY_AUTOCAPTURE_EVENT) {\n // you can't read the data from the clipboard event,\n // but you can guess that you can read it from the window's current selection\n const selectedContent = makeSafeText(window?.getSelection()?.toString())\n const clipType = (e as ClipboardEvent).type || 'clipboard'\n if (!selectedContent) {\n return false\n }\n props['$selected_content'] = selectedContent\n props['$copy_type'] = clipType\n }\n\n this.instance.capture(eventName, props)\n return true\n }\n }\n\n isBrowserSupported(): boolean {\n return isFunction(document?.querySelectorAll)\n }\n}\n","/**\n * uuidv7: An experimental implementation of the proposed UUID Version 7\n *\n * @license Apache-2.0\n * @copyright 2021-2023 LiosK\n * @packageDocumentation\n *\n * from https://github.com/LiosK/uuidv7/blob/e501462ea3d23241de13192ceae726956f9b3b7d/src/index.ts\n */\n\n// polyfill for IE11\nimport { window } from './utils/globals'\n\nimport { isNumber, isUndefined } from '@posthog/core'\n\nif (!Math.trunc) {\n Math.trunc = function (v) {\n return v < 0 ? Math.ceil(v) : Math.floor(v)\n }\n}\n\n// polyfill for IE11\nif (!Number.isInteger) {\n Number.isInteger = function (value) {\n return isNumber(value) && isFinite(value) && Math.floor(value) === value\n }\n}\n\nconst DIGITS = '0123456789abcdef'\n\n/** Represents a UUID as a 16-byte byte array. */\nexport class UUID {\n /** @param bytes - The 16-byte byte array representation. */\n constructor(readonly bytes: Readonly<Uint8Array>) {\n if (bytes.length !== 16) {\n throw new TypeError('not 128-bit length')\n }\n }\n\n /**\n * Builds a byte array from UUIDv7 field values.\n *\n * @param unixTsMs - A 48-bit `unix_ts_ms` field value.\n * @param randA - A 12-bit `rand_a` field value.\n * @param randBHi - The higher 30 bits of 62-bit `rand_b` field value.\n * @param randBLo - The lower 32 bits of 62-bit `rand_b` field value.\n */\n static fromFieldsV7(unixTsMs: number, randA: number, randBHi: number, randBLo: number): UUID {\n if (\n !Number.isInteger(unixTsMs) ||\n !Number.isInteger(randA) ||\n !Number.isInteger(randBHi) ||\n !Number.isInteger(randBLo) ||\n unixTsMs < 0 ||\n randA < 0 ||\n randBHi < 0 ||\n randBLo < 0 ||\n unixTsMs > 0xffff_ffff_ffff ||\n randA > 0xfff ||\n randBHi > 0x3fff_ffff ||\n randBLo > 0xffff_ffff\n ) {\n throw new RangeError('invalid field value')\n }\n\n const bytes = new Uint8Array(16)\n bytes[0] = unixTsMs / 2 ** 40\n bytes[1] = unixTsMs / 2 ** 32\n bytes[2] = unixTsMs / 2 ** 24\n bytes[3] = unixTsMs / 2 ** 16\n bytes[4] = unixTsMs / 2 ** 8\n bytes[5] = unixTsMs\n bytes[6] = 0x70 | (randA >>> 8)\n bytes[7] = randA\n bytes[8] = 0x80 | (randBHi >>> 24)\n bytes[9] = randBHi >>> 16\n bytes[10] = randBHi >>> 8\n bytes[11] = randBHi\n bytes[12] = randBLo >>> 24\n bytes[13] = randBLo >>> 16\n bytes[14] = randBLo >>> 8\n bytes[15] = randBLo\n return new UUID(bytes)\n }\n\n /** @returns The 8-4-4-4-12 canonical hexadecimal string representation. */\n toString(): string {\n let text = ''\n for (let i = 0; i < this.bytes.length; i++) {\n text = text + DIGITS.charAt(this.bytes[i] >>> 4) + DIGITS.charAt(this.bytes[i] & 0xf)\n if (i === 3 || i === 5 || i === 7 || i === 9) {\n text += '-'\n }\n }\n\n if (text.length !== 36) {\n // We saw one customer whose bundling code was mangling the UUID generation\n // rather than accept a bad UUID, we throw an error here.\n throw new Error('Invalid UUIDv7 was generated')\n }\n return text\n }\n\n /** Creates an object from `this`. */\n clone(): UUID {\n return new UUID(this.bytes.slice(0))\n }\n\n /** Returns true if `this` is equivalent to `other`. */\n equals(other: UUID): boolean {\n return this.compareTo(other) === 0\n }\n\n /**\n * Returns a negative integer, zero, or positive integer if `this` is less\n * than, equal to, or greater than `other`, respectively.\n */\n compareTo(other: UUID): number {\n for (let i = 0; i < 16; i++) {\n const diff = this.bytes[i] - other.bytes[i]\n if (diff !== 0) {\n return Math.sign(diff)\n }\n }\n return 0\n }\n}\n\n/** Encapsulates the monotonic counter state. */\nclass V7Generator {\n private _timestamp = 0\n private _counter = 0\n private readonly _random = new DefaultRandom()\n\n /**\n * Generates a new UUIDv7 object from the current timestamp, or resets the\n * generator upon significant timestamp rollback.\n *\n * This method returns monotonically increasing UUIDs unless the up-to-date\n * timestamp is significantly (by ten seconds or more) smaller than the one\n * embedded in the immediately preceding UUID. If such a significant clock\n * rollback is detected, this method resets the generator and returns a new\n * UUID based on the current timestamp.\n */\n generate(): UUID {\n const value = this.generateOrAbort()\n if (!isUndefined(value)) {\n return value\n } else {\n // reset state and resume\n this._timestamp = 0\n const valueAfterReset = this.generateOrAbort()\n if (isUndefined(valueAfterReset)) {\n throw new Error('Could not generate UUID after timestamp reset')\n }\n return valueAfterReset\n }\n }\n\n /**\n * Generates a new UUIDv7 object from the current timestamp, or returns\n * `undefined` upon significant timestamp rollback.\n *\n * This method returns monotonically increasing UUIDs unless the up-to-date\n * timestamp is significantly (by ten seconds or more) smaller than the one\n * embedded in the immediately preceding UUID. If such a significant clock\n * rollback is detected, this method aborts and returns `undefined`.\n */\n generateOrAbort(): UUID | undefined {\n const MAX_COUNTER = 0x3ff_ffff_ffff\n const ROLLBACK_ALLOWANCE = 10_000 // 10 seconds\n\n const ts = Date.now()\n if (ts > this._timestamp) {\n this._timestamp = ts\n this._resetCounter()\n } else if (ts + ROLLBACK_ALLOWANCE > this._timestamp) {\n // go on with previous timestamp if new one is not much smaller\n this._counter++\n if (this._counter > MAX_COUNTER) {\n // increment timestamp at counter overflow\n this._timestamp++\n this._resetCounter()\n }\n } else {\n // abort if clock went backwards to unbearable extent\n return undefined\n }\n\n return UUID.fromFieldsV7(\n this._timestamp,\n Math.trunc(this._counter / 2 ** 30),\n this._counter & (2 ** 30 - 1),\n this._random.nextUint32()\n )\n }\n\n /** Initializes the counter at a 42-bit random integer. */\n private _resetCounter(): void {\n this._counter = this._random.nextUint32() * 0x400 + (this._random.nextUint32() & 0x3ff)\n }\n}\n\n/** A global flag to force use of cryptographically strong RNG. */\ndeclare const UUIDV7_DENY_WEAK_RNG: boolean\n\n/** Stores `crypto.getRandomValues()` available in the environment. */\nlet getRandomValues: <T extends Uint8Array | Uint32Array>(buffer: T) => T = (buffer) => {\n // fall back on Math.random() unless the flag is set to true\n // TRICKY: don't use the isUndefined method here as can't pass the reference\n if (typeof UUIDV7_DENY_WEAK_RNG !== 'undefined' && UUIDV7_DENY_WEAK_RNG) {\n throw new Error('no cryptographically strong RNG available')\n }\n\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] = Math.trunc(Math.random() * 0x1_0000) * 0x1_0000 + Math.trunc(Math.random() * 0x1_0000)\n }\n return buffer\n}\n\n// detect Web Crypto API\nif (window && !isUndefined(window.crypto) && crypto.getRandomValues) {\n getRandomValues = (buffer) => crypto.getRandomValues(buffer)\n}\n\n/**\n * Wraps `crypto.getRandomValues()` and compatibles to enable buffering; this\n * uses a small buffer by default to avoid unbearable throughput decline in some\n * environments as well as the waste of time and space for unused values.\n */\nclass DefaultRandom {\n private readonly _buffer = new Uint32Array(8)\n private _cursor = Infinity\n nextUint32(): number {\n if (this._cursor >= this._buffer.length) {\n getRandomValues(this._buffer)\n this._cursor = 0\n }\n return this._buffer[this._cursor++]\n }\n}\n\nlet defaultGenerator: V7Generator | undefined\n\n/**\n * Generates a UUIDv7 string.\n *\n * @returns The 8-4-4-4-12 canonical hexadecimal string representation\n * (\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\").\n */\nexport const uuidv7 = (): string => uuidv7obj().toString()\n\n/** Generates a UUIDv7 object. */\nconst uuidv7obj = (): UUID => (defaultGenerator || (defaultGenerator = new V7Generator())).generate()\n\nexport const uuid7ToTimestampMs = (uuid: string): number => {\n // remove hyphens\n const hex = uuid.replace(/-/g, '')\n // ensure that it's a version 7 UUID\n if (hex.length !== 32) {\n throw new Error('Not a valid UUID')\n }\n if (hex[12] !== '7') {\n throw new Error('Not a UUIDv7')\n }\n // the first 6 bytes are the timestamp, which means that we can read only the first 12 hex characters\n return parseInt(hex.substring(0, 12), 16)\n}\n","import { extend } from './utils'\nimport { PersistentStore, Properties } from './types'\nimport {\n DEVICE_ID,\n DISTINCT_ID,\n ENABLE_PERSON_PROCESSING,\n INITIAL_PERSON_INFO,\n SESSION_ID,\n SESSION_RECORDING_IS_SAMPLED,\n} from './constants'\n\nimport { isNull, isUndefined } from '@posthog/core'\nimport { logger } from './utils/logger'\nimport { window, document } from './utils/globals'\nimport { uuidv7 } from './uuidv7'\n\n// we store the discovered subdomain in memory because it might be read multiple times\nlet firstNonPublicSubDomain = ''\n\n// helper to allow tests to clear this \"cache\"\nexport const resetSubDomainCache = () => {\n firstNonPublicSubDomain = ''\n}\n\n/**\n * Browsers don't offer a way to check if something is a public suffix\n * e.g. `.com.au`, `.io`, `.org.uk`\n *\n * But they do reject cookies set on public suffixes\n * Setting a cookie on `.co.uk` would mean it was sent for every `.co.uk` site visited\n *\n * So, we can use this to check if a domain is a public suffix\n * by trying to set a cookie on a subdomain of the provided hostname\n * until the browser accepts it\n *\n * inspired by https://github.com/AngusFu/browser-root-domain\n */\nexport function seekFirstNonPublicSubDomain(hostname: string, cookieJar = document): string {\n if (firstNonPublicSubDomain) {\n return firstNonPublicSubDomain\n }\n\n if (!cookieJar) {\n return ''\n }\n if (['localhost', '127.0.0.1'].includes(hostname)) return ''\n\n const list = hostname.split('.')\n let len = Math.min(list.length, 8) // paranoia - we know this number should be small\n const key = 'dmn_chk_' + uuidv7()\n\n while (!firstNonPublicSubDomain && len--) {\n const candidate = list.slice(len).join('.')\n const candidateCookieValue = key + '=1;domain=.' + candidate + ';path=/'\n\n // try to set cookie, include a short expiry in seconds since we'll check immediately\n cookieJar.cookie = candidateCookieValue + ';max-age=3'\n\n if (cookieJar.cookie.includes(key)) {\n // the cookie was accepted by the browser, remove the test cookie\n cookieJar.cookie = candidateCookieValue + ';max-age=0'\n firstNonPublicSubDomain = candidate\n }\n }\n\n return firstNonPublicSubDomain\n}\n\nconst DOMAIN_MATCH_REGEX = /[a-z0-9][a-z0-9-]+\\.[a-z]{2,}$/i\nconst originalCookieDomainFn = (hostname: string): string => {\n const matches = hostname.match(DOMAIN_MATCH_REGEX)\n return matches ? matches[0] : ''\n}\n\nexport function chooseCookieDomain(hostname: string, cross_subdomain: boolean | undefined): string {\n if (cross_subdomain) {\n // NOTE: Could we use this for cross domain tracking?\n let matchedSubDomain = seekFirstNonPublicSubDomain(hostname)\n\n if (!matchedSubDomain) {\n const originalMatch = originalCookieDomainFn(hostname)\n if (originalMatch !== matchedSubDomain) {\n logger.info('Warning: cookie subdomain discovery mismatch', originalMatch, matchedSubDomain)\n }\n matchedSubDomain = originalMatch\n }\n\n return matchedSubDomain ? '; domain=.' + matchedSubDomain : ''\n }\n return ''\n}\n\n// Methods partially borrowed from quirksmode.org/js/cookies.html\nexport const cookieStore: PersistentStore = {\n _is_supported: () => !!document,\n\n _error: function (msg) {\n logger.error('cookieStore error: ' + msg)\n },\n\n _get: function (name) {\n if (!document) {\n return\n }\n\n try {\n const nameEQ = name + '='\n const ca = document.cookie.split(';').filter((x) => x.length)\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i]\n while (c.charAt(0) == ' ') {\n c = c.substring(1, c.length)\n }\n if (c.indexOf(nameEQ) === 0) {\n return decodeURIComponent(c.substring(nameEQ.length, c.length))\n }\n }\n } catch {}\n return null\n },\n\n _parse: function (name) {\n let cookie\n try {\n cookie = JSON.parse(cookieStore._get(name)) || {}\n } catch {\n // noop\n }\n return cookie\n },\n\n _set: function (name, value, days, cross_subdomain, is_secure) {\n if (!document) {\n return\n }\n try {\n let expires = '',\n secure = ''\n\n const cdomain = chooseCookieDomain(document.location.hostname, cross_subdomain)\n\n if (days) {\n const date = new Date()\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000)\n expires = '; expires=' + date.toUTCString()\n }\n\n if (is_secure) {\n secure = '; secure'\n }\n\n const new_cookie_val =\n name +\n '=' +\n encodeURIComponent(JSON.stringify(value)) +\n expires +\n '; SameSite=Lax; path=/' +\n cdomain +\n secure\n\n // 4096 bytes is the size at which some browsers (e.g. firefox) will not store a cookie, warn slightly before that\n if (new_cookie_val.length > 4096 * 0.9) {\n logger.warn('cookieStore warning: large cookie, len=' + new_cookie_val.length)\n }\n\n document.cookie = new_cookie_val\n return new_cookie_val\n } catch {\n return\n }\n },\n\n _remove: function (name, cross_subdomain) {\n if (!document?.cookie) {\n return\n }\n try {\n cookieStore._set(name, '', -1, cross_subdomain)\n } catch {\n return\n }\n },\n}\n\nlet _localStorage_supported: boolean | null = null\nexport const resetLocalStorageSupported = () => {\n _localStorage_supported = null\n}\n\nexport const localStore: PersistentStore = {\n _is_supported: function () {\n if (!isNull(_localStorage_supported)) {\n return _localStorage_supported\n }\n\n let supported = true\n if (!isUndefined(window)) {\n try {\n const key = '__mplssupport__',\n val = 'xyz'\n localStore._set(key, val)\n if (localStore._get(key) !== '\"xyz\"') {\n supported = false\n }\n localStore._remove(key)\n } catch {\n supported = false\n }\n } else {\n supported = false\n }\n if (!supported) {\n logger.error('localStorage unsupported; falling back to cookie store')\n }\n\n _localStorage_supported = supported\n return supported\n },\n\n _error: function (msg) {\n logger.error('localStorage error: ' + msg)\n },\n\n _get: function (name) {\n try {\n return window?.localStorage.getItem(name)\n } catch (err) {\n localStore._error(err)\n }\n return null\n },\n\n _parse: function (name) {\n try {\n return JSON.parse(localStore._get(name)) || {}\n } catch {\n // noop\n }\n return null\n },\n\n _set: function (name, value) {\n try {\n window?.localStorage.setItem(name, JSON.stringify(value))\n } catch (err) {\n localStore._error(err)\n }\n },\n\n _remove: function (name) {\n try {\n window?.localStorage.removeItem(name)\n } catch (err) {\n localStore._error(err)\n }\n },\n}\n\n// Use localstorage for most data but still use cookie for COOKIE_PERSISTED_PROPERTIES\n// This solves issues with cookies having too much data in them causing headers too large\n// Also makes sure we don't have to send a ton of data to the server\nconst COOKIE_PERSISTED_PROPERTIES = [\n DEVICE_ID,\n DISTINCT_ID,\n SESSION_ID,\n SESSION_RECORDING_IS_SAMPLED,\n ENABLE_PERSON_PROCESSING,\n INITIAL_PERSON_INFO,\n]\n\n/**\n * Creates a localPlusCookieStore instance with custom cookie-persisted properties\n */\nexport const createLocalPlusCookieStore = (customCookieProperties: readonly string[] = []): PersistentStore => {\n const cookiePropertiesToPersist = [...COOKIE_PERSISTED_PROPERTIES, ...customCookieProperties]\n\n return {\n ...localStore,\n _parse: function (name) {\n try {\n let cookieProperties: Properties = {}\n try {\n // See if there's a cookie stored with data.\n cookieProperties = cookieStore._parse(name) || {}\n } catch {}\n const value = extend(cookieProperties, JSON.parse(localStore._get(name) || '{}'))\n localStore._set(name, value)\n return value\n } catch {\n // noop\n }\n return null\n },\n\n _set: function (name, value, days, cross_subdomain, is_secure, debug) {\n try {\n localStore._set(name, value, undefined, undefined, debug)\n const cookiePersistedProperties: Record<string, any> = {}\n cookiePropertiesToPersist.forEach((key) => {\n if (value[key]) {\n cookiePersistedProperties[key] = value[key]\n }\n })\n\n if (Object.keys(cookiePersistedProperties).length) {\n cookieStore._set(name, cookiePersistedProperties, days, cross_subdomain, is_secure, debug)\n }\n } catch (err) {\n localStore._error(err)\n }\n },\n\n _remove: function (name, cross_subdomain) {\n try {\n window?.localStorage.removeItem(name)\n cookieStore._remove(name, cross_subdomain)\n } catch (err) {\n localStore._error(err)\n }\n },\n }\n}\n\nconst memoryStorage: Properties = {}\n\n// Storage that only lasts the length of the pageview if we don't want to use cookies\nexport const memoryStore: PersistentStore = {\n _is_supported: function () {\n return true\n },\n\n _error: function (msg) {\n logger.error('memoryStorage error: ' + msg)\n },\n\n _get: function (name) {\n return memoryStorage[name] || null\n },\n\n _parse: function (name) {\n return memoryStorage[name] || null\n },\n\n _set: function (name, value) {\n memoryStorage[name] = value\n },\n\n _remove: function (name) {\n delete memoryStorage[name]\n },\n}\n\nlet sessionStorageSupported: boolean | null = null\nexport const resetSessionStorageSupported = () => {\n sessionStorageSupported = null\n}\n// Storage that only lasts the length of a tab/window. Survives page refreshes\nexport const sessionStore: PersistentStore = {\n _is_supported: function () {\n if (!isNull(sessionStorageSupported)) {\n return sessionStorageSupported\n }\n sessionStorageSupported = true\n if (!isUndefined(window)) {\n try {\n const key = '__support__',\n val = 'xyz'\n sessionStore._set(key, val)\n if (sessionStore._get(key) !== '\"xyz\"') {\n sessionStorageSupported = false\n }\n sessionStore._remove(key)\n } catch {\n sessionStorageSupported = false\n }\n } else {\n sessionStorageSupported = false\n }\n return sessionStorageSupported\n },\n\n _error: function (msg) {\n logger.error('sessionStorage error: ', msg)\n },\n\n _get: function (name) {\n try {\n return window?.sessionStorage.getItem(name)\n } catch (err) {\n sessionStore._error(err)\n }\n return null\n },\n\n _parse: function (name) {\n try {\n return JSON.parse(sessionStore._get(name)) || null\n } catch {\n // noop\n }\n return null\n },\n\n _set: function (name, value) {\n try {\n window?.sessionStorage.setItem(name, JSON.stringify(value))\n } catch (err) {\n sessionStore._error(err)\n }\n },\n\n _remove: function (name) {\n try {\n window?.sessionStorage.removeItem(name)\n } catch (err) {\n sessionStore._error(err)\n }\n },\n}\n","import { PostHog } from './posthog-core'\nimport { find } from './utils'\nimport { assignableWindow, navigator } from './utils/globals'\nimport { cookieStore, localStore } from './storage'\nimport { PersistentStore } from './types'\nimport { isNoLike, isYesLike } from '@posthog/core'\n\nconst OPT_OUT_PREFIX = '__ph_opt_in_out_'\n\nexport enum ConsentStatus {\n PENDING = -1,\n DENIED = 0,\n GRANTED = 1,\n}\n\n/**\n * ConsentManager provides tools for managing user consent as configured by the application.\n */\nexport class ConsentManager {\n private _persistentStore?: PersistentStore\n\n constructor(private _instance: PostHog) {}\n\n private get _config() {\n return this._instance.config\n }\n\n public get consent(): ConsentStatus {\n if (this._getDnt()) {\n return ConsentStatus.DENIED\n }\n\n return this._storedConsent\n }\n\n public isOptedOut() {\n if (this._config.cookieless_mode === 'always') {\n return true\n }\n // we are opted out if:\n // * consent is explicitly denied\n // * consent is pending, and we are configured to opt out by default\n // * consent is pending, and we are in cookieless mode \"on_reject\"\n return (\n this.consent === ConsentStatus.DENIED ||\n (this.consent === ConsentStatus.PENDING &&\n (this._config.opt_out_capturing_by_default || this._config.cookieless_mode === 'on_reject'))\n )\n }\n\n public isOptedIn() {\n return !this.isOptedOut()\n }\n\n public isExplicitlyOptedOut() {\n return this.consent === ConsentStatus.DENIED\n }\n\n public optInOut(isOptedIn: boolean) {\n this._storage._set(\n this._storageKey,\n isOptedIn ? 1 : 0,\n this._config.cookie_expiration,\n this._config.cross_subdomain_cookie,\n this._config.secure_cookie\n )\n }\n\n public reset() {\n this._storage._remove(this._storageKey, this._config.cross_subdomain_cookie)\n }\n\n private get _storageKey() {\n const { token, opt_out_capturing_cookie_prefix, consent_persistence_name } = this._instance.config\n if (consent_persistence_name) {\n return consent_persistence_name\n } else if (opt_out_capturing_cookie_prefix) {\n // Deprecated, but we still support it for backwards compatibility.\n // This was deprecated because it differed in behaviour from storage.ts, and appends the token.\n // This meant it was not possible to share the same consent state across multiple PostHog instances,\n // and made it harder for people to migrate from other systems.\n return opt_out_capturing_cookie_prefix + token\n } else {\n return OPT_OUT_PREFIX + token\n }\n }\n\n private get _storedConsent(): ConsentStatus {\n const value = this._storage._get(this._storageKey)\n // be somewhat permissive in what we accept as yes/opt-in, to make it easier for people to migrate from other systems\n return isYesLike(value) ? ConsentStatus.GRANTED : isNoLike(value) ? ConsentStatus.DENIED : ConsentStatus.PENDING\n }\n\n private get _storage() {\n if (!this._persistentStore) {\n const persistenceType = this._config.opt_out_capturing_persistence_type\n this._persistentStore = persistenceType === 'localStorage' ? localStore : cookieStore\n const otherStorage = persistenceType === 'localStorage' ? cookieStore : localStore\n\n if (otherStorage._get(this._storageKey)) {\n if (!this._persistentStore._get(this._storageKey)) {\n // This indicates we have moved to a new storage format so we migrate the value over\n this.optInOut(isYesLike(otherStorage._get(this._storageKey)))\n }\n\n otherStorage._remove(this._storageKey, this._config.cross_subdomain_cookie)\n }\n }\n\n return this._persistentStore\n }\n\n private _getDnt(): boolean {\n if (!this._config.respect_dnt) {\n return false\n }\n return !!find(\n [\n navigator?.doNotTrack, // standard\n (navigator as any)?.['msDoNotTrack'],\n assignableWindow['doNotTrack'],\n ],\n (dntValue): boolean => {\n return isYesLike(dntValue)\n }\n )\n }\n}\n","import { PostHog } from '../posthog-core'\nimport { DEAD_CLICKS_ENABLED_SERVER_SIDE } from '../constants'\nimport { isBoolean, isObject } from '@posthog/core'\nimport { assignableWindow, document, LazyLoadedDeadClicksAutocaptureInterface } from '../utils/globals'\nimport { createLogger } from '../utils/logger'\nimport { DeadClicksAutoCaptureConfig, RemoteConfig } from '../types'\n\nconst logger = createLogger('[Dead Clicks]')\n\nexport const isDeadClicksEnabledForHeatmaps = () => {\n return true\n}\nexport const isDeadClicksEnabledForAutocapture = (instance: DeadClicksAutocapture) => {\n const isRemoteEnabled = !!instance.instance.persistence?.get_property(DEAD_CLICKS_ENABLED_SERVER_SIDE)\n const clientConfig = instance.instance.config.capture_dead_clicks\n if (isBoolean(clientConfig)) {\n return clientConfig\n }\n if (isObject(clientConfig)) {\n return true\n }\n return isRemoteEnabled\n}\n\nexport class DeadClicksAutocapture {\n get lazyLoadedDeadClicksAutocapture(): LazyLoadedDeadClicksAutocaptureInterface | undefined {\n return this._lazyLoadedDeadClicksAutocapture\n }\n\n private _lazyLoadedDeadClicksAutocapture: LazyLoadedDeadClicksAutocaptureInterface | undefined\n\n constructor(\n readonly instance: PostHog,\n readonly isEnabled: (dca: DeadClicksAutocapture) => boolean,\n readonly onCapture?: DeadClicksAutoCaptureConfig['__onCapture']\n ) {\n this.startIfEnabled()\n }\n\n public onRemoteConfig(response: RemoteConfig) {\n if (this.instance.persistence) {\n this.instance.persistence.register({\n [DEAD_CLICKS_ENABLED_SERVER_SIDE]: response?.captureDeadClicks,\n })\n }\n this.startIfEnabled()\n }\n\n public startIfEnabled() {\n if (this.isEnabled(this)) {\n this._loadScript(() => {\n this._start()\n })\n }\n }\n\n private _loadScript(cb: () => void): void {\n if (assignableWindow.__PosthogExtensions__?.initDeadClicksAutocapture) {\n // already loaded\n cb()\n }\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(\n this.instance,\n 'dead-clicks-autocapture',\n (err) => {\n if (err) {\n logger.error('failed to load script', err)\n return\n }\n cb()\n }\n )\n }\n\n private _start() {\n if (!document) {\n logger.error('`document` not found. Cannot start.')\n return\n }\n\n if (\n !this._lazyLoadedDeadClicksAutocapture &&\n assignableWindow.__PosthogExtensions__?.initDeadClicksAutocapture\n ) {\n const config = isObject(this.instance.config.capture_dead_clicks)\n ? this.instance.config.capture_dead_clicks\n : {}\n config.__onCapture = this.onCapture\n\n this._lazyLoadedDeadClicksAutocapture = assignableWindow.__PosthogExtensions__.initDeadClicksAutocapture(\n this.instance,\n config\n )\n this._lazyLoadedDeadClicksAutocapture.start(document)\n logger.info(`starting...`)\n }\n }\n\n stop() {\n if (this._lazyLoadedDeadClicksAutocapture) {\n this._lazyLoadedDeadClicksAutocapture.stop()\n this._lazyLoadedDeadClicksAutocapture = undefined\n logger.info(`stopping...`)\n }\n }\n}\n","import { assignableWindow, window } from '../../utils/globals'\nimport { PostHog } from '../../posthog-core'\nimport { ExceptionAutoCaptureConfig, RemoteConfig } from '../../types'\n\nimport { createLogger } from '../../utils/logger'\nimport { EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE } from '../../constants'\nimport { isUndefined, BucketedRateLimiter, isObject } from '@posthog/core'\nimport { ErrorTracking } from '@posthog/core'\n\nconst logger = createLogger('[ExceptionAutocapture]')\n\nexport class ExceptionObserver {\n private _instance: PostHog\n private _rateLimiter: BucketedRateLimiter<string>\n private _remoteEnabled: boolean | undefined\n private _config: Required<ExceptionAutoCaptureConfig>\n private _unwrapOnError: (() => void) | undefined\n private _unwrapUnhandledRejection: (() => void) | undefined\n private _unwrapConsoleError: (() => void) | undefined\n\n constructor(instance: PostHog) {\n this._instance = instance\n this._remoteEnabled = !!this._instance.persistence?.props[EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE]\n\n // by default captures ten exceptions before rate limiting by exception type\n // refills at a rate of one token / 10 second period\n // e.g. will capture 1 exception rate limited exception every 10 seconds until burst ends\n this._rateLimiter = new BucketedRateLimiter({\n refillRate: this._instance.config.error_tracking.__exceptionRateLimiterRefillRate ?? 1,\n bucketSize: this._instance.config.error_tracking.__exceptionRateLimiterBucketSize ?? 10,\n refillInterval: 10000, // ten seconds in milliseconds,\n _logger: logger,\n })\n\n this._config = this._requiredConfig()\n this.startIfEnabledOrStop()\n }\n\n private _requiredConfig(): Required<ExceptionAutoCaptureConfig> {\n const providedConfig = this._instance.config.capture_exceptions\n let config = {\n capture_unhandled_errors: false,\n capture_unhandled_rejections: false,\n capture_console_errors: false,\n }\n\n if (isObject(providedConfig)) {\n config = { ...config, ...providedConfig }\n } else if (isUndefined(providedConfig) ? this._remoteEnabled : providedConfig) {\n config = { ...config, capture_unhandled_errors: true, capture_unhandled_rejections: true }\n }\n\n return config\n }\n\n public get isEnabled(): boolean {\n return (\n this._config.capture_console_errors ||\n this._config.capture_unhandled_errors ||\n this._config.capture_unhandled_rejections\n )\n }\n\n startIfEnabledOrStop(): void {\n if (this.isEnabled) {\n logger.info('enabled')\n this._stopCapturing()\n this._loadScript(this._startCapturing)\n } else {\n this._stopCapturing()\n }\n }\n\n private _loadScript(cb: () => void): void {\n if (assignableWindow.__PosthogExtensions__?.errorWrappingFunctions) {\n // already loaded\n cb()\n }\n\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(\n this._instance,\n 'exception-autocapture',\n (err) => {\n if (err) {\n return logger.error('failed to load script', err)\n }\n cb()\n }\n )\n }\n\n private _startCapturing = () => {\n if (!window || !this.isEnabled || !assignableWindow.__PosthogExtensions__?.errorWrappingFunctions) {\n return\n }\n\n const wrapOnError = assignableWindow.__PosthogExtensions__.errorWrappingFunctions.wrapOnError\n const wrapUnhandledRejection =\n assignableWindow.__PosthogExtensions__.errorWrappingFunctions.wrapUnhandledRejection\n const wrapConsoleError = assignableWindow.__PosthogExtensions__.errorWrappingFunctions.wrapConsoleError\n\n try {\n if (!this._unwrapOnError && this._config.capture_unhandled_errors) {\n this._unwrapOnError = wrapOnError(this.captureException.bind(this))\n }\n if (!this._unwrapUnhandledRejection && this._config.capture_unhandled_rejections) {\n this._unwrapUnhandledRejection = wrapUnhandledRejection(this.captureException.bind(this))\n }\n if (!this._unwrapConsoleError && this._config.capture_console_errors) {\n this._unwrapConsoleError = wrapConsoleError(this.captureException.bind(this))\n }\n } catch (e) {\n logger.error('failed to start', e)\n this._stopCapturing()\n }\n }\n\n private _stopCapturing() {\n this._unwrapOnError?.()\n this._unwrapOnError = undefined\n\n this._unwrapUnhandledRejection?.()\n this._unwrapUnhandledRejection = undefined\n\n this._unwrapConsoleError?.()\n this._unwrapConsoleError = undefined\n }\n\n onRemoteConfig(response: RemoteConfig) {\n const autocaptureExceptionsResponse = response.autocaptureExceptions\n\n // store this in-memory in case persistence is disabled\n this._remoteEnabled = !!autocaptureExceptionsResponse || false\n\n if (this._instance.persistence) {\n this._instance.persistence.register({\n [EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE]: this._remoteEnabled,\n })\n }\n\n this._config = this._requiredConfig()\n this.startIfEnabledOrStop()\n }\n\n onConfigChange() {\n this._config = this._requiredConfig()\n }\n\n captureException(errorProperties: ErrorTracking.ErrorProperties) {\n const exceptionType = errorProperties?.$exception_list?.[0]?.type ?? 'Exception'\n const isRateLimited = this._rateLimiter.consumeRateLimit(exceptionType)\n\n if (isRateLimited) {\n logger.info('Skipping exception capture because of client rate limiting.', {\n exception: exceptionType,\n })\n return\n }\n\n this._instance.exceptions.sendExceptionEvent(errorProperties)\n }\n}\n","// import { patch } from 'rrweb/typings/utils'\n// copied from https://github.com/rrweb-io/rrweb/blob/8aea5b00a4dfe5a6f59bd2ae72bb624f45e51e81/packages/rrweb/src/utils.ts#L129\n// which was copied from https://github.com/getsentry/sentry-javascript/blob/b2109071975af8bf0316d3b5b38f519bdaf5dc15/packages/utils/src/object.ts\nimport { isFunction } from '@posthog/core'\n\nexport function patch(\n source: { [key: string]: any },\n name: string,\n replacement: (...args: unknown[]) => unknown\n): () => void {\n try {\n if (!(name in source)) {\n return () => {\n //\n }\n }\n\n const original = source[name] as () => unknown\n const wrapped = replacement(original)\n\n // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work\n // otherwise it'll throw \"TypeError: Object.defineProperties called on non-object\"\n if (isFunction(wrapped)) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n wrapped.prototype = wrapped.prototype || {}\n Object.defineProperties(wrapped, {\n __posthog_wrapped__: {\n enumerable: false,\n value: true,\n },\n })\n }\n\n source[name] = wrapped\n\n return () => {\n source[name] = original\n }\n } catch {\n return () => {\n //\n }\n // This can throw if multiple fill happens on a global object like XMLHttpRequest\n // Fixes https://github.com/getsentry/sentry-javascript/issues/2043\n }\n}\n","import { PostHog } from '../posthog-core'\nimport { window } from '../utils/globals'\nimport { addEventListener } from '../utils'\nimport { logger } from '../utils/logger'\nimport { patch } from './replay/rrweb-plugins/patch'\n\n/**\n * This class is used to capture pageview events when the user navigates using the history API (pushState, replaceState)\n * and when the user navigates using the browser's back/forward buttons.\n *\n * The behavior is controlled by the `capture_pageview` configuration option:\n * - When set to `'history_change'`, this class will capture pageviews on history API changes\n */\nexport class HistoryAutocapture {\n private _instance: PostHog\n private _popstateListener: (() => void) | undefined\n private _lastPathname: string\n\n constructor(instance: PostHog) {\n this._instance = instance\n this._lastPathname = window?.location?.pathname || ''\n }\n\n public get isEnabled(): boolean {\n return this._instance.config.capture_pageview === 'history_change'\n }\n\n public startIfEnabled(): void {\n if (this.isEnabled) {\n logger.info('History API monitoring enabled, starting...')\n this.monitorHistoryChanges()\n }\n }\n\n public stop(): void {\n if (this._popstateListener) {\n this._popstateListener()\n }\n this._popstateListener = undefined\n logger.info('History API monitoring stopped')\n }\n\n public monitorHistoryChanges(): void {\n if (!window || !window.history) {\n return\n }\n\n // Old fashioned, we could also use arrow functions but I think the closure for a patch is more reliable\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this\n\n if (!(window.history.pushState as any)?.__posthog_wrapped__) {\n patch(window.history, 'pushState', (originalPushState) => {\n return function patchedPushState(\n this: History,\n state: any,\n title: string,\n url?: string | URL | null\n ): void {\n ;(originalPushState as History['pushState']).call(this, state, title, url)\n self._capturePageview('pushState')\n }\n })\n }\n\n if (!(window.history.replaceState as any)?.__posthog_wrapped__) {\n patch(window.history, 'replaceState', (originalReplaceState) => {\n return function patchedReplaceState(\n this: History,\n state: any,\n title: string,\n url?: string | URL | null\n ): void {\n ;(originalReplaceState as History['replaceState']).call(this, state, title, url)\n self._capturePageview('replaceState')\n }\n })\n }\n\n this._setupPopstateListener()\n }\n\n private _capturePageview(navigationType: 'pushState' | 'replaceState' | 'popstate'): void {\n try {\n const currentPathname = window?.location?.pathname\n\n if (!currentPathname) {\n return\n }\n\n // Only capture pageview if the pathname has changed and the feature is enabled\n if (currentPathname !== this._lastPathname && this.isEnabled) {\n this._instance.capture('$pageview', { navigation_type: navigationType })\n }\n\n this._lastPathname = currentPathname\n } catch (error) {\n logger.error(`Error capturing ${navigationType} pageview`, error)\n }\n }\n\n private _setupPopstateListener(): void {\n if (this._popstateListener) {\n return\n }\n\n const handler = () => {\n this._capturePageview('popstate')\n }\n\n addEventListener(window, 'popstate', handler)\n this._popstateListener = () => {\n if (window) {\n window.removeEventListener('popstate', handler)\n }\n }\n }\n}\n","/**\n * Extend Segment with extra PostHog JS functionality. Required for things like Recordings and feature flags to work correctly.\n *\n * ### Usage\n *\n * ```js\n * // After your standard segment anyalytics install\n * analytics.load(\"GOEDfA21zZTtR7clsBuDvmBKAtAdZ6Np\");\n *\n * analytics.ready(() => {\n * posthog.init('<posthog-api-key>', {\n * capture_pageview: false,\n * segment: window.analytics, // NOTE: Be sure to use window.analytics here!\n * });\n * window.analytics.page();\n * })\n * ```\n */\nimport { PostHog } from '../posthog-core'\nimport { createLogger } from '../utils/logger'\n\nimport { USER_STATE } from '../constants'\nimport { isFunction } from '@posthog/core'\nimport { uuidv7 } from '../uuidv7'\n\nimport type { SegmentUser, SegmentAnalytics, SegmentContext, SegmentPlugin } from '@posthog/types'\n\n// Re-export for backwards compatibility\nexport type { SegmentUser, SegmentAnalytics, SegmentContext, SegmentPlugin }\n\nconst logger = createLogger('[SegmentIntegration]')\n\nconst createSegmentIntegration = (posthog: PostHog): SegmentPlugin => {\n if (!Promise || !Promise.resolve) {\n logger.warn('This browser does not have Promise support, and can not use the segment integration')\n }\n\n const enrichEvent = (ctx: SegmentContext, eventName: string | undefined) => {\n if (!eventName) {\n return ctx\n }\n if (!ctx.event.userId && ctx.event.anonymousId !== posthog.get_distinct_id()) {\n // This is our only way of detecting that segment's analytics.reset() has been called so we also call it\n logger.info('No userId set, resetting PostHog')\n posthog.reset()\n }\n if (ctx.event.userId && ctx.event.userId !== posthog.get_distinct_id()) {\n logger.info('UserId set, identifying with PostHog')\n posthog.identify(ctx.event.userId)\n }\n\n const additionalProperties = posthog.calculateEventProperties(eventName, ctx.event.properties)\n ctx.event.properties = Object.assign({}, additionalProperties, ctx.event.properties)\n return ctx\n }\n\n return {\n name: 'PostHog JS',\n type: 'enrichment',\n version: '1.0.0',\n isLoaded: () => true,\n // check and early return above\n // eslint-disable-next-line compat/compat\n load: () => Promise.resolve(),\n track: (ctx) => enrichEvent(ctx, ctx.event.event),\n page: (ctx) => enrichEvent(ctx, '$pageview'),\n identify: (ctx) => enrichEvent(ctx, '$identify'),\n screen: (ctx) => enrichEvent(ctx, '$screen'),\n }\n}\n\nfunction setupPostHogFromSegment(posthog: PostHog, done: () => void) {\n const segment = posthog.config.segment\n if (!segment) {\n return done()\n }\n\n const bootstrapUser = (user: SegmentUser) => {\n // Use segments anonymousId instead\n const getSegmentAnonymousId = () => user.anonymousId() || uuidv7()\n posthog.config.get_device_id = getSegmentAnonymousId\n\n // If a segment user ID exists, set it as the distinct_id\n if (user.id()) {\n posthog.register({\n distinct_id: user.id(),\n $device_id: getSegmentAnonymousId(),\n })\n posthog.persistence!.set_property(USER_STATE, 'identified')\n }\n\n done()\n }\n\n const segmentUser = segment.user()\n if ('then' in segmentUser && isFunction(segmentUser.then)) {\n segmentUser.then(bootstrapUser)\n } else {\n bootstrapUser(segmentUser as SegmentUser)\n }\n}\n\nexport function setupSegmentIntegration(posthog: PostHog, done: () => void) {\n const segment = posthog.config.segment\n if (!segment) {\n return done()\n }\n\n setupPostHogFromSegment(posthog, () => {\n segment.register(createSegmentIntegration(posthog)).then(() => {\n done()\n })\n })\n}\n","/**\n * Integrate Sentry with PostHog. This will add a direct link to the person in Sentry, and an $exception event in PostHog\n *\n * ### Usage\n *\n * Sentry.init({\n * dsn: 'https://example',\n * integrations: [\n * new posthog.SentryIntegration(posthog)\n * ]\n * })\n *\n * @param {Object} [posthog] The posthog object\n * @param {string} [organization] Optional: The Sentry organization, used to send a direct link from PostHog to Sentry\n * @param {Number} [projectId] Optional: The Sentry project id, used to send a direct link from PostHog to Sentry\n * @param {string} [prefix] Optional: Url of a self-hosted sentry instance (default: https://sentry.io/organizations/)\n * @param {SeverityLevel[] | '*'} [severityAllowList] Optional: send events matching the provided levels. Use '*' to send all events (default: ['error'])\n * @param {boolean} [sendExceptionsToPostHog] Optional: capture exceptions as events in PostHog (default: true)\n */\n\nimport { PostHog } from '../posthog-core'\nimport { SeverityLevel } from '../types'\n\n// NOTE - we can't import from @sentry/types because it changes frequently and causes clashes\n// We only use a small subset of the types, so we can just define the integration overall and use any for the rest\n\n// import {\n// Event as _SentryEvent,\n// EventProcessor as _SentryEventProcessor,\n// Hub as _SentryHub,\n// Integration as _SentryIntegration,\n// SeverityLevel as _SeverityLevel,\n// IntegrationClass as _SentryIntegrationClass,\n// } from '@sentry/types'\n\n// Uncomment the above and comment the below to get type checking for development\n\ntype _SentryEvent = any\ntype _SentryException = any\ntype _SentryEventProcessor = any\ntype _SentryHub = any\n\ninterface _SentryIntegration {\n name: string\n processEvent(event: _SentryEvent): _SentryEvent\n}\n\ninterface _SentryIntegrationClass {\n name: string\n setupOnce(addGlobalEventProcessor: (callback: _SentryEventProcessor) => void, getCurrentHub: () => _SentryHub): void\n}\n\ninterface SentryExceptionProperties {\n $sentry_event_id: any\n $sentry_exception: any\n $sentry_exception_message: any\n $sentry_exception_type: any\n $sentry_tags: any\n $sentry_url?: string\n}\n\nexport type SentryIntegrationOptions = {\n organization?: string\n projectId?: number\n prefix?: string\n severityAllowList?: SeverityLevel[] | '*'\n sendExceptionsToPostHog?: boolean\n}\n\nconst NAME = 'posthog-js'\n\nexport function createEventProcessor(\n _posthog: PostHog,\n {\n organization,\n projectId,\n prefix,\n severityAllowList = ['error'],\n sendExceptionsToPostHog = true,\n }: SentryIntegrationOptions = {}\n): (event: _SentryEvent) => _SentryEvent {\n return (event) => {\n const shouldProcessLevel = severityAllowList === '*' || severityAllowList.includes(event.level as SeverityLevel)\n if (!shouldProcessLevel || !_posthog.__loaded) return event\n if (!event.tags) event.tags = {}\n\n const personUrl = _posthog.requestRouter.endpointFor(\n 'ui',\n `/project/${_posthog.config.token}/person/${_posthog.get_distinct_id()}`\n )\n event.tags['PostHog Person URL'] = personUrl\n if (_posthog.sessionRecordingStarted()) {\n event.tags['PostHog Recording URL'] = _posthog.get_session_replay_url({ withTimestamp: true })\n }\n\n const exceptions: _SentryException[] = event.exception?.values || []\n\n const exceptionList = exceptions.map((exception) => {\n return {\n ...exception,\n stacktrace: exception.stacktrace\n ? {\n ...exception.stacktrace,\n type: 'raw',\n frames: (exception.stacktrace.frames || []).map((frame: any) => {\n return { ...frame, platform: 'web:javascript' }\n }),\n }\n : undefined,\n }\n })\n\n const data: SentryExceptionProperties & {\n // two properties added to match any exception auto-capture\n // added manually to avoid any dependency on the lazily loaded content\n $exception_message: any\n $exception_type: any\n $exception_list: any\n $exception_level: SeverityLevel\n } = {\n // PostHog Exception Properties,\n $exception_message: exceptions[0]?.value || event.message,\n $exception_type: exceptions[0]?.type,\n $exception_level: event.level,\n $exception_list: exceptionList,\n // Sentry Exception Properties\n $sentry_event_id: event.event_id,\n $sentry_exception: event.exception,\n $sentry_exception_message: exceptions[0]?.value || event.message,\n $sentry_exception_type: exceptions[0]?.type,\n $sentry_tags: event.tags,\n }\n\n if (organization && projectId) {\n data['$sentry_url'] =\n (prefix || 'https://sentry.io/organizations/') +\n organization +\n '/issues/?project=' +\n projectId +\n '&query=' +\n event.event_id\n }\n\n if (sendExceptionsToPostHog) {\n _posthog.exceptions.sendExceptionEvent(data)\n }\n\n return event\n }\n}\n\n// V8 integration - function based\nexport function sentryIntegration(_posthog: PostHog, options?: SentryIntegrationOptions): _SentryIntegration {\n const processor = createEventProcessor(_posthog, options)\n return {\n name: NAME,\n processEvent(event) {\n return processor(event)\n },\n }\n}\n// V7 integration - class based\nexport class SentryIntegration implements _SentryIntegrationClass {\n name: string\n\n setupOnce: (\n addGlobalEventProcessor: (callback: _SentryEventProcessor) => void,\n getCurrentHub: () => _SentryHub\n ) => void\n\n constructor(\n _posthog: PostHog,\n organization?: string,\n projectId?: number,\n prefix?: string,\n severityAllowList?: SeverityLevel[] | '*',\n sendExceptionsToPostHog?: boolean\n ) {\n // setupOnce gets called by Sentry when it intializes the plugin\n this.name = NAME\n this.setupOnce = function (addGlobalEventProcessor: (callback: _SentryEventProcessor) => void) {\n addGlobalEventProcessor(\n createEventProcessor(_posthog, {\n organization,\n projectId,\n prefix,\n severityAllowList,\n sendExceptionsToPostHog: sendExceptionsToPostHog ?? true,\n })\n )\n }\n }\n}\n","import { addEventListener, trySafe } from '../utils'\nimport { PostHog } from '../posthog-core'\nimport { ToolbarParams } from '../types'\nimport { _getHashParam } from '../utils/request-utils'\nimport { createLogger } from '../utils/logger'\nimport { window, document, assignableWindow } from '../utils/globals'\nimport { TOOLBAR_ID } from '../constants'\nimport { isFunction, isNullish } from '@posthog/core'\n\n// TRICKY: Many web frameworks will modify the route on load, potentially before posthog is initialized.\n// To get ahead of this we grab it as soon as the posthog-js is parsed\nconst STATE_FROM_WINDOW = window?.location\n ? _getHashParam(window.location.hash, '__posthog') || _getHashParam(location.hash, 'state')\n : null\n\nconst LOCALSTORAGE_KEY = '_postHogToolbarParams'\n\nconst logger = createLogger('[Toolbar]')\n\nenum ToolbarState {\n UNINITIALIZED = 0,\n LOADING = 1,\n LOADED = 2,\n}\n\nexport class Toolbar {\n instance: PostHog\n\n constructor(instance: PostHog) {\n this.instance = instance\n }\n\n // NOTE: We store the state of the toolbar in the global scope to avoid multiple instances of the SDK loading the toolbar\n private _setToolbarState(state: ToolbarState) {\n assignableWindow['ph_toolbar_state'] = state\n }\n\n private _getToolbarState(): ToolbarState {\n return assignableWindow['ph_toolbar_state'] ?? ToolbarState.UNINITIALIZED\n }\n\n /**\n * To load the toolbar, we need an access token and other state. That state comes from one of three places:\n * 1. In the URL hash params\n * 2. From session storage under the key `toolbarParams` if the toolbar was initialized on a previous page\n */\n maybeLoadToolbar(\n location: Location | undefined = undefined,\n localStorage: Storage | undefined = undefined,\n history: History | undefined = undefined\n ): boolean {\n if (!window || !document) {\n return false\n }\n location = location ?? window.location\n history = history ?? window.history\n\n try {\n // Before running the code we check if we can access localStorage, if not we opt-out\n if (!localStorage) {\n try {\n window.localStorage.setItem('test', 'test')\n window.localStorage.removeItem('test')\n } catch {\n return false\n }\n\n // If localStorage was undefined, and localStorage is supported we set the default value\n localStorage = window?.localStorage\n }\n\n /**\n * Info about the state\n * The state is a json object\n * 1. (Legacy) The state can be `state={}` as a urlencoded object of info. In this case\n * 2. The state should now be found in `__posthog={}` and can be base64 encoded or urlencoded.\n * 3. Base64 encoding is preferred and will gradually be rolled out everywhere\n */\n\n const stateHash =\n STATE_FROM_WINDOW || _getHashParam(location.hash, '__posthog') || _getHashParam(location.hash, 'state')\n\n let toolbarParams: ToolbarParams\n const state = stateHash\n ? trySafe(() => JSON.parse(atob(decodeURIComponent(stateHash)))) ||\n trySafe(() => JSON.parse(decodeURIComponent(stateHash)))\n : null\n\n const parseFromUrl = state && state['action'] === 'ph_authorize'\n\n if (parseFromUrl) {\n // happens if they are initializing the toolbar using an old snippet\n toolbarParams = state\n toolbarParams.source = 'url'\n\n if (toolbarParams && Object.keys(toolbarParams).length > 0) {\n if (state['desiredHash']) {\n // hash that was in the url before the redirect\n location.hash = state['desiredHash']\n } else if (history) {\n // second param is unused see https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState\n history.replaceState(history.state, '', location.pathname + location.search) // completely remove hash\n } else {\n location.hash = '' // clear hash (but leaves # unfortunately)\n }\n }\n } else {\n // get credentials from localStorage from a previous initialization\n\n toolbarParams = JSON.parse(localStorage.getItem(LOCALSTORAGE_KEY) || '{}')\n toolbarParams.source = 'localstorage'\n\n // delete \"add-action\" or other intent from toolbarParams, otherwise we'll have the same intent\n // every time we open the page (e.g. you just visiting your own site an hour later)\n delete toolbarParams.userIntent\n }\n\n if (toolbarParams['token'] && this.instance.config.token === toolbarParams['token']) {\n this.loadToolbar(toolbarParams)\n return true\n } else {\n return false\n }\n } catch {\n return false\n }\n }\n\n private _callLoadToolbar(params: ToolbarParams) {\n const loadFn = assignableWindow['ph_load_toolbar'] || assignableWindow['ph_load_editor']\n if (isNullish(loadFn) || !isFunction(loadFn)) {\n logger.warn('No toolbar load function found')\n return\n }\n loadFn(params, this.instance)\n }\n\n loadToolbar(params?: ToolbarParams): boolean {\n const toolbarRunning = !!document?.getElementById(TOOLBAR_ID)\n\n if (!window || toolbarRunning) {\n // The toolbar will clear the localStorage key when it's done with it. If it is present that indicates the toolbar is already open and running\n return false\n }\n\n const disableToolbarMetrics =\n this.instance.requestRouter.region === 'custom' && this.instance.config.advanced_disable_toolbar_metrics\n\n const toolbarParams = {\n token: this.instance.config.token,\n ...params,\n apiURL: this.instance.requestRouter.endpointFor('ui'),\n ...(disableToolbarMetrics ? { instrument: false } : {}),\n }\n window.localStorage.setItem(\n LOCALSTORAGE_KEY,\n JSON.stringify({\n ...toolbarParams,\n source: undefined,\n })\n )\n\n if (this._getToolbarState() === ToolbarState.LOADED) {\n this._callLoadToolbar(toolbarParams)\n } else if (this._getToolbarState() === ToolbarState.UNINITIALIZED) {\n // only load the toolbar once, even if there are multiple instances of PostHogLib\n this._setToolbarState(ToolbarState.LOADING)\n\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(this.instance, 'toolbar', (err) => {\n if (err) {\n logger.error('[Toolbar] Failed to load', err)\n this._setToolbarState(ToolbarState.UNINITIALIZED)\n return\n }\n this._setToolbarState(ToolbarState.LOADED)\n this._callLoadToolbar(toolbarParams)\n })\n\n // Turbolinks doesn't fire an onload event but does replace the entire body, including the toolbar.\n // Thus, we ensure the toolbar is only loaded inside the body, and then reloaded on turbolinks:load.\n addEventListener(window, 'turbolinks:load', () => {\n this._setToolbarState(ToolbarState.UNINITIALIZED)\n this.loadToolbar(toolbarParams)\n })\n }\n\n return true\n }\n\n /** @deprecated Use \"loadToolbar\" instead. */\n _loadEditor(params: ToolbarParams): boolean {\n return this.loadToolbar(params)\n }\n\n /** @deprecated Use \"maybeLoadToolbar\" instead. */\n maybeLoadEditor(\n location: Location | undefined = undefined,\n localStorage: Storage | undefined = undefined,\n history: History | undefined = undefined\n ): boolean {\n return this.maybeLoadToolbar(location, localStorage, history)\n }\n}\n","import { PostHog } from '../posthog-core'\nimport { assignableWindow } from '../utils/globals'\nimport { createLogger } from '../utils/logger'\nimport { isUndefined } from '@posthog/core'\n\nconst logger = createLogger('[TracingHeaders]')\n\nexport class TracingHeaders {\n private _restoreXHRPatch: (() => void) | undefined = undefined\n private _restoreFetchPatch: (() => void) | undefined = undefined\n\n constructor(private readonly _instance: PostHog) {}\n\n private _loadScript(cb: () => void): void {\n if (assignableWindow.__PosthogExtensions__?.tracingHeadersPatchFns) {\n // already loaded\n cb()\n }\n\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(this._instance, 'tracing-headers', (err) => {\n if (err) {\n return logger.error('failed to load script', err)\n }\n cb()\n })\n }\n public startIfEnabledOrStop() {\n if (this._instance.config.__add_tracing_headers) {\n this._loadScript(this._startCapturing)\n } else {\n this._restoreXHRPatch?.()\n this._restoreFetchPatch?.()\n // we don't want to call these twice so we reset them\n this._restoreXHRPatch = undefined\n this._restoreFetchPatch = undefined\n }\n }\n\n private _startCapturing = () => {\n if (isUndefined(this._restoreXHRPatch)) {\n assignableWindow.__PosthogExtensions__?.tracingHeadersPatchFns?._patchXHR(\n this._instance.config.__add_tracing_headers || [],\n this._instance.get_distinct_id(),\n this._instance.sessionManager\n )\n }\n if (isUndefined(this._restoreFetchPatch)) {\n assignableWindow.__PosthogExtensions__?.tracingHeadersPatchFns?._patchFetch(\n this._instance.config.__add_tracing_headers || [],\n this._instance.get_distinct_id(),\n this._instance.sessionManager\n )\n }\n }\n}\n","import { convertToURL, getQueryParam, maskQueryParams } from './request-utils'\nimport { isNull, stripLeadingDollar } from '@posthog/core'\nimport { Properties } from '../types'\nimport Config from '../config'\nimport { each, extend, extendArray, stripEmptyProperties } from './index'\nimport { document, location, userAgent, window } from './globals'\nimport { detectBrowser, detectBrowserVersion, detectDevice, detectDeviceType, detectOS } from '@posthog/core'\nimport { cookieStore } from '../storage'\n\nconst URL_REGEX_PREFIX = 'https?://(.*)'\n\n// CAMPAIGN_PARAMS and EVENT_TO_PERSON_PROPERTIES should be kept in sync with\n// https://github.com/PostHog/posthog/blob/master/plugin-server/src/utils/db/utils.ts#L60\n\n// The list of campaign parameters that could be considered personal data under e.g. GDPR.\n// These can be masked in URLs and properties before being sent to posthog.\nexport const PERSONAL_DATA_CAMPAIGN_PARAMS = [\n 'gclid', // google ads\n 'gclsrc', // google ads 360\n 'dclid', // google display ads\n 'gbraid', // google ads, web to app\n 'wbraid', // google ads, app to web\n 'fbclid', // facebook\n 'msclkid', // microsoft\n 'twclid', // twitter\n 'li_fat_id', // linkedin\n 'igshid', // instagram\n 'ttclid', // tiktok\n 'rdt_cid', // reddit\n 'epik', // pinterest\n 'qclid', // quora\n 'sccid', // snapchat\n 'irclid', // impact\n '_kx', // klaviyo\n]\n\nexport const CAMPAIGN_PARAMS = extendArray(\n [\n 'utm_source',\n 'utm_medium',\n 'utm_campaign',\n 'utm_content',\n 'utm_term',\n 'gad_source', // google ads source\n 'mc_cid', // mailchimp campaign id\n ],\n PERSONAL_DATA_CAMPAIGN_PARAMS\n)\n\nexport const EVENT_TO_PERSON_PROPERTIES = [\n // mobile params\n '$app_build',\n '$app_name',\n '$app_namespace',\n '$app_version',\n // web params\n '$browser',\n '$browser_version',\n '$device_type',\n '$current_url',\n '$pathname',\n '$os',\n '$os_name', // $os_name is a special case, it's treated as an alias of $os!\n '$os_version',\n '$referring_domain',\n '$referrer',\n '$screen_height',\n '$screen_width',\n '$viewport_height',\n '$viewport_width',\n '$raw_user_agent',\n]\n\nexport const MASKED = '<masked>'\n\n// Campaign params that can be read from the cookie store\nexport const COOKIE_CAMPAIGN_PARAMS = [\n 'li_fat_id', // linkedin\n]\n\nexport function getCampaignParams(\n customTrackedParams?: string[],\n maskPersonalDataProperties?: boolean,\n customPersonalDataProperties?: string[] | undefined\n): Record<string, string> {\n if (!document) {\n return {}\n }\n\n const paramsToMask = maskPersonalDataProperties\n ? extendArray([], PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])\n : []\n\n // Initially get campaign params from the URL\n const urlCampaignParams = _getCampaignParamsFromUrl(\n maskQueryParams(document.URL, paramsToMask, MASKED),\n customTrackedParams\n )\n\n // But we can also get some of them from the cookie store\n // For example: https://learn.microsoft.com/en-us/linkedin/marketing/conversions/enabling-first-party-cookies?view=li-lms-2025-05#reading-li_fat_id-from-cookies\n const cookieCampaignParams = _getCampaignParamsFromCookie()\n\n // Prefer the values found in the urlCampaignParams if possible\n // `extend` will override the values if found in the second argument\n return extend(cookieCampaignParams, urlCampaignParams)\n}\n\nfunction _getCampaignParamsFromUrl(url: string, customParams?: string[]): Record<string, string> {\n const campaign_keywords = CAMPAIGN_PARAMS.concat(customParams || [])\n\n const params: Record<string, any> = {}\n each(campaign_keywords, function (kwkey) {\n const kw = getQueryParam(url, kwkey)\n params[kwkey] = kw ? kw : null\n })\n\n return params\n}\n\nfunction _getCampaignParamsFromCookie(): Record<string, string> {\n const params: Record<string, any> = {}\n each(COOKIE_CAMPAIGN_PARAMS, function (kwkey) {\n const kw = cookieStore._get(kwkey)\n params[kwkey] = kw ? kw : null\n })\n\n return params\n}\n\nfunction _getSearchEngine(referrer: string): string | null {\n if (!referrer) {\n return null\n } else {\n if (referrer.search(URL_REGEX_PREFIX + 'google.([^/?]*)') === 0) {\n return 'google'\n } else if (referrer.search(URL_REGEX_PREFIX + 'bing.com') === 0) {\n return 'bing'\n } else if (referrer.search(URL_REGEX_PREFIX + 'yahoo.com') === 0) {\n return 'yahoo'\n } else if (referrer.search(URL_REGEX_PREFIX + 'duckduckgo.com') === 0) {\n return 'duckduckgo'\n } else {\n return null\n }\n }\n}\n\nfunction _getSearchInfoFromReferrer(referrer: string): Record<string, any> {\n const search = _getSearchEngine(referrer)\n const param = search != 'yahoo' ? 'q' : 'p'\n const ret: Record<string, any> = {}\n\n if (!isNull(search)) {\n ret['$search_engine'] = search\n\n const keyword = document ? getQueryParam(document.referrer, param) : ''\n if (keyword.length) {\n ret['ph_keyword'] = keyword\n }\n }\n\n return ret\n}\n\nexport function getSearchInfo(): Record<string, any> {\n const referrer = document?.referrer\n if (!referrer) {\n return {}\n }\n return _getSearchInfoFromReferrer(referrer)\n}\n\nexport function getBrowserLanguage(): string | undefined {\n return (\n navigator.language || // Any modern browser\n (navigator as Record<string, any>).userLanguage // IE11\n )\n}\n\nexport function getBrowserLanguagePrefix(): string | undefined {\n const lang = getBrowserLanguage()\n return typeof lang === 'string' ? lang.split('-')[0] : undefined\n}\n\nexport function getReferrer(): string {\n return document?.referrer || '$direct'\n}\n\nexport function getReferringDomain(): string {\n if (!document?.referrer) {\n return '$direct'\n }\n return convertToURL(document.referrer)?.host || '$direct'\n}\n\nexport function getReferrerInfo(): Record<string, any> {\n return {\n $referrer: getReferrer(),\n $referring_domain: getReferringDomain(),\n }\n}\n\nexport function getPersonInfo(maskPersonalDataProperties?: boolean, customPersonalDataProperties?: string[]) {\n const paramsToMask = maskPersonalDataProperties\n ? extendArray([], PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])\n : []\n const url = location?.href.substring(0, 1000)\n // we're being a bit more economical with bytes here because this is stored in the cookie\n return {\n r: getReferrer().substring(0, 1000),\n u: url ? maskQueryParams(url, paramsToMask, MASKED) : undefined,\n }\n}\n\nexport function getPersonPropsFromInfo(info: Record<string, any>): Record<string, any> {\n const { r: referrer, u: url } = info\n const referring_domain =\n referrer == null ? undefined : referrer == '$direct' ? '$direct' : convertToURL(referrer)?.host\n\n const props: Record<string, string | undefined> = {\n $referrer: referrer,\n $referring_domain: referring_domain,\n }\n if (url) {\n props['$current_url'] = url\n const location = convertToURL(url)\n props['$host'] = location?.host\n props['$pathname'] = location?.pathname\n const campaignParams = _getCampaignParamsFromUrl(url)\n extend(props, campaignParams)\n }\n if (referrer) {\n const searchInfo = _getSearchInfoFromReferrer(referrer)\n extend(props, searchInfo)\n }\n return props\n}\n\nexport function getInitialPersonPropsFromInfo(info: Record<string, any>): Record<string, any> {\n const personProps = getPersonPropsFromInfo(info)\n const props: Record<string, any> = {}\n each(personProps, function (val: any, key: string) {\n props[`$initial_${stripLeadingDollar(key)}`] = val\n })\n return props\n}\n\nexport function getTimezone(): string | undefined {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone\n } catch {\n return undefined\n }\n}\n\nexport function getTimezoneOffset(): number | undefined {\n try {\n return new Date().getTimezoneOffset()\n } catch {\n return undefined\n }\n}\n\nexport function getEventProperties(\n maskPersonalDataProperties?: boolean,\n customPersonalDataProperties?: string[]\n): Properties {\n if (!userAgent) {\n return {}\n }\n const paramsToMask = maskPersonalDataProperties\n ? extendArray([], PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])\n : []\n const [os_name, os_version] = detectOS(userAgent)\n return extend(\n stripEmptyProperties({\n $os: os_name,\n $os_version: os_version,\n $browser: detectBrowser(userAgent, navigator.vendor),\n $device: detectDevice(userAgent),\n $device_type: detectDeviceType(userAgent),\n $timezone: getTimezone(),\n $timezone_offset: getTimezoneOffset(),\n }),\n {\n $current_url: maskQueryParams(location?.href, paramsToMask, MASKED),\n $host: location?.host,\n $pathname: location?.pathname,\n $raw_user_agent: userAgent.length > 1000 ? userAgent.substring(0, 997) + '...' : userAgent,\n $browser_version: detectBrowserVersion(userAgent, navigator.vendor),\n $browser_language: getBrowserLanguage(),\n $browser_language_prefix: getBrowserLanguagePrefix(),\n $screen_height: window?.screen.height,\n $screen_width: window?.screen.width,\n $viewport_height: window?.innerHeight,\n $viewport_width: window?.innerWidth,\n $lib: 'web',\n $lib_version: Config.LIB_VERSION,\n $insert_id: Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10),\n $time: Date.now() / 1000, // epoch time in seconds\n }\n )\n}\n","import { PostHog } from '../../posthog-core'\nimport { RemoteConfig, SupportedWebVitalsMetrics } from '../../types'\nimport { createLogger } from '../../utils/logger'\nimport { isBoolean, isNullish, isNumber, isUndefined, isObject } from '@posthog/core'\nimport { WEB_VITALS_ALLOWED_METRICS, WEB_VITALS_ENABLED_SERVER_SIDE } from '../../constants'\nimport { assignableWindow, window, location } from '../../utils/globals'\nimport { maskQueryParams } from '../../utils/request-utils'\nimport { PERSONAL_DATA_CAMPAIGN_PARAMS, MASKED } from '../../utils/event-utils'\nimport { extendArray } from '../../utils'\n\nconst logger = createLogger('[Web Vitals]')\n\ntype WebVitalsMetricCallback = (metric: any) => void\n\nexport const DEFAULT_FLUSH_TO_CAPTURE_TIMEOUT_MILLISECONDS = 5000\nconst ONE_MINUTE_IN_MILLIS = 60 * 1000\nexport const FIFTEEN_MINUTES_IN_MILLIS = 15 * ONE_MINUTE_IN_MILLIS\n\ntype WebVitalsEventBuffer = { url: string | undefined; metrics: any[]; firstMetricTimestamp: number | undefined }\n\nexport class WebVitalsAutocapture {\n private _enabledServerSide: boolean = false\n private _initialized = false\n\n private _buffer: WebVitalsEventBuffer = { url: undefined, metrics: [], firstMetricTimestamp: undefined }\n private _delayedFlushTimer: ReturnType<typeof setTimeout> | undefined\n\n constructor(private readonly _instance: PostHog) {\n this._enabledServerSide = !!this._instance.persistence?.props[WEB_VITALS_ENABLED_SERVER_SIDE]\n\n this.startIfEnabled()\n }\n\n public get allowedMetrics(): SupportedWebVitalsMetrics[] {\n const clientConfigMetricAllowList: SupportedWebVitalsMetrics[] | undefined = isObject(\n this._instance.config.capture_performance\n )\n ? this._instance.config.capture_performance?.web_vitals_allowed_metrics\n : undefined\n return !isUndefined(clientConfigMetricAllowList)\n ? clientConfigMetricAllowList\n : this._instance.persistence?.props[WEB_VITALS_ALLOWED_METRICS] || ['CLS', 'FCP', 'INP', 'LCP']\n }\n\n public get flushToCaptureTimeoutMs(): number {\n const clientConfig: number | undefined = isObject(this._instance.config.capture_performance)\n ? this._instance.config.capture_performance.web_vitals_delayed_flush_ms\n : undefined\n return clientConfig || DEFAULT_FLUSH_TO_CAPTURE_TIMEOUT_MILLISECONDS\n }\n\n public get _maxAllowedValue(): number {\n const configured =\n isObject(this._instance.config.capture_performance) &&\n isNumber(this._instance.config.capture_performance.__web_vitals_max_value)\n ? this._instance.config.capture_performance.__web_vitals_max_value\n : FIFTEEN_MINUTES_IN_MILLIS\n // you can set to 0 to disable the check or any value over ten seconds\n // 1 milli to 1 minute will be set to 15 minutes, cos that would be a silly low maximum\n return 0 < configured && configured <= ONE_MINUTE_IN_MILLIS ? FIFTEEN_MINUTES_IN_MILLIS : configured\n }\n\n public get isEnabled(): boolean {\n // Always disable web vitals if we're not on http or https\n const protocol = location?.protocol\n if (protocol !== 'http:' && protocol !== 'https:') {\n logger.info('Web Vitals are disabled on non-http/https protocols')\n return false\n }\n\n // Otherwise, check config\n const clientConfig = isObject(this._instance.config.capture_performance)\n ? this._instance.config.capture_performance.web_vitals\n : isBoolean(this._instance.config.capture_performance)\n ? this._instance.config.capture_performance\n : undefined\n return isBoolean(clientConfig) ? clientConfig : this._enabledServerSide\n }\n\n public startIfEnabled(): void {\n if (this.isEnabled && !this._initialized) {\n logger.info('enabled, starting...')\n this._loadScript(this._startCapturing)\n }\n }\n\n public onRemoteConfig(response: RemoteConfig) {\n const webVitalsOptIn = isObject(response.capturePerformance) && !!response.capturePerformance.web_vitals\n\n const allowedMetrics = isObject(response.capturePerformance)\n ? response.capturePerformance.web_vitals_allowed_metrics\n : undefined\n\n if (this._instance.persistence) {\n this._instance.persistence.register({\n [WEB_VITALS_ENABLED_SERVER_SIDE]: webVitalsOptIn,\n })\n\n this._instance.persistence.register({\n [WEB_VITALS_ALLOWED_METRICS]: allowedMetrics,\n })\n }\n // store this in-memory in case persistence is disabled\n this._enabledServerSide = webVitalsOptIn\n\n this.startIfEnabled()\n }\n\n private _loadScript(cb: () => void): void {\n if (assignableWindow.__PosthogExtensions__?.postHogWebVitalsCallbacks) {\n // already loaded\n cb()\n }\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(this._instance, 'web-vitals', (err) => {\n if (err) {\n logger.error('failed to load script', err)\n return\n }\n cb()\n })\n }\n\n private _currentURL(): string | undefined {\n const href = window ? window.location.href : undefined\n if (!href) {\n logger.error('Could not determine current URL')\n return undefined\n }\n\n // mask url query params\n const maskPersonalDataProperties = this._instance.config.mask_personal_data_properties\n const customPersonalDataProperties = this._instance.config.custom_personal_data_properties\n\n const paramsToMask = maskPersonalDataProperties\n ? extendArray([], PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])\n : []\n\n return maskQueryParams(href, paramsToMask, MASKED)\n }\n\n private _flushToCapture = () => {\n clearTimeout(this._delayedFlushTimer)\n if (this._buffer.metrics.length === 0) {\n return\n }\n\n this._instance.capture(\n '$web_vitals',\n this._buffer.metrics.reduce(\n (acc, metric) => ({\n ...acc,\n // the entire event so we can use it in the future e.g. includes google's rating\n [`$web_vitals_${metric.name}_event`]: { ...metric },\n [`$web_vitals_${metric.name}_value`]: metric.value,\n }),\n {}\n )\n )\n this._buffer = { url: undefined, metrics: [], firstMetricTimestamp: undefined }\n }\n\n private _addToBuffer = (metric: any) => {\n const sessionIds = this._instance.sessionManager?.checkAndGetSessionAndWindowId(true)\n if (isUndefined(sessionIds)) {\n logger.error('Could not read session ID. Dropping metrics!')\n return\n }\n\n this._buffer = this._buffer || { url: undefined, metrics: [], firstMetricTimestamp: undefined }\n\n const $currentUrl = this._currentURL()\n if (isUndefined($currentUrl)) {\n return\n }\n\n if (isNullish(metric?.name) || isNullish(metric?.value)) {\n logger.error('Invalid metric received', metric)\n return\n }\n\n // we observe some very large values sometimes, we'll ignore them\n // since the likelihood of LCP > 1 hour being correct is very low\n if (this._maxAllowedValue && metric.value >= this._maxAllowedValue) {\n logger.error('Ignoring metric with value >= ' + this._maxAllowedValue, metric)\n return\n }\n\n const urlHasChanged = this._buffer.url !== $currentUrl\n\n if (urlHasChanged) {\n // we need to send what we have\n this._flushToCapture()\n // poor performance is >4s, we wait twice that time to send\n // this is in case we haven't received all metrics\n // we'll at least gather some\n this._delayedFlushTimer = setTimeout(this._flushToCapture, this.flushToCaptureTimeoutMs)\n }\n\n if (isUndefined(this._buffer.url)) {\n this._buffer.url = $currentUrl\n }\n\n this._buffer.firstMetricTimestamp = isUndefined(this._buffer.firstMetricTimestamp)\n ? Date.now()\n : this._buffer.firstMetricTimestamp\n\n if (metric.attribution && metric.attribution.interactionTargetElement) {\n // we don't want to send the entire element\n // they can be very large\n // TODO we could run this through autocapture code so that we get elements chain info\n // and can display the element in the UI\n metric.attribution.interactionTargetElement = undefined\n }\n\n this._buffer.metrics.push({\n ...metric,\n $current_url: $currentUrl,\n $session_id: sessionIds.sessionId,\n $window_id: sessionIds.windowId,\n timestamp: Date.now(),\n })\n\n if (this._buffer.metrics.length === this.allowedMetrics.length) {\n // we have all allowed metrics\n this._flushToCapture()\n }\n }\n\n private _startCapturing = () => {\n let onLCP: WebVitalsMetricCallback | undefined\n let onCLS: WebVitalsMetricCallback | undefined\n let onFCP: WebVitalsMetricCallback | undefined\n let onINP: WebVitalsMetricCallback | undefined\n\n const posthogExtensions = assignableWindow.__PosthogExtensions__\n if (!isUndefined(posthogExtensions) && !isUndefined(posthogExtensions.postHogWebVitalsCallbacks)) {\n ;({ onLCP, onCLS, onFCP, onINP } = posthogExtensions.postHogWebVitalsCallbacks)\n }\n\n if (!onLCP || !onCLS || !onFCP || !onINP) {\n logger.error('web vitals callbacks not loaded - not starting')\n return\n }\n\n // register performance observers\n if (this.allowedMetrics.indexOf('LCP') > -1) {\n onLCP(this._addToBuffer.bind(this))\n }\n if (this.allowedMetrics.indexOf('CLS') > -1) {\n onCLS(this._addToBuffer.bind(this))\n }\n if (this.allowedMetrics.indexOf('FCP') > -1) {\n onFCP(this._addToBuffer.bind(this))\n }\n if (this.allowedMetrics.indexOf('INP') > -1) {\n onINP(this._addToBuffer.bind(this))\n }\n\n this._initialized = true\n }\n}\n","import RageClick from './extensions/rageclick'\nimport { DeadClickCandidate, Properties, RemoteConfig } from './types'\nimport { PostHog } from './posthog-core'\n\nimport { document, window } from './utils/globals'\nimport { getEventTarget, getParentElement } from './autocapture-utils'\nimport { HEATMAPS_ENABLED_SERVER_SIDE } from './constants'\nimport { isNumber, isUndefined, isEmptyObject, isObject } from '@posthog/core'\nimport { createLogger } from './utils/logger'\nimport { isElementInToolbar, isElementNode, isTag } from './utils/element-utils'\nimport { DeadClicksAutocapture, isDeadClicksEnabledForHeatmaps } from './extensions/dead-clicks-autocapture'\nimport { includes } from '@posthog/core'\nimport { addEventListener, extendArray } from './utils'\nimport { maskQueryParams } from './utils/request-utils'\nimport { PERSONAL_DATA_CAMPAIGN_PARAMS, MASKED } from './utils/event-utils'\n\nconst DEFAULT_FLUSH_INTERVAL = 5000\n\nconst logger = createLogger('[Heatmaps]')\n\ntype HeatmapEventBuffer =\n | {\n [key: string]: Properties[]\n }\n | undefined\n\nfunction elementOrParentPositionMatches(el: Element | null, matches: string[], breakOnElement?: Element): boolean {\n let curEl: Element | null | false = el\n\n while (curEl && isElementNode(curEl) && !isTag(curEl, 'body')) {\n if (curEl === breakOnElement) {\n return false\n }\n\n if (includes(matches, window?.getComputedStyle(curEl).position)) {\n return true\n }\n\n curEl = getParentElement(curEl)\n }\n\n return false\n}\n\nfunction isValidMouseEvent(e: unknown): e is MouseEvent {\n return isObject(e) && 'clientX' in e && 'clientY' in e && isNumber(e.clientX) && isNumber(e.clientY)\n}\n\nfunction shouldPoll(document: Document | undefined): boolean {\n return document?.visibilityState === 'visible'\n}\n\nexport class Heatmaps {\n instance: PostHog\n rageclicks: RageClick\n _enabledServerSide: boolean = false\n _initialized = false\n _mouseMoveTimeout: ReturnType<typeof setTimeout> | undefined\n\n private _buffer: HeatmapEventBuffer\n private _flushInterval: ReturnType<typeof setInterval> | null = null\n private _deadClicksCapture: DeadClicksAutocapture | undefined\n private _onClickHandler: ((e: Event) => void) | undefined\n private _onMouseMoveHandler: ((e: Event) => void) | undefined\n private _flushHandler: (() => void) | undefined\n private _onVisibilityChange_handler: (() => void) | undefined\n\n constructor(instance: PostHog) {\n this.instance = instance\n this._enabledServerSide = !!this.instance.persistence?.props[HEATMAPS_ENABLED_SERVER_SIDE]\n this.rageclicks = new RageClick(instance.config.rageclick)\n }\n\n public get flushIntervalMilliseconds(): number {\n let flushInterval = DEFAULT_FLUSH_INTERVAL\n if (\n isObject(this.instance.config.capture_heatmaps) &&\n this.instance.config.capture_heatmaps.flush_interval_milliseconds\n ) {\n flushInterval = this.instance.config.capture_heatmaps.flush_interval_milliseconds\n }\n return flushInterval\n }\n\n public get isEnabled(): boolean {\n if (!isUndefined(this.instance.config.capture_heatmaps)) {\n return this.instance.config.capture_heatmaps !== false\n }\n if (!isUndefined(this.instance.config.enable_heatmaps)) {\n return this.instance.config.enable_heatmaps\n }\n return this._enabledServerSide\n }\n\n public startIfEnabled(): void {\n if (this.isEnabled) {\n // nested if here since we only want to run the else\n // if this.enabled === false\n // not if this method is called more than once\n if (this._initialized) {\n return\n }\n logger.info('starting...')\n this._setupListeners()\n this._onVisibilityChange()\n } else {\n clearInterval(this._flushInterval ?? undefined)\n this._removeListeners()\n this.getAndClearBuffer()\n }\n }\n\n public onRemoteConfig(response: RemoteConfig) {\n const optIn = !!response['heatmaps']\n\n if (this.instance.persistence) {\n this.instance.persistence.register({\n [HEATMAPS_ENABLED_SERVER_SIDE]: optIn,\n })\n }\n // store this in-memory in case persistence is disabled\n this._enabledServerSide = optIn\n this.startIfEnabled()\n }\n\n public getAndClearBuffer(): HeatmapEventBuffer {\n const buffer = this._buffer\n this._buffer = undefined\n return buffer\n }\n\n private _onDeadClick(click: DeadClickCandidate): void {\n this._onClick(click.originalEvent, 'deadclick')\n }\n\n private _onVisibilityChange(): void {\n // always clear the interval just in case\n if (this._flushInterval) {\n clearInterval(this._flushInterval)\n }\n\n this._flushInterval = shouldPoll(document)\n ? setInterval(this._flush.bind(this), this.flushIntervalMilliseconds)\n : null\n }\n\n private _setupListeners(): void {\n if (!window || !document) {\n return\n }\n\n this._flushHandler = this._flush.bind(this)\n addEventListener(window, 'beforeunload', this._flushHandler)\n\n this._onClickHandler = (e) => this._onClick((e || window?.event) as MouseEvent)\n addEventListener(document, 'click', this._onClickHandler, { capture: true })\n\n this._onMouseMoveHandler = (e) => this._onMouseMove((e || window?.event) as MouseEvent)\n addEventListener(document, 'mousemove', this._onMouseMoveHandler, { capture: true })\n\n this._deadClicksCapture = new DeadClicksAutocapture(\n this.instance,\n isDeadClicksEnabledForHeatmaps,\n this._onDeadClick.bind(this)\n )\n this._deadClicksCapture.startIfEnabled()\n\n this._onVisibilityChange_handler = this._onVisibilityChange.bind(this)\n addEventListener(document, 'visibilitychange', this._onVisibilityChange_handler)\n\n this._initialized = true\n }\n\n private _removeListeners(): void {\n if (!window || !document) {\n return\n }\n\n if (this._flushHandler) {\n window.removeEventListener('beforeunload', this._flushHandler)\n }\n\n if (this._onClickHandler) {\n document.removeEventListener('click', this._onClickHandler, { capture: true })\n }\n\n if (this._onMouseMoveHandler) {\n document.removeEventListener('mousemove', this._onMouseMoveHandler, { capture: true })\n }\n\n if (this._onVisibilityChange_handler) {\n document.removeEventListener('visibilitychange', this._onVisibilityChange_handler)\n }\n\n clearTimeout(this._mouseMoveTimeout)\n\n this._deadClicksCapture?.stop()\n\n this._initialized = false\n }\n\n private _getProperties(e: MouseEvent, type: string): Properties {\n // We need to know if the target element is fixed or not\n // If fixed then we won't account for scrolling\n // If not then we will account for scrolling\n\n const scrollY = this.instance.scrollManager.scrollY()\n const scrollX = this.instance.scrollManager.scrollX()\n const scrollElement = this.instance.scrollManager.scrollElement()\n\n const isFixedOrSticky = elementOrParentPositionMatches(getEventTarget(e), ['fixed', 'sticky'], scrollElement)\n\n return {\n x: e.clientX + (isFixedOrSticky ? 0 : scrollX),\n y: e.clientY + (isFixedOrSticky ? 0 : scrollY),\n target_fixed: isFixedOrSticky,\n type,\n }\n }\n\n private _onClick(e: MouseEvent, type: string = 'click'): void {\n if (isElementInToolbar(e.target) || !isValidMouseEvent(e)) {\n return\n }\n\n const properties = this._getProperties(e, type)\n\n if (this.rageclicks?.isRageClick(e.clientX, e.clientY, new Date().getTime())) {\n this._capture({\n ...properties,\n type: 'rageclick',\n })\n }\n\n this._capture(properties)\n }\n\n private _onMouseMove(e: Event): void {\n if (isElementInToolbar(e.target) || !isValidMouseEvent(e)) {\n return\n }\n\n clearTimeout(this._mouseMoveTimeout)\n\n this._mouseMoveTimeout = setTimeout(() => {\n this._capture(this._getProperties(e as MouseEvent, 'mousemove'))\n }, 500)\n }\n\n private _capture(properties: Properties): void {\n if (!window) {\n return\n }\n\n const href = window.location.href\n\n // mask url query params\n const maskPersonalDataProperties = this.instance.config.mask_personal_data_properties\n const customPersonalDataProperties = this.instance.config.custom_personal_data_properties\n\n const paramsToMask = maskPersonalDataProperties\n ? extendArray([], PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])\n : []\n\n const url = maskQueryParams(href, paramsToMask, MASKED)\n\n this._buffer = this._buffer || {}\n\n if (!this._buffer[url]) {\n this._buffer[url] = []\n }\n\n this._buffer[url].push(properties)\n }\n\n private _flush(): void {\n if (!this._buffer || isEmptyObject(this._buffer)) {\n return\n }\n\n this.instance.capture('$$heatmap', {\n $heatmap_data: this.getAndClearBuffer(),\n })\n }\n}\n","import { window } from './utils/globals'\nimport { PostHog } from './posthog-core'\nimport { clampToRange, isUndefined } from '@posthog/core'\nimport { extend } from './utils'\nimport { logger } from './utils/logger'\nimport { SessionIdChangedCallback } from './types'\n\ninterface PageViewEventProperties {\n $pageview_id?: string\n $prev_pageview_id?: string\n $prev_pageview_pathname?: string\n $prev_pageview_duration?: number // seconds\n $prev_pageview_last_scroll?: number\n $prev_pageview_last_scroll_percentage?: number\n $prev_pageview_max_scroll?: number\n $prev_pageview_max_scroll_percentage?: number\n $prev_pageview_last_content?: number\n $prev_pageview_last_content_percentage?: number\n $prev_pageview_max_content?: number\n $prev_pageview_max_content_percentage?: number\n}\n\n// This keeps track of the PageView state (such as the previous PageView's path, timestamp, id, and scroll properties).\n// We store the state in memory, which means that for non-SPA sites, the state will be lost on page reload. This means\n// that non-SPA sites should always send a $pageleave event on any navigation, before the page unloads. For SPA sites,\n// they only need to send a $pageleave event when the user navigates away from the site, as the information is not lost\n// on an internal navigation, and is included as the $prev_pageview_ properties in the next $pageview event.\n\n// Practically, this means that to find the scroll properties for a given pageview, you need to find the event where\n// event name is $pageview or $pageleave and where $prev_pageview_id matches the original pageview event's id.\n\nexport class PageViewManager {\n _currentPageview?: { timestamp: Date; pageViewId: string | undefined; pathname: string | undefined }\n _instance: PostHog\n private _unsubscribeSessionId?: () => void\n\n constructor(instance: PostHog) {\n this._instance = instance\n this._setupSessionRotationHandler()\n }\n\n private _setupSessionRotationHandler(): void {\n this._unsubscribeSessionId = this._instance.sessionManager?.onSessionId(this._onSessionIdChange)\n }\n\n private _onSessionIdChange: SessionIdChangedCallback = (sessionId, _windowId, changeReason) => {\n // Only act on actual session rotations, not initial session creation\n if (!changeReason) {\n return\n }\n\n // Clear state when session changes for any of these reasons:\n // - noSessionId: after posthog.reset() or forced idle reset\n // - activityTimeout: 30 min idle (default, configurable up to 10 hours)\n // - sessionPastMaximumLength: 24 hour max session\n if (changeReason.noSessionId || changeReason.activityTimeout || changeReason.sessionPastMaximumLength) {\n logger.info('[PageViewManager] Session rotated, clearing pageview state', {\n sessionId,\n changeReason,\n })\n this._currentPageview = undefined\n this._instance.scrollManager.resetContext()\n }\n }\n\n destroy(): void {\n this._unsubscribeSessionId?.()\n this._unsubscribeSessionId = undefined\n }\n\n doPageView(timestamp: Date, pageViewId?: string): PageViewEventProperties {\n const response = this._previousPageViewProperties(timestamp, pageViewId)\n\n // On a pageview we reset the contexts\n this._currentPageview = { pathname: window?.location.pathname ?? '', pageViewId, timestamp }\n this._instance.scrollManager.resetContext()\n\n return response\n }\n\n doPageLeave(timestamp: Date): PageViewEventProperties {\n return this._previousPageViewProperties(timestamp, this._currentPageview?.pageViewId)\n }\n\n doEvent(): PageViewEventProperties {\n return { $pageview_id: this._currentPageview?.pageViewId }\n }\n\n private _previousPageViewProperties(timestamp: Date, pageviewId: string | undefined): PageViewEventProperties {\n const previousPageView = this._currentPageview\n\n if (!previousPageView) {\n return { $pageview_id: pageviewId }\n }\n\n let properties: PageViewEventProperties = {\n $pageview_id: pageviewId,\n $prev_pageview_id: previousPageView.pageViewId,\n }\n\n const scrollContext = this._instance.scrollManager.getContext()\n\n if (scrollContext && !this._instance.config.disable_scroll_properties) {\n let { maxScrollHeight, lastScrollY, maxScrollY, maxContentHeight, lastContentY, maxContentY } =\n scrollContext\n\n if (\n !isUndefined(maxScrollHeight) &&\n !isUndefined(lastScrollY) &&\n !isUndefined(maxScrollY) &&\n !isUndefined(maxContentHeight) &&\n !isUndefined(lastContentY) &&\n !isUndefined(maxContentY)\n ) {\n // Use ceil, so that e.g. scrolling 999.5px of a 1000px page is considered 100% scrolled\n maxScrollHeight = Math.ceil(maxScrollHeight)\n lastScrollY = Math.ceil(lastScrollY)\n maxScrollY = Math.ceil(maxScrollY)\n maxContentHeight = Math.ceil(maxContentHeight)\n lastContentY = Math.ceil(lastContentY)\n maxContentY = Math.ceil(maxContentY)\n\n // if the maximum scroll height is near 0, then the percentage is 1\n const lastScrollPercentage =\n maxScrollHeight <= 1 ? 1 : clampToRange(lastScrollY / maxScrollHeight, 0, 1, logger)\n const maxScrollPercentage =\n maxScrollHeight <= 1 ? 1 : clampToRange(maxScrollY / maxScrollHeight, 0, 1, logger)\n const lastContentPercentage =\n maxContentHeight <= 1 ? 1 : clampToRange(lastContentY / maxContentHeight, 0, 1, logger)\n const maxContentPercentage =\n maxContentHeight <= 1 ? 1 : clampToRange(maxContentY / maxContentHeight, 0, 1, logger)\n\n properties = extend(properties, {\n $prev_pageview_last_scroll: lastScrollY,\n $prev_pageview_last_scroll_percentage: lastScrollPercentage,\n $prev_pageview_max_scroll: maxScrollY,\n $prev_pageview_max_scroll_percentage: maxScrollPercentage,\n $prev_pageview_last_content: lastContentY,\n $prev_pageview_last_content_percentage: lastContentPercentage,\n $prev_pageview_max_content: maxContentY,\n $prev_pageview_max_content_percentage: maxContentPercentage,\n })\n }\n }\n\n if (previousPageView.pathname) {\n properties.$prev_pageview_pathname = previousPageView.pathname\n }\n if (previousPageView.timestamp) {\n // Use seconds, for consistency with our other duration-related properties like $duration\n properties.$prev_pageview_duration = (timestamp.getTime() - previousPageView.timestamp.getTime()) / 1000\n }\n\n return properties\n }\n}\n","import { PostHog } from './posthog-core'\nimport { Survey } from './posthog-surveys-types'\nimport { ConversationsRemoteConfig } from './posthog-conversations-types'\n\n// only importing types here, so won't affect the bundle\n// eslint-disable-next-line posthog-js/no-external-replay-imports\nimport type { SAMPLED } from './extensions/replay/external/triggerMatching'\n\n// ============================================================================\n// Re-export public types from @posthog/types\n// ============================================================================\n\n// PostHog instance type\nexport type { PostHog as PostHogInterface } from '@posthog/types'\n\n// Common types\nexport type { Property, Properties, JsonType, JsonRecord } from '@posthog/types'\n\n// Capture types\nexport type { KnownEventName, EventName, CaptureResult, CaptureOptions, BeforeSendFn } from '@posthog/types'\n\n// Feature flag types\nexport type {\n FeatureFlagsCallback,\n FeatureFlagDetail,\n FeatureFlagMetadata,\n EvaluationReason,\n RemoteConfigFeatureFlagCallback,\n EarlyAccessFeature,\n EarlyAccessFeatureStage,\n EarlyAccessFeatureCallback,\n EarlyAccessFeatureResponse,\n} from '@posthog/types'\n\n// Request types\nexport type { Headers, RequestResponse, RequestCallback } from '@posthog/types'\n\n// Session recording types\nexport type {\n SessionRecordingCanvasOptions,\n InitiatorType,\n NetworkRequest,\n CapturedNetworkRequest,\n SessionIdChangedCallback,\n SeverityLevel,\n} from '@posthog/types'\n\n// Config types\nexport type {\n AutocaptureCompatibleElement,\n DomAutocaptureEvents,\n AutocaptureConfig,\n RageclickConfig,\n BootstrapConfig,\n SupportedWebVitalsMetrics,\n PerformanceCaptureConfig,\n DeadClickCandidate,\n ExceptionAutoCaptureConfig,\n DeadClicksAutoCaptureConfig,\n HeatmapConfig,\n ConfigDefaults,\n ExternalIntegrationKind,\n ErrorTrackingOptions,\n MaskInputOptions,\n SlimDOMOptions,\n SessionRecordingOptions,\n RequestQueueConfig,\n PostHogConfig,\n} from '@posthog/types'\n\n// Re-export KnownUnsafeEditableEvent from @posthog/core for backwards compatibility\nexport type { KnownUnsafeEditableEvent } from '@posthog/core'\n\n// ============================================================================\n// Browser-specific types that depend on local imports\n// These cannot be moved to @posthog/types as they reference browser-specific code\n// ============================================================================\n\n// Import types for internal use in this file\nimport type {\n SessionRecordingCanvasOptions,\n PerformanceCaptureConfig,\n InitiatorType,\n JsonType,\n Properties,\n EventName,\n CapturedNetworkRequest,\n SessionRecordingOptions,\n FeatureFlagDetail,\n} from '@posthog/types'\n\nexport enum Compression {\n GZipJS = 'gzip-js',\n Base64 = 'base64',\n}\n\n// See https://nextjs.org/docs/app/api-reference/functions/fetch#fetchurl-options\ntype NextOptions = { revalidate: false | 0 | number; tags: string[] }\n\nexport interface RequestWithOptions {\n url: string\n // Data can be a single object or an array of objects when batched\n data?: Record<string, any> | Record<string, any>[]\n headers?: Record<string, any>\n transport?: 'XHR' | 'fetch' | 'sendBeacon'\n method?: 'POST' | 'GET'\n urlQueryArgs?: { compression: Compression }\n callback?: (response: import('@posthog/types').RequestResponse) => void\n timeout?: number\n noRetries?: boolean\n disableTransport?: ('XHR' | 'fetch' | 'sendBeacon')[]\n disableXHRCredentials?: boolean\n compression?: Compression | 'best-available'\n fetchOptions?: {\n cache?: RequestInit['cache']\n next?: NextOptions\n }\n}\n\n// Queued request types - the same as a request but with additional queueing information\nexport interface QueuedRequestWithOptions extends RequestWithOptions {\n /** key of queue, e.g. 'sessionRecording' vs 'event' */\n batchKey?: string\n}\n\n// Used explicitly for retriable requests\nexport interface RetriableRequestWithOptions extends QueuedRequestWithOptions {\n retriesPerformedSoFar?: number\n}\n\nexport type FlagVariant = { flag: string; variant: string }\n\n/** the config stored in persistence when session recording remote config is received */\nexport type SessionRecordingPersistedConfig = Omit<\n SessionRecordingRemoteConfig,\n | 'recordCanvas'\n | 'canvasFps'\n | 'canvasQuality'\n | 'networkPayloadCapture'\n | 'sampleRate'\n | 'minimumDurationMilliseconds'\n> & {\n enabled: boolean\n networkPayloadCapture: SessionRecordingRemoteConfig['networkPayloadCapture'] & {\n capturePerformance: RemoteConfig['capturePerformance']\n }\n canvasRecording: {\n enabled: SessionRecordingRemoteConfig['recordCanvas']\n fps: SessionRecordingRemoteConfig['canvasFps']\n quality: SessionRecordingRemoteConfig['canvasQuality']\n }\n // we don't allow string config here\n sampleRate: number | null\n minimumDurationMilliseconds: number | null | undefined\n}\n\nexport type SessionRecordingRemoteConfig = SessionRecordingCanvasOptions & {\n endpoint?: string\n consoleLogRecordingEnabled?: boolean\n // the API returns a decimal between 0 and 1 as a string\n sampleRate?: string | null\n minimumDurationMilliseconds?: number\n linkedFlag?: string | FlagVariant | null\n networkPayloadCapture?: Pick<NetworkRecordOptions, 'recordBody' | 'recordHeaders'>\n masking?: Pick<SessionRecordingOptions, 'maskAllInputs' | 'maskTextSelector' | 'blockSelector'>\n urlTriggers?: SessionRecordingUrlTrigger[]\n scriptConfig?: { script?: string | undefined }\n urlBlocklist?: SessionRecordingUrlTrigger[]\n eventTriggers?: string[]\n /**\n * Controls how event, url, sampling, and linked flag triggers are combined\n *\n * `any` means that if any of the triggers match, the session will be recorded\n * `all` means that all the triggers must match for the session to be recorded\n *\n * originally it was (event || url) && (sampling || linked flag)\n * which nobody wanted, now the default is all\n */\n triggerMatchType?: 'any' | 'all'\n}\n\n/**\n * Remote configuration for the PostHog instance\n *\n * All of these settings can be configured directly in your PostHog instance\n * Any configuration set in the client overrides the information from the server\n */\nexport interface RemoteConfig {\n /**\n * Supported compression algorithms\n */\n supportedCompression: Compression[]\n\n /**\n * If set, disables autocapture\n */\n autocapture_opt_out?: boolean\n\n /**\n * originally capturePerformance was replay only and so boolean true\n * is equivalent to { network_timing: true }\n * now capture performance can be separately enabled within replay\n * and as a standalone web vitals tracker\n * people can have them enabled separately\n * they work standalone but enhance each other\n * TODO: deprecate this so we make a new config that doesn't need this explanation\n */\n capturePerformance?: boolean | PerformanceCaptureConfig\n\n /**\n * Whether we should use a custom endpoint for analytics\n *\n * @default { endpoint: \"/e\" }\n */\n analytics?: {\n endpoint?: string\n }\n\n /**\n * Whether the `$elements_chain` property should be sent as a string or as an array\n *\n * @default false\n */\n elementsChainAsString?: boolean\n\n /**\n * Error tracking configuration options\n */\n errorTracking?: {\n autocaptureExceptions?: boolean\n captureExtensionExceptions?: boolean\n suppressionRules?: ErrorTrackingSuppressionRule[]\n }\n\n /**\n * This is currently in development and may have breaking changes without a major version bump\n */\n autocaptureExceptions?: boolean | { endpoint?: string }\n\n /**\n * Session recording configuration options\n */\n sessionRecording?: SessionRecordingRemoteConfig | false\n\n /**\n * Whether surveys are enabled\n */\n surveys?: boolean | Survey[]\n\n /**\n * Whether product tours are enabled\n */\n productTours?: boolean\n\n /**\n * Parameters for the toolbar\n */\n toolbarParams: ToolbarParams\n\n /**\n * @deprecated renamed to toolbarParams, still present on older API responses\n */\n editorParams?: ToolbarParams\n\n /**\n * @deprecated, moved to toolbarParams\n */\n toolbarVersion: 'toolbar'\n\n /**\n * Whether the user is authenticated\n */\n isAuthenticated: boolean\n\n /**\n * List of site apps with their IDs and URLs\n */\n siteApps: { id: string; url: string }[]\n\n /**\n * Whether heatmaps are enabled\n */\n heatmaps?: boolean\n\n /**\n * Whether to only capture identified users by default\n */\n defaultIdentifiedOnly?: boolean\n\n /**\n * Whether to capture dead clicks\n */\n captureDeadClicks?: boolean\n\n /**\n * Indicates if the team has any flags enabled (if not we don't need to load them)\n */\n hasFeatureFlags?: boolean\n\n /**\n * Conversations widget configuration\n */\n conversations?: boolean | ConversationsRemoteConfig\n}\n\n/**\n * Flags returns feature flags and their payloads, and optionally returns everything else from the remote config\n * assuming it's called with `config=true`\n */\nexport interface FlagsResponse extends RemoteConfig {\n featureFlags: Record<string, string | boolean>\n featureFlagPayloads: Record<string, JsonType>\n errorsWhileComputingFlags: boolean\n requestId?: string\n flags: Record<string, FeatureFlagDetail>\n evaluatedAt?: number\n}\n\nexport type SiteAppGlobals = {\n event: {\n uuid: string\n event: EventName\n properties: Properties\n timestamp?: Date\n elements_chain?: string\n distinct_id?: string\n }\n person: {\n properties: Properties\n }\n groups: Record<string, { id: string; type: string; properties: Properties }>\n}\n\nexport type SiteAppLoader = {\n id: string\n init: (config: { posthog: PostHog; callback: (success: boolean) => void }) => {\n processEvent?: (globals: SiteAppGlobals) => void\n }\n}\n\nexport type SiteApp = {\n id: string\n loaded: boolean\n errored: boolean\n processedBuffer: boolean\n processEvent?: (globals: SiteAppGlobals) => void\n}\n\nexport interface PersistentStore {\n _is_supported: () => boolean\n _error: (error: any) => void\n _parse: (name: string) => any\n _get: (name: string) => any\n _set: (\n name: string,\n value: any,\n expire_days?: number | null,\n cross_subdomain?: boolean,\n secure?: boolean,\n debug?: boolean\n ) => void\n _remove: (name: string, cross_subdomain?: boolean) => void\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport type Breaker = {}\nexport type EventHandler = (event: Event) => boolean | void\n\nexport type ToolbarUserIntent = 'add-action' | 'edit-action'\nexport type ToolbarSource = 'url' | 'localstorage'\nexport type ToolbarVersion = 'toolbar'\n\n/* sync with posthog */\nexport interface ToolbarParams {\n token?: string /** public posthog-js token */\n temporaryToken?: string /** private temporary user token */\n actionId?: number\n userIntent?: ToolbarUserIntent\n source?: ToolbarSource\n toolbarVersion?: ToolbarVersion\n instrument?: boolean\n distinctId?: string\n userEmail?: string\n dataAttributes?: string[]\n featureFlags?: Record<string, string | boolean>\n}\n\nexport type SnippetArrayItem = [method: string, ...args: any[]]\n\nexport type NetworkRecordOptions = {\n initiatorTypes?: InitiatorType[]\n maskRequestFn?: (data: CapturedNetworkRequest) => CapturedNetworkRequest | undefined\n recordHeaders?: boolean | { request: boolean; response: boolean }\n recordBody?: boolean | string[] | { request: boolean | string[]; response: boolean | string[] }\n recordInitialRequests?: boolean\n /**\n * whether to record PerformanceEntry events for network requests\n */\n recordPerformance?: boolean\n /**\n * the PerformanceObserver will only observe these entry types\n */\n performanceEntryTypeToObserve: string[]\n /**\n * the maximum size of the request/response body to record\n * NB this will be at most 1MB even if set larger\n */\n payloadSizeLimitBytes: number\n /**\n * some domains we should never record the payload\n * for example other companies session replay ingestion payloads aren't super useful but are gigantic\n * if this isn't provided we use a default list\n * if this is provided - we add the provided list to the default list\n * i.e. we never record the payloads on the default deny list\n */\n payloadHostDenyList?: string[]\n}\n\nexport type ErrorEventArgs = [\n event: string | Event,\n source?: string | undefined,\n lineno?: number | undefined,\n colno?: number | undefined,\n error?: Error | undefined,\n]\n\n// levels originally copied from Sentry to work with the sentry integration\n// and to avoid relying on a frequently changing @sentry/types dependency\n// but provided as an array of literal types, so we can constrain the level below\nexport const severityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug'] as const\n\nexport interface SessionRecordingUrlTrigger {\n url: string\n matching: 'regex'\n}\n\nexport type PropertyMatchType = 'regex' | 'not_regex' | 'exact' | 'is_not' | 'icontains' | 'not_icontains'\n\nexport interface ErrorTrackingSuppressionRule {\n type: 'AND' | 'OR'\n values: ErrorTrackingSuppressionRuleValue[]\n}\n\nexport interface ErrorTrackingSuppressionRuleValue {\n key: '$exception_types' | '$exception_values'\n operator: PropertyMatchType\n value: string | string[]\n type: string\n}\n\nexport type SessionStartReason =\n | 'sampling_overridden'\n | 'recording_initialized'\n | 'linked_flag_matched'\n | 'linked_flag_overridden'\n | typeof SAMPLED\n | 'session_id_changed'\n | 'url_trigger_matched'\n | 'event_trigger_matched'\n\nexport type OverrideConfig = {\n sampling: boolean\n linked_flag: boolean\n url_trigger: boolean\n event_trigger: boolean\n}\n","// DEFLATE is a complex format; to read this code, you should probably check the RFC first:\n// https://tools.ietf.org/html/rfc1951\n// You may also wish to take a look at the guide I made about this program:\n// https://gist.github.com/101arrowz/253f31eb5abc3d9275ab943003ffecad\n// Much of the following code is similar to that of UZIP.js:\n// https://github.com/photopea/UZIP.js\n// Many optimizations have been made, so the bundle size is ultimately smaller but performance is similar.\n// Sometimes 0 will appear where -1 would be more appropriate. This is because using a uint\n// is better for memory in most engines (I *think*).\nvar ch2 = {};\nvar wk = (function (c, id, msg, transfer, cb) {\n var u = ch2[id] || (ch2[id] = URL.createObjectURL(new Blob([c], { type: 'text/javascript' })));\n var w = new Worker(u);\n w.onerror = function (e) { return cb(e.error, null); };\n w.onmessage = function (e) { return cb(null, e.data); };\n w.postMessage(msg, transfer);\n return w;\n});\n\n// aliases for shorter compressed code (most minifers don't do this)\nvar u8 = Uint8Array, u16 = Uint16Array, u32 = Uint32Array;\n// fixed length extra bits\nvar fleb = new u8([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, /* unused */ 0, 0, /* impossible */ 0]);\n// fixed distance extra bits\n// see fleb note\nvar fdeb = new u8([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, /* unused */ 0, 0]);\n// code length index map\nvar clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);\n// get base, reverse index map from extra bits\nvar freb = function (eb, start) {\n var b = new u16(31);\n for (var i = 0; i < 31; ++i) {\n b[i] = start += 1 << eb[i - 1];\n }\n // numbers here are at max 18 bits\n var r = new u32(b[30]);\n for (var i = 1; i < 30; ++i) {\n for (var j = b[i]; j < b[i + 1]; ++j) {\n r[j] = ((j - b[i]) << 5) | i;\n }\n }\n return [b, r];\n};\nvar _a = freb(fleb, 2), fl = _a[0], revfl = _a[1];\n// we can ignore the fact that the other numbers are wrong; they never happen anyway\nfl[28] = 258, revfl[258] = 28;\nvar _b = freb(fdeb, 0), fd = _b[0], revfd = _b[1];\n// map of value to reverse (assuming 16 bits)\nvar rev = new u16(32768);\nfor (var i = 0; i < 32768; ++i) {\n // reverse table algorithm from SO\n var x = ((i & 0xAAAA) >>> 1) | ((i & 0x5555) << 1);\n x = ((x & 0xCCCC) >>> 2) | ((x & 0x3333) << 2);\n x = ((x & 0xF0F0) >>> 4) | ((x & 0x0F0F) << 4);\n rev[i] = (((x & 0xFF00) >>> 8) | ((x & 0x00FF) << 8)) >>> 1;\n}\n// create huffman tree from u8 \"map\": index -> code length for code index\n// mb (max bits) must be at most 15\n// TODO: optimize/split up?\nvar hMap = (function (cd, mb, r) {\n var s = cd.length;\n // index\n var i = 0;\n // u16 \"map\": index -> # of codes with bit length = index\n var l = new u16(mb);\n // length of cd must be 288 (total # of codes)\n for (; i < s; ++i)\n ++l[cd[i] - 1];\n // u16 \"map\": index -> minimum code for bit length = index\n var le = new u16(mb);\n for (i = 0; i < mb; ++i) {\n le[i] = (le[i - 1] + l[i - 1]) << 1;\n }\n var co;\n if (r) {\n // u16 \"map\": index -> number of actual bits, symbol for code\n co = new u16(1 << mb);\n // bits to remove for reverser\n var rvb = 15 - mb;\n for (i = 0; i < s; ++i) {\n // ignore 0 lengths\n if (cd[i]) {\n // num encoding both symbol and bits read\n var sv = (i << 4) | cd[i];\n // free bits\n var r_1 = mb - cd[i];\n // start value\n var v = le[cd[i] - 1]++ << r_1;\n // m is end value\n for (var m = v | ((1 << r_1) - 1); v <= m; ++v) {\n // every 16 bit value starting with the code yields the same result\n co[rev[v] >>> rvb] = sv;\n }\n }\n }\n }\n else {\n co = new u16(s);\n for (i = 0; i < s; ++i)\n co[i] = rev[le[cd[i] - 1]++] >>> (15 - cd[i]);\n }\n return co;\n});\n// fixed length tree\nvar flt = new u8(288);\nfor (var i = 0; i < 144; ++i)\n flt[i] = 8;\nfor (var i = 144; i < 256; ++i)\n flt[i] = 9;\nfor (var i = 256; i < 280; ++i)\n flt[i] = 7;\nfor (var i = 280; i < 288; ++i)\n flt[i] = 8;\n// fixed distance tree\nvar fdt = new u8(32);\nfor (var i = 0; i < 32; ++i)\n fdt[i] = 5;\n// fixed length map\nvar flm = /*#__PURE__*/ hMap(flt, 9, 0), flrm = /*#__PURE__*/ hMap(flt, 9, 1);\n// fixed distance map\nvar fdm = /*#__PURE__*/ hMap(fdt, 5, 0), fdrm = /*#__PURE__*/ hMap(fdt, 5, 1);\n// find max of array\nvar max = function (a) {\n var m = a[0];\n for (var i = 1; i < a.length; ++i) {\n if (a[i] > m)\n m = a[i];\n }\n return m;\n};\n// read d, starting at bit p and mask with m\nvar bits = function (d, p, m) {\n var o = (p / 8) >> 0;\n return ((d[o] | (d[o + 1] << 8)) >>> (p & 7)) & m;\n};\n// read d, starting at bit p continuing for at least 16 bits\nvar bits16 = function (d, p) {\n var o = (p / 8) >> 0;\n return ((d[o] | (d[o + 1] << 8) | (d[o + 2] << 16)) >>> (p & 7));\n};\n// get end of byte\nvar shft = function (p) { return ((p / 8) >> 0) + (p & 7 && 1); };\n// typed array slice - allows garbage collector to free original reference,\n// while being more compatible than .slice\nvar slc = function (v, s, e) {\n if (s == null || s < 0)\n s = 0;\n if (e == null || e > v.length)\n e = v.length;\n // can't use .constructor in case user-supplied\n var n = new (v instanceof u16 ? u16 : v instanceof u32 ? u32 : u8)(e - s);\n n.set(v.subarray(s, e));\n return n;\n};\n// expands raw DEFLATE data\nvar inflt = function (dat, buf, st) {\n // source length\n var sl = dat.length;\n // have to estimate size\n var noBuf = !buf || st;\n // no state\n var noSt = !st || st.i;\n if (!st)\n st = {};\n // Assumes roughly 33% compression ratio average\n if (!buf)\n buf = new u8(sl * 3);\n // ensure buffer can fit at least l elements\n var cbuf = function (l) {\n var bl = buf.length;\n // need to increase size to fit\n if (l > bl) {\n // Double or set to necessary, whichever is greater\n var nbuf = new u8(Math.max(bl * 2, l));\n nbuf.set(buf);\n buf = nbuf;\n }\n };\n // last chunk bitpos bytes\n var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;\n // total bits\n var tbts = sl * 8;\n do {\n if (!lm) {\n // BFINAL - this is only 1 when last chunk is next\n st.f = final = bits(dat, pos, 1);\n // type: 0 = no compression, 1 = fixed huffman, 2 = dynamic huffman\n var type = bits(dat, pos + 1, 3);\n pos += 3;\n if (!type) {\n // go to end of byte boundary\n var s = shft(pos) + 4, l = dat[s - 4] | (dat[s - 3] << 8), t = s + l;\n if (t > sl) {\n if (noSt)\n throw 'unexpected EOF';\n break;\n }\n // ensure size\n if (noBuf)\n cbuf(bt + l);\n // Copy over uncompressed data\n buf.set(dat.subarray(s, t), bt);\n // Get new bitpos, update byte count\n st.b = bt += l, st.p = pos = t * 8;\n continue;\n }\n else if (type == 1)\n lm = flrm, dm = fdrm, lbt = 9, dbt = 5;\n else if (type == 2) {\n // literal lengths\n var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;\n var tl = hLit + bits(dat, pos + 5, 31) + 1;\n pos += 14;\n // length+distance tree\n var ldt = new u8(tl);\n // code length tree\n var clt = new u8(19);\n for (var i = 0; i < hcLen; ++i) {\n // use index map to get real code\n clt[clim[i]] = bits(dat, pos + i * 3, 7);\n }\n pos += hcLen * 3;\n // code lengths bits\n var clb = max(clt), clbmsk = (1 << clb) - 1;\n if (!noSt && pos + tl * (clb + 7) > tbts)\n break;\n // code lengths map\n var clm = hMap(clt, clb, 1);\n for (var i = 0; i < tl;) {\n var r = clm[bits(dat, pos, clbmsk)];\n // bits read\n pos += r & 15;\n // symbol\n var s = r >>> 4;\n // code length to copy\n if (s < 16) {\n ldt[i++] = s;\n }\n else {\n // copy count\n var c = 0, n = 0;\n if (s == 16)\n n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];\n else if (s == 17)\n n = 3 + bits(dat, pos, 7), pos += 3;\n else if (s == 18)\n n = 11 + bits(dat, pos, 127), pos += 7;\n while (n--)\n ldt[i++] = c;\n }\n }\n // length tree distance tree\n var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);\n // max length bits\n lbt = max(lt);\n // max dist bits\n dbt = max(dt);\n lm = hMap(lt, lbt, 1);\n dm = hMap(dt, dbt, 1);\n }\n else\n throw 'invalid block type';\n if (pos > tbts)\n throw 'unexpected EOF';\n }\n // Make sure the buffer can hold this + the largest possible addition\n // Maximum chunk size (practically, theoretically infinite) is 2^17;\n if (noBuf)\n cbuf(bt + 131072);\n var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;\n var mxa = lbt + dbt + 18;\n while (noSt || pos + mxa < tbts) {\n // bits read, code\n var c = lm[bits16(dat, pos) & lms], sym = c >>> 4;\n pos += c & 15;\n if (pos > tbts)\n throw 'unexpected EOF';\n if (!c)\n throw 'invalid length/literal';\n if (sym < 256)\n buf[bt++] = sym;\n else if (sym == 256) {\n lm = null;\n break;\n }\n else {\n var add = sym - 254;\n // no extra bits needed if less\n if (sym > 264) {\n // index\n var i = sym - 257, b = fleb[i];\n add = bits(dat, pos, (1 << b) - 1) + fl[i];\n pos += b;\n }\n // dist\n var d = dm[bits16(dat, pos) & dms], dsym = d >>> 4;\n if (!d)\n throw 'invalid distance';\n pos += d & 15;\n var dt = fd[dsym];\n if (dsym > 3) {\n var b = fdeb[dsym];\n dt += bits16(dat, pos) & ((1 << b) - 1), pos += b;\n }\n if (pos > tbts)\n throw 'unexpected EOF';\n if (noBuf)\n cbuf(bt + 131072);\n var end = bt + add;\n for (; bt < end; bt += 4) {\n buf[bt] = buf[bt - dt];\n buf[bt + 1] = buf[bt + 1 - dt];\n buf[bt + 2] = buf[bt + 2 - dt];\n buf[bt + 3] = buf[bt + 3 - dt];\n }\n bt = end;\n }\n }\n st.l = lm, st.p = pos, st.b = bt;\n if (lm)\n final = 1, st.m = lbt, st.d = dm, st.n = dbt;\n } while (!final);\n return bt == buf.length ? buf : slc(buf, 0, bt);\n};\n// starting at p, write the minimum number of bits that can hold v to d\nvar wbits = function (d, p, v) {\n v <<= p & 7;\n var o = (p / 8) >> 0;\n d[o] |= v;\n d[o + 1] |= v >>> 8;\n};\n// starting at p, write the minimum number of bits (>8) that can hold v to d\nvar wbits16 = function (d, p, v) {\n v <<= p & 7;\n var o = (p / 8) >> 0;\n d[o] |= v;\n d[o + 1] |= v >>> 8;\n d[o + 2] |= v >>> 16;\n};\n// creates code lengths from a frequency table\nvar hTree = function (d, mb) {\n // Need extra info to make a tree\n var t = [];\n for (var i = 0; i < d.length; ++i) {\n if (d[i])\n t.push({ s: i, f: d[i] });\n }\n var s = t.length;\n var t2 = t.slice();\n if (!s)\n return [new u8(0), 0];\n if (s == 1) {\n var v = new u8(t[0].s + 1);\n v[t[0].s] = 1;\n return [v, 1];\n }\n t.sort(function (a, b) { return a.f - b.f; });\n // after i2 reaches last ind, will be stopped\n // freq must be greater than largest possible number of symbols\n t.push({ s: -1, f: 25001 });\n var l = t[0], r = t[1], i0 = 0, i1 = 1, i2 = 2;\n t[0] = { s: -1, f: l.f + r.f, l: l, r: r };\n // efficient algorithm from UZIP.js\n // i0 is lookbehind, i2 is lookahead - after processing two low-freq\n // symbols that combined have high freq, will start processing i2 (high-freq,\n // non-composite) symbols instead\n // see https://reddit.com/r/photopea/comments/ikekht/uzipjs_questions/\n while (i1 != s - 1) {\n l = t[t[i0].f < t[i2].f ? i0++ : i2++];\n r = t[i0 != i1 && t[i0].f < t[i2].f ? i0++ : i2++];\n t[i1++] = { s: -1, f: l.f + r.f, l: l, r: r };\n }\n var maxSym = t2[0].s;\n for (var i = 1; i < s; ++i) {\n if (t2[i].s > maxSym)\n maxSym = t2[i].s;\n }\n // code lengths\n var tr = new u16(maxSym + 1);\n // max bits in tree\n var mbt = ln(t[i1 - 1], tr, 0);\n if (mbt > mb) {\n // more algorithms from UZIP.js\n // TODO: find out how this code works (debt)\n // ind debt\n var i = 0, dt = 0;\n // left cost\n var lft = mbt - mb, cst = 1 << lft;\n t2.sort(function (a, b) { return tr[b.s] - tr[a.s] || a.f - b.f; });\n for (; i < s; ++i) {\n var i2_1 = t2[i].s;\n if (tr[i2_1] > mb) {\n dt += cst - (1 << (mbt - tr[i2_1]));\n tr[i2_1] = mb;\n }\n else\n break;\n }\n dt >>>= lft;\n while (dt > 0) {\n var i2_2 = t2[i].s;\n if (tr[i2_2] < mb)\n dt -= 1 << (mb - tr[i2_2]++ - 1);\n else\n ++i;\n }\n for (; i >= 0 && dt; --i) {\n var i2_3 = t2[i].s;\n if (tr[i2_3] == mb) {\n --tr[i2_3];\n ++dt;\n }\n }\n mbt = mb;\n }\n return [new u8(tr), mbt];\n};\n// get the max length and assign length codes\nvar ln = function (n, l, d) {\n return n.s == -1\n ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1))\n : (l[n.s] = d);\n};\n// length codes generation\nvar lc = function (c) {\n var s = c.length;\n // Note that the semicolon was intentional\n while (s && !c[--s])\n ;\n var cl = new u16(++s);\n // ind num streak\n var cli = 0, cln = c[0], cls = 1;\n var w = function (v) { cl[cli++] = v; };\n for (var i = 1; i <= s; ++i) {\n if (c[i] == cln && i != s)\n ++cls;\n else {\n if (!cln && cls > 2) {\n for (; cls > 138; cls -= 138)\n w(32754);\n if (cls > 2) {\n w(cls > 10 ? ((cls - 11) << 5) | 28690 : ((cls - 3) << 5) | 12305);\n cls = 0;\n }\n }\n else if (cls > 3) {\n w(cln), --cls;\n for (; cls > 6; cls -= 6)\n w(8304);\n if (cls > 2)\n w(((cls - 3) << 5) | 8208), cls = 0;\n }\n while (cls--)\n w(cln);\n cls = 1;\n cln = c[i];\n }\n }\n return [cl.subarray(0, cli), s];\n};\n// calculate the length of output from tree, code lengths\nvar clen = function (cf, cl) {\n var l = 0;\n for (var i = 0; i < cl.length; ++i)\n l += cf[i] * cl[i];\n return l;\n};\n// writes a fixed block\n// returns the new bit pos\nvar wfblk = function (out, pos, dat) {\n // no need to write 00 as type: TypedArray defaults to 0\n var s = dat.length;\n var o = shft(pos + 2);\n out[o] = s & 255;\n out[o + 1] = s >>> 8;\n out[o + 2] = out[o] ^ 255;\n out[o + 3] = out[o + 1] ^ 255;\n for (var i = 0; i < s; ++i)\n out[o + i + 4] = dat[i];\n return (o + 4 + s) * 8;\n};\n// writes a block\nvar wblk = function (dat, out, final, syms, lf, df, eb, li, bs, bl, p) {\n wbits(out, p++, final);\n ++lf[256];\n var _a = hTree(lf, 15), dlt = _a[0], mlb = _a[1];\n var _b = hTree(df, 15), ddt = _b[0], mdb = _b[1];\n var _c = lc(dlt), lclt = _c[0], nlc = _c[1];\n var _d = lc(ddt), lcdt = _d[0], ndc = _d[1];\n var lcfreq = new u16(19);\n for (var i = 0; i < lclt.length; ++i)\n lcfreq[lclt[i] & 31]++;\n for (var i = 0; i < lcdt.length; ++i)\n lcfreq[lcdt[i] & 31]++;\n var _e = hTree(lcfreq, 7), lct = _e[0], mlcb = _e[1];\n var nlcc = 19;\n for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)\n ;\n var flen = (bl + 5) << 3;\n var ftlen = clen(lf, flt) + clen(df, fdt) + eb;\n var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + (2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18]);\n if (flen <= ftlen && flen <= dtlen)\n return wfblk(out, p, dat.subarray(bs, bs + bl));\n var lm, ll, dm, dl;\n wbits(out, p, 1 + (dtlen < ftlen)), p += 2;\n if (dtlen < ftlen) {\n lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;\n var llm = hMap(lct, mlcb, 0);\n wbits(out, p, nlc - 257);\n wbits(out, p + 5, ndc - 1);\n wbits(out, p + 10, nlcc - 4);\n p += 14;\n for (var i = 0; i < nlcc; ++i)\n wbits(out, p + 3 * i, lct[clim[i]]);\n p += 3 * nlcc;\n var lcts = [lclt, lcdt];\n for (var it = 0; it < 2; ++it) {\n var clct = lcts[it];\n for (var i = 0; i < clct.length; ++i) {\n var len = clct[i] & 31;\n wbits(out, p, llm[len]), p += lct[len];\n if (len > 15)\n wbits(out, p, (clct[i] >>> 5) & 127), p += clct[i] >>> 12;\n }\n }\n }\n else {\n lm = flm, ll = flt, dm = fdm, dl = fdt;\n }\n for (var i = 0; i < li; ++i) {\n if (syms[i] > 255) {\n var len = (syms[i] >>> 18) & 31;\n wbits16(out, p, lm[len + 257]), p += ll[len + 257];\n if (len > 7)\n wbits(out, p, (syms[i] >>> 23) & 31), p += fleb[len];\n var dst = syms[i] & 31;\n wbits16(out, p, dm[dst]), p += dl[dst];\n if (dst > 3)\n wbits16(out, p, (syms[i] >>> 5) & 8191), p += fdeb[dst];\n }\n else {\n wbits16(out, p, lm[syms[i]]), p += ll[syms[i]];\n }\n }\n wbits16(out, p, lm[256]);\n return p + ll[256];\n};\n// deflate options (nice << 13) | chain\nvar deo = /*#__PURE__*/ new u32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]);\n// empty\nvar et = /*#__PURE__*/ new u8(0);\n// compresses data into a raw DEFLATE buffer\nvar dflt = function (dat, lvl, plvl, pre, post, lst) {\n var s = dat.length;\n var o = new u8(pre + s + 5 * (1 + Math.floor(s / 7000)) + post);\n // writing to this writes to the output buffer\n var w = o.subarray(pre, o.length - post);\n var pos = 0;\n if (!lvl || s < 8) {\n for (var i = 0; i <= s; i += 65535) {\n // end\n var e = i + 65535;\n if (e < s) {\n // write full block\n pos = wfblk(w, pos, dat.subarray(i, e));\n }\n else {\n // write final block\n w[i] = lst;\n pos = wfblk(w, pos, dat.subarray(i, s));\n }\n }\n }\n else {\n var opt = deo[lvl - 1];\n var n = opt >>> 13, c = opt & 8191;\n var msk_1 = (1 << plvl) - 1;\n // prev 2-byte val map curr 2-byte val map\n var prev = new u16(32768), head = new u16(msk_1 + 1);\n var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;\n var hsh = function (i) { return (dat[i] ^ (dat[i + 1] << bs1_1) ^ (dat[i + 2] << bs2_1)) & msk_1; };\n // 24576 is an arbitrary number of maximum symbols per block\n // 424 buffer for last block\n var syms = new u32(25000);\n // length/literal freq distance freq\n var lf = new u16(288), df = new u16(32);\n // l/lcnt exbits index l/lind waitdx bitpos\n var lc_1 = 0, eb = 0, i = 0, li = 0, wi = 0, bs = 0;\n for (; i < s; ++i) {\n // hash value\n var hv = hsh(i);\n // index mod 32768\n var imod = i & 32767;\n // previous index with this value\n var pimod = head[hv];\n prev[imod] = pimod;\n head[hv] = imod;\n // We always should modify head and prev, but only add symbols if\n // this data is not yet processed (\"wait\" for wait index)\n if (wi <= i) {\n // bytes remaining\n var rem = s - i;\n if ((lc_1 > 7000 || li > 24576) && rem > 423) {\n pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);\n li = lc_1 = eb = 0, bs = i;\n for (var j = 0; j < 286; ++j)\n lf[j] = 0;\n for (var j = 0; j < 30; ++j)\n df[j] = 0;\n }\n // len dist chain\n var l = 2, d = 0, ch_1 = c, dif = (imod - pimod) & 32767;\n if (rem > 2 && hv == hsh(i - dif)) {\n var maxn = Math.min(n, rem) - 1;\n var maxd = Math.min(32767, i);\n // max possible length\n // not capped at dif because decompressors implement \"rolling\" index population\n var ml = Math.min(258, rem);\n while (dif <= maxd && --ch_1 && imod != pimod) {\n if (dat[i + l] == dat[i + l - dif]) {\n var nl = 0;\n for (; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl)\n ;\n if (nl > l) {\n l = nl, d = dif;\n // break out early when we reach \"nice\" (we are satisfied enough)\n if (nl > maxn)\n break;\n // now, find the rarest 2-byte sequence within this\n // length of literals and search for that instead.\n // Much faster than just using the start\n var mmd = Math.min(dif, nl - 2);\n var md = 0;\n for (var j = 0; j < mmd; ++j) {\n var ti = (i - dif + j + 32768) & 32767;\n var pti = prev[ti];\n var cd = (ti - pti + 32768) & 32767;\n if (cd > md)\n md = cd, pimod = ti;\n }\n }\n }\n // check the previous match\n imod = pimod, pimod = prev[imod];\n dif += (imod - pimod + 32768) & 32767;\n }\n }\n // d will be nonzero only when a match was found\n if (d) {\n // store both dist and len data in one Uint32\n // Make sure this is recognized as a len/dist with 28th bit (2^28)\n syms[li++] = 268435456 | (revfl[l] << 18) | revfd[d];\n var lin = revfl[l] & 31, din = revfd[d] & 31;\n eb += fleb[lin] + fdeb[din];\n ++lf[257 + lin];\n ++df[din];\n wi = i + l;\n ++lc_1;\n }\n else {\n syms[li++] = dat[i];\n ++lf[dat[i]];\n }\n }\n }\n pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos);\n // this is the easiest way to avoid needing to maintain state\n if (!lst)\n pos = wfblk(w, pos, et);\n }\n return slc(o, 0, pre + shft(pos) + post);\n};\n// CRC32 table\nvar crct = /*#__PURE__*/ (function () {\n var t = new u32(256);\n for (var i = 0; i < 256; ++i) {\n var c = i, k = 9;\n while (--k)\n c = ((c & 1) && 0xEDB88320) ^ (c >>> 1);\n t[i] = c;\n }\n return t;\n})();\n// CRC32\nvar crc = function () {\n var c = 0xFFFFFFFF;\n return {\n p: function (d) {\n // closures have awful performance\n var cr = c;\n for (var i = 0; i < d.length; ++i)\n cr = crct[(cr & 255) ^ d[i]] ^ (cr >>> 8);\n c = cr;\n },\n d: function () { return c ^ 0xFFFFFFFF; }\n };\n};\n// Alder32\nvar adler = function () {\n var a = 1, b = 0;\n return {\n p: function (d) {\n // closures have awful performance\n var n = a, m = b;\n var l = d.length;\n for (var i = 0; i != l;) {\n var e = Math.min(i + 5552, l);\n for (; i < e; ++i)\n n += d[i], m += n;\n n %= 65521, m %= 65521;\n }\n a = n, b = m;\n },\n d: function () { return ((a >>> 8) << 16 | (b & 255) << 8 | (b >>> 8)) + ((a & 255) << 23) * 2; }\n };\n};\n;\n// deflate with opts\nvar dopt = function (dat, opt, pre, post, st) {\n return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : (12 + opt.mem), pre, post, !st);\n};\n// Walmart object spread\nvar mrg = function (a, b) {\n var o = {};\n for (var k in a)\n o[k] = a[k];\n for (var k in b)\n o[k] = b[k];\n return o;\n};\n// worker clone\n// This is possibly the craziest part of the entire codebase, despite how simple it may seem.\n// The only parameter to this function is a closure that returns an array of variables outside of the function scope.\n// We're going to try to figure out the variable names used in the closure as strings because that is crucial for workerization.\n// We will return an object mapping of true variable name to value (basically, the current scope as a JS object).\n// The reason we can't just use the original variable names is minifiers mangling the toplevel scope.\n// This took me three weeks to figure out how to do.\nvar wcln = function (fn, fnStr, td) {\n var dt = fn();\n var st = fn.toString();\n var ks = st.slice(st.indexOf('[') + 1, st.lastIndexOf(']')).replace(/ /g, '').split(',');\n for (var i = 0; i < dt.length; ++i) {\n var v = dt[i], k = ks[i];\n if (typeof v == 'function') {\n fnStr += ';' + k + '=';\n var st_1 = v.toString();\n if (v.prototype) {\n // for global objects\n if (st_1.indexOf('[native code]') != -1) {\n var spInd = st_1.indexOf(' ', 8) + 1;\n fnStr += st_1.slice(spInd, st_1.indexOf('(', spInd));\n }\n else {\n fnStr += st_1;\n for (var t in v.prototype)\n fnStr += ';' + k + '.prototype.' + t + '=' + v.prototype[t].toString();\n }\n }\n else\n fnStr += st_1;\n }\n else\n td[k] = v;\n }\n return [fnStr, td];\n};\nvar ch = [];\n// clone bufs\nvar cbfs = function (v) {\n var tl = [];\n for (var k in v) {\n if (v[k] instanceof u8 || v[k] instanceof u16 || v[k] instanceof u32)\n tl.push((v[k] = new v[k].constructor(v[k])).buffer);\n }\n return tl;\n};\n// use a worker to execute code\nvar wrkr = function (fns, init, id, cb) {\n var _a;\n if (!ch[id]) {\n var fnStr = '', td_1 = {}, m = fns.length - 1;\n for (var i = 0; i < m; ++i)\n _a = wcln(fns[i], fnStr, td_1), fnStr = _a[0], td_1 = _a[1];\n ch[id] = wcln(fns[m], fnStr, td_1);\n }\n var td = mrg({}, ch[id][1]);\n return wk(ch[id][0] + ';onmessage=function(e){for(var k in e.data)self[k]=e.data[k];onmessage=' + init.toString() + '}', id, td, cbfs(td), cb);\n};\n// base async inflate fn\nvar bInflt = function () { return [u8, u16, u32, fleb, fdeb, clim, fl, fd, flrm, fdrm, rev, hMap, max, bits, bits16, shft, slc, inflt, inflateSync, pbf, gu8]; };\nvar bDflt = function () { return [u8, u16, u32, fleb, fdeb, clim, revfl, revfd, flm, flt, fdm, fdt, rev, deo, et, hMap, wbits, wbits16, hTree, ln, lc, clen, wfblk, wblk, shft, slc, dflt, dopt, deflateSync, pbf]; };\n// gzip extra\nvar gze = function () { return [gzh, gzhl, wbytes, crc, crct]; };\n// gunzip extra\nvar guze = function () { return [gzs, gzl]; };\n// zlib extra\nvar zle = function () { return [zlh, wbytes, adler]; };\n// unzlib extra\nvar zule = function () { return [zlv]; };\n// post buf\nvar pbf = function (msg) { return postMessage(msg, [msg.buffer]); };\n// get u8\nvar gu8 = function (o) { return o && o.size && new u8(o.size); };\n// async helper\nvar cbify = function (dat, opts, fns, init, id, cb) {\n var w = wrkr(fns, init, id, function (err, dat) {\n w.terminate();\n cb(err, dat);\n });\n if (!opts.consume)\n dat = new u8(dat);\n w.postMessage([dat, opts], [dat.buffer]);\n return function () { w.terminate(); };\n};\n// auto stream\nvar astrm = function (strm) {\n strm.ondata = function (dat, final) { return postMessage([dat, final], [dat.buffer]); };\n return function (ev) { return strm.push(ev.data[0], ev.data[1]); };\n};\n// async stream attach\nvar astrmify = function (fns, strm, opts, init, id) {\n var t;\n var w = wrkr(fns, init, id, function (err, dat) {\n if (err)\n w.terminate(), strm.ondata.call(strm, err);\n else {\n if (dat[1])\n w.terminate();\n strm.ondata.call(strm, err, dat[0], dat[1]);\n }\n });\n w.postMessage(opts);\n strm.push = function (d, f) {\n if (t)\n throw 'stream finished';\n if (!strm.ondata)\n throw 'no stream handler';\n w.postMessage([d, t = f], [d.buffer]);\n };\n strm.terminate = function () { w.terminate(); };\n};\n// read 2 bytes\nvar b2 = function (d, b) { return d[b] | (d[b + 1] << 8); };\n// read 4 bytes\nvar b4 = function (d, b) { return (d[b] | (d[b + 1] << 8) | (d[b + 2] << 16)) + (d[b + 3] << 23) * 2; };\n// write bytes\nvar wbytes = function (d, b, v) {\n for (; v; ++b)\n d[b] = v, v >>>= 8;\n};\n// gzip header\nvar gzh = function (c, o) {\n var fn = o.filename;\n c[0] = 31, c[1] = 139, c[2] = 8, c[8] = o.level < 2 ? 4 : o.level == 9 ? 2 : 0, c[9] = 3; // assume Unix\n if (o.mtime != 0)\n wbytes(c, 4, Math.floor(new Date(o.mtime || Date.now()) / 1000));\n if (fn) {\n c[3] = 8;\n for (var i = 0; i <= fn.length; ++i)\n c[i + 10] = fn.charCodeAt(i);\n }\n};\n// gzip footer: -8 to -4 = CRC, -4 to -0 is length\n// gzip start\nvar gzs = function (d) {\n if (d[0] != 31 || d[1] != 139 || d[2] != 8)\n throw 'invalid gzip data';\n var flg = d[3];\n var st = 10;\n if (flg & 4)\n st += d[10] | (d[11] << 8) + 2;\n for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++])\n ;\n return st + (flg & 2);\n};\n// gzip length\nvar gzl = function (d) {\n var l = d.length;\n return (d[l - 4] | d[l - 3] << 8 | d[l - 2] << 16) + (2 * (d[l - 1] << 23));\n};\n// gzip header length\nvar gzhl = function (o) { return 10 + ((o.filename && (o.filename.length + 1)) || 0); };\n// zlib header\nvar zlh = function (c, o) {\n var lv = o.level, fl = lv == 0 ? 0 : lv < 6 ? 1 : lv == 9 ? 3 : 2;\n c[0] = 120, c[1] = (fl << 6) | (fl ? (32 - 2 * fl) : 1);\n};\n// zlib valid\nvar zlv = function (d) {\n if ((d[0] & 15) != 8 || (d[0] >>> 4) > 7 || ((d[0] << 8 | d[1]) % 31))\n throw 'invalid zlib data';\n if (d[1] & 32)\n throw 'invalid zlib data: preset dictionaries not supported';\n};\nfunction AsyncCmpStrm(opts, cb) {\n if (!cb && typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n return opts;\n}\n// zlib footer: -4 to -0 is Adler32\n/**\n * Streaming DEFLATE compression\n */\nvar Deflate = /*#__PURE__*/ (function () {\n function Deflate(opts, cb) {\n if (!cb && typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n this.o = opts || {};\n }\n Deflate.prototype.p = function (c, f) {\n this.ondata(dopt(c, this.o, 0, 0, !f), f);\n };\n /**\n * Pushes a chunk to be deflated\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Deflate.prototype.push = function (chunk, final) {\n if (this.d)\n throw 'stream finished';\n if (!this.ondata)\n throw 'no stream handler';\n this.d = final;\n this.p(chunk, final || false);\n };\n return Deflate;\n}());\nexport { Deflate };\n/**\n * Asynchronous streaming DEFLATE compression\n */\nvar AsyncDeflate = /*#__PURE__*/ (function () {\n function AsyncDeflate(opts, cb) {\n astrmify([\n bDflt,\n function () { return [astrm, Deflate]; }\n ], this, AsyncCmpStrm.call(this, opts, cb), function (ev) {\n var strm = new Deflate(ev.data);\n onmessage = astrm(strm);\n }, 6);\n }\n return AsyncDeflate;\n}());\nexport { AsyncDeflate };\nexport function deflate(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return cbify(data, opts, [\n bDflt,\n ], function (ev) { return pbf(deflateSync(ev.data[0], ev.data[1])); }, 0, cb);\n}\n/**\n * Compresses data with DEFLATE without any wrapper\n * @param data The data to compress\n * @param opts The compression options\n * @returns The deflated version of the data\n */\nexport function deflateSync(data, opts) {\n if (opts === void 0) { opts = {}; }\n return dopt(data, opts, 0, 0);\n}\n/**\n * Streaming DEFLATE decompression\n */\nvar Inflate = /*#__PURE__*/ (function () {\n /**\n * Creates an inflation stream\n * @param cb The callback to call whenever data is inflated\n */\n function Inflate(cb) {\n this.s = {};\n this.p = new u8(0);\n this.ondata = cb;\n }\n Inflate.prototype.e = function (c) {\n if (this.d)\n throw 'stream finished';\n if (!this.ondata)\n throw 'no stream handler';\n var l = this.p.length;\n var n = new u8(l + c.length);\n n.set(this.p), n.set(c, l), this.p = n;\n };\n Inflate.prototype.c = function (final) {\n this.d = this.s.i = final || false;\n var bts = this.s.b;\n var dt = inflt(this.p, this.o, this.s);\n this.ondata(slc(dt, bts, this.s.b), this.d);\n this.o = slc(dt, this.s.b - 32768), this.s.b = this.o.length;\n this.p = slc(this.p, (this.s.p / 8) >> 0), this.s.p &= 7;\n };\n /**\n * Pushes a chunk to be inflated\n * @param chunk The chunk to push\n * @param final Whether this is the final chunk\n */\n Inflate.prototype.push = function (chunk, final) {\n this.e(chunk), this.c(final);\n };\n return Inflate;\n}());\nexport { Inflate };\n/**\n * Asynchronous streaming DEFLATE decompression\n */\nvar AsyncInflate = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous inflation stream\n * @param cb The callback to call whenever data is deflated\n */\n function AsyncInflate(cb) {\n this.ondata = cb;\n astrmify([\n bInflt,\n function () { return [astrm, Inflate]; }\n ], this, 0, function () {\n var strm = new Inflate();\n onmessage = astrm(strm);\n }, 7);\n }\n return AsyncInflate;\n}());\nexport { AsyncInflate };\nexport function inflate(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return cbify(data, opts, [\n bInflt\n ], function (ev) { return pbf(inflateSync(ev.data[0], gu8(ev.data[1]))); }, 1, cb);\n}\n/**\n * Expands DEFLATE data with no wrapper\n * @param data The data to decompress\n * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.\n * @returns The decompressed version of the data\n */\nexport function inflateSync(data, out) {\n return inflt(data, out);\n}\n// before you yell at me for not just using extends, my reason is that TS inheritance is hard to workerize.\n/**\n * Streaming GZIP compression\n */\nvar Gzip = /*#__PURE__*/ (function () {\n function Gzip(opts, cb) {\n this.c = crc();\n this.l = 0;\n this.v = 1;\n Deflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be GZIPped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Gzip.prototype.push = function (chunk, final) {\n Deflate.prototype.push.call(this, chunk, final);\n };\n Gzip.prototype.p = function (c, f) {\n this.c.p(c);\n this.l += c.length;\n var raw = dopt(c, this.o, this.v && gzhl(this.o), f && 8, !f);\n if (this.v)\n gzh(raw, this.o), this.v = 0;\n if (f)\n wbytes(raw, raw.length - 8, this.c.d()), wbytes(raw, raw.length - 4, this.l);\n this.ondata(raw, f);\n };\n return Gzip;\n}());\nexport { Gzip };\n/**\n * Asynchronous streaming GZIP compression\n */\nvar AsyncGzip = /*#__PURE__*/ (function () {\n function AsyncGzip(opts, cb) {\n astrmify([\n bDflt,\n gze,\n function () { return [astrm, Deflate, Gzip]; }\n ], this, AsyncCmpStrm.call(this, opts, cb), function (ev) {\n var strm = new Gzip(ev.data);\n onmessage = astrm(strm);\n }, 8);\n }\n return AsyncGzip;\n}());\nexport { AsyncGzip };\nexport function gzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return cbify(data, opts, [\n bDflt,\n gze,\n function () { return [gzipSync]; }\n ], function (ev) { return pbf(gzipSync(ev.data[0], ev.data[1])); }, 2, cb);\n}\n/**\n * Compresses data with GZIP\n * @param data The data to compress\n * @param opts The compression options\n * @returns The gzipped version of the data\n */\nexport function gzipSync(data, opts) {\n if (opts === void 0) { opts = {}; }\n var c = crc(), l = data.length;\n c.p(data);\n var d = dopt(data, opts, gzhl(opts), 8), s = d.length;\n return gzh(d, opts), wbytes(d, s - 8, c.d()), wbytes(d, s - 4, l), d;\n}\n/**\n * Streaming GZIP decompression\n */\nvar Gunzip = /*#__PURE__*/ (function () {\n /**\n * Creates a GUNZIP stream\n * @param cb The callback to call whenever data is inflated\n */\n function Gunzip(cb) {\n this.v = 1;\n Inflate.call(this, cb);\n }\n /**\n * Pushes a chunk to be GUNZIPped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Gunzip.prototype.push = function (chunk, final) {\n Inflate.prototype.e.call(this, chunk);\n if (this.v) {\n var s = gzs(this.p);\n if (s >= this.p.length && !final)\n return;\n this.p = this.p.subarray(s), this.v = 0;\n }\n if (final) {\n if (this.p.length < 8)\n throw 'invalid gzip stream';\n this.p = this.p.subarray(0, -8);\n }\n // necessary to prevent TS from using the closure value\n // This allows for workerization to function correctly\n Inflate.prototype.c.call(this, final);\n };\n return Gunzip;\n}());\nexport { Gunzip };\n/**\n * Asynchronous streaming GZIP decompression\n */\nvar AsyncGunzip = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous GUNZIP stream\n * @param cb The callback to call whenever data is deflated\n */\n function AsyncGunzip(cb) {\n this.ondata = cb;\n astrmify([\n bInflt,\n guze,\n function () { return [astrm, Inflate, Gunzip]; }\n ], this, 0, function () {\n var strm = new Gunzip();\n onmessage = astrm(strm);\n }, 9);\n }\n return AsyncGunzip;\n}());\nexport { AsyncGunzip };\nexport function gunzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return cbify(data, opts, [\n bInflt,\n guze,\n function () { return [gunzipSync]; }\n ], function (ev) { return pbf(gunzipSync(ev.data[0])); }, 3, cb);\n}\n/**\n * Expands GZIP data\n * @param data The data to decompress\n * @param out Where to write the data. GZIP already encodes the output size, so providing this doesn't save memory.\n * @returns The decompressed version of the data\n */\nexport function gunzipSync(data, out) {\n return inflt(data.subarray(gzs(data), -8), out || new u8(gzl(data)));\n}\n/**\n * Streaming Zlib compression\n */\nvar Zlib = /*#__PURE__*/ (function () {\n function Zlib(opts, cb) {\n this.c = adler();\n this.v = 1;\n Deflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be zlibbed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Zlib.prototype.push = function (chunk, final) {\n Deflate.prototype.push.call(this, chunk, final);\n };\n Zlib.prototype.p = function (c, f) {\n this.c.p(c);\n var raw = dopt(c, this.o, this.v && 2, f && 4, !f);\n if (this.v)\n zlh(raw, this.o), this.v = 0;\n if (f)\n wbytes(raw, raw.length - 4, this.c.d());\n this.ondata(raw, f);\n };\n return Zlib;\n}());\nexport { Zlib };\n/**\n * Asynchronous streaming Zlib compression\n */\nvar AsyncZlib = /*#__PURE__*/ (function () {\n function AsyncZlib(opts, cb) {\n astrmify([\n bDflt,\n zle,\n function () { return [astrm, Deflate, Zlib]; }\n ], this, AsyncCmpStrm.call(this, opts, cb), function (ev) {\n var strm = new Zlib(ev.data);\n onmessage = astrm(strm);\n }, 10);\n }\n return AsyncZlib;\n}());\nexport { AsyncZlib };\nexport function zlib(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return cbify(data, opts, [\n bDflt,\n zle,\n function () { return [zlibSync]; }\n ], function (ev) { return pbf(zlibSync(ev.data[0], ev.data[1])); }, 4, cb);\n}\n/**\n * Compress data with Zlib\n * @param data The data to compress\n * @param opts The compression options\n * @returns The zlib-compressed version of the data\n */\nexport function zlibSync(data, opts) {\n if (opts === void 0) { opts = {}; }\n var a = adler();\n a.p(data);\n var d = dopt(data, opts, 2, 4);\n return zlh(d, opts), wbytes(d, d.length - 4, a.d()), d;\n}\n/**\n * Streaming Zlib decompression\n */\nvar Unzlib = /*#__PURE__*/ (function () {\n /**\n * Creates a Zlib decompression stream\n * @param cb The callback to call whenever data is inflated\n */\n function Unzlib(cb) {\n this.v = 1;\n Inflate.call(this, cb);\n }\n /**\n * Pushes a chunk to be unzlibbed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Unzlib.prototype.push = function (chunk, final) {\n Inflate.prototype.e.call(this, chunk);\n if (this.v) {\n if (this.p.length < 2 && !final)\n return;\n this.p = this.p.subarray(2), this.v = 0;\n }\n if (final) {\n if (this.p.length < 4)\n throw 'invalid zlib stream';\n this.p = this.p.subarray(0, -4);\n }\n // necessary to prevent TS from using the closure value\n // This allows for workerization to function correctly\n Inflate.prototype.c.call(this, final);\n };\n return Unzlib;\n}());\nexport { Unzlib };\n/**\n * Asynchronous streaming Zlib decompression\n */\nvar AsyncUnzlib = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous Zlib decompression stream\n * @param cb The callback to call whenever data is deflated\n */\n function AsyncUnzlib(cb) {\n this.ondata = cb;\n astrmify([\n bInflt,\n zule,\n function () { return [astrm, Inflate, Unzlib]; }\n ], this, 0, function () {\n var strm = new Unzlib();\n onmessage = astrm(strm);\n }, 11);\n }\n return AsyncUnzlib;\n}());\nexport { AsyncUnzlib };\nexport function unzlib(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return cbify(data, opts, [\n bInflt,\n zule,\n function () { return [unzlibSync]; }\n ], function (ev) { return pbf(unzlibSync(ev.data[0], gu8(ev.data[1]))); }, 5, cb);\n}\n/**\n * Expands Zlib data\n * @param data The data to decompress\n * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.\n * @returns The decompressed version of the data\n */\nexport function unzlibSync(data, out) {\n return inflt((zlv(data), data.subarray(2, -4)), out);\n}\n// Default algorithm for compression (used because having a known output size allows faster decompression)\nexport { gzip as compress, AsyncGzip as AsyncCompress };\n// Default algorithm for compression (used because having a known output size allows faster decompression)\nexport { gzipSync as compressSync, Gzip as Compress };\n/**\n * Streaming GZIP, Zlib, or raw DEFLATE decompression\n */\nvar Decompress = /*#__PURE__*/ (function () {\n /**\n * Creates a decompression stream\n * @param cb The callback to call whenever data is decompressed\n */\n function Decompress(cb) {\n this.G = Gunzip;\n this.I = Inflate;\n this.Z = Unzlib;\n this.ondata = cb;\n }\n /**\n * Pushes a chunk to be decompressed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Decompress.prototype.push = function (chunk, final) {\n if (!this.ondata)\n throw 'no stream handler';\n if (!this.s) {\n if (this.p && this.p.length) {\n var n = new u8(this.p.length + chunk.length);\n n.set(this.p), n.set(chunk, this.p.length);\n }\n else\n this.p = chunk;\n if (this.p.length > 2) {\n var _this_1 = this;\n var cb = function () { _this_1.ondata.apply(_this_1, arguments); };\n this.s = (this.p[0] == 31 && this.p[1] == 139 && this.p[2] == 8)\n ? new this.G(cb)\n : ((this.p[0] & 15) != 8 || (this.p[0] >> 4) > 7 || ((this.p[0] << 8 | this.p[1]) % 31))\n ? new this.I(cb)\n : new this.Z(cb);\n this.s.push(this.p, final);\n this.p = null;\n }\n }\n else\n this.s.push(chunk, final);\n };\n return Decompress;\n}());\nexport { Decompress };\n/**\n * Asynchronous streaming GZIP, Zlib, or raw DEFLATE decompression\n */\nvar AsyncDecompress = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous decompression stream\n * @param cb The callback to call whenever data is decompressed\n */\n function AsyncDecompress(cb) {\n this.G = AsyncGunzip;\n this.I = AsyncInflate;\n this.Z = AsyncUnzlib;\n this.ondata = cb;\n }\n /**\n * Pushes a chunk to be decompressed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n AsyncDecompress.prototype.push = function (chunk, final) {\n Decompress.prototype.push.call(this, chunk, final);\n };\n return AsyncDecompress;\n}());\nexport { AsyncDecompress };\nexport function decompress(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return (data[0] == 31 && data[1] == 139 && data[2] == 8)\n ? gunzip(data, opts, cb)\n : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31))\n ? inflate(data, opts, cb)\n : unzlib(data, opts, cb);\n}\n/**\n * Expands compressed GZIP, Zlib, or raw DEFLATE data, automatically detecting the format\n * @param data The data to decompress\n * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.\n * @returns The decompressed version of the data\n */\nexport function decompressSync(data, out) {\n return (data[0] == 31 && data[1] == 139 && data[2] == 8)\n ? gunzipSync(data, out)\n : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31))\n ? inflateSync(data, out)\n : unzlibSync(data, out);\n}\n// flatten a directory structure\nvar fltn = function (d, p, t, o) {\n for (var k in d) {\n var val = d[k], n = p + k;\n if (val instanceof u8)\n t[n] = [val, o];\n else if (Array.isArray(val))\n t[n] = [val[0], mrg(o, val[1])];\n else\n fltn(val, n + '/', t, o);\n }\n};\n/**\n * Converts a string into a Uint8Array for use with compression/decompression methods\n * @param str The string to encode\n * @param latin1 Whether or not to interpret the data as Latin-1. This should\n * not need to be true unless decoding a binary string.\n * @returns The string encoded in UTF-8/Latin-1 binary\n */\nexport function strToU8(str, latin1) {\n var l = str.length;\n if (!latin1 && typeof TextEncoder != 'undefined')\n return new TextEncoder().encode(str);\n var ar = new u8(str.length + (str.length >>> 1));\n var ai = 0;\n var w = function (v) { ar[ai++] = v; };\n for (var i = 0; i < l; ++i) {\n if (ai + 5 > ar.length) {\n var n = new u8(ai + 8 + ((l - i) << 1));\n n.set(ar);\n ar = n;\n }\n var c = str.charCodeAt(i);\n if (c < 128 || latin1)\n w(c);\n else if (c < 2048)\n w(192 | (c >>> 6)), w(128 | (c & 63));\n else if (c > 55295 && c < 57344)\n c = 65536 + (c & 1023 << 10) | (str.charCodeAt(++i) & 1023),\n w(240 | (c >>> 18)), w(128 | ((c >>> 12) & 63)), w(128 | ((c >>> 6) & 63)), w(128 | (c & 63));\n else\n w(224 | (c >>> 12)), w(128 | ((c >>> 6) & 63)), w(128 | (c & 63));\n }\n return slc(ar, 0, ai);\n}\n/**\n * Converts a Uint8Array to a string\n * @param dat The data to decode to string\n * @param latin1 Whether or not to interpret the data as Latin-1. This should\n * not need to be true unless encoding to binary string.\n * @returns The original UTF-8/Latin-1 string\n */\nexport function strFromU8(dat, latin1) {\n var r = '';\n if (!latin1 && typeof TextDecoder != 'undefined')\n return new TextDecoder().decode(dat);\n for (var i = 0; i < dat.length;) {\n var c = dat[i++];\n if (c < 128 || latin1)\n r += String.fromCharCode(c);\n else if (c < 224)\n r += String.fromCharCode((c & 31) << 6 | (dat[i++] & 63));\n else if (c < 240)\n r += String.fromCharCode((c & 15) << 12 | (dat[i++] & 63) << 6 | (dat[i++] & 63));\n else\n c = ((c & 15) << 18 | (dat[i++] & 63) << 12 | (dat[i++] & 63) << 6 | (dat[i++] & 63)) - 65536,\n r += String.fromCharCode(55296 | (c >> 10), 56320 | (c & 1023));\n }\n return r;\n}\n;\n// skip local zip header\nvar slzh = function (d, b) { return b + 30 + b2(d, b + 26) + b2(d, b + 28); };\n// read zip header\nvar zh = function (d, b, z) {\n var fnl = b2(d, b + 28), fn = strFromU8(d.subarray(b + 46, b + 46 + fnl), !(b2(d, b + 8) & 2048)), es = b + 46 + fnl;\n var _a = z ? z64e(d, es) : [b4(d, b + 20), b4(d, b + 24), b4(d, b + 42)], sc = _a[0], su = _a[1], off = _a[2];\n return [b2(d, b + 10), sc, su, fn, es + b2(d, b + 30) + b2(d, b + 32), off];\n};\n// read zip64 extra field\nvar z64e = function (d, b) {\n for (; b2(d, b) != 1; b += 4 + b2(d, b + 2))\n ;\n return [b4(d, b + 12), b4(d, b + 4), b4(d, b + 20)];\n};\n// write zip header\nvar wzh = function (d, b, c, cmp, su, fn, u, o, ce, t) {\n var fl = fn.length, l = cmp.length;\n wbytes(d, b, ce != null ? 0x2014B50 : 0x4034B50), b += 4;\n if (ce != null)\n d[b] = 20, b += 2;\n d[b] = 20, b += 2; // spec compliance? what's that?\n d[b++] = (t == 8 && (o.level == 1 ? 6 : o.level < 6 ? 4 : o.level == 9 ? 2 : 0)), d[b++] = u && 8;\n d[b] = t, b += 2;\n var dt = new Date(o.mtime || Date.now()), y = dt.getFullYear() - 1980;\n if (y < 0 || y > 119)\n throw 'date not in range 1980-2099';\n wbytes(d, b, ((y << 24) * 2) | ((dt.getMonth() + 1) << 21) | (dt.getDate() << 16) | (dt.getHours() << 11) | (dt.getMinutes() << 5) | (dt.getSeconds() >>> 1));\n b += 4;\n wbytes(d, b, c);\n wbytes(d, b + 4, l);\n wbytes(d, b + 8, su);\n wbytes(d, b + 12, fl), b += 16; // skip extra field, comment\n if (ce != null)\n wbytes(d, b += 10, ce), b += 4;\n d.set(fn, b);\n b += fl;\n if (ce == null)\n d.set(cmp, b);\n};\n// write zip footer (end of central directory)\nvar wzf = function (o, b, c, d, e) {\n wbytes(o, b, 0x6054B50); // skip disk\n wbytes(o, b + 8, c);\n wbytes(o, b + 10, c);\n wbytes(o, b + 12, d);\n wbytes(o, b + 16, e);\n};\nexport function zip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n var r = {};\n fltn(data, '', r, opts);\n var k = Object.keys(r);\n var lft = k.length, o = 0, tot = 0;\n var slft = lft, files = new Array(lft);\n var term = [];\n var tAll = function () {\n for (var i = 0; i < term.length; ++i)\n term[i]();\n };\n var cbf = function () {\n var out = new u8(tot + 22), oe = o, cdl = tot - o;\n tot = 0;\n for (var i = 0; i < slft; ++i) {\n var f = files[i];\n try {\n wzh(out, tot, f.c, f.d, f.m, f.n, f.u, f.p, null, f.t);\n wzh(out, o, f.c, f.d, f.m, f.n, f.u, f.p, tot, f.t), o += 46 + f.n.length, tot += 30 + f.n.length + f.d.length;\n }\n catch (e) {\n return cb(e, null);\n }\n }\n wzf(out, o, files.length, cdl, oe);\n cb(null, out);\n };\n if (!lft)\n cbf();\n var _loop_1 = function (i) {\n var fn = k[i];\n var _a = r[fn], file = _a[0], p = _a[1];\n var c = crc(), m = file.length;\n c.p(file);\n var n = strToU8(fn), s = n.length;\n var t = p.level == 0 ? 0 : 8;\n var cbl = function (e, d) {\n if (e) {\n tAll();\n cb(e, null);\n }\n else {\n var l = d.length;\n files[i] = {\n t: t,\n d: d,\n m: m,\n c: c.d(),\n u: fn.length != l,\n n: n,\n p: p\n };\n o += 30 + s + l;\n tot += 76 + 2 * s + l;\n if (!--lft)\n cbf();\n }\n };\n if (n.length > 65535)\n cbl('filename too long', null);\n if (!t)\n cbl(null, file);\n else if (m < 160000) {\n try {\n cbl(null, deflateSync(file, p));\n }\n catch (e) {\n cbl(e, null);\n }\n }\n else\n term.push(deflate(file, p, cbl));\n };\n // Cannot use lft because it can decrease\n for (var i = 0; i < slft; ++i) {\n _loop_1(i);\n }\n return tAll;\n}\n/**\n * Synchronously creates a ZIP file. Prefer using `zip` for better performance\n * with more than one file.\n * @param data The directory structure for the ZIP archive\n * @param opts The main options, merged with per-file options\n * @returns The generated ZIP archive\n */\nexport function zipSync(data, opts) {\n if (opts === void 0) { opts = {}; }\n var r = {};\n var files = [];\n fltn(data, '', r, opts);\n var o = 0;\n var tot = 0;\n for (var fn in r) {\n var _a = r[fn], file = _a[0], p = _a[1];\n var t = p.level == 0 ? 0 : 8;\n var n = strToU8(fn), s = n.length;\n if (n.length > 65535)\n throw 'filename too long';\n var d = t ? deflateSync(file, p) : file, l = d.length;\n var c = crc();\n c.p(file);\n files.push({\n t: t,\n d: d,\n m: file.length,\n c: c.d(),\n u: fn.length != s,\n n: n,\n o: o,\n p: p\n });\n o += 30 + s + l;\n tot += 76 + 2 * s + l;\n }\n var out = new u8(tot + 22), oe = o, cdl = tot - o;\n for (var i = 0; i < files.length; ++i) {\n var f = files[i];\n wzh(out, f.o, f.c, f.d, f.m, f.n, f.u, f.p, null, f.t);\n wzh(out, o, f.c, f.d, f.m, f.n, f.u, f.p, f.o, f.t), o += 46 + f.n.length;\n }\n wzf(out, o, files.length, cdl, oe);\n return out;\n}\n/**\n * Asynchronously decompresses a ZIP archive\n * @param data The raw compressed ZIP file\n * @param cb The callback to call with the decompressed files\n * @returns A function that can be used to immediately terminate the unzipping\n */\nexport function unzip(data, cb) {\n if (typeof cb != 'function')\n throw 'no callback';\n var term = [];\n var tAll = function () {\n for (var i = 0; i < term.length; ++i)\n term[i]();\n };\n var files = {};\n var e = data.length - 22;\n for (; b4(data, e) != 0x6054B50; --e) {\n if (!e || data.length - e > 65558) {\n cb('invalid zip file', null);\n return;\n }\n }\n ;\n var lft = b2(data, e + 8);\n if (!lft)\n cb(null, {});\n var c = lft;\n var o = b4(data, e + 16);\n var z = o == 4294967295;\n if (z) {\n e = b4(data, e - 12);\n if (b4(data, e) != 0x6064B50)\n throw 'invalid zip file';\n c = lft = b4(data, e + 32);\n o = b4(data, e + 48);\n }\n var _loop_2 = function (i) {\n var _a = zh(data, o, z), c_1 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off);\n o = no;\n var cbl = function (e, d) {\n if (e) {\n tAll();\n cb(e, null);\n }\n else {\n files[fn] = d;\n if (!--lft)\n cb(null, files);\n }\n };\n if (!c_1)\n cbl(null, slc(data, b, b + sc));\n else if (c_1 == 8) {\n var infl = data.subarray(b, b + sc);\n if (sc < 320000) {\n try {\n cbl(null, inflateSync(infl, new u8(su)));\n }\n catch (e) {\n cbl(e, null);\n }\n }\n else\n term.push(inflate(infl, { size: su }, cbl));\n }\n else\n cbl('unknown compression type ' + c_1, null);\n };\n for (var i = 0; i < c; ++i) {\n _loop_2(i);\n }\n return tAll;\n}\n/**\n * Synchronously decompresses a ZIP archive. Prefer using `unzip` for better\n * performance with more than one file.\n * @param data The raw compressed ZIP file\n * @returns The decompressed files\n */\nexport function unzipSync(data) {\n var files = {};\n var e = data.length - 22;\n for (; b4(data, e) != 0x6054B50; --e) {\n if (!e || data.length - e > 65558)\n throw 'invalid zip file';\n }\n ;\n var c = b2(data, e + 8);\n if (!c)\n return {};\n var o = b4(data, e + 16);\n var z = o == 4294967295;\n if (z) {\n e = b4(data, e - 12);\n if (b4(data, e) != 0x6064B50)\n throw 'invalid zip file';\n c = b4(data, e + 32);\n o = b4(data, e + 48);\n }\n for (var i = 0; i < c; ++i) {\n var _a = zh(data, o, z), c_2 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off);\n o = no;\n if (!c_2)\n files[fn] = slc(data, b, b + sc);\n else if (c_2 == 8)\n files[fn] = inflateSync(data.subarray(b, b + sc), new u8(su));\n else\n throw 'unknown compression type ' + c_2;\n }\n return files;\n}\n","import { isNull } from '@posthog/core'\n\nexport function _base64Encode(data: null): null\nexport function _base64Encode(data: undefined): undefined\nexport function _base64Encode(data: string): string\nexport function _base64Encode(data: string | null | undefined): string | null | undefined {\n const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='\n let o1,\n o2,\n o3,\n h1,\n h2,\n h3,\n h4,\n bits,\n i = 0,\n ac = 0,\n enc = ''\n const tmp_arr: string[] = []\n\n if (!data) {\n return data\n }\n\n data = utf8Encode(data)\n\n do {\n // pack three octets into four hexets\n o1 = data.charCodeAt(i++)\n o2 = data.charCodeAt(i++)\n o3 = data.charCodeAt(i++)\n\n bits = (o1 << 16) | (o2 << 8) | o3\n\n h1 = (bits >> 18) & 0x3f\n h2 = (bits >> 12) & 0x3f\n h3 = (bits >> 6) & 0x3f\n h4 = bits & 0x3f\n\n // use hexets to index into b64, and append result to encoded string\n tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4)\n } while (i < data.length)\n\n enc = tmp_arr.join('')\n\n switch (data.length % 3) {\n case 1:\n enc = enc.slice(0, -2) + '=='\n break\n case 2:\n enc = enc.slice(0, -1) + '='\n break\n }\n\n return enc\n}\n\nexport const utf8Encode = function (string: string): string {\n string = (string + '').replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n')\n\n let utftext = '',\n start,\n end\n let stringl = 0,\n n\n\n start = end = 0\n stringl = string.length\n\n for (n = 0; n < stringl; n++) {\n const c1 = string.charCodeAt(n)\n let enc = null\n\n if (c1 < 128) {\n end++\n } else if (c1 > 127 && c1 < 2048) {\n enc = String.fromCharCode((c1 >> 6) | 192, (c1 & 63) | 128)\n } else {\n enc = String.fromCharCode((c1 >> 12) | 224, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128)\n }\n if (!isNull(enc)) {\n if (end > start) {\n utftext += string.substring(start, end)\n }\n utftext += enc\n start = end = n + 1\n }\n }\n\n if (end > start) {\n utftext += string.substring(start, string.length)\n }\n\n return utftext\n}\n","import { each, find } from './utils'\nimport Config from './config'\nimport { Compression, RequestWithOptions, RequestResponse } from './types'\nimport { formDataToQuery } from './utils/request-utils'\n\nimport { logger } from './utils/logger'\nimport { AbortController, fetch, navigator, XMLHttpRequest } from './utils/globals'\nimport { gzipSync, strToU8 } from 'fflate'\n\nimport { _base64Encode } from './utils/encode-utils'\n\n// eslint-disable-next-line compat/compat\nexport const SUPPORTS_REQUEST = !!XMLHttpRequest || !!fetch\n\nconst CONTENT_TYPE_PLAIN = 'text/plain'\nconst CONTENT_TYPE_JSON = 'application/json'\nconst CONTENT_TYPE_FORM = 'application/x-www-form-urlencoded'\nconst SIXTY_FOUR_KILOBYTES = 64 * 1024\n/*\n fetch will fail if we request keepalive with a body greater than 64kb\n sets the threshold lower than that so that\n any overhead doesn't push over the threshold after checking here\n*/\nconst KEEP_ALIVE_THRESHOLD = SIXTY_FOUR_KILOBYTES * 0.8\ntype EncodedBody = {\n contentType: string\n body: string | BlobPart\n estimatedSize: number\n}\n\n/**\n * Extends a URL with additional query parameters\n * @param url - The URL to extend\n * @param params - The parameters to add\n * @param replace - When true (default), new params overwrite existing ones with same key. When false, existing params are preserved.\n * @returns The URL with extended parameters\n */\nexport const extendURLParams = (url: string, params: Record<string, any>, replace: boolean = true): string => {\n const [baseUrl, search] = url.split('?')\n const newParams = { ...params }\n\n const updatedSearch =\n search?.split('&').map((pair) => {\n const [key, origValue] = pair.split('=')\n const value = replace ? (newParams[key] ?? origValue) : origValue\n delete newParams[key]\n return `${key}=${value}`\n }) ?? []\n\n const remaining = formDataToQuery(newParams)\n if (remaining) {\n updatedSearch.push(remaining)\n }\n\n return `${baseUrl}?${updatedSearch.join('&')}`\n}\n\nexport const jsonStringify = (data: any, space?: string | number): string => {\n // With plain JSON.stringify, we get an exception when a property is a BigInt. This has caused problems for some users,\n // see https://github.com/PostHog/posthog-js/issues/1440\n // To work around this, we convert BigInts to strings before stringifying the data. This is not ideal, as we lose\n // information that this was originally a number, but given ClickHouse doesn't support BigInts, the customer\n // would not be able to operate on these numerically anyway.\n return JSON.stringify(data, (_, value) => (typeof value === 'bigint' ? value.toString() : value), space)\n}\n\nconst encodeToDataString = (data: string | Record<string, any>): string => {\n return 'data=' + encodeURIComponent(typeof data === 'string' ? data : jsonStringify(data))\n}\n\nconst encodePostData = ({ data, compression }: RequestWithOptions): EncodedBody | undefined => {\n if (!data) {\n return\n }\n\n if (compression === Compression.GZipJS) {\n const gzipData = gzipSync(strToU8(jsonStringify(data)), { mtime: 0 })\n const blob = new Blob([gzipData], { type: CONTENT_TYPE_PLAIN })\n return {\n contentType: CONTENT_TYPE_PLAIN,\n body: blob,\n estimatedSize: blob.size,\n }\n }\n\n if (compression === Compression.Base64) {\n const b64data = _base64Encode(jsonStringify(data))\n const encodedBody = encodeToDataString(b64data)\n\n return {\n contentType: CONTENT_TYPE_FORM,\n body: encodedBody,\n estimatedSize: new Blob([encodedBody]).size,\n }\n }\n\n const jsonBody = jsonStringify(data)\n return {\n contentType: CONTENT_TYPE_JSON,\n body: jsonBody,\n estimatedSize: new Blob([jsonBody]).size,\n }\n}\n\nconst xhr = (options: RequestWithOptions) => {\n const req = new XMLHttpRequest!()\n req.open(options.method || 'GET', options.url, true)\n const { contentType, body } = encodePostData(options) ?? {}\n\n each(options.headers, function (headerValue, headerName) {\n req.setRequestHeader(headerName, headerValue)\n })\n\n if (contentType) {\n req.setRequestHeader('Content-Type', contentType)\n }\n\n if (options.timeout) {\n req.timeout = options.timeout\n }\n if (!options.disableXHRCredentials) {\n // send the ph_optout cookie\n // withCredentials cannot be modified until after calling .open on Android and Mobile Safari\n req.withCredentials = true\n }\n req.onreadystatechange = () => {\n // XMLHttpRequest.DONE == 4, except in safari 4\n if (req.readyState === 4) {\n const response: RequestResponse = {\n statusCode: req.status,\n text: req.responseText,\n }\n if (req.status === 200) {\n try {\n response.json = JSON.parse(req.responseText)\n } catch {\n // logger.error(e)\n }\n }\n\n options.callback?.(response)\n }\n }\n req.send(body)\n}\n\nconst _fetch = (options: RequestWithOptions) => {\n const { contentType, body, estimatedSize } = encodePostData(options) ?? {}\n\n // eslint-disable-next-line compat/compat\n const headers = new Headers()\n each(options.headers, function (headerValue, headerName) {\n headers.append(headerName, headerValue)\n })\n\n if (contentType) {\n headers.append('Content-Type', contentType)\n }\n\n const url = options.url\n let aborter: { signal: any; timeout: ReturnType<typeof setTimeout> } | null = null\n\n if (AbortController) {\n const controller = new AbortController()\n aborter = {\n signal: controller.signal,\n timeout: setTimeout(() => controller.abort(), options.timeout),\n }\n }\n\n fetch!(url, {\n method: options?.method || 'GET',\n headers,\n // if body is greater than 64kb, then fetch with keepalive will error\n // see 8:10:5 at https://fetch.spec.whatwg.org/#http-network-or-cache-fetch,\n // but we do want to set keepalive sometimes as it can help with success\n // when e.g. a page is being closed\n // so let's get the best of both worlds and only set keepalive for POST requests\n // where the body is less than 64kb\n // NB this is fetch keepalive and not http keepalive\n keepalive: options.method === 'POST' && (estimatedSize || 0) < KEEP_ALIVE_THRESHOLD,\n body,\n signal: aborter?.signal,\n ...options.fetchOptions,\n })\n .then((response) => {\n return response.text().then((responseText) => {\n const res: RequestResponse = {\n statusCode: response.status,\n text: responseText,\n }\n\n if (response.status === 200) {\n try {\n res.json = JSON.parse(responseText)\n } catch (e) {\n logger.error(e)\n }\n }\n\n options.callback?.(res)\n })\n })\n .catch((error) => {\n logger.error(error)\n options.callback?.({ statusCode: 0, text: error })\n })\n .finally(() => (aborter ? clearTimeout(aborter.timeout) : null))\n\n return\n}\n\nconst _sendBeacon = (options: RequestWithOptions) => {\n // beacon documentation https://w3c.github.io/beacon/\n // beacons format the message and use the type property\n\n const url = extendURLParams(options.url, {\n beacon: '1',\n })\n\n try {\n const { contentType, body } = encodePostData(options) ?? {}\n // sendBeacon requires a blob so we convert it\n const sendBeaconBody = typeof body === 'string' ? new Blob([body], { type: contentType }) : body\n navigator!.sendBeacon!(url, sendBeaconBody)\n } catch {\n // send beacon is a best-effort, fire-and-forget mechanism on page unload,\n // we don't want to throw errors here\n }\n}\n\nconst AVAILABLE_TRANSPORTS: {\n transport: RequestWithOptions['transport']\n method: (options: RequestWithOptions) => void\n}[] = []\n\n// We add the transports in order of preference\nif (fetch) {\n AVAILABLE_TRANSPORTS.push({\n transport: 'fetch',\n method: _fetch,\n })\n}\n\nif (XMLHttpRequest) {\n AVAILABLE_TRANSPORTS.push({\n transport: 'XHR',\n method: xhr,\n })\n}\n\nif (navigator?.sendBeacon) {\n AVAILABLE_TRANSPORTS.push({\n transport: 'sendBeacon',\n method: _sendBeacon,\n })\n}\n\n// This is the entrypoint. It takes care of sanitizing the options and then calls the appropriate request method.\nexport const request = (_options: RequestWithOptions) => {\n // Clone the options so we don't modify the original object\n const options = { ..._options }\n options.timeout = options.timeout || 60000\n\n options.url = extendURLParams(options.url, {\n _: new Date().getTime().toString(),\n ver: Config.LIB_VERSION,\n compression: options.compression,\n })\n\n const transport = options.transport ?? 'fetch'\n\n const availableTransports = AVAILABLE_TRANSPORTS.filter(\n (t) => !options.disableTransport || !t.transport || !options.disableTransport.includes(t.transport)\n )\n\n const transportMethod =\n find(availableTransports, (t) => t.transport === transport)?.method ?? availableTransports[0].method\n\n if (!transportMethod) {\n throw new Error('No available transport method')\n }\n\n transportMethod(options)\n}\n","export const isValidRegex = function (str: string): boolean {\n try {\n new RegExp(str)\n } catch {\n return false\n }\n return true\n}\n\nexport const isMatchingRegex = function (value: string, pattern: string): boolean {\n if (!isValidRegex(pattern)) return false\n\n try {\n return new RegExp(pattern).test(value)\n } catch {\n return false\n }\n}\n","import { isNull, isUndefined } from '@posthog/core'\nimport { jsonStringify } from '../request'\nimport { PropertyFilters, PropertyOperator } from '../posthog-surveys-types'\nimport type { Properties } from '../types'\nimport { isMatchingRegex } from './regex-utils'\n\nexport function getPersonPropertiesHash(\n distinct_id: string,\n userPropertiesToSet?: Properties,\n userPropertiesToSetOnce?: Properties\n): string {\n return jsonStringify({ distinct_id, userPropertiesToSet, userPropertiesToSetOnce })\n}\n\nexport const propertyComparisons: Record<PropertyOperator, (targets: string[], values: string[]) => boolean> = {\n exact: (targets, values) => values.some((value) => targets.some((target) => value === target)),\n is_not: (targets, values) => values.every((value) => targets.every((target) => value !== target)),\n regex: (targets, values) => values.some((value) => targets.some((target) => isMatchingRegex(value, target))),\n not_regex: (targets, values) => values.every((value) => targets.every((target) => !isMatchingRegex(value, target))),\n icontains: (targets, values) =>\n values.map(toLowerCase).some((value) => targets.map(toLowerCase).some((target) => value.includes(target))),\n not_icontains: (targets, values) =>\n values.map(toLowerCase).every((value) => targets.map(toLowerCase).every((target) => !value.includes(target))),\n gt: (targets, values) =>\n values.some((value) => {\n const numValue = parseFloat(value)\n return !isNaN(numValue) && targets.some((t) => numValue > parseFloat(t))\n }),\n lt: (targets, values) =>\n values.some((value) => {\n const numValue = parseFloat(value)\n return !isNaN(numValue) && targets.some((t) => numValue < parseFloat(t))\n }),\n}\n\nconst toLowerCase = (v: string): string => v.toLowerCase()\n\nexport function matchPropertyFilters(\n propertyFilters: PropertyFilters | undefined,\n eventProperties: Properties | undefined\n): boolean {\n // if there are no property filters, it means we're only matching on event name\n if (!propertyFilters) {\n return true\n }\n\n return Object.entries(propertyFilters).every(([propertyName, filter]) => {\n const eventPropertyValue = eventProperties?.[propertyName]\n\n if (isUndefined(eventPropertyValue) || isNull(eventPropertyValue)) {\n return false\n }\n\n // convert event property to string array for comparison\n const eventValues = [String(eventPropertyValue)]\n\n const comparisonFunction = propertyComparisons[filter.operator]\n if (!comparisonFunction) {\n return false\n }\n\n return comparisonFunction(filter.values, eventValues)\n })\n}\n","import { ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS, ERROR_TRACKING_SUPPRESSION_RULES } from './constants'\nimport { PostHog } from './posthog-core'\nimport { CaptureResult, ErrorTrackingSuppressionRule, Properties, RemoteConfig } from './types'\nimport { createLogger } from './utils/logger'\nimport { propertyComparisons } from './utils/property-utils'\nimport { isString, isArray, ErrorTracking, isNullish } from '@posthog/core'\n\nconst logger = createLogger('[Error tracking]')\n\nexport function buildErrorPropertiesBuilder() {\n return new ErrorTracking.ErrorPropertiesBuilder(\n [\n new ErrorTracking.DOMExceptionCoercer(),\n new ErrorTracking.PromiseRejectionEventCoercer(),\n new ErrorTracking.ErrorEventCoercer(),\n new ErrorTracking.ErrorCoercer(),\n new ErrorTracking.EventCoercer(),\n new ErrorTracking.ObjectCoercer(),\n new ErrorTracking.StringCoercer(),\n new ErrorTracking.PrimitiveCoercer(),\n ],\n ErrorTracking.createDefaultStackParser()\n )\n}\nexport class PostHogExceptions {\n private readonly _instance: PostHog\n private _suppressionRules: ErrorTrackingSuppressionRule[] = []\n private _errorPropertiesBuilder: ErrorTracking.ErrorPropertiesBuilder = buildErrorPropertiesBuilder()\n\n constructor(instance: PostHog) {\n this._instance = instance\n this._suppressionRules = this._instance.persistence?.get_property(ERROR_TRACKING_SUPPRESSION_RULES) ?? []\n }\n\n onRemoteConfig(response: RemoteConfig) {\n const suppressionRules = response.errorTracking?.suppressionRules ?? []\n const captureExtensionExceptions = response.errorTracking?.captureExtensionExceptions\n\n // store this in-memory in case persistence is disabled\n this._suppressionRules = suppressionRules\n\n if (this._instance.persistence) {\n this._instance.persistence.register({\n [ERROR_TRACKING_SUPPRESSION_RULES]: this._suppressionRules,\n [ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS]: captureExtensionExceptions,\n })\n }\n }\n\n private get _captureExtensionExceptions() {\n const enabled_server_side = !!this._instance.get_property(ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS)\n const enabled_client_side = this._instance.config.error_tracking.captureExtensionExceptions\n return enabled_client_side ?? enabled_server_side ?? false\n }\n\n buildProperties(\n input: unknown,\n metadata?: { handled?: boolean; syntheticException?: Error }\n ): ErrorTracking.ErrorProperties {\n return this._errorPropertiesBuilder.buildFromUnknown(input, {\n syntheticException: metadata?.syntheticException,\n mechanism: {\n handled: metadata?.handled,\n },\n })\n }\n\n sendExceptionEvent(properties: Properties): CaptureResult | undefined {\n const exceptionList = properties.$exception_list\n\n if (this._isExceptionList(exceptionList)) {\n if (this._matchesSuppressionRule(exceptionList)) {\n logger.info('Skipping exception capture because a suppression rule matched')\n return\n }\n\n if (!this._captureExtensionExceptions && this._isExtensionException(exceptionList)) {\n logger.info('Skipping exception capture because it was thrown by an extension')\n return\n }\n\n if (\n !this._instance.config.error_tracking.__capturePostHogExceptions &&\n this._isPostHogException(exceptionList)\n ) {\n logger.info('Skipping exception capture because it was thrown by the PostHog SDK')\n return\n }\n }\n\n return this._instance.capture('$exception', properties, {\n _noTruncate: true,\n _batchKey: 'exceptionEvent',\n })\n }\n\n private _matchesSuppressionRule(exceptionList: ErrorTracking.ExceptionList): boolean {\n if (exceptionList.length === 0) {\n return false\n }\n\n const exceptionValues = exceptionList.reduce(\n (acc, { type, value }) => {\n if (isString(type) && type.length > 0) {\n acc['$exception_types'].push(type)\n }\n if (isString(value) && value.length > 0) {\n acc['$exception_values'].push(value)\n }\n return acc\n },\n {\n $exception_types: [] as string[],\n $exception_values: [] as string[],\n }\n )\n\n return this._suppressionRules.some((rule) => {\n const results = rule.values.map((v) => {\n const compare = propertyComparisons[v.operator]\n const targets = isArray(v.value) ? v.value : [v.value]\n const values = exceptionValues[v.key] ?? []\n return targets.length > 0 ? compare(targets, values) : false\n })\n return rule.type === 'OR' ? results.some(Boolean) : results.every(Boolean)\n })\n }\n\n private _isExtensionException(exceptionList: ErrorTracking.ExceptionList): boolean {\n const frames = exceptionList.flatMap((e) => e.stacktrace?.frames ?? [])\n return frames.some((f) => f.filename && f.filename.startsWith('chrome-extension://'))\n }\n\n private _isPostHogException(exceptionList: ErrorTracking.ExceptionList): boolean {\n if (exceptionList.length > 0) {\n const exception = exceptionList[0]\n const frames = exception.stacktrace?.frames ?? []\n const lastFrame = frames[frames.length - 1]\n return lastFrame?.filename?.includes('posthog.com/static') ?? false\n }\n\n return false\n }\n\n private _isExceptionList(candidate: unknown): candidate is ErrorTracking.ExceptionList {\n return !isNullish(candidate) && isArray(candidate)\n }\n}\n","import { entries, extend } from './utils'\nimport { PostHog } from './posthog-core'\nimport {\n FlagsResponse,\n FeatureFlagsCallback,\n EarlyAccessFeatureCallback,\n EarlyAccessFeatureResponse,\n Properties,\n JsonType,\n Compression,\n EarlyAccessFeature,\n RemoteConfigFeatureFlagCallback,\n EarlyAccessFeatureStage,\n FeatureFlagDetail,\n} from './types'\nimport { PostHogPersistence } from './posthog-persistence'\n\nimport {\n PERSISTENCE_EARLY_ACCESS_FEATURES,\n PERSISTENCE_FEATURE_FLAG_DETAILS,\n ENABLED_FEATURE_FLAGS,\n STORED_GROUP_PROPERTIES_KEY,\n STORED_PERSON_PROPERTIES_KEY,\n FLAG_CALL_REPORTED,\n} from './constants'\n\nimport { isUndefined, isArray, isNull } from '@posthog/core'\nimport { createLogger } from './utils/logger'\nimport { getTimezone } from './utils/event-utils'\n\nconst logger = createLogger('[FeatureFlags]')\nconst forceDebugLogger = createLogger('[FeatureFlags]', { debugEnabled: true })\n\nconst PERSISTENCE_ACTIVE_FEATURE_FLAGS = '$active_feature_flags'\nconst PERSISTENCE_OVERRIDE_FEATURE_FLAGS = '$override_feature_flags'\nconst PERSISTENCE_FEATURE_FLAG_PAYLOADS = '$feature_flag_payloads'\nconst PERSISTENCE_OVERRIDE_FEATURE_FLAG_PAYLOADS = '$override_feature_flag_payloads'\nconst PERSISTENCE_FEATURE_FLAG_REQUEST_ID = '$feature_flag_request_id'\nconst PERSISTENCE_FEATURE_FLAG_EVALUATED_AT = '$feature_flag_evaluated_at'\n\nexport const filterActiveFeatureFlags = (featureFlags?: Record<string, string | boolean>) => {\n const activeFeatureFlags: Record<string, string | boolean> = {}\n for (const [key, value] of entries(featureFlags || {})) {\n if (value) {\n activeFeatureFlags[key] = value\n }\n }\n return activeFeatureFlags\n}\n\nexport const parseFlagsResponse = (\n response: Partial<FlagsResponse>,\n persistence: PostHogPersistence,\n currentFlags: Record<string, string | boolean> = {},\n currentFlagPayloads: Record<string, JsonType> = {},\n currentFlagDetails: Record<string, FeatureFlagDetail> = {}\n) => {\n const normalizedResponse = normalizeFlagsResponse(response)\n const flagDetails = normalizedResponse.flags\n const featureFlags = normalizedResponse.featureFlags\n const flagPayloads = normalizedResponse.featureFlagPayloads\n\n if (!featureFlags) {\n return // <-- This early return means we don't update anything, which is good.\n }\n\n const requestId = response['requestId']\n const evaluatedAt = response['evaluatedAt']\n\n // using the v1 api\n if (isArray(featureFlags)) {\n logger.warn('v1 of the feature flags endpoint is deprecated. Please use the latest version.')\n const $enabled_feature_flags: Record<string, boolean> = {}\n if (featureFlags) {\n for (let i = 0; i < featureFlags.length; i++) {\n $enabled_feature_flags[featureFlags[i]] = true\n }\n }\n persistence &&\n persistence.register({\n [PERSISTENCE_ACTIVE_FEATURE_FLAGS]: featureFlags,\n [ENABLED_FEATURE_FLAGS]: $enabled_feature_flags,\n })\n return\n }\n\n // using the v2+ api\n let newFeatureFlags = featureFlags\n let newFeatureFlagPayloads = flagPayloads\n let newFeatureFlagDetails = flagDetails\n if (response.errorsWhileComputingFlags) {\n // if not all flags were computed, we upsert flags instead of replacing them\n newFeatureFlags = { ...currentFlags, ...newFeatureFlags }\n newFeatureFlagPayloads = { ...currentFlagPayloads, ...newFeatureFlagPayloads }\n newFeatureFlagDetails = { ...currentFlagDetails, ...newFeatureFlagDetails }\n }\n\n persistence &&\n persistence.register({\n [PERSISTENCE_ACTIVE_FEATURE_FLAGS]: Object.keys(filterActiveFeatureFlags(newFeatureFlags)),\n [ENABLED_FEATURE_FLAGS]: newFeatureFlags || {},\n [PERSISTENCE_FEATURE_FLAG_PAYLOADS]: newFeatureFlagPayloads || {},\n [PERSISTENCE_FEATURE_FLAG_DETAILS]: newFeatureFlagDetails || {},\n ...(requestId ? { [PERSISTENCE_FEATURE_FLAG_REQUEST_ID]: requestId } : {}),\n ...(evaluatedAt ? { [PERSISTENCE_FEATURE_FLAG_EVALUATED_AT]: evaluatedAt } : {}),\n })\n}\n\nconst normalizeFlagsResponse = (response: Partial<FlagsResponse>): Partial<FlagsResponse> => {\n const flagDetails = response['flags']\n\n if (flagDetails) {\n // This is a v=4 request.\n\n // Map of flag keys to flag values: Record<string, string | boolean>\n response.featureFlags = Object.fromEntries(\n Object.keys(flagDetails).map((flag) => [flag, flagDetails[flag].variant ?? flagDetails[flag].enabled])\n )\n // Map of flag keys to flag payloads: Record<string, JsonType>\n response.featureFlagPayloads = Object.fromEntries(\n Object.keys(flagDetails)\n .filter((flag) => flagDetails[flag].enabled)\n .filter((flag) => flagDetails[flag].metadata?.payload)\n .map((flag) => [flag, flagDetails[flag].metadata?.payload])\n )\n } else {\n logger.warn(\n 'Using an older version of the feature flags endpoint. Please upgrade your PostHog server to the latest version'\n )\n }\n return response\n}\n\ntype FeatureFlagOverrides = {\n [flagName: string]: string | boolean\n}\n\ntype FeatureFlagPayloadOverrides = {\n [flagName: string]: JsonType\n}\n\ntype FeatureFlagOverrideOptions = {\n flags?: boolean | string[] | FeatureFlagOverrides\n payloads?: FeatureFlagPayloadOverrides\n suppressWarning?: boolean\n}\n\ntype OverrideFeatureFlagsOptions =\n | boolean // clear all overrides\n | string[] // enable list of flags\n | FeatureFlagOverrides // set variants directly\n | FeatureFlagOverrideOptions\n\nexport enum QuotaLimitedResource {\n FeatureFlags = 'feature_flags',\n Recordings = 'recordings',\n}\n\nexport class PostHogFeatureFlags {\n _override_warning: boolean = false\n featureFlagEventHandlers: FeatureFlagsCallback[]\n $anon_distinct_id: string | undefined\n private _hasLoadedFlags: boolean = false\n private _requestInFlight: boolean = false\n private _reloadingDisabled: boolean = false\n private _additionalReloadRequested: boolean = false\n private _reloadDebouncer?: any\n private _flagsCalled: boolean = false\n private _flagsLoadedFromRemote: boolean = false\n\n constructor(private _instance: PostHog) {\n this.featureFlagEventHandlers = []\n }\n\n private _getValidEvaluationEnvironments(): string[] {\n const envs = this._instance.config.evaluation_environments\n if (!envs?.length) {\n return []\n }\n\n return envs.filter((env) => {\n const isValid = env && typeof env === 'string' && env.trim().length > 0\n if (!isValid) {\n logger.error('Invalid evaluation environment found:', env, 'Expected non-empty string')\n }\n return isValid\n })\n }\n\n private _shouldIncludeEvaluationEnvironments(): boolean {\n return this._getValidEvaluationEnvironments().length > 0\n }\n\n flags(): void {\n if (this._instance.config.__preview_remote_config) {\n // If remote config is enabled we don't call /flags and we mark it as called so that we don't simulate it\n this._flagsCalled = true\n return\n }\n\n // TRICKY: We want to disable flags if we don't have a queued reload, and one of the settings exist for disabling on first load\n const disableFlags =\n !this._reloadDebouncer &&\n (this._instance.config.advanced_disable_feature_flags ||\n this._instance.config.advanced_disable_feature_flags_on_first_load)\n\n this._callFlagsEndpoint({\n disableFlags,\n })\n }\n\n get hasLoadedFlags(): boolean {\n return this._hasLoadedFlags\n }\n\n getFlags(): string[] {\n return Object.keys(this.getFlagVariants())\n }\n\n getFlagsWithDetails(): Record<string, FeatureFlagDetail> {\n const flagDetails = this._instance.get_property(PERSISTENCE_FEATURE_FLAG_DETAILS)\n\n const overridenFlags = this._instance.get_property(PERSISTENCE_OVERRIDE_FEATURE_FLAGS)\n const overriddenPayloads = this._instance.get_property(PERSISTENCE_OVERRIDE_FEATURE_FLAG_PAYLOADS)\n\n if (!overriddenPayloads && !overridenFlags) {\n return flagDetails || {}\n }\n\n const finalDetails = extend({}, flagDetails || {})\n const overriddenKeys = [\n ...new Set([...Object.keys(overriddenPayloads || {}), ...Object.keys(overridenFlags || {})]),\n ]\n for (const key of overriddenKeys) {\n const originalDetail = finalDetails[key]\n const overrideFlagValue = overridenFlags?.[key]\n\n const finalEnabled = isUndefined(overrideFlagValue)\n ? (originalDetail?.enabled ?? false)\n : !!overrideFlagValue\n\n const overrideVariant = isUndefined(overrideFlagValue)\n ? originalDetail.variant\n : typeof overrideFlagValue === 'string'\n ? overrideFlagValue\n : undefined\n\n const overridePayload = overriddenPayloads?.[key]\n\n const overridenDetail = {\n ...originalDetail,\n enabled: finalEnabled,\n // If the flag is not enabled, the variant should be undefined, even if the original has a variant value.\n variant: finalEnabled ? (overrideVariant ?? originalDetail?.variant) : undefined,\n }\n\n // Keep track of the original enabled and variant values so we can send them in the $feature_flag_called event.\n // This will be helpful for debugging and for understanding the impact of overrides.\n if (finalEnabled !== originalDetail?.enabled) {\n overridenDetail.original_enabled = originalDetail?.enabled\n }\n\n if (overrideVariant !== originalDetail?.variant) {\n overridenDetail.original_variant = originalDetail?.variant\n }\n\n if (overridePayload) {\n overridenDetail.metadata = {\n ...originalDetail?.metadata,\n payload: overridePayload,\n original_payload: originalDetail?.metadata?.payload,\n }\n }\n\n finalDetails[key] = overridenDetail\n }\n\n if (!this._override_warning) {\n logger.warn(' Overriding feature flag details!', {\n flagDetails,\n overriddenPayloads,\n finalDetails,\n })\n this._override_warning = true\n }\n return finalDetails\n }\n\n getFlagVariants(): Record<string, string | boolean> {\n const enabledFlags = this._instance.get_property(ENABLED_FEATURE_FLAGS)\n const overriddenFlags = this._instance.get_property(PERSISTENCE_OVERRIDE_FEATURE_FLAGS)\n if (!overriddenFlags) {\n return enabledFlags || {}\n }\n\n const finalFlags = extend({}, enabledFlags)\n const overriddenKeys = Object.keys(overriddenFlags)\n for (let i = 0; i < overriddenKeys.length; i++) {\n finalFlags[overriddenKeys[i]] = overriddenFlags[overriddenKeys[i]]\n }\n if (!this._override_warning) {\n logger.warn(' Overriding feature flags!', {\n enabledFlags,\n overriddenFlags,\n finalFlags,\n })\n this._override_warning = true\n }\n return finalFlags\n }\n\n getFlagPayloads(): Record<string, JsonType> {\n const flagPayloads = this._instance.get_property(PERSISTENCE_FEATURE_FLAG_PAYLOADS)\n const overriddenPayloads = this._instance.get_property(PERSISTENCE_OVERRIDE_FEATURE_FLAG_PAYLOADS)\n\n if (!overriddenPayloads) {\n return flagPayloads || {}\n }\n\n const finalPayloads = extend({}, flagPayloads || {})\n const overriddenKeys = Object.keys(overriddenPayloads)\n for (let i = 0; i < overriddenKeys.length; i++) {\n finalPayloads[overriddenKeys[i]] = overriddenPayloads[overriddenKeys[i]]\n }\n\n if (!this._override_warning) {\n logger.warn(' Overriding feature flag payloads!', {\n flagPayloads,\n overriddenPayloads,\n finalPayloads,\n })\n this._override_warning = true\n }\n return finalPayloads\n }\n\n /**\n * Reloads feature flags asynchronously.\n *\n * Constraints:\n *\n * 1. Avoid parallel requests\n * 2. Delay a few milliseconds after each reloadFeatureFlags call to batch subsequent changes together\n */\n reloadFeatureFlags(): void {\n if (this._reloadingDisabled || this._instance.config.advanced_disable_feature_flags) {\n // If reloading has been explicitly disabled then we don't want to do anything\n // Or if feature flags are disabled\n return\n }\n\n if (this._reloadDebouncer) {\n // If we're already in a debounce then we don't want to do anything\n return\n }\n\n // Debounce multiple calls on the same tick\n this._reloadDebouncer = setTimeout(() => {\n this._callFlagsEndpoint()\n }, 5)\n }\n\n private _clearDebouncer(): void {\n clearTimeout(this._reloadDebouncer)\n this._reloadDebouncer = undefined\n }\n\n ensureFlagsLoaded(): void {\n if (this._hasLoadedFlags || this._requestInFlight || this._reloadDebouncer) {\n // If we are or have already loaded the flags then we don't want to do anything\n return\n }\n\n this.reloadFeatureFlags()\n }\n\n setAnonymousDistinctId(anon_distinct_id: string): void {\n this.$anon_distinct_id = anon_distinct_id\n }\n\n setReloadingPaused(isPaused: boolean): void {\n this._reloadingDisabled = isPaused\n }\n\n /**\n * NOTE: This is used both for flags and remote config. Once the RemoteConfig is fully released this will essentially only\n * be for flags and can eventually be replaced with the new flags endpoint\n */\n _callFlagsEndpoint(options?: { disableFlags?: boolean }): void {\n // Ensure we don't have double queued /flags requests\n this._clearDebouncer()\n if (this._instance._shouldDisableFlags()) {\n // The way this is documented is essentially used to refuse to ever call the /flags endpoint.\n return\n }\n if (this._requestInFlight) {\n this._additionalReloadRequested = true\n return\n }\n const token = this._instance.config.token\n const deviceId = this._instance.get_property('$device_id')\n\n const data: Record<string, any> = {\n token: token,\n distinct_id: this._instance.get_distinct_id(),\n groups: this._instance.getGroups(),\n $anon_distinct_id: this.$anon_distinct_id,\n person_properties: {\n ...(this._instance.persistence?.get_initial_props() || {}),\n ...(this._instance.get_property(STORED_PERSON_PROPERTIES_KEY) || {}),\n },\n group_properties: this._instance.get_property(STORED_GROUP_PROPERTIES_KEY),\n }\n\n // Add device_id if available (handle cookieless mode where it's null)\n if (!isNull(deviceId) && !isUndefined(deviceId)) {\n data.$device_id = deviceId\n }\n\n if (options?.disableFlags || this._instance.config.advanced_disable_feature_flags) {\n data.disable_flags = true\n }\n\n // Add evaluation environments if configured\n if (this._shouldIncludeEvaluationEnvironments()) {\n data.evaluation_environments = this._getValidEvaluationEnvironments()\n }\n\n // flags supports loading config data with the `config` query param, but if you're using remote config, you\n // don't need to add that parameter because all the config data is loaded from the remote config endpoint.\n const useRemoteConfigWithFlags = this._instance.config.__preview_remote_config\n\n const flagsRoute = useRemoteConfigWithFlags ? '/flags/?v=2' : '/flags/?v=2&config=true'\n\n const queryParams = this._instance.config.advanced_only_evaluate_survey_feature_flags\n ? '&only_evaluate_survey_feature_flags=true'\n : ''\n\n const url = this._instance.requestRouter.endpointFor('flags', flagsRoute + queryParams)\n\n if (useRemoteConfigWithFlags) {\n data.timezone = getTimezone()\n }\n\n this._requestInFlight = true\n this._instance._send_request({\n method: 'POST',\n url,\n data,\n compression: this._instance.config.disable_compression ? undefined : Compression.Base64,\n timeout: this._instance.config.feature_flag_request_timeout_ms,\n callback: (response) => {\n let errorsLoading = true\n\n if (response.statusCode === 200) {\n // successful request\n // reset anon_distinct_id after at least a single request with it\n // makes it through\n if (!this._additionalReloadRequested) {\n this.$anon_distinct_id = undefined\n }\n errorsLoading = false\n }\n\n this._requestInFlight = false\n\n // NB: this block is only reached if this._instance.config.__preview_remote_config is false\n if (!this._flagsCalled) {\n this._flagsCalled = true\n this._instance._onRemoteConfig(response.json ?? {})\n }\n\n if (data.disable_flags && !this._additionalReloadRequested) {\n // If flags are disabled then there is no need to call /flags again (flags are the only thing that may change)\n // UNLESS, an additional reload is requested.\n return\n }\n\n this._flagsLoadedFromRemote = !errorsLoading\n\n if (response.json && response.json.quotaLimited?.includes(QuotaLimitedResource.FeatureFlags)) {\n // log a warning and then early return\n logger.warn(\n 'You have hit your feature flags quota limit, and will not be able to load feature flags until the quota is reset. Please visit https://posthog.com/docs/billing/limits-alerts to learn more.'\n )\n return\n }\n\n if (!data.disable_flags) {\n this.receivedFeatureFlags(response.json ?? {}, errorsLoading)\n }\n\n if (this._additionalReloadRequested) {\n this._additionalReloadRequested = false\n this._callFlagsEndpoint()\n }\n },\n })\n }\n\n /*\n * Get feature flag's value for user.\n *\n * ### Usage:\n *\n * if(posthog.getFeatureFlag('my-flag') === 'some-variant') { // do something }\n *\n * @param {Object|String} key Key of the feature flag.\n * @param {Object|String} options (optional) If {send_event: false}, we won't send an $feature_flag_called event to PostHog.\n */\n getFeatureFlag(key: string, options: { send_event?: boolean } = {}): boolean | string | undefined {\n if (!this._hasLoadedFlags && !(this.getFlags() && this.getFlags().length > 0)) {\n logger.warn('getFeatureFlag for key \"' + key + '\" failed. Feature flags didn\\'t load in time.')\n return undefined\n }\n const flagValue = this.getFlagVariants()[key]\n const flagReportValue = `${flagValue}`\n const requestId = this._instance.get_property(PERSISTENCE_FEATURE_FLAG_REQUEST_ID) || undefined\n const evaluatedAt = this._instance.get_property(PERSISTENCE_FEATURE_FLAG_EVALUATED_AT) || undefined\n const flagCallReported: Record<string, string[]> = this._instance.get_property(FLAG_CALL_REPORTED) || {}\n\n if (options.send_event || !('send_event' in options)) {\n if (!(key in flagCallReported) || !flagCallReported[key].includes(flagReportValue)) {\n if (isArray(flagCallReported[key])) {\n flagCallReported[key].push(flagReportValue)\n } else {\n flagCallReported[key] = [flagReportValue]\n }\n this._instance.persistence?.register({ [FLAG_CALL_REPORTED]: flagCallReported })\n\n const flagDetails = this.getFeatureFlagDetails(key)\n\n const properties: Record<string, any | undefined> = {\n $feature_flag: key,\n $feature_flag_response: flagValue,\n $feature_flag_payload: this.getFeatureFlagPayload(key) || null,\n $feature_flag_request_id: requestId,\n $feature_flag_evaluated_at: evaluatedAt,\n $feature_flag_bootstrapped_response: this._instance.config.bootstrap?.featureFlags?.[key] || null,\n $feature_flag_bootstrapped_payload:\n this._instance.config.bootstrap?.featureFlagPayloads?.[key] || null,\n // If we haven't yet received a response from the /flags endpoint, we must have used the bootstrapped value\n $used_bootstrap_value: !this._flagsLoadedFromRemote,\n }\n\n if (!isUndefined(flagDetails?.metadata?.version)) {\n properties.$feature_flag_version = flagDetails.metadata.version\n }\n\n const reason = flagDetails?.reason?.description ?? flagDetails?.reason?.code\n if (reason) {\n properties.$feature_flag_reason = reason\n }\n\n if (flagDetails?.metadata?.id) {\n properties.$feature_flag_id = flagDetails.metadata.id\n }\n\n // It's possible that flag values were overridden by calling overrideFeatureFlags.\n // We want to capture the original values in case someone forgets they were using overrides\n // and is wondering why their app is acting weird.\n if (!isUndefined(flagDetails?.original_variant) || !isUndefined(flagDetails?.original_enabled)) {\n properties.$feature_flag_original_response = !isUndefined(flagDetails.original_variant)\n ? flagDetails.original_variant\n : flagDetails.original_enabled\n }\n\n if (flagDetails?.metadata?.original_payload) {\n properties.$feature_flag_original_payload = flagDetails?.metadata?.original_payload\n }\n\n this._instance.capture('$feature_flag_called', properties)\n }\n }\n return flagValue\n }\n\n /*\n * Retrieves the details for a feature flag.\n *\n * ### Usage:\n *\n * const details = getFeatureFlagDetails(\"my-flag\")\n * console.log(details.metadata.version)\n * console.log(details.reason)\n *\n * @param {String} key Key of the feature flag.\n */\n getFeatureFlagDetails(key: string): FeatureFlagDetail | undefined {\n const details = this.getFlagsWithDetails()\n return details[key]\n }\n\n getFeatureFlagPayload(key: string): JsonType {\n const payloads = this.getFlagPayloads()\n return payloads[key]\n }\n\n /*\n * Fetches the payload for a remote config feature flag. This method will bypass any cached values and fetch the latest\n * value from the PostHog API.\n *\n * Note: Because the posthog-js SDK is primarily used with public project API keys, encrypted remote config payloads will\n * be redacted, never decrypted in the response.\n *\n * ### Usage:\n *\n * getRemoteConfigPayload(\"home-page-welcome-message\", (payload) => console.log(`Fetched remote config: ${payload}`))\n *\n * @param {String} key Key of the feature flag.\n * @param {Function} [callback] The callback function will be called once the remote config feature flag payload has been fetched.\n */\n getRemoteConfigPayload(key: string, callback: RemoteConfigFeatureFlagCallback): void {\n const token = this._instance.config.token\n const data: Record<string, any> = {\n distinct_id: this._instance.get_distinct_id(),\n token,\n }\n\n // Add evaluation environments if configured\n if (this._shouldIncludeEvaluationEnvironments()) {\n data.evaluation_environments = this._getValidEvaluationEnvironments()\n }\n\n this._instance._send_request({\n method: 'POST',\n url: this._instance.requestRouter.endpointFor('flags', '/flags/?v=2&config=true'),\n data,\n compression: this._instance.config.disable_compression ? undefined : Compression.Base64,\n timeout: this._instance.config.feature_flag_request_timeout_ms,\n callback: (response) => {\n const flagPayloads = response.json?.['featureFlagPayloads']\n callback(flagPayloads?.[key] || undefined)\n },\n })\n }\n\n /**\n * See if feature flag is enabled for user.\n *\n * ### Usage:\n *\n * if(posthog.isFeatureEnabled('beta-feature')) { // do something }\n *\n * @param key Key of the feature flag.\n * @param [options] If {send_event: false}, we won't send an $feature_flag_call event to PostHog.\n * @returns A boolean value indicating whether or not the specified feature flag is enabled. If flag information has not yet been loaded,\n * or if the specified feature flag is disabled or does not exist, returns undefined.\n */\n isFeatureEnabled(key: string, options: { send_event?: boolean } = {}): boolean | undefined {\n if (!this._hasLoadedFlags && !(this.getFlags() && this.getFlags().length > 0)) {\n logger.warn('isFeatureEnabled for key \"' + key + '\" failed. Feature flags didn\\'t load in time.')\n return undefined\n }\n const flagValue = this.getFeatureFlag(key, options)\n return isUndefined(flagValue) ? undefined : !!flagValue\n }\n\n addFeatureFlagsHandler(handler: FeatureFlagsCallback): void {\n this.featureFlagEventHandlers.push(handler)\n }\n\n removeFeatureFlagsHandler(handler: FeatureFlagsCallback): void {\n this.featureFlagEventHandlers = this.featureFlagEventHandlers.filter((h) => h !== handler)\n }\n\n receivedFeatureFlags(response: Partial<FlagsResponse>, errorsLoading?: boolean): void {\n if (!this._instance.persistence) {\n return\n }\n this._hasLoadedFlags = true\n\n const currentFlags = this.getFlagVariants()\n const currentFlagPayloads = this.getFlagPayloads()\n const currentFlagDetails = this.getFlagsWithDetails()\n parseFlagsResponse(response, this._instance.persistence, currentFlags, currentFlagPayloads, currentFlagDetails)\n this._fireFeatureFlagsCallbacks(errorsLoading)\n }\n\n /**\n * @deprecated Use overrideFeatureFlags instead. This will be removed in a future version.\n */\n override(flags: boolean | string[] | Record<string, string | boolean>, suppressWarning: boolean = false): void {\n logger.warn('override is deprecated. Please use overrideFeatureFlags instead.')\n this.overrideFeatureFlags({\n flags: flags,\n suppressWarning: suppressWarning,\n })\n }\n\n /**\n * Override feature flags on the client-side. Useful for setting non-persistent feature flags,\n * or for testing/debugging feature flags in the PostHog app.\n *\n * ### Usage:\n *\n * - posthog.featureFlags.overrideFeatureFlags(false) // clear all overrides\n * - posthog.featureFlags.overrideFeatureFlags(['beta-feature']) // enable flags\n * - posthog.featureFlags.overrideFeatureFlags({'beta-feature': 'variant'}) // set variants\n * - posthog.featureFlags.overrideFeatureFlags({ // set both flags and payloads\n * flags: {'beta-feature': 'variant'},\n * payloads: { 'beta-feature': { someData: true } }\n * })\n * - posthog.featureFlags.overrideFeatureFlags({ // only override payloads\n * payloads: { 'beta-feature': { someData: true } }\n * })\n */\n overrideFeatureFlags(overrideOptions: OverrideFeatureFlagsOptions): void {\n if (!this._instance.__loaded || !this._instance.persistence) {\n return logger.uninitializedWarning('posthog.featureFlags.overrideFeatureFlags')\n }\n\n // Clear all overrides if false, lets you do something like posthog.featureFlags.overrideFeatureFlags(false)\n if (overrideOptions === false) {\n this._instance.persistence.unregister(PERSISTENCE_OVERRIDE_FEATURE_FLAGS)\n this._instance.persistence.unregister(PERSISTENCE_OVERRIDE_FEATURE_FLAG_PAYLOADS)\n this._fireFeatureFlagsCallbacks()\n\n return forceDebugLogger.info('All overrides cleared')\n }\n\n if (\n overrideOptions &&\n typeof overrideOptions === 'object' &&\n ('flags' in overrideOptions || 'payloads' in overrideOptions)\n ) {\n const options = overrideOptions\n this._override_warning = Boolean(options.suppressWarning ?? false)\n\n // Handle flags if provided, lets you do something like posthog.featureFlags.overrideFeatureFlags({flags: ['beta-feature']})\n if ('flags' in options) {\n if (options.flags === false) {\n this._instance.persistence.unregister(PERSISTENCE_OVERRIDE_FEATURE_FLAGS)\n forceDebugLogger.info('Flag overrides cleared')\n } else if (options.flags) {\n if (isArray(options.flags)) {\n const flagsObj: Record<string, string | boolean> = {}\n for (let i = 0; i < options.flags.length; i++) {\n flagsObj[options.flags[i]] = true\n }\n this._instance.persistence.register({ [PERSISTENCE_OVERRIDE_FEATURE_FLAGS]: flagsObj })\n } else {\n this._instance.persistence.register({ [PERSISTENCE_OVERRIDE_FEATURE_FLAGS]: options.flags })\n }\n\n forceDebugLogger.info('Flag overrides set', { flags: options.flags })\n }\n }\n\n // Handle payloads independently, lets you do something like posthog.featureFlags.overrideFeatureFlags({payloads: { 'beta-feature': { someData: true } }})\n if ('payloads' in options) {\n if (options.payloads === false) {\n this._instance.persistence.unregister(PERSISTENCE_OVERRIDE_FEATURE_FLAG_PAYLOADS)\n forceDebugLogger.info('Payload overrides cleared')\n } else if (options.payloads) {\n this._instance.persistence.register({\n [PERSISTENCE_OVERRIDE_FEATURE_FLAG_PAYLOADS]: options.payloads,\n })\n forceDebugLogger.info('Payload overrides set', { payloads: options.payloads })\n }\n }\n\n this._fireFeatureFlagsCallbacks()\n return\n }\n\n this._fireFeatureFlagsCallbacks()\n }\n\n /*\n * Register an event listener that runs when feature flags become available or when they change.\n * If there are flags, the listener is called immediately in addition to being called on future changes.\n *\n * ### Usage:\n *\n * posthog.onFeatureFlags(function(featureFlags, featureFlagsVariants, { errorsLoading }) { // do something })\n *\n * @param {Function} [callback] The callback function will be called once the feature flags are ready or when they are updated.\n * It'll return a list of feature flags enabled for the user, the variants,\n * and also a context object indicating whether we succeeded to fetch the flags or not.\n * @returns {Function} A function that can be called to unsubscribe the listener. Used by useEffect when the component unmounts.\n */\n onFeatureFlags(callback: FeatureFlagsCallback): () => void {\n this.addFeatureFlagsHandler(callback)\n if (this._hasLoadedFlags) {\n const { flags, flagVariants } = this._prepareFeatureFlagsForCallbacks()\n callback(flags, flagVariants)\n }\n return () => this.removeFeatureFlagsHandler(callback)\n }\n\n updateEarlyAccessFeatureEnrollment(key: string, isEnrolled: boolean, stage?: string): void {\n const existing_early_access_features: EarlyAccessFeature[] =\n this._instance.get_property(PERSISTENCE_EARLY_ACCESS_FEATURES) || []\n const feature = existing_early_access_features.find((f) => f.flagKey === key)\n\n const enrollmentPersonProp = {\n [`$feature_enrollment/${key}`]: isEnrolled,\n }\n\n const properties: Properties = {\n $feature_flag: key,\n $feature_enrollment: isEnrolled,\n $set: enrollmentPersonProp,\n }\n\n if (feature) {\n properties['$early_access_feature_name'] = feature.name\n }\n\n if (stage) {\n properties['$feature_enrollment_stage'] = stage\n }\n\n this._instance.capture('$feature_enrollment_update', properties)\n this.setPersonPropertiesForFlags(enrollmentPersonProp, false)\n\n const newFlags = { ...this.getFlagVariants(), [key]: isEnrolled }\n this._instance.persistence?.register({\n [PERSISTENCE_ACTIVE_FEATURE_FLAGS]: Object.keys(filterActiveFeatureFlags(newFlags)),\n [ENABLED_FEATURE_FLAGS]: newFlags,\n })\n this._fireFeatureFlagsCallbacks()\n }\n\n getEarlyAccessFeatures(\n callback: EarlyAccessFeatureCallback,\n force_reload = false,\n stages?: EarlyAccessFeatureStage[]\n ): void {\n const existing_early_access_features = this._instance.get_property(PERSISTENCE_EARLY_ACCESS_FEATURES)\n\n const stageParams = stages ? `&${stages.map((s) => `stage=${s}`).join('&')}` : ''\n\n if (!existing_early_access_features || force_reload) {\n this._instance._send_request({\n url: this._instance.requestRouter.endpointFor(\n 'api',\n `/api/early_access_features/?token=${this._instance.config.token}${stageParams}`\n ),\n method: 'GET',\n callback: (response) => {\n if (!response.json) {\n return\n }\n const earlyAccessFeatures = (response.json as EarlyAccessFeatureResponse).earlyAccessFeatures\n // Unregister first to ensure complete replacement, not merge\n // This prevents accumulation of stale features in persistence\n this._instance.persistence?.unregister(PERSISTENCE_EARLY_ACCESS_FEATURES)\n this._instance.persistence?.register({ [PERSISTENCE_EARLY_ACCESS_FEATURES]: earlyAccessFeatures })\n return callback(earlyAccessFeatures)\n },\n })\n } else {\n return callback(existing_early_access_features)\n }\n }\n\n _prepareFeatureFlagsForCallbacks(): { flags: string[]; flagVariants: Record<string, string | boolean> } {\n const flags = this.getFlags()\n const flagVariants = this.getFlagVariants()\n\n // Return truthy\n const truthyFlags = flags.filter((flag) => flagVariants[flag])\n const truthyFlagVariants = Object.keys(flagVariants)\n .filter((variantKey) => flagVariants[variantKey])\n .reduce((res: Record<string, string | boolean>, key) => {\n res[key] = flagVariants[key]\n return res\n }, {})\n\n return {\n flags: truthyFlags,\n flagVariants: truthyFlagVariants,\n }\n }\n\n _fireFeatureFlagsCallbacks(errorsLoading?: boolean): void {\n const { flags, flagVariants } = this._prepareFeatureFlagsForCallbacks()\n this.featureFlagEventHandlers.forEach((handler) => handler(flags, flagVariants, { errorsLoading }))\n }\n\n /**\n * Set override person properties for feature flags.\n * This is used when dealing with new persons / where you don't want to wait for ingestion\n * to update user properties.\n */\n setPersonPropertiesForFlags(properties: Properties, reloadFeatureFlags = true): void {\n // Get persisted person properties\n const existingProperties = this._instance.get_property(STORED_PERSON_PROPERTIES_KEY) || {}\n\n this._instance.register({\n [STORED_PERSON_PROPERTIES_KEY]: {\n ...existingProperties,\n ...properties,\n },\n })\n\n if (reloadFeatureFlags) {\n this._instance.reloadFeatureFlags()\n }\n }\n\n resetPersonPropertiesForFlags(): void {\n this._instance.unregister(STORED_PERSON_PROPERTIES_KEY)\n }\n\n /**\n * Set override group properties for feature flags.\n * This is used when dealing with new groups / where you don't want to wait for ingestion\n * to update properties.\n * Takes in an object, the key of which is the group type.\n * For example:\n * setGroupPropertiesForFlags({'organization': { name: 'CYZ', employees: '11' } })\n */\n setGroupPropertiesForFlags(properties: { [type: string]: Properties }, reloadFeatureFlags = true): void {\n // Get persisted group properties\n const existingProperties = this._instance.get_property(STORED_GROUP_PROPERTIES_KEY) || {}\n\n if (Object.keys(existingProperties).length !== 0) {\n Object.keys(existingProperties).forEach((groupType) => {\n existingProperties[groupType] = {\n ...existingProperties[groupType],\n ...properties[groupType],\n }\n delete properties[groupType]\n })\n }\n\n this._instance.register({\n [STORED_GROUP_PROPERTIES_KEY]: {\n ...existingProperties,\n ...properties,\n },\n })\n\n if (reloadFeatureFlags) {\n this._instance.reloadFeatureFlags()\n }\n }\n\n resetGroupPropertiesForFlags(group_type?: string): void {\n if (group_type) {\n const existingProperties = this._instance.get_property(STORED_GROUP_PROPERTIES_KEY) || {}\n this._instance.register({\n [STORED_GROUP_PROPERTIES_KEY]: { ...existingProperties, [group_type]: {} },\n })\n } else {\n this._instance.unregister(STORED_GROUP_PROPERTIES_KEY)\n }\n }\n\n reset(): void {\n this._hasLoadedFlags = false\n this._requestInFlight = false\n this._reloadingDisabled = false\n this._additionalReloadRequested = false\n this._flagsCalled = false\n this._flagsLoadedFromRemote = false\n this.$anon_distinct_id = undefined\n this._clearDebouncer()\n this._override_warning = false\n }\n}\n","/* eslint camelcase: \"off\" */\n\nimport { each, extend, include, stripEmptyProperties } from './utils'\nimport { cookieStore, createLocalPlusCookieStore, localStore, memoryStore, sessionStore } from './storage'\nimport { PersistentStore, PostHogConfig, Properties } from './types'\nimport {\n ENABLED_FEATURE_FLAGS,\n EVENT_TIMERS_KEY,\n INITIAL_CAMPAIGN_PARAMS,\n INITIAL_PERSON_INFO,\n INITIAL_REFERRER_INFO,\n PERSISTENCE_RESERVED_PROPERTIES,\n} from './constants'\n\nimport { isUndefined } from '@posthog/core'\nimport {\n getCampaignParams,\n getInitialPersonPropsFromInfo,\n getPersonInfo,\n getReferrerInfo,\n getSearchInfo,\n} from './utils/event-utils'\nimport { logger } from './utils/logger'\nimport { stripLeadingDollar, isEmptyObject, isObject } from '@posthog/core'\n\nconst CASE_INSENSITIVE_PERSISTENCE_TYPES: readonly Lowercase<PostHogConfig['persistence']>[] = [\n 'cookie',\n 'localstorage',\n 'localstorage+cookie',\n 'sessionstorage',\n 'memory',\n]\n\nconst parseName = (config: PostHogConfig): string => {\n let token = ''\n if (config['token']) {\n token = config['token'].replace(/\\+/g, 'PL').replace(/\\//g, 'SL').replace(/=/g, 'EQ')\n }\n\n if (config['persistence_name']) {\n return 'ph_' + config['persistence_name']\n } else {\n return 'ph_' + token + '_posthog'\n }\n}\n\nconst isArrayContentsEqual = (arr1: readonly string[], arr2: readonly string[]): boolean => {\n if (arr1.length !== arr2.length) {\n return false\n }\n\n const sortedArr1 = [...arr1].sort()\n const sortedArr2 = [...arr2].sort()\n return sortedArr1.every((item, index) => item === sortedArr2[index])\n}\n\n/**\n * PostHog Persistence Object\n * @constructor\n */\nexport class PostHogPersistence {\n private _config: PostHogConfig\n props: Properties\n private _storage: PersistentStore\n private _campaign_params_saved: boolean\n private readonly _name: string\n _disabled: boolean | undefined\n private _secure: boolean | undefined\n private _expire_days: number | undefined\n private _default_expiry: number | undefined\n private _cross_subdomain: boolean | undefined\n\n /**\n * @param {PostHogConfig} config initial PostHog configuration\n * @param {boolean=} isDisabled should persistence be disabled (e.g. because of consent management)\n */\n constructor(config: PostHogConfig, isDisabled?: boolean) {\n this._config = config\n this.props = {}\n this._campaign_params_saved = false\n this._name = parseName(config)\n this._storage = this._buildStorage(config)\n this.load()\n if (config.debug) {\n logger.info('Persistence loaded', config['persistence'], { ...this.props })\n }\n this.update_config(config, config, isDisabled)\n this.save()\n }\n\n /**\n * Returns whether persistence is disabled. Only available in SDKs > 1.257.1. Do not use on extensions, otherwise\n * it'll break backwards compatibility for any version before 1.257.1.\n */\n public isDisabled?(): boolean {\n return !!this._disabled\n }\n\n private _buildStorage(config: PostHogConfig) {\n if (\n CASE_INSENSITIVE_PERSISTENCE_TYPES.indexOf(\n config['persistence'].toLowerCase() as Lowercase<PostHogConfig['persistence']>\n ) === -1\n ) {\n logger.critical(\n 'Unknown persistence type ' + config['persistence'] + '; falling back to localStorage+cookie'\n )\n config['persistence'] = 'localStorage+cookie'\n }\n\n // Create this before hand to avoid creating it multiple times\n // Creating it inside each individual condition below is too complicated and will break backwards compatibility\n // so create it once for this specific config and use it if necessary\n const localPlusCookieStore = createLocalPlusCookieStore(config['cookie_persisted_properties'] || [])\n\n let store: PersistentStore\n\n // We handle storage type in a case-insensitive way for backwards compatibility\n const storage_type = config['persistence'].toLowerCase() as Lowercase<PostHogConfig['persistence']>\n if (storage_type === 'localstorage' && localStore._is_supported()) {\n store = localStore\n } else if (storage_type === 'localstorage+cookie' && localPlusCookieStore._is_supported()) {\n store = localPlusCookieStore\n } else if (storage_type === 'sessionstorage' && sessionStore._is_supported()) {\n store = sessionStore\n } else if (storage_type === 'memory') {\n store = memoryStore\n } else if (storage_type === 'cookie') {\n store = cookieStore\n } else if (localPlusCookieStore._is_supported()) {\n // selected storage type wasn't supported, fallback to 'localstorage+cookie' if possible\n store = localPlusCookieStore\n } else {\n store = cookieStore\n }\n\n return store\n }\n\n properties(): Properties {\n const p: Properties = {}\n // Filter out reserved properties\n each(this.props, function (v, k) {\n if (k === ENABLED_FEATURE_FLAGS && isObject(v)) {\n const keys = Object.keys(v)\n for (let i = 0; i < keys.length; i++) {\n p[`$feature/${keys[i]}`] = v[keys[i]]\n }\n } else if (!include(PERSISTENCE_RESERVED_PROPERTIES, k)) {\n p[k] = v\n }\n })\n return p\n }\n\n load(): void {\n if (this._disabled) {\n return\n }\n\n const entry = this._storage._parse(this._name)\n\n if (entry) {\n this.props = extend({}, entry)\n }\n }\n\n /**\n * NOTE: Saving frequently causes issues with Recordings and Consent Management Platform (CMP) tools which\n * observe cookie changes, and modify their UI, often causing infinite loops.\n * As such callers of this should ideally check that the data has changed beforehand\n */\n save(): void {\n if (this._disabled) {\n return\n }\n this._storage._set(\n this._name,\n this.props,\n this._expire_days,\n this._cross_subdomain,\n this._secure,\n this._config.debug\n )\n }\n\n remove(): void {\n // remove both domain and subdomain cookies\n this._storage._remove(this._name, false)\n this._storage._remove(this._name, true)\n }\n\n // removes the storage entry and deletes all loaded data\n // forced name for tests\n\n clear(): void {\n this.remove()\n this.props = {}\n }\n\n /**\n * @param {Object} props\n * @param {*=} default_value\n * @param {number=} days\n */\n\n register_once(props: Properties, default_value: any, days?: number): boolean {\n if (isObject(props)) {\n if (isUndefined(default_value)) {\n default_value = 'None'\n }\n this._expire_days = isUndefined(days) ? this._default_expiry : days\n\n let hasChanges = false\n\n each(props, (val, prop) => {\n if (!this.props.hasOwnProperty(prop) || this.props[prop] === default_value) {\n this.props[prop] = val\n hasChanges = true\n }\n })\n\n if (hasChanges) {\n this.save()\n return true\n }\n }\n return false\n }\n\n /**\n * @param {Object} props\n * @param {number=} days\n */\n\n register(props: Properties, days?: number): boolean {\n if (isObject(props)) {\n this._expire_days = isUndefined(days) ? this._default_expiry : days\n\n let hasChanges = false\n\n each(props, (val, prop) => {\n if (props.hasOwnProperty(prop) && this.props[prop] !== val) {\n this.props[prop] = val\n hasChanges = true\n }\n })\n\n if (hasChanges) {\n this.save()\n return true\n }\n }\n return false\n }\n\n unregister(prop: string): void {\n if (prop in this.props) {\n delete this.props[prop]\n this.save()\n }\n }\n\n update_campaign_params(): void {\n if (!this._campaign_params_saved) {\n const campaignParams = getCampaignParams(\n this._config.custom_campaign_params,\n this._config.mask_personal_data_properties,\n this._config.custom_personal_data_properties\n )\n // only save campaign params if there were any\n if (!isEmptyObject(stripEmptyProperties(campaignParams))) {\n this.register(campaignParams)\n }\n this._campaign_params_saved = true\n }\n }\n update_search_keyword(): void {\n this.register(getSearchInfo())\n }\n\n update_referrer_info(): void {\n this.register_once(getReferrerInfo(), undefined)\n }\n\n set_initial_person_info(): void {\n if (this.props[INITIAL_CAMPAIGN_PARAMS] || this.props[INITIAL_REFERRER_INFO]) {\n // the user has initial properties stored the previous way, don't save them again\n return\n }\n\n this.register_once(\n {\n [INITIAL_PERSON_INFO]: getPersonInfo(\n this._config.mask_personal_data_properties,\n this._config.custom_personal_data_properties\n ),\n },\n undefined\n )\n }\n\n get_initial_props(): Properties {\n const p: Properties = {}\n\n // this section isn't written to anymore, but we should keep reading from it for backwards compatibility\n // for a while\n each([INITIAL_REFERRER_INFO, INITIAL_CAMPAIGN_PARAMS], (key) => {\n const initialReferrerInfo = this.props[key]\n if (initialReferrerInfo) {\n each(initialReferrerInfo, function (v, k) {\n p['$initial_' + stripLeadingDollar(k)] = v\n })\n }\n })\n const initialPersonInfo = this.props[INITIAL_PERSON_INFO]\n if (initialPersonInfo) {\n const initialPersonProps = getInitialPersonPropsFromInfo(initialPersonInfo)\n extend(p, initialPersonProps)\n }\n\n return p\n }\n\n // safely fills the passed in object with stored properties,\n // does not override any properties defined in both\n // returns the passed in object\n\n safe_merge(props: Properties): Properties {\n each(this.props, function (val, prop) {\n if (!(prop in props)) {\n props[prop] = val\n }\n })\n\n return props\n }\n\n update_config(config: PostHogConfig, oldConfig: PostHogConfig, isDisabled?: boolean): void {\n this._default_expiry = this._expire_days = config['cookie_expiration']\n this.set_disabled(config['disable_persistence'] || !!isDisabled)\n this.set_cross_subdomain(config['cross_subdomain_cookie'])\n this.set_secure(config['secure_cookie'])\n\n // If the persistence type has changed, we need to migrate the data.\n if (\n config.persistence !== oldConfig.persistence ||\n !isArrayContentsEqual(config.cookie_persisted_properties || [], oldConfig.cookie_persisted_properties || [])\n ) {\n const newStore = this._buildStorage(config)\n const props = this.props\n\n // Clear the old store\n this.clear()\n\n // Set up the new store data\n this._storage = newStore\n this.props = props\n this.save()\n }\n }\n\n set_disabled(disabled: boolean): void {\n this._disabled = disabled\n if (this._disabled) {\n this.remove()\n } else {\n this.save()\n }\n }\n\n set_cross_subdomain(cross_subdomain: boolean): void {\n if (cross_subdomain !== this._cross_subdomain) {\n this._cross_subdomain = cross_subdomain\n this.remove()\n this.save()\n }\n }\n\n set_secure(secure: boolean): void {\n if (secure !== this._secure) {\n this._secure = secure\n this.remove()\n this.save()\n }\n }\n\n set_event_timer(event_name: string, timestamp: number): void {\n const timers = this.props[EVENT_TIMERS_KEY] || {}\n timers[event_name] = timestamp\n this.props[EVENT_TIMERS_KEY] = timers\n this.save()\n }\n\n remove_event_timer(event_name: string): number {\n const timers = this.props[EVENT_TIMERS_KEY] || {}\n const timestamp = timers[event_name]\n if (!isUndefined(timestamp)) {\n delete this.props[EVENT_TIMERS_KEY][event_name]\n this.save()\n }\n return timestamp\n }\n\n get_property(prop: string): any {\n return this.props[prop]\n }\n\n set_property(prop: string, to: any): void {\n this.props[prop] = to\n this.save()\n }\n}\n","import { PostHog } from './posthog-core'\nimport { ProductTour, ProductTourCallback } from './posthog-product-tours-types'\nimport { PRODUCT_TOURS_ENABLED_SERVER_SIDE } from './constants'\nimport { RemoteConfig } from './types'\nimport { createLogger } from './utils/logger'\nimport { isArray, isNullish } from '@posthog/core'\nimport { assignableWindow } from './utils/globals'\n\nconst logger = createLogger('[Product Tours]')\n\nconst PRODUCT_TOURS_STORAGE_KEY = 'ph_product_tours'\n\ninterface ProductTourManagerInterface {\n start: () => void\n stop: () => void\n showTourById: (tourId: string) => void\n previewTour: (tour: ProductTour) => void\n dismissTour: (reason: string) => void\n nextStep: () => void\n previousStep: () => void\n getActiveProductTours: (callback: ProductTourCallback) => void\n resetTour: (tourId: string) => void\n resetAllTours: () => void\n cancelPendingTour: (tourId: string) => void\n}\n\nconst isProductToursEnabled = (instance: PostHog): boolean => {\n if (instance.config.disable_product_tours) {\n return false\n }\n return !!instance.persistence?.get_property(PRODUCT_TOURS_ENABLED_SERVER_SIDE)\n}\n\nexport class PostHogProductTours {\n private _instance: PostHog\n private _productTourManager: ProductTourManagerInterface | null = null\n private _cachedTours: ProductTour[] | null = null\n\n constructor(instance: PostHog) {\n this._instance = instance\n }\n\n onRemoteConfig(response: RemoteConfig): void {\n if (this._instance.persistence) {\n this._instance.persistence.register({\n [PRODUCT_TOURS_ENABLED_SERVER_SIDE]: !!response?.productTours,\n })\n }\n this.loadIfEnabled()\n }\n\n loadIfEnabled(): void {\n if (this._productTourManager || !isProductToursEnabled(this._instance)) {\n return\n }\n this._loadScript(() => this._startProductTours())\n }\n\n private _loadScript(cb: () => void): void {\n if (assignableWindow.__PosthogExtensions__?.generateProductTours) {\n cb()\n return\n }\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(this._instance, 'product-tours', (err) => {\n if (err) {\n logger.error('Could not load product tours script', err)\n return\n }\n cb()\n })\n }\n\n private _startProductTours(): void {\n if (this._productTourManager || !assignableWindow.__PosthogExtensions__?.generateProductTours) {\n return\n }\n this._productTourManager = assignableWindow.__PosthogExtensions__.generateProductTours(this._instance, true)\n }\n\n getProductTours(callback: ProductTourCallback, forceReload: boolean = false): void {\n if (isArray(this._cachedTours) && !forceReload) {\n callback(this._cachedTours, { isLoaded: true })\n return\n }\n\n const persistence = this._instance.persistence\n if (persistence) {\n const storedTours = persistence.props[PRODUCT_TOURS_STORAGE_KEY]\n if (isArray(storedTours) && !forceReload) {\n this._cachedTours = storedTours\n callback(storedTours, { isLoaded: true })\n return\n }\n }\n\n this._instance._send_request({\n url: this._instance.requestRouter.endpointFor(\n 'api',\n `/api/product_tours/?token=${this._instance.config.token}`\n ),\n method: 'GET',\n callback: (response) => {\n const statusCode = response.statusCode\n if (statusCode !== 200 || !response.json) {\n const error = `Product Tours API could not be loaded, status: ${statusCode}`\n logger.error(error)\n callback([], { isLoaded: false, error })\n return\n }\n\n const tours: ProductTour[] = isArray(response.json.product_tours) ? response.json.product_tours : []\n this._cachedTours = tours\n\n if (persistence) {\n persistence.register({ [PRODUCT_TOURS_STORAGE_KEY]: tours })\n }\n\n callback(tours, { isLoaded: true })\n },\n })\n }\n\n getActiveProductTours(callback: ProductTourCallback): void {\n if (isNullish(this._productTourManager)) {\n callback([], { isLoaded: false, error: 'Product tours not loaded' })\n return\n }\n this._productTourManager.getActiveProductTours(callback)\n }\n\n showProductTour(tourId: string): void {\n this._productTourManager?.showTourById(tourId)\n }\n\n // force load product tours extension and render a tour,\n // ignoring all display conditions.\n previewTour(tour: ProductTour): void {\n if (this._productTourManager) {\n this._productTourManager.previewTour(tour)\n return\n }\n\n this._loadScript(() => {\n this._startProductTours()\n this._productTourManager?.previewTour(tour)\n })\n }\n\n dismissProductTour(): void {\n this._productTourManager?.dismissTour('user_clicked_skip')\n }\n\n nextStep(): void {\n this._productTourManager?.nextStep()\n }\n\n previousStep(): void {\n this._productTourManager?.previousStep()\n }\n\n clearCache(): void {\n this._cachedTours = null\n this._instance.persistence?.unregister(PRODUCT_TOURS_STORAGE_KEY)\n }\n\n resetTour(tourId: string): void {\n this._productTourManager?.resetTour(tourId)\n }\n\n resetAllTours(): void {\n this._productTourManager?.resetAllTours()\n }\n\n cancelPendingTour(tourId: string): void {\n this._productTourManager?.cancelPendingTour(tourId)\n }\n}\n","/**\n * Having Survey types in types.ts was confusing tsc\n * and generating an invalid module.d.ts\n * See https://github.com/PostHog/posthog-js/issues/698\n */\n\nimport type { PropertyMatchType } from './types'\nimport type { SurveyAppearance as CoreSurveyAppearance } from '@posthog/core'\n\nexport enum SurveyEventType {\n Activation = 'events',\n Cancellation = 'cancelEvents',\n}\n\n// Extended operator type to include numeric operators not in PropertyMatchType\nexport type PropertyOperator = PropertyMatchType | 'gt' | 'lt'\n\nexport type PropertyFilters = {\n [propertyName: string]: {\n values: string[]\n operator: PropertyOperator\n }\n}\n\nexport interface SurveyEventWithFilters {\n name: string\n propertyFilters?: PropertyFilters\n}\n\nexport enum SurveyWidgetType {\n Button = 'button',\n Tab = 'tab',\n Selector = 'selector',\n}\n\nexport enum SurveyPosition {\n TopLeft = 'top_left',\n TopRight = 'top_right',\n TopCenter = 'top_center',\n MiddleLeft = 'middle_left',\n MiddleRight = 'middle_right',\n MiddleCenter = 'middle_center',\n Left = 'left',\n Center = 'center',\n Right = 'right',\n NextToTrigger = 'next_to_trigger',\n}\n\nexport enum SurveyTabPosition {\n Top = 'top',\n Left = 'left',\n Right = 'right',\n Bottom = 'bottom',\n}\n\n// Extends core SurveyAppearance with browser-specific fields\n// Omit 'position' from core because browser's SurveyPosition has additional values (e.g., NextToTrigger)\nexport interface SurveyAppearance extends Omit<CoreSurveyAppearance, 'position'> {\n // Browser-specific fields not in core\n /** @deprecated - not currently used */\n descriptionTextColor?: string\n ratingButtonHoverColor?: string\n whiteLabel?: boolean\n tabPosition?: SurveyTabPosition\n fontFamily?: string\n maxWidth?: string\n zIndex?: string\n disabledButtonOpacity?: string\n boxPadding?: string\n /** @deprecated Use inputBackground instead (inherited from core) */\n inputBackgroundColor?: string\n // Hide the X (cancel) button - defaults to false (show the button)\n hideCancelButton?: boolean\n // Browser's SurveyPosition has more options than core (e.g., NextToTrigger)\n position?: SurveyPosition\n}\n\nexport enum SurveyType {\n Popover = 'popover',\n API = 'api',\n Widget = 'widget',\n ExternalSurvey = 'external_survey',\n}\n\nexport type SurveyQuestion = BasicSurveyQuestion | LinkSurveyQuestion | RatingSurveyQuestion | MultipleSurveyQuestion\n\nexport type SurveyQuestionDescriptionContentType = 'html' | 'text'\n\ninterface SurveyQuestionBase {\n question: string\n id?: string\n description?: string | null\n descriptionContentType?: SurveyQuestionDescriptionContentType\n optional?: boolean\n buttonText?: string\n branching?: NextQuestionBranching | EndBranching | ResponseBasedBranching | SpecificQuestionBranching\n}\n\nexport interface BasicSurveyQuestion extends SurveyQuestionBase {\n type: SurveyQuestionType.Open\n}\n\nexport interface LinkSurveyQuestion extends SurveyQuestionBase {\n type: SurveyQuestionType.Link\n link?: string | null\n}\n\nexport interface RatingSurveyQuestion extends SurveyQuestionBase {\n type: SurveyQuestionType.Rating\n display: 'number' | 'emoji'\n scale: 3 | 5 | 7 | 10\n lowerBoundLabel: string\n upperBoundLabel: string\n skipSubmitButton?: boolean\n}\n\nexport interface MultipleSurveyQuestion extends SurveyQuestionBase {\n type: SurveyQuestionType.SingleChoice | SurveyQuestionType.MultipleChoice\n choices: string[]\n hasOpenChoice?: boolean\n shuffleOptions?: boolean\n skipSubmitButton?: boolean\n}\n\nexport enum SurveyQuestionType {\n Open = 'open',\n MultipleChoice = 'multiple_choice',\n SingleChoice = 'single_choice',\n Rating = 'rating',\n Link = 'link',\n}\n\nexport enum SurveyQuestionBranchingType {\n NextQuestion = 'next_question',\n End = 'end',\n ResponseBased = 'response_based',\n SpecificQuestion = 'specific_question',\n}\n\ninterface NextQuestionBranching {\n type: SurveyQuestionBranchingType.NextQuestion\n}\n\ninterface EndBranching {\n type: SurveyQuestionBranchingType.End\n}\n\ninterface ResponseBasedBranching {\n type: SurveyQuestionBranchingType.ResponseBased\n responseValues: Record<string, any>\n}\n\ninterface SpecificQuestionBranching {\n type: SurveyQuestionBranchingType.SpecificQuestion\n index: number\n}\n\nexport type SurveyCallback = (surveys: Survey[], context?: { isLoaded: boolean; error?: string }) => void\n\nexport interface SurveyElement {\n text?: string\n $el_text?: string\n tag_name?: string\n href?: string\n attr_id?: string\n attr_class?: string[]\n nth_child?: number\n nth_of_type?: number\n attributes?: Record<string, any>\n event_id?: number\n order?: number\n group_id?: number\n}\nexport interface SurveyRenderReason {\n visible: boolean\n disabledReason?: string\n}\n\nexport enum SurveySchedule {\n Once = 'once',\n Recurring = 'recurring',\n Always = 'always',\n}\n\nexport interface Survey {\n // Sync this with the backend's SurveyAPISerializer!\n id: string\n name: string\n description: string\n type: SurveyType\n feature_flag_keys:\n | {\n key: string\n value?: string\n }[]\n | null\n // the linked flag key is the flag key that is used to link the survey to a flag\n linked_flag_key: string | null\n targeting_flag_key: string | null\n // the internal targeting flag key is the flag key that is used to target users who have seen the survey\n // eg survey-targeting-<survey-id>\n internal_targeting_flag_key: string | null\n questions: SurveyQuestion[]\n appearance: SurveyAppearance | null\n conditions: {\n url?: string\n selector?: string\n seenSurveyWaitPeriodInDays?: number\n urlMatchType?: PropertyMatchType\n /** events that trigger surveys */\n events: {\n repeatedActivation?: boolean\n values: SurveyEventWithFilters[]\n } | null\n /** events that cancel \"pending\" (time-delayed) surveys */\n cancelEvents: {\n values: SurveyEventWithFilters[]\n } | null\n actions: {\n values: SurveyActionType[]\n } | null\n deviceTypes?: string[]\n deviceTypesMatchType?: PropertyMatchType\n linkedFlagVariant?: string\n } | null\n start_date: string | null\n end_date: string | null\n current_iteration: number | null\n current_iteration_start_date: string | null\n schedule?: SurveySchedule | null\n enable_partial_responses?: boolean | null\n}\n\nexport type SurveyWithTypeAndAppearance = Pick<Survey, 'id' | 'type' | 'appearance'>\n\nexport interface SurveyActionType {\n id: number\n name: string | null\n steps?: ActionStepType[]\n}\n\n/** Sync with plugin-server/src/types.ts */\nexport type ActionStepStringMatching = 'contains' | 'exact' | 'regex'\n\nexport interface ActionStepType {\n event?: string | null\n selector?: string | null\n /** pre-compiled regex pattern for matching selector against $elements_chain */\n selector_regex?: string | null\n /** @deprecated Only `selector` should be used now. */\n tag_name?: string\n text?: string | null\n /** @default StringMatching.Exact */\n text_matching?: ActionStepStringMatching | null\n href?: string | null\n /** @default ActionStepStringMatching.Exact */\n href_matching?: ActionStepStringMatching | null\n url?: string | null\n /** @default StringMatching.Contains */\n url_matching?: ActionStepStringMatching | null\n /** Property filters for action step matching */\n properties?: {\n key: string\n value?: string | number | boolean | (string | number | boolean)[] | null\n operator?: PropertyMatchType\n type?: string\n }[]\n}\n\nexport enum SurveyEventName {\n SHOWN = 'survey shown',\n DISMISSED = 'survey dismissed',\n SENT = 'survey sent',\n ABANDONED = 'survey abandoned',\n}\n\nexport enum SurveyEventProperties {\n SURVEY_ID = '$survey_id',\n SURVEY_NAME = '$survey_name',\n SURVEY_RESPONSE = '$survey_response',\n SURVEY_ITERATION = '$survey_iteration',\n SURVEY_ITERATION_START_DATE = '$survey_iteration_start_date',\n SURVEY_PARTIALLY_COMPLETED = '$survey_partially_completed',\n SURVEY_SUBMISSION_ID = '$survey_submission_id',\n SURVEY_QUESTIONS = '$survey_questions',\n SURVEY_COMPLETED = '$survey_completed',\n PRODUCT_TOUR_ID = '$product_tour_id',\n SURVEY_LAST_SEEN_DATE = '$survey_last_seen_date',\n}\n\nexport enum DisplaySurveyType {\n Popover = 'popover',\n Inline = 'inline',\n}\n\ninterface DisplaySurveyOptionsBase {\n ignoreConditions: boolean\n ignoreDelay: boolean\n displayType: DisplaySurveyType\n}\n\ninterface DisplaySurveyPopoverOptions extends DisplaySurveyOptionsBase {\n displayType: DisplaySurveyType.Popover\n}\n\ninterface DisplaySurveyInlineOptions extends DisplaySurveyOptionsBase {\n displayType: DisplaySurveyType.Inline\n selector: string\n}\n\nexport type DisplaySurveyOptions = DisplaySurveyPopoverOptions | DisplaySurveyInlineOptions\n\nexport interface SurveyConfig {\n prefillFromUrl?: boolean\n /**\n * @deprecated No longer used. Surveys will automatically advance past\n * prefilled questions with skipSubmitButton enabled. If partial response\n * collection is enabled, partial responses for pre-filled questions will\n * be submitted automatically on page load.\n */\n autoSubmitIfComplete?: boolean\n /**\n * @deprecated No longer used. Pre-filled responses are now sent\n * immediately when partial responses are enabled, or all required\n * quesions have been pre-filled.\n */\n autoSubmitDelay?: number\n}\n","import { DisplaySurveyOptions, DisplaySurveyType, Survey, SurveyType } from '../posthog-surveys-types'\nimport { createLogger } from '../utils/logger'\n\nexport const SURVEY_LOGGER = createLogger('[Surveys]')\n\nexport function isSurveyRunning(survey: Survey): boolean {\n return !!(survey.start_date && !survey.end_date)\n}\n\nexport function doesSurveyActivateByEvent(survey: Pick<Survey, 'conditions'>): boolean {\n return !!survey.conditions?.events?.values?.length\n}\n\nexport function doesSurveyActivateByAction(survey: Pick<Survey, 'conditions'>): boolean {\n return !!survey.conditions?.actions?.values?.length\n}\n\nexport const SURVEY_SEEN_PREFIX = 'seenSurvey_'\nexport const SURVEY_IN_PROGRESS_PREFIX = 'inProgressSurvey_'\nexport const SURVEY_ABANDONED_PREFIX = 'abandonedSurvey_'\n\nexport const getSurveyInteractionProperty = (\n survey: Pick<Survey, 'id' | 'current_iteration'>,\n action: 'responded' | 'dismissed'\n): string => {\n let surveyProperty = `$survey_${action}/${survey.id}`\n if (survey.current_iteration && survey.current_iteration > 0) {\n surveyProperty = `$survey_${action}/${survey.id}/${survey.current_iteration}`\n }\n\n return surveyProperty\n}\n\nconst getSurveyStorageKey = (prefix: string, survey: Pick<Survey, 'id' | 'current_iteration'>): string => {\n let key = `${prefix}${survey.id}`\n if (survey.current_iteration && survey.current_iteration > 0) {\n key = `${prefix}${survey.id}_${survey.current_iteration}`\n }\n return key\n}\n\nexport const getSurveySeenKey = (survey: Pick<Survey, 'id' | 'current_iteration'>): string => {\n return getSurveyStorageKey(SURVEY_SEEN_PREFIX, survey)\n}\n\nexport const getSurveyAbandonedKey = (survey: Pick<Survey, 'id' | 'current_iteration'>): string => {\n return getSurveyStorageKey(SURVEY_ABANDONED_PREFIX, survey)\n}\n\nexport const setSurveySeenOnLocalStorage = (survey: Pick<Survey, 'id' | 'current_iteration'>) => {\n const isSurveySeen = localStorage.getItem(getSurveySeenKey(survey))\n // if survey is already seen, no need to set it again\n if (isSurveySeen) {\n return\n }\n\n localStorage.setItem(getSurveySeenKey(survey), 'true')\n}\n\n// These surveys are relevant for the getActiveMatchingSurveys method. They are used to\n// display surveys in our customer's application. Any new in-app survey type should be added here.\nexport const IN_APP_SURVEY_TYPES = [SurveyType.Popover, SurveyType.Widget, SurveyType.API]\n\nexport const DEFAULT_DISPLAY_SURVEY_OPTIONS: DisplaySurveyOptions = {\n ignoreConditions: false,\n ignoreDelay: false,\n displayType: DisplaySurveyType.Popover,\n}\n","export class SimpleEventEmitter {\n private _events: { [key: string]: ((...args: any[]) => void)[] } = {}\n\n constructor() {\n this._events = {}\n }\n\n on(event: string, listener: (...args: any[]) => void): () => void {\n if (!this._events[event]) {\n this._events[event] = []\n }\n this._events[event].push(listener)\n\n return () => {\n this._events[event] = this._events[event].filter((x) => x !== listener)\n }\n }\n\n emit(event: string, payload: any): void {\n for (const listener of this._events[event] || []) {\n listener(payload)\n }\n for (const listener of this._events['*'] || []) {\n listener(event, payload)\n }\n }\n}\n","import { isNullish } from '@posthog/core'\n\nexport function extractHref(elementsChain: string): string {\n const match = elementsChain.match(/(?::|\")href=\"(.*?)\"/)\n return match ? match[1] : ''\n}\n\nexport function extractTexts(elementsChain: string): string[] {\n const texts: string[] = []\n const regex = /(?::|\")text=\"(.*?)\"/g\n let match\n while (!isNullish((match = regex.exec(elementsChain)))) {\n if (!texts.includes(match[1])) {\n texts.push(match[1])\n }\n }\n return texts\n}\n\nexport function matchString(\n value: string | undefined | null,\n pattern: string,\n matching: 'exact' | 'contains' | 'regex'\n): boolean {\n if (isNullish(value)) return false\n switch (matching) {\n case 'exact':\n return value === pattern\n case 'contains': {\n // Simulating SQL LIKE behavior (_ = any single character, % = any zero or more characters)\n const likePattern = pattern\n .replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/_/g, '.')\n .replace(/%/g, '.*')\n return new RegExp(likePattern, 'i').test(value)\n }\n case 'regex':\n try {\n return new RegExp(pattern).test(value)\n } catch {\n return false\n }\n default:\n return false\n }\n}\n\nexport function matchTexts(texts: string[], pattern: string, matching: 'exact' | 'contains' | 'regex'): boolean {\n return texts.some((text) => matchString(text, pattern, matching))\n}\n","import { PostHog } from '../../posthog-core'\nimport { ActionStepType, PropertyFilters, SurveyActionType, SurveyElement } from '../../posthog-surveys-types'\nimport { SimpleEventEmitter } from '../../utils/simple-event-emitter'\nimport { CaptureResult, PropertyMatchType } from '../../types'\nimport { isArray, isUndefined } from '@posthog/core'\nimport { matchPropertyFilters } from '../../utils/property-utils'\nimport { extractTexts, extractHref, matchString, matchTexts } from '../../utils/elements-chain-utils'\n\nexport class ActionMatcher {\n private readonly _actionRegistry?: Set<SurveyActionType>\n private readonly _instance?: PostHog\n private readonly _actionEvents: Set<string>\n private _debugEventEmitter = new SimpleEventEmitter()\n\n constructor(instance?: PostHog) {\n this._instance = instance\n this._actionEvents = new Set<string>()\n this._actionRegistry = new Set<SurveyActionType>()\n }\n\n init() {\n if (!isUndefined(this._instance?._addCaptureHook)) {\n const matchEventToAction = (eventName: string, eventPayload: any) => {\n this.on(eventName, eventPayload)\n }\n this._instance?._addCaptureHook(matchEventToAction)\n }\n }\n\n register(actions: SurveyActionType[]): void {\n if (isUndefined(this._instance?._addCaptureHook)) {\n return\n }\n\n actions.forEach((action) => {\n this._actionRegistry?.add(action)\n action.steps?.forEach((step) => {\n this._actionEvents?.add(step?.event || '')\n })\n })\n\n if (this._instance?.autocapture) {\n const selectorsToWatch: Set<string> = new Set<string>()\n actions.forEach((action) => {\n action.steps?.forEach((step) => {\n if (step?.selector) {\n selectorsToWatch.add(step?.selector)\n }\n })\n })\n this._instance?.autocapture.setElementSelectors(selectorsToWatch)\n }\n }\n\n on(eventName: string, eventPayload?: CaptureResult) {\n if (eventPayload == null || eventName.length == 0) {\n return\n }\n\n if (!this._actionEvents.has(eventName) && !this._actionEvents.has(<string>eventPayload?.event)) {\n return\n }\n\n if (this._actionRegistry && this._actionRegistry?.size > 0) {\n this._actionRegistry.forEach((action) => {\n if (this._checkAction(eventPayload, action)) {\n this._debugEventEmitter.emit('actionCaptured', action.name)\n }\n })\n }\n }\n\n _addActionHook(callback: (actionName: string, eventPayload?: any) => void): void {\n this.onAction('actionCaptured', (data) => callback(data))\n }\n\n private _checkAction(event?: CaptureResult, action?: SurveyActionType): boolean {\n if (action?.steps == null) {\n return false\n }\n\n for (const step of action.steps) {\n if (this._checkStep(event, step)) {\n return true\n }\n }\n\n return false\n }\n\n onAction(event: 'actionCaptured', cb: (...args: any[]) => void): () => void {\n return this._debugEventEmitter.on(event, cb)\n }\n\n private _checkStep = (event?: CaptureResult, step?: ActionStepType): boolean => {\n return (\n this._checkStepEvent(event, step) &&\n this._checkStepUrl(event, step) &&\n this._checkStepElement(event, step) &&\n this._checkStepProperties(event, step)\n )\n }\n\n private _checkStepEvent = (event?: CaptureResult, step?: ActionStepType): boolean => {\n // CHECK CONDITIONS, OTHERWISE SKIPPED\n if (step?.event && event?.event !== step?.event) {\n return false // EVENT NAME IS A MISMATCH\n }\n return true\n }\n\n private _checkStepUrl(event?: CaptureResult, step?: ActionStepType): boolean {\n // CHECK CONDITIONS, OTHERWISE SKIPPED\n if (step?.url) {\n const eventUrl = event?.properties?.$current_url\n if (!eventUrl || typeof eventUrl !== 'string') {\n return false\n }\n if (!matchString(eventUrl, step.url, step.url_matching || 'contains')) {\n return false\n }\n }\n return true\n }\n\n private _checkStepElement(event?: CaptureResult, step?: ActionStepType): boolean {\n if (!this._checkStepHref(event, step)) return false\n if (!this._checkStepText(event, step)) return false\n if (!this._checkStepSelector(event, step)) return false\n return true\n }\n\n private _checkStepHref(event?: CaptureResult, step?: ActionStepType): boolean {\n if (!step?.href) return true\n\n const elements = this._getElementsList(event)\n if (elements.length > 0) {\n return elements.some((el) => matchString(el.href, step.href!, step.href_matching || 'exact'))\n }\n\n const chain = (event?.properties?.$elements_chain as string) || ''\n if (chain) {\n return matchString(extractHref(chain), step.href, step.href_matching || 'exact')\n }\n\n return false\n }\n\n private _checkStepText(event?: CaptureResult, step?: ActionStepType): boolean {\n if (!step?.text) return true\n\n const elements = this._getElementsList(event)\n if (elements.length > 0) {\n return elements.some(\n (el) =>\n matchString(el.text, step.text!, step.text_matching || 'exact') ||\n matchString(el.$el_text, step.text!, step.text_matching || 'exact')\n )\n }\n\n const chain = (event?.properties?.$elements_chain as string) || ''\n if (chain) {\n return matchTexts(extractTexts(chain), step.text, step.text_matching || 'exact')\n }\n\n return false\n }\n\n private _checkStepSelector(event?: CaptureResult, step?: ActionStepType): boolean {\n if (!step?.selector) return true\n\n // check exact match on $element_selectors from autocapture\n const elementSelectors = event?.properties?.$element_selectors as string[] | undefined\n if (elementSelectors?.includes(step.selector)) {\n return true\n }\n\n // check against compiled regex\n const chain = (event?.properties?.$elements_chain as string) || ''\n if (step.selector_regex && chain) {\n try {\n return new RegExp(step.selector_regex).test(chain)\n } catch {\n return false\n }\n }\n\n return false\n }\n\n private _getElementsList(event?: CaptureResult): SurveyElement[] {\n if (event?.properties?.$elements == null) {\n return []\n }\n\n return event?.properties.$elements as unknown as SurveyElement[]\n }\n\n private _checkStepProperties(event?: CaptureResult, step?: ActionStepType): boolean {\n if (!step?.properties || step.properties.length === 0) {\n return true\n }\n\n // transform to match same property format as normal events\n const propertyFilters: PropertyFilters = step.properties.reduce<PropertyFilters>((acc, filter) => {\n const values = isArray(filter.value)\n ? filter.value.map(String)\n : filter.value != null\n ? [String(filter.value)]\n : []\n\n acc[filter.key] = {\n values,\n operator: (filter.operator || 'exact') as PropertyMatchType,\n }\n return acc\n }, {})\n\n return matchPropertyFilters(propertyFilters, event?.properties)\n }\n}\n","import { SurveyActionType, SurveyEventType, SurveyEventWithFilters } from '../posthog-surveys-types'\nimport { ActionMatcher } from '../extensions/surveys/action-matcher'\nimport { PostHog } from '../posthog-core'\nimport { CaptureResult } from '../types'\nimport { matchPropertyFilters } from './property-utils'\nimport { isUndefined } from '@posthog/core'\nimport { createLogger } from './logger'\n\n/**\n * Interface for items that can be triggered by events/actions.\n * Both Survey and ProductTour implement this interface.\n */\nexport interface EventTriggerable {\n id: string\n conditions?: {\n events?: { repeatedActivation?: boolean; values: SurveyEventWithFilters[] } | null\n cancelEvents?: { values: SurveyEventWithFilters[] } | null\n actions?: { values: SurveyActionType[] } | null\n } | null\n}\n\n/**\n * Abstract base class for receiving events and matching them to triggerable items.\n * Subclasses implement type-specific behavior for surveys and product tours.\n */\nexport abstract class EventReceiver<T extends EventTriggerable> {\n // eventToItems is a mapping of event name to all the items that are activated by it\n protected _eventToItems: Map<string, string[]>\n // cancelEventToItems is a mapping of event name to all the items that should be cancelled by it\n protected _cancelEventToItems: Map<string, string[]>\n // actionToItems is a mapping of action name to all the items that are activated by it\n protected readonly _actionToItems: Map<string, string[]>\n // actionMatcher can look at CaptureResult payloads and match an event to its corresponding action.\n protected _actionMatcher?: ActionMatcher | null\n protected readonly _instance?: PostHog\n\n constructor(instance: PostHog) {\n this._instance = instance\n this._eventToItems = new Map<string, string[]>()\n this._cancelEventToItems = new Map<string, string[]>()\n this._actionToItems = new Map<string, string[]>()\n }\n\n // Abstract methods for subclasses to implement\n protected abstract _getActivatedKey(): string\n protected abstract _getShownEventName(): string\n protected abstract _getItems(callback: (items: T[]) => void): void\n protected abstract _cancelPendingItem(itemId: string): void\n protected abstract _getLogger(): ReturnType<typeof createLogger>\n /** Check if item is permanently ineligible (e.g. completed/dismissed). Skip adding to activated list. */\n protected abstract _isItemPermanentlyIneligible(itemId?: string): boolean\n\n private _doesEventMatchFilter(\n eventConfig: SurveyEventWithFilters | undefined,\n eventPayload?: CaptureResult\n ): boolean {\n if (!eventConfig) {\n return false\n }\n\n return matchPropertyFilters(eventConfig.propertyFilters, eventPayload?.properties)\n }\n\n private _buildEventToItemMap(items: T[], conditionField: SurveyEventType): Map<string, string[]> {\n const map = new Map<string, string[]>()\n items.forEach((item) => {\n item.conditions?.[conditionField]?.values?.forEach((event) => {\n if (event?.name) {\n const existing = map.get(event.name) || []\n existing.push(item.id)\n map.set(event.name, existing)\n }\n })\n })\n return map\n }\n\n /**\n * build a map of (Event1) => [Item1, Item2, Item3]\n * used for items that should be [activated|cancelled] by Event1\n */\n private _getMatchingItems(\n eventName: string,\n eventPayload: CaptureResult | undefined,\n conditionField: SurveyEventType\n ): T[] {\n const itemIdMap = conditionField === SurveyEventType.Activation ? this._eventToItems : this._cancelEventToItems\n const itemIds = itemIdMap.get(eventName)\n\n let items: T[] = []\n this._getItems((allItems) => {\n items = allItems.filter((item) => itemIds?.includes(item.id))\n })\n\n return items.filter((item) => {\n const eventConfig = item.conditions?.[conditionField]?.values?.find((e) => e.name === eventName)\n return this._doesEventMatchFilter(eventConfig, eventPayload)\n })\n }\n\n register(items: T[]): void {\n if (isUndefined(this._instance?._addCaptureHook)) {\n return\n }\n\n this._setupEventBasedItems(items)\n this._setupActionBasedItems(items)\n }\n\n private _setupActionBasedItems(items: T[]) {\n const actionBasedItems = items.filter(\n (item: T) => item.conditions?.actions && item.conditions?.actions?.values?.length > 0\n )\n\n if (actionBasedItems.length === 0) {\n return\n }\n\n if (this._actionMatcher == null) {\n this._actionMatcher = new ActionMatcher(this._instance)\n this._actionMatcher.init()\n // match any actions to its corresponding item.\n const matchActionToItem = (actionName: string) => {\n this.onAction(actionName)\n }\n\n this._actionMatcher._addActionHook(matchActionToItem)\n }\n\n actionBasedItems.forEach((item) => {\n if (\n item.conditions &&\n item.conditions?.actions &&\n item.conditions?.actions?.values &&\n item.conditions?.actions?.values?.length > 0\n ) {\n // register the known set of actions with\n // the action-matcher so it can match\n // events to actions\n this._actionMatcher?.register(item.conditions.actions.values)\n\n // maintain a mapping of (Action1) => [Item1, Item2, Item3]\n // where Items 1-3 are all activated by Action1\n item.conditions?.actions?.values?.forEach((action) => {\n if (action && action.name) {\n const knownItems: string[] | undefined = this._actionToItems.get(action.name)\n if (knownItems) {\n knownItems.push(item.id)\n }\n this._actionToItems.set(action.name, knownItems || [item.id])\n }\n })\n }\n })\n }\n\n private _setupEventBasedItems(items: T[]) {\n const eventBasedItems = items.filter(\n (item: T) => item.conditions?.events && item.conditions?.events?.values?.length > 0\n )\n\n const itemsWithCancelEvents = items.filter(\n (item: T) => item.conditions?.cancelEvents && item.conditions?.cancelEvents?.values?.length > 0\n )\n\n if (eventBasedItems.length === 0 && itemsWithCancelEvents.length === 0) {\n return\n }\n\n // match any events to its corresponding item.\n const matchEventToItem = (eventName: string, eventPayload?: CaptureResult) => {\n this.onEvent(eventName, eventPayload)\n }\n this._instance?._addCaptureHook(matchEventToItem)\n\n this._eventToItems = this._buildEventToItemMap(items, SurveyEventType.Activation)\n this._cancelEventToItems = this._buildEventToItemMap(items, SurveyEventType.Cancellation)\n }\n\n onEvent(event: string, eventPayload?: CaptureResult): void {\n const logger = this._getLogger()\n const activatedKey = this._getActivatedKey()\n const shownEventName = this._getShownEventName()\n\n const existingActivatedItems: string[] = this._instance?.persistence?.props[activatedKey] || []\n if (shownEventName === event && eventPayload && existingActivatedItems.length > 0) {\n // remove item from activatedItems here.\n logger.info('event matched, removing item from activated items', {\n event,\n eventPayload,\n existingActivatedItems,\n })\n const itemId = eventPayload?.properties?.$survey_id || eventPayload?.properties?.$product_tour_id\n if (itemId) {\n const index = existingActivatedItems.indexOf(itemId)\n if (index >= 0) {\n existingActivatedItems.splice(index, 1)\n this._updateActivatedItems(existingActivatedItems)\n }\n }\n\n return\n }\n\n // check if this event should cancel any pending items\n if (this._cancelEventToItems.has(event)) {\n const itemsToCancel = this._getMatchingItems(event, eventPayload, SurveyEventType.Cancellation)\n\n if (itemsToCancel.length > 0) {\n logger.info('cancel event matched, cancelling items', {\n event,\n itemsToCancel: itemsToCancel.map((s) => s.id),\n })\n\n itemsToCancel.forEach((item) => {\n // remove from activated items\n const index = existingActivatedItems.indexOf(item.id)\n if (index >= 0) {\n existingActivatedItems.splice(index, 1)\n }\n // cancel any pending timeout for this item\n this._cancelPendingItem(item.id)\n })\n\n this._updateActivatedItems(existingActivatedItems)\n }\n }\n\n // if the event is not in the eventToItems map, nothing else to do\n if (!this._eventToItems.has(event)) {\n return\n }\n\n logger.info('event name matched', {\n event,\n eventPayload,\n items: this._eventToItems.get(event),\n })\n\n const matchedItems = this._getMatchingItems(event, eventPayload, SurveyEventType.Activation)\n\n this._updateActivatedItems(existingActivatedItems.concat(matchedItems.map((item) => item.id) || []))\n }\n\n onAction(actionName: string): void {\n const activatedKey = this._getActivatedKey()\n const existingActivatedItems: string[] = this._instance?.persistence?.props[activatedKey] || []\n if (this._actionToItems.has(actionName)) {\n this._updateActivatedItems(existingActivatedItems.concat(this._actionToItems.get(actionName) || []))\n }\n }\n\n private _updateActivatedItems(activatedItems: string[]) {\n const logger = this._getLogger()\n const activatedKey = this._getActivatedKey()\n // Filter out permanently ineligible items and remove duplicates\n const eligibleItems = [...new Set(activatedItems)].filter(\n (itemId) => !this._isItemPermanentlyIneligible(itemId)\n )\n logger.info('updating activated items', {\n activatedItems: eligibleItems,\n })\n\n this._instance?.persistence?.register({\n [activatedKey]: eligibleItems,\n })\n }\n\n getActivatedIds(): string[] {\n const activatedKey = this._getActivatedKey()\n const existingActivatedItems = this._instance?.persistence?.props[activatedKey]\n return existingActivatedItems ? existingActivatedItems : []\n }\n\n getEventToItemsMap(): Map<string, string[]> {\n return this._eventToItems\n }\n\n _getActionMatcher(): ActionMatcher | null | undefined {\n return this._actionMatcher\n }\n}\n","import { SURVEYS_ACTIVATED } from '../constants'\nimport { Survey, SurveyEventName } from '../posthog-surveys-types'\nimport { PostHog } from '../posthog-core'\nimport { SURVEY_LOGGER as logger } from './survey-utils'\nimport { EventReceiver } from './event-receiver'\nimport { createLogger } from './logger'\n\nexport class SurveyEventReceiver extends EventReceiver<Survey> {\n constructor(instance: PostHog) {\n super(instance)\n }\n\n protected _getActivatedKey(): string {\n return SURVEYS_ACTIVATED\n }\n\n protected _getShownEventName(): string {\n return SurveyEventName.SHOWN\n }\n\n protected _getItems(callback: (items: Survey[]) => void): void {\n this._instance?.getSurveys(callback)\n }\n\n protected _cancelPendingItem(itemId: string): void {\n this._instance?.cancelPendingSurvey(itemId)\n }\n\n protected _getLogger(): ReturnType<typeof createLogger> {\n return logger\n }\n\n protected _isItemPermanentlyIneligible(): boolean {\n // Surveys have complex eligibility rules checked at display time\n // For now, we don't filter at activation time\n return false\n }\n\n // Backward compatibility - keep getSurveys() as alias for getActivatedIds()\n getSurveys(): string[] {\n return this.getActivatedIds()\n }\n\n // Backward compatibility - keep getEventToSurveys() as alias\n getEventToSurveys(): Map<string, string[]> {\n return this.getEventToItemsMap()\n }\n}\n","import { SURVEYS } from './constants'\nimport { SurveyManager } from './extensions/surveys'\nimport { PostHog } from './posthog-core'\nimport {\n DisplaySurveyOptions,\n DisplaySurveyType,\n Survey,\n SurveyCallback,\n SurveyRenderReason,\n} from './posthog-surveys-types'\nimport { RemoteConfig } from './types'\nimport { assignableWindow, document } from './utils/globals'\nimport { SurveyEventReceiver } from './utils/survey-event-receiver'\nimport {\n doesSurveyActivateByAction,\n doesSurveyActivateByEvent,\n IN_APP_SURVEY_TYPES,\n isSurveyRunning,\n SURVEY_LOGGER as logger,\n SURVEY_IN_PROGRESS_PREFIX,\n SURVEY_SEEN_PREFIX,\n} from './utils/survey-utils'\nimport { isNullish, isUndefined, isArray } from '@posthog/core'\n\nexport class PostHogSurveys {\n // this is set to undefined until the remote config is loaded\n // then it's set to true if there are surveys to load\n // or false if there are no surveys to load\n // or false if the surveys feature is disabled in the project settings\n private _isSurveysEnabled?: boolean = undefined\n public _surveyEventReceiver: SurveyEventReceiver | null\n private _surveyManager: SurveyManager | null = null\n private _isInitializingSurveys: boolean = false\n private _surveyCallbacks: SurveyCallback[] = []\n // Promise for in-flight survey fetch - allows multiple callers to await the same request\n private _getSurveysInFlightPromise: Promise<{\n surveys: Survey[]\n context: { isLoaded: boolean; error?: string }\n }> | null = null\n\n constructor(private readonly _instance: PostHog) {\n // we set this to undefined here because we need the persistence storage for this type\n // but that's not initialized until loadIfEnabled is called.\n this._surveyEventReceiver = null\n }\n\n onRemoteConfig(response: RemoteConfig) {\n // only load surveys if they are enabled and there are surveys to load\n if (this._instance.config.disable_surveys) {\n return\n }\n\n const surveys = response['surveys']\n if (isNullish(surveys)) {\n return logger.warn('Flags not loaded yet. Not loading surveys.')\n }\n const isArrayResponse = isArray(surveys)\n this._isSurveysEnabled = isArrayResponse ? surveys.length > 0 : surveys\n logger.info(`flags response received, isSurveysEnabled: ${this._isSurveysEnabled}`)\n this.loadIfEnabled()\n }\n\n reset(): void {\n localStorage.removeItem('lastSeenSurveyDate')\n const surveyKeys = []\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i)\n if (key?.startsWith(SURVEY_SEEN_PREFIX) || key?.startsWith(SURVEY_IN_PROGRESS_PREFIX)) {\n surveyKeys.push(key)\n }\n }\n\n surveyKeys.forEach((key) => localStorage.removeItem(key))\n }\n\n loadIfEnabled() {\n // Initial guard clauses\n if (this._surveyManager) {\n return\n } // Already loaded\n if (this._isInitializingSurveys) {\n logger.info('Already initializing surveys, skipping...')\n return\n }\n if (this._instance.config.disable_surveys) {\n logger.info('Disabled. Not loading surveys.')\n return\n }\n if (this._instance.config.cookieless_mode && this._instance.consent.isOptedOut()) {\n logger.info('Not loading surveys in cookieless mode without consent.')\n return\n }\n\n const phExtensions = assignableWindow?.__PosthogExtensions__\n if (!phExtensions) {\n logger.error('PostHog Extensions not found.')\n return\n }\n\n // waiting for remote config to load\n // if surveys is forced enable (like external surveys), ignore the remote config and load surveys\n if (isUndefined(this._isSurveysEnabled) && !this._instance.config.advanced_enable_surveys) {\n return\n }\n\n const isSurveysEnabled = this._isSurveysEnabled || this._instance.config.advanced_enable_surveys\n\n this._isInitializingSurveys = true\n\n try {\n const generateSurveys = phExtensions.generateSurveys\n if (generateSurveys) {\n // Surveys code is already loaded\n this._completeSurveyInitialization(generateSurveys, isSurveysEnabled)\n return\n }\n\n // If we reach here, surveys code is not loaded yet\n const loadExternalDependency = phExtensions.loadExternalDependency\n if (!loadExternalDependency) {\n // Cannot load surveys code\n this._handleSurveyLoadError('PostHog loadExternalDependency extension not found.')\n return\n }\n\n // If we reach here, we need to load the dependency\n loadExternalDependency(this._instance, 'surveys', (err) => {\n if (err || !phExtensions.generateSurveys) {\n this._handleSurveyLoadError('Could not load surveys script', err)\n } else {\n // Need to get the function reference again inside the callback\n this._completeSurveyInitialization(phExtensions.generateSurveys, isSurveysEnabled)\n }\n })\n } catch (e) {\n this._handleSurveyLoadError('Error initializing surveys', e)\n throw e\n } finally {\n // Ensure the flag is always reset\n this._isInitializingSurveys = false\n }\n }\n\n /** Helper to finalize survey initialization */\n private _completeSurveyInitialization(\n generateSurveysFn: (instance: PostHog, isSurveysEnabled: boolean) => any,\n isSurveysEnabled: boolean\n ): void {\n this._surveyManager = generateSurveysFn(this._instance, isSurveysEnabled)\n this._surveyEventReceiver = new SurveyEventReceiver(this._instance)\n logger.info('Surveys loaded successfully')\n this._notifySurveyCallbacks({ isLoaded: true })\n }\n\n /** Helper to handle errors during survey loading */\n private _handleSurveyLoadError(message: string, error?: any): void {\n logger.error(message, error)\n this._notifySurveyCallbacks({ isLoaded: false, error: message })\n }\n\n /**\n * Register a callback that runs when surveys are initialized.\n * ### Usage:\n *\n * posthog.onSurveysLoaded((surveys) => {\n * // You can work with all surveys\n * console.log('All available surveys:', surveys)\n *\n * // Or get active matching surveys\n * posthog.getActiveMatchingSurveys((activeMatchingSurveys) => {\n * if (activeMatchingSurveys.length > 0) {\n * posthog.renderSurvey(activeMatchingSurveys[0].id, '#survey-container')\n * }\n * })\n * })\n *\n * @param {Function} callback The callback function will be called when surveys are loaded or updated.\n * It receives the array of all surveys and a context object with error status.\n * @returns {Function} A function that can be called to unsubscribe the listener.\n */\n onSurveysLoaded(callback: SurveyCallback): () => void {\n this._surveyCallbacks.push(callback)\n\n if (this._surveyManager) {\n this._notifySurveyCallbacks({\n isLoaded: true,\n })\n }\n // Return unsubscribe function\n return () => {\n this._surveyCallbacks = this._surveyCallbacks.filter((cb: SurveyCallback) => cb !== callback)\n }\n }\n\n getSurveys(callback: SurveyCallback, forceReload = false) {\n // In case we manage to load the surveys script, but config says not to load surveys\n // then we shouldn't return survey data\n if (this._instance.config.disable_surveys) {\n logger.info('Disabled. Not loading surveys.')\n return callback([])\n }\n\n const existingSurveys = this._instance.get_property(SURVEYS)\n if (existingSurveys && !forceReload) {\n return callback(existingSurveys, {\n isLoaded: true,\n })\n }\n\n // If a fetch is already in progress and Promise is available, reuse that promise\n // In browsers without Promise (IE11), we skip this optimization and just make concurrent requests\n if (typeof Promise !== 'undefined' && this._getSurveysInFlightPromise) {\n this._getSurveysInFlightPromise.then(({ surveys, context }) => callback(surveys, context))\n return\n }\n\n // Create a new promise for this fetch that other callers can reuse\n // We need to assign the promise before starting the request, because\n // in tests (and potentially in some edge cases) the callback may fire synchronously\n let resolvePromise: (value: { surveys: Survey[]; context: { isLoaded: boolean; error?: string } }) => void\n if (typeof Promise !== 'undefined') {\n this._getSurveysInFlightPromise = new Promise((resolve) => {\n resolvePromise = resolve\n })\n }\n\n this._instance._send_request({\n url: this._instance.requestRouter.endpointFor('api', `/api/surveys/?token=${this._instance.config.token}`),\n method: 'GET',\n timeout: this._instance.config.surveys_request_timeout_ms,\n callback: (response) => {\n this._getSurveysInFlightPromise = null\n\n const statusCode = response.statusCode\n if (statusCode !== 200 || !response.json) {\n const error = `Surveys API could not be loaded, status: ${statusCode}`\n logger.error(error)\n const context = { isLoaded: false, error }\n callback([], context)\n resolvePromise?.({ surveys: [], context })\n return\n }\n const surveys = response.json.surveys || []\n\n const eventOrActionBasedSurveys = surveys.filter(\n (survey: Survey) =>\n isSurveyRunning(survey) &&\n (doesSurveyActivateByEvent(survey) || doesSurveyActivateByAction(survey))\n )\n\n if (eventOrActionBasedSurveys.length > 0) {\n this._surveyEventReceiver?.register(eventOrActionBasedSurveys)\n }\n\n this._instance.persistence?.register({ [SURVEYS]: surveys })\n const context = { isLoaded: true }\n callback(surveys, context)\n resolvePromise?.({ surveys, context })\n },\n })\n }\n\n /** Helper method to notify all registered callbacks */\n private _notifySurveyCallbacks(context: { isLoaded: boolean; error?: string }): void {\n for (const callback of this._surveyCallbacks) {\n try {\n if (!context.isLoaded) {\n return callback([], context)\n }\n this.getSurveys(callback)\n } catch (error) {\n logger.error('Error in survey callback', error)\n }\n }\n }\n\n getActiveMatchingSurveys(callback: SurveyCallback, forceReload = false) {\n if (isNullish(this._surveyManager)) {\n logger.warn('init was not called')\n return\n }\n return this._surveyManager.getActiveMatchingSurveys(callback, forceReload)\n }\n\n private _getSurveyById(surveyId: string): Survey | null {\n let survey: Survey | null = null\n this.getSurveys((surveys) => {\n survey = surveys.find((x) => x.id === surveyId) ?? null\n })\n return survey\n }\n\n private _checkSurveyEligibility(surveyId: string | Survey): { eligible: boolean; reason?: string } {\n if (isNullish(this._surveyManager)) {\n return { eligible: false, reason: 'SDK is not enabled or survey functionality is not yet loaded' }\n }\n const survey = typeof surveyId === 'string' ? this._getSurveyById(surveyId) : surveyId\n if (!survey) {\n return { eligible: false, reason: 'Survey not found' }\n }\n return this._surveyManager.checkSurveyEligibility(survey)\n }\n\n canRenderSurvey(surveyId: string | Survey): SurveyRenderReason {\n if (isNullish(this._surveyManager)) {\n logger.warn('init was not called')\n return { visible: false, disabledReason: 'SDK is not enabled or survey functionality is not yet loaded' }\n }\n const eligibility = this._checkSurveyEligibility(surveyId)\n\n return { visible: eligibility.eligible, disabledReason: eligibility.reason }\n }\n\n canRenderSurveyAsync(surveyId: string, forceReload: boolean): Promise<SurveyRenderReason> {\n // Ensure surveys are loaded before checking\n // Using Promise to wrap the callback-based getSurveys method\n if (isNullish(this._surveyManager)) {\n logger.warn('init was not called')\n return Promise.resolve({\n visible: false,\n disabledReason: 'SDK is not enabled or survey functionality is not yet loaded',\n })\n }\n\n // eslint-disable-next-line compat/compat\n return new Promise<SurveyRenderReason>((resolve) => {\n this.getSurveys((surveys) => {\n const survey = surveys.find((x) => x.id === surveyId) ?? null\n if (!survey) {\n resolve({ visible: false, disabledReason: 'Survey not found' })\n } else {\n const eligibility = this._checkSurveyEligibility(survey)\n resolve({ visible: eligibility.eligible, disabledReason: eligibility.reason })\n }\n }, forceReload)\n })\n }\n\n renderSurvey(surveyId: string | Survey, selector: string) {\n if (isNullish(this._surveyManager)) {\n logger.warn('init was not called')\n return\n }\n const survey = typeof surveyId === 'string' ? this._getSurveyById(surveyId) : surveyId\n if (!survey?.id) {\n logger.warn('Survey not found')\n return\n }\n if (!IN_APP_SURVEY_TYPES.includes(survey.type)) {\n logger.warn(`Surveys of type ${survey.type} cannot be rendered in the app`)\n return\n }\n const elem = document?.querySelector(selector)\n if (!elem) {\n logger.warn('Survey element not found')\n return\n }\n if (survey.appearance?.surveyPopupDelaySeconds) {\n logger.info(\n `Rendering survey ${survey.id} with delay of ${survey.appearance.surveyPopupDelaySeconds} seconds`\n )\n setTimeout(() => {\n logger.info(\n `Rendering survey ${survey.id} with delay of ${survey.appearance?.surveyPopupDelaySeconds} seconds`\n )\n this._surveyManager?.renderSurvey(survey, elem)\n logger.info(`Survey ${survey.id} rendered`)\n }, survey.appearance.surveyPopupDelaySeconds * 1000)\n return\n }\n this._surveyManager.renderSurvey(survey, elem)\n }\n\n displaySurvey(surveyId: string, options: DisplaySurveyOptions) {\n if (isNullish(this._surveyManager)) {\n logger.warn('init was not called')\n return\n }\n const survey = this._getSurveyById(surveyId)\n if (!survey) {\n logger.warn('Survey not found')\n return\n }\n let surveyToDisplay = survey\n if (survey.appearance?.surveyPopupDelaySeconds && options.ignoreDelay) {\n surveyToDisplay = {\n ...survey,\n appearance: {\n ...survey.appearance,\n surveyPopupDelaySeconds: 0,\n },\n }\n }\n if (options.ignoreConditions === false) {\n const canRender = this.canRenderSurvey(survey)\n if (!canRender.visible) {\n logger.warn('Survey is not eligible to be displayed: ', canRender.disabledReason)\n return\n }\n }\n if (options.displayType === DisplaySurveyType.Inline) {\n this.renderSurvey(surveyToDisplay, options.selector)\n return\n }\n this._surveyManager.handlePopoverSurvey(surveyToDisplay)\n }\n\n cancelPendingSurvey(surveyId: string): void {\n if (isNullish(this._surveyManager)) {\n logger.warn('init was not called')\n return\n }\n this._surveyManager.cancelSurvey(surveyId)\n }\n\n handlePageUnload(): void {\n this._surveyManager?.handlePageUnload()\n }\n}\n","import { PostHog } from '../../posthog-core'\nimport {\n ConversationsRemoteConfig,\n GetMessagesResponse,\n GetTicketsOptions,\n GetTicketsResponse,\n MarkAsReadResponse,\n SendMessageResponse,\n UserProvidedTraits,\n} from '../../posthog-conversations-types'\nimport { RemoteConfig } from '../../types'\nimport { assignableWindow, LazyLoadedConversationsInterface } from '../../utils/globals'\nimport { createLogger } from '../../utils/logger'\nimport { isNullish, isUndefined, isBoolean, isNull } from '@posthog/core'\n\nconst logger = createLogger('[Conversations]')\n\nexport type ConversationsManager = LazyLoadedConversationsInterface\n\nexport class PostHogConversations {\n // This is set to undefined until the remote config is loaded\n // then it's set to true if conversations are enabled\n // or false if conversations are disabled in the project settings\n private _isConversationsEnabled?: boolean = undefined\n private _conversationsManager: LazyLoadedConversationsInterface | null = null\n private _isInitializing: boolean = false\n private _remoteConfig: ConversationsRemoteConfig | null = null\n\n constructor(private _instance: PostHog) {}\n\n onRemoteConfig(response: RemoteConfig) {\n // Don't load conversations if disabled via config\n if (this._instance.config.disable_conversations) {\n return\n }\n\n const conversations = response['conversations']\n if (isNullish(conversations)) {\n return\n }\n\n // Handle both boolean and object response\n if (isBoolean(conversations)) {\n this._isConversationsEnabled = conversations\n } else {\n // It's a ConversationsRemoteConfig object\n this._isConversationsEnabled = conversations.enabled\n this._remoteConfig = conversations\n }\n\n this.loadIfEnabled()\n }\n\n reset(): void {\n // Delegate cleanup to the lazy-loaded manager (which knows about persistence keys)\n // If not loaded, there's nothing to reset anyway\n this._conversationsManager?.reset()\n this._conversationsManager = null\n\n // Reset local state\n this._isConversationsEnabled = undefined\n this._remoteConfig = null\n }\n\n loadIfEnabled() {\n if (this._conversationsManager) {\n return\n }\n if (this._isInitializing) {\n return\n }\n if (this._instance.config.disable_conversations) {\n return\n }\n if (this._instance.config.cookieless_mode && this._instance.consent.isOptedOut()) {\n return\n }\n\n const phExtensions = assignableWindow?.__PosthogExtensions__\n if (!phExtensions) {\n return\n }\n\n // Wait for remote config to load\n if (isUndefined(this._isConversationsEnabled)) {\n return\n }\n\n // Check if conversations are enabled\n if (!this._isConversationsEnabled) {\n return\n }\n\n // Check if we have the required config\n if (!this._remoteConfig || !this._remoteConfig.token) {\n logger.error('Conversations enabled but missing token in remote config.')\n return\n }\n\n // Note: Domain check is done in ConversationsManager for widget rendering\n // The conversations API is loaded regardless of domain restrictions\n\n this._isInitializing = true\n\n try {\n const initConversations = phExtensions.initConversations\n if (initConversations) {\n // Conversations code is already loaded\n this._completeInitialization(initConversations)\n this._isInitializing = false\n return\n }\n\n // If we reach here, conversations code is not loaded yet\n const loadExternalDependency = phExtensions.loadExternalDependency\n if (!loadExternalDependency) {\n this._handleLoadError('PostHog loadExternalDependency extension not found.')\n return\n }\n\n // Load the conversations bundle\n loadExternalDependency(this._instance, 'conversations', (err) => {\n if (err || !phExtensions.initConversations) {\n this._handleLoadError('Could not load conversations script', err)\n } else {\n this._completeInitialization(phExtensions.initConversations)\n }\n this._isInitializing = false\n })\n } catch (e) {\n this._handleLoadError('Error initializing conversations', e)\n this._isInitializing = false\n }\n }\n\n /** Helper to finalize conversations initialization */\n private _completeInitialization(\n initConversationsFn: (config: ConversationsRemoteConfig, posthog: PostHog) => LazyLoadedConversationsInterface\n ): void {\n if (!this._remoteConfig) {\n logger.error('Cannot complete initialization: remote config is null')\n return\n }\n\n try {\n // Pass config and PostHog instance to the extension\n this._conversationsManager = initConversationsFn(this._remoteConfig, this._instance)\n logger.info('Conversations loaded successfully')\n } catch (e) {\n this._handleLoadError('Error completing conversations initialization', e)\n }\n }\n\n /** Helper to handle initialization errors */\n private _handleLoadError(message: string, error?: any): void {\n logger.error(message, error)\n this._conversationsManager = null\n this._isInitializing = false\n }\n\n /**\n * Show the conversations widget (button and chat panel)\n */\n show(): void {\n if (!this._conversationsManager) {\n logger.warn('Conversations not loaded yet.')\n return\n }\n this._conversationsManager.show()\n }\n\n /**\n * Hide the conversations widget completely (button and chat panel)\n */\n hide(): void {\n if (!this._conversationsManager) {\n return\n }\n this._conversationsManager.hide()\n }\n\n /**\n * Check if conversations are available (enabled in remote config AND loaded)\n * Use this to check if conversations API can be used.\n */\n isAvailable(): boolean {\n return this._isConversationsEnabled === true && !isNull(this._conversationsManager)\n }\n\n /**\n * Check if the widget is currently visible (rendered and shown)\n */\n isVisible(): boolean {\n return this._conversationsManager?.isVisible() ?? false\n }\n\n /**\n * Send a message programmatically\n * Creates a new ticket if none exists or if newTicket is true\n *\n * @param message - The message text to send\n * @param userTraits - Optional user identification data (name, email)\n * @param newTicket - If true, forces creation of a new ticket (starts new conversation)\n * @returns Promise with response or null if conversations not available yet\n * @note Conversations must be available first (check with isAvailable())\n *\n * @example\n * // Send to existing or create new conversation\n * const response = await posthog.conversations.sendMessage('Hello!', {\n * name: 'John Doe',\n * email: 'john@example.com'\n * })\n *\n * @example\n * // Force creation of a new conversation/ticket\n * const newConvo = await posthog.conversations.sendMessage('Start fresh', undefined, true)\n */\n async sendMessage(\n message: string,\n userTraits?: UserProvidedTraits,\n newTicket?: boolean\n ): Promise<SendMessageResponse | null> {\n if (!this._conversationsManager) {\n logger.warn('Conversations not available yet.')\n return null\n }\n return this._conversationsManager.sendMessage(message, userTraits, newTicket)\n }\n\n /**\n * Get messages for the current or specified ticket\n *\n * @param ticketId - Optional ticket ID (defaults to current active ticket)\n * @param after - Optional ISO timestamp to fetch messages after\n * @returns Promise with messages response or null if conversations not available yet\n * @note Conversations must be available first (check with isAvailable())\n *\n * @example\n * // Get messages for current ticket\n * const messages = await posthog.conversations.getMessages()\n *\n * // Get messages for specific ticket\n * const messages = await posthog.conversations.getMessages('ticket-uuid')\n */\n async getMessages(ticketId?: string, after?: string): Promise<GetMessagesResponse | null> {\n if (!this._conversationsManager) {\n logger.warn('Conversations not available yet.')\n return null\n }\n return this._conversationsManager.getMessages(ticketId, after)\n }\n\n /**\n * Mark messages as read for the current or specified ticket\n *\n * @param ticketId - Optional ticket ID (defaults to current active ticket)\n * @returns Promise with response or null if conversations not available yet\n * @note Conversations must be available first (check with isAvailable())\n *\n * @example\n * await posthog.conversations.markAsRead()\n */\n async markAsRead(ticketId?: string): Promise<MarkAsReadResponse | null> {\n if (!this._conversationsManager) {\n logger.warn('Conversations not available yet.')\n return null\n }\n return this._conversationsManager.markAsRead(ticketId)\n }\n\n /**\n * Get list of tickets for the current widget session\n *\n * @param options - Optional filtering and pagination options\n * @returns Promise with tickets response or null if conversations not available yet\n * @note Conversations must be available first (check with isAvailable())\n *\n * @example\n * const tickets = await posthog.conversations.getTickets({\n * limit: 10,\n * offset: 0,\n * status: 'open'\n * })\n */\n async getTickets(options?: GetTicketsOptions): Promise<GetTicketsResponse | null> {\n if (!this._conversationsManager) {\n logger.warn('Conversations not available yet.')\n return null\n }\n return this._conversationsManager.getTickets(options)\n }\n\n /**\n * Get the current active ticket ID\n * Returns null if no conversation has been started yet or if not available\n *\n * @returns Ticket ID or null\n * @note Safe to call before conversations are available, will return null\n *\n * @example\n * const ticketId = posthog.conversations.getCurrentTicketId()\n * if (ticketId) {\n * console.log('Active conversation:', ticketId)\n * }\n */\n getCurrentTicketId(): string | null {\n return this._conversationsManager?.getCurrentTicketId() ?? null\n }\n\n /**\n * Get the widget session ID (persistent browser identifier)\n * This ID is used for access control and stays the same across page loads\n * Returns null if conversations not available yet\n *\n * @returns Session ID or null if not available\n * @note Safe to call before conversations are available, will return null\n *\n * @example\n * const sessionId = posthog.conversations.getWidgetSessionId()\n * if (!sessionId) {\n * // Conversations not available yet\n * posthog.conversations.show()\n * }\n */\n getWidgetSessionId(): string | null {\n return this._conversationsManager?.getWidgetSessionId() ?? null\n }\n}\n","import { CAPTURE_RATE_LIMIT } from './constants'\nimport type { PostHog } from './posthog-core'\nimport { RequestResponse } from './types'\nimport { createLogger } from './utils/logger'\n\nconst logger = createLogger('[RateLimiter]')\n\nconst ONE_MINUTE_IN_MILLISECONDS = 60 * 1000\nconst RATE_LIMIT_EVENT = '$$client_ingestion_warning'\n\ninterface CaptureResponse {\n quota_limited?: string[]\n}\n\nexport class RateLimiter {\n instance: PostHog\n serverLimits: Record<string, number> = {}\n\n captureEventsPerSecond: number\n captureEventsBurstLimit: number\n lastEventRateLimited = false\n\n constructor(instance: PostHog) {\n this.instance = instance\n\n this.captureEventsPerSecond = instance.config.rate_limiting?.events_per_second || 10\n this.captureEventsBurstLimit = Math.max(\n instance.config.rate_limiting?.events_burst_limit || this.captureEventsPerSecond * 10,\n this.captureEventsPerSecond\n )\n\n this.lastEventRateLimited = this.clientRateLimitContext(true).isRateLimited\n }\n\n public clientRateLimitContext(checkOnly = false): {\n isRateLimited: boolean\n remainingTokens: number\n } {\n // This is primarily to prevent runaway loops from flooding capture with millions of events for a single user.\n // It's as much for our protection as theirs.\n const now = new Date().getTime()\n const bucket = this.instance.persistence?.get_property(CAPTURE_RATE_LIMIT) ?? {\n tokens: this.captureEventsBurstLimit,\n last: now,\n }\n\n bucket.tokens += ((now - bucket.last) / 1000) * this.captureEventsPerSecond\n bucket.last = now\n\n if (bucket.tokens > this.captureEventsBurstLimit) {\n bucket.tokens = this.captureEventsBurstLimit\n }\n\n const isRateLimited = bucket.tokens < 1\n\n if (!isRateLimited && !checkOnly) {\n bucket.tokens = Math.max(0, bucket.tokens - 1)\n }\n\n if (isRateLimited && !this.lastEventRateLimited && !checkOnly) {\n this.instance.capture(\n RATE_LIMIT_EVENT,\n {\n $$client_ingestion_warning_message: `posthog-js client rate limited. Config is set to ${this.captureEventsPerSecond} events per second and ${this.captureEventsBurstLimit} events burst limit.`,\n },\n {\n skip_client_rate_limiting: true,\n }\n )\n }\n\n this.lastEventRateLimited = isRateLimited\n this.instance.persistence?.set_property(CAPTURE_RATE_LIMIT, bucket)\n\n return {\n isRateLimited,\n remainingTokens: bucket.tokens,\n }\n }\n\n public isServerRateLimited(batchKey: string | undefined): boolean {\n const retryAfter = this.serverLimits[batchKey || 'events'] || false\n\n if (retryAfter === false) {\n return false\n }\n return new Date().getTime() < retryAfter\n }\n\n public checkForLimiting = (httpResponse: RequestResponse): void => {\n const text = httpResponse.text\n\n if (!text || !text.length) {\n return\n }\n\n try {\n const response: CaptureResponse = JSON.parse(text)\n const quotaLimitedProducts = response.quota_limited || []\n quotaLimitedProducts.forEach((batchKey) => {\n logger.info(`${batchKey || 'events'} is quota limited.`)\n this.serverLimits[batchKey] = new Date().getTime() + ONE_MINUTE_IN_MILLISECONDS\n })\n } catch (e: any) {\n logger.warn(`could not rate limit - continuing. Error: \"${e?.message}\"`, { text })\n return\n }\n }\n}\n","import { PostHog } from './posthog-core'\nimport { RemoteConfig } from './types'\n\nimport { createLogger } from './utils/logger'\nimport { assignableWindow } from './utils/globals'\n\nconst logger = createLogger('[RemoteConfig]')\n\nexport class RemoteConfigLoader {\n constructor(private readonly _instance: PostHog) {}\n\n get remoteConfig(): RemoteConfig | undefined {\n return assignableWindow._POSTHOG_REMOTE_CONFIG?.[this._instance.config.token]?.config\n }\n\n private _loadRemoteConfigJs(cb: (config?: RemoteConfig) => void): void {\n if (assignableWindow.__PosthogExtensions__?.loadExternalDependency) {\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(this._instance, 'remote-config', () => {\n return cb(this.remoteConfig)\n })\n } else {\n logger.error('PostHog Extensions not found. Cannot load remote config.')\n cb()\n }\n }\n\n private _loadRemoteConfigJSON(cb: (config?: RemoteConfig) => void): void {\n this._instance._send_request({\n method: 'GET',\n url: this._instance.requestRouter.endpointFor('assets', `/array/${this._instance.config.token}/config`),\n callback: (response) => {\n cb(response.json as RemoteConfig | undefined)\n },\n })\n }\n\n load(): void {\n try {\n // Attempt 1 - use the pre-loaded config if it came as part of the token-specific array.js\n if (this.remoteConfig) {\n logger.info('Using preloaded remote config', this.remoteConfig)\n this._onRemoteConfig(this.remoteConfig)\n return\n }\n\n if (this._instance._shouldDisableFlags()) {\n // This setting is essentially saying \"dont call external APIs\" hence we respect it here\n logger.warn('Remote config is disabled. Falling back to local config.')\n return\n }\n\n // Attempt 2 - if we have the external deps loader then lets load the script version of the config that includes site apps\n this._loadRemoteConfigJs((config) => {\n if (!config) {\n logger.info('No config found after loading remote JS config. Falling back to JSON.')\n // Attempt 3 Load the config json instead of the script - we won't get site apps etc. but we will get the config\n this._loadRemoteConfigJSON((config) => {\n this._onRemoteConfig(config)\n })\n return\n }\n\n this._onRemoteConfig(config)\n })\n } catch (error) {\n logger.error('Error loading remote config', error)\n }\n }\n\n private _onRemoteConfig(config?: RemoteConfig): void {\n // NOTE: Once this is rolled out we will remove the /flags related code above. Until then the code duplication is fine.\n if (!config) {\n logger.error('Failed to fetch remote config from PostHog.')\n return\n }\n\n if (!this._instance.config.__preview_remote_config) {\n logger.info('__preview_remote_config is disabled. Logging config instead', config)\n return\n }\n\n this._instance._onRemoteConfig(config)\n\n // We only need to reload if we haven't already loaded the flags or if the request is in flight\n if (config.hasFeatureFlags !== false) {\n // If the config has feature flags, we need to call /flags to get the feature flags\n // This completely separates it from the config logic which is good in terms of separation of concerns\n this._instance.featureFlags.ensureFlagsLoaded()\n }\n }\n}\n","import { QueuedRequestWithOptions, RequestQueueConfig } from './types'\nimport { each } from './utils'\n\nimport { isArray, isUndefined, clampToRange } from '@posthog/core'\nimport { logger } from './utils/logger'\n\nexport const DEFAULT_FLUSH_INTERVAL_MS = 3000\n\nexport class RequestQueue {\n // We start in a paused state and only start flushing when enabled by the parent\n private _isPaused: boolean = true\n private _queue: QueuedRequestWithOptions[] = []\n private _flushTimeout?: ReturnType<typeof setTimeout>\n private _flushTimeoutMs: number\n private _sendRequest: (req: QueuedRequestWithOptions) => void\n\n constructor(sendRequest: (req: QueuedRequestWithOptions) => void, config?: RequestQueueConfig) {\n this._flushTimeoutMs = clampToRange(\n config?.flush_interval_ms || DEFAULT_FLUSH_INTERVAL_MS,\n 250,\n 5000,\n logger.createLogger('flush interval'),\n DEFAULT_FLUSH_INTERVAL_MS\n )\n this._sendRequest = sendRequest\n }\n\n enqueue(req: QueuedRequestWithOptions): void {\n this._queue.push(req)\n\n if (!this._flushTimeout) {\n this._setFlushTimeout()\n }\n }\n\n unload(): void {\n this._clearFlushTimeout()\n const requests = this._queue.length > 0 ? this._formatQueue() : {}\n const requestValues = Object.values(requests)\n\n // Always force events to be sent before recordings, as events are more important, and recordings are bigger and thus less likely to arrive\n const sortedRequests = [\n ...requestValues.filter((r) => r.url.indexOf('/e') === 0),\n ...requestValues.filter((r) => r.url.indexOf('/e') !== 0),\n ]\n sortedRequests.map((req) => {\n this._sendRequest({ ...req, transport: 'sendBeacon' })\n })\n }\n\n enable(): void {\n this._isPaused = false\n this._setFlushTimeout()\n }\n\n private _setFlushTimeout(): void {\n if (this._isPaused) {\n return\n }\n this._flushTimeout = setTimeout(() => {\n this._clearFlushTimeout()\n if (this._queue.length > 0) {\n const requests = this._formatQueue()\n for (const key in requests) {\n const req = requests[key]\n const now = new Date().getTime()\n\n if (req.data && isArray(req.data)) {\n each(req.data, (data) => {\n data['offset'] = Math.abs(data['timestamp'] - now)\n delete data['timestamp']\n })\n }\n this._sendRequest(req)\n }\n }\n }, this._flushTimeoutMs)\n }\n\n private _clearFlushTimeout(): void {\n clearTimeout(this._flushTimeout)\n this._flushTimeout = undefined\n }\n\n private _formatQueue(): Record<string, QueuedRequestWithOptions> {\n const requests: Record<string, QueuedRequestWithOptions> = {}\n each(this._queue, (request: QueuedRequestWithOptions) => {\n const req = request\n const key = (req ? req.batchKey : null) || req.url\n if (isUndefined(requests[key])) {\n // TODO: What about this -it seems to batch data into an array - do we always want that?\n requests[key] = { ...req, data: [] }\n }\n\n requests[key].data?.push(req.data)\n })\n\n this._queue = []\n return requests\n }\n}\n","import { RetriableRequestWithOptions } from './types'\n\nimport { isNumber, isUndefined } from '@posthog/core'\nimport { logger } from './utils/logger'\nimport { window } from './utils/globals'\nimport { PostHog } from './posthog-core'\nimport { extendURLParams } from './request'\nimport { addEventListener } from './utils'\n\nconst thirtyMinutes = 30 * 60 * 1000\n\n/**\n * Generates a jitter-ed exponential backoff delay in milliseconds\n *\n * The base value is 6 seconds, which is doubled with each retry\n * up to the maximum of 30 minutes\n *\n * Each value then has +/- 50% jitter\n *\n * Giving a range of 6 seconds up to 45 minutes\n */\nexport function pickNextRetryDelay(retriesPerformedSoFar: number): number {\n const rawBackoffTime = 3000 * 2 ** retriesPerformedSoFar\n const minBackoff = rawBackoffTime / 2\n const cappedBackoffTime = Math.min(thirtyMinutes, rawBackoffTime)\n const jitterFraction = Math.random() - 0.5 // A random number between -0.5 and 0.5\n const jitter = jitterFraction * (cappedBackoffTime - minBackoff)\n return Math.ceil(cappedBackoffTime + jitter)\n}\n\ninterface RetryQueueElement {\n retryAt: number\n requestOptions: RetriableRequestWithOptions\n}\n\nexport class RetryQueue {\n private _isPolling: boolean = false\n private _poller: number | undefined\n private _pollIntervalMs: number = 3000\n private _queue: RetryQueueElement[] = []\n private _areWeOnline: boolean\n private _onlineListener: (() => void) | undefined\n private _offlineListener: (() => void) | undefined\n\n constructor(private _instance: PostHog) {\n this._queue = []\n this._areWeOnline = true\n\n if (!isUndefined(window) && 'onLine' in window.navigator) {\n this._areWeOnline = window.navigator.onLine\n\n this._onlineListener = () => {\n this._areWeOnline = true\n this._flush()\n }\n\n this._offlineListener = () => {\n this._areWeOnline = false\n }\n\n addEventListener(window, 'online', this._onlineListener)\n addEventListener(window, 'offline', this._offlineListener)\n }\n }\n\n get length() {\n return this._queue.length\n }\n\n retriableRequest({ retriesPerformedSoFar, ...options }: RetriableRequestWithOptions): void {\n if (isNumber(retriesPerformedSoFar) && retriesPerformedSoFar > 0) {\n options.url = extendURLParams(options.url, { retry_count: retriesPerformedSoFar })\n }\n\n this._instance._send_request({\n ...options,\n callback: (response) => {\n if (response.statusCode !== 200 && (response.statusCode < 400 || response.statusCode >= 500)) {\n if ((retriesPerformedSoFar ?? 0) < 10) {\n this._enqueue({\n retriesPerformedSoFar,\n ...options,\n })\n return\n }\n }\n\n options.callback?.(response)\n },\n })\n }\n\n private _enqueue(requestOptions: RetriableRequestWithOptions): void {\n const retriesPerformedSoFar = requestOptions.retriesPerformedSoFar || 0\n requestOptions.retriesPerformedSoFar = retriesPerformedSoFar + 1\n\n const msToNextRetry = pickNextRetryDelay(retriesPerformedSoFar)\n const retryAt = Date.now() + msToNextRetry\n\n this._queue.push({ retryAt, requestOptions })\n\n let logMessage = `Enqueued failed request for retry in ${msToNextRetry}`\n if (!navigator.onLine) {\n logMessage += ' (Browser is offline)'\n }\n logger.warn(logMessage)\n\n if (!this._isPolling) {\n this._isPolling = true\n this._poll()\n }\n }\n\n private _poll(): void {\n this._poller && clearTimeout(this._poller)\n\n if (this._queue.length === 0) {\n this._isPolling = false\n this._poller = undefined\n return\n }\n\n this._poller = setTimeout(() => {\n if (this._areWeOnline && this._queue.length > 0) {\n this._flush()\n }\n this._poll()\n }, this._pollIntervalMs) as any as number\n }\n\n private _flush(): void {\n const now = Date.now()\n const notToFlush: RetryQueueElement[] = []\n const toFlush = this._queue.filter((item) => {\n if (item.retryAt < now) {\n return true\n }\n notToFlush.push(item)\n return false\n })\n\n this._queue = notToFlush\n\n if (toFlush.length > 0) {\n for (const { requestOptions } of toFlush) {\n this.retriableRequest(requestOptions)\n }\n }\n }\n\n unload(): void {\n if (this._poller) {\n clearTimeout(this._poller)\n this._poller = undefined\n }\n\n this._isPolling = false\n\n if (!isUndefined(window)) {\n if (this._onlineListener) {\n window.removeEventListener('online', this._onlineListener)\n this._onlineListener = undefined\n }\n if (this._offlineListener) {\n window.removeEventListener('offline', this._offlineListener)\n this._offlineListener = undefined\n }\n }\n\n for (const { requestOptions } of this._queue) {\n try {\n // we've had send beacon in place for at least 2 years\n // eslint-disable-next-line compat/compat\n this._instance._send_request({\n ...requestOptions,\n transport: 'sendBeacon',\n })\n } catch (e) {\n // Note sendBeacon automatically retries, and after the first retry it will lose reference to contextual `this`.\n // This means in some cases `this.getConfig` will be undefined.\n logger.error(e)\n }\n }\n this._queue = []\n }\n}\n","import { window } from './utils/globals'\nimport { PostHog } from './posthog-core'\nimport { addEventListener } from './utils'\nimport { isArray } from '@posthog/core'\n\nexport interface ScrollContext {\n // scroll is how far down the page the user has scrolled,\n // content is how far down the page the user can view content\n // (e.g. if the page is 1000 tall, but the user's screen is only 500 tall,\n // and they don't scroll at all, then scroll is 0 and content is 500)\n maxScrollHeight?: number\n maxScrollY?: number\n lastScrollY?: number\n maxContentHeight?: number\n maxContentY?: number\n lastContentY?: number\n}\n\n// This class is responsible for tracking scroll events and maintaining the scroll context\nexport class ScrollManager {\n private _context: ScrollContext | undefined\n\n constructor(private _instance: PostHog) {}\n\n getContext(): ScrollContext | undefined {\n return this._context\n }\n\n resetContext(): ScrollContext | undefined {\n const ctx = this._context\n\n // update the scroll properties for the new page, but wait until the next tick\n // of the event loop\n setTimeout(this._updateScrollData, 0)\n\n return ctx\n }\n\n private _updateScrollData = () => {\n if (!this._context) {\n this._context = {}\n }\n\n const el = this.scrollElement()\n\n const scrollY = this.scrollY()\n const scrollHeight = el ? Math.max(0, el.scrollHeight - el.clientHeight) : 0\n const contentY = scrollY + (el?.clientHeight || 0)\n const contentHeight = el?.scrollHeight || 0\n\n this._context.lastScrollY = Math.ceil(scrollY)\n this._context.maxScrollY = Math.max(scrollY, this._context.maxScrollY ?? 0)\n this._context.maxScrollHeight = Math.max(scrollHeight, this._context.maxScrollHeight ?? 0)\n\n this._context.lastContentY = contentY\n this._context.maxContentY = Math.max(contentY, this._context.maxContentY ?? 0)\n this._context.maxContentHeight = Math.max(contentHeight, this._context.maxContentHeight ?? 0)\n }\n\n // `capture: true` is required to get scroll events for other scrollable elements\n // on the page, not just the window\n // see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#usecapture\n startMeasuringScrollPosition() {\n addEventListener(window, 'scroll', this._updateScrollData, { capture: true })\n addEventListener(window, 'scrollend', this._updateScrollData, { capture: true })\n addEventListener(window, 'resize', this._updateScrollData)\n }\n\n public scrollElement(): Element | undefined {\n if (this._instance.config.scroll_root_selector) {\n const selectors = isArray(this._instance.config.scroll_root_selector)\n ? this._instance.config.scroll_root_selector\n : [this._instance.config.scroll_root_selector]\n for (const selector of selectors) {\n const element = window?.document.querySelector(selector)\n if (element) {\n return element\n }\n }\n return undefined\n } else {\n return window?.document.documentElement\n }\n }\n\n public scrollY(): number {\n if (this._instance.config.scroll_root_selector) {\n const element = this.scrollElement()\n return (element && element.scrollTop) || 0\n } else {\n return window ? window.scrollY || window.pageYOffset || window.document.documentElement.scrollTop || 0 : 0\n }\n }\n\n public scrollX(): number {\n if (this._instance.config.scroll_root_selector) {\n const element = this.scrollElement()\n return (element && element.scrollLeft) || 0\n } else {\n return window ? window.scrollX || window.pageXOffset || window.document.documentElement.scrollLeft || 0 : 0\n }\n }\n}\n","/* Store some session-level attribution-related properties in the persistence layer\n *\n * These have the same lifespan as a session_id, meaning that if the session_id changes, these properties will be reset.\n *\n * We only store the entry URL and referrer, and derive many props (such as utm tags) from those.\n *\n * Given that the cookie is limited to 4K bytes, we don't want to store too much data, so we chose not to store device\n * properties (such as browser, OS, etc) here, as usually getting the current value of those from event properties is\n * sufficient.\n */\nimport { getPersonInfo, getPersonPropsFromInfo } from './utils/event-utils'\nimport type { SessionIdManager } from './sessionid'\nimport type { PostHogPersistence } from './posthog-persistence'\nimport { CLIENT_SESSION_PROPS } from './constants'\nimport type { PostHog } from './posthog-core'\nimport { each, stripEmptyProperties } from './utils'\nimport { stripLeadingDollar } from '@posthog/core'\n\ninterface LegacySessionSourceProps {\n initialPathName: string\n referringDomain: string // Is actually referring host, but named referring domain for internal consistency. Should contain a port if there is one.\n utm_medium?: string\n utm_source?: string\n utm_campaign?: string\n utm_content?: string\n utm_term?: string\n}\n\ninterface CurrentSessionSourceProps {\n r: string // Referring host\n u: string | undefined // full URL\n}\n\ninterface StoredSessionSourceProps {\n sessionId: string\n props: LegacySessionSourceProps | CurrentSessionSourceProps\n}\n\nconst generateSessionSourceParams = (posthog?: PostHog): LegacySessionSourceProps | CurrentSessionSourceProps => {\n return getPersonInfo(posthog?.config.mask_personal_data_properties, posthog?.config.custom_personal_data_properties)\n}\n\nexport class SessionPropsManager {\n private readonly _instance: PostHog\n private readonly _sessionIdManager: SessionIdManager\n private readonly _persistence: PostHogPersistence\n private readonly _sessionSourceParamGenerator: (\n instance?: PostHog\n ) => LegacySessionSourceProps | CurrentSessionSourceProps\n\n constructor(\n instance: PostHog,\n sessionIdManager: SessionIdManager,\n persistence: PostHogPersistence,\n sessionSourceParamGenerator?: (instance?: PostHog) => LegacySessionSourceProps | CurrentSessionSourceProps\n ) {\n this._instance = instance\n this._sessionIdManager = sessionIdManager\n this._persistence = persistence\n this._sessionSourceParamGenerator = sessionSourceParamGenerator || generateSessionSourceParams\n\n this._sessionIdManager.onSessionId(this._onSessionIdCallback)\n }\n\n _getStored(): StoredSessionSourceProps | undefined {\n return this._persistence.props[CLIENT_SESSION_PROPS]\n }\n\n _onSessionIdCallback = (sessionId: string) => {\n const stored = this._getStored()\n if (stored && stored.sessionId === sessionId) {\n return\n }\n\n const newProps: StoredSessionSourceProps = {\n sessionId,\n props: this._sessionSourceParamGenerator(this._instance),\n }\n this._persistence.register({ [CLIENT_SESSION_PROPS]: newProps })\n }\n\n getSetOnceProps() {\n const p = this._getStored()?.props\n if (!p) {\n return {}\n }\n if ('r' in p) {\n return getPersonPropsFromInfo(p)\n } else {\n return {\n $referring_domain: p.referringDomain,\n $pathname: p.initialPathName,\n utm_source: p.utm_source,\n utm_campaign: p.utm_campaign,\n utm_medium: p.utm_medium,\n utm_content: p.utm_content,\n utm_term: p.utm_term,\n }\n }\n }\n\n getSessionProps() {\n // it's the same props, but don't include null for unset properties, and add a prefix\n const p: Record<string, any> = {}\n each(stripEmptyProperties(this.getSetOnceProps()), (v, k) => {\n if (k === '$current_url') {\n // $session_entry_current_url would be a weird name, call it $session_entry_url instead\n k = 'url'\n }\n p[`$session_entry_${stripLeadingDollar(k)}`] = v\n })\n return p\n }\n}\n","import { PostHogPersistence } from './posthog-persistence'\nimport { SESSION_ID } from './constants'\nimport { sessionStore } from './storage'\nimport { PostHogConfig, SessionIdChangedCallback } from './types'\nimport { uuid7ToTimestampMs, uuidv7 } from './uuidv7'\nimport { window } from './utils/globals'\n\nimport { createLogger } from './utils/logger'\n\nimport { isArray, isNumber, isUndefined, clampToRange } from '@posthog/core'\nimport { PostHog } from './posthog-core'\nimport { addEventListener } from './utils'\nimport { SimpleEventEmitter } from './utils/simple-event-emitter'\n\nconst logger = createLogger('[SessionId]')\n\nexport const DEFAULT_SESSION_IDLE_TIMEOUT_SECONDS = 30 * 60 // 30 minutes\nexport const MAX_SESSION_IDLE_TIMEOUT_SECONDS = 10 * 60 * 60 // 10 hours\nconst MIN_SESSION_IDLE_TIMEOUT_SECONDS = 60 // 1 minute\nconst SESSION_LENGTH_LIMIT_MILLISECONDS = 24 * 3600 * 1000 // 24 hours\n\nexport class SessionIdManager {\n private readonly _sessionIdGenerator: () => string\n private readonly _windowIdGenerator: () => string\n private _config: Partial<PostHogConfig>\n private _persistence: PostHogPersistence\n private _windowId: string | null | undefined\n private _sessionId: string | null | undefined\n private readonly _window_id_storage_key: string\n private readonly _primary_window_exists_storage_key: string\n private _sessionStartTimestamp: number | null\n\n private _sessionActivityTimestamp: number | null\n private _sessionIdChangedHandlers: SessionIdChangedCallback[] = []\n private readonly _sessionTimeoutMs: number\n\n // we track activity so we can end the session proactively when it has passed the idle timeout\n private _enforceIdleTimeout: ReturnType<typeof setTimeout> | undefined\n\n private _beforeUnloadListener: (() => void) | undefined = undefined\n\n private _eventEmitter: SimpleEventEmitter = new SimpleEventEmitter()\n public on(event: 'forcedIdleReset', handler: () => void): () => void {\n return this._eventEmitter.on(event, handler)\n }\n\n constructor(instance: PostHog, sessionIdGenerator?: () => string, windowIdGenerator?: () => string) {\n if (!instance.persistence) {\n throw new Error('SessionIdManager requires a PostHogPersistence instance')\n }\n if (instance.config.cookieless_mode === 'always') {\n throw new Error('SessionIdManager cannot be used with cookieless_mode=\"always\"')\n }\n\n this._config = instance.config\n this._persistence = instance.persistence\n this._windowId = undefined\n this._sessionId = undefined\n this._sessionStartTimestamp = null\n this._sessionActivityTimestamp = null\n this._sessionIdGenerator = sessionIdGenerator || uuidv7\n this._windowIdGenerator = windowIdGenerator || uuidv7\n\n const persistenceName = this._config['persistence_name'] || this._config['token']\n\n const desiredTimeout = this._config['session_idle_timeout_seconds'] || DEFAULT_SESSION_IDLE_TIMEOUT_SECONDS\n this._sessionTimeoutMs =\n clampToRange(\n desiredTimeout,\n MIN_SESSION_IDLE_TIMEOUT_SECONDS,\n MAX_SESSION_IDLE_TIMEOUT_SECONDS,\n logger.createLogger('session_idle_timeout_seconds'),\n DEFAULT_SESSION_IDLE_TIMEOUT_SECONDS\n ) * 1000\n\n instance.register({ $configured_session_timeout_ms: this._sessionTimeoutMs })\n this._resetIdleTimer()\n\n this._window_id_storage_key = 'ph_' + persistenceName + '_window_id'\n this._primary_window_exists_storage_key = 'ph_' + persistenceName + '_primary_window_exists'\n\n // primary_window_exists is set when the DOM has been loaded and is cleared on unload\n // if it exists here it means there was no unload which suggests this window is opened as a tab duplication, window.open, etc.\n if (this._canUseSessionStorage()) {\n const lastWindowId = sessionStore._parse(this._window_id_storage_key)\n\n const primaryWindowExists = sessionStore._parse(this._primary_window_exists_storage_key)\n if (lastWindowId && !primaryWindowExists) {\n // Persist window from previous storage state\n this._windowId = lastWindowId\n } else {\n // Wipe any reference to previous window id\n sessionStore._remove(this._window_id_storage_key)\n }\n // Flag this session as having a primary window\n sessionStore._set(this._primary_window_exists_storage_key, true)\n }\n\n if (this._config.bootstrap?.sessionID) {\n try {\n const sessionStartTimestamp = uuid7ToTimestampMs(this._config.bootstrap.sessionID)\n this._setSessionId(this._config.bootstrap.sessionID, new Date().getTime(), sessionStartTimestamp)\n } catch (e) {\n logger.error('Invalid sessionID in bootstrap', e)\n }\n }\n\n this._listenToReloadWindow()\n }\n\n get sessionTimeoutMs(): number {\n return this._sessionTimeoutMs\n }\n\n onSessionId(callback: SessionIdChangedCallback): () => void {\n // KLUDGE: when running in tests the handlers array was always undefined\n // it's yucky but safe to set it here so that it's always definitely available\n if (isUndefined(this._sessionIdChangedHandlers)) {\n this._sessionIdChangedHandlers = []\n }\n\n this._sessionIdChangedHandlers.push(callback)\n if (this._sessionId) {\n callback(this._sessionId, this._windowId)\n }\n return () => {\n this._sessionIdChangedHandlers = this._sessionIdChangedHandlers.filter((h) => h !== callback)\n }\n }\n\n private _canUseSessionStorage(): boolean {\n // We only want to use sessionStorage if persistence is enabled and not memory storage\n return this._config.persistence !== 'memory' && !this._persistence._disabled && sessionStore._is_supported()\n }\n\n // Note: this tries to store the windowId in sessionStorage. SessionStorage is unique to the current window/tab,\n // and persists page loads/reloads. So it's uniquely suited for storing the windowId. This function also respects\n // when persistence is disabled (by user config) and when sessionStorage is not supported (it *should* be supported on all browsers),\n // and in that case, it falls back to memory (which sadly, won't persist page loads)\n private _setWindowId(windowId: string): void {\n if (windowId !== this._windowId) {\n this._windowId = windowId\n if (this._canUseSessionStorage()) {\n sessionStore._set(this._window_id_storage_key, windowId)\n }\n }\n }\n\n private _getWindowId(): string | null {\n if (this._windowId) {\n return this._windowId\n }\n if (this._canUseSessionStorage()) {\n return sessionStore._parse(this._window_id_storage_key)\n }\n // New window id will be generated\n return null\n }\n\n // Note: 'this.persistence.register' can be disabled in the config.\n // In that case, this works by storing sessionId and the timestamp in memory.\n private _setSessionId(\n sessionId: string | null,\n sessionActivityTimestamp: number | null,\n sessionStartTimestamp: number | null\n ): void {\n if (\n sessionId !== this._sessionId ||\n sessionActivityTimestamp !== this._sessionActivityTimestamp ||\n sessionStartTimestamp !== this._sessionStartTimestamp\n ) {\n this._sessionStartTimestamp = sessionStartTimestamp\n this._sessionActivityTimestamp = sessionActivityTimestamp\n this._sessionId = sessionId\n\n this._persistence.register({\n [SESSION_ID]: [sessionActivityTimestamp, sessionId, sessionStartTimestamp],\n })\n }\n }\n\n private _getSessionId(): [number, string, number] {\n // Always read from persistence - it's the source of truth\n // The in-memory cache could become stale (e.g., in a frozen tab scenario where\n // time passes but the cache isn't updated)\n const sessionIdInfo = this._persistence.props[SESSION_ID]\n\n if (isArray(sessionIdInfo) && sessionIdInfo.length === 2) {\n // Storage does not yet have a session start time. Add the last activity timestamp as the start time\n sessionIdInfo.push(sessionIdInfo[0])\n }\n\n return sessionIdInfo || [0, null, 0]\n }\n\n // Resets the session id by setting it to null. On the subsequent call to checkAndGetSessionAndWindowId,\n // new ids will be generated.\n resetSessionId(): void {\n this._setSessionId(null, null, null)\n }\n\n /**\n * Cleans up resources used by SessionIdManager.\n * Should be called when the SessionIdManager is no longer needed to prevent memory leaks.\n */\n destroy(): void {\n // Clear the idle timeout timer\n clearTimeout(this._enforceIdleTimeout)\n this._enforceIdleTimeout = undefined\n\n // Remove the beforeunload event listener\n if (this._beforeUnloadListener && window) {\n window.removeEventListener('beforeunload', this._beforeUnloadListener, { capture: false } as any)\n this._beforeUnloadListener = undefined\n }\n\n // Clear session id changed handlers\n this._sessionIdChangedHandlers = []\n }\n\n /*\n * Listens to window unloads and removes the primaryWindowExists key from sessionStorage.\n * Reloaded or fresh tabs created after a DOM unloads (reloading the same tab) WILL NOT have this primaryWindowExists flag in session storage.\n * Cloned sessions (new tab, tab duplication, window.open(), ...) WILL have this primaryWindowExists flag in their copied session storage.\n * We conditionally check the primaryWindowExists value in the constructor to decide if the window id in the last session storage should be carried over.\n */\n private _listenToReloadWindow(): void {\n this._beforeUnloadListener = () => {\n if (this._canUseSessionStorage()) {\n sessionStore._remove(this._primary_window_exists_storage_key)\n }\n }\n addEventListener(window, 'beforeunload', this._beforeUnloadListener, { capture: false })\n }\n\n private _sessionHasBeenIdleTooLong = (timestamp: number, lastActivityTimestamp: number) => {\n return Math.abs(timestamp - lastActivityTimestamp) > this.sessionTimeoutMs\n }\n\n /*\n * This function returns the current sessionId and windowId. It should be used to\n * access these values over directly calling `._sessionId` or `._windowId`.\n * In addition to returning the sessionId and windowId, this function also manages cycling the\n * sessionId and windowId when appropriate by doing the following:\n *\n * 1. If the sessionId or windowId is not set, it will generate a new one and store it.\n * 2. If the readOnly param is set to false, it will:\n * a. Check if it has been > SESSION_CHANGE_THRESHOLD since the last call with this flag set.\n * If so, it will generate a new sessionId and store it.\n * b. Update the timestamp stored with the sessionId to ensure the current session is extended\n * for the appropriate amount of time.\n *\n * @param {boolean} readOnly (optional) Defaults to False. Should be set to True when the call to the function should not extend or cycle the session (e.g. being called for non-user generated events)\n * @param {Number} timestamp (optional) Defaults to the current time. The timestamp to be stored with the sessionId (used when determining if a new sessionId should be generated)\n */\n checkAndGetSessionAndWindowId(readOnly = false, _timestamp: number | null = null) {\n if (this._config.cookieless_mode === 'always') {\n throw new Error('checkAndGetSessionAndWindowId should not be called with cookieless_mode=\"always\"')\n }\n const timestamp = _timestamp || new Date().getTime()\n\n // eslint-disable-next-line prefer-const\n let [lastActivityTimestamp, sessionId, startTimestamp] = this._getSessionId()\n let windowId = this._getWindowId()\n\n const sessionPastMaximumLength =\n isNumber(startTimestamp) &&\n startTimestamp > 0 &&\n Math.abs(timestamp - startTimestamp) > SESSION_LENGTH_LIMIT_MILLISECONDS\n\n let valuesChanged = false\n const noSessionId = !sessionId\n const activityTimeout =\n !noSessionId && !readOnly && this._sessionHasBeenIdleTooLong(timestamp, lastActivityTimestamp)\n if (noSessionId || activityTimeout || sessionPastMaximumLength) {\n sessionId = this._sessionIdGenerator()\n windowId = this._windowIdGenerator()\n logger.info('new session ID generated', {\n sessionId,\n windowId,\n changeReason: { noSessionId, activityTimeout, sessionPastMaximumLength },\n })\n startTimestamp = timestamp\n valuesChanged = true\n } else if (!windowId) {\n windowId = this._windowIdGenerator()\n valuesChanged = true\n }\n\n const newActivityTimestamp =\n lastActivityTimestamp === 0 || !readOnly || sessionPastMaximumLength ? timestamp : lastActivityTimestamp\n const sessionStartTimestamp = startTimestamp === 0 ? new Date().getTime() : startTimestamp\n\n this._setWindowId(windowId)\n this._setSessionId(sessionId, newActivityTimestamp, sessionStartTimestamp)\n\n if (!readOnly) {\n this._resetIdleTimer()\n }\n\n if (valuesChanged) {\n this._sessionIdChangedHandlers.forEach((handler) =>\n handler(\n sessionId,\n windowId,\n valuesChanged ? { noSessionId, activityTimeout, sessionPastMaximumLength } : undefined\n )\n )\n }\n\n return {\n sessionId,\n windowId,\n sessionStartTimestamp,\n changeReason: valuesChanged ? { noSessionId, activityTimeout, sessionPastMaximumLength } : undefined,\n lastActivityTimestamp: lastActivityTimestamp,\n }\n }\n\n private _resetIdleTimer() {\n clearTimeout(this._enforceIdleTimeout)\n this._enforceIdleTimeout = setTimeout(() => {\n // enforce idle timeout a little after the session timeout to ensure the session is reset even without activity\n // we need to check session activity first in case a different window has kept the session active\n // while this window has been idle - and the timer has not progressed - e.g. window memory frozen while hidden\n const [lastActivityTimestamp] = this._getSessionId()\n if (this._sessionHasBeenIdleTooLong(new Date().getTime(), lastActivityTimestamp)) {\n const idleSessionId = this._sessionId\n this.resetSessionId()\n this._eventEmitter.emit('forcedIdleReset', { idleSessionId })\n }\n }, this.sessionTimeoutMs * 1.1)\n }\n}\n","import { PostHog } from './posthog-core'\nimport { CaptureResult, Properties, RemoteConfig, SiteApp, SiteAppGlobals, SiteAppLoader } from './types'\nimport { assignableWindow } from './utils/globals'\nimport { createLogger } from './utils/logger'\n\nconst logger = createLogger('[SiteApps]')\n\nexport class SiteApps {\n apps: Record<string, SiteApp>\n\n private _stopBuffering?: () => void\n private _bufferedInvocations: SiteAppGlobals[]\n\n constructor(private _instance: PostHog) {\n // events captured between loading posthog-js and the site app; up to 1000 events\n this._bufferedInvocations = []\n this.apps = {}\n }\n\n public get isEnabled(): boolean {\n return !!this._instance.config.opt_in_site_apps\n }\n\n private _eventCollector(_eventName: string, eventPayload?: CaptureResult | undefined) {\n if (!eventPayload) {\n return\n }\n const globals = this.globalsForEvent(eventPayload)\n this._bufferedInvocations.push(globals)\n if (this._bufferedInvocations.length > 1000) {\n this._bufferedInvocations = this._bufferedInvocations.slice(10)\n }\n }\n\n get siteAppLoaders(): SiteAppLoader[] | undefined {\n return assignableWindow._POSTHOG_REMOTE_CONFIG?.[this._instance.config.token]?.siteApps\n }\n\n init() {\n if (this.isEnabled) {\n const stop = this._instance._addCaptureHook(this._eventCollector.bind(this))\n this._stopBuffering = () => {\n stop()\n this._bufferedInvocations = []\n this._stopBuffering = undefined\n }\n }\n }\n\n globalsForEvent(event: CaptureResult): SiteAppGlobals {\n if (!event) {\n throw new Error('Event payload is required')\n }\n const groups: SiteAppGlobals['groups'] = {}\n const groupIds = this._instance.get_property('$groups') || []\n const groupProperties: Record<string, Properties> =\n this._instance.get_property('$stored_group_properties') || {}\n for (const [type, properties] of Object.entries(groupProperties)) {\n groups[type] = { id: groupIds[type], type, properties }\n }\n const { $set_once, $set, ..._event } = event\n const globals = {\n event: {\n ..._event,\n properties: {\n ...event.properties,\n ...($set ? { $set: { ...(event.properties?.$set ?? {}), ...$set } } : {}),\n ...($set_once ? { $set_once: { ...(event.properties?.$set_once ?? {}), ...$set_once } } : {}),\n },\n elements_chain: event.properties?.['$elements_chain'] ?? '',\n // TODO:\n // - elements_chain_href: '',\n // - elements_chain_texts: [] as string[],\n // - elements_chain_ids: [] as string[],\n // - elements_chain_elements: [] as string[],\n distinct_id: event.properties?.['distinct_id'],\n },\n person: {\n properties: this._instance.get_property('$stored_person_properties'),\n },\n groups,\n }\n return globals\n }\n\n setupSiteApp(loader: SiteAppLoader) {\n const app = this.apps[loader.id]\n const processBufferedEvents = () => {\n if (!app.errored && this._bufferedInvocations.length) {\n logger.info(`Processing ${this._bufferedInvocations.length} events for site app with id ${loader.id}`)\n this._bufferedInvocations.forEach((globals) => app.processEvent?.(globals))\n app.processedBuffer = true\n }\n\n if (Object.values(this.apps).every((app) => app.processedBuffer || app.errored)) {\n this._stopBuffering?.()\n }\n }\n\n let hasInitReturned = false\n const onLoaded = (success: boolean) => {\n app.errored = !success\n app.loaded = true\n logger.info(`Site app with id ${loader.id} ${success ? 'loaded' : 'errored'}`)\n // ensure that we don't call processBufferedEvents until after init() returns and we've set up processEvent\n if (hasInitReturned) {\n processBufferedEvents()\n }\n }\n\n try {\n const { processEvent } = loader.init({\n posthog: this._instance,\n callback: (success) => {\n onLoaded(success)\n },\n })\n if (processEvent) {\n app.processEvent = processEvent\n }\n hasInitReturned = true\n } catch (e) {\n logger.error(`Error while initializing PostHog app with config id ${loader.id}`, e)\n onLoaded(false)\n }\n\n // if the app loaded synchronously, process the events now\n if (hasInitReturned && app.loaded) {\n try {\n processBufferedEvents()\n } catch (e) {\n logger.error(`Error while processing buffered events PostHog app with config id ${loader.id}`, e)\n app.errored = true\n }\n }\n }\n\n private _setupSiteApps() {\n const siteAppLoaders = this.siteAppLoaders || []\n\n // do this in 2 passes, so that this.apps is populated before we call init\n for (const loader of siteAppLoaders) {\n this.apps[loader.id] = {\n id: loader.id,\n loaded: false,\n errored: false,\n processedBuffer: false,\n }\n }\n for (const loader of siteAppLoaders) {\n this.setupSiteApp(loader)\n }\n }\n\n private _onCapturedEvent(event: CaptureResult) {\n if (Object.keys(this.apps).length === 0) {\n return\n }\n\n const globals = this.globalsForEvent(event)\n\n for (const app of Object.values(this.apps)) {\n try {\n app.processEvent?.(globals)\n } catch (e) {\n logger.error(`Error while processing event ${event.event} for site app ${app.id}`, e)\n }\n }\n }\n\n onRemoteConfig(response: RemoteConfig): void {\n if (this.siteAppLoaders?.length) {\n if (!this.isEnabled) {\n logger.error(`PostHog site apps are disabled. Enable the \"opt_in_site_apps\" config to proceed.`)\n return\n }\n\n this._setupSiteApps()\n\n // NOTE: We could improve this to only fire if we actually have listeners for the event\n this._instance.on('eventCaptured', (event) => this._onCapturedEvent(event))\n\n return\n }\n\n // NOTE: Below this is now only the fallback for legacy site app support. Once we have fully removed to the remote config loader we can get rid of this\n\n this._stopBuffering?.()\n\n if (!response['siteApps']?.length) {\n return\n }\n\n if (!this.isEnabled) {\n logger.error(`PostHog site apps are disabled. Enable the \"opt_in_site_apps\" config to proceed.`)\n return\n }\n\n for (const { id, url } of response['siteApps']) {\n assignableWindow[`__$$ph_site_app_${id}`] = this._instance\n assignableWindow.__PosthogExtensions__?.loadSiteApp?.(this._instance, url, (err) => {\n if (err) {\n return logger.error(`Error while initializing PostHog app with config id ${id}`, err)\n }\n })\n }\n }\n}\n","// Re-export shared bot detection logic from @posthog/core\nimport { isBlockedUA as isBlockedUACore } from '@posthog/core'\nexport { DEFAULT_BLOCKED_UA_STRS, isBlockedUA } from '@posthog/core'\n\n// There's more in the type, but this is all we use. It's currently experimental, see\n// https://developer.mozilla.org/en-US/docs/Web/API/Navigator/userAgentData\n// if you're reading this in the future, when it's no longer experimental, please remove this type and use an official one.\n// Be extremely defensive here to ensure backwards and *forwards* compatibility, and remove this defensiveness in the\n// future when it is safe to do so.\nexport interface NavigatorUAData {\n brands?: {\n brand: string\n version: string\n }[]\n}\ndeclare global {\n interface Navigator {\n userAgentData?: NavigatorUAData\n }\n}\n\nexport const isLikelyBot = function (navigator: Navigator | undefined, customBlockedUserAgents: string[]): boolean {\n if (!navigator) {\n return false\n }\n const ua = navigator.userAgent\n if (ua) {\n if (isBlockedUACore(ua, customBlockedUserAgents)) {\n return true\n }\n }\n try {\n // eslint-disable-next-line compat/compat\n const uaData = navigator?.userAgentData as NavigatorUAData\n if (\n uaData?.brands &&\n uaData.brands.some((brandObj) => isBlockedUACore(brandObj?.brand, customBlockedUserAgents))\n ) {\n return true\n }\n } catch {\n // ignore the error, we were using experimental browser features\n }\n\n return !!navigator.webdriver\n\n // There's some more enhancements we could make in this area, e.g. it's possible to check if Chrome dev tools are\n // open, which will detect some bots that are trying to mask themselves and might get past the checks above.\n // However, this would give false positives for actual humans who have dev tools open.\n\n // We could also use the data in navigator.userAgentData.getHighEntropyValues() to detect bots, but we should wait\n // until this stops being experimental. The MDN docs imply that this might eventually require user permission.\n // See https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData/getHighEntropyValues\n // It would be very bad if posthog-js caused a permission prompt to appear on every page load.\n}\n","import { PostHog } from '../posthog-core'\n\n/**\n * The request router helps simplify the logic to determine which endpoints should be called for which things\n * The basic idea is that for a given region (US or EU), we have a set of endpoints that we should call depending\n * on the type of request (events, replays, flags, etc.) and handle overrides that may come from configs or the flags endpoint\n */\n\nexport enum RequestRouterRegion {\n US = 'us',\n EU = 'eu',\n CUSTOM = 'custom',\n}\n\nexport type RequestRouterTarget = 'api' | 'ui' | 'assets' | 'flags'\n\nconst ingestionDomain = 'i.posthog.com'\n\nexport class RequestRouter {\n instance: PostHog\n private _regionCache: Record<string, RequestRouterRegion> = {}\n\n constructor(instance: PostHog) {\n this.instance = instance\n }\n\n get apiHost(): string {\n const host = this.instance.config.api_host.trim().replace(/\\/$/, '')\n if (host === 'https://app.posthog.com') {\n return 'https://us.i.posthog.com'\n }\n return host\n }\n\n get flagsApiHost(): string {\n const customHost = this.instance.config.flags_api_host\n if (customHost) {\n return customHost.trim().replace(/\\/$/, '')\n }\n // Backwards compatibility: if no custom flags_api_host is set, fall back to the regular apiHost\n return this.apiHost\n }\n\n get uiHost(): string | undefined {\n let host = this.instance.config.ui_host?.replace(/\\/$/, '')\n\n if (!host) {\n // No ui_host set, get it from the api_host. But api_host differs\n // from the actual UI host, so replace the ingestion subdomain with just posthog.com\n host = this.apiHost.replace(`.${ingestionDomain}`, '.posthog.com')\n }\n\n if (host === 'https://app.posthog.com') {\n return 'https://us.posthog.com'\n }\n\n return host\n }\n\n get region(): RequestRouterRegion {\n // We don't need to compute this every time so we cache the result\n if (!this._regionCache[this.apiHost]) {\n if (/https:\\/\\/(app|us|us-assets)(\\.i)?\\.posthog\\.com/i.test(this.apiHost)) {\n this._regionCache[this.apiHost] = RequestRouterRegion.US\n } else if (/https:\\/\\/(eu|eu-assets)(\\.i)?\\.posthog\\.com/i.test(this.apiHost)) {\n this._regionCache[this.apiHost] = RequestRouterRegion.EU\n } else {\n this._regionCache[this.apiHost] = RequestRouterRegion.CUSTOM\n }\n }\n return this._regionCache[this.apiHost]\n }\n\n endpointFor(target: RequestRouterTarget, path: string = ''): string {\n if (path) {\n path = path[0] === '/' ? path : `/${path}`\n }\n\n if (target === 'ui') {\n return this.uiHost + path\n }\n\n if (target === 'flags') {\n return this.flagsApiHost + path\n }\n\n if (this.region === RequestRouterRegion.CUSTOM) {\n return this.apiHost + path\n }\n\n const suffix = ingestionDomain + path\n\n switch (target) {\n case 'assets':\n return `https://${this.region}-assets.${suffix}`\n case 'api':\n return `https://${this.region}.${suffix}`\n }\n }\n}\n","import { PostHog } from './posthog-core'\nimport { navigator, window } from './utils/globals'\nimport {\n WebExperiment,\n WebExperimentsCallback,\n WebExperimentTransform,\n WebExperimentUrlMatchType,\n WebExperimentVariant,\n} from './web-experiments-types'\nimport { WEB_EXPERIMENTS } from './constants'\nimport { isNullish, isString } from '@posthog/core'\nimport { getQueryParam } from './utils/request-utils'\nimport { isMatchingRegex } from './utils/regex-utils'\nimport { logger } from './utils/logger'\nimport { isLikelyBot } from './utils/blocked-uas'\nimport { getCampaignParams } from './utils/event-utils'\n\nexport const webExperimentUrlValidationMap: Record<\n WebExperimentUrlMatchType,\n (conditionsUrl: string, location: Location) => boolean\n> = {\n icontains: (conditionsUrl, location) =>\n !!window && location.href.toLowerCase().indexOf(conditionsUrl.toLowerCase()) > -1,\n not_icontains: (conditionsUrl, location) =>\n !!window && location.href.toLowerCase().indexOf(conditionsUrl.toLowerCase()) === -1,\n regex: (conditionsUrl, location) => !!window && isMatchingRegex(location.href, conditionsUrl),\n not_regex: (conditionsUrl, location) => !!window && !isMatchingRegex(location.href, conditionsUrl),\n exact: (conditionsUrl, location) => location.href === conditionsUrl,\n is_not: (conditionsUrl, location) => location.href !== conditionsUrl,\n}\n\nexport class WebExperiments {\n private _flagToExperiments?: Map<string, WebExperiment>\n\n constructor(private _instance: PostHog) {\n this._instance.onFeatureFlags((flags: string[]) => {\n this.onFeatureFlags(flags)\n })\n }\n\n onFeatureFlags(flags: string[]) {\n if (this._is_bot()) {\n WebExperiments._logInfo('Refusing to render web experiment since the viewer is a likely bot')\n return\n }\n\n if (this._instance.config.disable_web_experiments) {\n return\n }\n\n if (isNullish(this._flagToExperiments)) {\n // Indicates first load so we trigger the loaders\n this._flagToExperiments = new Map<string, WebExperiment>()\n this.loadIfEnabled()\n this.previewWebExperiment()\n return\n }\n\n WebExperiments._logInfo('applying feature flags', flags)\n flags.forEach((flag) => {\n if (this._flagToExperiments && this._flagToExperiments?.has(flag)) {\n const selectedVariant = this._instance.getFeatureFlag(flag) as unknown as string\n const webExperiment = this._flagToExperiments?.get(flag)\n if (selectedVariant && webExperiment?.variants[selectedVariant]) {\n this._applyTransforms(\n webExperiment.name,\n selectedVariant,\n webExperiment.variants[selectedVariant].transforms\n )\n }\n }\n })\n }\n\n previewWebExperiment() {\n const location = WebExperiments.getWindowLocation()\n if (location?.search) {\n const experimentID = getQueryParam(location?.search, '__experiment_id')\n const variant = getQueryParam(location?.search, '__experiment_variant')\n if (experimentID && variant) {\n WebExperiments._logInfo(`previewing web experiments ${experimentID} && ${variant}`)\n this.getWebExperiments(\n (webExperiments) => {\n this._showPreviewWebExperiment(parseInt(experimentID), variant, webExperiments)\n },\n false,\n true\n )\n }\n }\n }\n\n loadIfEnabled() {\n if (this._instance.config.disable_web_experiments) {\n return\n }\n\n this.getWebExperimentsAndEvaluateDisplayLogic()\n }\n\n public getWebExperimentsAndEvaluateDisplayLogic = (forceReload: boolean = false): void => {\n this.getWebExperiments((webExperiments) => {\n WebExperiments._logInfo(`retrieved web experiments from the server`)\n this._flagToExperiments = new Map<string, WebExperiment>()\n\n webExperiments.forEach((webExperiment) => {\n if (webExperiment.feature_flag_key) {\n if (this._flagToExperiments) {\n WebExperiments._logInfo(\n `setting flag key `,\n webExperiment.feature_flag_key,\n ` to web experiment `,\n webExperiment\n )\n this._flagToExperiments?.set(webExperiment.feature_flag_key, webExperiment)\n }\n\n const selectedVariant = this._instance.getFeatureFlag(webExperiment.feature_flag_key)\n if (isString(selectedVariant) && webExperiment.variants[selectedVariant]) {\n this._applyTransforms(\n webExperiment.name,\n selectedVariant,\n webExperiment.variants[selectedVariant].transforms\n )\n }\n } else if (webExperiment.variants) {\n for (const variant in webExperiment.variants) {\n const testVariant = webExperiment.variants[variant]\n const matchTest = WebExperiments._matchesTestVariant(testVariant)\n if (matchTest) {\n this._applyTransforms(webExperiment.name, variant, testVariant.transforms)\n }\n }\n }\n })\n }, forceReload)\n }\n\n public getWebExperiments(callback: WebExperimentsCallback, forceReload: boolean, previewing?: boolean) {\n if (this._instance.config.disable_web_experiments && !previewing) {\n return callback([])\n }\n\n const existingWebExperiments = this._instance.get_property(WEB_EXPERIMENTS)\n if (existingWebExperiments && !forceReload) {\n return callback(existingWebExperiments)\n }\n\n this._instance._send_request({\n url: this._instance.requestRouter.endpointFor(\n 'api',\n `/api/web_experiments/?token=${this._instance.config.token}`\n ),\n method: 'GET',\n callback: (response) => {\n if (response.statusCode !== 200 || !response.json) {\n return callback([])\n }\n const webExperiments = response.json.experiments || []\n return callback(webExperiments)\n },\n })\n }\n\n private _showPreviewWebExperiment(experimentID: number, variant: string, webExperiments: WebExperiment[]) {\n const previewExperiments = webExperiments.filter((exp) => exp.id === experimentID)\n if (previewExperiments && previewExperiments.length > 0) {\n WebExperiments._logInfo(\n `Previewing web experiment [${previewExperiments[0].name}] with variant [${variant}]`\n )\n this._applyTransforms(\n previewExperiments[0].name,\n variant,\n previewExperiments[0].variants[variant].transforms\n )\n }\n }\n private static _matchesTestVariant(testVariant: WebExperimentVariant) {\n if (isNullish(testVariant.conditions)) {\n return false\n }\n return WebExperiments._matchUrlConditions(testVariant) && WebExperiments._matchUTMConditions(testVariant)\n }\n\n private static _matchUrlConditions(testVariant: WebExperimentVariant): boolean {\n if (isNullish(testVariant.conditions) || isNullish(testVariant.conditions?.url)) {\n return true\n }\n\n const location = WebExperiments.getWindowLocation()\n if (location) {\n const urlCheck = testVariant.conditions?.url\n ? webExperimentUrlValidationMap[testVariant.conditions?.urlMatchType ?? 'icontains'](\n testVariant.conditions.url,\n location\n )\n : true\n return urlCheck\n }\n\n return false\n }\n\n public static getWindowLocation(): Location | undefined {\n return window?.location\n }\n\n private static _matchUTMConditions(testVariant: WebExperimentVariant): boolean {\n if (isNullish(testVariant.conditions) || isNullish(testVariant.conditions?.utm)) {\n return true\n }\n const campaignParams = getCampaignParams()\n if (campaignParams['utm_source']) {\n // eslint-disable-next-line compat/compat\n const utmCampaignMatched = testVariant.conditions?.utm?.utm_campaign\n ? testVariant.conditions?.utm?.utm_campaign == campaignParams['utm_campaign']\n : true\n\n const utmSourceMatched = testVariant.conditions?.utm?.utm_source\n ? testVariant.conditions?.utm?.utm_source == campaignParams['utm_source']\n : true\n\n const utmMediumMatched = testVariant.conditions?.utm?.utm_medium\n ? testVariant.conditions?.utm?.utm_medium == campaignParams['utm_medium']\n : true\n\n const utmTermMatched = testVariant.conditions?.utm?.utm_term\n ? testVariant.conditions?.utm?.utm_term == campaignParams['utm_term']\n : true\n\n return utmCampaignMatched && utmMediumMatched && utmTermMatched && utmSourceMatched\n }\n\n return false\n }\n\n private static _logInfo(msg: string, ...args: any[]) {\n logger.info(`[WebExperiments] ${msg}`, args)\n }\n\n private _applyTransforms(experiment: string, variant: string, transforms: WebExperimentTransform[]) {\n if (this._is_bot()) {\n WebExperiments._logInfo('Refusing to render web experiment since the viewer is a likely bot')\n return\n }\n\n if (variant === 'control') {\n WebExperiments._logInfo('Control variants leave the page unmodified.')\n return\n }\n\n transforms.forEach((transform) => {\n if (transform.selector) {\n WebExperiments._logInfo(\n `applying transform of variant ${variant} for experiment ${experiment} `,\n transform\n )\n\n // eslint-disable-next-line no-restricted-globals\n const elements = document?.querySelectorAll(transform.selector)\n elements?.forEach((element) => {\n const htmlElement = element as HTMLElement\n if (transform.html) {\n htmlElement.innerHTML = transform.html\n }\n\n if (transform.css) {\n htmlElement.setAttribute('style', transform.css)\n }\n })\n }\n })\n }\n\n _is_bot(): boolean | undefined {\n if (navigator && this._instance) {\n return isLikelyBot(navigator, this._instance.config.custom_blocked_useragents)\n } else {\n return undefined\n }\n }\n}\n","import { PostHog } from '../posthog-core'\nimport { ExternalIntegrationKind } from '../types'\nimport { assignableWindow, ExternalExtensionKind } from '../utils/globals'\nimport { createLogger } from '../utils/logger'\n\nconst logger = createLogger('[PostHog ExternalIntegrations]')\n\nconst MAPPED_INTEGRATIONS: Record<ExternalIntegrationKind, ExternalExtensionKind> = {\n intercom: 'intercom-integration',\n crispChat: 'crisp-chat-integration',\n}\n\nexport class ExternalIntegrations {\n constructor(private readonly _instance: PostHog) {}\n\n private _loadScript(name: ExternalExtensionKind, cb: () => void): void {\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(this._instance, name, (err) => {\n if (err) {\n return logger.error('failed to load script', err)\n }\n cb()\n })\n }\n\n public startIfEnabledOrStop() {\n for (const [key, value] of Object.entries(this._instance.config.integrations ?? {})) {\n // if the integration is enabled, and not present, then load it\n if (value && !assignableWindow.__PosthogExtensions__?.integrations?.[key as ExternalIntegrationKind]) {\n this._loadScript(MAPPED_INTEGRATIONS[key as ExternalIntegrationKind], () => {\n assignableWindow.__PosthogExtensions__?.integrations?.[key as ExternalIntegrationKind]?.start(\n this._instance\n )\n })\n }\n // if the integration is disabled, and present, then stop it\n if (!value && assignableWindow.__PosthogExtensions__?.integrations?.[key as ExternalIntegrationKind]) {\n assignableWindow.__PosthogExtensions__?.integrations?.[key as ExternalIntegrationKind]?.stop()\n }\n }\n }\n}\n","import {\n SESSION_RECORDING_EVENT_TRIGGER_ACTIVATED_SESSION,\n SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION,\n} from '../../../constants'\nimport { PostHog } from '../../../posthog-core'\nimport { FlagVariant, RemoteConfig, SessionRecordingPersistedConfig, SessionRecordingUrlTrigger } from '../../../types'\nimport { isNullish, isBoolean, isString, isObject } from '@posthog/core'\nimport { window } from '../../../utils/globals'\n\nexport const DISABLED = 'disabled'\nexport const SAMPLED = 'sampled'\nexport const ACTIVE = 'active'\nexport const BUFFERING = 'buffering'\nexport const PAUSED = 'paused'\nexport const LAZY_LOADING = 'lazy_loading'\n\nconst TRIGGER = 'trigger'\nexport const TRIGGER_ACTIVATED = TRIGGER + '_activated'\nexport const TRIGGER_PENDING = TRIGGER + '_pending'\nexport const TRIGGER_DISABLED = TRIGGER + '_' + DISABLED\n\nexport interface RecordingTriggersStatus {\n get receivedFlags(): boolean\n get isRecordingEnabled(): false | true | undefined\n get isSampled(): false | true | null\n get urlTriggerMatching(): URLTriggerMatching\n get eventTriggerMatching(): EventTriggerMatching\n get linkedFlagMatching(): LinkedFlagMatching\n get sessionId(): string\n}\n\nexport type TriggerType = 'url' | 'event'\n/* \ntriggers can have one of three statuses:\n * - trigger_activated: the trigger met conditions to start recording\n * - trigger_pending: the trigger is present, but the conditions are not yet met\n * - trigger_disabled: the trigger is not present\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst triggerStatuses = [TRIGGER_ACTIVATED, TRIGGER_PENDING, TRIGGER_DISABLED] as const\nexport type TriggerStatus = (typeof triggerStatuses)[number]\n\n/**\n * Session recording starts in buffering mode while waiting for \"flags response\".\n * Once the response is received, it might be disabled, active or sampled.\n * When \"sampled\" that means a sample rate is set, and the last time the session ID rotated\n * the sample rate determined this session should be sent to the server.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst sessionRecordingStatuses = [DISABLED, SAMPLED, ACTIVE, BUFFERING, PAUSED, LAZY_LOADING] as const\nexport type SessionRecordingStatus = (typeof sessionRecordingStatuses)[number]\n\n// while we have both lazy and eager loaded replay we might get either type of config\ntype ReplayConfigType = RemoteConfig | SessionRecordingPersistedConfig\n\nfunction sessionRecordingUrlTriggerMatches(url: string, triggers: SessionRecordingUrlTrigger[]) {\n return triggers.some((trigger) => {\n switch (trigger.matching) {\n case 'regex':\n return new RegExp(trigger.url).test(url)\n default:\n return false\n }\n })\n}\n\nexport interface TriggerStatusMatching {\n triggerStatus(sessionId: string): TriggerStatus\n stop(): void\n}\nexport class OrTriggerMatching implements TriggerStatusMatching {\n constructor(private readonly _matchers: TriggerStatusMatching[]) {}\n\n triggerStatus(sessionId: string): TriggerStatus {\n const statuses = this._matchers.map((m) => m.triggerStatus(sessionId))\n if (statuses.includes(TRIGGER_ACTIVATED)) {\n return TRIGGER_ACTIVATED\n }\n if (statuses.includes(TRIGGER_PENDING)) {\n return TRIGGER_PENDING\n }\n return TRIGGER_DISABLED\n }\n\n stop(): void {\n this._matchers.forEach((m) => m.stop())\n }\n}\n\nexport class AndTriggerMatching implements TriggerStatusMatching {\n constructor(private readonly _matchers: TriggerStatusMatching[]) {}\n\n triggerStatus(sessionId: string): TriggerStatus {\n const statuses = new Set<TriggerStatus>()\n for (const matcher of this._matchers) {\n statuses.add(matcher.triggerStatus(sessionId))\n }\n\n // trigger_disabled means no config\n statuses.delete(TRIGGER_DISABLED)\n switch (statuses.size) {\n case 0:\n return TRIGGER_DISABLED\n case 1:\n return Array.from(statuses)[0]\n default:\n return TRIGGER_PENDING\n }\n }\n\n stop(): void {\n this._matchers.forEach((m) => m.stop())\n }\n}\n\nexport class PendingTriggerMatching implements TriggerStatusMatching {\n triggerStatus(): TriggerStatus {\n return TRIGGER_PENDING\n }\n\n stop(): void {\n // no-op\n }\n}\n\nconst isEagerLoadedConfig = (x: ReplayConfigType): x is RemoteConfig => {\n return 'sessionRecording' in x\n}\n\nexport class URLTriggerMatching implements TriggerStatusMatching {\n _urlTriggers: SessionRecordingUrlTrigger[] = []\n _urlBlocklist: SessionRecordingUrlTrigger[] = []\n\n urlBlocked: boolean = false\n\n constructor(private readonly _instance: PostHog) {}\n\n onConfig(config: ReplayConfigType) {\n this._urlTriggers =\n (isEagerLoadedConfig(config)\n ? isObject(config.sessionRecording)\n ? config.sessionRecording?.urlTriggers\n : []\n : config?.urlTriggers) || []\n this._urlBlocklist =\n (isEagerLoadedConfig(config)\n ? isObject(config.sessionRecording)\n ? config.sessionRecording?.urlBlocklist\n : []\n : config?.urlBlocklist) || []\n }\n\n /**\n * @deprecated Use onConfig instead\n */\n onRemoteConfig(response: RemoteConfig) {\n this.onConfig(response)\n }\n\n private _urlTriggerStatus(sessionId: string): TriggerStatus {\n if (this._urlTriggers.length === 0) {\n return TRIGGER_DISABLED\n }\n\n const currentTriggerSession = this._instance?.get_property(SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION)\n return currentTriggerSession === sessionId ? TRIGGER_ACTIVATED : TRIGGER_PENDING\n }\n\n triggerStatus(sessionId: string): TriggerStatus {\n const urlTriggerStatus = this._urlTriggerStatus(sessionId)\n const eitherIsActivated = urlTriggerStatus === TRIGGER_ACTIVATED\n const eitherIsPending = urlTriggerStatus === TRIGGER_PENDING\n\n const result = eitherIsActivated ? TRIGGER_ACTIVATED : eitherIsPending ? TRIGGER_PENDING : TRIGGER_DISABLED\n this._instance.register_for_session({\n $sdk_debug_replay_url_trigger_status: result,\n })\n return result\n }\n\n checkUrlTriggerConditions(\n onPause: () => void,\n onResume: () => void,\n onActivate: (triggerType: TriggerType) => void,\n sessionId: string\n ) {\n if (typeof window === 'undefined' || !window.location.href) {\n return\n }\n\n const url = window.location.href\n\n const wasBlocked = this.urlBlocked\n const isNowBlocked = sessionRecordingUrlTriggerMatches(url, this._urlBlocklist)\n\n if (wasBlocked && isNowBlocked) {\n return\n }\n\n if (isNowBlocked && !wasBlocked) {\n onPause()\n } else if (!isNowBlocked && wasBlocked) {\n onResume()\n }\n\n const isActivated = this._urlTriggerStatus(sessionId) === TRIGGER_ACTIVATED\n const urlMatches = sessionRecordingUrlTriggerMatches(url, this._urlTriggers)\n\n if (!isActivated && urlMatches) {\n onActivate('url')\n }\n }\n\n stop(): void {\n // no-op\n }\n}\n\nexport class LinkedFlagMatching implements TriggerStatusMatching {\n linkedFlag: string | FlagVariant | null = null\n linkedFlagSeen: boolean = false\n private _flagListenerCleanup: () => void = () => {}\n constructor(private readonly _instance: PostHog) {}\n\n triggerStatus(): TriggerStatus {\n let result = TRIGGER_PENDING\n if (isNullish(this.linkedFlag)) {\n result = TRIGGER_DISABLED\n }\n if (this.linkedFlagSeen) {\n result = TRIGGER_ACTIVATED\n }\n this._instance.register_for_session({\n $sdk_debug_replay_linked_flag_trigger_status: result,\n })\n return result\n }\n\n onConfig(config: ReplayConfigType, onStarted: (flag: string, variant: string | null) => void) {\n this.linkedFlag =\n (isEagerLoadedConfig(config)\n ? isObject(config.sessionRecording)\n ? config.sessionRecording?.linkedFlag\n : null\n : config?.linkedFlag) || null\n\n if (!isNullish(this.linkedFlag) && !this.linkedFlagSeen) {\n const linkedFlag = isString(this.linkedFlag) ? this.linkedFlag : this.linkedFlag.flag\n const linkedVariant = isString(this.linkedFlag) ? null : this.linkedFlag.variant\n this._flagListenerCleanup = this._instance.onFeatureFlags((_flags, variants) => {\n const flagIsPresent = isObject(variants) && linkedFlag in variants\n let linkedFlagMatches = false\n if (flagIsPresent) {\n const variantForFlagKey = variants[linkedFlag]\n if (isBoolean(variantForFlagKey)) {\n linkedFlagMatches = variantForFlagKey === true\n } else if (linkedVariant) {\n linkedFlagMatches = variantForFlagKey === linkedVariant\n } else {\n // then this is a variant flag and we want to match any string\n linkedFlagMatches = !!variantForFlagKey\n }\n }\n this.linkedFlagSeen = linkedFlagMatches\n if (linkedFlagMatches) {\n onStarted(linkedFlag, linkedVariant)\n }\n })\n }\n }\n\n /**\n * @deprecated Use onConfig instead\n */\n onRemoteConfig(response: RemoteConfig, onStarted: (flag: string, variant: string | null) => void) {\n this.onConfig(response, onStarted)\n }\n\n stop(): void {\n this._flagListenerCleanup()\n }\n}\n\nexport class EventTriggerMatching implements TriggerStatusMatching {\n _eventTriggers: string[] = []\n\n constructor(private readonly _instance: PostHog) {}\n\n onConfig(config: ReplayConfigType) {\n this._eventTriggers =\n (isEagerLoadedConfig(config)\n ? isObject(config.sessionRecording)\n ? config.sessionRecording?.eventTriggers\n : []\n : config?.eventTriggers) || []\n }\n\n /**\n * @deprecated Use onConfig instead\n */\n onRemoteConfig(response: RemoteConfig) {\n this.onConfig(response)\n }\n\n private _eventTriggerStatus(sessionId: string): TriggerStatus {\n if (this._eventTriggers.length === 0) {\n return TRIGGER_DISABLED\n }\n\n const currentTriggerSession = this._instance?.get_property(SESSION_RECORDING_EVENT_TRIGGER_ACTIVATED_SESSION)\n return currentTriggerSession === sessionId ? TRIGGER_ACTIVATED : TRIGGER_PENDING\n }\n\n triggerStatus(sessionId: string): TriggerStatus {\n const eventTriggerStatus = this._eventTriggerStatus(sessionId)\n const result =\n eventTriggerStatus === TRIGGER_ACTIVATED\n ? TRIGGER_ACTIVATED\n : eventTriggerStatus === TRIGGER_PENDING\n ? TRIGGER_PENDING\n : TRIGGER_DISABLED\n this._instance.register_for_session({\n $sdk_debug_replay_event_trigger_status: result,\n })\n return result\n }\n\n stop(): void {\n // no-op\n }\n}\n\n// we need a no-op matcher before we can lazy-load the other matches, since all matchers wait on remote config anyway\nexport function nullMatchSessionRecordingStatus(triggersStatus: RecordingTriggersStatus): SessionRecordingStatus {\n if (!triggersStatus.isRecordingEnabled) {\n return DISABLED\n }\n\n return BUFFERING\n}\n\nexport function anyMatchSessionRecordingStatus(triggersStatus: RecordingTriggersStatus): SessionRecordingStatus {\n if (!triggersStatus.receivedFlags) {\n return BUFFERING\n }\n\n if (!triggersStatus.isRecordingEnabled) {\n return DISABLED\n }\n\n if (triggersStatus.urlTriggerMatching.urlBlocked) {\n return PAUSED\n }\n\n const sampledActive = triggersStatus.isSampled === true\n const triggerMatches = new OrTriggerMatching([\n triggersStatus.eventTriggerMatching,\n triggersStatus.urlTriggerMatching,\n triggersStatus.linkedFlagMatching,\n ]).triggerStatus(triggersStatus.sessionId)\n\n if (sampledActive) {\n return SAMPLED\n }\n\n if (triggerMatches === TRIGGER_ACTIVATED) {\n return ACTIVE\n }\n\n if (triggerMatches === TRIGGER_PENDING) {\n // even if sampled active is false, we should still be buffering\n // since a pending trigger could override it\n return BUFFERING\n }\n\n // if sampling is set and the session is already decided to not be sampled\n // then we should never be active\n if (triggersStatus.isSampled === false) {\n return DISABLED\n }\n\n return ACTIVE\n}\n\nexport function allMatchSessionRecordingStatus(triggersStatus: RecordingTriggersStatus): SessionRecordingStatus {\n if (!triggersStatus.receivedFlags) {\n return BUFFERING\n }\n\n if (!triggersStatus.isRecordingEnabled) {\n return DISABLED\n }\n\n if (triggersStatus.urlTriggerMatching.urlBlocked) {\n return PAUSED\n }\n\n const andTriggerMatch = new AndTriggerMatching([\n triggersStatus.eventTriggerMatching,\n triggersStatus.urlTriggerMatching,\n triggersStatus.linkedFlagMatching,\n ])\n const currentTriggerStatus = andTriggerMatch.triggerStatus(triggersStatus.sessionId)\n const hasTriggersConfigured = currentTriggerStatus !== TRIGGER_DISABLED\n\n const hasSamplingConfigured = isBoolean(triggersStatus.isSampled)\n\n if (hasTriggersConfigured && currentTriggerStatus === TRIGGER_PENDING) {\n return BUFFERING\n }\n\n if (hasTriggersConfigured && currentTriggerStatus === TRIGGER_DISABLED) {\n return DISABLED\n }\n\n // sampling can't ever cause buffering, it's always determined right away or not configured\n if (hasSamplingConfigured && !triggersStatus.isSampled) {\n return DISABLED\n }\n\n // If sampling is configured and set to true, return sampled\n if (triggersStatus.isSampled === true) {\n return SAMPLED\n }\n\n return ACTIVE\n}\n","import {\n SESSION_RECORDING_IS_SAMPLED,\n SESSION_RECORDING_OVERRIDE_SAMPLING,\n SESSION_RECORDING_OVERRIDE_LINKED_FLAG,\n SESSION_RECORDING_OVERRIDE_EVENT_TRIGGER,\n SESSION_RECORDING_OVERRIDE_URL_TRIGGER,\n SESSION_RECORDING_REMOTE_CONFIG,\n} from '../../constants'\nimport { PostHog } from '../../posthog-core'\nimport { Properties, RemoteConfig, SessionRecordingPersistedConfig, SessionStartReason } from '../../types'\nimport { type eventWithTime } from './types/rrweb-types'\n\nimport { isNullish, isUndefined } from '@posthog/core'\nimport { createLogger } from '../../utils/logger'\nimport {\n assignableWindow,\n LazyLoadedSessionRecordingInterface,\n PostHogExtensionKind,\n window,\n} from '../../utils/globals'\nimport { DISABLED, LAZY_LOADING, SessionRecordingStatus, TriggerType } from './external/triggerMatching'\n\nconst LOGGER_PREFIX = '[SessionRecording]'\nconst logger = createLogger(LOGGER_PREFIX)\n\nexport class SessionRecording {\n _forceAllowLocalhostNetworkCapture: boolean = false\n\n private _receivedFlags: boolean = false\n\n private _persistFlagsOnSessionListener: (() => void) | undefined = undefined\n private _lazyLoadedSessionRecording: LazyLoadedSessionRecordingInterface | undefined\n\n public get started(): boolean {\n return !!this._lazyLoadedSessionRecording?.isStarted\n }\n\n /**\n * defaults to buffering mode until a flags response is received\n * once a flags response is received status can be disabled, active or sampled\n */\n get status(): SessionRecordingStatus {\n if (this._lazyLoadedSessionRecording) {\n return this._lazyLoadedSessionRecording.status\n }\n\n if (this._receivedFlags && !this._isRecordingEnabled) {\n return DISABLED\n }\n\n return LAZY_LOADING\n }\n\n constructor(private readonly _instance: PostHog) {\n if (!this._instance.sessionManager) {\n logger.error('started without valid sessionManager')\n throw new Error(LOGGER_PREFIX + ' started without valid sessionManager. This is a bug.')\n }\n\n if (this._instance.config.cookieless_mode === 'always') {\n throw new Error(LOGGER_PREFIX + ' cannot be used with cookieless_mode=\"always\"')\n }\n }\n\n private get _isRecordingEnabled() {\n const enabled_server_side = !!this._instance.get_property(SESSION_RECORDING_REMOTE_CONFIG)?.enabled\n const enabled_client_side = !this._instance.config.disable_session_recording\n const isDisabled = this._instance.config.disable_session_recording || this._instance.consent.isOptedOut()\n return window && enabled_server_side && enabled_client_side && !isDisabled\n }\n\n startIfEnabledOrStop(startReason?: SessionStartReason) {\n if (this._isRecordingEnabled && this._lazyLoadedSessionRecording?.isStarted) {\n return\n }\n\n // According to the rrweb docs, rrweb is not supported on IE11 and below:\n // \"rrweb does not support IE11 and below because it uses the MutationObserver API, which was supported by these browsers.\"\n // https://github.com/rrweb-io/rrweb/blob/master/guide.md#compatibility-note\n //\n // However, MutationObserver does exist on IE11, it just doesn't work well and does not detect all changes.\n // Instead, when we load \"recorder.js\", the first JS error is about \"Object.assign\" and \"Array.from\" being undefined.\n // Thus instead of MutationObserver, we look for this function and block recording if it's undefined.\n const canRunReplay = !isUndefined(Object.assign) && !isUndefined(Array.from)\n if (this._isRecordingEnabled && canRunReplay) {\n this._lazyLoadAndStart(startReason)\n logger.info('starting')\n } else {\n this.stopRecording()\n }\n }\n\n /**\n * session recording waits until it receives remote config before loading the script\n * this is to ensure we can control the script name remotely\n * and because we wait until we have local and remote config to determine if we should start at all\n * if start is called and there is no remote config then we wait until there is\n */\n private _lazyLoadAndStart(startReason?: SessionStartReason) {\n // by checking `_isRecordingEnabled` here we know that\n // we have stored remote config and client config to read\n // replay waits for both local and remote config before starting\n if (!this._isRecordingEnabled) {\n return\n }\n\n // If recorder.js is already loaded (if array.full.js snippet is used or posthog-js/dist/recorder is\n // imported), don't load the script. Otherwise, remotely import recorder.js from cdn since it hasn't been loaded.\n if (\n !assignableWindow?.__PosthogExtensions__?.rrweb?.record ||\n !assignableWindow.__PosthogExtensions__?.initSessionRecording\n ) {\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(\n this._instance,\n this._scriptName,\n (err) => {\n if (err) {\n return logger.error('could not load recorder', err)\n }\n this._onScriptLoaded(startReason)\n }\n )\n } else {\n this._onScriptLoaded(startReason)\n }\n }\n\n stopRecording() {\n this._persistFlagsOnSessionListener?.()\n this._persistFlagsOnSessionListener = undefined\n this._lazyLoadedSessionRecording?.stop()\n }\n\n private _resetSampling() {\n this._instance.persistence?.unregister(SESSION_RECORDING_IS_SAMPLED)\n }\n\n private _persistRemoteConfig(response: RemoteConfig): void {\n if (this._instance.persistence) {\n const persistence = this._instance.persistence\n\n const persistResponse = () => {\n const sessionRecordingConfigResponse =\n response.sessionRecording === false ? undefined : response.sessionRecording\n\n const receivedSampleRate = sessionRecordingConfigResponse?.sampleRate\n\n const parsedSampleRate = isNullish(receivedSampleRate) ? null : parseFloat(receivedSampleRate)\n if (isNullish(parsedSampleRate)) {\n this._resetSampling()\n }\n\n const receivedMinimumDuration = sessionRecordingConfigResponse?.minimumDurationMilliseconds\n\n persistence.register({\n [SESSION_RECORDING_REMOTE_CONFIG]: {\n enabled: !!sessionRecordingConfigResponse,\n ...sessionRecordingConfigResponse,\n networkPayloadCapture: {\n capturePerformance: response.capturePerformance,\n ...sessionRecordingConfigResponse?.networkPayloadCapture,\n },\n canvasRecording: {\n enabled: sessionRecordingConfigResponse?.recordCanvas,\n fps: sessionRecordingConfigResponse?.canvasFps,\n quality: sessionRecordingConfigResponse?.canvasQuality,\n },\n sampleRate: parsedSampleRate,\n minimumDurationMilliseconds: isUndefined(receivedMinimumDuration)\n ? null\n : receivedMinimumDuration,\n endpoint: sessionRecordingConfigResponse?.endpoint,\n triggerMatchType: sessionRecordingConfigResponse?.triggerMatchType,\n masking: sessionRecordingConfigResponse?.masking,\n urlTriggers: sessionRecordingConfigResponse?.urlTriggers,\n } satisfies SessionRecordingPersistedConfig,\n })\n }\n\n persistResponse()\n\n // in case we see multiple flags responses, we should only use the response from the most recent one\n this._persistFlagsOnSessionListener?.()\n // we 100% know there is a session manager by this point\n this._persistFlagsOnSessionListener = this._instance.sessionManager?.onSessionId(persistResponse)\n }\n }\n\n onRemoteConfig(response: RemoteConfig) {\n if (!('sessionRecording' in response)) {\n // if sessionRecording is not in the response, we do nothing\n logger.info('skipping remote config with no sessionRecording', response)\n return\n }\n if (response.sessionRecording === false) {\n // remotely disabled\n this._receivedFlags = true\n return\n }\n\n this._persistRemoteConfig(response)\n this._receivedFlags = true\n this.startIfEnabledOrStop()\n }\n\n log(message: string, level: 'log' | 'warn' | 'error' = 'log') {\n if (this._lazyLoadedSessionRecording?.log) {\n this._lazyLoadedSessionRecording.log(message, level)\n } else {\n logger.warn('log called before recorder was ready')\n }\n }\n\n private get _scriptName(): PostHogExtensionKind {\n const remoteConfig: SessionRecordingPersistedConfig | undefined = this._instance?.persistence?.get_property(\n SESSION_RECORDING_REMOTE_CONFIG\n )\n return (remoteConfig?.scriptConfig?.script as PostHogExtensionKind) || 'lazy-recorder'\n }\n\n private _onScriptLoaded(startReason?: SessionStartReason) {\n if (!assignableWindow.__PosthogExtensions__?.initSessionRecording) {\n throw Error('Called on script loaded before session recording is available')\n }\n\n if (!this._lazyLoadedSessionRecording) {\n this._lazyLoadedSessionRecording = assignableWindow.__PosthogExtensions__?.initSessionRecording(\n this._instance\n )\n ;(this._lazyLoadedSessionRecording as any)._forceAllowLocalhostNetworkCapture =\n this._forceAllowLocalhostNetworkCapture\n }\n\n this._lazyLoadedSessionRecording.start(startReason)\n }\n\n /**\n * this is maintained on the public API only because it has always been on the public API\n * if you are calling this directly you are certainly doing something wrong\n * @deprecated\n */\n onRRwebEmit(rawEvent: eventWithTime) {\n this._lazyLoadedSessionRecording?.onRRwebEmit?.(rawEvent)\n }\n\n /**\n * this ignores the linked flag config and (if other conditions are met) causes capture to start\n *\n * It is not usual to call this directly,\n * instead call `posthog.startSessionRecording({linked_flag: true})`\n * */\n public overrideLinkedFlag() {\n if (!this._lazyLoadedSessionRecording) {\n this._instance.persistence?.register({\n [SESSION_RECORDING_OVERRIDE_LINKED_FLAG]: true,\n })\n }\n\n this._lazyLoadedSessionRecording?.overrideLinkedFlag()\n }\n\n /**\n * this ignores the sampling config and (if other conditions are met) causes capture to start\n *\n * It is not usual to call this directly,\n * instead call `posthog.startSessionRecording({sampling: true})`\n * */\n public overrideSampling() {\n if (!this._lazyLoadedSessionRecording) {\n this._instance.persistence?.register({\n [SESSION_RECORDING_OVERRIDE_SAMPLING]: true,\n })\n }\n\n this._lazyLoadedSessionRecording?.overrideSampling()\n }\n\n /**\n * this ignores the URL/Event trigger config and (if other conditions are met) causes capture to start\n *\n * It is not usual to call this directly,\n * instead call `posthog.startSessionRecording({trigger: 'url' | 'event'})`\n * */\n public overrideTrigger(triggerType: TriggerType) {\n if (!this._lazyLoadedSessionRecording) {\n this._instance.persistence?.register({\n [triggerType === 'url'\n ? SESSION_RECORDING_OVERRIDE_URL_TRIGGER\n : SESSION_RECORDING_OVERRIDE_EVENT_TRIGGER]: true,\n })\n }\n\n this._lazyLoadedSessionRecording?.overrideTrigger(triggerType)\n }\n\n /*\n * whenever we capture an event, we add these properties to the event\n * these are used to debug issues with the session recording\n * when looking at the event feed for a session\n */\n get sdkDebugProperties(): Properties {\n return (\n this._lazyLoadedSessionRecording?.sdkDebugProperties || {\n $recording_status: this.status,\n }\n )\n }\n\n /**\n * This adds a custom event to the session recording\n *\n * It is not intended for arbitrary public use - playback only displays known custom events\n * And is exposed on the public interface only so that other parts of the SDK are able to use it\n *\n * if you are calling this from client code, you're probably looking for `posthog.capture('$custom_event', {...})`\n */\n tryAddCustomEvent(tag: string, payload: any): boolean {\n return !!this._lazyLoadedSessionRecording?.tryAddCustomEvent(tag, payload)\n }\n}\n","import { Autocapture } from './autocapture'\nimport Config from './config'\nimport { ConsentManager, ConsentStatus } from './consent'\nimport {\n ALIAS_ID_KEY,\n COOKIELESS_MODE_FLAG_PROPERTY,\n COOKIELESS_SENTINEL_VALUE,\n ENABLE_PERSON_PROCESSING,\n FLAG_CALL_REPORTED,\n PEOPLE_DISTINCT_ID_KEY,\n SURVEYS_REQUEST_TIMEOUT_MS,\n USER_STATE,\n} from './constants'\nimport { DeadClicksAutocapture, isDeadClicksEnabledForAutocapture } from './extensions/dead-clicks-autocapture'\nimport { ExceptionObserver } from './extensions/exception-autocapture'\nimport { HistoryAutocapture } from './extensions/history-autocapture'\nimport { setupSegmentIntegration } from './extensions/segment-integration'\nimport { SentryIntegration, sentryIntegration, SentryIntegrationOptions } from './extensions/sentry-integration'\nimport { Toolbar } from './extensions/toolbar'\nimport { TracingHeaders } from './extensions/tracing-headers'\nimport { WebVitalsAutocapture } from './extensions/web-vitals'\nimport { Heatmaps } from './heatmaps'\nimport { PageViewManager } from './page-view'\nimport { PostHogExceptions } from './posthog-exceptions'\nimport { PostHogFeatureFlags } from './posthog-featureflags'\nimport { PostHogPersistence } from './posthog-persistence'\nimport { PostHogProductTours } from './posthog-product-tours'\nimport { PostHogSurveys } from './posthog-surveys'\nimport { PostHogConversations } from './extensions/conversations/posthog-conversations'\nimport {\n DisplaySurveyOptions,\n SurveyCallback,\n SurveyEventName,\n SurveyEventProperties,\n SurveyRenderReason,\n} from './posthog-surveys-types'\nimport { RateLimiter } from './rate-limiter'\nimport { RemoteConfigLoader } from './remote-config'\nimport { extendURLParams, request, SUPPORTS_REQUEST } from './request'\nimport { DEFAULT_FLUSH_INTERVAL_MS, RequestQueue } from './request-queue'\nimport { RetryQueue } from './retry-queue'\nimport { ScrollManager } from './scroll-manager'\nimport { SessionPropsManager } from './session-props'\nimport { SessionIdManager } from './sessionid'\nimport { SiteApps } from './site-apps'\nimport { localStore } from './storage'\nimport {\n CaptureOptions,\n CaptureResult,\n Compression,\n ConfigDefaults,\n EarlyAccessFeatureCallback,\n EarlyAccessFeatureStage,\n EventName,\n ExceptionAutoCaptureConfig,\n FeatureFlagDetail,\n FeatureFlagsCallback,\n JsonType,\n OverrideConfig,\n PostHogConfig,\n Properties,\n Property,\n QueuedRequestWithOptions,\n RemoteConfig,\n RequestCallback,\n SessionIdChangedCallback,\n SnippetArrayItem,\n ToolbarParams,\n PostHogInterface,\n} from './types'\nimport {\n _copyAndTruncateStrings,\n addEventListener,\n each,\n eachArray,\n extend,\n isCrossDomainCookie,\n migrateConfigField,\n safewrapClass,\n} from './utils'\nimport { isLikelyBot } from './utils/blocked-uas'\nimport { getEventProperties } from './utils/event-utils'\nimport { assignableWindow, document, location, navigator, userAgent, window } from './utils/globals'\nimport { logger } from './utils/logger'\nimport { getPersonPropertiesHash } from './utils/property-utils'\nimport { RequestRouter, RequestRouterRegion } from './utils/request-router'\nimport { SimpleEventEmitter } from './utils/simple-event-emitter'\nimport {\n DEFAULT_DISPLAY_SURVEY_OPTIONS,\n getSurveyInteractionProperty,\n setSurveySeenOnLocalStorage,\n} from './utils/survey-utils'\nimport {\n isEmptyString,\n isFunction,\n isKnownUnsafeEditableEvent,\n isNullish,\n isNumber,\n isString,\n isUndefined,\n includes,\n isDistinctIdStringLike,\n isArray,\n isEmptyObject,\n isObject,\n isBoolean,\n} from '@posthog/core'\nimport { uuidv7 } from './uuidv7'\nimport { WebExperiments } from './web-experiments'\nimport { ExternalIntegrations } from './extensions/external-integration'\nimport { SessionRecording } from './extensions/replay/session-recording'\n\n/*\nSIMPLE STYLE GUIDE:\n\nUse TypeScript accessibility modifiers, e.g. private/protected\n\nIf something is not part of the public interface:\n* prefix it with _ to allow mangling\n* prefix it with __ to disable mangling, but signal that it is internal\n\nGlobals should be all caps\n*/\n\n/* posthog.init is called with `Partial<PostHogConfig>`\n * and we want to ensure that only valid keys are passed to the config object.\n * TypeScript does not enforce that the object passed does not have extra keys.\n * So someone can call with { bootstrap: { distinctId: '123'} }\n * which is not a valid key. They should have passed distinctID (upper case D).\n * That's a really tricky mistake to spot.\n * The OnlyValidKeys type ensures that only keys that are valid in the PostHogConfig type are allowed.\n */\ntype OnlyValidKeys<T, Shape> = T extends Shape ? (Exclude<keyof T, keyof Shape> extends never ? T : never) : never\n\nconst instances: Record<string, PostHog> = {}\n\n// some globals for comparisons\nconst __NOOP = () => {}\n\nconst PRIMARY_INSTANCE_NAME = 'posthog'\n\n/*\n * Dynamic... constants? Is that an oxymoron?\n */\n// http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/\n// https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#withCredentials\n\n// IE<10 does not support cross-origin XHR's but script tags\n// with defer won't block window.onload; ENQUEUE_REQUESTS\n// should only be true for Opera<12\nlet ENQUEUE_REQUESTS = !SUPPORTS_REQUEST && userAgent?.indexOf('MSIE') === -1 && userAgent?.indexOf('Mozilla') === -1\n\nconst defaultsThatVaryByConfig = (\n defaults?: ConfigDefaults\n): Pick<PostHogConfig, 'rageclick' | 'capture_pageview' | 'session_recording'> => ({\n rageclick: defaults && defaults >= '2025-11-30' ? { content_ignorelist: true } : true,\n capture_pageview: defaults && defaults >= '2025-05-24' ? 'history_change' : true,\n session_recording: defaults && defaults >= '2025-11-30' ? { strictMinimumDuration: true } : {},\n})\n\n// NOTE: Remember to update `types.ts` when changing a default value\n// to guarantee documentation is up to date, make sure to also update our website docs\n// NOTE²: This shouldn't ever change because we try very hard to be backwards-compatible\nexport const defaultConfig = (defaults?: ConfigDefaults): PostHogConfig => ({\n api_host: 'https://us.i.posthog.com',\n flags_api_host: null,\n ui_host: null,\n token: '',\n autocapture: true,\n cross_subdomain_cookie: isCrossDomainCookie(document?.location),\n persistence: 'localStorage+cookie', // up to 1.92.0 this was 'cookie'. It's easy to migrate as 'localStorage+cookie' will migrate data from cookie storage\n persistence_name: '',\n cookie_persisted_properties: [],\n loaded: __NOOP,\n save_campaign_params: true,\n custom_campaign_params: [],\n custom_blocked_useragents: [],\n save_referrer: true,\n capture_pageleave: 'if_capture_pageview', // We'll only capture pageleave events if capture_pageview is also true\n defaults: defaults ?? 'unset',\n __preview_deferred_init_extensions: false, // Opt-in only for now\n debug: (location && isString(location?.search) && location.search.indexOf('__posthog_debug=true') !== -1) || false,\n cookie_expiration: 365,\n upgrade: false,\n disable_session_recording: false,\n disable_persistence: false,\n disable_web_experiments: true, // disabled in beta.\n disable_surveys: false,\n disable_surveys_automatic_display: false,\n disable_conversations: false,\n disable_product_tours: true,\n disable_external_dependency_loading: false,\n enable_recording_console_log: undefined, // When undefined, it falls back to the server-side setting\n secure_cookie: window?.location?.protocol === 'https:',\n ip: false,\n opt_out_capturing_by_default: false,\n opt_out_persistence_by_default: false,\n opt_out_useragent_filter: false,\n opt_out_capturing_persistence_type: 'localStorage',\n consent_persistence_name: null,\n opt_out_capturing_cookie_prefix: null,\n opt_in_site_apps: false,\n property_denylist: [],\n respect_dnt: false,\n sanitize_properties: null,\n request_headers: {}, // { header: value, header2: value }\n request_batching: true,\n properties_string_max_length: 65535,\n mask_all_element_attributes: false,\n mask_all_text: false,\n mask_personal_data_properties: false,\n custom_personal_data_properties: [],\n advanced_disable_flags: false,\n advanced_disable_decide: false,\n advanced_disable_feature_flags: false,\n advanced_disable_feature_flags_on_first_load: false,\n advanced_only_evaluate_survey_feature_flags: false,\n advanced_enable_surveys: false,\n advanced_disable_toolbar_metrics: false,\n feature_flag_request_timeout_ms: 3000,\n surveys_request_timeout_ms: SURVEYS_REQUEST_TIMEOUT_MS,\n on_request_error: (res) => {\n const error = 'Bad HTTP status: ' + res.statusCode + ' ' + res.text\n logger.error(error)\n },\n get_device_id: (uuid) => uuid,\n capture_performance: undefined,\n name: 'posthog',\n bootstrap: {},\n disable_compression: false,\n session_idle_timeout_seconds: 30 * 60, // 30 minutes\n person_profiles: 'identified_only',\n before_send: undefined,\n request_queue_config: { flush_interval_ms: DEFAULT_FLUSH_INTERVAL_MS },\n error_tracking: {},\n\n // Used for internal testing\n _onCapture: __NOOP,\n\n // make the default be lazy loading replay\n __preview_eager_load_replay: false,\n\n ...defaultsThatVaryByConfig(defaults),\n})\n\nexport const configRenames = (origConfig: Partial<PostHogConfig>): Partial<PostHogConfig> => {\n const renames: Partial<PostHogConfig> = {}\n if (!isUndefined(origConfig.process_person)) {\n renames.person_profiles = origConfig.process_person\n }\n if (!isUndefined(origConfig.xhr_headers)) {\n renames.request_headers = origConfig.xhr_headers\n }\n if (!isUndefined(origConfig.cookie_name)) {\n renames.persistence_name = origConfig.cookie_name\n }\n if (!isUndefined(origConfig.disable_cookie)) {\n renames.disable_persistence = origConfig.disable_cookie\n }\n if (!isUndefined(origConfig.store_google)) {\n renames.save_campaign_params = origConfig.store_google\n }\n if (!isUndefined(origConfig.verbose)) {\n renames.debug = origConfig.verbose\n }\n // on_xhr_error is not present, as the type is different to on_request_error\n\n // the original config takes priority over the renames\n const newConfig = extend({}, renames, origConfig)\n\n // merge property_blacklist into property_denylist\n if (isArray(origConfig.property_blacklist)) {\n if (isUndefined(origConfig.property_denylist)) {\n newConfig.property_denylist = origConfig.property_blacklist\n } else if (isArray(origConfig.property_denylist)) {\n newConfig.property_denylist = [...origConfig.property_blacklist, ...origConfig.property_denylist]\n } else {\n logger.error('Invalid value for property_denylist config: ' + origConfig.property_denylist)\n }\n }\n\n return newConfig\n}\n\nclass DeprecatedWebPerformanceObserver {\n get _forceAllowLocalhost(): boolean {\n return this.__forceAllowLocalhost\n }\n\n set _forceAllowLocalhost(value: boolean) {\n logger.error(\n 'WebPerformanceObserver is deprecated and has no impact on network capture. Use `_forceAllowLocalhostNetworkCapture` on `posthog.sessionRecording`'\n )\n this.__forceAllowLocalhost = value\n }\n\n private __forceAllowLocalhost: boolean = false\n}\n\n/**\n *\n * This is the SDK reference for the PostHog JavaScript Web SDK.\n * You can learn more about example usage in the\n * [JavaScript Web SDK documentation](/docs/libraries/js).\n * You can also follow [framework specific guides](/docs/frameworks)\n * to integrate PostHog into your project.\n *\n * This SDK is designed for browser environments.\n * Use the PostHog [Node.js SDK](/docs/libraries/node) for server-side usage.\n *\n * @constructor\n */\nexport class PostHog implements PostHogInterface {\n __loaded: boolean\n config: PostHogConfig\n _originalUserConfig?: Partial<PostHogConfig>\n\n rateLimiter: RateLimiter\n scrollManager: ScrollManager\n pageViewManager: PageViewManager\n featureFlags: PostHogFeatureFlags\n surveys: PostHogSurveys\n conversations: PostHogConversations\n experiments: WebExperiments\n toolbar: Toolbar\n exceptions: PostHogExceptions\n consent: ConsentManager\n\n // These are instance-specific state created after initialisation\n persistence?: PostHogPersistence\n sessionPersistence?: PostHogPersistence\n sessionManager?: SessionIdManager\n sessionPropsManager?: SessionPropsManager\n requestRouter: RequestRouter\n siteApps?: SiteApps\n autocapture?: Autocapture\n heatmaps?: Heatmaps\n webVitalsAutocapture?: WebVitalsAutocapture\n exceptionObserver?: ExceptionObserver\n deadClicksAutocapture?: DeadClicksAutocapture\n historyAutocapture?: HistoryAutocapture\n productTours?: PostHogProductTours\n\n _requestQueue?: RequestQueue\n _retryQueue?: RetryQueue\n sessionRecording?: SessionRecording\n externalIntegrations?: ExternalIntegrations\n webPerformance = new DeprecatedWebPerformanceObserver()\n\n _initialPageviewCaptured: boolean\n _visibilityStateListener: (() => void) | null\n _personProcessingSetOncePropertiesSent: boolean = false\n _triggered_notifs: any\n compression?: Compression\n __request_queue: QueuedRequestWithOptions[]\n _pendingRemoteConfig?: RemoteConfig\n analyticsDefaultEndpoint: string\n version: string = Config.LIB_VERSION\n _initialPersonProfilesConfig: 'always' | 'never' | 'identified_only' | null\n _cachedPersonProperties: string | null\n\n SentryIntegration: typeof SentryIntegration\n sentryIntegration: (options?: SentryIntegrationOptions) => ReturnType<typeof sentryIntegration>\n\n private _internalEventEmitter = new SimpleEventEmitter()\n\n // Legacy property to support existing usage - this isn't technically correct but it's what it has always been - a proxy for flags being loaded\n /** @deprecated Use `flagsEndpointWasHit` instead. We migrated to using a new feature flag endpoint and the new method is more semantically accurate */\n public get decideEndpointWasHit(): boolean {\n return this.featureFlags?.hasLoadedFlags ?? false\n }\n\n public get flagsEndpointWasHit(): boolean {\n return this.featureFlags?.hasLoadedFlags ?? false\n }\n\n /** DEPRECATED: We keep this to support existing usage but now one should just call .setPersonProperties */\n people: {\n set: (prop: string | Properties, to?: string, callback?: RequestCallback) => void\n set_once: (prop: string | Properties, to?: string, callback?: RequestCallback) => void\n }\n\n constructor() {\n this.config = defaultConfig()\n\n this.SentryIntegration = SentryIntegration\n this.sentryIntegration = (options?: SentryIntegrationOptions) => sentryIntegration(this, options)\n this.__request_queue = []\n this.__loaded = false\n this.analyticsDefaultEndpoint = '/e/'\n this._initialPageviewCaptured = false\n this._visibilityStateListener = null\n this._initialPersonProfilesConfig = null\n this._cachedPersonProperties = null\n this.featureFlags = new PostHogFeatureFlags(this)\n this.toolbar = new Toolbar(this)\n this.scrollManager = new ScrollManager(this)\n this.pageViewManager = new PageViewManager(this)\n this.surveys = new PostHogSurveys(this)\n this.conversations = new PostHogConversations(this)\n this.experiments = new WebExperiments(this)\n this.exceptions = new PostHogExceptions(this)\n this.rateLimiter = new RateLimiter(this)\n this.requestRouter = new RequestRouter(this)\n this.consent = new ConsentManager(this)\n this.externalIntegrations = new ExternalIntegrations(this)\n // NOTE: See the property definition for deprecation notice\n this.people = {\n set: (prop: string | Properties, to?: string, callback?: RequestCallback) => {\n const setProps = isString(prop) ? { [prop]: to } : prop\n this.setPersonProperties(setProps)\n callback?.({} as any)\n },\n set_once: (prop: string | Properties, to?: string, callback?: RequestCallback) => {\n const setProps = isString(prop) ? { [prop]: to } : prop\n this.setPersonProperties(undefined, setProps)\n callback?.({} as any)\n },\n }\n\n this.on('eventCaptured', (data) => logger.info(`send \"${data?.event}\"`, data))\n }\n\n // Initialization methods\n\n /**\n * Initializes a new instance of the PostHog capturing object.\n *\n * @remarks\n * All new instances are added to the main posthog object as sub properties (such as\n * `posthog.library_name`) and also returned by this function. [Learn more about configuration options](https://github.com/posthog/posthog-js/blob/6e0e873/src/posthog-core.js#L57-L91)\n *\n * @example\n * ```js\n * // basic initialization\n * posthog.init('<ph_project_api_key>', {\n * api_host: '<ph_client_api_host>'\n * })\n * ```\n *\n * @example\n * ```js\n * // multiple instances\n * posthog.init('<ph_project_api_key>', {}, 'project1')\n * posthog.init('<ph_project_api_key>', {}, 'project2')\n * ```\n *\n * @public\n *\n * @param token - Your PostHog API token\n * @param config - A dictionary of config options to override\n * @param name - The name for the new posthog instance that you want created\n *\n * {@label Initialization}\n *\n * @returns The newly initialized PostHog instance\n */\n init(\n token: string,\n config?: OnlyValidKeys<Partial<PostHogConfig>, Partial<PostHogConfig>>,\n name?: string\n ): PostHog {\n if (!name || name === PRIMARY_INSTANCE_NAME) {\n // This means we are initializing the primary instance (i.e. this)\n return this._init(token, config, name)\n } else {\n const namedPosthog = instances[name] ?? new PostHog()\n namedPosthog._init(token, config, name)\n instances[name] = namedPosthog\n\n // Add as a property to the primary instance (this isn't type-safe but it is how it was always done)\n ;(instances[PRIMARY_INSTANCE_NAME] as any)[name] = namedPosthog\n\n return namedPosthog\n }\n }\n\n // posthog._init(token:string, config:object, name:string)\n //\n // This function sets up the current instance of the posthog\n // library. The difference between this method and the init(...)\n // method is this one initializes the actual instance, whereas the\n // init(...) method sets up a new library and calls _init on it.\n //\n // Note that there are operations that can be asynchronous, so we\n // accept a callback that is called when all the asynchronous work\n // is done. Note that we do not use promises because we want to be\n // IE11 compatible. We could use polyfills, which would make the\n // code a bit cleaner, but will add some overhead.\n //\n _init(token: string, config: Partial<PostHogConfig> = {}, name?: string): PostHog {\n if (isUndefined(token) || isEmptyString(token)) {\n logger.critical(\n 'PostHog was initialized without a token. This likely indicates a misconfiguration. Please check the first argument passed to posthog.init()'\n )\n return this\n }\n\n if (this.__loaded) {\n // need to be able to log before having processed debug config\n // eslint-disable-next-line no-console\n console.warn('[PostHog.js]', 'You have already initialized PostHog! Re-initializing is a no-op')\n return this\n }\n\n this.__loaded = true\n this.config = {} as PostHogConfig // will be set right below\n config.debug = this._checkLocalStorageForDebug(config.debug)\n this._originalUserConfig = config // Store original user config for migration\n\n this._triggered_notifs = []\n\n if (config.person_profiles) {\n this._initialPersonProfilesConfig = config.person_profiles\n }\n\n this.set_config(\n extend({}, defaultConfig(config.defaults), configRenames(config), {\n name: name,\n token: token,\n })\n )\n\n if (this.config.on_xhr_error) {\n logger.error('on_xhr_error is deprecated. Use on_request_error instead')\n }\n\n this.compression = config.disable_compression ? undefined : Compression.GZipJS\n\n const persistenceDisabled = this._is_persistence_disabled()\n\n this.persistence = new PostHogPersistence(this.config, persistenceDisabled)\n this.sessionPersistence =\n this.config.persistence === 'sessionStorage' || this.config.persistence === 'memory'\n ? this.persistence\n : new PostHogPersistence({ ...this.config, persistence: 'sessionStorage' }, persistenceDisabled)\n\n // should I store the initial person profiles config in persistence?\n const initialPersistenceProps = { ...this.persistence.props }\n const initialSessionProps = { ...this.sessionPersistence.props }\n\n this.register({ $initialization_time: new Date().toISOString() })\n\n this._requestQueue = new RequestQueue(\n (req) => this._send_retriable_request(req),\n this.config.request_queue_config\n )\n this._retryQueue = new RetryQueue(this)\n this.__request_queue = []\n\n const startInCookielessMode =\n this.config.cookieless_mode === 'always' ||\n (this.config.cookieless_mode === 'on_reject' && this.consent.isExplicitlyOptedOut())\n\n if (!startInCookielessMode) {\n this.sessionManager = new SessionIdManager(this)\n this.sessionPropsManager = new SessionPropsManager(this, this.sessionManager, this.persistence)\n }\n\n // Conditionally defer extension initialization based on config\n if (this.config.__preview_deferred_init_extensions) {\n // EXPERIMENTAL: Defer non-critical extension initialization to next tick\n // This reduces main thread blocking during init\n // while keeping critical path (persistence, sessions, capture) synchronous\n logger.info('Deferring extension initialization to improve startup performance')\n setTimeout(() => {\n this._initExtensions(startInCookielessMode)\n }, 0)\n } else {\n // Legacy synchronous initialization (default for now)\n logger.info('Initializing extensions synchronously')\n this._initExtensions(startInCookielessMode)\n }\n\n // if any instance on the page has debug = true, we set the\n // global debug to be true\n Config.DEBUG = Config.DEBUG || this.config.debug\n if (Config.DEBUG) {\n logger.info('Starting in debug mode', {\n this: this,\n config,\n thisC: { ...this.config },\n p: initialPersistenceProps,\n s: initialSessionProps,\n })\n }\n\n // isUndefined doesn't provide typehint here so wouldn't reduce bundle as we'd need to assign\n // eslint-disable-next-line posthog-js/no-direct-undefined-check\n if (config.bootstrap?.distinctID !== undefined) {\n const uuid = this.config.get_device_id(uuidv7())\n const deviceID = config.bootstrap?.isIdentifiedID ? uuid : config.bootstrap.distinctID\n this.persistence.set_property(USER_STATE, config.bootstrap?.isIdentifiedID ? 'identified' : 'anonymous')\n this.register({\n distinct_id: config.bootstrap.distinctID,\n $device_id: deviceID,\n })\n }\n\n if (this._hasBootstrappedFeatureFlags()) {\n const activeFlags = Object.keys(config.bootstrap?.featureFlags || {})\n .filter((flag) => !!config.bootstrap?.featureFlags?.[flag])\n .reduce((res: Record<string, string | boolean>, key) => {\n res[key] = config.bootstrap?.featureFlags?.[key] || false\n return res\n }, {})\n const featureFlagPayloads = Object.keys(config.bootstrap?.featureFlagPayloads || {})\n .filter((key) => activeFlags[key])\n .reduce((res: Record<string, JsonType>, key) => {\n if (config.bootstrap?.featureFlagPayloads?.[key]) {\n res[key] = config.bootstrap?.featureFlagPayloads?.[key]\n }\n return res\n }, {})\n\n this.featureFlags.receivedFeatureFlags({ featureFlags: activeFlags, featureFlagPayloads })\n }\n\n if (startInCookielessMode) {\n this.register_once(\n {\n distinct_id: COOKIELESS_SENTINEL_VALUE,\n $device_id: null,\n },\n ''\n )\n } else if (!this.get_distinct_id()) {\n // There is no need to set the distinct id\n // or the device id if something was already stored\n // in the persistence\n const uuid = this.config.get_device_id(uuidv7())\n\n this.register_once(\n {\n distinct_id: uuid,\n $device_id: uuid,\n },\n ''\n )\n // distinct id == $device_id is a proxy for anonymous user\n this.persistence.set_property(USER_STATE, 'anonymous')\n }\n // Set up event handler for pageleave\n // Use `onpagehide` if available, see https://calendar.perfplanet.com/2020/beaconing-in-practice/#beaconing-reliability-avoiding-abandons\n //\n // Not making it passive to try and force the browser to handle this before the page is unloaded\n addEventListener(window, 'onpagehide' in self ? 'pagehide' : 'unload', this._handle_unload.bind(this), {\n passive: false,\n })\n\n this.toolbar.maybeLoadToolbar()\n\n // We want to avoid promises for IE11 compatibility, so we use callbacks here\n if (config.segment) {\n setupSegmentIntegration(this, () => this._loaded())\n } else {\n this._loaded()\n }\n\n if (isFunction(this.config._onCapture) && this.config._onCapture !== __NOOP) {\n logger.warn('onCapture is deprecated. Please use `before_send` instead')\n this.on('eventCaptured', (data) => this.config._onCapture(data.event, data))\n }\n\n if (this.config.ip) {\n logger.warn(\n 'The `ip` config option has NO EFFECT AT ALL and has been deprecated. Use a custom transformation or \"Discard IP data\" project setting instead. See https://posthog.com/tutorials/web-redact-properties#hiding-customer-ip-address for more information.'\n )\n }\n\n return this\n }\n\n private _initExtensions(startInCookielessMode: boolean): void {\n // we don't support IE11 anymore, so performance.now is safe\n // eslint-disable-next-line compat/compat\n const initStartTime = performance.now()\n\n this.historyAutocapture = new HistoryAutocapture(this)\n this.historyAutocapture.startIfEnabled()\n\n // Build queue of extension initialization tasks\n const initTasks: Array<() => void> = []\n\n initTasks.push(() => {\n new TracingHeaders(this).startIfEnabledOrStop()\n })\n\n initTasks.push(() => {\n this.siteApps = new SiteApps(this)\n this.siteApps?.init()\n })\n\n if (!startInCookielessMode) {\n initTasks.push(() => {\n this.sessionRecording = new SessionRecording(this)\n this.sessionRecording.startIfEnabledOrStop()\n })\n }\n\n if (!this.config.disable_scroll_properties) {\n initTasks.push(() => {\n this.scrollManager.startMeasuringScrollPosition()\n })\n }\n\n initTasks.push(() => {\n this.autocapture = new Autocapture(this)\n this.autocapture.startIfEnabled()\n })\n\n initTasks.push(() => {\n this.surveys.loadIfEnabled()\n })\n\n initTasks.push(() => {\n this.conversations.loadIfEnabled()\n })\n\n initTasks.push(() => {\n this.productTours = new PostHogProductTours(this)\n this.productTours.loadIfEnabled()\n })\n\n initTasks.push(() => {\n this.heatmaps = new Heatmaps(this)\n this.heatmaps.startIfEnabled()\n })\n\n initTasks.push(() => {\n this.webVitalsAutocapture = new WebVitalsAutocapture(this)\n })\n\n initTasks.push(() => {\n this.exceptionObserver = new ExceptionObserver(this)\n this.exceptionObserver.startIfEnabledOrStop()\n })\n\n initTasks.push(() => {\n this.deadClicksAutocapture = new DeadClicksAutocapture(this, isDeadClicksEnabledForAutocapture)\n this.deadClicksAutocapture.startIfEnabled()\n })\n\n // Replay any pending remote config that arrived before extensions were ready\n initTasks.push(() => {\n if (this._pendingRemoteConfig) {\n const config = this._pendingRemoteConfig\n this._pendingRemoteConfig = undefined // Clear before replaying to avoid re-storing\n this._onRemoteConfig(config)\n }\n })\n\n // Process tasks with time-slicing to avoid blocking\n this._processInitTaskQueue(initTasks, initStartTime)\n }\n\n private _processInitTaskQueue(queue: Array<() => void>, initStartTime: number): void {\n const TIME_BUDGET_MS = 30 // Respect frame budget (~60fps = 16ms, but we're already deferred)\n\n while (queue.length > 0) {\n // Only time-slice if deferred init is enabled, otherwise run synchronously\n if (this.config.__preview_deferred_init_extensions) {\n // we don't support IE11 anymore, so performance.now is safe\n // eslint-disable-next-line compat/compat\n const elapsed = performance.now() - initStartTime\n\n // Check if we've exceeded our time budget\n if (elapsed >= TIME_BUDGET_MS && queue.length > 0) {\n // Yield to browser, then continue processing\n setTimeout(() => {\n this._processInitTaskQueue(queue, initStartTime)\n }, 0)\n return\n }\n }\n\n // Process next task\n const task = queue.shift()\n if (task) {\n try {\n task()\n } catch (error) {\n logger.error('Error initializing extension:', error)\n }\n }\n }\n\n // All tasks complete - record timing for both sync and deferred modes\n // we don't support IE11 anymore, so performance.now is safe\n // eslint-disable-next-line compat/compat\n const taskInitTiming = Math.round(performance.now() - initStartTime)\n this.register_for_session({\n $sdk_debug_extensions_init_method: this.config.__preview_deferred_init_extensions\n ? 'deferred'\n : 'synchronous',\n $sdk_debug_extensions_init_time_ms: taskInitTiming,\n })\n if (this.config.__preview_deferred_init_extensions) {\n logger.info(`PostHog extensions initialized (${taskInitTiming}ms)`)\n }\n }\n\n _onRemoteConfig(config: RemoteConfig) {\n if (!(document && document.body)) {\n logger.info('document not ready yet, trying again in 500 milliseconds...')\n setTimeout(() => {\n this._onRemoteConfig(config)\n }, 500)\n return\n }\n\n // Store config in case extensions aren't initialized yet (only needed for deferred init)\n if (this.config.__preview_deferred_init_extensions) {\n this._pendingRemoteConfig = config\n }\n\n this.compression = undefined\n if (config.supportedCompression && !this.config.disable_compression) {\n this.compression = includes(config['supportedCompression'], Compression.GZipJS)\n ? Compression.GZipJS\n : includes(config['supportedCompression'], Compression.Base64)\n ? Compression.Base64\n : undefined\n }\n\n if (config.analytics?.endpoint) {\n this.analyticsDefaultEndpoint = config.analytics.endpoint\n }\n\n this.set_config({\n person_profiles: this._initialPersonProfilesConfig ? this._initialPersonProfilesConfig : 'identified_only',\n })\n\n this.siteApps?.onRemoteConfig(config)\n this.sessionRecording?.onRemoteConfig(config)\n this.autocapture?.onRemoteConfig(config)\n this.heatmaps?.onRemoteConfig(config)\n this.surveys.onRemoteConfig(config)\n this.conversations.onRemoteConfig(config)\n this.productTours?.onRemoteConfig(config)\n this.webVitalsAutocapture?.onRemoteConfig(config)\n this.exceptionObserver?.onRemoteConfig(config)\n this.exceptions.onRemoteConfig(config)\n this.deadClicksAutocapture?.onRemoteConfig(config)\n }\n\n _loaded(): void {\n try {\n this.config.loaded(this)\n } catch (err) {\n logger.critical('`loaded` function failed', err)\n }\n\n this._start_queue_if_opted_in()\n\n // this happens after \"loaded\" so a user can call identify or any other things before the pageview fires\n if (this.config.capture_pageview) {\n // NOTE: We want to fire this on the next tick as the previous implementation had this side effect\n // and some clients may rely on it\n setTimeout(() => {\n if (this.consent.isOptedIn() || this.config.cookieless_mode === 'always') {\n this._captureInitialPageview()\n }\n }, 1)\n }\n\n new RemoteConfigLoader(this).load()\n this.featureFlags.flags()\n }\n\n _start_queue_if_opted_in(): void {\n if (this.is_capturing()) {\n if (this.config.request_batching) {\n this._requestQueue?.enable()\n }\n }\n }\n\n _dom_loaded(): void {\n if (this.is_capturing()) {\n eachArray(this.__request_queue, (item) => this._send_retriable_request(item))\n }\n\n this.__request_queue = []\n this._start_queue_if_opted_in()\n }\n\n _handle_unload(): void {\n this.surveys.handlePageUnload()\n\n if (!this.config.request_batching) {\n if (this._shouldCapturePageleave()) {\n this.capture('$pageleave', null, { transport: 'sendBeacon' })\n }\n return\n }\n\n if (this._shouldCapturePageleave()) {\n this.capture('$pageleave')\n }\n\n this._requestQueue?.unload()\n this._retryQueue?.unload()\n }\n\n _send_request(options: QueuedRequestWithOptions): void {\n if (!this.__loaded) {\n return\n }\n\n if (ENQUEUE_REQUESTS) {\n this.__request_queue.push(options)\n return\n }\n\n if (this.rateLimiter.isServerRateLimited(options.batchKey)) {\n return\n }\n\n options.transport = options.transport || this.config.api_transport\n options.url = extendURLParams(options.url, {\n // Whether to detect ip info or not\n ip: this.config.ip ? 1 : 0,\n })\n options.headers = {\n ...this.config.request_headers,\n ...options.headers,\n }\n options.compression = options.compression === 'best-available' ? this.compression : options.compression\n options.disableXHRCredentials = this.config.__preview_disable_xhr_credentials\n if (this.config.__preview_disable_beacon) {\n options.disableTransport = ['sendBeacon']\n }\n\n // Specially useful if you're doing SSR with NextJS\n // Users must be careful when tweaking `cache` because they might get out-of-date feature flags\n options.fetchOptions = options.fetchOptions || this.config.fetch_options\n\n request({\n ...options,\n callback: (response) => {\n this.rateLimiter.checkForLimiting(response)\n\n if (response.statusCode >= 400) {\n this.config.on_request_error?.(response)\n }\n\n options.callback?.(response)\n },\n })\n }\n\n _send_retriable_request(options: QueuedRequestWithOptions): void {\n if (this._retryQueue) {\n this._retryQueue.retriableRequest(options)\n } else {\n this._send_request(options)\n }\n }\n\n /**\n * _execute_array() deals with processing any posthog function\n * calls that were called before the PostHog library were loaded\n * (and are thus stored in an array so they can be called later)\n *\n * Note: we fire off all the posthog function calls && user defined\n * functions BEFORE we fire off posthog capturing calls. This is so\n * identify/register/set_config calls can properly modify early\n * capturing calls.\n *\n * @param {Array} array\n */\n _execute_array(array: SnippetArrayItem[]): void {\n let fn_name\n const alias_calls: SnippetArrayItem[] = []\n const other_calls: SnippetArrayItem[] = []\n const capturing_calls: SnippetArrayItem[] = []\n eachArray(array, (item) => {\n if (item) {\n fn_name = item[0]\n if (isArray(fn_name)) {\n capturing_calls.push(item) // chained call e.g. posthog.get_group().set()\n } else if (isFunction(item)) {\n ;(item as any).call(this)\n } else if (isArray(item) && fn_name === 'alias') {\n alias_calls.push(item)\n } else if (isArray(item) && fn_name.indexOf('capture') !== -1 && isFunction((this as any)[fn_name])) {\n capturing_calls.push(item)\n } else {\n other_calls.push(item)\n }\n }\n })\n\n const execute = function (calls: SnippetArrayItem[], thisArg: any) {\n eachArray(\n calls,\n function (item) {\n if (isArray(item[0])) {\n // chained call\n let caller = thisArg\n each(item, function (call) {\n caller = caller[call[0]].apply(caller, call.slice(1))\n })\n } else {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this[item[0]].apply(this, item.slice(1))\n }\n },\n thisArg\n )\n }\n\n execute(alias_calls, this)\n execute(other_calls, this)\n execute(capturing_calls, this)\n }\n\n _hasBootstrappedFeatureFlags(): boolean {\n return (\n (this.config.bootstrap?.featureFlags && Object.keys(this.config.bootstrap?.featureFlags).length > 0) ||\n false\n )\n }\n\n /**\n * push() keeps the standard async-array-push\n * behavior around after the lib is loaded.\n * This is only useful for external integrations that\n * do not wish to rely on our convenience methods\n * (created in the snippet).\n *\n * @example\n * ```js\n * posthog.push(['register', { a: 'b' }]);\n * ```\n *\n * @param {Array} item A [function_name, args...] array to be executed\n */\n push(item: SnippetArrayItem): void {\n this._execute_array([item])\n }\n\n /**\n * Captures an event with optional properties and configuration.\n *\n * @remarks\n * You can capture arbitrary object-like values as events. [Learn about capture best practices](/docs/product-analytics/capture-events)\n *\n * @example\n * ```js\n * // basic event capture\n * posthog.capture('cta-button-clicked', {\n * button_name: 'Get Started',\n * page: 'homepage'\n * })\n * ```\n *\n * {@label Capture}\n *\n * @public\n *\n * @param event_name - The name of the event (e.g., 'Sign Up', 'Button Click', 'Purchase')\n * @param properties - Properties to include with the event describing the user or event details\n * @param options - Optional configuration for the capture request\n *\n * @returns The capture result containing event data, or undefined if capture failed\n */\n capture(\n event_name: EventName,\n properties?: Properties | null,\n options?: CaptureOptions\n ): CaptureResult | undefined {\n // While developing, a developer might purposefully _not_ call init(),\n // in this case, we would like capture to be a noop.\n if (!this.__loaded || !this.persistence || !this.sessionPersistence || !this._requestQueue) {\n logger.uninitializedWarning('posthog.capture')\n return\n }\n\n if (!this.is_capturing()) {\n return\n }\n\n // typing doesn't prevent interesting data\n if (isUndefined(event_name) || !isString(event_name)) {\n logger.error('No event name provided to posthog.capture')\n return\n }\n\n const isBot = !this.config.opt_out_useragent_filter && this._is_bot()\n const shouldDropBotEvent = isBot && !this.config.__preview_capture_bot_pageviews\n\n // We drop bot events unless the preview flag to send bot pageviews is enabled\n // or the user has explicitly opted out of useragent filtering\n if (shouldDropBotEvent) {\n return\n }\n\n const clientRateLimitContext = !options?.skip_client_rate_limiting\n ? this.rateLimiter.clientRateLimitContext()\n : undefined\n\n if (clientRateLimitContext?.isRateLimited) {\n logger.critical('This capture call is ignored due to client rate limiting.')\n return\n }\n\n if (properties?.$current_url && !isString(properties?.$current_url)) {\n logger.error(\n 'Invalid `$current_url` property provided to `posthog.capture`. Input must be a string. Ignoring provided value.'\n )\n delete properties?.$current_url\n }\n\n // update persistence\n this.sessionPersistence.update_search_keyword()\n\n // The initial campaign/referrer props need to be stored in the regular persistence, as they are there to mimic\n // the person-initial props. The non-initial versions are stored in the sessionPersistence, as they are sent\n // with every event and used by the session table to create session-initial props.\n if (this.config.save_campaign_params) {\n this.sessionPersistence.update_campaign_params()\n }\n if (this.config.save_referrer) {\n this.sessionPersistence.update_referrer_info()\n }\n\n if (this.config.save_campaign_params || this.config.save_referrer) {\n this.persistence.set_initial_person_info()\n }\n\n const systemTime = new Date()\n const timestamp = options?.timestamp || systemTime\n\n const uuid = uuidv7()\n let data: CaptureResult = {\n uuid,\n event: event_name,\n properties: this.calculateEventProperties(event_name, properties || {}, timestamp, uuid),\n }\n\n // Route pageviews to $bot_pageview when bot detected and preview flag enabled\n if (event_name === '$pageview' && this.config.__preview_capture_bot_pageviews && isBot) {\n data.event = '$bot_pageview'\n // While it's obvious that a $bot_pageview is (likely) from a bot, we explicitly set $browser_type\n // to make it easy to filter and test bot pageviews in the product\n data.properties.$browser_type = 'bot'\n }\n\n if (clientRateLimitContext) {\n data.properties['$lib_rate_limit_remaining_tokens'] = clientRateLimitContext.remainingTokens\n }\n\n const setProperties = options?.$set\n if (setProperties) {\n data.$set = options?.$set\n }\n // $groupidentify doesn't process person $set_once on the server, so don't mark\n // initial person props as sent. This ensures they're included with subsequent\n // $identify calls.\n const markSetOnceAsSent = event_name !== '$groupidentify'\n const setOnceProperties = this._calculate_set_once_properties(options?.$set_once, markSetOnceAsSent)\n if (setOnceProperties) {\n data.$set_once = setOnceProperties\n }\n\n data = _copyAndTruncateStrings(data, options?._noTruncate ? null : this.config.properties_string_max_length)\n data.timestamp = timestamp\n if (!isUndefined(options?.timestamp)) {\n data.properties['$event_time_override_provided'] = true\n data.properties['$event_time_override_system_time'] = systemTime\n }\n\n if (event_name === SurveyEventName.DISMISSED || event_name === SurveyEventName.SENT) {\n const surveyId = properties?.[SurveyEventProperties.SURVEY_ID]\n const surveyIteration = properties?.[SurveyEventProperties.SURVEY_ITERATION]\n setSurveySeenOnLocalStorage({ id: surveyId, current_iteration: surveyIteration })\n data.$set = {\n ...data.$set,\n [getSurveyInteractionProperty(\n { id: surveyId, current_iteration: surveyIteration },\n event_name === SurveyEventName.SENT ? 'responded' : 'dismissed'\n )]: true,\n }\n } else if (event_name === SurveyEventName.SHOWN) {\n data.$set = {\n ...data.$set,\n [SurveyEventProperties.SURVEY_LAST_SEEN_DATE]: new Date().toISOString(),\n }\n }\n\n // Top-level $set overriding values from the one from properties is taken from the plugin-server normalizeEvent\n // This doesn't handle $set_once, because posthog-people doesn't either\n const finalSet = { ...data.properties['$set'], ...data['$set'] }\n if (!isEmptyObject(finalSet)) {\n this.setPersonPropertiesForFlags(finalSet)\n }\n\n if (!isNullish(this.config.before_send)) {\n const beforeSendResult = this._runBeforeSend(data)\n if (!beforeSendResult) {\n return\n } else {\n data = beforeSendResult\n }\n }\n\n this._internalEventEmitter.emit('eventCaptured', data)\n\n const requestOptions: QueuedRequestWithOptions = {\n method: 'POST',\n url: options?._url ?? this.requestRouter.endpointFor('api', this.analyticsDefaultEndpoint),\n data,\n compression: 'best-available',\n batchKey: options?._batchKey,\n }\n\n if (this.config.request_batching && (!options || options?._batchKey) && !options?.send_instantly) {\n this._requestQueue.enqueue(requestOptions)\n } else {\n this._send_retriable_request(requestOptions)\n }\n\n return data\n }\n\n _addCaptureHook(callback: (eventName: string, eventPayload?: CaptureResult) => void): () => void {\n return this.on('eventCaptured', (data) => callback(data.event, data))\n }\n\n /**\n * This method is used internally to calculate the event properties before sending it to PostHog. It can also be\n * used by integrations (e.g. Segment) to enrich events with PostHog properties before sending them to Segment,\n * which is required for some PostHog products to work correctly. (e.g. to have a correct $session_id property).\n *\n * @param {String} eventName The name of the event. This can be anything the user does - 'Button Click', 'Sign Up', '$pageview', etc.\n * @param {Object} eventProperties The properties to include with the event.\n * @param {Date} [timestamp] The timestamp of the event, e.g. for calculating time on page. If not set, it'll automatically be set to the current time.\n * @param {String} [uuid] The uuid of the event, e.g. for storing the $pageview ID.\n * @param {Boolean} [readOnly] Set this if you do not intend to actually send the event, and therefore do not want to update internal state e.g. session timeout\n *\n * @internal\n */\n public calculateEventProperties(\n eventName: string,\n eventProperties: Properties,\n timestamp?: Date,\n uuid?: string,\n readOnly?: boolean\n ): Properties {\n timestamp = timestamp || new Date()\n if (!this.persistence || !this.sessionPersistence) {\n return eventProperties\n }\n\n // set defaults\n const startTimestamp = readOnly ? undefined : this.persistence.remove_event_timer(eventName)\n let properties = { ...eventProperties }\n properties['token'] = this.config.token\n properties['$config_defaults'] = this.config.defaults\n\n if (\n this.config.cookieless_mode == 'always' ||\n (this.config.cookieless_mode == 'on_reject' && this.consent.isExplicitlyOptedOut())\n ) {\n // Set a flag to tell the plugin server to use cookieless server hash mode\n properties[COOKIELESS_MODE_FLAG_PROPERTY] = true\n }\n\n if (eventName === '$snapshot') {\n const persistenceProps = { ...this.persistence.properties(), ...this.sessionPersistence.properties() }\n properties['distinct_id'] = persistenceProps.distinct_id\n if (\n // we spotted one customer that was managing to send `false` for ~9k events a day\n !(isString(properties['distinct_id']) || isNumber(properties['distinct_id'])) ||\n isEmptyString(properties['distinct_id'])\n ) {\n logger.error('Invalid distinct_id for replay event. This indicates a bug in your implementation')\n }\n return properties\n }\n\n const infoProperties = getEventProperties(\n this.config.mask_personal_data_properties,\n this.config.custom_personal_data_properties\n )\n\n if (this.sessionManager) {\n const { sessionId, windowId } = this.sessionManager.checkAndGetSessionAndWindowId(\n readOnly,\n timestamp.getTime()\n )\n properties['$session_id'] = sessionId\n properties['$window_id'] = windowId\n }\n if (this.sessionPropsManager) {\n extend(properties, this.sessionPropsManager.getSessionProps())\n }\n\n try {\n if (this.sessionRecording) {\n extend(properties, this.sessionRecording.sdkDebugProperties)\n }\n properties['$sdk_debug_retry_queue_size'] = this._retryQueue?.length\n } catch (e: any) {\n properties['$sdk_debug_error_capturing_properties'] = String(e)\n }\n\n if (this.requestRouter.region === RequestRouterRegion.CUSTOM) {\n properties['$lib_custom_api_host'] = this.config.api_host\n }\n\n let pageviewProperties: Record<string, any>\n if (eventName === '$pageview' && !readOnly) {\n pageviewProperties = this.pageViewManager.doPageView(timestamp, uuid)\n } else if (eventName === '$pageleave' && !readOnly) {\n pageviewProperties = this.pageViewManager.doPageLeave(timestamp)\n } else {\n pageviewProperties = this.pageViewManager.doEvent()\n }\n properties = extend(properties, pageviewProperties)\n\n if (eventName === '$pageview' && document) {\n properties['title'] = document.title\n }\n\n // set $duration if time_event was previously called for this event\n if (!isUndefined(startTimestamp)) {\n const duration_in_ms = timestamp.getTime() - startTimestamp\n properties['$duration'] = parseFloat((duration_in_ms / 1000).toFixed(3))\n }\n\n // this is only added when this.config.opt_out_useragent_filter is true,\n // or it would always add \"browser\"\n if (userAgent && this.config.opt_out_useragent_filter) {\n properties['$browser_type'] = this._is_bot() ? 'bot' : 'browser'\n }\n\n // note: extend writes to the first object, so lets make sure we\n // don't write to the persistence properties object and info\n // properties object by passing in a new object\n\n // update properties with pageview info and super-properties\n properties = extend(\n {},\n infoProperties,\n this.persistence.properties(),\n this.sessionPersistence.properties(),\n properties\n )\n\n properties['$is_identified'] = this._isIdentified()\n\n if (isArray(this.config.property_denylist)) {\n each(this.config.property_denylist, function (denylisted_prop) {\n delete properties[denylisted_prop]\n })\n } else {\n logger.error(\n 'Invalid value for property_denylist config: ' +\n this.config.property_denylist +\n ' or property_blacklist config: ' +\n this.config.property_blacklist\n )\n }\n\n const sanitize_properties = this.config.sanitize_properties\n if (sanitize_properties) {\n logger.error('sanitize_properties is deprecated. Use before_send instead')\n properties = sanitize_properties(properties, eventName)\n }\n\n // add person processing flag as very last step, so it cannot be overridden\n const hasPersonProcessing = this._hasPersonProcessing()\n properties['$process_person_profile'] = hasPersonProcessing\n // if the event has person processing, ensure that all future events will too, even if the setting changes\n if (hasPersonProcessing && !readOnly) {\n this._requirePersonProcessing('_calculate_event_properties')\n }\n\n return properties\n }\n\n /** @deprecated - deprecated in 1.241.0, use `calculateEventProperties` instead */\n _calculate_event_properties = this.calculateEventProperties.bind(this)\n\n /**\n * Add additional set_once properties to the event when creating a person profile. This allows us to create the\n * profile with mostly-accurate properties, despite earlier events not setting them. We do this by storing them in\n * persistence.\n * @param dataSetOnce\n * @param markAsSent - if true, marks the properties as sent so they won't be included in future events.\n * Set to false for events like $groupidentify where the server doesn't process person props.\n */\n _calculate_set_once_properties(dataSetOnce?: Properties, markAsSent: boolean = true): Properties | undefined {\n if (!this.persistence || !this._hasPersonProcessing()) {\n return dataSetOnce\n }\n\n if (this._personProcessingSetOncePropertiesSent) {\n // We only need to send these properties once. Sending them with later events would be redundant and would\n // just require extra work on the server to process them.\n return dataSetOnce\n }\n // if we're an identified person, send initial params with every event\n const initialProps = this.persistence.get_initial_props()\n const sessionProps = this.sessionPropsManager?.getSetOnceProps()\n let setOnceProperties = extend({}, initialProps, sessionProps || {}, dataSetOnce || {})\n const sanitize_properties = this.config.sanitize_properties\n if (sanitize_properties) {\n logger.error('sanitize_properties is deprecated. Use before_send instead')\n setOnceProperties = sanitize_properties(setOnceProperties, '$set_once')\n }\n if (markAsSent) {\n this._personProcessingSetOncePropertiesSent = true\n }\n if (isEmptyObject(setOnceProperties)) {\n return undefined\n }\n return setOnceProperties\n }\n\n /**\n * Registers super properties that are included with all events.\n *\n * @remarks\n * Super properties are stored in persistence and automatically added to every event you capture.\n * These values will overwrite any existing super properties with the same keys.\n *\n * @example\n * ```js\n * // register a single property\n * posthog.register({ plan: 'premium' })\n * ```\n *\n * {@label Capture}\n *\n * @example\n * ```js\n * // register multiple properties\n * posthog.register({\n * email: 'user@example.com',\n * account_type: 'business',\n * signup_date: '2023-01-15'\n * })\n * ```\n *\n * @example\n * ```js\n * // register with custom expiration\n * posthog.register({ campaign: 'summer_sale' }, 7) // expires in 7 days\n * ```\n *\n * @public\n *\n * @param {Object} properties properties to store about the user\n * @param {Number} [days] How many days since the user's last visit to store the super properties\n */\n register(properties: Properties, days?: number): void {\n this.persistence?.register(properties, days)\n }\n\n /**\n * Registers super properties only if they haven't been set before.\n *\n * @remarks\n * Unlike `register()`, this method will not overwrite existing super properties.\n * Use this for properties that should only be set once, like signup date or initial referrer.\n *\n * {@label Capture}\n *\n * @example\n * ```js\n * // register once-only properties\n * posthog.register_once({\n * first_login_date: new Date().toISOString(),\n * initial_referrer: document.referrer\n * })\n * ```\n *\n * @example\n * ```js\n * // override existing value if it matches default\n * posthog.register_once(\n * { user_type: 'premium' },\n * 'unknown' // overwrite if current value is 'unknown'\n * )\n * ```\n *\n * @public\n *\n * @param {Object} properties An associative array of properties to store about the user\n * @param {*} [default_value] Value to override if already set in super properties (ex: 'False') Default: 'None'\n * @param {Number} [days] How many days since the users last visit to store the super properties\n */\n register_once(properties: Properties, default_value?: Property, days?: number): void {\n this.persistence?.register_once(properties, default_value, days)\n }\n\n /**\n * Registers super properties for the current session only.\n *\n * @remarks\n * Session super properties are automatically added to all events during the current browser session.\n * Unlike regular super properties, these are cleared when the session ends and are stored in sessionStorage.\n *\n * {@label Capture}\n *\n * @example\n * ```js\n * // register session-specific properties\n * posthog.register_for_session({\n * current_page_type: 'checkout',\n * ab_test_variant: 'control'\n * })\n * ```\n *\n * @example\n * ```js\n * // register properties for user flow tracking\n * posthog.register_for_session({\n * selected_plan: 'pro',\n * completed_steps: 3,\n * flow_id: 'signup_flow_v2'\n * })\n * ```\n *\n * @public\n *\n * @param {Object} properties An associative array of properties to store about the user\n */\n register_for_session(properties: Properties): void {\n this.sessionPersistence?.register(properties)\n }\n\n /**\n * Removes a super property from persistent storage.\n *\n * @remarks\n * This will stop the property from being automatically included in future events.\n * The property will be permanently removed from the user's profile.\n *\n * {@label Capture}\n *\n * @example\n * ```js\n * // remove a super property\n * posthog.unregister('plan_type')\n * ```\n *\n * @public\n *\n * @param {String} property The name of the super property to remove\n */\n unregister(property: string): void {\n this.persistence?.unregister(property)\n }\n\n /**\n * Removes a session super property from the current session.\n *\n * @remarks\n * This will stop the property from being automatically included in future events for this session.\n * The property is removed from sessionStorage.\n *\n * {@label Capture}\n *\n * @example\n * ```js\n * // remove a session property\n * posthog.unregister_for_session('current_flow')\n * ```\n *\n * @public\n *\n * @param {String} property The name of the session super property to remove\n */\n unregister_for_session(property: string): void {\n this.sessionPersistence?.unregister(property)\n }\n\n _register_single(prop: string, value: Property) {\n this.register({ [prop]: value })\n }\n\n /**\n * Gets the value of a feature flag for the current user.\n *\n * @remarks\n * Returns the feature flag value which can be a boolean, string, or undefined.\n * Supports multivariate flags that can return custom string values.\n *\n * {@label Feature flags}\n *\n * @example\n * ```js\n * // check boolean flag\n * if (posthog.getFeatureFlag('new-feature')) {\n * // show new feature\n * }\n * ```\n *\n * @example\n * ```js\n * // check multivariate flag\n * const variant = posthog.getFeatureFlag('button-color')\n * if (variant === 'red') {\n * // show red button\n * }\n * ```\n *\n * @public\n *\n * @param {Object|String} prop Key of the feature flag.\n * @param {Object|String} options (optional) If {send_event: false}, we won't send an $feature_flag_call event to PostHog.\n */\n getFeatureFlag(key: string, options?: { send_event?: boolean }): boolean | string | undefined {\n return this.featureFlags.getFeatureFlag(key, options)\n }\n\n /**\n * Get feature flag payload value matching key for user (supports multivariate flags).\n *\n * {@label Feature flags}\n *\n * @example\n * ```js\n * if(posthog.getFeatureFlag('beta-feature') === 'some-value') {\n * const someValue = posthog.getFeatureFlagPayload('beta-feature')\n * // do something\n * }\n * ```\n *\n * @public\n *\n * @param {Object|String} prop Key of the feature flag.\n */\n getFeatureFlagPayload(key: string): JsonType {\n const payload = this.featureFlags.getFeatureFlagPayload(key)\n try {\n return JSON.parse(payload as any)\n } catch {\n return payload\n }\n }\n\n /**\n * Checks if a feature flag is enabled for the current user.\n *\n * @remarks\n * Returns true if the flag is enabled, false if disabled, or undefined if not found.\n * This is a convenience method that treats any truthy value as enabled.\n *\n * {@label Feature flags}\n *\n * @example\n * ```js\n * // simple feature flag check\n * if (posthog.isFeatureEnabled('new-checkout')) {\n * showNewCheckout()\n * }\n * ```\n *\n * @example\n * ```js\n * // disable event tracking\n * if (posthog.isFeatureEnabled('feature', { send_event: false })) {\n * // flag checked without sending $feature_flag_call event\n * }\n * ```\n *\n * @public\n *\n * @param {Object|String} prop Key of the feature flag.\n * @param {Object|String} options (optional) If {send_event: false}, we won't send an $feature_flag_call event to PostHog.\n */\n isFeatureEnabled(key: string, options?: { send_event: boolean }): boolean | undefined {\n return this.featureFlags.isFeatureEnabled(key, options)\n }\n\n /**\n * Feature flag values are cached. If something has changed with your user and you'd like to refetch their flag values, call this method.\n *\n * {@label Feature flags}\n *\n * @example\n * ```js\n * posthog.reloadFeatureFlags()\n * ```\n *\n * @public\n */\n reloadFeatureFlags(): void {\n this.featureFlags.reloadFeatureFlags()\n }\n\n /**\n * Manually update feature flag values without making a network request.\n *\n * This is useful when you have feature flag values from an external source\n * (e.g., server-side evaluation, edge middleware) and want to inject them\n * into the client SDK.\n *\n * {@label Feature flags}\n *\n * @example\n * ```js\n * // Replace all flags with server-evaluated values\n * posthog.updateFlags({\n * 'my-flag': true,\n * 'my-experiment': 'variant-a'\n * })\n *\n * // Merge with existing flags (update only specified flags)\n * posthog.updateFlags(\n * { 'my-flag': true },\n * undefined,\n * { merge: true }\n * )\n *\n * // With payloads\n * posthog.updateFlags(\n * { 'my-flag': true },\n * { 'my-flag': { some: 'data' } }\n * )\n * ```\n *\n * @param flags - An object mapping flag keys to their values (boolean or string variant)\n * @param payloads - Optional object mapping flag keys to their JSON payloads\n * @param options - Optional settings. Use `{ merge: true }` to merge with existing flags instead of replacing.\n * @public\n */\n updateFlags(\n flags: Record<string, boolean | string>,\n payloads?: Record<string, JsonType>,\n options?: { merge?: boolean }\n ): void {\n // If merging, combine with existing flags\n const existingFlags = options?.merge ? this.featureFlags.getFlagVariants() : {}\n const existingPayloads = options?.merge ? this.featureFlags.getFlagPayloads() : {}\n const finalFlags = { ...existingFlags, ...flags }\n const finalPayloads = { ...existingPayloads, ...payloads }\n\n // Convert simple flags to v4 format to avoid deprecation warning\n const flagDetails: Record<string, FeatureFlagDetail> = {}\n for (const [key, value] of Object.entries(finalFlags)) {\n const isVariant = typeof value === 'string'\n flagDetails[key] = {\n key,\n enabled: isVariant ? true : Boolean(value),\n variant: isVariant ? value : undefined,\n reason: undefined,\n // id: 0 indicates manually injected flags (not from server evaluation)\n metadata: !isUndefined(finalPayloads?.[key])\n ? { id: 0, version: undefined, description: undefined, payload: finalPayloads[key] }\n : undefined,\n }\n }\n\n this.featureFlags.receivedFeatureFlags({\n flags: flagDetails,\n })\n }\n\n /**\n * Opt the user in or out of an early access feature. [Learn more in the docs](/docs/feature-flags/early-access-feature-management#option-2-custom-implementation)\n *\n * {@label Feature flags}\n *\n * @example\n * ```js\n * const toggleBeta = (betaKey) => {\n * if (activeBetas.some(\n * beta => beta.flagKey === betaKey\n * )) {\n * posthog.updateEarlyAccessFeatureEnrollment(\n * betaKey,\n * false\n * )\n * setActiveBetas(\n * prevActiveBetas => prevActiveBetas.filter(\n * item => item.flagKey !== betaKey\n * )\n * );\n * return\n * }\n *\n * posthog.updateEarlyAccessFeatureEnrollment(\n * betaKey,\n * true\n * )\n * setInactiveBetas(\n * prevInactiveBetas => prevInactiveBetas.filter(\n * item => item.flagKey !== betaKey\n * )\n * );\n * }\n *\n * const registerInterest = (featureKey) => {\n * posthog.updateEarlyAccessFeatureEnrollment(\n * featureKey,\n * true\n * )\n * // Update UI to show user has registered\n * }\n * ```\n *\n * @public\n *\n * @param {String} key The key of the feature flag to update.\n * @param {Boolean} isEnrolled Whether the user is enrolled in the feature.\n * @param {String} [stage] The stage of the feature flag to update.\n */\n updateEarlyAccessFeatureEnrollment(key: string, isEnrolled: boolean, stage?: string): void {\n this.featureFlags.updateEarlyAccessFeatureEnrollment(key, isEnrolled, stage)\n }\n\n /**\n * Get the list of early access features. To check enrollment status, use `isFeatureEnabled`. [Learn more in the docs](/docs/feature-flags/early-access-feature-management#option-2-custom-implementation)\n *\n * {@label Feature flags}\n *\n * @example\n * ```js\n * const posthog = usePostHog()\n * const activeFlags = useActiveFeatureFlags()\n *\n * const [activeBetas, setActiveBetas] = useState([])\n * const [inactiveBetas, setInactiveBetas] = useState([])\n * const [comingSoonFeatures, setComingSoonFeatures] = useState([])\n *\n * useEffect(() => {\n * posthog.getEarlyAccessFeatures((features) => {\n * // Filter features by stage\n * const betaFeatures = features.filter(feature => feature.stage === 'beta')\n * const conceptFeatures = features.filter(feature => feature.stage === 'concept')\n *\n * setComingSoonFeatures(conceptFeatures)\n *\n * if (!activeFlags || activeFlags.length === 0) {\n * setInactiveBetas(betaFeatures)\n * return\n * }\n *\n * const activeBetas = betaFeatures.filter(\n * beta => activeFlags.includes(beta.flagKey)\n * );\n * const inactiveBetas = betaFeatures.filter(\n * beta => !activeFlags.includes(beta.flagKey)\n * );\n * setActiveBetas(activeBetas)\n * setInactiveBetas(inactiveBetas)\n * }, true, ['concept', 'beta'])\n * }, [activeFlags])\n * ```\n *\n * @public\n *\n * @param {Function} callback The callback function will be called when the early access features are loaded.\n * @param {Boolean} [force_reload] Whether to force a reload of the early access features.\n * @param {String[]} [stages] The stages of the early access features to load.\n */\n getEarlyAccessFeatures(\n callback: EarlyAccessFeatureCallback,\n force_reload = false,\n stages?: EarlyAccessFeatureStage[]\n ): void {\n return this.featureFlags.getEarlyAccessFeatures(callback, force_reload, stages)\n }\n\n /**\n * Exposes a set of events that PostHog will emit.\n * e.g. `eventCaptured` is emitted immediately before trying to send an event\n *\n * Unlike `onFeatureFlags` and `onSessionId` these are not called when the\n * listener is registered, the first callback will be the next event\n * _after_ registering a listener\n *\n * {@label Capture}\n *\n * @example\n * ```js\n * posthog.on('eventCaptured', (event) => {\n * console.log(event)\n * })\n * ```\n *\n * @public\n *\n * @param {String} event The event to listen for.\n * @param {Function} cb The callback function to call when the event is emitted.\n * @returns {Function} A function that can be called to unsubscribe the listener.\n */\n on(event: 'eventCaptured', cb: (...args: any[]) => void): () => void {\n return this._internalEventEmitter.on(event, cb)\n }\n\n /**\n * Register an event listener that runs when feature flags become available or when they change.\n * If there are flags, the listener is called immediately in addition to being called on future changes.\n * Note that this is not called only when we fetch feature flags from the server, but also when they change in the browser.\n *\n * {@label Feature flags}\n *\n * @example\n * ```js\n * posthog.onFeatureFlags(function(featureFlags, featureFlagsVariants, { errorsLoading }) {\n * // do something\n * })\n * ```\n *\n * @param callback - The callback function will be called once the feature flags are ready or when they are updated.\n * It'll return a list of feature flags enabled for the user, the variants,\n * and also a context object indicating whether we succeeded to fetch the flags or not.\n * @returns A function that can be called to unsubscribe the listener. Used by `useEffect` when the component unmounts.\n */\n onFeatureFlags(callback: FeatureFlagsCallback): () => void {\n return this.featureFlags.onFeatureFlags(callback)\n }\n\n /**\n * Register an event listener that runs when surveys are loaded.\n *\n * Callback parameters:\n * - surveys: Survey[]: An array containing all survey objects fetched from PostHog using the getSurveys method\n * - context: { isLoaded: boolean, error?: string }: An object indicating if the surveys were loaded successfully\n *\n * {@label Surveys}\n *\n * @example\n * ```js\n * posthog.onSurveysLoaded((surveys, context) => { // do something })\n * ```\n *\n *\n * @param {Function} callback The callback function will be called when surveys are loaded or updated.\n * @returns {Function} A function that can be called to unsubscribe the listener.\n */\n onSurveysLoaded(callback: SurveyCallback): () => void {\n return this.surveys.onSurveysLoaded(callback)\n }\n\n /**\n * Register an event listener that runs whenever the session id or window id change.\n * If there is already a session id, the listener is called immediately in addition to being called on future changes.\n *\n * Can be used, for example, to sync the PostHog session id with a backend session.\n *\n * {@label Identification}\n *\n * @example\n * ```js\n * posthog.onSessionId(function(sessionId, windowId) { // do something })\n * ```\n *\n * @param {Function} [callback] The callback function will be called once a session id is present or when it or the window id are updated.\n * @returns {Function} A function that can be called to unsubscribe the listener. E.g. Used by `useEffect` when the component unmounts.\n */\n onSessionId(callback: SessionIdChangedCallback): () => void {\n return this.sessionManager?.onSessionId(callback) ?? (() => {})\n }\n\n /**\n * Get list of all surveys.\n *\n * {@label Surveys}\n *\n * @example\n * ```js\n * function callback(surveys, context) {\n * // do something\n * }\n *\n * posthog.getSurveys(callback, false)\n * ```\n *\n * @public\n *\n * @param {Function} [callback] Function that receives the array of surveys\n * @param {Boolean} [forceReload] Optional boolean to force an API call for updated surveys\n */\n getSurveys(callback: SurveyCallback, forceReload = false): void {\n this.surveys.getSurveys(callback, forceReload)\n }\n\n /**\n * Get surveys that should be enabled for the current user. See [fetching surveys documentation](/docs/surveys/implementing-custom-surveys#fetching-surveys-manually) for more details.\n *\n * {@label Surveys}\n *\n * @example\n * ```js\n * posthog.getActiveMatchingSurveys((surveys) => {\n * // do something\n * })\n * ```\n *\n * @public\n *\n * @param {Function} [callback] The callback function will be called when the surveys are loaded or updated.\n * @param {Boolean} [forceReload] Whether to force a reload of the surveys.\n */\n getActiveMatchingSurveys(callback: SurveyCallback, forceReload = false): void {\n this.surveys.getActiveMatchingSurveys(callback, forceReload)\n }\n\n /**\n * Although we recommend using popover surveys and display conditions,\n * if you want to show surveys programmatically without setting up all\n * the extra logic needed for API surveys, you can render surveys\n * programmatically with the renderSurvey method.\n *\n * This takes a survey ID and an HTML selector to render an unstyled survey.\n *\n * {@label Surveys}\n *\n * @example\n * ```js\n * posthog.renderSurvey(coolSurveyID, '#survey-container')\n * ```\n *\n * @deprecated Use displaySurvey instead - it's more complete and also supports popover surveys.\n *\n * @public\n *\n * @param {String} surveyId The ID of the survey to render.\n * @param {String} selector The selector of the HTML element to render the survey on.\n */\n renderSurvey(surveyId: string, selector: string): void {\n this.surveys.renderSurvey(surveyId, selector)\n }\n\n /**\n * Display a survey programmatically as either a popover or inline element.\n *\n * @param {string} surveyId - The survey ID to display\n * @param {DisplaySurveyOptions} options - Display configuration\n *\n * @example\n * ```js\n * // Display as popover (respects all conditions defined in the dashboard)\n * posthog.displaySurvey('survey-id-123')\n * ```\n *\n * @example\n * ```js\n * // Display inline in a specific element\n * posthog.displaySurvey('survey-id-123', {\n * displayType: DisplaySurveyType.Inline,\n * selector: '#survey-container'\n * })\n * ```\n *\n * @example\n * ```js\n * // Force display ignoring conditions and delays\n * posthog.displaySurvey('survey-id-123', {\n * displayType: DisplaySurveyType.Popover,\n * ignoreConditions: true,\n * ignoreDelay: true\n * })\n * ```\n *\n * {@label Surveys}\n */\n displaySurvey(surveyId: string, options: DisplaySurveyOptions = DEFAULT_DISPLAY_SURVEY_OPTIONS): void {\n this.surveys.displaySurvey(surveyId, options)\n }\n\n /**\n * Cancels a pending survey that is waiting to be displayed (e.g., due to a popup delay).\n *\n * {@label Surveys}\n */\n cancelPendingSurvey(surveyId: string): void {\n this.surveys.cancelPendingSurvey(surveyId)\n }\n\n /**\n * Checks the feature flags associated with this Survey to see if the survey can be rendered.\n * This method is deprecated because it's synchronous and won't return the correct result if surveys are not loaded.\n * Use `canRenderSurveyAsync` instead.\n *\n * {@label Surveys}\n *\n *\n * @deprecated\n *\n * @param surveyId The ID of the survey to check.\n * @returns A SurveyRenderReason object indicating if the survey can be rendered.\n */\n canRenderSurvey(surveyId: string): SurveyRenderReason | null {\n return this.surveys.canRenderSurvey(surveyId)\n }\n\n /**\n * Checks the feature flags associated with this Survey to see if the survey can be rendered.\n *\n * {@label Surveys}\n *\n * @example\n * ```js\n * posthog.canRenderSurveyAsync(surveyId).then((result) => {\n * if (result.visible) {\n * // Survey can be rendered\n * console.log('Survey can be rendered')\n * } else {\n * // Survey cannot be rendered\n * console.log('Survey cannot be rendered:', result.disabledReason)\n * }\n * })\n * ```\n *\n * @public\n *\n * @param surveyId The ID of the survey to check.\n * @param forceReload If true, the survey will be reloaded from the server, Default: false\n * @returns A SurveyRenderReason object indicating if the survey can be rendered.\n */\n canRenderSurveyAsync(surveyId: string, forceReload = false): Promise<SurveyRenderReason> {\n return this.surveys.canRenderSurveyAsync(surveyId, forceReload)\n }\n\n /**\n * Associates a user with a unique identifier instead of an auto-generated ID.\n * Learn more about [identifying users](/docs/product-analytics/identify)\n *\n * {@label Identification}\n *\n * @remarks\n * By default, PostHog assigns each user a randomly generated `distinct_id`. Use this method to\n * replace that ID with your own unique identifier (like a user ID from your database).\n *\n * @example\n * ```js\n * // basic identification\n * posthog.identify('user_12345')\n * ```\n *\n * @example\n * ```js\n * // identify with user properties\n * posthog.identify('user_12345', {\n * email: 'user@example.com',\n * plan: 'premium'\n * })\n * ```\n *\n * @example\n * ```js\n * // identify with set and set_once properties\n * posthog.identify('user_12345',\n * { last_login: new Date() }, // updates every time\n * { signup_date: new Date() } // sets only once\n * )\n * ```\n *\n * @public\n *\n * @param {String} [new_distinct_id] A string that uniquely identifies a user. If not provided, the distinct_id currently in the persistent store (cookie or localStorage) will be used.\n * @param {Object} [userPropertiesToSet] Optional: An associative array of properties to store about the user. Note: For feature flag evaluations, if the same key is present in the userPropertiesToSetOnce,\n * it will be overwritten by the value in userPropertiesToSet.\n * @param {Object} [userPropertiesToSetOnce] Optional: An associative array of properties to store about the user. If property is previously set, this does not override that value.\n */\n identify(new_distinct_id?: string, userPropertiesToSet?: Properties, userPropertiesToSetOnce?: Properties): void {\n if (!this.__loaded || !this.persistence) {\n return logger.uninitializedWarning('posthog.identify')\n }\n if (isNumber(new_distinct_id)) {\n new_distinct_id = (new_distinct_id as number).toString()\n logger.warn(\n 'The first argument to posthog.identify was a number, but it should be a string. It has been converted to a string.'\n )\n }\n\n //if the new_distinct_id has not been set ignore the identify event\n if (!new_distinct_id) {\n logger.error('Unique user id has not been set in posthog.identify')\n return\n }\n\n if (isDistinctIdStringLike(new_distinct_id)) {\n logger.critical(\n `The string \"${new_distinct_id}\" was set in posthog.identify which indicates an error. This ID should be unique to the user and not a hardcoded string.`\n )\n return\n }\n if (new_distinct_id === COOKIELESS_SENTINEL_VALUE) {\n logger.critical(\n `The string \"${COOKIELESS_SENTINEL_VALUE}\" was set in posthog.identify which indicates an error. This ID is only used as a sentinel value.`\n )\n return\n }\n\n if (!this._requirePersonProcessing('posthog.identify')) {\n return\n }\n\n const previous_distinct_id = this.get_distinct_id()\n this.register({ $user_id: new_distinct_id })\n\n if (!this.get_property('$device_id')) {\n // The persisted distinct id might not actually be a device id at all\n // it might be a distinct id of the user from before\n const device_id = previous_distinct_id\n this.register_once(\n {\n $had_persisted_distinct_id: true,\n $device_id: device_id,\n },\n ''\n )\n }\n\n // if the previous distinct id had an alias stored, then we clear it\n if (new_distinct_id !== previous_distinct_id && new_distinct_id !== this.get_property(ALIAS_ID_KEY)) {\n this.unregister(ALIAS_ID_KEY)\n this.register({ distinct_id: new_distinct_id })\n }\n\n const isKnownAnonymous = (this.persistence.get_property(USER_STATE) || 'anonymous') === 'anonymous'\n\n // send an $identify event any time the distinct_id is changing and the old ID is an anonymous ID\n // - logic on the server will determine whether or not to do anything with it.\n if (new_distinct_id !== previous_distinct_id && isKnownAnonymous) {\n this.persistence.set_property(USER_STATE, 'identified')\n\n // Update current user properties\n this.setPersonPropertiesForFlags(\n { ...(userPropertiesToSetOnce || {}), ...(userPropertiesToSet || {}) },\n false\n )\n\n this.capture(\n '$identify',\n {\n distinct_id: new_distinct_id,\n $anon_distinct_id: previous_distinct_id,\n },\n { $set: userPropertiesToSet || {}, $set_once: userPropertiesToSetOnce || {} }\n )\n\n this._cachedPersonProperties = getPersonPropertiesHash(\n new_distinct_id,\n userPropertiesToSet,\n userPropertiesToSetOnce\n )\n\n // let the reload feature flag request know to send this previous distinct id\n // for flag consistency\n this.featureFlags.setAnonymousDistinctId(previous_distinct_id)\n } else if (userPropertiesToSet || userPropertiesToSetOnce) {\n // If the distinct_id is not changing, but we have user properties to set, we can check if they have changed\n // and if so, send a $set event\n\n this.setPersonProperties(userPropertiesToSet, userPropertiesToSetOnce)\n }\n\n // Reload active feature flags if the user identity changes.\n // Note we don't reload this on property changes as these get processed async\n if (new_distinct_id !== previous_distinct_id) {\n this.reloadFeatureFlags()\n // also clear any stored flag calls\n this.unregister(FLAG_CALL_REPORTED)\n }\n }\n\n /**\n * Sets properties on the person profile associated with the current `distinct_id`.\n * Learn more about [identifying users](/docs/product-analytics/identify)\n *\n * {@label Identification}\n *\n * @remarks\n * Updates user properties that are stored with the person profile in PostHog.\n * If `person_profiles` is set to `identified_only` and no profile exists, this will create one.\n *\n * @example\n * ```js\n * // set user properties\n * posthog.setPersonProperties({\n * email: 'user@example.com',\n * plan: 'premium'\n * })\n * ```\n *\n * @example\n * ```js\n * // set properties\n * posthog.setPersonProperties(\n * { name: 'Max Hedgehog' }, // $set properties\n * { initial_url: '/blog' } // $set_once properties\n * )\n * ```\n *\n * @public\n *\n * @param {Object} [userPropertiesToSet] Optional: An associative array of properties to store about the user. Note: For feature flag evaluations, if the same key is present in the userPropertiesToSetOnce,\n * it will be overwritten by the value in userPropertiesToSet.\n * @param {Object} [userPropertiesToSetOnce] Optional: An associative array of properties to store about the user. If property is previously set, this does not override that value.\n */\n setPersonProperties(userPropertiesToSet?: Properties, userPropertiesToSetOnce?: Properties): void {\n if (!userPropertiesToSet && !userPropertiesToSetOnce) {\n return\n }\n\n if (!this._requirePersonProcessing('posthog.setPersonProperties')) {\n return\n }\n\n const hash = getPersonPropertiesHash(this.get_distinct_id(), userPropertiesToSet, userPropertiesToSetOnce)\n\n // if exactly this $set call has been sent before, don't send it again - determine based on hash of properties\n if (this._cachedPersonProperties === hash) {\n logger.info('A duplicate setPersonProperties call was made with the same properties. It has been ignored.')\n return\n }\n\n // Update current user properties\n this.setPersonPropertiesForFlags({ ...(userPropertiesToSetOnce || {}), ...(userPropertiesToSet || {}) })\n\n this.capture('$set', { $set: userPropertiesToSet || {}, $set_once: userPropertiesToSetOnce || {} })\n\n this._cachedPersonProperties = hash\n }\n\n /**\n * Associates the user with a group for group-based analytics.\n * Learn more about [groups](/docs/product-analytics/group-analytics)\n *\n * {@label Identification}\n *\n * @remarks\n * Groups allow you to analyze users collectively (e.g., by organization, team, or account).\n * This sets the group association for all subsequent events and reloads feature flags.\n *\n * @example\n * ```js\n * // associate user with an organization\n * posthog.group('organization', 'org_12345', {\n * name: 'Acme Corp',\n * plan: 'enterprise'\n * })\n * ```\n *\n * @example\n * ```js\n * // associate with multiple group types\n * posthog.group('organization', 'org_12345')\n * posthog.group('team', 'team_67890')\n * ```\n *\n * @public\n *\n * @param {String} groupType Group type (example: 'organization')\n * @param {String} groupKey Group key (example: 'org::5')\n * @param {Object} groupPropertiesToSet Optional properties to set for group\n */\n group(groupType: string, groupKey: string, groupPropertiesToSet?: Properties): void {\n if (!groupType || !groupKey) {\n logger.error('posthog.group requires a group type and group key')\n return\n }\n\n const existingGroups = this.getGroups()\n\n // if group key changes, remove stored group properties\n if (existingGroups[groupType] !== groupKey) {\n this.resetGroupPropertiesForFlags(groupType)\n }\n\n this.register({ $groups: { ...existingGroups, [groupType]: groupKey } })\n\n if (groupPropertiesToSet) {\n this.capture('$groupidentify', {\n $group_type: groupType,\n $group_key: groupKey,\n $group_set: groupPropertiesToSet,\n })\n this.setGroupPropertiesForFlags({ [groupType]: groupPropertiesToSet })\n }\n\n // If groups change and no properties change, reload feature flags.\n // The property change reload case is handled in setGroupPropertiesForFlags.\n if (existingGroups[groupType] !== groupKey && !groupPropertiesToSet) {\n this.reloadFeatureFlags()\n }\n }\n\n /**\n * Resets only the group properties of the user currently logged in.\n * Learn more about [groups](/docs/product-analytics/group-analytics)\n *\n * {@label Identification}\n *\n * @example\n * ```js\n * posthog.resetGroups()\n * ```\n *\n * @public\n */\n resetGroups(): void {\n this.register({ $groups: {} })\n this.resetGroupPropertiesForFlags()\n\n // If groups changed, reload feature flags.\n this.reloadFeatureFlags()\n }\n\n /**\n * Sometimes, you might want to evaluate feature flags using properties that haven't been ingested yet,\n * or were set incorrectly earlier. You can do so by setting properties the flag depends on with these calls:\n *\n * {@label Feature flags}\n *\n * @example\n * ```js\n * // Set properties\n * posthog.setPersonPropertiesForFlags({'property1': 'value', property2: 'value2'})\n * ```\n *\n * @example\n * ```js\n * // Set properties without reloading\n * posthog.setPersonPropertiesForFlags({'property1': 'value', property2: 'value2'}, false)\n * ```\n *\n * @public\n *\n * @param {Object} properties The properties to override.\n * @param {Boolean} [reloadFeatureFlags] Whether to reload feature flags.\n */\n setPersonPropertiesForFlags(properties: Properties, reloadFeatureFlags = true): void {\n this.featureFlags.setPersonPropertiesForFlags(properties, reloadFeatureFlags)\n }\n\n /**\n * Resets the person properties for feature flags.\n *\n * {@label Feature flags}\n *\n * @public\n *\n * @example\n * ```js\n * posthog.resetPersonPropertiesForFlags()\n * ```\n */\n resetPersonPropertiesForFlags(): void {\n this.featureFlags.resetPersonPropertiesForFlags()\n }\n\n /**\n * Set override group properties for feature flags.\n * This is used when dealing with new groups / where you don't want to wait for ingestion\n * to update properties.\n * Takes in an object, the key of which is the group type.\n *\n * {@label Feature flags}\n *\n * @public\n *\n * @example\n * ```js\n * // Set properties with reload\n * posthog.setGroupPropertiesForFlags({'organization': { name: 'CYZ', employees: '11' } })\n * ```\n *\n * @example\n * ```js\n * // Set properties without reload\n * posthog.setGroupPropertiesForFlags({'organization': { name: 'CYZ', employees: '11' } }, false)\n * ```\n *\n * @param {Object} properties The properties to override, the key of which is the group type.\n * @param {Boolean} [reloadFeatureFlags] Whether to reload feature flags.\n */\n setGroupPropertiesForFlags(properties: { [type: string]: Properties }, reloadFeatureFlags = true): void {\n if (!this._requirePersonProcessing('posthog.setGroupPropertiesForFlags')) {\n return\n }\n this.featureFlags.setGroupPropertiesForFlags(properties, reloadFeatureFlags)\n }\n\n /**\n * Resets the group properties for feature flags.\n *\n * {@label Feature flags}\n *\n * @public\n *\n * @example\n * ```js\n * posthog.resetGroupPropertiesForFlags()\n * ```\n */\n resetGroupPropertiesForFlags(group_type?: string): void {\n this.featureFlags.resetGroupPropertiesForFlags(group_type)\n }\n\n /**\n * Resets all user data and starts a fresh session.\n *\n * ⚠️ **Warning**: Only call this when a user logs out. Calling at the wrong time can cause split sessions.\n *\n * This clears:\n * - Session ID and super properties\n * - User identification (sets new random distinct_id)\n * - Cached data and consent settings\n *\n * {@label Identification}\n * @example\n * ```js\n * // reset on user logout\n * function logout() {\n * posthog.reset()\n * // redirect to login page\n * }\n * ```\n *\n * @example\n * ```js\n * // reset and generate new device ID\n * posthog.reset(true) // also resets device_id\n * ```\n *\n * @public\n */\n reset(reset_device_id?: boolean): void {\n logger.info('reset')\n if (!this.__loaded) {\n return logger.uninitializedWarning('posthog.reset')\n }\n const device_id = this.get_property('$device_id')\n this.consent.reset()\n this.persistence?.clear()\n this.sessionPersistence?.clear()\n this.surveys.reset()\n this.featureFlags.reset()\n this.persistence?.set_property(USER_STATE, 'anonymous')\n this.sessionManager?.resetSessionId()\n this._cachedPersonProperties = null\n if (this.config.cookieless_mode === 'always') {\n this.register_once(\n {\n distinct_id: COOKIELESS_SENTINEL_VALUE,\n $device_id: null,\n },\n ''\n )\n } else {\n const uuid = this.config.get_device_id(uuidv7())\n this.register_once(\n {\n distinct_id: uuid,\n $device_id: reset_device_id ? uuid : device_id,\n },\n ''\n )\n }\n\n this.register(\n {\n $last_posthog_reset: new Date().toISOString(),\n },\n 1\n )\n }\n\n /**\n * Returns the current distinct ID for the user.\n *\n * @remarks\n * This is either the auto-generated ID or the ID set via `identify()`.\n * The distinct ID is used to associate events with users in PostHog.\n *\n * {@label Identification}\n *\n * @example\n * ```js\n * // get the current user ID\n * const userId = posthog.get_distinct_id()\n * console.log('Current user:', userId)\n * ```\n *\n * @example\n * ```js\n * // use in loaded callback\n * posthog.init('token', {\n * loaded: (posthog) => {\n * const id = posthog.get_distinct_id()\n * // use the ID\n * }\n * })\n * ```\n *\n * @public\n *\n * @returns The current distinct ID\n */\n get_distinct_id(): string {\n return this.get_property('distinct_id')\n }\n\n /**\n * Returns the current groups.\n *\n * {@label Identification}\n *\n * @public\n *\n * @returns The current groups\n */\n getGroups(): Record<string, any> {\n return this.get_property('$groups') || {}\n }\n\n /**\n * Returns the current session_id.\n *\n * @remarks\n * This should only be used for informative purposes.\n * Any actual internal use case for the session_id should be handled by the sessionManager.\n *\n * @public\n *\n * @returns The stored session ID for the current session. This may be an empty string if the client is not yet fully initialized.\n */\n get_session_id(): string {\n return this.sessionManager?.checkAndGetSessionAndWindowId(true).sessionId ?? ''\n }\n\n /**\n * Returns the Replay url for the current session.\n *\n * {@label Session replay}\n *\n * @public\n *\n * @example\n * ```js\n * // basic usage\n * posthog.get_session_replay_url()\n *\n * @example\n * ```js\n * // timestamp\n * posthog.get_session_replay_url({ withTimestamp: true })\n * ```\n *\n * @example\n * ```js\n * // timestamp and lookback\n * posthog.get_session_replay_url({\n * withTimestamp: true,\n * timestampLookBack: 30 // look back 30 seconds\n * })\n * ```\n *\n * @param options Options for the url\n * @param options.withTimestamp Whether to include the timestamp in the url (defaults to false)\n * @param options.timestampLookBack How many seconds to look back for the timestamp (defaults to 10)\n */\n get_session_replay_url(options?: { withTimestamp?: boolean; timestampLookBack?: number }): string {\n if (!this.sessionManager) {\n return ''\n }\n const { sessionId, sessionStartTimestamp } = this.sessionManager.checkAndGetSessionAndWindowId(true)\n let url = this.requestRouter.endpointFor('ui', `/project/${this.config.token}/replay/${sessionId}`)\n if (options?.withTimestamp && sessionStartTimestamp) {\n const LOOK_BACK = options.timestampLookBack ?? 10\n if (!sessionStartTimestamp) {\n return url\n }\n const recordingStartTime = Math.max(\n Math.floor((new Date().getTime() - sessionStartTimestamp) / 1000) - LOOK_BACK,\n 0\n )\n url += `?t=${recordingStartTime}`\n }\n\n return url\n }\n\n /**\n * Creates an alias linking two distinct user identifiers. Learn more about [identifying users](/docs/product-analytics/identify)\n *\n * {@label Identification}\n *\n * @remarks\n * PostHog will use this to link two distinct_ids going forward (not retroactively).\n * Call this when a user signs up to connect their anonymous session with their account.\n *\n *\n * @example\n * ```js\n * // link anonymous user to account on signup\n * posthog.alias('user_12345')\n * ```\n *\n * @example\n * ```js\n * // explicit alias with original ID\n * posthog.alias('user_12345', 'anonymous_abc123')\n * ```\n *\n * @public\n *\n * @param {String} alias A unique identifier that you want to use for this user in the future.\n * @param {String} [original] The current identifier being used for this user.\n */\n alias(alias: string, original?: string): CaptureResult | void | number {\n // If the $people_distinct_id key exists in persistence, there has been a previous\n // posthog.people.identify() call made for this user. It is VERY BAD to make an alias with\n // this ID, as it will duplicate users.\n if (alias === this.get_property(PEOPLE_DISTINCT_ID_KEY)) {\n logger.critical('Attempting to create alias for existing People user - aborting.')\n return -2\n }\n if (!this._requirePersonProcessing('posthog.alias')) {\n return\n }\n\n if (isUndefined(original)) {\n original = this.get_distinct_id()\n }\n if (alias !== original) {\n this._register_single(ALIAS_ID_KEY, alias)\n return this.capture('$create_alias', { alias: alias, distinct_id: original })\n } else {\n logger.warn('alias matches current distinct_id - skipping api call.')\n this.identify(alias)\n return -1\n }\n }\n\n /**\n * Updates the configuration of the PostHog instance.\n *\n * {@label Initialization}\n *\n * @public\n *\n * @param {Partial<PostHogConfig>} config A dictionary of new configuration values to update\n */\n set_config(config: Partial<PostHogConfig>): void {\n const oldConfig = { ...this.config }\n if (isObject(config)) {\n extend(this.config, configRenames(config))\n\n const isPersistenceDisabled = this._is_persistence_disabled()\n this.persistence?.update_config(this.config, oldConfig, isPersistenceDisabled)\n this.sessionPersistence =\n this.config.persistence === 'sessionStorage' || this.config.persistence === 'memory'\n ? this.persistence\n : new PostHogPersistence({ ...this.config, persistence: 'sessionStorage' }, isPersistenceDisabled)\n\n const debugConfigFromLocalStorage = this._checkLocalStorageForDebug(this.config.debug)\n if (isBoolean(debugConfigFromLocalStorage)) {\n this.config.debug = debugConfigFromLocalStorage\n }\n\n if (isBoolean(this.config.debug)) {\n if (this.config.debug) {\n Config.DEBUG = true\n localStore._is_supported() && localStore._set('ph_debug', 'true')\n logger.info('set_config', {\n config,\n oldConfig,\n newConfig: { ...this.config },\n })\n } else {\n Config.DEBUG = false\n localStore._is_supported() && localStore._remove('ph_debug')\n }\n }\n\n this.exceptionObserver?.onConfigChange()\n\n this.sessionRecording?.startIfEnabledOrStop()\n this.autocapture?.startIfEnabled()\n this.heatmaps?.startIfEnabled()\n this.exceptionObserver?.startIfEnabledOrStop()\n this.surveys.loadIfEnabled()\n this._sync_opt_out_with_persistence()\n this.externalIntegrations?.startIfEnabledOrStop()\n }\n }\n\n /**\n * turns session recording on, and updates the config option `disable_session_recording` to false\n *\n * {@label Session replay}\n *\n * @public\n *\n * @example\n * ```js\n * // Start and ignore controls\n * posthog.startSessionRecording(true)\n * ```\n *\n * @example\n * ```js\n * // Start and override controls\n * posthog.startSessionRecording({\n * // you don't have to send all of these\n * sampling: true || false,\n * linked_flag: true || false,\n * url_trigger: true || false,\n * event_trigger: true || false\n * })\n * ```\n *\n * @param override.sampling - optional boolean to override the default sampling behavior - ensures the next session recording to start will not be skipped by sampling config.\n * @param override.linked_flag - optional boolean to override the default linked_flag behavior - ensures the next session recording to start will not be skipped by linked_flag config.\n * @param override.url_trigger - optional boolean to override the default url_trigger behavior - ensures the next session recording to start will not be skipped by url_trigger config.\n * @param override.event_trigger - optional boolean to override the default event_trigger behavior - ensures the next session recording to start will not be skipped by event_trigger config.\n * @param override - optional boolean to override the default sampling behavior - ensures the next session recording to start will not be skipped by sampling or linked_flag config. `true` is shorthand for { sampling: true, linked_flag: true }\n */\n startSessionRecording(\n override?: { sampling?: boolean; linked_flag?: boolean; url_trigger?: true; event_trigger?: true } | true\n ): void {\n const overrideAll = override === true\n const overrideConfig: OverrideConfig = {\n sampling: overrideAll || !!override?.sampling,\n linked_flag: overrideAll || !!override?.linked_flag,\n url_trigger: overrideAll || !!override?.url_trigger,\n event_trigger: overrideAll || !!override?.event_trigger,\n }\n\n if (Object.values(overrideConfig).some(Boolean)) {\n // allow the session id check to rotate session id if necessary\n this.sessionManager?.checkAndGetSessionAndWindowId()\n\n if (overrideConfig.sampling) {\n this.sessionRecording?.overrideSampling()\n }\n\n if (overrideConfig.linked_flag) {\n this.sessionRecording?.overrideLinkedFlag()\n }\n\n if (overrideConfig.url_trigger) {\n this.sessionRecording?.overrideTrigger('url')\n }\n\n if (overrideConfig.event_trigger) {\n this.sessionRecording?.overrideTrigger('event')\n }\n }\n\n this.set_config({ disable_session_recording: false })\n }\n\n /**\n * turns session recording off, and updates the config option\n * disable_session_recording to true\n *\n * {@label Session replay}\n *\n * @public\n *\n * @example\n * ```js\n * // Stop session recording\n * posthog.stopSessionRecording()\n * ```\n */\n stopSessionRecording(): void {\n this.set_config({ disable_session_recording: true })\n }\n\n /**\n * returns a boolean indicating whether session recording\n * is currently running\n *\n * {@label Session replay}\n *\n * @public\n *\n * @example\n * ```js\n * // Stop session recording if it's running\n * if (posthog.sessionRecordingStarted()) {\n * posthog.stopSessionRecording()\n * }\n * ```\n */\n sessionRecordingStarted(): boolean {\n return !!this.sessionRecording?.started\n }\n\n /**\n * Capture a caught exception manually\n *\n * {@label Error tracking}\n *\n * @public\n *\n * @example\n * ```js\n * // Capture a caught exception\n * try {\n * // something that might throw\n * } catch (error) {\n * posthog.captureException(error)\n * }\n * ```\n *\n * @example\n * ```js\n * // With additional properties\n * posthog.captureException(error, {\n * customProperty: 'value',\n * anotherProperty: ['I', 'can be a list'],\n * ...\n * })\n * ```\n *\n * @param {Error} error The error to capture\n * @param {Object} [additionalProperties] Any additional properties to add to the error event\n * @returns {CaptureResult} The result of the capture\n */\n captureException(error: unknown, additionalProperties?: Properties): CaptureResult | undefined {\n const syntheticException = new Error('PostHog syntheticException')\n const errorToProperties = this.exceptions.buildProperties(error, {\n handled: true,\n syntheticException,\n })\n return this.exceptions.sendExceptionEvent({\n ...errorToProperties,\n ...additionalProperties,\n })\n }\n\n /**\n * turns exception autocapture on, and updates the config option `capture_exceptions` to the provided config (or `true`)\n *\n * {@label Error tracking}\n *\n * @public\n *\n * @example\n * ```js\n * // Start with default exception autocapture rules. No-op if already enabled\n * posthog.startExceptionAutocapture()\n * ```\n *\n * @example\n * ```js\n * // Start and override controls\n * posthog.startExceptionAutocapture({\n * // you don't have to send all of these (unincluded values will use the default)\n * capture_unhandled_errors: true || false,\n * capture_unhandled_rejections: true || false,\n * capture_console_errors: true || false\n * })\n * ```\n *\n * @param config - optional configuration option to control the exception autocapture behavior\n */\n startExceptionAutocapture(config?: ExceptionAutoCaptureConfig): void {\n this.set_config({ capture_exceptions: config ?? true })\n }\n\n /**\n * turns exception autocapture off by updating the config option `capture_exceptions` to `false`\n *\n * {@label Error tracking}\n *\n * @public\n *\n * @example\n * ```js\n * // Stop capturing exceptions automatically\n * posthog.stopExceptionAutocapture()\n * ```\n */\n stopExceptionAutocapture(): void {\n this.set_config({ capture_exceptions: false })\n }\n\n /**\n * returns a boolean indicating whether the [toolbar](/docs/toolbar) loaded\n *\n * {@label Toolbar}\n *\n * @public\n *\n * @param toolbarParams\n * @returns {boolean} Whether the toolbar loaded\n */\n\n loadToolbar(params: ToolbarParams): boolean {\n return this.toolbar.loadToolbar(params)\n }\n\n /**\n * Returns the value of a super property. Returns undefined if the property doesn't exist.\n *\n * {@label Identification}\n *\n * @remarks\n * get_property() can only be called after the PostHog library has finished loading.\n * init() has a loaded function available to handle this automatically.\n *\n * @example\n * ```js\n * // grab value for '$user_id' after the posthog library has loaded\n * posthog.init('<YOUR PROJECT TOKEN>', {\n * loaded: function(posthog) {\n * user_id = posthog.get_property('$user_id');\n * }\n * });\n * ```\n * @public\n *\n * @param {String} property_name The name of the super property you want to retrieve\n */\n get_property(property_name: string): Property | undefined {\n return this.persistence?.props[property_name]\n }\n\n /**\n * Returns the value of the session super property named property_name. If no such\n * property is set, getSessionProperty() will return the undefined value.\n *\n * {@label Identification}\n *\n * @remarks\n * This is based on browser-level `sessionStorage`, NOT the PostHog session.\n * getSessionProperty() can only be called after the PostHog library has finished loading.\n * init() has a loaded function available to handle this automatically.\n *\n * @example\n * ```js\n * // grab value for 'user_id' after the posthog library has loaded\n * posthog.init('YOUR PROJECT TOKEN', {\n * loaded: function(posthog) {\n * user_id = posthog.getSessionProperty('user_id');\n * }\n * });\n * ```\n *\n * @param {String} property_name The name of the session super property you want to retrieve\n */\n getSessionProperty(property_name: string): Property | undefined {\n return this.sessionPersistence?.props[property_name]\n }\n\n /**\n * Returns a string representation of the PostHog instance.\n *\n * {@label Initialization}\n *\n * @internal\n */\n toString(): string {\n let name = this.config.name ?? PRIMARY_INSTANCE_NAME\n if (name !== PRIMARY_INSTANCE_NAME) {\n name = PRIMARY_INSTANCE_NAME + '.' + name\n }\n return name\n }\n\n _isIdentified(): boolean {\n return (\n this.persistence?.get_property(USER_STATE) === 'identified' ||\n this.sessionPersistence?.get_property(USER_STATE) === 'identified'\n )\n }\n\n _hasPersonProcessing(): boolean {\n return !(\n this.config.person_profiles === 'never' ||\n (this.config.person_profiles === 'identified_only' &&\n !this._isIdentified() &&\n isEmptyObject(this.getGroups()) &&\n !this.persistence?.props?.[ALIAS_ID_KEY] &&\n !this.persistence?.props?.[ENABLE_PERSON_PROCESSING])\n )\n }\n\n _shouldCapturePageleave(): boolean {\n return (\n this.config.capture_pageleave === true ||\n (this.config.capture_pageleave === 'if_capture_pageview' &&\n (this.config.capture_pageview === true || this.config.capture_pageview === 'history_change'))\n )\n }\n\n /**\n * Creates a person profile for the current user, if they don't already have one and config.person_profiles is set\n * to 'identified_only'. Produces a warning and does not create a profile if config.person_profiles is set to\n * 'never'. Learn more about [person profiles](/docs/product-analytics/identify)\n *\n * {@label Identification}\n *\n * @public\n *\n * @example\n * ```js\n * posthog.createPersonProfile()\n * ```\n */\n createPersonProfile(): void {\n if (this._hasPersonProcessing()) {\n // if a person profile already exists, don't send an event when we don't need to\n return\n }\n if (!this._requirePersonProcessing('posthog.createPersonProfile')) {\n return\n }\n // sent a $set event. We don't set any properties here, but attribution props will be added later\n this.setPersonProperties({}, {})\n }\n\n /**\n * Enables person processing if possible, returns true if it does so or already enabled, false otherwise\n *\n * @param function_name\n */\n _requirePersonProcessing(function_name: string): boolean {\n if (this.config.person_profiles === 'never') {\n logger.error(\n function_name + ' was called, but process_person is set to \"never\". This call will be ignored.'\n )\n return false\n }\n this._register_single(ENABLE_PERSON_PROCESSING, true)\n return true\n }\n\n private _is_persistence_disabled(): boolean {\n if (this.config.cookieless_mode === 'always') {\n return true\n }\n const isOptedOut = this.consent.isOptedOut()\n const defaultPersistenceDisabled =\n this.config.opt_out_persistence_by_default || this.config.cookieless_mode === 'on_reject'\n\n // TRICKY: We want a deterministic state for persistence so that a new pageload has the same persistence\n return this.config.disable_persistence || (isOptedOut && !!defaultPersistenceDisabled)\n }\n\n private _sync_opt_out_with_persistence(): boolean {\n const persistenceDisabled = this._is_persistence_disabled()\n\n if (this.persistence?._disabled !== persistenceDisabled) {\n this.persistence?.set_disabled(persistenceDisabled)\n }\n if (this.sessionPersistence?._disabled !== persistenceDisabled) {\n this.sessionPersistence?.set_disabled(persistenceDisabled)\n }\n return persistenceDisabled\n }\n\n /**\n * Opts the user into data capturing and persistence.\n *\n * {@label Privacy}\n *\n * @remarks\n * Enables event tracking and data persistence (cookies/localStorage) for this PostHog instance.\n * By default, captures an `$opt_in` event unless disabled.\n *\n * @example\n * ```js\n * // simple opt-in\n * posthog.opt_in_capturing()\n * ```\n *\n * @example\n * ```js\n * // opt-in with custom event and properties\n * posthog.opt_in_capturing({\n * captureEventName: 'Privacy Accepted',\n * captureProperties: { source: 'banner' }\n * })\n * ```\n *\n * @example\n * ```js\n * // opt-in without capturing event\n * posthog.opt_in_capturing({\n * captureEventName: false\n * })\n * ```\n *\n * @public\n *\n * @param {Object} [config] A dictionary of config options to override\n * @param {string} [config.capture_event_name=$opt_in] Event name to be used for capturing the opt-in action. Set to `null` or `false` to skip capturing the optin event\n * @param {Object} [config.capture_properties] Set of properties to be captured along with the opt-in action\n */\n opt_in_capturing(options?: {\n captureEventName?: EventName | null | false /** event name to be used for capturing the opt-in action */\n captureProperties?: Properties /** set of properties to be captured along with the opt-in action */\n }): void {\n if (this.config.cookieless_mode === 'always') {\n logger.warn('Consent opt in/out is not valid with cookieless_mode=\"always\" and will be ignored')\n return\n }\n if (this.config.cookieless_mode === 'on_reject' && this.consent.isExplicitlyOptedOut()) {\n // If the user has explicitly opted out on_reject mode, then before we can start sending regular non-cookieless events\n // we need to reset the instance to ensure that there is no leaking of state or data between the cookieless and regular events\n this.reset(true)\n this.sessionManager?.destroy()\n this.pageViewManager?.destroy()\n this.sessionManager = new SessionIdManager(this)\n this.pageViewManager = new PageViewManager(this)\n if (this.persistence) {\n this.sessionPropsManager = new SessionPropsManager(this, this.sessionManager, this.persistence)\n }\n this.sessionRecording = new SessionRecording(this)\n this.sessionRecording.startIfEnabledOrStop()\n }\n\n this.consent.optInOut(true)\n this._sync_opt_out_with_persistence()\n\n // Start queue after opting in\n this._start_queue_if_opted_in()\n\n // Restart session recording if it should now be enabled\n // (this handles the case where opt_out_capturing_by_default or cookieless_mode prevented it from starting)\n this.sessionRecording?.startIfEnabledOrStop()\n\n // Reinitialize surveys if we're in cookieless mode and just opted in\n if (this.config.cookieless_mode == 'on_reject') {\n this.surveys.loadIfEnabled()\n }\n\n // Don't capture if captureEventName is null or false\n if (isUndefined(options?.captureEventName) || options?.captureEventName) {\n this.capture(options?.captureEventName ?? '$opt_in', options?.captureProperties, { send_instantly: true })\n }\n\n if (this.config.capture_pageview) {\n this._captureInitialPageview()\n }\n }\n\n /**\n * Opts the user out of data capturing and persistence.\n *\n * {@label Privacy}\n *\n * @remarks\n * Disables event tracking and data persistence (cookies/localStorage) for this PostHog instance.\n * If `opt_out_persistence_by_default` is true, SDK persistence will also be disabled.\n *\n * @example\n * ```js\n * // opt user out (e.g., on privacy settings page)\n * posthog.opt_out_capturing()\n * ```\n *\n * @public\n */\n opt_out_capturing(): void {\n if (this.config.cookieless_mode === 'always') {\n logger.warn('Consent opt in/out is not valid with cookieless_mode=\"always\" and will be ignored')\n return\n }\n\n if (this.config.cookieless_mode === 'on_reject' && this.consent.isOptedIn()) {\n // If the user has opted in, we need to reset the instance to ensure that there is no leaking of state or data between the cookieless and regular events\n this.reset(true)\n }\n\n this.consent.optInOut(false)\n this._sync_opt_out_with_persistence()\n\n if (this.config.cookieless_mode === 'on_reject') {\n // If cookieless_mode is 'on_reject', we start capturing events in cookieless mode\n this.register({\n distinct_id: COOKIELESS_SENTINEL_VALUE,\n $device_id: null,\n })\n this.sessionManager?.destroy()\n this.pageViewManager?.destroy()\n this.sessionManager = undefined\n this.sessionPropsManager = undefined\n this.sessionRecording?.stopRecording()\n this.sessionRecording = undefined\n this._captureInitialPageview()\n }\n }\n\n /**\n * Checks if the user has opted into data capturing.\n *\n * {@label Privacy}\n *\n * @remarks\n * Returns the current consent status for event tracking and data persistence.\n *\n * @example\n * ```js\n * if (posthog.has_opted_in_capturing()) {\n * // show analytics features\n * }\n * ```\n *\n * @public\n *\n * @returns {boolean} current opt-in status\n */\n has_opted_in_capturing(): boolean {\n return this.consent.isOptedIn()\n }\n\n /**\n * Checks if the user has opted out of data capturing.\n *\n * {@label Privacy}\n *\n * @remarks\n * Returns the current consent status for event tracking and data persistence.\n *\n * @example\n * ```js\n * if (posthog.has_opted_out_capturing()) {\n * // disable analytics features\n * }\n * ```\n *\n * @public\n *\n * @returns {boolean} current opt-out status\n */\n has_opted_out_capturing(): boolean {\n return this.consent.isOptedOut()\n }\n\n /**\n * Returns the explicit consent status of the user.\n *\n * @remarks\n * This can be used to check if the user has explicitly opted in or out of data capturing, or neither. This does not\n * take the default config options into account, only whether the user has made an explicit choice, so this can be\n * used to determine whether to show an initial cookie banner or not.\n *\n * @example\n * ```js\n * const consentStatus = posthog.get_explicit_consent_status()\n * if (consentStatus === \"granted\") {\n * // user has explicitly opted in\n * } else if (consentStatus === \"denied\") {\n * // user has explicitly opted out\n * } else if (consentStatus === \"pending\"){\n * // user has not made a choice, show consent banner\n * }\n * ```\n *\n * @public\n *\n * @returns {boolean | null} current explicit consent status\n */\n get_explicit_consent_status(): 'granted' | 'denied' | 'pending' {\n const consent = this.consent.consent\n return consent === ConsentStatus.GRANTED ? 'granted' : consent === ConsentStatus.DENIED ? 'denied' : 'pending'\n }\n\n /**\n * Checks whether the PostHog library is currently capturing events.\n *\n * Usually this means that the user has not opted out of capturing, but the exact behaviour can be controlled by\n * some config options.\n *\n * Additionally, if the cookieless_mode is set to 'on_reject', we will capture events in cookieless mode if the\n * user has explicitly opted out.\n *\n * {@label Privacy}\n *\n * @see {PostHogConfig.cookieless_mode}\n * @see {PostHogConfig.opt_out_persistence_by_default}\n * @see {PostHogConfig.respect_dnt}\n *\n * @returns {boolean} whether the posthog library is capturing events\n */\n is_capturing(): boolean {\n if (this.config.cookieless_mode === 'always') {\n return true\n }\n if (this.config.cookieless_mode === 'on_reject') {\n return this.consent.isExplicitlyOptedOut() || this.consent.isOptedIn()\n } else {\n return !this.has_opted_out_capturing()\n }\n }\n\n /**\n * Clear the user's opt in/out status of data capturing and cookies/localstorage for this PostHog instance\n *\n * {@label Privacy}\n *\n * @public\n *\n */\n clear_opt_in_out_capturing(): void {\n this.consent.reset()\n this._sync_opt_out_with_persistence()\n }\n\n _is_bot(): boolean | undefined {\n if (navigator) {\n return isLikelyBot(navigator, this.config.custom_blocked_useragents)\n } else {\n return undefined\n }\n }\n\n _captureInitialPageview(): void {\n if (!document) {\n return\n }\n\n // If page is not visible, add a listener to detect when the page becomes visible\n // and trigger the pageview only then\n // This is useful to avoid `prerender` calls from Chrome/Wordpress/SPAs\n // that are not visible to the user\n\n if (document.visibilityState !== 'visible') {\n if (!this._visibilityStateListener) {\n this._visibilityStateListener = this._captureInitialPageview.bind(this)\n addEventListener(document, 'visibilitychange', this._visibilityStateListener)\n }\n\n return\n }\n\n // Extra check here to guarantee we only ever trigger a single `$pageview` event\n if (!this._initialPageviewCaptured) {\n this._initialPageviewCaptured = true\n this.capture('$pageview', { title: document.title }, { send_instantly: true })\n\n // After we've captured the initial pageview, we can remove the listener\n if (this._visibilityStateListener) {\n document.removeEventListener('visibilitychange', this._visibilityStateListener)\n this._visibilityStateListener = null\n }\n }\n }\n\n /**\n * Enables or disables debug mode for detailed logging.\n *\n * @remarks\n * Debug mode logs all PostHog calls to the browser console for troubleshooting.\n * Can also be enabled by adding `?__posthog_debug=true` to the URL.\n *\n * {@label Initialization}\n *\n * @example\n * ```js\n * // enable debug mode\n * posthog.debug(true)\n * ```\n *\n * @example\n * ```js\n * // disable debug mode\n * posthog.debug(false)\n * ```\n *\n * @public\n *\n * @param {boolean} [debug] If true, will enable debug mode.\n */\n debug(debug?: boolean): void {\n if (debug === false) {\n window?.console.log(\"You've disabled debug mode.\")\n this.set_config({ debug: false })\n } else {\n window?.console.log(\n \"You're now in debug mode. All calls to PostHog will be logged in your console.\\nYou can disable this with `posthog.debug(false)`.\"\n )\n this.set_config({ debug: true })\n }\n }\n\n /**\n * Helper method to check if external API calls (flags/decide) should be disabled\n * Handles migration from old `advanced_disable_decide` to new `advanced_disable_flags`\n */\n _shouldDisableFlags(): boolean {\n // Check if advanced_disable_flags was explicitly set in original config\n const originalConfig = this._originalUserConfig || {}\n if ('advanced_disable_flags' in originalConfig) {\n return !!originalConfig.advanced_disable_flags\n }\n\n // Check if advanced_disable_flags was set post-init (different from default false)\n if (this.config.advanced_disable_flags !== false) {\n return !!this.config.advanced_disable_flags\n }\n\n // Check for post-init changes to advanced_disable_decide\n if (this.config.advanced_disable_decide === true) {\n logger.warn(\n \"Config field 'advanced_disable_decide' is deprecated. Please use 'advanced_disable_flags' instead. \" +\n 'The old field will be removed in a future major version.'\n )\n return true\n }\n\n // Fall back to migration logic for original user config\n return migrateConfigField(originalConfig, 'advanced_disable_flags', 'advanced_disable_decide', false, logger)\n }\n\n private _runBeforeSend(data: CaptureResult): CaptureResult | null {\n if (isNullish(this.config.before_send)) {\n return data\n }\n\n const fns = isArray(this.config.before_send) ? this.config.before_send : [this.config.before_send]\n let beforeSendResult: CaptureResult | null = data\n for (const fn of fns) {\n beforeSendResult = fn(beforeSendResult)\n if (isNullish(beforeSendResult)) {\n const logMessage = `Event '${data.event}' was rejected in beforeSend function`\n if (isKnownUnsafeEditableEvent(data.event)) {\n logger.warn(`${logMessage}. This can cause unexpected behavior.`)\n } else {\n logger.info(logMessage)\n }\n return null\n }\n if (!beforeSendResult.properties || isEmptyObject(beforeSendResult.properties)) {\n logger.warn(\n `Event '${data.event}' has no properties after beforeSend function, this is likely an error.`\n )\n }\n }\n return beforeSendResult\n }\n\n /**\n * Returns the current page view ID.\n *\n * {@label Initialization}\n *\n * @public\n *\n * @returns {string} The current page view ID\n */\n public getPageViewId(): string | undefined {\n return this.pageViewManager._currentPageview?.pageViewId\n }\n\n /**\n * Capture written user feedback for a LLM trace. Numeric values are converted to strings.\n *\n * {@label LLM analytics}\n *\n * @public\n *\n * @param traceId The trace ID to capture feedback for.\n * @param userFeedback The feedback to capture.\n */\n captureTraceFeedback(traceId: string | number, userFeedback: string) {\n this.capture('$ai_feedback', {\n $ai_trace_id: String(traceId),\n $ai_feedback_text: userFeedback,\n })\n }\n\n /**\n * Capture a metric for a LLM trace. Numeric values are converted to strings.\n *\n * {@label LLM analytics}\n *\n * @public\n *\n * @param traceId The trace ID to capture the metric for.\n * @param metricName The name of the metric to capture.\n * @param metricValue The value of the metric to capture.\n */\n captureTraceMetric(traceId: string | number, metricName: string, metricValue: string | number | boolean) {\n this.capture('$ai_metric', {\n $ai_trace_id: String(traceId),\n $ai_metric_name: metricName,\n $ai_metric_value: String(metricValue),\n })\n }\n\n private _checkLocalStorageForDebug(debugConfig: boolean | undefined) {\n const explicitlyFalse = isBoolean(debugConfig) && !debugConfig\n const isTrueInLocalStorage = localStore._is_supported() && localStore._get('ph_debug') === 'true'\n return explicitlyFalse ? false : isTrueInLocalStorage ? true : debugConfig\n }\n}\n\nsafewrapClass(PostHog, ['identify'])\n\nconst add_dom_loaded_handler = function () {\n // Cross browser DOM Loaded support\n function dom_loaded_handler() {\n // function flag since we only want to execute this once\n if ((dom_loaded_handler as any).done) {\n return\n }\n ;(dom_loaded_handler as any).done = true\n\n ENQUEUE_REQUESTS = false\n\n each(instances, function (inst: PostHog) {\n inst._dom_loaded()\n })\n }\n\n if (document?.addEventListener) {\n if (document.readyState === 'complete') {\n // safari 4 can fire the DOMContentLoaded event before loading all\n // external JS (including this file). you will see some copypasta\n // on the internet that checks for 'complete' and 'loaded', but\n // 'loaded' is an IE thing\n dom_loaded_handler()\n } else {\n addEventListener(document, 'DOMContentLoaded', dom_loaded_handler, { capture: false })\n }\n\n return\n }\n\n // Only IE6-8 don't support `document.addEventListener` and we don't support them\n // so let's simply log an error stating PostHog couldn't be initialized\n // We're checking for `window` to avoid erroring out on a SSR context\n if (window) {\n logger.error(\"Browser doesn't support `document.addEventListener` so PostHog couldn't be initialized\")\n }\n}\n\nexport function init_from_snippet(): void {\n const posthogMain = (instances[PRIMARY_INSTANCE_NAME] = new PostHog())\n\n const snippetPostHog = assignableWindow['posthog']\n\n if (snippetPostHog) {\n /**\n * The snippet uses some clever tricks to allow deferred loading of array.js (this code)\n *\n * window.posthog is an array which the queue of calls made before the lib is loaded\n * It has methods attached to it to simulate the posthog object so for instance\n *\n * window.posthog.init(\"TOKEN\", {api_host: \"foo\" })\n * window.posthog.capture(\"my-event\", {foo: \"bar\" })\n *\n * ... will mean that window.posthog will look like this:\n * window.posthog == [\n * [\"my-event\", {foo: \"bar\"}]\n * ]\n *\n * window.posthog[_i] == [\n * [\"TOKEN\", {api_host: \"foo\" }, \"posthog\"]\n * ]\n *\n * If a name is given to the init function then the same as above is true but as a sub-property on the object:\n *\n * window.posthog.init(\"TOKEN\", {}, \"ph2\")\n * window.posthog.ph2.people.set({foo: \"bar\"})\n *\n * window.posthog.ph2 == []\n * window.posthog.people == [\n * [\"set\", {foo: \"bar\"}]\n * ]\n *\n */\n\n // Call all pre-loaded init calls properly\n\n each(snippetPostHog['_i'], function (item: [token: string, config: Partial<PostHogConfig>, name: string]) {\n if (item && isArray(item)) {\n const instance = posthogMain.init(item[0], item[1], item[2])\n\n const instanceSnippet = snippetPostHog[item[2]] || snippetPostHog\n\n if (instance) {\n // Crunch through the people queue first - we queue this data up &\n // flush on identify, so it's better to do all these operations first\n instance._execute_array.call(instance.people, instanceSnippet.people)\n instance._execute_array(instanceSnippet)\n }\n }\n })\n }\n\n assignableWindow['posthog'] = posthogMain\n\n add_dom_loaded_handler()\n}\n\nexport function init_as_module(): PostHog {\n const posthogMain = (instances[PRIMARY_INSTANCE_NAME] = new PostHog())\n\n add_dom_loaded_handler()\n\n return posthogMain\n}\n","import { PropertyMatchType } from './types'\nimport { SurveyActionType, SurveyEventWithFilters } from './posthog-surveys-types'\n\nexport interface JSONContent {\n type?: string\n attrs?: Record<string, any>\n content?: JSONContent[]\n marks?: { type: string; attrs?: Record<string, any> }[]\n text?: string\n}\n\nexport type ProductTourStepType = 'element' | 'modal' | 'survey'\n\nexport type ProductTourSurveyQuestionType = 'open' | 'rating'\n\nexport interface ProductTourSurveyQuestion {\n type: ProductTourSurveyQuestionType\n questionText: string\n /** Rating display type - emoji or number */\n display?: 'emoji' | 'number'\n /** Rating scale - 3 or 5 for emoji, 5 or 10 for number */\n scale?: 3 | 5 | 10\n /** Label for low end of rating scale (e.g., \"Not likely\") */\n lowerBoundLabel?: string\n /** Label for high end of rating scale (e.g., \"Very likely\") */\n upperBoundLabel?: string\n}\n\nexport interface ProductTourStep {\n id: string\n type: ProductTourStepType\n selector?: string\n progressionTrigger: 'button' | 'click'\n content: JSONContent | null\n /** Inline survey question config - if present, this is a survey step */\n survey?: ProductTourSurveyQuestion\n /** ID of the auto-created survey for this step (set by backend) */\n linkedSurveyId?: string\n /** ID of the survey question (set by backend, used for event tracking) */\n linkedSurveyQuestionId?: string\n}\n\nexport interface ProductTourConditions {\n url?: string\n urlMatchType?: PropertyMatchType\n selector?: string\n autoShowDelaySeconds?: number\n events?: {\n values: SurveyEventWithFilters[]\n } | null\n cancelEvents?: {\n values: SurveyEventWithFilters[]\n } | null\n actions?: {\n values: SurveyActionType[]\n } | null\n}\n\nexport interface ProductTourAppearance {\n backgroundColor?: string\n textColor?: string\n buttonColor?: string\n borderRadius?: number\n buttonBorderRadius?: number\n borderColor?: string\n fontFamily?: string\n boxShadow?: string\n showOverlay?: boolean\n whiteLabel?: boolean\n}\n\nexport interface ProductTour {\n id: string\n name: string\n description?: string\n type: 'product_tour'\n auto_launch?: boolean\n start_date: string | null\n end_date: string | null\n current_iteration?: number\n conditions?: ProductTourConditions\n appearance?: ProductTourAppearance\n steps: ProductTourStep[]\n internal_targeting_flag_key?: string\n linked_flag_key?: string\n}\n\nexport type ProductTourCallback = (tours: ProductTour[], context?: { isLoaded: boolean; error?: string }) => void\n\nexport type ProductTourSelectorError = 'not_found' | 'multiple_matches' | 'not_visible'\n\nexport type ProductTourDismissReason =\n | 'user_clicked_skip'\n | 'user_clicked_outside'\n | 'escape_key'\n | 'element_unavailable'\n\nexport type ProductTourRenderReason = 'auto' | 'api' | 'trigger' | 'event'\n\nexport const DEFAULT_PRODUCT_TOUR_APPEARANCE: Required<ProductTourAppearance> = {\n backgroundColor: '#ffffff',\n textColor: '#1d1f27',\n buttonColor: '#1d1f27',\n borderRadius: 8,\n buttonBorderRadius: 6,\n borderColor: '#e5e7eb',\n fontFamily: 'system-ui',\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',\n showOverlay: true,\n whiteLabel: false,\n}\n\nexport interface ShowTourOptions {\n reason?: ProductTourRenderReason\n enableStrictValidation?: boolean\n}\n","import { init_as_module } from '../posthog-core'\nexport { PostHog } from '../posthog-core'\nexport * from '../types'\nexport * from '../posthog-surveys-types'\nexport * from '../posthog-product-tours-types'\nexport * from '../posthog-conversations-types'\nexport const posthog = init_as_module()\nexport default posthog\n"],"names":["win","window","undefined","global","globalThis","self","File","ArrayProto","Array","prototype","nativeForEach","forEach","nativeIndexOf","indexOf","navigator","document","location","fetch","XMLHttpRequest","AbortController","userAgent","assignableWindow","Config","DEBUG","LIB_VERSION","DEFAULT_BLOCKED_UA_STRS","isBlockedUA","ua","customBlockedUserAgents","uaLower","toLowerCase","concat","some","blockedUA","blockedUaLower","knownUnsafeEditableEvent","includes","str","needle","trim","stripLeadingDollar","s","replace","nativeIsArray","isArray","ObjProto","Object","type_utils_hasOwnProperty","hasOwnProperty","type_utils_toString","toString","obj","call","isFunction","x","isObject","isEmptyObject","key","isUndefined","isString","isEmptyString","length","isNull","isNullish","isNumber","isBoolean","isFormData","FormData","isKnownUnsafeEditableEvent","isPrimitive","value","isBuiltin","candidate","className","isEvent","Event","base","_unused","isInstanceOf","yesLikeValues","isYesLike","val","noLikeValues","clampToRange","min","max","logger","fallbackValue","warn","BucketedRateLimiter","constructor","options","this","_buckets","_onBucketRateLimited","_bucketSize","bucketSize","_logger","_refillRate","refillRate","_refillInterval","refillInterval","_applyRefill","bucket","now","elapsedMs","lastAccess","refillIntervals","Math","floor","tokensToAdd","tokens","consumeRateLimit","_this$_onBucketRateLi","Date","keyStr","String","stop","MOBILE","IOS","ANDROID","TABLET","ANDROID_TABLET","IPAD","APPLE","APPLE_WATCH","SAFARI","BLACKBERRY","SAMSUNG","SAMSUNG_BROWSER","SAMSUNG_INTERNET","CHROME","CHROME_OS","CHROME_IOS","INTERNET_EXPLORER","INTERNET_EXPLORER_MOBILE","OPERA","OPERA_MINI","EDGE","MICROSOFT_EDGE","FIREFOX","FIREFOX_IOS","NINTENDO","PLAYSTATION","XBOX","ANDROID_MOBILE","MOBILE_SAFARI","WINDOWS","WINDOWS_PHONE","NOKIA","OUYA","GENERIC","GENERIC_MOBILE","GENERIC_TABLET","KONQUEROR","BROWSER_VERSION_REGEX_SUFFIX","DEFAULT_BROWSER_VERSION_REGEX","RegExp","XBOX_REGEX","PLAYSTATION_REGEX","NINTENDO_REGEX","BLACKBERRY_REGEX","windowsVersionMap","parsedStackResults","lastKeysCount","cachedFilenameChunkIds","safariCheck","vendor","isSafari","detectBrowser","user_agent","test","FACEBOOK","versionRegexes","Mozilla","detectBrowserVersion","browser","regexes","i","regex","matches","match","parseFloat","osMatchers","_","exec","version","osVersion","versionParts","join","result","detectDevice","isError","Error","getFilenameToChunkIdMap","stackParser","chunkIdMap","_posthogChunkIds","chunkIdKeys","keys","reduce","acc","stackKey","parsedStack","stackFrame","filename","chunkId","ErrorPropertiesBuilder","coercers","modifiers","buildFromUnknown","input","hint","mechanism","handled","type","exceptionWithCause","buildCoercingContext","apply","parsingContext","buildParsingContext","exceptionWithStack","parseStacktrace","$exception_list","convertToExceptionList","$exception_level","modifyFrames","exceptionList","_this","_asyncToGenerator","exc","stacktrace","frames","applyModifiers","coerceFallback","ctx","_ctx$syntheticExcepti","stack","syntheticException","synthetic","err","cause","applyChunkIds","_extends","map","frame","chunk_id","applyCoercers","adapter","coerce","_this2","newFrames","modifier","_mechanism$type","_mechanism$handled","_exceptionWithStack$s","currentException","push","depth","next","UNKNOWN_FUNCTION","createFrame","platform","func","lineno","colno","function","in_app","extractSafariExtensionDetails","isSafariExtension","isSafariWebExtension","split","chromeRegexNoFnName","chromeRegex","chromeEvalRegex","chromeStackLineParser","line","noFnParts","col","parts","subMatch","geckoREgex","geckoEvalRegex","geckoStackLineParser","WEBPACK_ERROR_REGEXP","STACKTRACE_FRAME_LIMIT","createDefaultStackParser","_len","arguments","parsers","_key","skipFirstLines","lines","cleanedLine","parser","localStack","from","reverse","slice","arr","reverseAndStripFrames","createStackParser","DOMExceptionCoercer","isDOMException","isDOMError","hasStack","getType","getValue","name","message","ErrorCoercer","isPlainError","getMessage","getStack","_ctx","error","ErrorEventCoercer","exceptionLike","ERROR_TYPES_PATTERN","StringCoercer","getInfos","groups","severityLevels","extractExceptionKeysForMessage","maxLength","sort","serialized","ObjectCoercer","errorProperty","getErrorPropertyFromObject","level","isSeverityLevel","getObjectClassName","prop","getPrototypeOf","e","EventCoercer","evt","constructorName","PrimitiveCoercer","PromiseRejectionEventCoercer","reason","getUnhandledRejectionReason","detail","_createLogger","prefix","_temp","debugEnabled","_log","POSTHOG_DEBUG","console","consoleLog","args","info","_len2","_key2","_len3","_key3","_len4","_key4","critical","_len5","_key5","uninitializedWarning","methodName","createLogger","additionalPrefix","loadScript","posthog","url","callback","config","disable_external_dependency_loading","existingScripts","querySelectorAll","_ret","_loop","src","alreadyExistingScriptTag","__posthog_loading_callback_fired","v","addEventListener","event","onerror","addScript","scriptTag","createElement","crossOrigin","onload","prepare_external_dependency_script","_scripts$0$parentNode","scripts","parentNode","insertBefore","body","appendChild","__PosthogExtensions__","loadExternalDependency","kind","scriptUrlToLoad","token","fiveMinutesInMillis","requestRouter","endpointFor","loadSiteApp","scriptUrl","breaker","eachArray","iterator","thisArg","l","each","pair","entries","extend","source","extendArray","item","ownProps","resArray","trySafe","fn","safewrap","f","stripEmptyProperties","p","ret","k","_copyAndTruncateStrings","object","maxStringLength","customizer","COPY_IN_PROGRESS_SET","Set","internalDeepCircularCopy","has","add","it","EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE","isCrossDomainCookie","documentLocation","hostname","lastTwoParts","excluded","find","predicate","element","capture","passive","PEOPLE_DISTINCT_ID_KEY","ALIAS_ID_KEY","EVENT_TIMERS_KEY","AUTOCAPTURE_DISABLED_SERVER_SIDE","HEATMAPS_ENABLED_SERVER_SIDE","EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE","ERROR_TRACKING_SUPPRESSION_RULES","ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS","WEB_VITALS_ENABLED_SERVER_SIDE","DEAD_CLICKS_ENABLED_SERVER_SIDE","PRODUCT_TOURS_ENABLED_SERVER_SIDE","WEB_VITALS_ALLOWED_METRICS","SESSION_RECORDING_REMOTE_CONFIG","SESSION_ID","SESSION_RECORDING_IS_SAMPLED","ENABLED_FEATURE_FLAGS","PERSISTENCE_EARLY_ACCESS_FEATURES","PERSISTENCE_FEATURE_FLAG_DETAILS","STORED_PERSON_PROPERTIES_KEY","STORED_GROUP_PROPERTIES_KEY","SURVEYS","FLAG_CALL_REPORTED","USER_STATE","CLIENT_SESSION_PROPS","CAPTURE_RATE_LIMIT","INITIAL_CAMPAIGN_PARAMS","INITIAL_REFERRER_INFO","INITIAL_PERSON_INFO","ENABLE_PERSON_PROCESSING","TOOLBAR_ID","COOKIELESS_SENTINEL_VALUE","PERSISTENCE_RESERVED_PROPERTIES","isElementInToolbar","el","Element","id","closest","isElementNode","nodeType","isTag","tag","tagName","isTextNode","isDocumentFragment","splitClassString","checkForURLMatches","urlsList","href","getClassNames","baseVal","getAttribute","makeSafeText","filter","shouldCaptureValue","substring","getSafeText","elText","shouldCaptureElement","isSensitiveElement","childNodes","child","_makeSafeText","textContent","getEventTarget","target","srcElement","_e$target","shadowRoot","composedPath","autocaptureCompatibleElements","checkIfElementsMatchCSSSelector","elements","selectorList","_ret2","_loop2","selector","getParentElement","curEl","DEFAULT_CONTENT_IGNORELIST","MAX_CONTENT_IGNORELIST_ENTRIES","DEFAULT_RAGE_CLICK_IGNORE_LIST","shouldCaptureRageclick","_config","cannotCheckForAutocapture","selectorIgnoreList","contentIgnorelist","_config$css_selector_","css_selector_ignorelist","content_ignorelist","targetElementList","getElementAndParentsForElement","elementsWithText","keywords","_ref","safeText","ariaLabel","keyword","shouldIgnoreByContent","_element$getAttribute","captureOnAnyElement","parentIsUsefulElement","host","compStyles","getComputedStyle","getPropertyValue","shouldCaptureDomEvent","autocaptureConfig","allowedEventTypes","_autocaptureConfig","_autocaptureConfig2","_autocaptureConfig3","_autocaptureConfig4","url_allowlist","url_ignorelist","dom_event_allowlist","allowlist","eventType","element_allowlist","elementType","checkIfElementTreePassesElementAllowList","css_selector_allowlist","classes","coreCCPattern","anchoredCCRegex","unanchoredCCRegex","coreSSNPattern","anchoredSSNRegex","unanchoredSSNRegex","anchorRegexes","getDirectAndNestedSpanText","text","getNestedSpanText","_child$tagName","spanText","getElementsChainString","_element$nth_child","_element$nth_of_type","el_string","tag_name","attr_class","single_class","attributes","nth_child","nth_of_type","attr_id","sortedAttributes","_ref2","_ref3","a","b","localeCompare","_ref4","escapeQuotes","_ref5","elementsToString","_el$$el_text","_el$attr__href","response","extractAttrClass","_ref6","_ref7","extractElements","RageClick","rageclickConfig","disabled","conf","thresholdPx","threshold_px","timeoutMs","timeout_ms","clickCount","click_count","clicks","isRageClick","y","timestamp","lastClick","abs","convertToURL","formDataToQuery","formdata","arg_separator","use_val","use_key","tph_arr","encodeURIComponent","isFile","getQueryParam","param","keyValuePair","queryParts","decodeURIComponent","maskQueryParams","maskedParams","mask","splitHash","withoutHash","hash","splitQuery","queryString","urlWithoutQueryAndHash","paramStrings","_getHashParam","COPY_AUTOCAPTURE_EVENT","limitText","previousElementSibling","_el","previousSibling","getPropertiesFromElement","elem","maskAllAttributes","maskText","elementAttributeIgnorelist","props","c","attr","attributeName","nthChild","nthOfType","currentElem","autocapturePropertiesForElement","_elementsJson$","_elementsJson$2","maskAllElementAttributes","maskAllText","elementAttributeIgnoreList","elementsChainAsString","externalHref","elementsJson","autocaptureAugmentProperties","explicitNoCapture","shouldCaptureEl","augmentProperties","propertyKey","propertyValue","getAugmentPropertiesFromElement","_convertToURL","_window$location","hrefHost","locationHost","$event_type","$ce_version","$elements","$elements_chain","$el_text","$external_click_url","Autocapture","instance","_initialized","_isDisabledServerSide","_elementsChainAsString","rageclicks","rageclick","_elementSelectors","_config$url_allowlist","_config$url_ignorelis","autocapture","_addDomEventHandlers","isBrowserSupported","handler","_captureEvent","capture_copied_text","copiedTextHandler","startIfEnabled","isEnabled","onRemoteConfig","persistence","register","setElementSelectors","selectors","getElementSelectors","_this$_elementSelecto","elementSelectors","matchedElements","matchedElement","_this$instance$persis","_this$_isDisabledServ","persistedServerDisabled","memoryDisabled","_shouldDisableFlags","disabledServer","eventName","_this$rageclicks","MouseEvent","clientX","clientY","timeStamp","getTime","isCopyAutocapture","mask_all_element_attributes","mask_all_text","element_attribute_ignorelist","_window$getSelection","selectedContent","getSelection","clipType","trunc","ceil","Number","isInteger","isFinite","DIGITS","UUID","bytes","TypeError","fromFieldsV7","unixTsMs","randA","randBHi","randBLo","RangeError","Uint8Array","pow","charAt","clone","equals","other","compareTo","diff","sign","V7Generator","_timestamp","_counter","_random","DefaultRandom","generate","generateOrAbort","valueAfterReset","ts","_resetCounter","nextUint32","defaultGenerator","getRandomValues","buffer","UUIDV7_DENY_WEAK_RNG","random","crypto","_buffer","Uint32Array","_cursor","Infinity","uuidv7","uuidv7obj","firstNonPublicSubDomain","DOMAIN_MATCH_REGEX","chooseCookieDomain","cross_subdomain","matchedSubDomain","cookieJar","list","len","candidateCookieValue","cookie","seekFirstNonPublicSubDomain","originalMatch","originalCookieDomainFn","cookieStore","_is_supported","_error","msg","_get","nameEQ","ca","_parse","JSON","parse","_unused2","_set","days","is_secure","expires","secure","cdomain","date","setTime","toUTCString","new_cookie_val","stringify","_unused3","_remove","_unused4","_localStorage_supported","localStore","supported","_unused5","localStorage","getItem","_unused6","setItem","removeItem","COOKIE_PERSISTED_PROPERTIES","memoryStorage","memoryStore","sessionStorageSupported","sessionStore","_unused9","sessionStorage","_unused0","ConsentStatus","ConsentManager","_instance","consent","_getDnt","DENIED","_storedConsent","isOptedOut","cookieless_mode","PENDING","opt_out_capturing_by_default","isOptedIn","isExplicitlyOptedOut","optInOut","_storage","_storageKey","cookie_expiration","cross_subdomain_cookie","secure_cookie","reset","opt_out_capturing_cookie_prefix","consent_persistence_name","GRANTED","_persistentStore","persistenceType","opt_out_capturing_persistence_type","otherStorage","respect_dnt","doNotTrack","dntValue","isDeadClicksEnabledForHeatmaps","isDeadClicksEnabledForAutocapture","_instance$instance$pe","isRemoteEnabled","get_property","clientConfig","capture_dead_clicks","DeadClicksAutocapture","lazyLoadedDeadClicksAutocapture","_lazyLoadedDeadClicksAutocapture","onCapture","captureDeadClicks","_loadScript","_start","cb","_assignableWindow$__P","_assignableWindow$__P2","initDeadClicksAutocapture","_assignableWindow$__P3","__onCapture","start","ExceptionObserver","_this$_instance$persi","_this$_instance$confi","_this$_instance$confi2","_startCapturing","errorWrappingFunctions","wrapOnError","wrapUnhandledRejection","wrapConsoleError","_unwrapOnError","capture_unhandled_errors","captureException","bind","_unwrapUnhandledRejection","capture_unhandled_rejections","_unwrapConsoleError","capture_console_errors","_stopCapturing","_remoteEnabled","_rateLimiter","error_tracking","__exceptionRateLimiterRefillRate","__exceptionRateLimiterBucketSize","_requiredConfig","startIfEnabledOrStop","providedConfig","capture_exceptions","_this$_unwrapOnError","_this$_unwrapUnhandle","_this$_unwrapConsoleE","autocaptureExceptionsResponse","autocaptureExceptions","onConfigChange","errorProperties","_errorProperties$$exc","_errorProperties$$exc2","exceptionType","exception","exceptions","sendExceptionEvent","patch","replacement","original","wrapped","defineProperties","__posthog_wrapped__","enumerable","HistoryAutocapture","_lastPathname","pathname","capture_pageview","monitorHistoryChanges","_popstateListener","_window$history$pushS","_window$history$repla","history","pushState","originalPushState","state","title","_capturePageview","replaceState","originalReplaceState","_setupPopstateListener","navigationType","_window$location2","currentPathname","navigation_type","removeEventListener","setupSegmentIntegration","done","segment","bootstrapUser","user","getSegmentAnonymousId","anonymousId","get_device_id","distinct_id","$device_id","set_property","segmentUser","then","setupPostHogFromSegment","Promise","resolve","enrichEvent","userId","get_distinct_id","identify","additionalProperties","calculateEventProperties","properties","assign","isLoaded","load","track","page","screen","createSegmentIntegration","NAME","createEventProcessor","_posthog","organization","projectId","severityAllowList","sendExceptionsToPostHog","_event$exception","_exceptions$","_exceptions$2","_exceptions$3","_exceptions$4","__loaded","tags","personUrl","sessionRecordingStarted","get_session_replay_url","withTimestamp","values","data","$exception_message","$exception_type","$sentry_event_id","event_id","$sentry_exception","$sentry_exception_message","$sentry_exception_type","$sentry_tags","SentryIntegration","setupOnce","addGlobalEventProcessor","STATE_FROM_WINDOW","LOCALSTORAGE_KEY","ToolbarState","Toolbar","_setToolbarState","_getToolbarState","_assignableWindow$ph_","UNINITIALIZED","maybeLoadToolbar","toolbarParams","stateHash","atob","search","userIntent","loadToolbar","_callLoadToolbar","params","loadFn","toolbarRunning","getElementById","disableToolbarMetrics","region","advanced_disable_toolbar_metrics","apiURL","instrument","LOADED","LOADING","_loadEditor","maybeLoadEditor","TracingHeaders","_restoreXHRPatch","_restoreFetchPatch","tracingHeadersPatchFns","_patchXHR","__add_tracing_headers","sessionManager","_patchFetch","_assignableWindow$__P4","_this$_restoreXHRPatc","_this$_restoreFetchPa","URL_REGEX_PREFIX","PERSONAL_DATA_CAMPAIGN_PARAMS","CAMPAIGN_PARAMS","MASKED","COOKIE_CAMPAIGN_PARAMS","getCampaignParams","customTrackedParams","maskPersonalDataProperties","customPersonalDataProperties","paramsToMask","urlCampaignParams","_getCampaignParamsFromUrl","URL","cookieCampaignParams","kwkey","kw","customParams","campaign_keywords","_getSearchInfoFromReferrer","referrer","_getSearchEngine","getBrowserLanguage","language","userLanguage","getReferrer","getPersonInfo","r","u","getPersonPropsFromInfo","_convertToURL2","$referrer","$referring_domain","campaignParams","searchInfo","getTimezone","Intl","DateTimeFormat","resolvedOptions","timeZone","getTimezoneOffset","getEventProperties","lang","device","os_name","os_version","rgex","resultOrFn","detectOS","$os","$os_version","$browser","$device","$device_type","$timezone","$timezone_offset","$current_url","$host","$pathname","$raw_user_agent","$browser_version","$browser_language","$browser_language_prefix","$screen_height","height","$screen_width","width","$viewport_height","innerHeight","$viewport_width","innerWidth","$lib","$lib_version","$insert_id","$time","FIFTEEN_MINUTES_IN_MILLIS","WebVitalsAutocapture","_enabledServerSide","metrics","firstMetricTimestamp","_flushToCapture","clearTimeout","_delayedFlushTimer","metric","_addToBuffer","_this$_instance$sessi","sessionIds","checkAndGetSessionAndWindowId","$currentUrl","_currentURL","_maxAllowedValue","setTimeout","flushToCaptureTimeoutMs","attribution","interactionTargetElement","$session_id","sessionId","$window_id","windowId","allowedMetrics","onLCP","onCLS","onFCP","onINP","posthogExtensions","postHogWebVitalsCallbacks","_this$_instance$persi2","clientConfigMetricAllowList","capture_performance","web_vitals_allowed_metrics","web_vitals_delayed_flush_ms","configured","__web_vitals_max_value","protocol","web_vitals","webVitalsOptIn","capturePerformance","mask_personal_data_properties","custom_personal_data_properties","isValidMouseEvent","Heatmaps","_flushInterval","flushIntervalMilliseconds","flushInterval","capture_heatmaps","flush_interval_milliseconds","enable_heatmaps","_setupListeners","_onVisibilityChange","_this$_flushInterval","clearInterval","_removeListeners","getAndClearBuffer","optIn","_onDeadClick","click","_onClick","originalEvent","visibilityState","shouldPoll","setInterval","_flush","_flushHandler","_onClickHandler","_onMouseMoveHandler","_onMouseMove","_deadClicksCapture","_onVisibilityChange_handler","_this$_deadClicksCapt","_mouseMoveTimeout","_getProperties","scrollY","scrollManager","scrollX","scrollElement","isFixedOrSticky","breakOnElement","position","elementOrParentPositionMatches","target_fixed","_capture","$heatmap_data","PageViewManager","_onSessionIdChange","_windowId","changeReason","noSessionId","activityTimeout","sessionPastMaximumLength","_currentPageview","resetContext","_setupSessionRotationHandler","_unsubscribeSessionId","onSessionId","destroy","_this$_unsubscribeSes","doPageView","pageViewId","_window$location$path","_previousPageViewProperties","doPageLeave","_this$_currentPagevie","doEvent","_this$_currentPagevie2","$pageview_id","pageviewId","previousPageView","$prev_pageview_id","scrollContext","getContext","disable_scroll_properties","maxScrollHeight","lastScrollY","maxScrollY","maxContentHeight","lastContentY","maxContentY","lastScrollPercentage","maxScrollPercentage","lastContentPercentage","maxContentPercentage","$prev_pageview_last_scroll","$prev_pageview_last_scroll_percentage","$prev_pageview_max_scroll","$prev_pageview_max_scroll_percentage","$prev_pageview_last_content","$prev_pageview_last_content_percentage","$prev_pageview_max_content","$prev_pageview_max_content_percentage","$prev_pageview_pathname","$prev_pageview_duration","Compression","u8","u16","Uint16Array","u32","fleb","fdeb","clim","freb","eb","j","_a","fl","revfl","revfd","rev","hMap","cd","mb","co","le","rvb","sv","r_1","m","flt","fdt","flm","fdm","shft","slc","n","set","subarray","wbits","d","o","wbits16","hTree","t","t2","i0","i1","i2","maxSym","tr","mbt","ln","dt","lft","cst","i2_1","i2_2","i2_3","lc","cl","cli","cln","cls","w","clen","cf","wfblk","out","pos","dat","wblk","final","syms","lf","df","li","bs","bl","dlt","mlb","_b","ddt","mdb","_c","lclt","nlc","_d","lcdt","ndc","lcfreq","_e","lct","mlcb","nlcc","lm","ll","dm","dl","flen","ftlen","dtlen","llm","lcts","clct","dst","deo","crct","dopt","opt","pre","post","st","lvl","plvl","lst","msk_1","prev","head","bs1_1","bs2_1","hsh","lc_1","wi","hv","imod","pimod","rem","ch_1","dif","maxn","maxd","ml","nl","mmd","md","ti","lin","din","dflt","mem","log","wbytes","gzipSync","opts","cr","crc","mtime","charCodeAt","gzh","utf8Encode","string","end","stringl","utftext","c1","enc","fromCharCode","SUPPORTS_REQUEST","CONTENT_TYPE_PLAIN","extendURLParams","_search$split$map","baseUrl","newParams","updatedSearch","_newParams$key","origValue","remaining","jsonStringify","space","encodePostData","compression","GZipJS","gzipData","latin1","TextEncoder","encode","ar","ai","strToU8","blob","Blob","contentType","estimatedSize","size","Base64","b64data","h1","h2","h3","h4","bits","b64","ac","tmp_arr","_base64Encode","encodedBody","encodeToDataString","jsonBody","AVAILABLE_TRANSPORTS","transport","method","_encodePostData2","_aborter","headers","Headers","headerValue","headerName","append","aborter","controller","signal","timeout","abort","keepalive","SIXTY_FOUR_KILOBYTES","fetchOptions","responseText","res","statusCode","status","json","catch","finally","_encodePostData","req","open","setRequestHeader","disableXHRCredentials","withCredentials","onreadystatechange","readyState","send","sendBeacon","beacon","_encodePostData3","sendBeaconBody","isMatchingRegex","pattern","isValidRegex","getPersonPropertiesHash","userPropertiesToSet","userPropertiesToSetOnce","propertyComparisons","exact","targets","is_not","every","not_regex","icontains","not_icontains","gt","numValue","isNaN","lt","matchPropertyFilters","propertyFilters","eventProperties","propertyName","eventPropertyValue","eventValues","comparisonFunction","operator","PostHogExceptions","_suppressionRules","_errorPropertiesBuilder","ErrorTracking","_response$errorTracki","_response$errorTracki2","_response$errorTracki3","suppressionRules","errorTracking","captureExtensionExceptions","_captureExtensionExceptions","enabled_server_side","enabled_client_side","buildProperties","metadata","_isExceptionList","_matchesSuppressionRule","_isExtensionException","__capturePostHogExceptions","_isPostHogException","_noTruncate","_batchKey","exceptionValues","$exception_types","$exception_values","rule","results","_exceptionValues$v$ke","compare","Boolean","flatMap","_e$stacktrace$frames","_e$stacktrace","startsWith","_exception$stacktrace","_exception$stacktrace2","_lastFrame$filename$i","_lastFrame$filename","lastFrame","forceDebugLogger","PERSISTENCE_ACTIVE_FEATURE_FLAGS","PERSISTENCE_OVERRIDE_FEATURE_FLAGS","PERSISTENCE_FEATURE_FLAG_PAYLOADS","PERSISTENCE_OVERRIDE_FEATURE_FLAG_PAYLOADS","PERSISTENCE_FEATURE_FLAG_REQUEST_ID","PERSISTENCE_FEATURE_FLAG_EVALUATED_AT","filterActiveFeatureFlags","featureFlags","activeFeatureFlags","normalizeFlagsResponse","flagDetails","fromEntries","flag","_flagDetails$flag$var","variant","enabled","featureFlagPayloads","_flagDetails$flag$met","payload","_flagDetails$flag$met2","QuotaLimitedResource","PostHogFeatureFlags","_override_warning","_hasLoadedFlags","_requestInFlight","_reloadingDisabled","_additionalReloadRequested","_flagsCalled","_flagsLoadedFromRemote","featureFlagEventHandlers","_getValidEvaluationEnvironments","envs","evaluation_environments","env","isValid","_shouldIncludeEvaluationEnvironments","flags","__preview_remote_config","disableFlags","_reloadDebouncer","advanced_disable_feature_flags","advanced_disable_feature_flags_on_first_load","_callFlagsEndpoint","hasLoadedFlags","getFlags","getFlagVariants","getFlagsWithDetails","overridenFlags","overriddenPayloads","finalDetails","overriddenKeys","_originalDetail$enabl","_originalDetail$metad","originalDetail","overrideFlagValue","finalEnabled","overrideVariant","overridePayload","overridenDetail","original_enabled","original_variant","original_payload","enabledFlags","overriddenFlags","finalFlags","getFlagPayloads","flagPayloads","finalPayloads","reloadFeatureFlags","_clearDebouncer","ensureFlagsLoaded","setAnonymousDistinctId","anon_distinct_id","$anon_distinct_id","setReloadingPaused","isPaused","deviceId","getGroups","person_properties","get_initial_props","group_properties","disable_flags","useRemoteConfigWithFlags","flagsRoute","queryParams","advanced_only_evaluate_survey_feature_flags","timezone","_send_request","disable_compression","feature_flag_request_timeout_ms","_response$json$quotaL","_response$json","errorsLoading","_onRemoteConfig","quotaLimited","FeatureFlags","_response$json2","receivedFeatureFlags","getFeatureFlag","flagValue","flagReportValue","requestId","evaluatedAt","flagCallReported","send_event","_flagDetails$metadata","_flagDetails$reason$d","_flagDetails$reason","_flagDetails$reason2","_flagDetails$metadata2","_flagDetails$metadata3","getFeatureFlagDetails","$feature_flag","$feature_flag_response","$feature_flag_payload","getFeatureFlagPayload","$feature_flag_request_id","$feature_flag_evaluated_at","$feature_flag_bootstrapped_response","bootstrap","$feature_flag_bootstrapped_payload","$used_bootstrap_value","$feature_flag_version","_flagDetails$metadata4","description","code","$feature_flag_reason","$feature_flag_id","$feature_flag_original_response","$feature_flag_original_payload","getRemoteConfigPayload","_response$json3","isFeatureEnabled","addFeatureFlagsHandler","removeFeatureFlagsHandler","h","currentFlags","currentFlagPayloads","currentFlagDetails","normalizedResponse","$enabled_feature_flags","newFeatureFlags","newFeatureFlagPayloads","newFeatureFlagDetails","errorsWhileComputingFlags","parseFlagsResponse","_fireFeatureFlagsCallbacks","override","suppressWarning","overrideFeatureFlags","overrideOptions","unregister","_options$suppressWarn","flagsObj","payloads","onFeatureFlags","flagVariants","_prepareFeatureFlagsForCallbacks","updateEarlyAccessFeatureEnrollment","isEnrolled","stage","_this$_instance$persi3","feature","flagKey","enrollmentPersonProp","$feature_enrollment","$set","setPersonPropertiesForFlags","newFlags","getEarlyAccessFeatures","force_reload","stages","existing_early_access_features","stageParams","_this$_instance$persi4","_this$_instance$persi5","earlyAccessFeatures","variantKey","existingProperties","resetPersonPropertiesForFlags","setGroupPropertiesForFlags","groupType","resetGroupPropertiesForFlags","group_type","CASE_INSENSITIVE_PERSISTENCE_TYPES","PostHogPersistence","isDisabled","_campaign_params_saved","_name","parseName","_buildStorage","debug","update_config","save","_disabled","localPlusCookieStore","customCookieProperties","cookiePropertiesToPersist","cookieProperties","_unused7","_unused8","cookiePersistedProperties","createLocalPlusCookieStore","storage_type","found","entry","_expire_days","_cross_subdomain","_secure","remove","clear","register_once","default_value","_default_expiry","hasChanges","update_campaign_params","custom_campaign_params","update_search_keyword","update_referrer_info","set_initial_person_info","initialReferrerInfo","personProps","initialPersonInfo","initialPersonProps","safe_merge","oldConfig","set_disabled","set_cross_subdomain","set_secure","isArrayContentsEqual","arr1","arr2","sortedArr1","sortedArr2","index","cookie_persisted_properties","newStore","set_event_timer","event_name","timers","remove_event_timer","to","PRODUCT_TOURS_STORAGE_KEY","PostHogProductTours","_productTourManager","_cachedTours","productTours","loadIfEnabled","_instance$persistence","disable_product_tours","_startProductTours","generateProductTours","getProductTours","forceReload","storedTours","tours","product_tours","getActiveProductTours","showProductTour","tourId","_this$_productTourMan","showTourById","previewTour","tour","_this$_productTourMan2","dismissProductTour","_this$_productTourMan3","dismissTour","nextStep","_this$_productTourMan4","previousStep","_this$_productTourMan5","clearCache","resetTour","_this$_productTourMan6","resetAllTours","_this$_productTourMan7","cancelPendingTour","_this$_productTourMan8","SurveyEventType","SurveyWidgetType","SurveyPosition","SurveyTabPosition","SurveyType","SurveyQuestionType","SurveyQuestionBranchingType","SurveySchedule","SurveyEventName","SurveyEventProperties","DisplaySurveyType","SURVEY_LOGGER","SURVEY_SEEN_PREFIX","getSurveyInteractionProperty","survey","action","surveyProperty","current_iteration","getSurveySeenKey","getSurveyStorageKey","IN_APP_SURVEY_TYPES","Popover","Widget","API","DEFAULT_DISPLAY_SURVEY_OPTIONS","ignoreConditions","ignoreDelay","displayType","SimpleEventEmitter","_events","on","listener","emit","matchString","matching","likePattern","ActionMatcher","_debugEventEmitter","_checkStep","step","_checkStepEvent","_checkStepUrl","_checkStepElement","_checkStepProperties","_actionEvents","_actionRegistry","init","_this$_instance","_addCaptureHook","_this$_instance2","matchEventToAction","eventPayload","actions","_this$_instance3","_this$_instance4","_this$_actionRegistry","_action$steps","steps","_this$_actionEvents","_this$_instance5","selectorsToWatch","_action$steps2","_this$_actionRegistry2","_checkAction","_addActionHook","onAction","_event$properties","eventUrl","url_matching","_checkStepHref","_checkStepText","_checkStepSelector","_event$properties2","_getElementsList","href_matching","chain","_event$properties3","text_matching","texts","elementsChain","extractTexts","_event$properties4","_event$properties5","$element_selectors","selector_regex","_event$properties6","EventReceiver","_eventToItems","Map","_cancelEventToItems","_actionToItems","_doesEventMatchFilter","eventConfig","_buildEventToItemMap","items","conditionField","_item$conditions","conditions","existing","get","_getMatchingItems","itemIds","Activation","_getItems","allItems","_item$conditions2","_setupEventBasedItems","_setupActionBasedItems","actionBasedItems","_item$conditions3","_item$conditions4","_actionMatcher","actionName","_item$conditions5","_item$conditions6","_item$conditions7","_this$_actionMatcher","_item$conditions8","knownItems","eventBasedItems","_item$conditions9","_item$conditions0","events","itemsWithCancelEvents","_item$conditions1","_item$conditions10","cancelEvents","matchEventToItem","onEvent","Cancellation","_getLogger","activatedKey","_getActivatedKey","shownEventName","_getShownEventName","existingActivatedItems","_eventPayload$propert","_eventPayload$propert2","itemId","$survey_id","$product_tour_id","splice","_updateActivatedItems","itemsToCancel","_cancelPendingItem","matchedItems","activatedItems","eligibleItems","_isItemPermanentlyIneligible","getActivatedIds","_this$_instance6","getEventToItemsMap","_getActionMatcher","SurveyEventReceiver","super","SHOWN","getSurveys","cancelPendingSurvey","getEventToSurveys","PostHogSurveys","_isSurveysEnabled","_surveyManager","_isInitializingSurveys","_surveyCallbacks","_getSurveysInFlightPromise","_surveyEventReceiver","disable_surveys","surveys","isArrayResponse","surveyKeys","phExtensions","advanced_enable_surveys","isSurveysEnabled","generateSurveys","_completeSurveyInitialization","_handleSurveyLoadError","generateSurveysFn","_notifySurveyCallbacks","onSurveysLoaded","resolvePromise","existingSurveys","context","surveys_request_timeout_ms","_this$_surveyEventRec","eventOrActionBasedSurveys","start_date","end_date","isSurveyRunning","_survey$conditions","doesSurveyActivateByEvent","_survey$conditions2","doesSurveyActivateByAction","getActiveMatchingSurveys","_getSurveyById","surveyId","_surveys$find","_checkSurveyEligibility","eligible","checkSurveyEligibility","canRenderSurvey","visible","disabledReason","eligibility","canRenderSurveyAsync","_surveys$find2","renderSurvey","_survey$appearance","querySelector","appearance","surveyPopupDelaySeconds","_survey$appearance2","_this$_surveyManager","displaySurvey","_survey$appearance3","surveyToDisplay","canRender","Inline","handlePopoverSurvey","cancelSurvey","handlePageUnload","_this$_surveyManager2","PostHogConversations","_isConversationsEnabled","_conversationsManager","_isInitializing","_remoteConfig","disable_conversations","conversations","_this$_conversationsM","initConversations","_completeInitialization","_handleLoadError","initConversationsFn","show","hide","isAvailable","isVisible","_this$_conversationsM2","_this$_conversationsM3","sendMessage","userTraits","newTicket","getMessages","ticketId","after","markAsRead","_this3","getTickets","_this4","getCurrentTicketId","_this$_conversationsM4","_this$_conversationsM5","getWidgetSessionId","_this$_conversationsM6","_this$_conversationsM7","RateLimiter","_instance$config$rate","_instance$config$rate2","serverLimits","lastEventRateLimited","checkForLimiting","httpResponse","quota_limited","batchKey","captureEventsPerSecond","rate_limiting","events_per_second","captureEventsBurstLimit","events_burst_limit","clientRateLimitContext","isRateLimited","checkOnly","_this$instance$persis2","_this$instance$persis3","last","$$client_ingestion_warning_message","skip_client_rate_limiting","remainingTokens","isServerRateLimited","retryAfter","RemoteConfigLoader","remoteConfig","_assignableWindow$_PO","_POSTHOG_REMOTE_CONFIG","_loadRemoteConfigJs","_loadRemoteConfigJSON","hasFeatureFlags","DEFAULT_FLUSH_INTERVAL_MS","RequestQueue","sendRequest","_isPaused","_queue","_flushTimeoutMs","flush_interval_ms","_sendRequest","enqueue","_flushTimeout","_setFlushTimeout","unload","_clearFlushTimeout","requests","_formatQueue","requestValues","enable","request","_requests$key$data","RetryQueue","_isPolling","_pollIntervalMs","_areWeOnline","onLine","_onlineListener","_offlineListener","retriableRequest","retriesPerformedSoFar","_objectWithoutPropertiesLoose","_excluded","retry_count","_enqueue","requestOptions","msToNextRetry","rawBackoffTime","minBackoff","cappedBackoffTime","jitter","pickNextRetryDelay","retryAt","logMessage","_poll","_poller","notToFlush","toFlush","ScrollManager","_updateScrollData","_this$_context$maxScr","_this$_context$maxScr2","_this$_context$maxCon","_this$_context$maxCon2","_context","scrollHeight","clientHeight","contentY","contentHeight","startMeasuringScrollPosition","scroll_root_selector","documentElement","scrollTop","pageYOffset","scrollLeft","pageXOffset","generateSessionSourceParams","SessionPropsManager","sessionIdManager","sessionSourceParamGenerator","_onSessionIdCallback","stored","_getStored","newProps","_sessionSourceParamGenerator","_persistence","_sessionIdManager","getSetOnceProps","_this$_getStored","referringDomain","initialPathName","utm_source","utm_campaign","utm_medium","utm_content","utm_term","getSessionProps","SessionIdManager","_eventEmitter","sessionIdGenerator","windowIdGenerator","_this$_config$bootstr","_sessionIdChangedHandlers","_beforeUnloadListener","_sessionHasBeenIdleTooLong","lastActivityTimestamp","sessionTimeoutMs","_sessionId","_sessionStartTimestamp","_sessionActivityTimestamp","_sessionIdGenerator","_windowIdGenerator","persistenceName","desiredTimeout","_sessionTimeoutMs","$configured_session_timeout_ms","_resetIdleTimer","_window_id_storage_key","_primary_window_exists_storage_key","_canUseSessionStorage","lastWindowId","primaryWindowExists","sessionID","sessionStartTimestamp","uuid","hex","parseInt","uuid7ToTimestampMs","_setSessionId","_listenToReloadWindow","_setWindowId","_getWindowId","sessionActivityTimestamp","_getSessionId","sessionIdInfo","resetSessionId","_enforceIdleTimeout","readOnly","startTimestamp","valuesChanged","newActivityTimestamp","idleSessionId","SiteApps","_bufferedInvocations","apps","opt_in_site_apps","_eventCollector","_eventName","globals","globalsForEvent","siteAppLoaders","siteApps","_stopBuffering","_event$properties$$se","_event$properties$$se2","_event$properties$$el","groupIds","groupProperties","$set_once","elements_chain","person","setupSiteApp","loader","app","processBufferedEvents","_this$_stopBuffering","errored","processEvent","processedBuffer","hasInitReturned","onLoaded","success","loaded","_setupSiteApps","_onCapturedEvent","_this$siteAppLoaders","_this$_stopBuffering2","_response$siteApps","isLikelyBot","isBlockedUACore","uaData","userAgentData","brands","brandObj","brand","webdriver","RequestRouterRegion","ingestionDomain","RequestRouter","_regionCache","apiHost","api_host","flagsApiHost","customHost","flags_api_host","uiHost","_this$instance$config","ui_host","US","EU","CUSTOM","path","suffix","webExperimentUrlValidationMap","conditionsUrl","WebExperiments","getWebExperimentsAndEvaluateDisplayLogic","getWebExperiments","webExperiments","_logInfo","_flagToExperiments","webExperiment","feature_flag_key","_this$_flagToExperime","selectedVariant","variants","_applyTransforms","transforms","testVariant","_matchesTestVariant","_is_bot","disable_web_experiments","previewWebExperiment","_this$_flagToExperime2","_this$_flagToExperime3","getWindowLocation","experimentID","_showPreviewWebExperiment","previewing","existingWebExperiments","experiments","previewExperiments","exp","_matchUrlConditions","_matchUTMConditions","_testVariant$conditio","_testVariant$conditio2","_testVariant$conditio3","_testVariant$conditio4","urlMatchType","_testVariant$conditio5","utm","_testVariant$conditio6","_testVariant$conditio7","_testVariant$conditio8","_testVariant$conditio9","_testVariant$conditio0","_testVariant$conditio1","_testVariant$conditio10","_testVariant$conditio11","utmCampaignMatched","utmSourceMatched","utmMediumMatched","utmTermMatched","experiment","transform","_document","htmlElement","html","innerHTML","css","setAttribute","custom_blocked_useragents","MAPPED_INTEGRATIONS","intercom","crispChat","ExternalIntegrations","_assignableWindow$__P5","integrations","LOGGER_PREFIX","SessionRecording","started","_this$_lazyLoadedSess","_lazyLoadedSessionRecording","isStarted","_receivedFlags","_isRecordingEnabled","_forceAllowLocalhostNetworkCapture","_persistFlagsOnSessionListener","_this$_instance$get_p","disable_session_recording","startReason","_this$_lazyLoadedSess2","canRunReplay","_lazyLoadAndStart","stopRecording","rrweb","record","initSessionRecording","_onScriptLoaded","_scriptName","_this$_persistFlagsOn","_this$_lazyLoadedSess3","_resetSampling","_persistRemoteConfig","_this$_persistFlagsOn2","persistResponse","sessionRecordingConfigResponse","sessionRecording","receivedSampleRate","sampleRate","parsedSampleRate","receivedMinimumDuration","minimumDurationMilliseconds","networkPayloadCapture","canvasRecording","recordCanvas","fps","canvasFps","quality","canvasQuality","endpoint","triggerMatchType","masking","urlTriggers","_this$_lazyLoadedSess4","_remoteConfig$scriptC","scriptConfig","script","onRRwebEmit","rawEvent","_this$_lazyLoadedSess5","overrideLinkedFlag","_this$_lazyLoadedSess6","$replay_override_linked_flag","overrideSampling","_this$_lazyLoadedSess7","$replay_override_sampling","overrideTrigger","triggerType","_this$_lazyLoadedSess8","sdkDebugProperties","_this$_lazyLoadedSess9","$recording_status","tryAddCustomEvent","_this$_lazyLoadedSess0","instances","__NOOP","PRIMARY_INSTANCE_NAME","ENQUEUE_REQUESTS","defaultConfig","defaults","persistence_name","save_campaign_params","save_referrer","capture_pageleave","__preview_deferred_init_extensions","upgrade","disable_persistence","disable_surveys_automatic_display","enable_recording_console_log","ip","opt_out_persistence_by_default","opt_out_useragent_filter","property_denylist","sanitize_properties","request_headers","request_batching","properties_string_max_length","advanced_disable_flags","advanced_disable_decide","on_request_error","session_idle_timeout_seconds","person_profiles","before_send","request_queue_config","_onCapture","__preview_eager_load_replay","session_recording","strictMinimumDuration","defaultsThatVaryByConfig","configRenames","origConfig","renames","process_person","xhr_headers","cookie_name","disable_cookie","store_google","verbose","newConfig","property_blacklist","DeprecatedWebPerformanceObserver","__forceAllowLocalhost","_forceAllowLocalhost","PostHog","decideEndpointWasHit","_this$featureFlags$ha","_this$featureFlags","flagsEndpointWasHit","_this$featureFlags$ha2","_this$featureFlags2","webPerformance","_personProcessingSetOncePropertiesSent","_internalEventEmitter","_calculate_event_properties","sentryIntegration","processor","__request_queue","analyticsDefaultEndpoint","_initialPageviewCaptured","_visibilityStateListener","_initialPersonProfilesConfig","_cachedPersonProperties","toolbar","pageViewManager","rateLimiter","externalIntegrations","people","setProps","setPersonProperties","set_once","_instances$name","namedPosthog","_init","_config$bootstrap","_checkLocalStorageForDebug","_originalUserConfig","_triggered_notifs","set_config","on_xhr_error","persistenceDisabled","_is_persistence_disabled","sessionPersistence","initialPersistenceProps","initialSessionProps","$initialization_time","toISOString","_requestQueue","_send_retriable_request","_retryQueue","startInCookielessMode","sessionPropsManager","_initExtensions","thisC","distinctID","_config$bootstrap2","_config$bootstrap3","deviceID","isIdentifiedID","_hasBootstrappedFeatureFlags","_config$bootstrap4","_config$bootstrap7","activeFlags","_config$bootstrap5","_config$bootstrap6","_config$bootstrap8","_config$bootstrap9","_handle_unload","_loaded","initStartTime","performance","historyAutocapture","initTasks","_this$siteApps","heatmaps","webVitalsAutocapture","exceptionObserver","deadClicksAutocapture","_pendingRemoteConfig","_processInitTaskQueue","queue","task","shift","taskInitTiming","round","register_for_session","$sdk_debug_extensions_init_method","$sdk_debug_extensions_init_time_ms","_config$analytics","_this$siteApps2","_this$sessionRecordin","_this$autocapture","_this$heatmaps","_this$productTours","_this$webVitalsAutoca","_this$exceptionObserv","_this$deadClicksAutoc","supportedCompression","analytics","_start_queue_if_opted_in","_captureInitialPageview","_this$_requestQueue","is_capturing","_dom_loaded","_this$_requestQueue2","_this$_retryQueue","_shouldCapturePageleave","api_transport","__preview_disable_xhr_credentials","__preview_disable_beacon","disableTransport","fetch_options","_options","_options$transport","_find$method","_find","ver","availableTransports","transportMethod","_this$config$on_reque","_this$config","_execute_array","array","fn_name","alias_calls","other_calls","capturing_calls","execute","calls","caller","_this$config$bootstra","_this$config$bootstra2","_options$_url","isBot","__preview_capture_bot_pageviews","systemTime","$browser_type","markSetOnceAsSent","setOnceProperties","_calculate_set_once_properties","DISMISSED","SENT","SURVEY_ID","surveyIteration","SURVEY_ITERATION","SURVEY_LAST_SEEN_DATE","finalSet","beforeSendResult","_runBeforeSend","_url","send_instantly","persistenceProps","pageviewProperties","infoProperties","_this$_retryQueue2","duration_in_ms","toFixed","_isIdentified","denylisted_prop","hasPersonProcessing","_hasPersonProcessing","_requirePersonProcessing","dataSetOnce","markAsSent","_this$sessionPropsMan","initialProps","sessionProps","_this$persistence","_this$persistence2","_this$sessionPersiste","property","_this$persistence3","unregister_for_session","_this$sessionPersiste2","_register_single","updateFlags","existingFlags","merge","existingPayloads","isVariant","_this$sessionManager$","_this$sessionManager","new_distinct_id","previous_distinct_id","$user_id","device_id","$had_persisted_distinct_id","isKnownAnonymous","group","groupKey","groupPropertiesToSet","existingGroups","$groups","$group_type","$group_key","$group_set","resetGroups","reset_device_id","_this$persistence4","_this$sessionPersiste3","_this$persistence5","_this$sessionManager2","$last_posthog_reset","get_session_id","_this$sessionManager$2","_this$sessionManager3","_options$timestampLoo","LOOK_BACK","timestampLookBack","alias","_this$persistence6","_this$exceptionObserv2","_this$sessionRecordin2","_this$autocapture2","_this$heatmaps2","_this$exceptionObserv3","_this$externalIntegra","isPersistenceDisabled","debugConfigFromLocalStorage","_sync_opt_out_with_persistence","startSessionRecording","overrideAll","overrideConfig","sampling","linked_flag","url_trigger","event_trigger","_this$sessionManager4","_this$sessionRecordin3","_this$sessionRecordin4","_this$sessionRecordin5","_this$sessionRecordin6","stopSessionRecording","_this$sessionRecordin7","errorToProperties","startExceptionAutocapture","stopExceptionAutocapture","property_name","_this$persistence7","getSessionProperty","_this$sessionPersiste4","_this$config$name","_this$persistence8","_this$sessionPersiste5","_this$persistence9","_this$persistence0","createPersonProfile","function_name","defaultPersistenceDisabled","_this$persistence1","_this$sessionPersiste6","_this$persistence10","_this$sessionPersiste7","opt_in_capturing","_this$sessionRecordin8","_this$sessionManager5","_this$pageViewManager","_options$captureEvent","captureEventName","captureProperties","opt_out_capturing","_this$sessionManager6","_this$pageViewManager2","_this$sessionRecordin9","has_opted_in_capturing","has_opted_out_capturing","get_explicit_consent_status","clear_opt_in_out_capturing","newField","oldField","defaultValue","loggerInstance","hasNewField","hasOldField","originalConfig","fns","getPageViewId","_this$pageViewManager3","captureTraceFeedback","traceId","userFeedback","$ai_trace_id","$ai_feedback_text","captureTraceMetric","metricName","metricValue","$ai_metric_name","$ai_metric_value","debugConfig","explicitlyFalse","isTrueInLocalStorage","klass","functions","safewrapClass","posthogMain","DEFAULT_PRODUCT_TOUR_APPEARANCE","backgroundColor","textColor","buttonColor","borderRadius","buttonBorderRadius","borderColor","fontFamily","boxShadow","showOverlay","whiteLabel","dom_loaded_handler","inst","add_dom_loaded_handler"],"mappings":"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","x_google_ignoreList":[52]}
1
+ {"version":3,"file":"module.js","sources":["../src/utils/globals.ts","../src/config.ts","../../core/dist/utils/bot-detection.mjs","../../core/dist/types.mjs","../../core/dist/utils/string-utils.mjs","../../core/dist/utils/type-utils.mjs","../../core/dist/utils/number-utils.mjs","../../core/dist/utils/bucketed-rate-limiter.mjs","../../core/dist/utils/user-agent-utils.mjs","../../core/dist/error-tracking/chunk-ids.mjs","../../core/dist/utils/index.mjs","../../core/dist/error-tracking/error-properties-builder.mjs","../../core/dist/error-tracking/parsers/base.mjs","../../core/dist/error-tracking/parsers/safari.mjs","../../core/dist/error-tracking/parsers/chrome.mjs","../../core/dist/error-tracking/parsers/gecko.mjs","../../core/dist/error-tracking/parsers/index.mjs","../../core/dist/error-tracking/coercers/dom-exception-coercer.mjs","../../core/dist/error-tracking/coercers/error-coercer.mjs","../../core/dist/error-tracking/coercers/error-event-coercer.mjs","../../core/dist/error-tracking/coercers/string-coercer.mjs","../../core/dist/error-tracking/types.mjs","../../core/dist/error-tracking/coercers/utils.mjs","../../core/dist/error-tracking/coercers/object-coercer.mjs","../../core/dist/error-tracking/coercers/event-coercer.mjs","../../core/dist/error-tracking/coercers/primitive-coercer.mjs","../../core/dist/error-tracking/coercers/promise-rejection-event.mjs","../src/utils/logger.ts","../src/entrypoints/external-scripts-loader.ts","../src/utils/index.ts","../src/constants.ts","../src/utils/element-utils.ts","../src/autocapture-utils.ts","../src/extensions/rageclick.ts","../src/utils/request-utils.ts","../src/autocapture.ts","../src/uuidv7.ts","../src/storage.ts","../src/consent.ts","../src/extensions/dead-clicks-autocapture.ts","../src/extensions/exception-autocapture/index.ts","../src/extensions/replay/rrweb-plugins/patch.ts","../src/extensions/history-autocapture.ts","../src/extensions/segment-integration.ts","../src/extensions/sentry-integration.ts","../src/extensions/toolbar.ts","../src/extensions/tracing-headers.ts","../src/utils/event-utils.ts","../src/extensions/web-vitals/index.ts","../src/heatmaps.ts","../src/page-view.ts","../src/types.ts","../../../node_modules/.pnpm/fflate@0.4.8/node_modules/fflate/esm/browser.js","../src/utils/encode-utils.ts","../src/request.ts","../src/utils/regex-utils.ts","../src/utils/property-utils.ts","../src/posthog-exceptions.ts","../src/posthog-featureflags.ts","../src/posthog-persistence.ts","../src/posthog-product-tours.ts","../src/posthog-surveys-types.ts","../src/utils/survey-utils.ts","../src/utils/simple-event-emitter.ts","../src/utils/elements-chain-utils.ts","../src/extensions/surveys/action-matcher.ts","../src/utils/event-receiver.ts","../src/utils/survey-event-receiver.ts","../src/posthog-surveys.ts","../src/extensions/conversations/posthog-conversations.ts","../src/rate-limiter.ts","../src/remote-config.ts","../src/request-queue.ts","../src/retry-queue.ts","../src/scroll-manager.ts","../src/session-props.ts","../src/sessionid.ts","../src/site-apps.ts","../src/utils/blocked-uas.ts","../src/utils/request-router.ts","../src/web-experiments.ts","../src/extensions/external-integration.ts","../src/extensions/replay/external/triggerMatching.ts","../src/extensions/replay/session-recording.ts","../src/posthog-core.ts","../src/posthog-product-tours-types.ts","../src/entrypoints/module.no-external.es.ts"],"sourcesContent":["import type { PostHog } from '../posthog-core'\nimport { SessionIdManager } from '../sessionid'\nimport {\n DeadClicksAutoCaptureConfig,\n ExternalIntegrationKind,\n Properties,\n RemoteConfig,\n SiteAppLoader,\n SessionStartReason,\n} from '../types'\nimport type {\n ConversationsRemoteConfig,\n GetMessagesResponse,\n GetTicketsOptions,\n GetTicketsResponse,\n MarkAsReadResponse,\n SendMessageResponse,\n UserProvidedTraits,\n} from '../posthog-conversations-types'\n// only importing types here, so won't affect the bundle\n// eslint-disable-next-line posthog-js/no-external-replay-imports\nimport type { SessionRecordingStatus, TriggerType } from '../extensions/replay/external/triggerMatching'\nimport { eventWithTime } from '../extensions/replay/types/rrweb-types'\nimport { ErrorTracking } from '@posthog/core'\n\n/*\n * Global helpers to protect access to browser globals in a way that is safer for different targets\n * like DOM, SSR, Web workers etc.\n *\n * NOTE: Typically we want the \"window\" but globalThis works for both the typical browser context as\n * well as other contexts such as the web worker context. Window is still exported for any bits that explicitly require it.\n * If in doubt - export the global you need from this file and use that as an optional value. This way the code path is forced\n * to handle the case where the global is not available.\n */\n\n// eslint-disable-next-line no-restricted-globals\nconst win: (Window & typeof globalThis) | undefined = typeof window !== 'undefined' ? window : undefined\n\nexport type AssignableWindow = Window &\n typeof globalThis & {\n /*\n * Main PostHog instance\n */\n posthog: any\n\n /*\n * This is our contract between (potentially) lazily loaded extensions and the SDK\n */\n __PosthogExtensions__?: PostHogExtensions\n\n /**\n * When loading remote config, we assign it to this global configuration\n * for ease of sharing it with the rest of the SDK\n */\n _POSTHOG_REMOTE_CONFIG?: Record<\n string,\n {\n config: RemoteConfig\n siteApps: SiteAppLoader[]\n }\n >\n\n /**\n * If this is set on the window, our logger will log to the console\n * for ease of debugging. Used for testing purposes only.\n *\n * @see {Config.DEBUG} from config.ts\n */\n POSTHOG_DEBUG: any\n\n // Exposed by the browser\n doNotTrack: any\n\n // See entrypoints/customizations.full.ts\n posthogCustomizations: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/exception-autocapture.ts\n *\n * @deprecated use `__PosthogExtensions__.errorWrappingFunctions` instead\n */\n posthogErrorWrappingFunctions: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/posthog-recorder.ts\n *\n * @deprecated use `__PosthogExtensions__.rrweb` instead\n */\n rrweb: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/posthog-recorder.ts\n *\n * @deprecated use `__PosthogExtensions__.rrwebConsoleRecord` instead\n */\n rrwebConsoleRecord: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/posthog-recorder.ts\n *\n * @deprecated use `__PosthogExtensions__.getRecordNetworkPlugin` instead\n */\n getRecordNetworkPlugin: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/web-vitals.ts\n *\n * @deprecated use `__PosthogExtensions__.postHogWebVitalsCallbacks` instead\n */\n postHogWebVitalsCallbacks: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/tracing-headers.ts\n *\n * @deprecated use `__PosthogExtensions__.postHogTracingHeadersPatchFns` instead\n */\n postHogTracingHeadersPatchFns: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/surveys.ts\n *\n * @deprecated use `__PosthogExtensions__.generateSurveys` instead\n */\n extendPostHogWithSurveys: any\n\n /*\n * These are used to handle our toolbar state.\n * @see {Toolbar} from extensions/toolbar.ts\n */\n ph_load_toolbar: any\n ph_load_editor: any\n ph_toolbar_state: any\n } & Record<`__$$ph_site_app_${string}`, any>\n\n/**\n * This is our contract between (potentially) lazily loaded extensions and the SDK\n * changes to this interface can be breaking changes for users of the SDK\n */\n\nexport type ExternalExtensionKind = 'intercom-integration' | 'crisp-chat-integration'\n\nexport type PostHogExtensionKind =\n | 'toolbar'\n | 'exception-autocapture'\n | 'web-vitals'\n | 'recorder'\n | 'lazy-recorder'\n | 'tracing-headers'\n | 'surveys'\n | 'conversations'\n | 'product-tours'\n | 'dead-clicks-autocapture'\n | 'remote-config'\n | ExternalExtensionKind\n\nexport interface LazyLoadedSessionRecordingInterface {\n start: (startReason?: SessionStartReason) => void\n stop: () => void\n sessionId: string\n status: SessionRecordingStatus\n onRRwebEmit: (rawEvent: eventWithTime) => void\n log: (message: string, level: 'log' | 'warn' | 'error') => void\n sdkDebugProperties: Properties\n overrideLinkedFlag: () => void\n overrideSampling: () => void\n overrideTrigger: (triggerType: TriggerType) => void\n isStarted: boolean\n tryAddCustomEvent(tag: string, payload: any): boolean\n}\n\nexport interface LazyLoadedDeadClicksAutocaptureInterface {\n start: (observerTarget: Node) => void\n stop: () => void\n}\n\nexport interface LazyLoadedConversationsInterface {\n // Widget control\n show: () => void\n hide: () => void\n isVisible: () => boolean\n\n // Lifecycle\n reset: () => void\n\n // API methods\n sendMessage: (message: string, userTraits?: UserProvidedTraits, newTicket?: boolean) => Promise<SendMessageResponse>\n getMessages: (ticketId?: string, after?: string) => Promise<GetMessagesResponse>\n markAsRead: (ticketId?: string) => Promise<MarkAsReadResponse>\n getTickets: (options?: GetTicketsOptions) => Promise<GetTicketsResponse>\n getCurrentTicketId: () => string | null\n getWidgetSessionId: () => string\n}\n\ninterface PostHogExtensions {\n loadExternalDependency?: (\n posthog: PostHog,\n kind: PostHogExtensionKind,\n callback: (error?: string | Event, event?: Event) => void\n ) => void\n\n loadSiteApp?: (posthog: PostHog, appUrl: string, callback: (error?: string | Event, event?: Event) => void) => void\n\n errorWrappingFunctions?: {\n wrapOnError: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void\n wrapUnhandledRejection: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void\n wrapConsoleError: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void\n }\n rrweb?: { record: any; version: string }\n rrwebPlugins?: { getRecordConsolePlugin: any; getRecordNetworkPlugin?: any }\n generateSurveys?: (posthog: PostHog, isSurveysEnabled: boolean) => any | undefined\n generateProductTours?: (posthog: PostHog, isEnabled: boolean) => any | undefined\n postHogWebVitalsCallbacks?: {\n onLCP: (metric: any) => void\n onCLS: (metric: any) => void\n onFCP: (metric: any) => void\n onINP: (metric: any) => void\n }\n tracingHeadersPatchFns?: {\n _patchFetch: (hostnames: string[], distinctId: string, sessionManager?: SessionIdManager) => () => void\n _patchXHR: (hostnames: string[], distinctId: string, sessionManager?: SessionIdManager) => () => void\n }\n initDeadClicksAutocapture?: (\n ph: PostHog,\n config: DeadClicksAutoCaptureConfig\n ) => LazyLoadedDeadClicksAutocaptureInterface\n integrations?: {\n [K in ExternalIntegrationKind]?: { start: (posthog: PostHog) => void; stop: () => void }\n }\n initSessionRecording?: (ph: PostHog) => LazyLoadedSessionRecordingInterface\n initConversations?: (config: ConversationsRemoteConfig, posthog: PostHog) => LazyLoadedConversationsInterface\n}\n\nconst global: typeof globalThis | undefined = typeof globalThis !== 'undefined' ? globalThis : win\n\n// React Native polyfills for posthog-js compatibility\nif (typeof self === 'undefined') {\n ;(global as any).self = global\n}\nif (typeof File === 'undefined') {\n ;(global as any).File = function () {}\n}\n\nexport const ArrayProto = Array.prototype\nexport const nativeForEach = ArrayProto.forEach\nexport const nativeIndexOf = ArrayProto.indexOf\n\nexport const navigator = global?.navigator\nexport const document = global?.document\nexport const location = global?.location\nexport const fetch = global?.fetch\nexport const XMLHttpRequest =\n global?.XMLHttpRequest && 'withCredentials' in new global.XMLHttpRequest() ? global.XMLHttpRequest : undefined\nexport const AbortController = global?.AbortController\nexport const userAgent = navigator?.userAgent\nexport const assignableWindow: AssignableWindow = win ?? ({} as any)\n\nexport { win as window }\n","import packageInfo from '../package.json'\n\n// overridden in posthog-core,\n// e.g. Config.DEBUG = Config.DEBUG || instance.config.debug\nconst Config = {\n DEBUG: false,\n LIB_VERSION: packageInfo.version,\n}\n\nexport default Config\n","const DEFAULT_BLOCKED_UA_STRS = [\n 'amazonbot',\n 'amazonproductbot',\n 'app.hypefactors.com',\n 'applebot',\n 'archive.org_bot',\n 'awariobot',\n 'backlinksextendedbot',\n 'baiduspider',\n 'bingbot',\n 'bingpreview',\n 'chrome-lighthouse',\n 'dataforseobot',\n 'deepscan',\n 'duckduckbot',\n 'facebookexternal',\n 'facebookcatalog',\n 'http://yandex.com/bots',\n 'hubspot',\n 'ia_archiver',\n 'leikibot',\n 'linkedinbot',\n 'meta-externalagent',\n 'mj12bot',\n 'msnbot',\n 'nessus',\n 'petalbot',\n 'pinterest',\n 'prerender',\n 'rogerbot',\n 'screaming frog',\n 'sebot-wa',\n 'sitebulb',\n 'slackbot',\n 'slurp',\n 'trendictionbot',\n 'turnitin',\n 'twitterbot',\n 'vercel-screenshot',\n 'vercelbot',\n 'yahoo! slurp',\n 'yandexbot',\n 'zoombot',\n 'bot.htm',\n 'bot.php',\n '(bot;',\n 'bot/',\n 'crawler',\n 'ahrefsbot',\n 'ahrefssiteaudit',\n 'semrushbot',\n 'siteauditbot',\n 'splitsignalbot',\n 'gptbot',\n 'oai-searchbot',\n 'chatgpt-user',\n 'perplexitybot',\n 'better uptime bot',\n 'sentryuptimebot',\n 'uptimerobot',\n 'headlesschrome',\n 'cypress',\n 'google-hoteladsverifier',\n 'adsbot-google',\n 'apis-google',\n 'duplexweb-google',\n 'feedfetcher-google',\n 'google favicon',\n 'google web preview',\n 'google-read-aloud',\n 'googlebot',\n 'googleother',\n 'google-cloudvertexbot',\n 'googleweblight',\n 'mediapartners-google',\n 'storebot-google',\n 'google-inspectiontool',\n 'bytespider'\n];\nconst isBlockedUA = function(ua, customBlockedUserAgents = []) {\n if (!ua) return false;\n const uaLower = ua.toLowerCase();\n return DEFAULT_BLOCKED_UA_STRS.concat(customBlockedUserAgents).some((blockedUA)=>{\n const blockedUaLower = blockedUA.toLowerCase();\n return -1 !== uaLower.indexOf(blockedUaLower);\n });\n};\nexport { DEFAULT_BLOCKED_UA_STRS, isBlockedUA };\n","var types_PostHogPersistedProperty = /*#__PURE__*/ function(PostHogPersistedProperty) {\n PostHogPersistedProperty[\"AnonymousId\"] = \"anonymous_id\";\n PostHogPersistedProperty[\"DistinctId\"] = \"distinct_id\";\n PostHogPersistedProperty[\"Props\"] = \"props\";\n PostHogPersistedProperty[\"FeatureFlagDetails\"] = \"feature_flag_details\";\n PostHogPersistedProperty[\"FeatureFlags\"] = \"feature_flags\";\n PostHogPersistedProperty[\"FeatureFlagPayloads\"] = \"feature_flag_payloads\";\n PostHogPersistedProperty[\"BootstrapFeatureFlagDetails\"] = \"bootstrap_feature_flag_details\";\n PostHogPersistedProperty[\"BootstrapFeatureFlags\"] = \"bootstrap_feature_flags\";\n PostHogPersistedProperty[\"BootstrapFeatureFlagPayloads\"] = \"bootstrap_feature_flag_payloads\";\n PostHogPersistedProperty[\"OverrideFeatureFlags\"] = \"override_feature_flags\";\n PostHogPersistedProperty[\"Queue\"] = \"queue\";\n PostHogPersistedProperty[\"OptedOut\"] = \"opted_out\";\n PostHogPersistedProperty[\"SessionId\"] = \"session_id\";\n PostHogPersistedProperty[\"SessionStartTimestamp\"] = \"session_start_timestamp\";\n PostHogPersistedProperty[\"SessionLastTimestamp\"] = \"session_timestamp\";\n PostHogPersistedProperty[\"PersonProperties\"] = \"person_properties\";\n PostHogPersistedProperty[\"GroupProperties\"] = \"group_properties\";\n PostHogPersistedProperty[\"InstalledAppBuild\"] = \"installed_app_build\";\n PostHogPersistedProperty[\"InstalledAppVersion\"] = \"installed_app_version\";\n PostHogPersistedProperty[\"SessionReplay\"] = \"session_replay\";\n PostHogPersistedProperty[\"SurveyLastSeenDate\"] = \"survey_last_seen_date\";\n PostHogPersistedProperty[\"SurveysSeen\"] = \"surveys_seen\";\n PostHogPersistedProperty[\"Surveys\"] = \"surveys\";\n PostHogPersistedProperty[\"RemoteConfig\"] = \"remote_config\";\n PostHogPersistedProperty[\"FlagsEndpointWasHit\"] = \"flags_endpoint_was_hit\";\n return PostHogPersistedProperty;\n}({});\nvar types_Compression = /*#__PURE__*/ function(Compression) {\n Compression[\"GZipJS\"] = \"gzip-js\";\n Compression[\"Base64\"] = \"base64\";\n return Compression;\n}({});\nvar types_SurveyPosition = /*#__PURE__*/ function(SurveyPosition) {\n SurveyPosition[\"TopLeft\"] = \"top_left\";\n SurveyPosition[\"TopCenter\"] = \"top_center\";\n SurveyPosition[\"TopRight\"] = \"top_right\";\n SurveyPosition[\"MiddleLeft\"] = \"middle_left\";\n SurveyPosition[\"MiddleCenter\"] = \"middle_center\";\n SurveyPosition[\"MiddleRight\"] = \"middle_right\";\n SurveyPosition[\"Left\"] = \"left\";\n SurveyPosition[\"Right\"] = \"right\";\n SurveyPosition[\"Center\"] = \"center\";\n return SurveyPosition;\n}({});\nvar types_SurveyWidgetType = /*#__PURE__*/ function(SurveyWidgetType) {\n SurveyWidgetType[\"Button\"] = \"button\";\n SurveyWidgetType[\"Tab\"] = \"tab\";\n SurveyWidgetType[\"Selector\"] = \"selector\";\n return SurveyWidgetType;\n}({});\nvar types_SurveyType = /*#__PURE__*/ function(SurveyType) {\n SurveyType[\"Popover\"] = \"popover\";\n SurveyType[\"API\"] = \"api\";\n SurveyType[\"Widget\"] = \"widget\";\n SurveyType[\"ExternalSurvey\"] = \"external_survey\";\n return SurveyType;\n}({});\nvar types_SurveyQuestionDescriptionContentType = /*#__PURE__*/ function(SurveyQuestionDescriptionContentType) {\n SurveyQuestionDescriptionContentType[\"Html\"] = \"html\";\n SurveyQuestionDescriptionContentType[\"Text\"] = \"text\";\n return SurveyQuestionDescriptionContentType;\n}({});\nvar types_SurveyRatingDisplay = /*#__PURE__*/ function(SurveyRatingDisplay) {\n SurveyRatingDisplay[\"Number\"] = \"number\";\n SurveyRatingDisplay[\"Emoji\"] = \"emoji\";\n return SurveyRatingDisplay;\n}({});\nvar types_SurveyQuestionType = /*#__PURE__*/ function(SurveyQuestionType) {\n SurveyQuestionType[\"Open\"] = \"open\";\n SurveyQuestionType[\"MultipleChoice\"] = \"multiple_choice\";\n SurveyQuestionType[\"SingleChoice\"] = \"single_choice\";\n SurveyQuestionType[\"Rating\"] = \"rating\";\n SurveyQuestionType[\"Link\"] = \"link\";\n return SurveyQuestionType;\n}({});\nvar types_SurveyQuestionBranchingType = /*#__PURE__*/ function(SurveyQuestionBranchingType) {\n SurveyQuestionBranchingType[\"NextQuestion\"] = \"next_question\";\n SurveyQuestionBranchingType[\"End\"] = \"end\";\n SurveyQuestionBranchingType[\"ResponseBased\"] = \"response_based\";\n SurveyQuestionBranchingType[\"SpecificQuestion\"] = \"specific_question\";\n return SurveyQuestionBranchingType;\n}({});\nvar types_SurveyMatchType = /*#__PURE__*/ function(SurveyMatchType) {\n SurveyMatchType[\"Regex\"] = \"regex\";\n SurveyMatchType[\"NotRegex\"] = \"not_regex\";\n SurveyMatchType[\"Exact\"] = \"exact\";\n SurveyMatchType[\"IsNot\"] = \"is_not\";\n SurveyMatchType[\"Icontains\"] = \"icontains\";\n SurveyMatchType[\"NotIcontains\"] = \"not_icontains\";\n return SurveyMatchType;\n}({});\nvar types_ActionStepStringMatching = /*#__PURE__*/ function(ActionStepStringMatching) {\n ActionStepStringMatching[\"Contains\"] = \"contains\";\n ActionStepStringMatching[\"Exact\"] = \"exact\";\n ActionStepStringMatching[\"Regex\"] = \"regex\";\n return ActionStepStringMatching;\n}({});\nconst knownUnsafeEditableEvent = [\n '$snapshot',\n '$pageview',\n '$pageleave',\n '$set',\n 'survey dismissed',\n 'survey sent',\n 'survey shown',\n '$identify',\n '$groupidentify',\n '$create_alias',\n '$$client_ingestion_warning',\n '$web_experiment_applied',\n '$feature_enrollment_update',\n '$feature_flag_called'\n];\nexport { types_ActionStepStringMatching as ActionStepStringMatching, types_Compression as Compression, types_PostHogPersistedProperty as PostHogPersistedProperty, types_SurveyMatchType as SurveyMatchType, types_SurveyPosition as SurveyPosition, types_SurveyQuestionBranchingType as SurveyQuestionBranchingType, types_SurveyQuestionDescriptionContentType as SurveyQuestionDescriptionContentType, types_SurveyQuestionType as SurveyQuestionType, types_SurveyRatingDisplay as SurveyRatingDisplay, types_SurveyType as SurveyType, types_SurveyWidgetType as SurveyWidgetType, knownUnsafeEditableEvent };\n","function includes(str, needle) {\n return -1 !== str.indexOf(needle);\n}\nconst trim = function(str) {\n return str.trim();\n};\nconst stripLeadingDollar = function(s) {\n return s.replace(/^\\$/, '');\n};\nfunction isDistinctIdStringLike(value) {\n return [\n 'distinct_id',\n 'distinctid'\n ].includes(value.toLowerCase());\n}\nexport { includes, isDistinctIdStringLike, stripLeadingDollar, trim };\n","import { knownUnsafeEditableEvent } from \"../types.mjs\";\nimport { includes } from \"./string-utils.mjs\";\nconst nativeIsArray = Array.isArray;\nconst ObjProto = Object.prototype;\nconst type_utils_hasOwnProperty = ObjProto.hasOwnProperty;\nconst type_utils_toString = ObjProto.toString;\nconst isArray = nativeIsArray || function(obj) {\n return '[object Array]' === type_utils_toString.call(obj);\n};\nconst isFunction = (x)=>'function' == typeof x;\nconst isNativeFunction = (x)=>isFunction(x) && -1 !== x.toString().indexOf('[native code]');\nconst isObject = (x)=>x === Object(x) && !isArray(x);\nconst isEmptyObject = (x)=>{\n if (isObject(x)) {\n for(const key in x)if (type_utils_hasOwnProperty.call(x, key)) return false;\n return true;\n }\n return false;\n};\nconst isUndefined = (x)=>void 0 === x;\nconst isString = (x)=>'[object String]' == type_utils_toString.call(x);\nconst isEmptyString = (x)=>isString(x) && 0 === x.trim().length;\nconst isNull = (x)=>null === x;\nconst isNullish = (x)=>isUndefined(x) || isNull(x);\nconst isNumber = (x)=>'[object Number]' == type_utils_toString.call(x);\nconst isBoolean = (x)=>'[object Boolean]' === type_utils_toString.call(x);\nconst isFormData = (x)=>x instanceof FormData;\nconst isFile = (x)=>x instanceof File;\nconst isPlainError = (x)=>x instanceof Error;\nconst isKnownUnsafeEditableEvent = (x)=>includes(knownUnsafeEditableEvent, x);\nfunction isPrimitive(value) {\n return null === value || 'object' != typeof value;\n}\nfunction isBuiltin(candidate, className) {\n return Object.prototype.toString.call(candidate) === `[object ${className}]`;\n}\nfunction isError(candidate) {\n switch(Object.prototype.toString.call(candidate)){\n case '[object Error]':\n case '[object Exception]':\n case '[object DOMException]':\n case '[object DOMError]':\n case '[object WebAssembly.Exception]':\n return true;\n default:\n return isInstanceOf(candidate, Error);\n }\n}\nfunction isErrorEvent(event) {\n return isBuiltin(event, 'ErrorEvent');\n}\nfunction isEvent(candidate) {\n return !isUndefined(Event) && isInstanceOf(candidate, Event);\n}\nfunction isPlainObject(candidate) {\n return isBuiltin(candidate, 'Object');\n}\nfunction isInstanceOf(candidate, base) {\n try {\n return candidate instanceof base;\n } catch {\n return false;\n }\n}\nconst yesLikeValues = [\n true,\n 'true',\n 1,\n '1',\n 'yes'\n];\nconst isYesLike = (val)=>includes(yesLikeValues, val);\nconst noLikeValues = [\n false,\n 'false',\n 0,\n '0',\n 'no'\n];\nconst isNoLike = (val)=>includes(noLikeValues, val);\nexport { type_utils_hasOwnProperty as hasOwnProperty, isArray, isBoolean, isBuiltin, isEmptyObject, isEmptyString, isError, isErrorEvent, isEvent, isFile, isFormData, isFunction, isKnownUnsafeEditableEvent, isNativeFunction, isNoLike, isNull, isNullish, isNumber, isObject, isPlainError, isPlainObject, isPrimitive, isString, isUndefined, isYesLike, noLikeValues, yesLikeValues };\n","import { isNumber } from \"./type-utils.mjs\";\nfunction clampToRange(value, min, max, logger, fallbackValue) {\n if (min > max) {\n logger.warn('min cannot be greater than max.');\n min = max;\n }\n if (isNumber(value)) if (value > max) {\n logger.warn(' cannot be greater than max: ' + max + '. Using max value instead.');\n return max;\n } else {\n if (!(value < min)) return value;\n logger.warn(' cannot be less than min: ' + min + '. Using min value instead.');\n return min;\n }\n logger.warn(' must be a number. using max or fallback. max: ' + max + ', fallback: ' + fallbackValue);\n return clampToRange(fallbackValue || max, min, max, logger);\n}\nexport { clampToRange };\n","import { clampToRange } from \"./number-utils.mjs\";\nconst ONE_DAY_IN_MS = 86400000;\nclass BucketedRateLimiter {\n constructor(options){\n this._buckets = {};\n this._onBucketRateLimited = options._onBucketRateLimited;\n this._bucketSize = clampToRange(options.bucketSize, 0, 100, options._logger);\n this._refillRate = clampToRange(options.refillRate, 0, this._bucketSize, options._logger);\n this._refillInterval = clampToRange(options.refillInterval, 0, ONE_DAY_IN_MS, options._logger);\n }\n _applyRefill(bucket, now) {\n const elapsedMs = now - bucket.lastAccess;\n const refillIntervals = Math.floor(elapsedMs / this._refillInterval);\n if (refillIntervals > 0) {\n const tokensToAdd = refillIntervals * this._refillRate;\n bucket.tokens = Math.min(bucket.tokens + tokensToAdd, this._bucketSize);\n bucket.lastAccess = bucket.lastAccess + refillIntervals * this._refillInterval;\n }\n }\n consumeRateLimit(key) {\n const now = Date.now();\n const keyStr = String(key);\n let bucket = this._buckets[keyStr];\n if (bucket) this._applyRefill(bucket, now);\n else {\n bucket = {\n tokens: this._bucketSize,\n lastAccess: now\n };\n this._buckets[keyStr] = bucket;\n }\n if (0 === bucket.tokens) return true;\n bucket.tokens--;\n if (0 === bucket.tokens) this._onBucketRateLimited?.(key);\n return 0 === bucket.tokens;\n }\n stop() {\n this._buckets = {};\n }\n}\nexport { BucketedRateLimiter };\n","import { includes } from \"./string-utils.mjs\";\nimport { isFunction, isUndefined } from \"./type-utils.mjs\";\nconst FACEBOOK = 'Facebook';\nconst MOBILE = 'Mobile';\nconst IOS = 'iOS';\nconst ANDROID = 'Android';\nconst TABLET = 'Tablet';\nconst ANDROID_TABLET = ANDROID + ' ' + TABLET;\nconst IPAD = 'iPad';\nconst APPLE = 'Apple';\nconst APPLE_WATCH = APPLE + ' Watch';\nconst SAFARI = 'Safari';\nconst BLACKBERRY = 'BlackBerry';\nconst SAMSUNG = 'Samsung';\nconst SAMSUNG_BROWSER = SAMSUNG + 'Browser';\nconst SAMSUNG_INTERNET = SAMSUNG + ' Internet';\nconst CHROME = 'Chrome';\nconst CHROME_OS = CHROME + ' OS';\nconst CHROME_IOS = CHROME + ' ' + IOS;\nconst INTERNET_EXPLORER = 'Internet Explorer';\nconst INTERNET_EXPLORER_MOBILE = INTERNET_EXPLORER + ' ' + MOBILE;\nconst OPERA = 'Opera';\nconst OPERA_MINI = OPERA + ' Mini';\nconst EDGE = 'Edge';\nconst MICROSOFT_EDGE = 'Microsoft ' + EDGE;\nconst FIREFOX = 'Firefox';\nconst FIREFOX_IOS = FIREFOX + ' ' + IOS;\nconst NINTENDO = 'Nintendo';\nconst PLAYSTATION = 'PlayStation';\nconst XBOX = 'Xbox';\nconst ANDROID_MOBILE = ANDROID + ' ' + MOBILE;\nconst MOBILE_SAFARI = MOBILE + ' ' + SAFARI;\nconst WINDOWS = 'Windows';\nconst WINDOWS_PHONE = WINDOWS + ' Phone';\nconst NOKIA = 'Nokia';\nconst OUYA = 'Ouya';\nconst GENERIC = 'Generic';\nconst GENERIC_MOBILE = GENERIC + ' ' + MOBILE.toLowerCase();\nconst GENERIC_TABLET = GENERIC + ' ' + TABLET.toLowerCase();\nconst KONQUEROR = 'Konqueror';\nconst BROWSER_VERSION_REGEX_SUFFIX = '(\\\\d+(\\\\.\\\\d+)?)';\nconst DEFAULT_BROWSER_VERSION_REGEX = new RegExp('Version/' + BROWSER_VERSION_REGEX_SUFFIX);\nconst XBOX_REGEX = new RegExp(XBOX, 'i');\nconst PLAYSTATION_REGEX = new RegExp(PLAYSTATION + ' \\\\w+', 'i');\nconst NINTENDO_REGEX = new RegExp(NINTENDO + ' \\\\w+', 'i');\nconst BLACKBERRY_REGEX = new RegExp(BLACKBERRY + '|PlayBook|BB10', 'i');\nconst windowsVersionMap = {\n 'NT3.51': 'NT 3.11',\n 'NT4.0': 'NT 4.0',\n '5.0': '2000',\n '5.1': 'XP',\n '5.2': 'XP',\n '6.0': 'Vista',\n '6.1': '7',\n '6.2': '8',\n '6.3': '8.1',\n '6.4': '10',\n '10.0': '10'\n};\nfunction isSafari(userAgent) {\n return includes(userAgent, SAFARI) && !includes(userAgent, CHROME) && !includes(userAgent, ANDROID);\n}\nconst safariCheck = (ua, vendor)=>vendor && includes(vendor, APPLE) || isSafari(ua);\nconst detectBrowser = function(user_agent, vendor) {\n vendor = vendor || '';\n if (includes(user_agent, ' OPR/') && includes(user_agent, 'Mini')) return OPERA_MINI;\n if (includes(user_agent, ' OPR/')) return OPERA;\n if (BLACKBERRY_REGEX.test(user_agent)) return BLACKBERRY;\n if (includes(user_agent, 'IE' + MOBILE) || includes(user_agent, 'WPDesktop')) return INTERNET_EXPLORER_MOBILE;\n if (includes(user_agent, SAMSUNG_BROWSER)) return SAMSUNG_INTERNET;\n else if (includes(user_agent, EDGE) || includes(user_agent, 'Edg/')) return MICROSOFT_EDGE;\n else if (includes(user_agent, 'FBIOS')) return FACEBOOK + ' ' + MOBILE;\n else if (includes(user_agent, 'UCWEB') || includes(user_agent, 'UCBrowser')) return 'UC Browser';\n else if (includes(user_agent, 'CriOS')) return CHROME_IOS;\n else if (includes(user_agent, 'CrMo')) return CHROME;\n else if (includes(user_agent, CHROME)) return CHROME;\n else if (includes(user_agent, ANDROID) && includes(user_agent, SAFARI)) return ANDROID_MOBILE;\n else if (includes(user_agent, 'FxiOS')) return FIREFOX_IOS;\n else if (includes(user_agent.toLowerCase(), KONQUEROR.toLowerCase())) return KONQUEROR;\n else if (safariCheck(user_agent, vendor)) return includes(user_agent, MOBILE) ? MOBILE_SAFARI : SAFARI;\n else if (includes(user_agent, FIREFOX)) return FIREFOX;\n else if (includes(user_agent, 'MSIE') || includes(user_agent, 'Trident/')) return INTERNET_EXPLORER;\n else if (includes(user_agent, 'Gecko')) return FIREFOX;\n return '';\n};\nconst versionRegexes = {\n [INTERNET_EXPLORER_MOBILE]: [\n new RegExp('rv:' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [MICROSOFT_EDGE]: [\n new RegExp(EDGE + '?\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [CHROME]: [\n new RegExp('(' + CHROME + '|CrMo)\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [CHROME_IOS]: [\n new RegExp('CriOS\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n 'UC Browser': [\n new RegExp('(UCBrowser|UCWEB)\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [SAFARI]: [\n DEFAULT_BROWSER_VERSION_REGEX\n ],\n [MOBILE_SAFARI]: [\n DEFAULT_BROWSER_VERSION_REGEX\n ],\n [OPERA]: [\n new RegExp('(' + OPERA + '|OPR)\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [FIREFOX]: [\n new RegExp(FIREFOX + '\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [FIREFOX_IOS]: [\n new RegExp('FxiOS\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [KONQUEROR]: [\n new RegExp('Konqueror[:/]?' + BROWSER_VERSION_REGEX_SUFFIX, 'i')\n ],\n [BLACKBERRY]: [\n new RegExp(BLACKBERRY + ' ' + BROWSER_VERSION_REGEX_SUFFIX),\n DEFAULT_BROWSER_VERSION_REGEX\n ],\n [ANDROID_MOBILE]: [\n new RegExp('android\\\\s' + BROWSER_VERSION_REGEX_SUFFIX, 'i')\n ],\n [SAMSUNG_INTERNET]: [\n new RegExp(SAMSUNG_BROWSER + '\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [INTERNET_EXPLORER]: [\n new RegExp('(rv:|MSIE )' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n Mozilla: [\n new RegExp('rv:' + BROWSER_VERSION_REGEX_SUFFIX)\n ]\n};\nconst detectBrowserVersion = function(userAgent, vendor) {\n const browser = detectBrowser(userAgent, vendor);\n const regexes = versionRegexes[browser];\n if (isUndefined(regexes)) return null;\n for(let i = 0; i < regexes.length; i++){\n const regex = regexes[i];\n const matches = userAgent.match(regex);\n if (matches) return parseFloat(matches[matches.length - 2]);\n }\n return null;\n};\nconst osMatchers = [\n [\n new RegExp(XBOX + '; ' + XBOX + ' (.*?)[);]', 'i'),\n (match)=>[\n XBOX,\n match && match[1] || ''\n ]\n ],\n [\n new RegExp(NINTENDO, 'i'),\n [\n NINTENDO,\n ''\n ]\n ],\n [\n new RegExp(PLAYSTATION, 'i'),\n [\n PLAYSTATION,\n ''\n ]\n ],\n [\n BLACKBERRY_REGEX,\n [\n BLACKBERRY,\n ''\n ]\n ],\n [\n new RegExp(WINDOWS, 'i'),\n (_, user_agent)=>{\n if (/Phone/.test(user_agent) || /WPDesktop/.test(user_agent)) return [\n WINDOWS_PHONE,\n ''\n ];\n if (new RegExp(MOBILE).test(user_agent) && !/IEMobile\\b/.test(user_agent)) return [\n WINDOWS + ' ' + MOBILE,\n ''\n ];\n const match = /Windows NT ([0-9.]+)/i.exec(user_agent);\n if (match && match[1]) {\n const version = match[1];\n let osVersion = windowsVersionMap[version] || '';\n if (/arm/i.test(user_agent)) osVersion = 'RT';\n return [\n WINDOWS,\n osVersion\n ];\n }\n return [\n WINDOWS,\n ''\n ];\n }\n ],\n [\n /((iPhone|iPad|iPod).*?OS (\\d+)_(\\d+)_?(\\d+)?|iPhone)/,\n (match)=>{\n if (match && match[3]) {\n const versionParts = [\n match[3],\n match[4],\n match[5] || '0'\n ];\n return [\n IOS,\n versionParts.join('.')\n ];\n }\n return [\n IOS,\n ''\n ];\n }\n ],\n [\n /(watch.*\\/(\\d+\\.\\d+\\.\\d+)|watch os,(\\d+\\.\\d+),)/i,\n (match)=>{\n let version = '';\n if (match && match.length >= 3) version = isUndefined(match[2]) ? match[3] : match[2];\n return [\n 'watchOS',\n version\n ];\n }\n ],\n [\n new RegExp('(' + ANDROID + ' (\\\\d+)\\\\.(\\\\d+)\\\\.?(\\\\d+)?|' + ANDROID + ')', 'i'),\n (match)=>{\n if (match && match[2]) {\n const versionParts = [\n match[2],\n match[3],\n match[4] || '0'\n ];\n return [\n ANDROID,\n versionParts.join('.')\n ];\n }\n return [\n ANDROID,\n ''\n ];\n }\n ],\n [\n /Mac OS X (\\d+)[_.](\\d+)[_.]?(\\d+)?/i,\n (match)=>{\n const result = [\n 'Mac OS X',\n ''\n ];\n if (match && match[1]) {\n const versionParts = [\n match[1],\n match[2],\n match[3] || '0'\n ];\n result[1] = versionParts.join('.');\n }\n return result;\n }\n ],\n [\n /Mac/i,\n [\n 'Mac OS X',\n ''\n ]\n ],\n [\n /CrOS/,\n [\n CHROME_OS,\n ''\n ]\n ],\n [\n /Linux|debian/i,\n [\n 'Linux',\n ''\n ]\n ]\n];\nconst detectOS = function(user_agent) {\n for(let i = 0; i < osMatchers.length; i++){\n const [rgex, resultOrFn] = osMatchers[i];\n const match = rgex.exec(user_agent);\n const result = match && (isFunction(resultOrFn) ? resultOrFn(match, user_agent) : resultOrFn);\n if (result) return result;\n }\n return [\n '',\n ''\n ];\n};\nconst detectDevice = function(user_agent) {\n if (NINTENDO_REGEX.test(user_agent)) return NINTENDO;\n if (PLAYSTATION_REGEX.test(user_agent)) return PLAYSTATION;\n if (XBOX_REGEX.test(user_agent)) return XBOX;\n if (new RegExp(OUYA, 'i').test(user_agent)) return OUYA;\n if (new RegExp('(' + WINDOWS_PHONE + '|WPDesktop)', 'i').test(user_agent)) return WINDOWS_PHONE;\n else if (/iPad/.test(user_agent)) return IPAD;\n else if (/iPod/.test(user_agent)) return 'iPod Touch';\n else if (/iPhone/.test(user_agent)) return 'iPhone';\n else if (/(watch)(?: ?os[,/]|\\d,\\d\\/)[\\d.]+/i.test(user_agent)) return APPLE_WATCH;\n else if (BLACKBERRY_REGEX.test(user_agent)) return BLACKBERRY;\n else if (/(kobo)\\s(ereader|touch)/i.test(user_agent)) return 'Kobo';\n else if (new RegExp(NOKIA, 'i').test(user_agent)) return NOKIA;\n else if (/(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\\))/i.test(user_agent) || /(kf[a-z]+)( bui|\\)).+silk\\//i.test(user_agent)) return 'Kindle Fire';\n else if (/(Android|ZTE)/i.test(user_agent)) if (!(!new RegExp(MOBILE).test(user_agent) || /(9138B|TB782B|Nexus [97]|pixel c|HUAWEISHT|BTV|noble nook|smart ultra 6)/i.test(user_agent))) return ANDROID;\n else {\n if (/pixel[\\daxl ]{1,6}/i.test(user_agent) && !/pixel c/i.test(user_agent) || /(huaweimed-al00|tah-|APA|SM-G92|i980|zte|U304AA)/i.test(user_agent) || /lmy47v/i.test(user_agent) && !/QTAQZ3/i.test(user_agent)) return ANDROID;\n return ANDROID_TABLET;\n }\n else if (new RegExp('(pda|' + MOBILE + ')', 'i').test(user_agent)) return GENERIC_MOBILE;\n else if (new RegExp(TABLET, 'i').test(user_agent) && !new RegExp(TABLET + ' pc', 'i').test(user_agent)) return GENERIC_TABLET;\n else return '';\n};\nconst detectDeviceType = function(user_agent) {\n const device = detectDevice(user_agent);\n if (device === IPAD || device === ANDROID_TABLET || 'Kobo' === device || 'Kindle Fire' === device || device === GENERIC_TABLET) return TABLET;\n if (device === NINTENDO || device === XBOX || device === PLAYSTATION || device === OUYA) return 'Console';\n if (device === APPLE_WATCH) return 'Wearable';\n if (device) return MOBILE;\n return 'Desktop';\n};\nexport { detectBrowser, detectBrowserVersion, detectDevice, detectDeviceType, detectOS };\n","let parsedStackResults;\nlet lastKeysCount;\nlet cachedFilenameChunkIds;\nfunction getFilenameToChunkIdMap(stackParser) {\n const chunkIdMap = globalThis._posthogChunkIds;\n if (!chunkIdMap) return;\n const chunkIdKeys = Object.keys(chunkIdMap);\n if (cachedFilenameChunkIds && chunkIdKeys.length === lastKeysCount) return cachedFilenameChunkIds;\n lastKeysCount = chunkIdKeys.length;\n cachedFilenameChunkIds = chunkIdKeys.reduce((acc, stackKey)=>{\n if (!parsedStackResults) parsedStackResults = {};\n const result = parsedStackResults[stackKey];\n if (result) acc[result[0]] = result[1];\n else {\n const parsedStack = stackParser(stackKey);\n for(let i = parsedStack.length - 1; i >= 0; i--){\n const stackFrame = parsedStack[i];\n const filename = stackFrame?.filename;\n const chunkId = chunkIdMap[stackKey];\n if (filename && chunkId) {\n acc[filename] = chunkId;\n parsedStackResults[stackKey] = [\n filename,\n chunkId\n ];\n break;\n }\n }\n }\n return acc;\n }, {});\n return cachedFilenameChunkIds;\n}\nexport { getFilenameToChunkIdMap };\n","export * from \"./bot-detection.mjs\";\nexport * from \"./bucketed-rate-limiter.mjs\";\nexport * from \"./number-utils.mjs\";\nexport * from \"./string-utils.mjs\";\nexport * from \"./type-utils.mjs\";\nexport * from \"./promise-queue.mjs\";\nexport * from \"./logger.mjs\";\nexport * from \"./user-agent-utils.mjs\";\nconst STRING_FORMAT = 'utf8';\nfunction assert(truthyValue, message) {\n if (!truthyValue || 'string' != typeof truthyValue || isEmpty(truthyValue)) throw new Error(message);\n}\nfunction isEmpty(truthyValue) {\n if (0 === truthyValue.trim().length) return true;\n return false;\n}\nfunction removeTrailingSlash(url) {\n return url?.replace(/\\/+$/, '');\n}\nasync function retriable(fn, props) {\n let lastError = null;\n for(let i = 0; i < props.retryCount + 1; i++){\n if (i > 0) await new Promise((r)=>setTimeout(r, props.retryDelay));\n try {\n const res = await fn();\n return res;\n } catch (e) {\n lastError = e;\n if (!props.retryCheck(e)) throw e;\n }\n }\n throw lastError;\n}\nfunction currentTimestamp() {\n return new Date().getTime();\n}\nfunction currentISOTime() {\n return new Date().toISOString();\n}\nfunction safeSetTimeout(fn, timeout) {\n const t = setTimeout(fn, timeout);\n t?.unref && t?.unref();\n return t;\n}\nconst isPromise = (obj)=>obj && 'function' == typeof obj.then;\nconst isError = (x)=>x instanceof Error;\nfunction getFetch() {\n return 'undefined' != typeof fetch ? fetch : void 0 !== globalThis.fetch ? globalThis.fetch : void 0;\n}\nfunction allSettled(promises) {\n return Promise.all(promises.map((p)=>(p ?? Promise.resolve()).then((value)=>({\n status: 'fulfilled',\n value\n }), (reason)=>({\n status: 'rejected',\n reason\n }))));\n}\nexport { STRING_FORMAT, allSettled, assert, currentISOTime, currentTimestamp, getFetch, isError, isPromise, removeTrailingSlash, retriable, safeSetTimeout };\n","import { isArray } from \"../utils/index.mjs\";\nimport { getFilenameToChunkIdMap } from \"./chunk-ids.mjs\";\nconst MAX_CAUSE_RECURSION = 4;\nclass ErrorPropertiesBuilder {\n constructor(coercers, stackParser, modifiers = []){\n this.coercers = coercers;\n this.stackParser = stackParser;\n this.modifiers = modifiers;\n }\n buildFromUnknown(input, hint = {}) {\n const providedMechanism = hint && hint.mechanism;\n const mechanism = providedMechanism || {\n handled: true,\n type: 'generic'\n };\n const coercingContext = this.buildCoercingContext(mechanism, hint, 0);\n const exceptionWithCause = coercingContext.apply(input);\n const parsingContext = this.buildParsingContext();\n const exceptionWithStack = this.parseStacktrace(exceptionWithCause, parsingContext);\n const exceptionList = this.convertToExceptionList(exceptionWithStack, mechanism);\n return {\n $exception_list: exceptionList,\n $exception_level: 'error'\n };\n }\n async modifyFrames(exceptionList) {\n for (const exc of exceptionList)if (exc.stacktrace && exc.stacktrace.frames && isArray(exc.stacktrace.frames)) exc.stacktrace.frames = await this.applyModifiers(exc.stacktrace.frames);\n return exceptionList;\n }\n coerceFallback(ctx) {\n return {\n type: 'Error',\n value: 'Unknown error',\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n parseStacktrace(err, ctx) {\n let cause;\n if (null != err.cause) cause = this.parseStacktrace(err.cause, ctx);\n let stack;\n if ('' != err.stack && null != err.stack) stack = this.applyChunkIds(this.stackParser(err.stack, err.synthetic ? 1 : 0), ctx.chunkIdMap);\n return {\n ...err,\n cause,\n stack\n };\n }\n applyChunkIds(frames, chunkIdMap) {\n return frames.map((frame)=>{\n if (frame.filename && chunkIdMap) frame.chunk_id = chunkIdMap[frame.filename];\n return frame;\n });\n }\n applyCoercers(input, ctx) {\n for (const adapter of this.coercers)if (adapter.match(input)) return adapter.coerce(input, ctx);\n return this.coerceFallback(ctx);\n }\n async applyModifiers(frames) {\n let newFrames = frames;\n for (const modifier of this.modifiers)newFrames = await modifier(newFrames);\n return newFrames;\n }\n convertToExceptionList(exceptionWithStack, mechanism) {\n const currentException = {\n type: exceptionWithStack.type,\n value: exceptionWithStack.value,\n mechanism: {\n type: mechanism.type ?? 'generic',\n handled: mechanism.handled ?? true,\n synthetic: exceptionWithStack.synthetic ?? false\n }\n };\n if (exceptionWithStack.stack) currentException.stacktrace = {\n type: 'raw',\n frames: exceptionWithStack.stack\n };\n const exceptionList = [\n currentException\n ];\n if (null != exceptionWithStack.cause) exceptionList.push(...this.convertToExceptionList(exceptionWithStack.cause, {\n ...mechanism,\n handled: true\n }));\n return exceptionList;\n }\n buildParsingContext() {\n const context = {\n chunkIdMap: getFilenameToChunkIdMap(this.stackParser)\n };\n return context;\n }\n buildCoercingContext(mechanism, hint, depth = 0) {\n const coerce = (input, depth)=>{\n if (!(depth <= MAX_CAUSE_RECURSION)) return;\n {\n const ctx = this.buildCoercingContext(mechanism, hint, depth);\n return this.applyCoercers(input, ctx);\n }\n };\n const context = {\n ...hint,\n syntheticException: 0 == depth ? hint.syntheticException : void 0,\n mechanism,\n apply: (input)=>coerce(input, depth),\n next: (input)=>coerce(input, depth + 1)\n };\n return context;\n }\n}\nexport { ErrorPropertiesBuilder };\n","import { isUndefined } from \"../../utils/index.mjs\";\nconst UNKNOWN_FUNCTION = '?';\nfunction createFrame(platform, filename, func, lineno, colno) {\n const frame = {\n platform,\n filename,\n function: '<anonymous>' === func ? UNKNOWN_FUNCTION : func,\n in_app: true\n };\n if (!isUndefined(lineno)) frame.lineno = lineno;\n if (!isUndefined(colno)) frame.colno = colno;\n return frame;\n}\nexport { UNKNOWN_FUNCTION, createFrame };\n","import { UNKNOWN_FUNCTION } from \"./base.mjs\";\nconst extractSafariExtensionDetails = (func, filename)=>{\n const isSafariExtension = -1 !== func.indexOf('safari-extension');\n const isSafariWebExtension = -1 !== func.indexOf('safari-web-extension');\n return isSafariExtension || isSafariWebExtension ? [\n -1 !== func.indexOf('@') ? func.split('@')[0] : UNKNOWN_FUNCTION,\n isSafariExtension ? `safari-extension:${filename}` : `safari-web-extension:${filename}`\n ] : [\n func,\n filename\n ];\n};\nexport { extractSafariExtensionDetails };\n","import { UNKNOWN_FUNCTION, createFrame } from \"./base.mjs\";\nimport { extractSafariExtensionDetails } from \"./safari.mjs\";\nconst chromeRegexNoFnName = /^\\s*at (\\S+?)(?::(\\d+))(?::(\\d+))\\s*$/i;\nconst chromeRegex = /^\\s*at (?:(.+?\\)(?: \\[.+\\])?|.*?) ?\\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\\/)?.*?)(?::(\\d+))?(?::(\\d+))?\\)?\\s*$/i;\nconst chromeEvalRegex = /\\((\\S*)(?::(\\d+))(?::(\\d+))\\)/;\nconst chromeStackLineParser = (line, platform)=>{\n const noFnParts = chromeRegexNoFnName.exec(line);\n if (noFnParts) {\n const [, filename, line, col] = noFnParts;\n return createFrame(platform, filename, UNKNOWN_FUNCTION, +line, +col);\n }\n const parts = chromeRegex.exec(line);\n if (parts) {\n const isEval = parts[2] && 0 === parts[2].indexOf('eval');\n if (isEval) {\n const subMatch = chromeEvalRegex.exec(parts[2]);\n if (subMatch) {\n parts[2] = subMatch[1];\n parts[3] = subMatch[2];\n parts[4] = subMatch[3];\n }\n }\n const [func, filename] = extractSafariExtensionDetails(parts[1] || UNKNOWN_FUNCTION, parts[2]);\n return createFrame(platform, filename, func, parts[3] ? +parts[3] : void 0, parts[4] ? +parts[4] : void 0);\n }\n};\nexport { chromeStackLineParser };\n","import { UNKNOWN_FUNCTION, createFrame } from \"./base.mjs\";\nimport { extractSafariExtensionDetails } from \"./safari.mjs\";\nconst geckoREgex = /^\\s*(.*?)(?:\\((.*?)\\))?(?:^|@)?((?:[-a-z]+)?:\\/.*?|\\[native code\\]|[^@]*(?:bundle|\\d+\\.js)|\\/[\\w\\-. /=]+)(?::(\\d+))?(?::(\\d+))?\\s*$/i;\nconst geckoEvalRegex = /(\\S+) line (\\d+)(?: > eval line \\d+)* > eval/i;\nconst geckoStackLineParser = (line, platform)=>{\n const parts = geckoREgex.exec(line);\n if (parts) {\n const isEval = parts[3] && parts[3].indexOf(' > eval') > -1;\n if (isEval) {\n const subMatch = geckoEvalRegex.exec(parts[3]);\n if (subMatch) {\n parts[1] = parts[1] || 'eval';\n parts[3] = subMatch[1];\n parts[4] = subMatch[2];\n parts[5] = '';\n }\n }\n let filename = parts[3];\n let func = parts[1] || UNKNOWN_FUNCTION;\n [func, filename] = extractSafariExtensionDetails(func, filename);\n return createFrame(platform, filename, func, parts[4] ? +parts[4] : void 0, parts[5] ? +parts[5] : void 0);\n }\n};\nexport { geckoStackLineParser };\n","import { UNKNOWN_FUNCTION } from \"./base.mjs\";\nimport { chromeStackLineParser } from \"./chrome.mjs\";\nimport { geckoStackLineParser } from \"./gecko.mjs\";\nimport { winjsStackLineParser } from \"./winjs.mjs\";\nimport { opera10StackLineParser, opera11StackLineParser } from \"./opera.mjs\";\nimport { nodeStackLineParser } from \"./node.mjs\";\nconst WEBPACK_ERROR_REGEXP = /\\(error: (.*)\\)/;\nconst STACKTRACE_FRAME_LIMIT = 50;\nfunction reverseAndStripFrames(stack) {\n if (!stack.length) return [];\n const localStack = Array.from(stack);\n localStack.reverse();\n return localStack.slice(0, STACKTRACE_FRAME_LIMIT).map((frame)=>({\n ...frame,\n filename: frame.filename || getLastStackFrame(localStack).filename,\n function: frame.function || UNKNOWN_FUNCTION\n }));\n}\nfunction getLastStackFrame(arr) {\n return arr[arr.length - 1] || {};\n}\nfunction createDefaultStackParser() {\n return createStackParser(\"web:javascript\", chromeStackLineParser, geckoStackLineParser);\n}\nfunction createStackParser(platform, ...parsers) {\n return (stack, skipFirstLines = 0)=>{\n const frames = [];\n const lines = stack.split('\\n');\n for(let i = skipFirstLines; i < lines.length; i++){\n const line = lines[i];\n if (line.length > 1024) continue;\n const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, '$1') : line;\n if (!cleanedLine.match(/\\S*Error: /)) {\n for (const parser of parsers){\n const frame = parser(cleanedLine, platform);\n if (frame) {\n frames.push(frame);\n break;\n }\n }\n if (frames.length >= STACKTRACE_FRAME_LIMIT) break;\n }\n }\n return reverseAndStripFrames(frames);\n };\n}\nexport { chromeStackLineParser, createDefaultStackParser, createStackParser, geckoStackLineParser, nodeStackLineParser, opera10StackLineParser, opera11StackLineParser, reverseAndStripFrames, winjsStackLineParser };\n","import { isBuiltin, isString } from \"../../utils/index.mjs\";\nclass DOMExceptionCoercer {\n match(err) {\n return this.isDOMException(err) || this.isDOMError(err);\n }\n coerce(err, ctx) {\n const hasStack = isString(err.stack);\n return {\n type: this.getType(err),\n value: this.getValue(err),\n stack: hasStack ? err.stack : void 0,\n cause: err.cause ? ctx.next(err.cause) : void 0,\n synthetic: false\n };\n }\n getType(candidate) {\n return this.isDOMError(candidate) ? 'DOMError' : 'DOMException';\n }\n getValue(err) {\n const name = err.name || (this.isDOMError(err) ? 'DOMError' : 'DOMException');\n const message = err.message ? `${name}: ${err.message}` : name;\n return message;\n }\n isDOMException(err) {\n return isBuiltin(err, 'DOMException');\n }\n isDOMError(err) {\n return isBuiltin(err, 'DOMError');\n }\n}\nexport { DOMExceptionCoercer };\n","import { isPlainError } from \"../../utils/index.mjs\";\nclass ErrorCoercer {\n match(err) {\n return isPlainError(err);\n }\n coerce(err, ctx) {\n return {\n type: this.getType(err),\n value: this.getMessage(err, ctx),\n stack: this.getStack(err),\n cause: err.cause ? ctx.next(err.cause) : void 0,\n synthetic: false\n };\n }\n getType(err) {\n return err.name || err.constructor.name;\n }\n getMessage(err, _ctx) {\n const message = err.message;\n if (message.error && 'string' == typeof message.error.message) return String(message.error.message);\n return String(message);\n }\n getStack(err) {\n return err.stacktrace || err.stack || void 0;\n }\n}\nexport { ErrorCoercer };\n","import { isErrorEvent } from \"../../utils/index.mjs\";\nclass ErrorEventCoercer {\n constructor(){}\n match(err) {\n return isErrorEvent(err) && void 0 != err.error;\n }\n coerce(err, ctx) {\n const exceptionLike = ctx.apply(err.error);\n if (!exceptionLike) return {\n type: 'ErrorEvent',\n value: err.message,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n return exceptionLike;\n }\n}\nexport { ErrorEventCoercer };\n","const ERROR_TYPES_PATTERN = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;\nclass StringCoercer {\n match(input) {\n return 'string' == typeof input;\n }\n coerce(input, ctx) {\n const [type, value] = this.getInfos(input);\n return {\n type: type ?? 'Error',\n value: value ?? input,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n getInfos(candidate) {\n let type = 'Error';\n let value = candidate;\n const groups = candidate.match(ERROR_TYPES_PATTERN);\n if (groups) {\n type = groups[1];\n value = groups[2];\n }\n return [\n type,\n value\n ];\n }\n}\nexport { StringCoercer };\n","const severityLevels = [\n 'fatal',\n 'error',\n 'warning',\n 'log',\n 'info',\n 'debug'\n];\nexport { severityLevels };\n","function truncate(str, max = 0) {\n if ('string' != typeof str || 0 === max) return str;\n return str.length <= max ? str : `${str.slice(0, max)}...`;\n}\nfunction extractExceptionKeysForMessage(err, maxLength = 40) {\n const keys = Object.keys(err);\n keys.sort();\n if (!keys.length) return '[object has no keys]';\n for(let i = keys.length; i > 0; i--){\n const serialized = keys.slice(0, i).join(', ');\n if (!(serialized.length > maxLength)) {\n if (i === keys.length) return serialized;\n return serialized.length <= maxLength ? serialized : `${serialized.slice(0, maxLength)}...`;\n }\n }\n return '';\n}\nexport { extractExceptionKeysForMessage, truncate };\n","import { isEmptyString, isError, isEvent, isString } from \"../../utils/index.mjs\";\nimport { severityLevels } from \"../types.mjs\";\nimport { extractExceptionKeysForMessage } from \"./utils.mjs\";\nclass ObjectCoercer {\n match(candidate) {\n return 'object' == typeof candidate && null !== candidate;\n }\n coerce(candidate, ctx) {\n const errorProperty = this.getErrorPropertyFromObject(candidate);\n if (errorProperty) return ctx.apply(errorProperty);\n return {\n type: this.getType(candidate),\n value: this.getValue(candidate),\n stack: ctx.syntheticException?.stack,\n level: this.isSeverityLevel(candidate.level) ? candidate.level : 'error',\n synthetic: true\n };\n }\n getType(err) {\n return isEvent(err) ? err.constructor.name : 'Error';\n }\n getValue(err) {\n if ('name' in err && 'string' == typeof err.name) {\n let message = `'${err.name}' captured as exception`;\n if ('message' in err && 'string' == typeof err.message) message += ` with message: '${err.message}'`;\n return message;\n }\n if ('message' in err && 'string' == typeof err.message) return err.message;\n const className = this.getObjectClassName(err);\n const keys = extractExceptionKeysForMessage(err);\n return `${className && 'Object' !== className ? `'${className}'` : 'Object'} captured as exception with keys: ${keys}`;\n }\n isSeverityLevel(x) {\n return isString(x) && !isEmptyString(x) && severityLevels.indexOf(x) >= 0;\n }\n getErrorPropertyFromObject(obj) {\n for(const prop in obj)if (Object.prototype.hasOwnProperty.call(obj, prop)) {\n const value = obj[prop];\n if (isError(value)) return value;\n }\n }\n getObjectClassName(obj) {\n try {\n const prototype = Object.getPrototypeOf(obj);\n return prototype ? prototype.constructor.name : void 0;\n } catch (e) {\n return;\n }\n }\n}\nexport { ObjectCoercer };\n","import { isEvent } from \"../../utils/index.mjs\";\nimport { extractExceptionKeysForMessage } from \"./utils.mjs\";\nclass EventCoercer {\n match(err) {\n return isEvent(err);\n }\n coerce(evt, ctx) {\n const constructorName = evt.constructor.name;\n return {\n type: constructorName,\n value: `${constructorName} captured as exception with keys: ${extractExceptionKeysForMessage(evt)}`,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n}\nexport { EventCoercer };\n","import { isPrimitive } from \"../../utils/index.mjs\";\nclass PrimitiveCoercer {\n match(candidate) {\n return isPrimitive(candidate);\n }\n coerce(value, ctx) {\n return {\n type: 'Error',\n value: `Primitive value captured as exception: ${String(value)}`,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n}\nexport { PrimitiveCoercer };\n","import { isBuiltin, isPrimitive } from \"../../utils/index.mjs\";\nclass PromiseRejectionEventCoercer {\n match(err) {\n return isBuiltin(err, 'PromiseRejectionEvent');\n }\n coerce(err, ctx) {\n const reason = this.getUnhandledRejectionReason(err);\n if (isPrimitive(reason)) return {\n type: 'UnhandledRejection',\n value: `Non-Error promise rejection captured with value: ${String(reason)}`,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n return ctx.apply(reason);\n }\n getUnhandledRejectionReason(error) {\n if (isPrimitive(error)) return error;\n try {\n if ('reason' in error) return error.reason;\n if ('detail' in error && 'reason' in error.detail) return error.detail.reason;\n } catch {}\n return error;\n }\n}\nexport { PromiseRejectionEventCoercer };\n","import Config from '../config'\nimport { isUndefined } from '@posthog/core'\nimport { assignableWindow, window } from './globals'\nimport type { Logger } from '@posthog/core'\n\ntype CreateLoggerOptions = {\n debugEnabled?: boolean\n}\n\ntype PosthogJsLogger = Omit<Logger, 'createLogger'> & {\n _log: (level: 'log' | 'warn' | 'error', ...args: any[]) => void\n uninitializedWarning: (methodName: string) => void\n createLogger: (prefix: string, options?: CreateLoggerOptions) => PosthogJsLogger\n}\n\nconst _createLogger = (prefix: string, { debugEnabled }: CreateLoggerOptions = {}): PosthogJsLogger => {\n const logger: PosthogJsLogger = {\n _log: (level: 'log' | 'warn' | 'error', ...args: any[]) => {\n if (\n window &&\n (Config.DEBUG || assignableWindow.POSTHOG_DEBUG || debugEnabled) &&\n !isUndefined(window.console) &&\n window.console\n ) {\n const consoleLog =\n '__rrweb_original__' in window.console[level]\n ? (window.console[level] as any)['__rrweb_original__']\n : window.console[level]\n\n // eslint-disable-next-line no-console\n consoleLog(prefix, ...args)\n }\n },\n\n info: (...args: any[]) => {\n logger._log('log', ...args)\n },\n\n warn: (...args: any[]) => {\n logger._log('warn', ...args)\n },\n\n error: (...args: any[]) => {\n logger._log('error', ...args)\n },\n\n critical: (...args: any[]) => {\n // Critical errors are always logged to the console\n // eslint-disable-next-line no-console\n console.error(prefix, ...args)\n },\n\n uninitializedWarning: (methodName: string) => {\n logger.error(`You must initialize PostHog before calling ${methodName}`)\n },\n\n createLogger: (additionalPrefix: string, options?: CreateLoggerOptions) =>\n _createLogger(`${prefix} ${additionalPrefix}`, options),\n }\n return logger\n}\n\nexport const logger = _createLogger('[PostHog.js]')\n\nexport const createLogger = logger.createLogger\n","import type { PostHog } from '../posthog-core'\nimport { assignableWindow, document, PostHogExtensionKind } from '../utils/globals'\nimport { createLogger } from '../utils/logger'\n\nconst logger = createLogger('[ExternalScriptsLoader]')\n\nconst loadScript = (posthog: PostHog, url: string, callback: (error?: string | Event, event?: Event) => void) => {\n if (posthog.config.disable_external_dependency_loading) {\n logger.warn(`${url} was requested but loading of external scripts is disabled.`)\n return callback('Loading of external scripts is disabled')\n }\n\n // If we add a script more than once then the browser will parse and execute it\n // So, even if idempotent we waste parsing and processing time\n const existingScripts = document?.querySelectorAll('script')\n if (existingScripts) {\n for (let i = 0; i < existingScripts.length; i++) {\n if (existingScripts[i].src === url) {\n const alreadyExistingScriptTag = existingScripts[i]\n\n if ((alreadyExistingScriptTag as any).__posthog_loading_callback_fired) {\n // script already exists and fired its load event,\n // we call the callback again, they need to be idempotent\n return callback()\n }\n\n // eslint-disable-next-line posthog-js/no-add-event-listener\n alreadyExistingScriptTag.addEventListener('load', (event) => {\n // it hasn't already loaded\n // we probably called loadScript twice in quick succession,\n // so we attach a callback to the onload event\n ;(alreadyExistingScriptTag as any).__posthog_loading_callback_fired = true\n callback(undefined, event)\n })\n alreadyExistingScriptTag.onerror = (error) => callback(error)\n\n return // and finish processing here\n }\n }\n }\n\n const addScript = () => {\n if (!document) {\n return callback('document not found')\n }\n let scriptTag: HTMLScriptElement | null = document.createElement('script')\n scriptTag.type = 'text/javascript'\n scriptTag.crossOrigin = 'anonymous'\n scriptTag.src = url\n scriptTag.onload = (event) => {\n // mark the script as having had its callback fired, so we can avoid double-calling it\n ;(scriptTag as any).__posthog_loading_callback_fired = true\n callback(undefined, event)\n }\n scriptTag.onerror = (error) => callback(error)\n\n if (posthog.config.prepare_external_dependency_script) {\n scriptTag = posthog.config.prepare_external_dependency_script(scriptTag)\n }\n\n if (!scriptTag) {\n return callback('prepare_external_dependency_script returned null')\n }\n\n const scripts = document.querySelectorAll('body > script')\n if (scripts.length > 0) {\n scripts[0].parentNode?.insertBefore(scriptTag, scripts[0])\n } else {\n // In exceptional situations this call might load before the DOM is fully ready.\n document.body.appendChild(scriptTag)\n }\n }\n\n if (document?.body) {\n addScript()\n } else {\n // Inlining this because we don't care about `passive: true` here\n // and this saves us ~3% of the bundle size\n // eslint-disable-next-line posthog-js/no-add-event-listener\n document?.addEventListener('DOMContentLoaded', addScript)\n }\n}\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nassignableWindow.__PosthogExtensions__.loadExternalDependency = (\n posthog: PostHog,\n kind: PostHogExtensionKind,\n callback: (error?: string | Event, event?: Event) => void\n): void => {\n let scriptUrlToLoad = `/static/${kind}.js` + `?v=${posthog.version}`\n\n if (kind === 'remote-config') {\n scriptUrlToLoad = `/array/${posthog.config.token}/config.js`\n }\n\n if (kind === 'toolbar') {\n // toolbar.js is served from the PostHog CDN, this has a TTL of 24 hours.\n // the toolbar asset includes a rotating \"token\" that is valid for 5 minutes.\n const fiveMinutesInMillis = 5 * 60 * 1000\n // this ensures that we bust the cache periodically\n const timestampToNearestFiveMinutes = Math.floor(Date.now() / fiveMinutesInMillis) * fiveMinutesInMillis\n\n scriptUrlToLoad = `${scriptUrlToLoad}&t=${timestampToNearestFiveMinutes}`\n }\n const url = posthog.requestRouter.endpointFor('assets', scriptUrlToLoad)\n\n loadScript(posthog, url, callback)\n}\n\nassignableWindow.__PosthogExtensions__.loadSiteApp = (\n posthog: PostHog,\n url: string,\n callback: (error?: string | Event, event?: Event) => void\n): void => {\n const scriptUrl = posthog.requestRouter.endpointFor('api', url)\n\n loadScript(posthog, scriptUrl, callback)\n}\n","import { Breaker, Properties } from '../types'\nimport { nativeForEach, nativeIndexOf } from './globals'\nimport { logger } from './logger'\nimport { isFormData, isNull, isNullish, isNumber, isString, isUndefined, hasOwnProperty, isArray } from '@posthog/core'\n\nconst breaker: Breaker = {}\n\nexport function eachArray<E = any>(\n obj: E[] | null | undefined,\n iterator: (value: E, key: number) => void | Breaker,\n thisArg?: any\n): void {\n if (isArray(obj)) {\n if (nativeForEach && obj.forEach === nativeForEach) {\n obj.forEach(iterator, thisArg)\n } else if ('length' in obj && obj.length === +obj.length) {\n for (let i = 0, l = obj.length; i < l; i++) {\n if (i in obj && iterator.call(thisArg, obj[i], i) === breaker) {\n return\n }\n }\n }\n }\n}\n\n/**\n * @param {*=} obj\n * @param {function(...*)=} iterator\n * @param {Object=} thisArg\n */\nexport function each(obj: any, iterator: (value: any, key: any) => void | Breaker, thisArg?: any): void {\n if (isNullish(obj)) {\n return\n }\n if (isArray(obj)) {\n return eachArray(obj, iterator, thisArg)\n }\n if (isFormData(obj)) {\n for (const pair of obj.entries()) {\n if (iterator.call(thisArg, pair[1], pair[0]) === breaker) {\n return\n }\n }\n return\n }\n for (const key in obj) {\n if (hasOwnProperty.call(obj, key)) {\n if (iterator.call(thisArg, obj[key], key) === breaker) {\n return\n }\n }\n }\n}\n\nexport const extend = function (obj: Record<string, any>, ...args: Record<string, any>[]): Record<string, any> {\n eachArray(args, function (source) {\n for (const prop in source) {\n if (source[prop] !== void 0) {\n obj[prop] = source[prop]\n }\n }\n })\n return obj\n}\n\nexport const extendArray = function <T>(obj: T[], ...args: T[][]): T[] {\n eachArray(args, function (source) {\n eachArray(source, function (item) {\n obj.push(item)\n })\n })\n return obj\n}\n\nexport const include = function (\n obj: null | string | Array<any> | Record<string, any>,\n target: any\n): boolean | Breaker {\n let found = false\n if (isNull(obj)) {\n return found\n }\n if (nativeIndexOf && obj.indexOf === nativeIndexOf) {\n return obj.indexOf(target) != -1\n }\n each(obj, function (value) {\n if (found || (found = value === target)) {\n return breaker\n }\n return\n })\n return found\n}\n\n/**\n * Object.entries() polyfill\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries\n */\nexport function entries<T = any>(obj: Record<string, T>): [string, T][] {\n const ownProps = Object.keys(obj)\n let i = ownProps.length\n const resArray = new Array(i) // preallocate the Array\n\n while (i--) {\n resArray[i] = [ownProps[i], obj[ownProps[i]]]\n }\n return resArray\n}\n\nexport const trySafe = function <T>(fn: () => T): T | undefined {\n try {\n return fn()\n } catch {\n return undefined\n }\n}\n\nexport const safewrap = function <F extends (...args: any[]) => any = (...args: any[]) => any>(f: F): F {\n return function (...args) {\n try {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return f.apply(this, args)\n } catch (e) {\n logger.critical(\n 'Implementation error. Please turn on debug mode and open a ticket on https://app.posthog.com/home#panel=support%3Asupport%3A.'\n )\n logger.critical(e)\n }\n } as F\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport const safewrapClass = function (klass: Function, functions: string[]): void {\n for (let i = 0; i < functions.length; i++) {\n klass.prototype[functions[i]] = safewrap(klass.prototype[functions[i]])\n }\n}\n\nexport const stripEmptyProperties = function (p: Properties): Properties {\n const ret: Properties = {}\n each(p, function (v, k) {\n if ((isString(v) && v.length > 0) || isNumber(v)) {\n ret[k] = v\n }\n })\n return ret\n}\n\n/**\n * Deep copies an object.\n * It handles cycles by replacing all references to them with `undefined`\n * Also supports customizing native values\n *\n * @param value\n * @param customizer\n * @returns {{}|undefined|*}\n */\nfunction deepCircularCopy<T extends Record<string, any> = Record<string, any>>(\n value: T,\n customizer?: <K extends keyof T = keyof T>(value: T[K], key?: K) => T[K]\n): T | undefined {\n const COPY_IN_PROGRESS_SET = new Set()\n\n function internalDeepCircularCopy(value: T, key?: string): T | undefined {\n if (value !== Object(value)) return customizer ? customizer(value as any, key) : value // primitive value\n\n if (COPY_IN_PROGRESS_SET.has(value)) return undefined\n COPY_IN_PROGRESS_SET.add(value)\n let result: T\n\n if (isArray(value)) {\n result = [] as any as T\n eachArray(value, (it) => {\n result.push(internalDeepCircularCopy(it))\n })\n } else {\n result = {} as T\n each(value, (val, key) => {\n if (!COPY_IN_PROGRESS_SET.has(val)) {\n ;(result as any)[key] = internalDeepCircularCopy(val, key)\n }\n })\n }\n return result\n }\n return internalDeepCircularCopy(value)\n}\n\nexport function _copyAndTruncateStrings<T extends Record<string, any> = Record<string, any>>(\n object: T,\n maxStringLength: number | null\n): T {\n return deepCircularCopy(object, (value: any) => {\n if (isString(value) && !isNull(maxStringLength)) {\n return (value as string).slice(0, maxStringLength)\n }\n return value\n }) as T\n}\n\n// NOTE: Update PostHogConfig docs if you change this list\n// We will not try to catch all bullets here, but we should make an effort to catch the most common ones\n// You should be highly against adding more to this list, because ultimately customers can configure\n// their `cross_subdomain_cookie` setting to anything they want.\nconst EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE = ['herokuapp.com', 'vercel.app', 'netlify.app']\nexport function isCrossDomainCookie(documentLocation: Location | undefined) {\n const hostname = documentLocation?.hostname\n\n if (!isString(hostname)) {\n return false\n }\n // split and slice isn't a great way to match arbitrary domains,\n // but it's good enough for ensuring we only match herokuapp.com when it is the TLD\n // for the hostname\n const lastTwoParts = hostname.split('.').slice(-2).join('.')\n\n for (const excluded of EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE) {\n if (lastTwoParts === excluded) {\n return false\n }\n }\n\n return true\n}\n\nexport function find<T>(value: T[], predicate: (value: T) => boolean): T | undefined {\n for (let i = 0; i < value.length; i++) {\n if (predicate(value[i])) {\n return value[i]\n }\n }\n return undefined\n}\n\n// Use this instead of element.addEventListener to avoid eslint errors\n// this properly implements the default options for passive event listeners\nexport function addEventListener(\n element: Window | Document | Element | undefined,\n event: string,\n callback: EventListener,\n options?: AddEventListenerOptions\n): void {\n const { capture = false, passive = true } = options ?? {}\n\n // This is the only place where we are allowed to call this function\n // because the whole idea is that we should be calling this instead of the built-in one\n // eslint-disable-next-line posthog-js/no-add-event-listener\n element?.addEventListener(event, callback, { capture, passive })\n}\n\n/**\n * Helper to migrate deprecated config fields to new field names with appropriate warnings\n * @param config - The config object to check\n * @param newField - The new field name to use\n * @param oldField - The deprecated field name to check for\n * @param defaultValue - The default value if neither field is set\n * @param loggerInstance - Optional logger instance for deprecation warnings\n * @returns The value to use (new field takes precedence over old field)\n */\nexport function migrateConfigField<T>(\n config: Record<string, any>,\n newField: string,\n oldField: string,\n defaultValue: T,\n loggerInstance?: { warn: (message: string) => void }\n): T {\n const hasNewField = newField in config && !isUndefined(config[newField])\n const hasOldField = oldField in config && !isUndefined(config[oldField])\n\n if (hasNewField) {\n return config[newField]\n }\n\n if (hasOldField) {\n if (loggerInstance) {\n loggerInstance.warn(\n `Config field '${oldField}' is deprecated. Please use '${newField}' instead. ` +\n `The old field will be removed in a future major version.`\n )\n }\n return config[oldField]\n }\n\n return defaultValue\n}\n","/*\n * Constants\n */\n\n/* PROPERTY KEYS */\n\n// This key is deprecated, but we want to check for it to see whether aliasing is allowed.\nexport const PEOPLE_DISTINCT_ID_KEY = '$people_distinct_id'\nexport const DISTINCT_ID = 'distinct_id'\nexport const DEVICE_ID = '$device_id'\nexport const ALIAS_ID_KEY = '__alias'\nexport const CAMPAIGN_IDS_KEY = '__cmpns'\nexport const EVENT_TIMERS_KEY = '__timers'\nexport const AUTOCAPTURE_DISABLED_SERVER_SIDE = '$autocapture_disabled_server_side'\nexport const HEATMAPS_ENABLED_SERVER_SIDE = '$heatmaps_enabled_server_side'\nexport const EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE = '$exception_capture_enabled_server_side'\nexport const ERROR_TRACKING_SUPPRESSION_RULES = '$error_tracking_suppression_rules'\nexport const ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS = '$error_tracking_capture_extension_exceptions'\nexport const WEB_VITALS_ENABLED_SERVER_SIDE = '$web_vitals_enabled_server_side'\nexport const DEAD_CLICKS_ENABLED_SERVER_SIDE = '$dead_clicks_enabled_server_side'\nexport const PRODUCT_TOURS_ENABLED_SERVER_SIDE = '$product_tours_enabled_server_side'\nexport const WEB_VITALS_ALLOWED_METRICS = '$web_vitals_allowed_metrics'\nexport const SESSION_RECORDING_REMOTE_CONFIG = '$session_recording_remote_config'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_ENABLED_SERVER_SIDE = '$session_recording_enabled_server_side'\n// @deprecated can be removed along with eager loaded replay\nexport const CONSOLE_LOG_RECORDING_ENABLED_SERVER_SIDE = '$console_log_recording_enabled_server_side'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_NETWORK_PAYLOAD_CAPTURE = '$session_recording_network_payload_capture'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_MASKING = '$session_recording_masking'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_CANVAS_RECORDING = '$session_recording_canvas_recording'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_SAMPLE_RATE = '$replay_sample_rate'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_MINIMUM_DURATION = '$replay_minimum_duration'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_SCRIPT_CONFIG = '$replay_script_config'\nexport const SESSION_RECORDING_OVERRIDE_SAMPLING = '$replay_override_sampling'\nexport const SESSION_RECORDING_OVERRIDE_LINKED_FLAG = '$replay_override_linked_flag'\nexport const SESSION_RECORDING_OVERRIDE_URL_TRIGGER = '$replay_override_url_trigger'\nexport const SESSION_RECORDING_OVERRIDE_EVENT_TRIGGER = '$replay_override_event_trigger'\nexport const SESSION_ID = '$sesid'\nexport const SESSION_RECORDING_IS_SAMPLED = '$session_is_sampled'\nexport const SESSION_RECORDING_PAST_MINIMUM_DURATION = '$session_past_minimum_duration'\nexport const SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION = '$session_recording_url_trigger_activated_session'\nexport const SESSION_RECORDING_EVENT_TRIGGER_ACTIVATED_SESSION = '$session_recording_event_trigger_activated_session'\nexport const ENABLED_FEATURE_FLAGS = '$enabled_feature_flags'\nexport const PERSISTENCE_EARLY_ACCESS_FEATURES = '$early_access_features'\nexport const PERSISTENCE_FEATURE_FLAG_DETAILS = '$feature_flag_details'\nexport const STORED_PERSON_PROPERTIES_KEY = '$stored_person_properties'\nexport const STORED_GROUP_PROPERTIES_KEY = '$stored_group_properties'\nexport const SURVEYS = '$surveys'\nexport const SURVEYS_ACTIVATED = '$surveys_activated'\nexport const PRODUCT_TOURS_ACTIVATED = '$product_tours_activated'\nexport const CONVERSATIONS = '$conversations'\nexport const FLAG_CALL_REPORTED = '$flag_call_reported'\nexport const USER_STATE = '$user_state'\nexport const CLIENT_SESSION_PROPS = '$client_session_props'\nexport const CAPTURE_RATE_LIMIT = '$capture_rate_limit'\n\n/** @deprecated Delete this when INITIAL_PERSON_INFO has been around for long enough to ignore backwards compat */\nexport const INITIAL_CAMPAIGN_PARAMS = '$initial_campaign_params'\n/** @deprecated Delete this when INITIAL_PERSON_INFO has been around for long enough to ignore backwards compat */\nexport const INITIAL_REFERRER_INFO = '$initial_referrer_info'\nexport const INITIAL_PERSON_INFO = '$initial_person_info'\nexport const ENABLE_PERSON_PROCESSING = '$epp'\nexport const TOOLBAR_ID = '__POSTHOG_TOOLBAR__'\nexport const TOOLBAR_CONTAINER_CLASS = 'toolbar-global-fade-container'\n\n/**\n * PREVIEW - MAY CHANGE WITHOUT WARNING - DO NOT USE IN PRODUCTION\n * Sentinel value for distinct id, device id, session id. Signals that the server should generate the value\n * */\nexport const COOKIELESS_SENTINEL_VALUE = '$posthog_cookieless'\nexport const COOKIELESS_MODE_FLAG_PROPERTY = '$cookieless_mode'\n\nexport const WEB_EXPERIMENTS = '$web_experiments'\n\n// These are properties that are reserved and will not be automatically included in events\nexport const PERSISTENCE_RESERVED_PROPERTIES = [\n PEOPLE_DISTINCT_ID_KEY,\n ALIAS_ID_KEY,\n CAMPAIGN_IDS_KEY,\n EVENT_TIMERS_KEY,\n SESSION_RECORDING_ENABLED_SERVER_SIDE,\n HEATMAPS_ENABLED_SERVER_SIDE,\n SESSION_ID,\n ENABLED_FEATURE_FLAGS,\n ERROR_TRACKING_SUPPRESSION_RULES,\n USER_STATE,\n PERSISTENCE_EARLY_ACCESS_FEATURES,\n PERSISTENCE_FEATURE_FLAG_DETAILS,\n STORED_GROUP_PROPERTIES_KEY,\n STORED_PERSON_PROPERTIES_KEY,\n SURVEYS,\n FLAG_CALL_REPORTED,\n CLIENT_SESSION_PROPS,\n CAPTURE_RATE_LIMIT,\n INITIAL_CAMPAIGN_PARAMS,\n INITIAL_REFERRER_INFO,\n ENABLE_PERSON_PROCESSING,\n INITIAL_PERSON_INFO,\n // Conversations keys (defined in lazy-loaded extension)\n '$conversations_widget_session_id',\n '$conversations_ticket_id',\n '$conversations_widget_state',\n '$conversations_user_traits',\n]\n\nexport const SURVEYS_REQUEST_TIMEOUT_MS = 10000\n","import { TOOLBAR_CONTAINER_CLASS, TOOLBAR_ID } from '../constants'\n\nexport function isElementInToolbar(el: EventTarget | null): boolean {\n if (el instanceof Element) {\n // closest isn't available in IE11, but we'll polyfill when bundling\n return el.id === TOOLBAR_ID || !!el.closest?.('.' + TOOLBAR_CONTAINER_CLASS)\n }\n return false\n}\n\n/*\n * Check whether an element has nodeType Node.ELEMENT_NODE\n * @param {Element} el - element to check\n * @returns {boolean} whether el is of the correct nodeType\n */\nexport function isElementNode(el: Node | Element | undefined | null): el is Element {\n return !!el && el.nodeType === 1 // Node.ELEMENT_NODE - use integer constant for browser portability\n}\n\n/*\n * Check whether an element is of a given tag type.\n * Due to potential reference discrepancies (such as the webcomponents.js polyfill),\n * we want to match tagNames instead of specific references because something like\n * element === document.body won't always work because element might not be a native\n * element.\n * @param {Element} el - element to check\n * @param {string} tag - tag name (e.g., \"div\")\n * @returns {boolean} whether el is of the given tag type\n */\nexport function isTag(el: Element | undefined | null, tag: string): el is HTMLElement {\n return !!el && !!el.tagName && el.tagName.toLowerCase() === tag.toLowerCase()\n}\n\n/*\n * Check whether an element has nodeType Node.TEXT_NODE\n * @param {Element} el - element to check\n * @returns {boolean} whether el is of the correct nodeType\n */\nexport function isTextNode(el: Element | undefined | null): el is HTMLElement {\n return !!el && el.nodeType === 3 // Node.TEXT_NODE - use integer constant for browser portability\n}\n\n/*\n * Check whether an element has nodeType Node.DOCUMENT_FRAGMENT_NODE\n * @param {Element} el - element to check\n * @returns {boolean} whether el is of the correct nodeType\n */\nexport function isDocumentFragment(el: Element | ParentNode | undefined | null): el is DocumentFragment {\n return !!el && el.nodeType === 11 // Node.DOCUMENT_FRAGMENT_NODE - use integer constant for browser portability\n}\n","import { AutocaptureConfig, PostHogConfig, Properties } from './types'\nimport { each, entries } from './utils'\n\nimport { isNullish, isString, isUndefined, isArray, isBoolean } from '@posthog/core'\nimport { logger } from './utils/logger'\nimport { window } from './utils/globals'\nimport { isDocumentFragment, isElementNode, isTag, isTextNode } from './utils/element-utils'\nimport { includes, trim } from '@posthog/core'\n\nexport function splitClassString(s: string): string[] {\n return s ? trim(s).split(/\\s+/) : []\n}\n\nfunction checkForURLMatches(urlsList: (string | RegExp)[]): boolean {\n const url = window?.location.href\n return !!(url && urlsList && urlsList.some((regex) => url.match(regex)))\n}\n\n/*\n * Get the className of an element, accounting for edge cases where element.className is an object\n *\n * Because this is a string it can contain unexpected characters\n * So, this method safely splits the className and returns that array.\n */\nexport function getClassNames(el: Element): string[] {\n let className = ''\n switch (typeof el.className) {\n case 'string':\n className = el.className\n break\n // TODO: when is this ever used?\n case 'object': // handle cases where className might be SVGAnimatedString or some other type\n className =\n (el.className && 'baseVal' in el.className ? (el.className as any).baseVal : null) ||\n el.getAttribute('class') ||\n ''\n break\n default:\n className = ''\n }\n\n return splitClassString(className)\n}\n\nexport function makeSafeText(s: string | null | undefined): string | null {\n if (isNullish(s)) {\n return null\n }\n\n return (\n trim(s)\n // scrub potentially sensitive values\n .split(/(\\s+)/)\n .filter((s) => shouldCaptureValue(s))\n .join('')\n // normalize whitespace\n .replace(/[\\r\\n]/g, ' ')\n .replace(/[ ]+/g, ' ')\n // truncate\n .substring(0, 255)\n )\n}\n\n/*\n * Get the direct text content of an element, protecting against sensitive data collection.\n * Concats textContent of each of the element's text node children; this avoids potential\n * collection of sensitive data that could happen if we used element.textContent and the\n * element had sensitive child elements, since element.textContent includes child content.\n * Scrubs values that look like they could be sensitive (i.e. cc or ssn number).\n * @param {Element} el - element to get the text of\n * @returns {string} the element's direct text content\n */\nexport function getSafeText(el: Element): string {\n let elText = ''\n\n if (shouldCaptureElement(el) && !isSensitiveElement(el) && el.childNodes && el.childNodes.length) {\n each(el.childNodes, function (child) {\n if (isTextNode(child) && child.textContent) {\n elText += makeSafeText(child.textContent) ?? ''\n }\n })\n }\n\n return trim(elText)\n}\n\nexport function getEventTarget(e: Event): Element | null {\n // https://developer.mozilla.org/en-US/docs/Web/API/Event/target#Compatibility_notes\n if (isUndefined(e.target)) {\n return (e.srcElement as Element) || null\n } else {\n if ((e.target as HTMLElement)?.shadowRoot) {\n return (e.composedPath()[0] as Element) || null\n }\n return (e.target as Element) || null\n }\n}\n\nexport const autocaptureCompatibleElements = ['a', 'button', 'form', 'input', 'select', 'textarea', 'label']\n\n/*\n if there is no config, then all elements are allowed\n if there is a config, and there is an allow list, then only elements in the allow list are allowed\n assumes that some other code is checking this element's parents\n */\nfunction checkIfElementTreePassesElementAllowList(\n elements: Element[],\n autocaptureConfig: AutocaptureConfig | undefined\n): boolean {\n const allowlist = autocaptureConfig?.element_allowlist\n if (isUndefined(allowlist)) {\n // everything is allowed, when there is no allow list\n return true\n }\n\n // check each element in the tree\n // if any of the elements are in the allow list, then the tree is allowed\n for (const el of elements) {\n if (allowlist.some((elementType) => el.tagName.toLowerCase() === elementType)) {\n return true\n }\n }\n\n // otherwise there is an allow list and this element tree didn't match it\n return false\n}\n\n/*\n if there is no selector list (i.e. it is undefined), then any elements matches\n if there is an empty list, then no elements match\n if there is a selector list, then check it against each element provided\n */\nfunction checkIfElementsMatchCSSSelector(elements: Element[], selectorList: string[] | undefined): boolean {\n if (isUndefined(selectorList)) {\n // everything is allowed, when there is no selector list\n return true\n }\n\n for (const el of elements) {\n if (selectorList.some((selector) => el.matches(selector))) {\n return true\n }\n }\n\n return false\n}\n\nexport function getParentElement(curEl: Element): Element | false {\n const parentNode = curEl.parentNode\n if (!parentNode || !isElementNode(parentNode)) return false\n return parentNode\n}\n\nconst DEFAULT_CONTENT_IGNORELIST = ['next', 'previous', 'prev', '>', '<']\nconst MAX_CONTENT_IGNORELIST_ENTRIES = 10\n\ninterface ElementWithText {\n safeText: string\n ariaLabel: string\n}\n\nfunction shouldIgnoreByContent(\n contentIgnorelist: boolean | string[] | undefined,\n elementsWithText: ElementWithText[]\n): boolean {\n if (contentIgnorelist === false || isUndefined(contentIgnorelist)) {\n return false\n }\n\n let keywords: string[]\n if (contentIgnorelist === true) {\n keywords = DEFAULT_CONTENT_IGNORELIST\n } else if (isArray(contentIgnorelist)) {\n if (contentIgnorelist.length > MAX_CONTENT_IGNORELIST_ENTRIES) {\n logger.error(\n `[PostHog] content_ignorelist array cannot exceed ${MAX_CONTENT_IGNORELIST_ENTRIES} items. Use css_selector_ignorelist for more complex matching.`\n )\n return false\n }\n keywords = contentIgnorelist.map((k) => k.toLowerCase())\n } else {\n return false\n }\n\n return elementsWithText.some(({ safeText, ariaLabel }) => {\n return keywords.some((keyword) => safeText.includes(keyword) || ariaLabel.includes(keyword))\n })\n}\n\n// autocapture check will already filter for ph-no-capture,\n// but we include it here to protect against future changes accidentally removing that check\nconst DEFAULT_RAGE_CLICK_IGNORE_LIST = ['.ph-no-rageclick', '.ph-no-capture']\nexport function shouldCaptureRageclick(el: Element | null, _config: PostHogConfig['rageclick']) {\n if (!window || cannotCheckForAutocapture(el)) {\n return false\n }\n\n let selectorIgnoreList: string[] | boolean\n let contentIgnorelist: boolean | string[] | undefined\n if (isBoolean(_config)) {\n selectorIgnoreList = _config ? DEFAULT_RAGE_CLICK_IGNORE_LIST : false\n // For backward compatibility, don't enable content filtering for rageclick: true\n contentIgnorelist = undefined\n } else {\n selectorIgnoreList = _config?.css_selector_ignorelist ?? DEFAULT_RAGE_CLICK_IGNORE_LIST\n contentIgnorelist = _config?.content_ignorelist\n }\n\n if (selectorIgnoreList === false) {\n return false\n }\n\n // Traverse DOM once and cache element data to avoid redundant calls to getSafeText\n const { targetElementList } = getElementAndParentsForElement(el, false)\n const elementsWithText: ElementWithText[] = targetElementList.map((element) => ({\n safeText: getSafeText(element).toLowerCase(),\n ariaLabel: element.getAttribute('aria-label')?.toLowerCase().trim() || '',\n }))\n\n if (shouldIgnoreByContent(contentIgnorelist, elementsWithText)) {\n return false\n }\n\n // we don't capture if we match the ignore list\n return !checkIfElementsMatchCSSSelector(targetElementList, selectorIgnoreList)\n}\n\nconst cannotCheckForAutocapture = (el: Element | null) => {\n return !el || isTag(el, 'html') || !isElementNode(el)\n}\n\nconst getElementAndParentsForElement = (el: Element, captureOnAnyElement: false | true | undefined) => {\n if (!window || cannotCheckForAutocapture(el)) {\n return { parentIsUsefulElement: false, targetElementList: [] }\n }\n\n let parentIsUsefulElement = false\n const targetElementList: Element[] = [el]\n let curEl: Element = el\n while (curEl.parentNode && !isTag(curEl, 'body')) {\n // If element is a shadow root, we skip it\n if (isDocumentFragment(curEl.parentNode)) {\n targetElementList.push((curEl.parentNode as any).host)\n curEl = (curEl.parentNode as any).host\n continue\n }\n const parentNode = getParentElement(curEl)\n if (!parentNode) break\n if (captureOnAnyElement || autocaptureCompatibleElements.indexOf(parentNode.tagName.toLowerCase()) > -1) {\n parentIsUsefulElement = true\n } else {\n const compStyles = window.getComputedStyle(parentNode)\n if (compStyles && compStyles.getPropertyValue('cursor') === 'pointer') {\n parentIsUsefulElement = true\n }\n }\n\n targetElementList.push(parentNode)\n curEl = parentNode\n }\n return { parentIsUsefulElement, targetElementList }\n}\n\n/*\n * Check whether a DOM event should be \"captured\" or if it may contain sensitive data\n * using a variety of heuristics.\n * @param {Element} el - element to check\n * @param {Event} event - event to check\n * @param {Object} autocaptureConfig - autocapture config\n * @param {boolean} captureOnAnyElement - whether to capture on any element, clipboard autocapture doesn't restrict to \"clickable\" elements\n * @param {string[]} allowedEventTypes - event types to capture, normally just 'click', but some autocapture types react to different events, some elements have fixed events (e.g., form has \"submit\")\n * @returns {boolean} whether the event should be captured\n */\nexport function shouldCaptureDomEvent(\n el: Element,\n event: Event,\n autocaptureConfig: AutocaptureConfig | undefined = undefined,\n captureOnAnyElement?: boolean,\n allowedEventTypes?: string[]\n): boolean {\n if (!window || cannotCheckForAutocapture(el)) {\n return false\n }\n\n if (autocaptureConfig?.url_allowlist) {\n // if the current URL is not in the allow list, don't capture\n if (!checkForURLMatches(autocaptureConfig.url_allowlist)) {\n return false\n }\n }\n\n if (autocaptureConfig?.url_ignorelist) {\n // if the current URL is in the ignore list, don't capture\n if (checkForURLMatches(autocaptureConfig.url_ignorelist)) {\n return false\n }\n }\n\n if (autocaptureConfig?.dom_event_allowlist) {\n const allowlist = autocaptureConfig.dom_event_allowlist\n if (allowlist && !allowlist.some((eventType) => event.type === eventType)) {\n return false\n }\n }\n\n const { parentIsUsefulElement, targetElementList } = getElementAndParentsForElement(el, captureOnAnyElement)\n\n if (!checkIfElementTreePassesElementAllowList(targetElementList, autocaptureConfig)) {\n return false\n }\n\n if (!checkIfElementsMatchCSSSelector(targetElementList, autocaptureConfig?.css_selector_allowlist)) {\n return false\n }\n\n const compStyles = window.getComputedStyle(el)\n if (compStyles && compStyles.getPropertyValue('cursor') === 'pointer' && event.type === 'click') {\n return true\n }\n\n const tag = el.tagName.toLowerCase()\n switch (tag) {\n case 'html':\n return false\n case 'form':\n return (allowedEventTypes || ['submit']).indexOf(event.type) >= 0\n case 'input':\n case 'select':\n case 'textarea':\n return (allowedEventTypes || ['change', 'click']).indexOf(event.type) >= 0\n default:\n if (parentIsUsefulElement) return (allowedEventTypes || ['click']).indexOf(event.type) >= 0\n return (\n (allowedEventTypes || ['click']).indexOf(event.type) >= 0 &&\n (autocaptureCompatibleElements.indexOf(tag) > -1 || el.getAttribute('contenteditable') === 'true')\n )\n }\n}\n\n/*\n * Check whether a DOM element should be \"captured\" or if it may contain sensitive data\n * using a variety of heuristics.\n * @param {Element} el - element to check\n * @returns {boolean} whether the element should be captured\n */\nexport function shouldCaptureElement(el: Element): boolean {\n for (let curEl = el; curEl.parentNode && !isTag(curEl, 'body'); curEl = curEl.parentNode as Element) {\n const classes = getClassNames(curEl)\n if (includes(classes, 'ph-sensitive') || includes(classes, 'ph-no-capture')) {\n return false\n }\n }\n\n if (includes(getClassNames(el), 'ph-include')) {\n return true\n }\n\n // don't include hidden or password fields\n const type = (el as HTMLInputElement).type || ''\n if (isString(type)) {\n // it's possible for el.type to be a DOM element if el is a form with a child input[name=\"type\"]\n switch (type.toLowerCase()) {\n case 'hidden':\n return false\n case 'password':\n return false\n }\n }\n\n // filter out data from fields that look like sensitive fields\n const name = (el as HTMLInputElement).name || el.id || ''\n // See https://github.com/posthog/posthog-js/issues/165\n // Under specific circumstances a bug caused .replace to be called on a DOM element\n // instead of a string, removing the element from the page. Ensure this issue is mitigated.\n if (isString(name)) {\n // it's possible for el.name or el.id to be a DOM element if el is a form with a child input[name=\"name\"]\n const sensitiveNameRegex =\n /^cc|cardnum|ccnum|creditcard|csc|cvc|cvv|exp|pass|pwd|routing|seccode|securitycode|securitynum|socialsec|socsec|ssn/i\n if (sensitiveNameRegex.test(name.replace(/[^a-zA-Z0-9]/g, ''))) {\n return false\n }\n }\n\n return true\n}\n\n/*\n * Check whether a DOM element is 'sensitive' and we should only capture limited data\n * @param {Element} el - element to check\n * @returns {boolean} whether the element should be captured\n */\nexport function isSensitiveElement(el: Element): boolean {\n // don't send data from inputs or similar elements since there will always be\n // a risk of clientside javascript placing sensitive data in attributes\n const allowedInputTypes = ['button', 'checkbox', 'submit', 'reset']\n if (\n (isTag(el, 'input') && !allowedInputTypes.includes((el as HTMLInputElement).type)) ||\n isTag(el, 'select') ||\n isTag(el, 'textarea') ||\n el.getAttribute('contenteditable') === 'true'\n ) {\n return true\n }\n return false\n}\n\n// Define the core pattern for matching credit card numbers\nconst 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})`\n// Create the Anchored version of the regex by adding '^' at the start and '$' at the end\nconst anchoredCCRegex = new RegExp(`^(?:${coreCCPattern})$`)\n// The Unanchored version is essentially the core pattern, usable as is for partial matches\nconst unanchoredCCRegex = new RegExp(coreCCPattern)\n\n// Define the core pattern for matching SSNs with optional dashes\nconst coreSSNPattern = `\\\\d{3}-?\\\\d{2}-?\\\\d{4}`\n// Create the Anchored version of the regex by adding '^' at the start and '$' at the end\nconst anchoredSSNRegex = new RegExp(`^(${coreSSNPattern})$`)\n// The Unanchored version is essentially the core pattern itself, usable for partial matches\nconst unanchoredSSNRegex = new RegExp(`(${coreSSNPattern})`)\n\n/*\n * Check whether a string value should be \"captured\" or if it may contain sensitive data\n * using a variety of heuristics.\n * @param {string} value - string value to check\n * @param {boolean} anchorRegexes - whether to anchor the regexes to the start and end of the string\n * @returns {boolean} whether the element should be captured\n */\nexport function shouldCaptureValue(value: string, anchorRegexes = true): boolean {\n if (isNullish(value)) {\n return false\n }\n\n if (isString(value)) {\n value = trim(value)\n\n // check to see if input value looks like a credit card number\n // see: https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch04s20.html\n const ccRegex = anchorRegexes ? anchoredCCRegex : unanchoredCCRegex\n if (ccRegex.test((value || '').replace(/[- ]/g, ''))) {\n return false\n }\n\n // check to see if input value looks like a social security number\n const ssnRegex = anchorRegexes ? anchoredSSNRegex : unanchoredSSNRegex\n if (ssnRegex.test(value)) {\n return false\n }\n }\n\n return true\n}\n\n/*\n * Check whether an attribute name is an Angular style attr (either _ngcontent or _nghost)\n * These update on each build and lead to noise in the element chain\n * More details on the attributes here: https://angular.io/guide/view-encapsulation\n * @param {string} attributeName - string value to check\n * @returns {boolean} whether the element is an angular tag\n */\nexport function isAngularStyleAttr(attributeName: string): boolean {\n if (isString(attributeName)) {\n return attributeName.substring(0, 10) === '_ngcontent' || attributeName.substring(0, 7) === '_nghost'\n }\n return false\n}\n\n/*\n * Iterate through children of a target element looking for span tags\n * and return the text content of the span tags, separated by spaces,\n * along with the direct text content of the target element\n * @param {Element} target - element to check\n * @returns {string} text content of the target element and its child span tags\n */\nexport function getDirectAndNestedSpanText(target: Element): string {\n let text = getSafeText(target)\n text = `${text} ${getNestedSpanText(target)}`.trim()\n return shouldCaptureValue(text) ? text : ''\n}\n\n/*\n * Iterate through children of a target element looking for span tags\n * and return the text content of the span tags, separated by spaces\n * @param {Element} target - element to check\n * @returns {string} text content of span tags\n */\nexport function getNestedSpanText(target: Element): string {\n let text = ''\n if (target && target.childNodes && target.childNodes.length) {\n each(target.childNodes, function (child) {\n if (child && child.tagName?.toLowerCase() === 'span') {\n try {\n const spanText = getSafeText(child)\n text = `${text} ${spanText}`.trim()\n\n if (child.childNodes && child.childNodes.length) {\n text = `${text} ${getNestedSpanText(child)}`.trim()\n }\n } catch (e) {\n logger.error('[AutoCapture]', e)\n }\n }\n })\n }\n return text\n}\n\n/*\nBack in the day storing events in Postgres we use Elements for autocapture events.\nNow we're using elements_chain. We used to do this parsing/processing during ingestion.\nThis code is just copied over from ingestion, but we should optimize it\nto create elements_chain string directly.\n*/\nexport function getElementsChainString(elements: Properties[]): string {\n return elementsToString(extractElements(elements))\n}\n\n// This interface is called 'Element' in plugin-scaffold https://github.com/PostHog/plugin-scaffold/blob/b07d3b879796ecc7e22deb71bf627694ba05386b/src/types.ts#L200\n// However 'Element' is a DOM Element when run in the browser, so we have to rename it\ninterface PHElement {\n text?: string\n tag_name?: string\n href?: string\n attr_id?: string\n attr_class?: string[]\n nth_child?: number\n nth_of_type?: number\n attributes?: Record<string, any>\n event_id?: number\n order?: number\n group_id?: number\n}\n\nfunction escapeQuotes(input: string): string {\n return input.replace(/\"|\\\\\"/g, '\\\\\"')\n}\n\nfunction elementsToString(elements: PHElement[]): string {\n const ret = elements.map((element) => {\n let el_string = ''\n if (element.tag_name) {\n el_string += element.tag_name\n }\n if (element.attr_class) {\n element.attr_class.sort()\n for (const single_class of element.attr_class) {\n el_string += `.${single_class.replace(/\"/g, '')}`\n }\n }\n const attributes: Record<string, any> = {\n ...(element.text ? { text: element.text } : {}),\n 'nth-child': element.nth_child ?? 0,\n 'nth-of-type': element.nth_of_type ?? 0,\n ...(element.href ? { href: element.href } : {}),\n ...(element.attr_id ? { attr_id: element.attr_id } : {}),\n ...element.attributes,\n }\n const sortedAttributes: Record<string, any> = {}\n entries(attributes)\n .sort(([a], [b]) => a.localeCompare(b))\n .forEach(\n ([key, value]) => (sortedAttributes[escapeQuotes(key.toString())] = escapeQuotes(value.toString()))\n )\n el_string += ':'\n el_string += entries(sortedAttributes)\n .map(([key, value]) => `${key}=\"${value}\"`)\n .join('')\n return el_string\n })\n return ret.join(';')\n}\n\nfunction extractElements(elements: Properties[]): PHElement[] {\n return elements.map((el) => {\n const response = {\n text: el['$el_text']?.slice(0, 400),\n tag_name: el['tag_name'],\n href: el['attr__href']?.slice(0, 2048),\n attr_class: extractAttrClass(el),\n attr_id: el['attr__id'],\n nth_child: el['nth_child'],\n nth_of_type: el['nth_of_type'],\n attributes: {} as { [id: string]: any },\n }\n\n entries(el)\n .filter(([key]) => key.indexOf('attr__') === 0)\n .forEach(([key, value]) => (response.attributes[key] = value))\n return response\n })\n}\n\nfunction extractAttrClass(el: Properties): PHElement['attr_class'] {\n const attr_class = el['attr__class']\n if (!attr_class) {\n return undefined\n } else if (isArray(attr_class)) {\n return attr_class\n } else {\n return splitClassString(attr_class)\n }\n}\n","// Naive rage click implementation: If mouse has not moved further than thresholdPx\n// over clickCount clicks with max timeoutMs between clicks, it's\n// counted as a rage click\n\nimport { isObject } from '@posthog/core'\nimport { RageclickConfig } from '../types'\n\nconst DEFAULT_THRESHOLD_PX = 30\nconst DEFAULT_TIMEOUT_MS = 1000\nconst DEFAULT_CLICK_COUNT = 3\n\nexport default class RageClick {\n clicks: { x: number; y: number; timestamp: number }[]\n\n thresholdPx: number\n timeoutMs: number\n clickCount: number\n disabled: boolean\n\n constructor(rageclickConfig: RageclickConfig | boolean) {\n this.disabled = rageclickConfig === false\n const conf = isObject(rageclickConfig) ? rageclickConfig : {}\n\n this.thresholdPx = conf.threshold_px || DEFAULT_THRESHOLD_PX\n this.timeoutMs = conf.timeout_ms || DEFAULT_TIMEOUT_MS\n this.clickCount = conf.click_count || DEFAULT_CLICK_COUNT\n\n this.clicks = []\n }\n\n isRageClick(x: number, y: number, timestamp: number): boolean {\n if (this.disabled) {\n return false\n }\n\n const lastClick = this.clicks[this.clicks.length - 1]\n if (\n lastClick &&\n Math.abs(x - lastClick.x) + Math.abs(y - lastClick.y) < this.thresholdPx &&\n timestamp - lastClick.timestamp < this.timeoutMs\n ) {\n this.clicks.push({ x, y, timestamp })\n\n if (this.clicks.length === this.clickCount) {\n return true\n }\n } else {\n this.clicks = [{ x, y, timestamp }]\n }\n\n return false\n }\n}\n","import { each } from './'\n\nimport { isArray, isFile, isUndefined } from '@posthog/core'\nimport { logger } from './logger'\nimport { document } from './globals'\n\nconst localDomains = ['localhost', '127.0.0.1']\n\n/**\n * IE11 doesn't support `new URL`\n * so we can create an anchor element and use that to parse the URL\n * there's a lot of overlap between HTMLHyperlinkElementUtils and URL\n * meaning useful properties like `pathname` are available on both\n */\nexport const convertToURL = (url: string): HTMLAnchorElement | null => {\n const location = document?.createElement('a')\n if (isUndefined(location)) {\n return null\n }\n\n location.href = url\n return location\n}\n\nexport const formDataToQuery = function (formdata: Record<string, any> | FormData, arg_separator = '&'): string {\n let use_val: string\n let use_key: string\n const tph_arr: string[] = []\n\n each(formdata, function (val: File | string | undefined, key: string | undefined) {\n // the key might be literally the string undefined for e.g. if {undefined: 'something'}\n if (isUndefined(val) || isUndefined(key) || key === 'undefined') {\n return\n }\n\n use_val = encodeURIComponent(isFile(val) ? val.name : val.toString())\n use_key = encodeURIComponent(key)\n tph_arr[tph_arr.length] = use_key + '=' + use_val\n })\n\n return tph_arr.join(arg_separator)\n}\n\n// NOTE: Once we get rid of IE11/op_mini we can start using URLSearchParams\nexport const getQueryParam = function (url: string, param: string): string {\n const withoutHash: string = url.split('#')[0] || ''\n\n // Split only on the first ? to sort problem out for those with multiple ?s\n // and then remove them\n const queryParams: string = withoutHash.split(/\\?(.*)/)[1] || ''\n const cleanedQueryParams = queryParams.replace(/^\\?+/g, '')\n\n const queryParts = cleanedQueryParams.split('&')\n let keyValuePair\n\n for (let i = 0; i < queryParts.length; i++) {\n const parts = queryParts[i].split('=')\n if (parts[0] === param) {\n keyValuePair = parts\n break\n }\n }\n\n if (!isArray(keyValuePair) || keyValuePair.length < 2) {\n return ''\n } else {\n let result = keyValuePair[1]\n try {\n result = decodeURIComponent(result)\n } catch {\n logger.error('Skipping decoding for malformed query param: ' + result)\n }\n return result.replace(/\\+/g, ' ')\n }\n}\n\n// replace any query params in the url with the provided mask value. Tries to keep the URL as instant as possible,\n// including preserving malformed text in most cases\nexport const maskQueryParams = function <T extends string | undefined>(\n url: T,\n maskedParams: string[] | undefined,\n mask: string\n): T extends string ? string : undefined {\n if (!url || !maskedParams || !maskedParams.length) {\n return url as any\n }\n\n const splitHash = url.split('#')\n const withoutHash: string = splitHash[0] || ''\n const hash = splitHash[1]\n\n const splitQuery: string[] = withoutHash.split('?')\n const queryString: string = splitQuery[1]\n const urlWithoutQueryAndHash: string = splitQuery[0]\n const queryParts = (queryString || '').split('&')\n\n // use an array of strings rather than an object to preserve ordering and duplicates\n const paramStrings: string[] = []\n\n for (let i = 0; i < queryParts.length; i++) {\n const keyValuePair = queryParts[i].split('=')\n if (!isArray(keyValuePair)) {\n continue\n } else if (maskedParams.includes(keyValuePair[0])) {\n paramStrings.push(keyValuePair[0] + '=' + mask)\n } else {\n paramStrings.push(queryParts[i])\n }\n }\n\n let result = urlWithoutQueryAndHash\n if (queryString != null) {\n result += '?' + paramStrings.join('&')\n }\n if (hash != null) {\n result += '#' + hash\n }\n\n return result as any\n}\n\nexport const _getHashParam = function (hash: string, param: string): string | null {\n const matches = hash.match(new RegExp(param + '=([^&]*)'))\n return matches ? matches[1] : null\n}\n\nexport const isLocalhost = (): boolean => {\n return localDomains.includes(location.hostname)\n}\n","import { addEventListener, each, extend } from './utils'\nimport {\n autocaptureCompatibleElements,\n getClassNames,\n getDirectAndNestedSpanText,\n getElementsChainString,\n getEventTarget,\n getSafeText,\n isAngularStyleAttr,\n isSensitiveElement,\n makeSafeText,\n shouldCaptureDomEvent,\n shouldCaptureElement,\n shouldCaptureRageclick,\n shouldCaptureValue,\n splitClassString,\n} from './autocapture-utils'\n\nimport RageClick from './extensions/rageclick'\nimport { AutocaptureConfig, EventName, Properties, RemoteConfig } from './types'\nimport { PostHog } from './posthog-core'\nimport { AUTOCAPTURE_DISABLED_SERVER_SIDE } from './constants'\n\nimport { isBoolean, isFunction, isNull, isObject } from '@posthog/core'\nimport { createLogger } from './utils/logger'\nimport { document, window } from './utils/globals'\nimport { convertToURL } from './utils/request-utils'\nimport { isDocumentFragment, isElementNode, isTag, isTextNode } from './utils/element-utils'\nimport { includes } from '@posthog/core'\n\nconst COPY_AUTOCAPTURE_EVENT = '$copy_autocapture'\n\nconst logger = createLogger('[AutoCapture]')\n\nfunction limitText(length: number, text: string): string {\n if (text.length > length) {\n return text.slice(0, length) + '...'\n }\n return text\n}\n\nexport function getAugmentPropertiesFromElement(elem: Element): Properties {\n const shouldCaptureEl = shouldCaptureElement(elem)\n if (!shouldCaptureEl) {\n return {}\n }\n\n const props: Properties = {}\n\n each(elem.attributes, function (attr: Attr) {\n if (attr.name && attr.name.indexOf('data-ph-capture-attribute') === 0) {\n const propertyKey = attr.name.replace('data-ph-capture-attribute-', '')\n const propertyValue = attr.value\n if (propertyKey && propertyValue && shouldCaptureValue(propertyValue)) {\n props[propertyKey] = propertyValue\n }\n }\n })\n\n return props\n}\n\nexport function previousElementSibling(el: Element): Element | null {\n if (el.previousElementSibling) {\n return el.previousElementSibling\n }\n let _el: Element | null = el\n do {\n _el = _el.previousSibling as Element | null // resolves to ChildNode->Node, which is Element's parent class\n } while (_el && !isElementNode(_el))\n return _el\n}\n\nexport function getDefaultProperties(eventType: string): Properties {\n return {\n $event_type: eventType,\n $ce_version: 1,\n }\n}\n\nexport function getPropertiesFromElement(\n elem: Element,\n maskAllAttributes: boolean,\n maskText: boolean,\n elementAttributeIgnorelist: string[] | undefined\n): Properties {\n const tag_name = elem.tagName.toLowerCase()\n const props: Properties = {\n tag_name: tag_name,\n }\n if (autocaptureCompatibleElements.indexOf(tag_name) > -1 && !maskText) {\n if (tag_name.toLowerCase() === 'a' || tag_name.toLowerCase() === 'button') {\n props['$el_text'] = limitText(1024, getDirectAndNestedSpanText(elem))\n } else {\n props['$el_text'] = limitText(1024, getSafeText(elem))\n }\n }\n\n const classes = getClassNames(elem)\n if (classes.length > 0)\n props['classes'] = classes.filter(function (c) {\n return c !== ''\n })\n\n // capture the deny list here because this not-a-class class makes it tricky to use this.config in the function below\n each(elem.attributes, function (attr: Attr) {\n // Only capture attributes we know are safe\n if (isSensitiveElement(elem) && ['name', 'id', 'class', 'aria-label'].indexOf(attr.name) === -1) return\n\n if (elementAttributeIgnorelist?.includes(attr.name)) return\n\n if (!maskAllAttributes && shouldCaptureValue(attr.value) && !isAngularStyleAttr(attr.name)) {\n let value = attr.value\n if (attr.name === 'class') {\n // html attributes can _technically_ contain linebreaks,\n // but we're very intolerant of them in the class string,\n // so we strip them.\n value = splitClassString(value).join(' ')\n }\n props['attr__' + attr.name] = limitText(1024, value)\n }\n })\n\n let nthChild = 1\n let nthOfType = 1\n let currentElem: Element | null = elem\n while ((currentElem = previousElementSibling(currentElem))) {\n // eslint-disable-line no-cond-assign\n nthChild++\n if (currentElem.tagName === elem.tagName) {\n nthOfType++\n }\n }\n props['nth_child'] = nthChild\n props['nth_of_type'] = nthOfType\n\n return props\n}\n\nexport function autocapturePropertiesForElement(\n target: Element,\n {\n e,\n maskAllElementAttributes,\n maskAllText,\n elementAttributeIgnoreList,\n elementsChainAsString,\n }: {\n e: Event\n maskAllElementAttributes: boolean\n maskAllText: boolean\n elementAttributeIgnoreList?: string[] | undefined\n elementsChainAsString: boolean\n }\n): { props: Properties; explicitNoCapture?: boolean } {\n const targetElementList = [target]\n let curEl = target\n while (curEl.parentNode && !isTag(curEl, 'body')) {\n if (isDocumentFragment(curEl.parentNode)) {\n targetElementList.push((curEl.parentNode as any).host)\n curEl = (curEl.parentNode as any).host\n continue\n }\n targetElementList.push(curEl.parentNode as Element)\n curEl = curEl.parentNode as Element\n }\n\n const elementsJson: Properties[] = []\n const autocaptureAugmentProperties: Properties = {}\n let href: string | false = false\n let explicitNoCapture = false\n\n each(targetElementList, (el) => {\n const shouldCaptureEl = shouldCaptureElement(el)\n\n // if the element or a parent element is an anchor tag\n // include the href as a property\n if (el.tagName.toLowerCase() === 'a') {\n href = el.getAttribute('href')\n href = shouldCaptureEl && href && shouldCaptureValue(href) && href\n }\n\n // allow users to programmatically prevent capturing of elements by adding class 'ph-no-capture'\n const classes = getClassNames(el)\n if (includes(classes, 'ph-no-capture')) {\n explicitNoCapture = true\n }\n\n elementsJson.push(\n getPropertiesFromElement(el, maskAllElementAttributes, maskAllText, elementAttributeIgnoreList)\n )\n\n const augmentProperties = getAugmentPropertiesFromElement(el)\n extend(autocaptureAugmentProperties, augmentProperties)\n })\n\n if (explicitNoCapture) {\n return { props: {}, explicitNoCapture }\n }\n\n if (!maskAllText) {\n // if the element is a button or anchor tag get the span text from any\n // children and include it as/with the text property on the parent element\n if (target.tagName.toLowerCase() === 'a' || target.tagName.toLowerCase() === 'button') {\n elementsJson[0]['$el_text'] = getDirectAndNestedSpanText(target)\n } else {\n elementsJson[0]['$el_text'] = getSafeText(target)\n }\n }\n\n let externalHref: string | undefined\n if (href) {\n elementsJson[0]['attr__href'] = href\n const hrefHost = convertToURL(href)?.host\n const locationHost = window?.location?.host\n if (hrefHost && locationHost && hrefHost !== locationHost) {\n externalHref = href\n }\n }\n\n const props = extend(\n getDefaultProperties(e.type),\n // Sending \"$elements\" is deprecated. Only one client on US cloud uses this.\n !elementsChainAsString ? { $elements: elementsJson } : {},\n // Always send $elements_chain, as it's needed downstream in site app filtering\n { $elements_chain: getElementsChainString(elementsJson) },\n elementsJson[0]?.['$el_text'] ? { $el_text: elementsJson[0]?.['$el_text'] } : {},\n externalHref && e.type === 'click' ? { $external_click_url: externalHref } : {},\n autocaptureAugmentProperties\n )\n\n return { props }\n}\n\nexport class Autocapture {\n instance: PostHog\n _initialized: boolean = false\n _isDisabledServerSide: boolean | null = null\n _elementSelectors: Set<string> | null\n rageclicks: RageClick\n _elementsChainAsString = false\n\n constructor(instance: PostHog) {\n this.instance = instance\n this.rageclicks = new RageClick(instance.config.rageclick)\n this._elementSelectors = null\n }\n\n private get _config(): AutocaptureConfig {\n const config = isObject(this.instance.config.autocapture) ? this.instance.config.autocapture : {}\n // precompile the regex\n config.url_allowlist = config.url_allowlist?.map((url) => new RegExp(url))\n config.url_ignorelist = config.url_ignorelist?.map((url) => new RegExp(url))\n return config\n }\n\n _addDomEventHandlers(): void {\n if (!this.isBrowserSupported()) {\n logger.info('Disabling Automatic Event Collection because this browser is not supported')\n return\n }\n\n if (!window || !document) {\n return\n }\n\n const handler = (e: Event) => {\n e = e || window?.event\n try {\n this._captureEvent(e)\n } catch (error) {\n logger.error('Failed to capture event', error)\n }\n }\n\n addEventListener(document, 'submit', handler, { capture: true })\n addEventListener(document, 'change', handler, { capture: true })\n addEventListener(document, 'click', handler, { capture: true })\n\n if (this._config.capture_copied_text) {\n const copiedTextHandler = (e: Event) => {\n e = e || window?.event\n this._captureEvent(e, COPY_AUTOCAPTURE_EVENT)\n }\n\n addEventListener(document, 'copy', copiedTextHandler, { capture: true })\n addEventListener(document, 'cut', copiedTextHandler, { capture: true })\n }\n }\n\n public startIfEnabled() {\n if (this.isEnabled && !this._initialized) {\n this._addDomEventHandlers()\n this._initialized = true\n }\n }\n\n public onRemoteConfig(response: RemoteConfig) {\n if (response.elementsChainAsString) {\n this._elementsChainAsString = response.elementsChainAsString\n }\n\n if (this.instance.persistence) {\n this.instance.persistence.register({\n [AUTOCAPTURE_DISABLED_SERVER_SIDE]: !!response['autocapture_opt_out'],\n })\n }\n // store this in-memory in case persistence is disabled\n this._isDisabledServerSide = !!response['autocapture_opt_out']\n this.startIfEnabled()\n }\n\n public setElementSelectors(selectors: Set<string>): void {\n this._elementSelectors = selectors\n }\n\n public getElementSelectors(element: Element | null): string[] | null {\n const elementSelectors: string[] = []\n\n this._elementSelectors?.forEach((selector) => {\n const matchedElements = document?.querySelectorAll(selector)\n matchedElements?.forEach((matchedElement: Element) => {\n if (element === matchedElement) {\n elementSelectors.push(selector)\n }\n })\n })\n\n return elementSelectors\n }\n\n public get isEnabled(): boolean {\n const persistedServerDisabled = this.instance.persistence?.props[AUTOCAPTURE_DISABLED_SERVER_SIDE]\n const memoryDisabled = this._isDisabledServerSide\n\n if (isNull(memoryDisabled) && !isBoolean(persistedServerDisabled) && !this.instance._shouldDisableFlags()) {\n // We only enable if we know that the server has not disabled it (unless /flags is disabled)\n return false\n }\n\n const disabledServer = this._isDisabledServerSide ?? !!persistedServerDisabled\n const disabledClient = !this.instance.config.autocapture\n return !disabledClient && !disabledServer\n }\n\n private _captureEvent(e: Event, eventName: EventName = '$autocapture'): boolean | void {\n if (!this.isEnabled) {\n return\n }\n\n /*** Don't mess with this code without running IE8 tests on it ***/\n let target = getEventTarget(e)\n if (isTextNode(target)) {\n // defeat Safari bug (see: http://www.quirksmode.org/js/events_properties.html)\n target = (target.parentNode || null) as Element | null\n }\n\n if (eventName === '$autocapture' && e.type === 'click' && e instanceof MouseEvent) {\n if (\n !!this.instance.config.rageclick &&\n this.rageclicks?.isRageClick(e.clientX, e.clientY, e.timeStamp || new Date().getTime())\n ) {\n if (shouldCaptureRageclick(target, this.instance.config.rageclick)) {\n this._captureEvent(e, '$rageclick')\n }\n }\n }\n\n const isCopyAutocapture = eventName === COPY_AUTOCAPTURE_EVENT\n if (\n target &&\n shouldCaptureDomEvent(\n target,\n e,\n this._config,\n // mostly this method cares about the target element, but in the case of copy events,\n // we want some of the work this check does without insisting on the target element's type\n isCopyAutocapture,\n // we also don't want to restrict copy checks to clicks,\n // so we pass that knowledge in here, rather than add the logic inside the check\n isCopyAutocapture ? ['copy', 'cut'] : undefined\n )\n ) {\n const { props, explicitNoCapture } = autocapturePropertiesForElement(target, {\n e,\n maskAllElementAttributes: this.instance.config.mask_all_element_attributes,\n maskAllText: this.instance.config.mask_all_text,\n elementAttributeIgnoreList: this._config.element_attribute_ignorelist,\n elementsChainAsString: this._elementsChainAsString,\n })\n\n if (explicitNoCapture) {\n return false\n }\n\n const elementSelectors = this.getElementSelectors(target)\n if (elementSelectors && elementSelectors.length > 0) {\n props['$element_selectors'] = elementSelectors\n }\n\n if (eventName === COPY_AUTOCAPTURE_EVENT) {\n // you can't read the data from the clipboard event,\n // but you can guess that you can read it from the window's current selection\n const selectedContent = makeSafeText(window?.getSelection()?.toString())\n const clipType = (e as ClipboardEvent).type || 'clipboard'\n if (!selectedContent) {\n return false\n }\n props['$selected_content'] = selectedContent\n props['$copy_type'] = clipType\n }\n\n this.instance.capture(eventName, props)\n return true\n }\n }\n\n isBrowserSupported(): boolean {\n return isFunction(document?.querySelectorAll)\n }\n}\n","/**\n * uuidv7: An experimental implementation of the proposed UUID Version 7\n *\n * @license Apache-2.0\n * @copyright 2021-2023 LiosK\n * @packageDocumentation\n *\n * from https://github.com/LiosK/uuidv7/blob/e501462ea3d23241de13192ceae726956f9b3b7d/src/index.ts\n */\n\n// polyfill for IE11\nimport { window } from './utils/globals'\n\nimport { isNumber, isUndefined } from '@posthog/core'\n\nif (!Math.trunc) {\n Math.trunc = function (v) {\n return v < 0 ? Math.ceil(v) : Math.floor(v)\n }\n}\n\n// polyfill for IE11\nif (!Number.isInteger) {\n Number.isInteger = function (value) {\n return isNumber(value) && isFinite(value) && Math.floor(value) === value\n }\n}\n\nconst DIGITS = '0123456789abcdef'\n\n/** Represents a UUID as a 16-byte byte array. */\nexport class UUID {\n /** @param bytes - The 16-byte byte array representation. */\n constructor(readonly bytes: Readonly<Uint8Array>) {\n if (bytes.length !== 16) {\n throw new TypeError('not 128-bit length')\n }\n }\n\n /**\n * Builds a byte array from UUIDv7 field values.\n *\n * @param unixTsMs - A 48-bit `unix_ts_ms` field value.\n * @param randA - A 12-bit `rand_a` field value.\n * @param randBHi - The higher 30 bits of 62-bit `rand_b` field value.\n * @param randBLo - The lower 32 bits of 62-bit `rand_b` field value.\n */\n static fromFieldsV7(unixTsMs: number, randA: number, randBHi: number, randBLo: number): UUID {\n if (\n !Number.isInteger(unixTsMs) ||\n !Number.isInteger(randA) ||\n !Number.isInteger(randBHi) ||\n !Number.isInteger(randBLo) ||\n unixTsMs < 0 ||\n randA < 0 ||\n randBHi < 0 ||\n randBLo < 0 ||\n unixTsMs > 0xffff_ffff_ffff ||\n randA > 0xfff ||\n randBHi > 0x3fff_ffff ||\n randBLo > 0xffff_ffff\n ) {\n throw new RangeError('invalid field value')\n }\n\n const bytes = new Uint8Array(16)\n bytes[0] = unixTsMs / 2 ** 40\n bytes[1] = unixTsMs / 2 ** 32\n bytes[2] = unixTsMs / 2 ** 24\n bytes[3] = unixTsMs / 2 ** 16\n bytes[4] = unixTsMs / 2 ** 8\n bytes[5] = unixTsMs\n bytes[6] = 0x70 | (randA >>> 8)\n bytes[7] = randA\n bytes[8] = 0x80 | (randBHi >>> 24)\n bytes[9] = randBHi >>> 16\n bytes[10] = randBHi >>> 8\n bytes[11] = randBHi\n bytes[12] = randBLo >>> 24\n bytes[13] = randBLo >>> 16\n bytes[14] = randBLo >>> 8\n bytes[15] = randBLo\n return new UUID(bytes)\n }\n\n /** @returns The 8-4-4-4-12 canonical hexadecimal string representation. */\n toString(): string {\n let text = ''\n for (let i = 0; i < this.bytes.length; i++) {\n text = text + DIGITS.charAt(this.bytes[i] >>> 4) + DIGITS.charAt(this.bytes[i] & 0xf)\n if (i === 3 || i === 5 || i === 7 || i === 9) {\n text += '-'\n }\n }\n\n if (text.length !== 36) {\n // We saw one customer whose bundling code was mangling the UUID generation\n // rather than accept a bad UUID, we throw an error here.\n throw new Error('Invalid UUIDv7 was generated')\n }\n return text\n }\n\n /** Creates an object from `this`. */\n clone(): UUID {\n return new UUID(this.bytes.slice(0))\n }\n\n /** Returns true if `this` is equivalent to `other`. */\n equals(other: UUID): boolean {\n return this.compareTo(other) === 0\n }\n\n /**\n * Returns a negative integer, zero, or positive integer if `this` is less\n * than, equal to, or greater than `other`, respectively.\n */\n compareTo(other: UUID): number {\n for (let i = 0; i < 16; i++) {\n const diff = this.bytes[i] - other.bytes[i]\n if (diff !== 0) {\n return Math.sign(diff)\n }\n }\n return 0\n }\n}\n\n/** Encapsulates the monotonic counter state. */\nclass V7Generator {\n private _timestamp = 0\n private _counter = 0\n private readonly _random = new DefaultRandom()\n\n /**\n * Generates a new UUIDv7 object from the current timestamp, or resets the\n * generator upon significant timestamp rollback.\n *\n * This method returns monotonically increasing UUIDs unless the up-to-date\n * timestamp is significantly (by ten seconds or more) smaller than the one\n * embedded in the immediately preceding UUID. If such a significant clock\n * rollback is detected, this method resets the generator and returns a new\n * UUID based on the current timestamp.\n */\n generate(): UUID {\n const value = this.generateOrAbort()\n if (!isUndefined(value)) {\n return value\n } else {\n // reset state and resume\n this._timestamp = 0\n const valueAfterReset = this.generateOrAbort()\n if (isUndefined(valueAfterReset)) {\n throw new Error('Could not generate UUID after timestamp reset')\n }\n return valueAfterReset\n }\n }\n\n /**\n * Generates a new UUIDv7 object from the current timestamp, or returns\n * `undefined` upon significant timestamp rollback.\n *\n * This method returns monotonically increasing UUIDs unless the up-to-date\n * timestamp is significantly (by ten seconds or more) smaller than the one\n * embedded in the immediately preceding UUID. If such a significant clock\n * rollback is detected, this method aborts and returns `undefined`.\n */\n generateOrAbort(): UUID | undefined {\n const MAX_COUNTER = 0x3ff_ffff_ffff\n const ROLLBACK_ALLOWANCE = 10_000 // 10 seconds\n\n const ts = Date.now()\n if (ts > this._timestamp) {\n this._timestamp = ts\n this._resetCounter()\n } else if (ts + ROLLBACK_ALLOWANCE > this._timestamp) {\n // go on with previous timestamp if new one is not much smaller\n this._counter++\n if (this._counter > MAX_COUNTER) {\n // increment timestamp at counter overflow\n this._timestamp++\n this._resetCounter()\n }\n } else {\n // abort if clock went backwards to unbearable extent\n return undefined\n }\n\n return UUID.fromFieldsV7(\n this._timestamp,\n Math.trunc(this._counter / 2 ** 30),\n this._counter & (2 ** 30 - 1),\n this._random.nextUint32()\n )\n }\n\n /** Initializes the counter at a 42-bit random integer. */\n private _resetCounter(): void {\n this._counter = this._random.nextUint32() * 0x400 + (this._random.nextUint32() & 0x3ff)\n }\n}\n\n/** A global flag to force use of cryptographically strong RNG. */\ndeclare const UUIDV7_DENY_WEAK_RNG: boolean\n\n/** Stores `crypto.getRandomValues()` available in the environment. */\nlet getRandomValues: <T extends Uint8Array | Uint32Array>(buffer: T) => T = (buffer) => {\n // fall back on Math.random() unless the flag is set to true\n // TRICKY: don't use the isUndefined method here as can't pass the reference\n if (typeof UUIDV7_DENY_WEAK_RNG !== 'undefined' && UUIDV7_DENY_WEAK_RNG) {\n throw new Error('no cryptographically strong RNG available')\n }\n\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] = Math.trunc(Math.random() * 0x1_0000) * 0x1_0000 + Math.trunc(Math.random() * 0x1_0000)\n }\n return buffer\n}\n\n// detect Web Crypto API\nif (window && !isUndefined(window.crypto) && crypto.getRandomValues) {\n getRandomValues = (buffer) => crypto.getRandomValues(buffer)\n}\n\n/**\n * Wraps `crypto.getRandomValues()` and compatibles to enable buffering; this\n * uses a small buffer by default to avoid unbearable throughput decline in some\n * environments as well as the waste of time and space for unused values.\n */\nclass DefaultRandom {\n private readonly _buffer = new Uint32Array(8)\n private _cursor = Infinity\n nextUint32(): number {\n if (this._cursor >= this._buffer.length) {\n getRandomValues(this._buffer)\n this._cursor = 0\n }\n return this._buffer[this._cursor++]\n }\n}\n\nlet defaultGenerator: V7Generator | undefined\n\n/**\n * Generates a UUIDv7 string.\n *\n * @returns The 8-4-4-4-12 canonical hexadecimal string representation\n * (\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\").\n */\nexport const uuidv7 = (): string => uuidv7obj().toString()\n\n/** Generates a UUIDv7 object. */\nconst uuidv7obj = (): UUID => (defaultGenerator || (defaultGenerator = new V7Generator())).generate()\n\nexport const uuid7ToTimestampMs = (uuid: string): number => {\n // remove hyphens\n const hex = uuid.replace(/-/g, '')\n // ensure that it's a version 7 UUID\n if (hex.length !== 32) {\n throw new Error('Not a valid UUID')\n }\n if (hex[12] !== '7') {\n throw new Error('Not a UUIDv7')\n }\n // the first 6 bytes are the timestamp, which means that we can read only the first 12 hex characters\n return parseInt(hex.substring(0, 12), 16)\n}\n","import { extend } from './utils'\nimport { PersistentStore, Properties } from './types'\nimport {\n DEVICE_ID,\n DISTINCT_ID,\n ENABLE_PERSON_PROCESSING,\n INITIAL_PERSON_INFO,\n SESSION_ID,\n SESSION_RECORDING_IS_SAMPLED,\n} from './constants'\n\nimport { isNull, isUndefined } from '@posthog/core'\nimport { logger } from './utils/logger'\nimport { window, document } from './utils/globals'\nimport { uuidv7 } from './uuidv7'\n\n// we store the discovered subdomain in memory because it might be read multiple times\nlet firstNonPublicSubDomain = ''\n\n// helper to allow tests to clear this \"cache\"\nexport const resetSubDomainCache = () => {\n firstNonPublicSubDomain = ''\n}\n\n/**\n * Browsers don't offer a way to check if something is a public suffix\n * e.g. `.com.au`, `.io`, `.org.uk`\n *\n * But they do reject cookies set on public suffixes\n * Setting a cookie on `.co.uk` would mean it was sent for every `.co.uk` site visited\n *\n * So, we can use this to check if a domain is a public suffix\n * by trying to set a cookie on a subdomain of the provided hostname\n * until the browser accepts it\n *\n * inspired by https://github.com/AngusFu/browser-root-domain\n */\nexport function seekFirstNonPublicSubDomain(hostname: string, cookieJar = document): string {\n if (firstNonPublicSubDomain) {\n return firstNonPublicSubDomain\n }\n\n if (!cookieJar) {\n return ''\n }\n if (['localhost', '127.0.0.1'].includes(hostname)) return ''\n\n const list = hostname.split('.')\n let len = Math.min(list.length, 8) // paranoia - we know this number should be small\n const key = 'dmn_chk_' + uuidv7()\n\n while (!firstNonPublicSubDomain && len--) {\n const candidate = list.slice(len).join('.')\n const candidateCookieValue = key + '=1;domain=.' + candidate + ';path=/'\n\n // try to set cookie, include a short expiry in seconds since we'll check immediately\n cookieJar.cookie = candidateCookieValue + ';max-age=3'\n\n if (cookieJar.cookie.includes(key)) {\n // the cookie was accepted by the browser, remove the test cookie\n cookieJar.cookie = candidateCookieValue + ';max-age=0'\n firstNonPublicSubDomain = candidate\n }\n }\n\n return firstNonPublicSubDomain\n}\n\nconst DOMAIN_MATCH_REGEX = /[a-z0-9][a-z0-9-]+\\.[a-z]{2,}$/i\nconst originalCookieDomainFn = (hostname: string): string => {\n const matches = hostname.match(DOMAIN_MATCH_REGEX)\n return matches ? matches[0] : ''\n}\n\nexport function chooseCookieDomain(hostname: string, cross_subdomain: boolean | undefined): string {\n if (cross_subdomain) {\n // NOTE: Could we use this for cross domain tracking?\n let matchedSubDomain = seekFirstNonPublicSubDomain(hostname)\n\n if (!matchedSubDomain) {\n const originalMatch = originalCookieDomainFn(hostname)\n if (originalMatch !== matchedSubDomain) {\n logger.info('Warning: cookie subdomain discovery mismatch', originalMatch, matchedSubDomain)\n }\n matchedSubDomain = originalMatch\n }\n\n return matchedSubDomain ? '; domain=.' + matchedSubDomain : ''\n }\n return ''\n}\n\n// Methods partially borrowed from quirksmode.org/js/cookies.html\nexport const cookieStore: PersistentStore = {\n _is_supported: () => !!document,\n\n _error: function (msg) {\n logger.error('cookieStore error: ' + msg)\n },\n\n _get: function (name) {\n if (!document) {\n return\n }\n\n try {\n const nameEQ = name + '='\n const ca = document.cookie.split(';').filter((x) => x.length)\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i]\n while (c.charAt(0) == ' ') {\n c = c.substring(1, c.length)\n }\n if (c.indexOf(nameEQ) === 0) {\n return decodeURIComponent(c.substring(nameEQ.length, c.length))\n }\n }\n } catch {}\n return null\n },\n\n _parse: function (name) {\n let cookie\n try {\n cookie = JSON.parse(cookieStore._get(name)) || {}\n } catch {\n // noop\n }\n return cookie\n },\n\n _set: function (name, value, days, cross_subdomain, is_secure) {\n if (!document) {\n return\n }\n try {\n let expires = '',\n secure = ''\n\n const cdomain = chooseCookieDomain(document.location.hostname, cross_subdomain)\n\n if (days) {\n const date = new Date()\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000)\n expires = '; expires=' + date.toUTCString()\n }\n\n if (is_secure) {\n secure = '; secure'\n }\n\n const new_cookie_val =\n name +\n '=' +\n encodeURIComponent(JSON.stringify(value)) +\n expires +\n '; SameSite=Lax; path=/' +\n cdomain +\n secure\n\n // 4096 bytes is the size at which some browsers (e.g. firefox) will not store a cookie, warn slightly before that\n if (new_cookie_val.length > 4096 * 0.9) {\n logger.warn('cookieStore warning: large cookie, len=' + new_cookie_val.length)\n }\n\n document.cookie = new_cookie_val\n return new_cookie_val\n } catch {\n return\n }\n },\n\n _remove: function (name, cross_subdomain) {\n if (!document?.cookie) {\n return\n }\n try {\n cookieStore._set(name, '', -1, cross_subdomain)\n } catch {\n return\n }\n },\n}\n\nlet _localStorage_supported: boolean | null = null\nexport const resetLocalStorageSupported = () => {\n _localStorage_supported = null\n}\n\nexport const localStore: PersistentStore = {\n _is_supported: function () {\n if (!isNull(_localStorage_supported)) {\n return _localStorage_supported\n }\n\n let supported = true\n if (!isUndefined(window)) {\n try {\n const key = '__mplssupport__',\n val = 'xyz'\n localStore._set(key, val)\n if (localStore._get(key) !== '\"xyz\"') {\n supported = false\n }\n localStore._remove(key)\n } catch {\n supported = false\n }\n } else {\n supported = false\n }\n if (!supported) {\n logger.error('localStorage unsupported; falling back to cookie store')\n }\n\n _localStorage_supported = supported\n return supported\n },\n\n _error: function (msg) {\n logger.error('localStorage error: ' + msg)\n },\n\n _get: function (name) {\n try {\n return window?.localStorage.getItem(name)\n } catch (err) {\n localStore._error(err)\n }\n return null\n },\n\n _parse: function (name) {\n try {\n return JSON.parse(localStore._get(name)) || {}\n } catch {\n // noop\n }\n return null\n },\n\n _set: function (name, value) {\n try {\n window?.localStorage.setItem(name, JSON.stringify(value))\n } catch (err) {\n localStore._error(err)\n }\n },\n\n _remove: function (name) {\n try {\n window?.localStorage.removeItem(name)\n } catch (err) {\n localStore._error(err)\n }\n },\n}\n\n// Use localstorage for most data but still use cookie for COOKIE_PERSISTED_PROPERTIES\n// This solves issues with cookies having too much data in them causing headers too large\n// Also makes sure we don't have to send a ton of data to the server\nconst COOKIE_PERSISTED_PROPERTIES = [\n DEVICE_ID,\n DISTINCT_ID,\n SESSION_ID,\n SESSION_RECORDING_IS_SAMPLED,\n ENABLE_PERSON_PROCESSING,\n INITIAL_PERSON_INFO,\n]\n\n/**\n * Creates a localPlusCookieStore instance with custom cookie-persisted properties\n */\nexport const createLocalPlusCookieStore = (customCookieProperties: readonly string[] = []): PersistentStore => {\n const cookiePropertiesToPersist = [...COOKIE_PERSISTED_PROPERTIES, ...customCookieProperties]\n\n return {\n ...localStore,\n _parse: function (name) {\n try {\n let cookieProperties: Properties = {}\n try {\n // See if there's a cookie stored with data.\n cookieProperties = cookieStore._parse(name) || {}\n } catch {}\n const value = extend(cookieProperties, JSON.parse(localStore._get(name) || '{}'))\n localStore._set(name, value)\n return value\n } catch {\n // noop\n }\n return null\n },\n\n _set: function (name, value, days, cross_subdomain, is_secure, debug) {\n try {\n localStore._set(name, value, undefined, undefined, debug)\n const cookiePersistedProperties: Record<string, any> = {}\n cookiePropertiesToPersist.forEach((key) => {\n if (value[key]) {\n cookiePersistedProperties[key] = value[key]\n }\n })\n\n if (Object.keys(cookiePersistedProperties).length) {\n cookieStore._set(name, cookiePersistedProperties, days, cross_subdomain, is_secure, debug)\n }\n } catch (err) {\n localStore._error(err)\n }\n },\n\n _remove: function (name, cross_subdomain) {\n try {\n window?.localStorage.removeItem(name)\n cookieStore._remove(name, cross_subdomain)\n } catch (err) {\n localStore._error(err)\n }\n },\n }\n}\n\nconst memoryStorage: Properties = {}\n\n// Storage that only lasts the length of the pageview if we don't want to use cookies\nexport const memoryStore: PersistentStore = {\n _is_supported: function () {\n return true\n },\n\n _error: function (msg) {\n logger.error('memoryStorage error: ' + msg)\n },\n\n _get: function (name) {\n return memoryStorage[name] || null\n },\n\n _parse: function (name) {\n return memoryStorage[name] || null\n },\n\n _set: function (name, value) {\n memoryStorage[name] = value\n },\n\n _remove: function (name) {\n delete memoryStorage[name]\n },\n}\n\nlet sessionStorageSupported: boolean | null = null\nexport const resetSessionStorageSupported = () => {\n sessionStorageSupported = null\n}\n// Storage that only lasts the length of a tab/window. Survives page refreshes\nexport const sessionStore: PersistentStore = {\n _is_supported: function () {\n if (!isNull(sessionStorageSupported)) {\n return sessionStorageSupported\n }\n sessionStorageSupported = true\n if (!isUndefined(window)) {\n try {\n const key = '__support__',\n val = 'xyz'\n sessionStore._set(key, val)\n if (sessionStore._get(key) !== '\"xyz\"') {\n sessionStorageSupported = false\n }\n sessionStore._remove(key)\n } catch {\n sessionStorageSupported = false\n }\n } else {\n sessionStorageSupported = false\n }\n return sessionStorageSupported\n },\n\n _error: function (msg) {\n logger.error('sessionStorage error: ', msg)\n },\n\n _get: function (name) {\n try {\n return window?.sessionStorage.getItem(name)\n } catch (err) {\n sessionStore._error(err)\n }\n return null\n },\n\n _parse: function (name) {\n try {\n return JSON.parse(sessionStore._get(name)) || null\n } catch {\n // noop\n }\n return null\n },\n\n _set: function (name, value) {\n try {\n window?.sessionStorage.setItem(name, JSON.stringify(value))\n } catch (err) {\n sessionStore._error(err)\n }\n },\n\n _remove: function (name) {\n try {\n window?.sessionStorage.removeItem(name)\n } catch (err) {\n sessionStore._error(err)\n }\n },\n}\n","import { PostHog } from './posthog-core'\nimport { find } from './utils'\nimport { assignableWindow, navigator } from './utils/globals'\nimport { cookieStore, localStore } from './storage'\nimport { PersistentStore } from './types'\nimport { isNoLike, isYesLike } from '@posthog/core'\n\nconst OPT_OUT_PREFIX = '__ph_opt_in_out_'\n\nexport enum ConsentStatus {\n PENDING = -1,\n DENIED = 0,\n GRANTED = 1,\n}\n\n/**\n * ConsentManager provides tools for managing user consent as configured by the application.\n */\nexport class ConsentManager {\n private _persistentStore?: PersistentStore\n\n constructor(private _instance: PostHog) {}\n\n private get _config() {\n return this._instance.config\n }\n\n public get consent(): ConsentStatus {\n if (this._getDnt()) {\n return ConsentStatus.DENIED\n }\n\n return this._storedConsent\n }\n\n public isOptedOut() {\n if (this._config.cookieless_mode === 'always') {\n return true\n }\n // we are opted out if:\n // * consent is explicitly denied\n // * consent is pending, and we are configured to opt out by default\n // * consent is pending, and we are in cookieless mode \"on_reject\"\n return (\n this.consent === ConsentStatus.DENIED ||\n (this.consent === ConsentStatus.PENDING &&\n (this._config.opt_out_capturing_by_default || this._config.cookieless_mode === 'on_reject'))\n )\n }\n\n public isOptedIn() {\n return !this.isOptedOut()\n }\n\n public isExplicitlyOptedOut() {\n return this.consent === ConsentStatus.DENIED\n }\n\n public optInOut(isOptedIn: boolean) {\n this._storage._set(\n this._storageKey,\n isOptedIn ? 1 : 0,\n this._config.cookie_expiration,\n this._config.cross_subdomain_cookie,\n this._config.secure_cookie\n )\n }\n\n public reset() {\n this._storage._remove(this._storageKey, this._config.cross_subdomain_cookie)\n }\n\n private get _storageKey() {\n const { token, opt_out_capturing_cookie_prefix, consent_persistence_name } = this._instance.config\n if (consent_persistence_name) {\n return consent_persistence_name\n } else if (opt_out_capturing_cookie_prefix) {\n // Deprecated, but we still support it for backwards compatibility.\n // This was deprecated because it differed in behaviour from storage.ts, and appends the token.\n // This meant it was not possible to share the same consent state across multiple PostHog instances,\n // and made it harder for people to migrate from other systems.\n return opt_out_capturing_cookie_prefix + token\n } else {\n return OPT_OUT_PREFIX + token\n }\n }\n\n private get _storedConsent(): ConsentStatus {\n const value = this._storage._get(this._storageKey)\n // be somewhat permissive in what we accept as yes/opt-in, to make it easier for people to migrate from other systems\n return isYesLike(value) ? ConsentStatus.GRANTED : isNoLike(value) ? ConsentStatus.DENIED : ConsentStatus.PENDING\n }\n\n private get _storage() {\n if (!this._persistentStore) {\n const persistenceType = this._config.opt_out_capturing_persistence_type\n this._persistentStore = persistenceType === 'localStorage' ? localStore : cookieStore\n const otherStorage = persistenceType === 'localStorage' ? cookieStore : localStore\n\n if (otherStorage._get(this._storageKey)) {\n if (!this._persistentStore._get(this._storageKey)) {\n // This indicates we have moved to a new storage format so we migrate the value over\n this.optInOut(isYesLike(otherStorage._get(this._storageKey)))\n }\n\n otherStorage._remove(this._storageKey, this._config.cross_subdomain_cookie)\n }\n }\n\n return this._persistentStore\n }\n\n private _getDnt(): boolean {\n if (!this._config.respect_dnt) {\n return false\n }\n return !!find(\n [\n navigator?.doNotTrack, // standard\n (navigator as any)?.['msDoNotTrack'],\n assignableWindow['doNotTrack'],\n ],\n (dntValue): boolean => {\n return isYesLike(dntValue)\n }\n )\n }\n}\n","import { PostHog } from '../posthog-core'\nimport { DEAD_CLICKS_ENABLED_SERVER_SIDE } from '../constants'\nimport { isBoolean, isObject } from '@posthog/core'\nimport { assignableWindow, document, LazyLoadedDeadClicksAutocaptureInterface } from '../utils/globals'\nimport { createLogger } from '../utils/logger'\nimport { DeadClicksAutoCaptureConfig, RemoteConfig } from '../types'\n\nconst logger = createLogger('[Dead Clicks]')\n\nexport const isDeadClicksEnabledForHeatmaps = () => {\n return true\n}\nexport const isDeadClicksEnabledForAutocapture = (instance: DeadClicksAutocapture) => {\n const isRemoteEnabled = !!instance.instance.persistence?.get_property(DEAD_CLICKS_ENABLED_SERVER_SIDE)\n const clientConfig = instance.instance.config.capture_dead_clicks\n if (isBoolean(clientConfig)) {\n return clientConfig\n }\n if (isObject(clientConfig)) {\n return true\n }\n return isRemoteEnabled\n}\n\nexport class DeadClicksAutocapture {\n get lazyLoadedDeadClicksAutocapture(): LazyLoadedDeadClicksAutocaptureInterface | undefined {\n return this._lazyLoadedDeadClicksAutocapture\n }\n\n private _lazyLoadedDeadClicksAutocapture: LazyLoadedDeadClicksAutocaptureInterface | undefined\n\n constructor(\n readonly instance: PostHog,\n readonly isEnabled: (dca: DeadClicksAutocapture) => boolean,\n readonly onCapture?: DeadClicksAutoCaptureConfig['__onCapture']\n ) {\n this.startIfEnabled()\n }\n\n public onRemoteConfig(response: RemoteConfig) {\n if (this.instance.persistence) {\n this.instance.persistence.register({\n [DEAD_CLICKS_ENABLED_SERVER_SIDE]: response?.captureDeadClicks,\n })\n }\n this.startIfEnabled()\n }\n\n public startIfEnabled() {\n if (this.isEnabled(this)) {\n this._loadScript(() => {\n this._start()\n })\n }\n }\n\n private _loadScript(cb: () => void): void {\n if (assignableWindow.__PosthogExtensions__?.initDeadClicksAutocapture) {\n // already loaded\n cb()\n }\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(\n this.instance,\n 'dead-clicks-autocapture',\n (err) => {\n if (err) {\n logger.error('failed to load script', err)\n return\n }\n cb()\n }\n )\n }\n\n private _start() {\n if (!document) {\n logger.error('`document` not found. Cannot start.')\n return\n }\n\n if (\n !this._lazyLoadedDeadClicksAutocapture &&\n assignableWindow.__PosthogExtensions__?.initDeadClicksAutocapture\n ) {\n const config = isObject(this.instance.config.capture_dead_clicks)\n ? this.instance.config.capture_dead_clicks\n : {}\n config.__onCapture = this.onCapture\n\n this._lazyLoadedDeadClicksAutocapture = assignableWindow.__PosthogExtensions__.initDeadClicksAutocapture(\n this.instance,\n config\n )\n this._lazyLoadedDeadClicksAutocapture.start(document)\n logger.info(`starting...`)\n }\n }\n\n stop() {\n if (this._lazyLoadedDeadClicksAutocapture) {\n this._lazyLoadedDeadClicksAutocapture.stop()\n this._lazyLoadedDeadClicksAutocapture = undefined\n logger.info(`stopping...`)\n }\n }\n}\n","import { assignableWindow, window } from '../../utils/globals'\nimport { PostHog } from '../../posthog-core'\nimport { ExceptionAutoCaptureConfig, RemoteConfig } from '../../types'\n\nimport { createLogger } from '../../utils/logger'\nimport { EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE } from '../../constants'\nimport { isUndefined, BucketedRateLimiter, isObject } from '@posthog/core'\nimport { ErrorTracking } from '@posthog/core'\n\nconst logger = createLogger('[ExceptionAutocapture]')\n\nexport class ExceptionObserver {\n private _instance: PostHog\n private _rateLimiter: BucketedRateLimiter<string>\n private _remoteEnabled: boolean | undefined\n private _config: Required<ExceptionAutoCaptureConfig>\n private _unwrapOnError: (() => void) | undefined\n private _unwrapUnhandledRejection: (() => void) | undefined\n private _unwrapConsoleError: (() => void) | undefined\n\n constructor(instance: PostHog) {\n this._instance = instance\n this._remoteEnabled = !!this._instance.persistence?.props[EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE]\n\n // by default captures ten exceptions before rate limiting by exception type\n // refills at a rate of one token / 10 second period\n // e.g. will capture 1 exception rate limited exception every 10 seconds until burst ends\n this._rateLimiter = new BucketedRateLimiter({\n refillRate: this._instance.config.error_tracking.__exceptionRateLimiterRefillRate ?? 1,\n bucketSize: this._instance.config.error_tracking.__exceptionRateLimiterBucketSize ?? 10,\n refillInterval: 10000, // ten seconds in milliseconds,\n _logger: logger,\n })\n\n this._config = this._requiredConfig()\n this.startIfEnabledOrStop()\n }\n\n private _requiredConfig(): Required<ExceptionAutoCaptureConfig> {\n const providedConfig = this._instance.config.capture_exceptions\n let config = {\n capture_unhandled_errors: false,\n capture_unhandled_rejections: false,\n capture_console_errors: false,\n }\n\n if (isObject(providedConfig)) {\n config = { ...config, ...providedConfig }\n } else if (isUndefined(providedConfig) ? this._remoteEnabled : providedConfig) {\n config = { ...config, capture_unhandled_errors: true, capture_unhandled_rejections: true }\n }\n\n return config\n }\n\n public get isEnabled(): boolean {\n return (\n this._config.capture_console_errors ||\n this._config.capture_unhandled_errors ||\n this._config.capture_unhandled_rejections\n )\n }\n\n startIfEnabledOrStop(): void {\n if (this.isEnabled) {\n logger.info('enabled')\n this._stopCapturing()\n this._loadScript(this._startCapturing)\n } else {\n this._stopCapturing()\n }\n }\n\n private _loadScript(cb: () => void): void {\n if (assignableWindow.__PosthogExtensions__?.errorWrappingFunctions) {\n // already loaded\n cb()\n }\n\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(\n this._instance,\n 'exception-autocapture',\n (err) => {\n if (err) {\n return logger.error('failed to load script', err)\n }\n cb()\n }\n )\n }\n\n private _startCapturing = () => {\n if (!window || !this.isEnabled || !assignableWindow.__PosthogExtensions__?.errorWrappingFunctions) {\n return\n }\n\n const wrapOnError = assignableWindow.__PosthogExtensions__.errorWrappingFunctions.wrapOnError\n const wrapUnhandledRejection =\n assignableWindow.__PosthogExtensions__.errorWrappingFunctions.wrapUnhandledRejection\n const wrapConsoleError = assignableWindow.__PosthogExtensions__.errorWrappingFunctions.wrapConsoleError\n\n try {\n if (!this._unwrapOnError && this._config.capture_unhandled_errors) {\n this._unwrapOnError = wrapOnError(this.captureException.bind(this))\n }\n if (!this._unwrapUnhandledRejection && this._config.capture_unhandled_rejections) {\n this._unwrapUnhandledRejection = wrapUnhandledRejection(this.captureException.bind(this))\n }\n if (!this._unwrapConsoleError && this._config.capture_console_errors) {\n this._unwrapConsoleError = wrapConsoleError(this.captureException.bind(this))\n }\n } catch (e) {\n logger.error('failed to start', e)\n this._stopCapturing()\n }\n }\n\n private _stopCapturing() {\n this._unwrapOnError?.()\n this._unwrapOnError = undefined\n\n this._unwrapUnhandledRejection?.()\n this._unwrapUnhandledRejection = undefined\n\n this._unwrapConsoleError?.()\n this._unwrapConsoleError = undefined\n }\n\n onRemoteConfig(response: RemoteConfig) {\n const autocaptureExceptionsResponse = response.autocaptureExceptions\n\n // store this in-memory in case persistence is disabled\n this._remoteEnabled = !!autocaptureExceptionsResponse || false\n\n if (this._instance.persistence) {\n this._instance.persistence.register({\n [EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE]: this._remoteEnabled,\n })\n }\n\n this._config = this._requiredConfig()\n this.startIfEnabledOrStop()\n }\n\n onConfigChange() {\n this._config = this._requiredConfig()\n }\n\n captureException(errorProperties: ErrorTracking.ErrorProperties) {\n const exceptionType = errorProperties?.$exception_list?.[0]?.type ?? 'Exception'\n const isRateLimited = this._rateLimiter.consumeRateLimit(exceptionType)\n\n if (isRateLimited) {\n logger.info('Skipping exception capture because of client rate limiting.', {\n exception: exceptionType,\n })\n return\n }\n\n this._instance.exceptions.sendExceptionEvent(errorProperties)\n }\n}\n","// import { patch } from 'rrweb/typings/utils'\n// copied from https://github.com/rrweb-io/rrweb/blob/8aea5b00a4dfe5a6f59bd2ae72bb624f45e51e81/packages/rrweb/src/utils.ts#L129\n// which was copied from https://github.com/getsentry/sentry-javascript/blob/b2109071975af8bf0316d3b5b38f519bdaf5dc15/packages/utils/src/object.ts\nimport { isFunction } from '@posthog/core'\n\nexport function patch(\n source: { [key: string]: any },\n name: string,\n replacement: (...args: unknown[]) => unknown\n): () => void {\n try {\n if (!(name in source)) {\n return () => {\n //\n }\n }\n\n const original = source[name] as () => unknown\n const wrapped = replacement(original)\n\n // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work\n // otherwise it'll throw \"TypeError: Object.defineProperties called on non-object\"\n if (isFunction(wrapped)) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n wrapped.prototype = wrapped.prototype || {}\n Object.defineProperties(wrapped, {\n __posthog_wrapped__: {\n enumerable: false,\n value: true,\n },\n })\n }\n\n source[name] = wrapped\n\n return () => {\n source[name] = original\n }\n } catch {\n return () => {\n //\n }\n // This can throw if multiple fill happens on a global object like XMLHttpRequest\n // Fixes https://github.com/getsentry/sentry-javascript/issues/2043\n }\n}\n","import { PostHog } from '../posthog-core'\nimport { window } from '../utils/globals'\nimport { addEventListener } from '../utils'\nimport { logger } from '../utils/logger'\nimport { patch } from './replay/rrweb-plugins/patch'\n\n/**\n * This class is used to capture pageview events when the user navigates using the history API (pushState, replaceState)\n * and when the user navigates using the browser's back/forward buttons.\n *\n * The behavior is controlled by the `capture_pageview` configuration option:\n * - When set to `'history_change'`, this class will capture pageviews on history API changes\n */\nexport class HistoryAutocapture {\n private _instance: PostHog\n private _popstateListener: (() => void) | undefined\n private _lastPathname: string\n\n constructor(instance: PostHog) {\n this._instance = instance\n this._lastPathname = window?.location?.pathname || ''\n }\n\n public get isEnabled(): boolean {\n return this._instance.config.capture_pageview === 'history_change'\n }\n\n public startIfEnabled(): void {\n if (this.isEnabled) {\n logger.info('History API monitoring enabled, starting...')\n this.monitorHistoryChanges()\n }\n }\n\n public stop(): void {\n if (this._popstateListener) {\n this._popstateListener()\n }\n this._popstateListener = undefined\n logger.info('History API monitoring stopped')\n }\n\n public monitorHistoryChanges(): void {\n if (!window || !window.history) {\n return\n }\n\n // Old fashioned, we could also use arrow functions but I think the closure for a patch is more reliable\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this\n\n if (!(window.history.pushState as any)?.__posthog_wrapped__) {\n patch(window.history, 'pushState', (originalPushState) => {\n return function patchedPushState(\n this: History,\n state: any,\n title: string,\n url?: string | URL | null\n ): void {\n ;(originalPushState as History['pushState']).call(this, state, title, url)\n self._capturePageview('pushState')\n }\n })\n }\n\n if (!(window.history.replaceState as any)?.__posthog_wrapped__) {\n patch(window.history, 'replaceState', (originalReplaceState) => {\n return function patchedReplaceState(\n this: History,\n state: any,\n title: string,\n url?: string | URL | null\n ): void {\n ;(originalReplaceState as History['replaceState']).call(this, state, title, url)\n self._capturePageview('replaceState')\n }\n })\n }\n\n this._setupPopstateListener()\n }\n\n private _capturePageview(navigationType: 'pushState' | 'replaceState' | 'popstate'): void {\n try {\n const currentPathname = window?.location?.pathname\n\n if (!currentPathname) {\n return\n }\n\n // Only capture pageview if the pathname has changed and the feature is enabled\n if (currentPathname !== this._lastPathname && this.isEnabled) {\n this._instance.capture('$pageview', { navigation_type: navigationType })\n }\n\n this._lastPathname = currentPathname\n } catch (error) {\n logger.error(`Error capturing ${navigationType} pageview`, error)\n }\n }\n\n private _setupPopstateListener(): void {\n if (this._popstateListener) {\n return\n }\n\n const handler = () => {\n this._capturePageview('popstate')\n }\n\n addEventListener(window, 'popstate', handler)\n this._popstateListener = () => {\n if (window) {\n window.removeEventListener('popstate', handler)\n }\n }\n }\n}\n","/**\n * Extend Segment with extra PostHog JS functionality. Required for things like Recordings and feature flags to work correctly.\n *\n * ### Usage\n *\n * ```js\n * // After your standard segment anyalytics install\n * analytics.load(\"GOEDfA21zZTtR7clsBuDvmBKAtAdZ6Np\");\n *\n * analytics.ready(() => {\n * posthog.init('<posthog-api-key>', {\n * capture_pageview: false,\n * segment: window.analytics, // NOTE: Be sure to use window.analytics here!\n * });\n * window.analytics.page();\n * })\n * ```\n */\nimport { PostHog } from '../posthog-core'\nimport { createLogger } from '../utils/logger'\n\nimport { USER_STATE } from '../constants'\nimport { isFunction } from '@posthog/core'\nimport { uuidv7 } from '../uuidv7'\n\nimport type { SegmentUser, SegmentAnalytics, SegmentContext, SegmentPlugin } from '@posthog/types'\n\n// Re-export for backwards compatibility\nexport type { SegmentUser, SegmentAnalytics, SegmentContext, SegmentPlugin }\n\nconst logger = createLogger('[SegmentIntegration]')\n\nconst createSegmentIntegration = (posthog: PostHog): SegmentPlugin => {\n if (!Promise || !Promise.resolve) {\n logger.warn('This browser does not have Promise support, and can not use the segment integration')\n }\n\n const enrichEvent = (ctx: SegmentContext, eventName: string | undefined) => {\n if (!eventName) {\n return ctx\n }\n if (!ctx.event.userId && ctx.event.anonymousId !== posthog.get_distinct_id()) {\n // This is our only way of detecting that segment's analytics.reset() has been called so we also call it\n logger.info('No userId set, resetting PostHog')\n posthog.reset()\n }\n if (ctx.event.userId && ctx.event.userId !== posthog.get_distinct_id()) {\n logger.info('UserId set, identifying with PostHog')\n posthog.identify(ctx.event.userId)\n }\n\n const additionalProperties = posthog.calculateEventProperties(eventName, ctx.event.properties)\n ctx.event.properties = Object.assign({}, additionalProperties, ctx.event.properties)\n return ctx\n }\n\n return {\n name: 'PostHog JS',\n type: 'enrichment',\n version: '1.0.0',\n isLoaded: () => true,\n // check and early return above\n // eslint-disable-next-line compat/compat\n load: () => Promise.resolve(),\n track: (ctx) => enrichEvent(ctx, ctx.event.event),\n page: (ctx) => enrichEvent(ctx, '$pageview'),\n identify: (ctx) => enrichEvent(ctx, '$identify'),\n screen: (ctx) => enrichEvent(ctx, '$screen'),\n }\n}\n\nfunction setupPostHogFromSegment(posthog: PostHog, done: () => void) {\n const segment = posthog.config.segment\n if (!segment) {\n return done()\n }\n\n const bootstrapUser = (user: SegmentUser) => {\n // Use segments anonymousId instead\n const getSegmentAnonymousId = () => user.anonymousId() || uuidv7()\n posthog.config.get_device_id = getSegmentAnonymousId\n\n // If a segment user ID exists, set it as the distinct_id\n if (user.id()) {\n posthog.register({\n distinct_id: user.id(),\n $device_id: getSegmentAnonymousId(),\n })\n posthog.persistence!.set_property(USER_STATE, 'identified')\n }\n\n done()\n }\n\n const segmentUser = segment.user()\n if ('then' in segmentUser && isFunction(segmentUser.then)) {\n segmentUser.then(bootstrapUser)\n } else {\n bootstrapUser(segmentUser as SegmentUser)\n }\n}\n\nexport function setupSegmentIntegration(posthog: PostHog, done: () => void) {\n const segment = posthog.config.segment\n if (!segment) {\n return done()\n }\n\n setupPostHogFromSegment(posthog, () => {\n segment.register(createSegmentIntegration(posthog)).then(() => {\n done()\n })\n })\n}\n","/**\n * Integrate Sentry with PostHog. This will add a direct link to the person in Sentry, and an $exception event in PostHog\n *\n * ### Usage\n *\n * Sentry.init({\n * dsn: 'https://example',\n * integrations: [\n * new posthog.SentryIntegration(posthog)\n * ]\n * })\n *\n * @param {Object} [posthog] The posthog object\n * @param {string} [organization] Optional: The Sentry organization, used to send a direct link from PostHog to Sentry\n * @param {Number} [projectId] Optional: The Sentry project id, used to send a direct link from PostHog to Sentry\n * @param {string} [prefix] Optional: Url of a self-hosted sentry instance (default: https://sentry.io/organizations/)\n * @param {SeverityLevel[] | '*'} [severityAllowList] Optional: send events matching the provided levels. Use '*' to send all events (default: ['error'])\n * @param {boolean} [sendExceptionsToPostHog] Optional: capture exceptions as events in PostHog (default: true)\n */\n\nimport { PostHog } from '../posthog-core'\nimport { SeverityLevel } from '../types'\n\n// NOTE - we can't import from @sentry/types because it changes frequently and causes clashes\n// We only use a small subset of the types, so we can just define the integration overall and use any for the rest\n\n// import {\n// Event as _SentryEvent,\n// EventProcessor as _SentryEventProcessor,\n// Hub as _SentryHub,\n// Integration as _SentryIntegration,\n// SeverityLevel as _SeverityLevel,\n// IntegrationClass as _SentryIntegrationClass,\n// } from '@sentry/types'\n\n// Uncomment the above and comment the below to get type checking for development\n\ntype _SentryEvent = any\ntype _SentryException = any\ntype _SentryEventProcessor = any\ntype _SentryHub = any\n\ninterface _SentryIntegration {\n name: string\n processEvent(event: _SentryEvent): _SentryEvent\n}\n\ninterface _SentryIntegrationClass {\n name: string\n setupOnce(addGlobalEventProcessor: (callback: _SentryEventProcessor) => void, getCurrentHub: () => _SentryHub): void\n}\n\ninterface SentryExceptionProperties {\n $sentry_event_id: any\n $sentry_exception: any\n $sentry_exception_message: any\n $sentry_exception_type: any\n $sentry_tags: any\n $sentry_url?: string\n}\n\nexport type SentryIntegrationOptions = {\n organization?: string\n projectId?: number\n prefix?: string\n severityAllowList?: SeverityLevel[] | '*'\n sendExceptionsToPostHog?: boolean\n}\n\nconst NAME = 'posthog-js'\n\nexport function createEventProcessor(\n _posthog: PostHog,\n {\n organization,\n projectId,\n prefix,\n severityAllowList = ['error'],\n sendExceptionsToPostHog = true,\n }: SentryIntegrationOptions = {}\n): (event: _SentryEvent) => _SentryEvent {\n return (event) => {\n const shouldProcessLevel = severityAllowList === '*' || severityAllowList.includes(event.level as SeverityLevel)\n if (!shouldProcessLevel || !_posthog.__loaded) return event\n if (!event.tags) event.tags = {}\n\n const personUrl = _posthog.requestRouter.endpointFor(\n 'ui',\n `/project/${_posthog.config.token}/person/${_posthog.get_distinct_id()}`\n )\n event.tags['PostHog Person URL'] = personUrl\n if (_posthog.sessionRecordingStarted()) {\n event.tags['PostHog Recording URL'] = _posthog.get_session_replay_url({ withTimestamp: true })\n }\n\n const exceptions: _SentryException[] = event.exception?.values || []\n\n const exceptionList = exceptions.map((exception) => {\n return {\n ...exception,\n stacktrace: exception.stacktrace\n ? {\n ...exception.stacktrace,\n type: 'raw',\n frames: (exception.stacktrace.frames || []).map((frame: any) => {\n return { ...frame, platform: 'web:javascript' }\n }),\n }\n : undefined,\n }\n })\n\n const data: SentryExceptionProperties & {\n // two properties added to match any exception auto-capture\n // added manually to avoid any dependency on the lazily loaded content\n $exception_message: any\n $exception_type: any\n $exception_list: any\n $exception_level: SeverityLevel\n } = {\n // PostHog Exception Properties,\n $exception_message: exceptions[0]?.value || event.message,\n $exception_type: exceptions[0]?.type,\n $exception_level: event.level,\n $exception_list: exceptionList,\n // Sentry Exception Properties\n $sentry_event_id: event.event_id,\n $sentry_exception: event.exception,\n $sentry_exception_message: exceptions[0]?.value || event.message,\n $sentry_exception_type: exceptions[0]?.type,\n $sentry_tags: event.tags,\n }\n\n if (organization && projectId) {\n data['$sentry_url'] =\n (prefix || 'https://sentry.io/organizations/') +\n organization +\n '/issues/?project=' +\n projectId +\n '&query=' +\n event.event_id\n }\n\n if (sendExceptionsToPostHog) {\n _posthog.exceptions.sendExceptionEvent(data)\n }\n\n return event\n }\n}\n\n// V8 integration - function based\nexport function sentryIntegration(_posthog: PostHog, options?: SentryIntegrationOptions): _SentryIntegration {\n const processor = createEventProcessor(_posthog, options)\n return {\n name: NAME,\n processEvent(event) {\n return processor(event)\n },\n }\n}\n// V7 integration - class based\nexport class SentryIntegration implements _SentryIntegrationClass {\n name: string\n\n setupOnce: (\n addGlobalEventProcessor: (callback: _SentryEventProcessor) => void,\n getCurrentHub: () => _SentryHub\n ) => void\n\n constructor(\n _posthog: PostHog,\n organization?: string,\n projectId?: number,\n prefix?: string,\n severityAllowList?: SeverityLevel[] | '*',\n sendExceptionsToPostHog?: boolean\n ) {\n // setupOnce gets called by Sentry when it intializes the plugin\n this.name = NAME\n this.setupOnce = function (addGlobalEventProcessor: (callback: _SentryEventProcessor) => void) {\n addGlobalEventProcessor(\n createEventProcessor(_posthog, {\n organization,\n projectId,\n prefix,\n severityAllowList,\n sendExceptionsToPostHog: sendExceptionsToPostHog ?? true,\n })\n )\n }\n }\n}\n","import { addEventListener, trySafe } from '../utils'\nimport { PostHog } from '../posthog-core'\nimport { ToolbarParams } from '../types'\nimport { _getHashParam } from '../utils/request-utils'\nimport { createLogger } from '../utils/logger'\nimport { window, document, assignableWindow } from '../utils/globals'\nimport { TOOLBAR_ID } from '../constants'\nimport { isFunction, isNullish } from '@posthog/core'\n\n// TRICKY: Many web frameworks will modify the route on load, potentially before posthog is initialized.\n// To get ahead of this we grab it as soon as the posthog-js is parsed\nconst STATE_FROM_WINDOW = window?.location\n ? _getHashParam(window.location.hash, '__posthog') || _getHashParam(location.hash, 'state')\n : null\n\nconst LOCALSTORAGE_KEY = '_postHogToolbarParams'\n\nconst logger = createLogger('[Toolbar]')\n\nenum ToolbarState {\n UNINITIALIZED = 0,\n LOADING = 1,\n LOADED = 2,\n}\n\nexport class Toolbar {\n instance: PostHog\n\n constructor(instance: PostHog) {\n this.instance = instance\n }\n\n // NOTE: We store the state of the toolbar in the global scope to avoid multiple instances of the SDK loading the toolbar\n private _setToolbarState(state: ToolbarState) {\n assignableWindow['ph_toolbar_state'] = state\n }\n\n private _getToolbarState(): ToolbarState {\n return assignableWindow['ph_toolbar_state'] ?? ToolbarState.UNINITIALIZED\n }\n\n /**\n * To load the toolbar, we need an access token and other state. That state comes from one of three places:\n * 1. In the URL hash params\n * 2. From session storage under the key `toolbarParams` if the toolbar was initialized on a previous page\n */\n maybeLoadToolbar(\n location: Location | undefined = undefined,\n localStorage: Storage | undefined = undefined,\n history: History | undefined = undefined\n ): boolean {\n if (!window || !document) {\n return false\n }\n location = location ?? window.location\n history = history ?? window.history\n\n try {\n // Before running the code we check if we can access localStorage, if not we opt-out\n if (!localStorage) {\n try {\n window.localStorage.setItem('test', 'test')\n window.localStorage.removeItem('test')\n } catch {\n return false\n }\n\n // If localStorage was undefined, and localStorage is supported we set the default value\n localStorage = window?.localStorage\n }\n\n /**\n * Info about the state\n * The state is a json object\n * 1. (Legacy) The state can be `state={}` as a urlencoded object of info. In this case\n * 2. The state should now be found in `__posthog={}` and can be base64 encoded or urlencoded.\n * 3. Base64 encoding is preferred and will gradually be rolled out everywhere\n */\n\n const stateHash =\n STATE_FROM_WINDOW || _getHashParam(location.hash, '__posthog') || _getHashParam(location.hash, 'state')\n\n let toolbarParams: ToolbarParams\n const state = stateHash\n ? trySafe(() => JSON.parse(atob(decodeURIComponent(stateHash)))) ||\n trySafe(() => JSON.parse(decodeURIComponent(stateHash)))\n : null\n\n const parseFromUrl = state && state['action'] === 'ph_authorize'\n\n if (parseFromUrl) {\n // happens if they are initializing the toolbar using an old snippet\n toolbarParams = state\n toolbarParams.source = 'url'\n\n if (toolbarParams && Object.keys(toolbarParams).length > 0) {\n if (state['desiredHash']) {\n // hash that was in the url before the redirect\n location.hash = state['desiredHash']\n } else if (history) {\n // second param is unused see https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState\n history.replaceState(history.state, '', location.pathname + location.search) // completely remove hash\n } else {\n location.hash = '' // clear hash (but leaves # unfortunately)\n }\n }\n } else {\n // get credentials from localStorage from a previous initialization\n\n toolbarParams = JSON.parse(localStorage.getItem(LOCALSTORAGE_KEY) || '{}')\n toolbarParams.source = 'localstorage'\n\n // delete \"add-action\" or other intent from toolbarParams, otherwise we'll have the same intent\n // every time we open the page (e.g. you just visiting your own site an hour later)\n delete toolbarParams.userIntent\n }\n\n if (toolbarParams['token'] && this.instance.config.token === toolbarParams['token']) {\n this.loadToolbar(toolbarParams)\n return true\n } else {\n return false\n }\n } catch {\n return false\n }\n }\n\n private _callLoadToolbar(params: ToolbarParams) {\n const loadFn = assignableWindow['ph_load_toolbar'] || assignableWindow['ph_load_editor']\n if (isNullish(loadFn) || !isFunction(loadFn)) {\n logger.warn('No toolbar load function found')\n return\n }\n loadFn(params, this.instance)\n }\n\n loadToolbar(params?: ToolbarParams): boolean {\n const toolbarRunning = !!document?.getElementById(TOOLBAR_ID)\n\n if (!window || toolbarRunning) {\n // The toolbar will clear the localStorage key when it's done with it. If it is present that indicates the toolbar is already open and running\n return false\n }\n\n const disableToolbarMetrics =\n this.instance.requestRouter.region === 'custom' && this.instance.config.advanced_disable_toolbar_metrics\n\n const toolbarParams = {\n token: this.instance.config.token,\n ...params,\n apiURL: this.instance.requestRouter.endpointFor('ui'),\n ...(disableToolbarMetrics ? { instrument: false } : {}),\n }\n window.localStorage.setItem(\n LOCALSTORAGE_KEY,\n JSON.stringify({\n ...toolbarParams,\n source: undefined,\n })\n )\n\n if (this._getToolbarState() === ToolbarState.LOADED) {\n this._callLoadToolbar(toolbarParams)\n } else if (this._getToolbarState() === ToolbarState.UNINITIALIZED) {\n // only load the toolbar once, even if there are multiple instances of PostHogLib\n this._setToolbarState(ToolbarState.LOADING)\n\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(this.instance, 'toolbar', (err) => {\n if (err) {\n logger.error('[Toolbar] Failed to load', err)\n this._setToolbarState(ToolbarState.UNINITIALIZED)\n return\n }\n this._setToolbarState(ToolbarState.LOADED)\n this._callLoadToolbar(toolbarParams)\n })\n\n // Turbolinks doesn't fire an onload event but does replace the entire body, including the toolbar.\n // Thus, we ensure the toolbar is only loaded inside the body, and then reloaded on turbolinks:load.\n addEventListener(window, 'turbolinks:load', () => {\n this._setToolbarState(ToolbarState.UNINITIALIZED)\n this.loadToolbar(toolbarParams)\n })\n }\n\n return true\n }\n\n /** @deprecated Use \"loadToolbar\" instead. */\n _loadEditor(params: ToolbarParams): boolean {\n return this.loadToolbar(params)\n }\n\n /** @deprecated Use \"maybeLoadToolbar\" instead. */\n maybeLoadEditor(\n location: Location | undefined = undefined,\n localStorage: Storage | undefined = undefined,\n history: History | undefined = undefined\n ): boolean {\n return this.maybeLoadToolbar(location, localStorage, history)\n }\n}\n","import { PostHog } from '../posthog-core'\nimport { assignableWindow } from '../utils/globals'\nimport { createLogger } from '../utils/logger'\nimport { isUndefined } from '@posthog/core'\n\nconst logger = createLogger('[TracingHeaders]')\n\nexport class TracingHeaders {\n private _restoreXHRPatch: (() => void) | undefined = undefined\n private _restoreFetchPatch: (() => void) | undefined = undefined\n\n constructor(private readonly _instance: PostHog) {}\n\n private _loadScript(cb: () => void): void {\n if (assignableWindow.__PosthogExtensions__?.tracingHeadersPatchFns) {\n // already loaded\n cb()\n }\n\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(this._instance, 'tracing-headers', (err) => {\n if (err) {\n return logger.error('failed to load script', err)\n }\n cb()\n })\n }\n public startIfEnabledOrStop() {\n if (this._instance.config.__add_tracing_headers) {\n this._loadScript(this._startCapturing)\n } else {\n this._restoreXHRPatch?.()\n this._restoreFetchPatch?.()\n // we don't want to call these twice so we reset them\n this._restoreXHRPatch = undefined\n this._restoreFetchPatch = undefined\n }\n }\n\n private _startCapturing = () => {\n if (isUndefined(this._restoreXHRPatch)) {\n assignableWindow.__PosthogExtensions__?.tracingHeadersPatchFns?._patchXHR(\n this._instance.config.__add_tracing_headers || [],\n this._instance.get_distinct_id(),\n this._instance.sessionManager\n )\n }\n if (isUndefined(this._restoreFetchPatch)) {\n assignableWindow.__PosthogExtensions__?.tracingHeadersPatchFns?._patchFetch(\n this._instance.config.__add_tracing_headers || [],\n this._instance.get_distinct_id(),\n this._instance.sessionManager\n )\n }\n }\n}\n","import { convertToURL, getQueryParam, maskQueryParams } from './request-utils'\nimport { isNull, stripLeadingDollar } from '@posthog/core'\nimport { Properties } from '../types'\nimport Config from '../config'\nimport { each, extend, extendArray, stripEmptyProperties } from './index'\nimport { document, location, userAgent, window } from './globals'\nimport { detectBrowser, detectBrowserVersion, detectDevice, detectDeviceType, detectOS } from '@posthog/core'\nimport { cookieStore } from '../storage'\n\nconst URL_REGEX_PREFIX = 'https?://(.*)'\n\n// CAMPAIGN_PARAMS and EVENT_TO_PERSON_PROPERTIES should be kept in sync with\n// https://github.com/PostHog/posthog/blob/master/plugin-server/src/utils/db/utils.ts#L60\n\n// The list of campaign parameters that could be considered personal data under e.g. GDPR.\n// These can be masked in URLs and properties before being sent to posthog.\nexport const PERSONAL_DATA_CAMPAIGN_PARAMS = [\n 'gclid', // google ads\n 'gclsrc', // google ads 360\n 'dclid', // google display ads\n 'gbraid', // google ads, web to app\n 'wbraid', // google ads, app to web\n 'fbclid', // facebook\n 'msclkid', // microsoft\n 'twclid', // twitter\n 'li_fat_id', // linkedin\n 'igshid', // instagram\n 'ttclid', // tiktok\n 'rdt_cid', // reddit\n 'epik', // pinterest\n 'qclid', // quora\n 'sccid', // snapchat\n 'irclid', // impact\n '_kx', // klaviyo\n]\n\nexport const CAMPAIGN_PARAMS = extendArray(\n [\n 'utm_source',\n 'utm_medium',\n 'utm_campaign',\n 'utm_content',\n 'utm_term',\n 'gad_source', // google ads source\n 'mc_cid', // mailchimp campaign id\n ],\n PERSONAL_DATA_CAMPAIGN_PARAMS\n)\n\nexport const EVENT_TO_PERSON_PROPERTIES = [\n // mobile params\n '$app_build',\n '$app_name',\n '$app_namespace',\n '$app_version',\n // web params\n '$browser',\n '$browser_version',\n '$device_type',\n '$current_url',\n '$pathname',\n '$os',\n '$os_name', // $os_name is a special case, it's treated as an alias of $os!\n '$os_version',\n '$referring_domain',\n '$referrer',\n '$screen_height',\n '$screen_width',\n '$viewport_height',\n '$viewport_width',\n '$raw_user_agent',\n]\n\nexport const MASKED = '<masked>'\n\n// Campaign params that can be read from the cookie store\nexport const COOKIE_CAMPAIGN_PARAMS = [\n 'li_fat_id', // linkedin\n]\n\nexport function getCampaignParams(\n customTrackedParams?: string[],\n maskPersonalDataProperties?: boolean,\n customPersonalDataProperties?: string[] | undefined\n): Record<string, string> {\n if (!document) {\n return {}\n }\n\n const paramsToMask = maskPersonalDataProperties\n ? extendArray([], PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])\n : []\n\n // Initially get campaign params from the URL\n const urlCampaignParams = _getCampaignParamsFromUrl(\n maskQueryParams(document.URL, paramsToMask, MASKED),\n customTrackedParams\n )\n\n // But we can also get some of them from the cookie store\n // For example: https://learn.microsoft.com/en-us/linkedin/marketing/conversions/enabling-first-party-cookies?view=li-lms-2025-05#reading-li_fat_id-from-cookies\n const cookieCampaignParams = _getCampaignParamsFromCookie()\n\n // Prefer the values found in the urlCampaignParams if possible\n // `extend` will override the values if found in the second argument\n return extend(cookieCampaignParams, urlCampaignParams)\n}\n\nfunction _getCampaignParamsFromUrl(url: string, customParams?: string[]): Record<string, string> {\n const campaign_keywords = CAMPAIGN_PARAMS.concat(customParams || [])\n\n const params: Record<string, any> = {}\n each(campaign_keywords, function (kwkey) {\n const kw = getQueryParam(url, kwkey)\n params[kwkey] = kw ? kw : null\n })\n\n return params\n}\n\nfunction _getCampaignParamsFromCookie(): Record<string, string> {\n const params: Record<string, any> = {}\n each(COOKIE_CAMPAIGN_PARAMS, function (kwkey) {\n const kw = cookieStore._get(kwkey)\n params[kwkey] = kw ? kw : null\n })\n\n return params\n}\n\nfunction _getSearchEngine(referrer: string): string | null {\n if (!referrer) {\n return null\n } else {\n if (referrer.search(URL_REGEX_PREFIX + 'google.([^/?]*)') === 0) {\n return 'google'\n } else if (referrer.search(URL_REGEX_PREFIX + 'bing.com') === 0) {\n return 'bing'\n } else if (referrer.search(URL_REGEX_PREFIX + 'yahoo.com') === 0) {\n return 'yahoo'\n } else if (referrer.search(URL_REGEX_PREFIX + 'duckduckgo.com') === 0) {\n return 'duckduckgo'\n } else {\n return null\n }\n }\n}\n\nfunction _getSearchInfoFromReferrer(referrer: string): Record<string, any> {\n const search = _getSearchEngine(referrer)\n const param = search != 'yahoo' ? 'q' : 'p'\n const ret: Record<string, any> = {}\n\n if (!isNull(search)) {\n ret['$search_engine'] = search\n\n const keyword = document ? getQueryParam(document.referrer, param) : ''\n if (keyword.length) {\n ret['ph_keyword'] = keyword\n }\n }\n\n return ret\n}\n\nexport function getSearchInfo(): Record<string, any> {\n const referrer = document?.referrer\n if (!referrer) {\n return {}\n }\n return _getSearchInfoFromReferrer(referrer)\n}\n\nexport function getBrowserLanguage(): string | undefined {\n return (\n navigator.language || // Any modern browser\n (navigator as Record<string, any>).userLanguage // IE11\n )\n}\n\nexport function getBrowserLanguagePrefix(): string | undefined {\n const lang = getBrowserLanguage()\n return typeof lang === 'string' ? lang.split('-')[0] : undefined\n}\n\nexport function getReferrer(): string {\n return document?.referrer || '$direct'\n}\n\nexport function getReferringDomain(): string {\n if (!document?.referrer) {\n return '$direct'\n }\n return convertToURL(document.referrer)?.host || '$direct'\n}\n\nexport function getReferrerInfo(): Record<string, any> {\n return {\n $referrer: getReferrer(),\n $referring_domain: getReferringDomain(),\n }\n}\n\nexport function getPersonInfo(maskPersonalDataProperties?: boolean, customPersonalDataProperties?: string[]) {\n const paramsToMask = maskPersonalDataProperties\n ? extendArray([], PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])\n : []\n const url = location?.href.substring(0, 1000)\n // we're being a bit more economical with bytes here because this is stored in the cookie\n return {\n r: getReferrer().substring(0, 1000),\n u: url ? maskQueryParams(url, paramsToMask, MASKED) : undefined,\n }\n}\n\nexport function getPersonPropsFromInfo(info: Record<string, any>): Record<string, any> {\n const { r: referrer, u: url } = info\n const referring_domain =\n referrer == null ? undefined : referrer == '$direct' ? '$direct' : convertToURL(referrer)?.host\n\n const props: Record<string, string | undefined> = {\n $referrer: referrer,\n $referring_domain: referring_domain,\n }\n if (url) {\n props['$current_url'] = url\n const location = convertToURL(url)\n props['$host'] = location?.host\n props['$pathname'] = location?.pathname\n const campaignParams = _getCampaignParamsFromUrl(url)\n extend(props, campaignParams)\n }\n if (referrer) {\n const searchInfo = _getSearchInfoFromReferrer(referrer)\n extend(props, searchInfo)\n }\n return props\n}\n\nexport function getInitialPersonPropsFromInfo(info: Record<string, any>): Record<string, any> {\n const personProps = getPersonPropsFromInfo(info)\n const props: Record<string, any> = {}\n each(personProps, function (val: any, key: string) {\n props[`$initial_${stripLeadingDollar(key)}`] = val\n })\n return props\n}\n\nexport function getTimezone(): string | undefined {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone\n } catch {\n return undefined\n }\n}\n\nexport function getTimezoneOffset(): number | undefined {\n try {\n return new Date().getTimezoneOffset()\n } catch {\n return undefined\n }\n}\n\nexport function getEventProperties(\n maskPersonalDataProperties?: boolean,\n customPersonalDataProperties?: string[]\n): Properties {\n if (!userAgent) {\n return {}\n }\n const paramsToMask = maskPersonalDataProperties\n ? extendArray([], PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])\n : []\n const [os_name, os_version] = detectOS(userAgent)\n return extend(\n stripEmptyProperties({\n $os: os_name,\n $os_version: os_version,\n $browser: detectBrowser(userAgent, navigator.vendor),\n $device: detectDevice(userAgent),\n $device_type: detectDeviceType(userAgent),\n $timezone: getTimezone(),\n $timezone_offset: getTimezoneOffset(),\n }),\n {\n $current_url: maskQueryParams(location?.href, paramsToMask, MASKED),\n $host: location?.host,\n $pathname: location?.pathname,\n $raw_user_agent: userAgent.length > 1000 ? userAgent.substring(0, 997) + '...' : userAgent,\n $browser_version: detectBrowserVersion(userAgent, navigator.vendor),\n $browser_language: getBrowserLanguage(),\n $browser_language_prefix: getBrowserLanguagePrefix(),\n $screen_height: window?.screen.height,\n $screen_width: window?.screen.width,\n $viewport_height: window?.innerHeight,\n $viewport_width: window?.innerWidth,\n $lib: 'web',\n $lib_version: Config.LIB_VERSION,\n $insert_id: Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10),\n $time: Date.now() / 1000, // epoch time in seconds\n }\n )\n}\n","import { PostHog } from '../../posthog-core'\nimport { RemoteConfig, SupportedWebVitalsMetrics } from '../../types'\nimport { createLogger } from '../../utils/logger'\nimport { isBoolean, isNullish, isNumber, isUndefined, isObject } from '@posthog/core'\nimport { WEB_VITALS_ALLOWED_METRICS, WEB_VITALS_ENABLED_SERVER_SIDE } from '../../constants'\nimport { assignableWindow, window, location } from '../../utils/globals'\nimport { maskQueryParams } from '../../utils/request-utils'\nimport { PERSONAL_DATA_CAMPAIGN_PARAMS, MASKED } from '../../utils/event-utils'\nimport { extendArray } from '../../utils'\n\nconst logger = createLogger('[Web Vitals]')\n\ntype WebVitalsMetricCallback = (metric: any) => void\n\nexport const DEFAULT_FLUSH_TO_CAPTURE_TIMEOUT_MILLISECONDS = 5000\nconst ONE_MINUTE_IN_MILLIS = 60 * 1000\nexport const FIFTEEN_MINUTES_IN_MILLIS = 15 * ONE_MINUTE_IN_MILLIS\n\ntype WebVitalsEventBuffer = { url: string | undefined; metrics: any[]; firstMetricTimestamp: number | undefined }\n\nexport class WebVitalsAutocapture {\n private _enabledServerSide: boolean = false\n private _initialized = false\n\n private _buffer: WebVitalsEventBuffer = { url: undefined, metrics: [], firstMetricTimestamp: undefined }\n private _delayedFlushTimer: ReturnType<typeof setTimeout> | undefined\n\n constructor(private readonly _instance: PostHog) {\n this._enabledServerSide = !!this._instance.persistence?.props[WEB_VITALS_ENABLED_SERVER_SIDE]\n\n this.startIfEnabled()\n }\n\n public get allowedMetrics(): SupportedWebVitalsMetrics[] {\n const clientConfigMetricAllowList: SupportedWebVitalsMetrics[] | undefined = isObject(\n this._instance.config.capture_performance\n )\n ? this._instance.config.capture_performance?.web_vitals_allowed_metrics\n : undefined\n return !isUndefined(clientConfigMetricAllowList)\n ? clientConfigMetricAllowList\n : this._instance.persistence?.props[WEB_VITALS_ALLOWED_METRICS] || ['CLS', 'FCP', 'INP', 'LCP']\n }\n\n public get flushToCaptureTimeoutMs(): number {\n const clientConfig: number | undefined = isObject(this._instance.config.capture_performance)\n ? this._instance.config.capture_performance.web_vitals_delayed_flush_ms\n : undefined\n return clientConfig || DEFAULT_FLUSH_TO_CAPTURE_TIMEOUT_MILLISECONDS\n }\n\n public get _maxAllowedValue(): number {\n const configured =\n isObject(this._instance.config.capture_performance) &&\n isNumber(this._instance.config.capture_performance.__web_vitals_max_value)\n ? this._instance.config.capture_performance.__web_vitals_max_value\n : FIFTEEN_MINUTES_IN_MILLIS\n // you can set to 0 to disable the check or any value over ten seconds\n // 1 milli to 1 minute will be set to 15 minutes, cos that would be a silly low maximum\n return 0 < configured && configured <= ONE_MINUTE_IN_MILLIS ? FIFTEEN_MINUTES_IN_MILLIS : configured\n }\n\n public get isEnabled(): boolean {\n // Always disable web vitals if we're not on http or https\n const protocol = location?.protocol\n if (protocol !== 'http:' && protocol !== 'https:') {\n logger.info('Web Vitals are disabled on non-http/https protocols')\n return false\n }\n\n // Otherwise, check config\n const clientConfig = isObject(this._instance.config.capture_performance)\n ? this._instance.config.capture_performance.web_vitals\n : isBoolean(this._instance.config.capture_performance)\n ? this._instance.config.capture_performance\n : undefined\n return isBoolean(clientConfig) ? clientConfig : this._enabledServerSide\n }\n\n public startIfEnabled(): void {\n if (this.isEnabled && !this._initialized) {\n logger.info('enabled, starting...')\n this._loadScript(this._startCapturing)\n }\n }\n\n public onRemoteConfig(response: RemoteConfig) {\n const webVitalsOptIn = isObject(response.capturePerformance) && !!response.capturePerformance.web_vitals\n\n const allowedMetrics = isObject(response.capturePerformance)\n ? response.capturePerformance.web_vitals_allowed_metrics\n : undefined\n\n if (this._instance.persistence) {\n this._instance.persistence.register({\n [WEB_VITALS_ENABLED_SERVER_SIDE]: webVitalsOptIn,\n })\n\n this._instance.persistence.register({\n [WEB_VITALS_ALLOWED_METRICS]: allowedMetrics,\n })\n }\n // store this in-memory in case persistence is disabled\n this._enabledServerSide = webVitalsOptIn\n\n this.startIfEnabled()\n }\n\n private _loadScript(cb: () => void): void {\n if (assignableWindow.__PosthogExtensions__?.postHogWebVitalsCallbacks) {\n // already loaded\n cb()\n }\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(this._instance, 'web-vitals', (err) => {\n if (err) {\n logger.error('failed to load script', err)\n return\n }\n cb()\n })\n }\n\n private _currentURL(): string | undefined {\n const href = window ? window.location.href : undefined\n if (!href) {\n logger.error('Could not determine current URL')\n return undefined\n }\n\n // mask url query params\n const maskPersonalDataProperties = this._instance.config.mask_personal_data_properties\n const customPersonalDataProperties = this._instance.config.custom_personal_data_properties\n\n const paramsToMask = maskPersonalDataProperties\n ? extendArray([], PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])\n : []\n\n return maskQueryParams(href, paramsToMask, MASKED)\n }\n\n private _flushToCapture = () => {\n clearTimeout(this._delayedFlushTimer)\n if (this._buffer.metrics.length === 0) {\n return\n }\n\n this._instance.capture(\n '$web_vitals',\n this._buffer.metrics.reduce(\n (acc, metric) => ({\n ...acc,\n // the entire event so we can use it in the future e.g. includes google's rating\n [`$web_vitals_${metric.name}_event`]: { ...metric },\n [`$web_vitals_${metric.name}_value`]: metric.value,\n }),\n {}\n )\n )\n this._buffer = { url: undefined, metrics: [], firstMetricTimestamp: undefined }\n }\n\n private _addToBuffer = (metric: any) => {\n const sessionIds = this._instance.sessionManager?.checkAndGetSessionAndWindowId(true)\n if (isUndefined(sessionIds)) {\n logger.error('Could not read session ID. Dropping metrics!')\n return\n }\n\n this._buffer = this._buffer || { url: undefined, metrics: [], firstMetricTimestamp: undefined }\n\n const $currentUrl = this._currentURL()\n if (isUndefined($currentUrl)) {\n return\n }\n\n if (isNullish(metric?.name) || isNullish(metric?.value)) {\n logger.error('Invalid metric received', metric)\n return\n }\n\n // we observe some very large values sometimes, we'll ignore them\n // since the likelihood of LCP > 1 hour being correct is very low\n if (this._maxAllowedValue && metric.value >= this._maxAllowedValue) {\n logger.error('Ignoring metric with value >= ' + this._maxAllowedValue, metric)\n return\n }\n\n const urlHasChanged = this._buffer.url !== $currentUrl\n\n if (urlHasChanged) {\n // we need to send what we have\n this._flushToCapture()\n // poor performance is >4s, we wait twice that time to send\n // this is in case we haven't received all metrics\n // we'll at least gather some\n this._delayedFlushTimer = setTimeout(this._flushToCapture, this.flushToCaptureTimeoutMs)\n }\n\n if (isUndefined(this._buffer.url)) {\n this._buffer.url = $currentUrl\n }\n\n this._buffer.firstMetricTimestamp = isUndefined(this._buffer.firstMetricTimestamp)\n ? Date.now()\n : this._buffer.firstMetricTimestamp\n\n if (metric.attribution && metric.attribution.interactionTargetElement) {\n // we don't want to send the entire element\n // they can be very large\n // TODO we could run this through autocapture code so that we get elements chain info\n // and can display the element in the UI\n metric.attribution.interactionTargetElement = undefined\n }\n\n this._buffer.metrics.push({\n ...metric,\n $current_url: $currentUrl,\n $session_id: sessionIds.sessionId,\n $window_id: sessionIds.windowId,\n timestamp: Date.now(),\n })\n\n if (this._buffer.metrics.length === this.allowedMetrics.length) {\n // we have all allowed metrics\n this._flushToCapture()\n }\n }\n\n private _startCapturing = () => {\n let onLCP: WebVitalsMetricCallback | undefined\n let onCLS: WebVitalsMetricCallback | undefined\n let onFCP: WebVitalsMetricCallback | undefined\n let onINP: WebVitalsMetricCallback | undefined\n\n const posthogExtensions = assignableWindow.__PosthogExtensions__\n if (!isUndefined(posthogExtensions) && !isUndefined(posthogExtensions.postHogWebVitalsCallbacks)) {\n ;({ onLCP, onCLS, onFCP, onINP } = posthogExtensions.postHogWebVitalsCallbacks)\n }\n\n if (!onLCP || !onCLS || !onFCP || !onINP) {\n logger.error('web vitals callbacks not loaded - not starting')\n return\n }\n\n // register performance observers\n if (this.allowedMetrics.indexOf('LCP') > -1) {\n onLCP(this._addToBuffer.bind(this))\n }\n if (this.allowedMetrics.indexOf('CLS') > -1) {\n onCLS(this._addToBuffer.bind(this))\n }\n if (this.allowedMetrics.indexOf('FCP') > -1) {\n onFCP(this._addToBuffer.bind(this))\n }\n if (this.allowedMetrics.indexOf('INP') > -1) {\n onINP(this._addToBuffer.bind(this))\n }\n\n this._initialized = true\n }\n}\n","import RageClick from './extensions/rageclick'\nimport { DeadClickCandidate, Properties, RemoteConfig } from './types'\nimport { PostHog } from './posthog-core'\n\nimport { document, window } from './utils/globals'\nimport { getEventTarget, getParentElement } from './autocapture-utils'\nimport { HEATMAPS_ENABLED_SERVER_SIDE } from './constants'\nimport { isNumber, isUndefined, isEmptyObject, isObject } from '@posthog/core'\nimport { createLogger } from './utils/logger'\nimport { isElementInToolbar, isElementNode, isTag } from './utils/element-utils'\nimport { DeadClicksAutocapture, isDeadClicksEnabledForHeatmaps } from './extensions/dead-clicks-autocapture'\nimport { includes } from '@posthog/core'\nimport { addEventListener, extendArray } from './utils'\nimport { maskQueryParams } from './utils/request-utils'\nimport { PERSONAL_DATA_CAMPAIGN_PARAMS, MASKED } from './utils/event-utils'\n\nconst DEFAULT_FLUSH_INTERVAL = 5000\n\nconst logger = createLogger('[Heatmaps]')\n\ntype HeatmapEventBuffer =\n | {\n [key: string]: Properties[]\n }\n | undefined\n\nfunction elementOrParentPositionMatches(el: Element | null, matches: string[], breakOnElement?: Element): boolean {\n let curEl: Element | null | false = el\n\n while (curEl && isElementNode(curEl) && !isTag(curEl, 'body')) {\n if (curEl === breakOnElement) {\n return false\n }\n\n if (includes(matches, window?.getComputedStyle(curEl).position)) {\n return true\n }\n\n curEl = getParentElement(curEl)\n }\n\n return false\n}\n\nfunction isValidMouseEvent(e: unknown): e is MouseEvent {\n return isObject(e) && 'clientX' in e && 'clientY' in e && isNumber(e.clientX) && isNumber(e.clientY)\n}\n\nfunction shouldPoll(document: Document | undefined): boolean {\n return document?.visibilityState === 'visible'\n}\n\nexport class Heatmaps {\n instance: PostHog\n rageclicks: RageClick\n _enabledServerSide: boolean = false\n _initialized = false\n _mouseMoveTimeout: ReturnType<typeof setTimeout> | undefined\n\n private _buffer: HeatmapEventBuffer\n private _flushInterval: ReturnType<typeof setInterval> | null = null\n private _deadClicksCapture: DeadClicksAutocapture | undefined\n private _onClickHandler: ((e: Event) => void) | undefined\n private _onMouseMoveHandler: ((e: Event) => void) | undefined\n private _flushHandler: (() => void) | undefined\n private _onVisibilityChange_handler: (() => void) | undefined\n\n constructor(instance: PostHog) {\n this.instance = instance\n this._enabledServerSide = !!this.instance.persistence?.props[HEATMAPS_ENABLED_SERVER_SIDE]\n this.rageclicks = new RageClick(instance.config.rageclick)\n }\n\n public get flushIntervalMilliseconds(): number {\n let flushInterval = DEFAULT_FLUSH_INTERVAL\n if (\n isObject(this.instance.config.capture_heatmaps) &&\n this.instance.config.capture_heatmaps.flush_interval_milliseconds\n ) {\n flushInterval = this.instance.config.capture_heatmaps.flush_interval_milliseconds\n }\n return flushInterval\n }\n\n public get isEnabled(): boolean {\n if (!isUndefined(this.instance.config.capture_heatmaps)) {\n return this.instance.config.capture_heatmaps !== false\n }\n if (!isUndefined(this.instance.config.enable_heatmaps)) {\n return this.instance.config.enable_heatmaps\n }\n return this._enabledServerSide\n }\n\n public startIfEnabled(): void {\n if (this.isEnabled) {\n // nested if here since we only want to run the else\n // if this.enabled === false\n // not if this method is called more than once\n if (this._initialized) {\n return\n }\n logger.info('starting...')\n this._setupListeners()\n this._onVisibilityChange()\n } else {\n clearInterval(this._flushInterval ?? undefined)\n this._removeListeners()\n this.getAndClearBuffer()\n }\n }\n\n public onRemoteConfig(response: RemoteConfig) {\n const optIn = !!response['heatmaps']\n\n if (this.instance.persistence) {\n this.instance.persistence.register({\n [HEATMAPS_ENABLED_SERVER_SIDE]: optIn,\n })\n }\n // store this in-memory in case persistence is disabled\n this._enabledServerSide = optIn\n this.startIfEnabled()\n }\n\n public getAndClearBuffer(): HeatmapEventBuffer {\n const buffer = this._buffer\n this._buffer = undefined\n return buffer\n }\n\n private _onDeadClick(click: DeadClickCandidate): void {\n this._onClick(click.originalEvent, 'deadclick')\n }\n\n private _onVisibilityChange(): void {\n // always clear the interval just in case\n if (this._flushInterval) {\n clearInterval(this._flushInterval)\n }\n\n this._flushInterval = shouldPoll(document)\n ? setInterval(this._flush.bind(this), this.flushIntervalMilliseconds)\n : null\n }\n\n private _setupListeners(): void {\n if (!window || !document) {\n return\n }\n\n this._flushHandler = this._flush.bind(this)\n addEventListener(window, 'beforeunload', this._flushHandler)\n\n this._onClickHandler = (e) => this._onClick((e || window?.event) as MouseEvent)\n addEventListener(document, 'click', this._onClickHandler, { capture: true })\n\n this._onMouseMoveHandler = (e) => this._onMouseMove((e || window?.event) as MouseEvent)\n addEventListener(document, 'mousemove', this._onMouseMoveHandler, { capture: true })\n\n this._deadClicksCapture = new DeadClicksAutocapture(\n this.instance,\n isDeadClicksEnabledForHeatmaps,\n this._onDeadClick.bind(this)\n )\n this._deadClicksCapture.startIfEnabled()\n\n this._onVisibilityChange_handler = this._onVisibilityChange.bind(this)\n addEventListener(document, 'visibilitychange', this._onVisibilityChange_handler)\n\n this._initialized = true\n }\n\n private _removeListeners(): void {\n if (!window || !document) {\n return\n }\n\n if (this._flushHandler) {\n window.removeEventListener('beforeunload', this._flushHandler)\n }\n\n if (this._onClickHandler) {\n document.removeEventListener('click', this._onClickHandler, { capture: true })\n }\n\n if (this._onMouseMoveHandler) {\n document.removeEventListener('mousemove', this._onMouseMoveHandler, { capture: true })\n }\n\n if (this._onVisibilityChange_handler) {\n document.removeEventListener('visibilitychange', this._onVisibilityChange_handler)\n }\n\n clearTimeout(this._mouseMoveTimeout)\n\n this._deadClicksCapture?.stop()\n\n this._initialized = false\n }\n\n private _getProperties(e: MouseEvent, type: string): Properties {\n // We need to know if the target element is fixed or not\n // If fixed then we won't account for scrolling\n // If not then we will account for scrolling\n\n const scrollY = this.instance.scrollManager.scrollY()\n const scrollX = this.instance.scrollManager.scrollX()\n const scrollElement = this.instance.scrollManager.scrollElement()\n\n const isFixedOrSticky = elementOrParentPositionMatches(getEventTarget(e), ['fixed', 'sticky'], scrollElement)\n\n return {\n x: e.clientX + (isFixedOrSticky ? 0 : scrollX),\n y: e.clientY + (isFixedOrSticky ? 0 : scrollY),\n target_fixed: isFixedOrSticky,\n type,\n }\n }\n\n private _onClick(e: MouseEvent, type: string = 'click'): void {\n if (isElementInToolbar(e.target) || !isValidMouseEvent(e)) {\n return\n }\n\n const properties = this._getProperties(e, type)\n\n if (this.rageclicks?.isRageClick(e.clientX, e.clientY, new Date().getTime())) {\n this._capture({\n ...properties,\n type: 'rageclick',\n })\n }\n\n this._capture(properties)\n }\n\n private _onMouseMove(e: Event): void {\n if (isElementInToolbar(e.target) || !isValidMouseEvent(e)) {\n return\n }\n\n clearTimeout(this._mouseMoveTimeout)\n\n this._mouseMoveTimeout = setTimeout(() => {\n this._capture(this._getProperties(e as MouseEvent, 'mousemove'))\n }, 500)\n }\n\n private _capture(properties: Properties): void {\n if (!window) {\n return\n }\n\n const href = window.location.href\n\n // mask url query params\n const maskPersonalDataProperties = this.instance.config.mask_personal_data_properties\n const customPersonalDataProperties = this.instance.config.custom_personal_data_properties\n\n const paramsToMask = maskPersonalDataProperties\n ? extendArray([], PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])\n : []\n\n const url = maskQueryParams(href, paramsToMask, MASKED)\n\n this._buffer = this._buffer || {}\n\n if (!this._buffer[url]) {\n this._buffer[url] = []\n }\n\n this._buffer[url].push(properties)\n }\n\n private _flush(): void {\n if (!this._buffer || isEmptyObject(this._buffer)) {\n return\n }\n\n this.instance.capture('$$heatmap', {\n $heatmap_data: this.getAndClearBuffer(),\n })\n }\n}\n","import { window } from './utils/globals'\nimport { PostHog } from './posthog-core'\nimport { clampToRange, isUndefined } from '@posthog/core'\nimport { extend } from './utils'\nimport { logger } from './utils/logger'\nimport { SessionIdChangedCallback } from './types'\n\ninterface PageViewEventProperties {\n $pageview_id?: string\n $prev_pageview_id?: string\n $prev_pageview_pathname?: string\n $prev_pageview_duration?: number // seconds\n $prev_pageview_last_scroll?: number\n $prev_pageview_last_scroll_percentage?: number\n $prev_pageview_max_scroll?: number\n $prev_pageview_max_scroll_percentage?: number\n $prev_pageview_last_content?: number\n $prev_pageview_last_content_percentage?: number\n $prev_pageview_max_content?: number\n $prev_pageview_max_content_percentage?: number\n}\n\n// This keeps track of the PageView state (such as the previous PageView's path, timestamp, id, and scroll properties).\n// We store the state in memory, which means that for non-SPA sites, the state will be lost on page reload. This means\n// that non-SPA sites should always send a $pageleave event on any navigation, before the page unloads. For SPA sites,\n// they only need to send a $pageleave event when the user navigates away from the site, as the information is not lost\n// on an internal navigation, and is included as the $prev_pageview_ properties in the next $pageview event.\n\n// Practically, this means that to find the scroll properties for a given pageview, you need to find the event where\n// event name is $pageview or $pageleave and where $prev_pageview_id matches the original pageview event's id.\n\nexport class PageViewManager {\n _currentPageview?: { timestamp: Date; pageViewId: string | undefined; pathname: string | undefined }\n _instance: PostHog\n private _unsubscribeSessionId?: () => void\n\n constructor(instance: PostHog) {\n this._instance = instance\n this._setupSessionRotationHandler()\n }\n\n private _setupSessionRotationHandler(): void {\n this._unsubscribeSessionId = this._instance.sessionManager?.onSessionId(this._onSessionIdChange)\n }\n\n private _onSessionIdChange: SessionIdChangedCallback = (sessionId, _windowId, changeReason) => {\n // Only act on actual session rotations, not initial session creation\n if (!changeReason) {\n return\n }\n\n // Clear state when session changes for any of these reasons:\n // - noSessionId: after posthog.reset() or forced idle reset\n // - activityTimeout: 30 min idle (default, configurable up to 10 hours)\n // - sessionPastMaximumLength: 24 hour max session\n if (changeReason.noSessionId || changeReason.activityTimeout || changeReason.sessionPastMaximumLength) {\n logger.info('[PageViewManager] Session rotated, clearing pageview state', {\n sessionId,\n changeReason,\n })\n this._currentPageview = undefined\n this._instance.scrollManager.resetContext()\n }\n }\n\n destroy(): void {\n this._unsubscribeSessionId?.()\n this._unsubscribeSessionId = undefined\n }\n\n doPageView(timestamp: Date, pageViewId?: string): PageViewEventProperties {\n const response = this._previousPageViewProperties(timestamp, pageViewId)\n\n // On a pageview we reset the contexts\n this._currentPageview = { pathname: window?.location.pathname ?? '', pageViewId, timestamp }\n this._instance.scrollManager.resetContext()\n\n return response\n }\n\n doPageLeave(timestamp: Date): PageViewEventProperties {\n return this._previousPageViewProperties(timestamp, this._currentPageview?.pageViewId)\n }\n\n doEvent(): PageViewEventProperties {\n return { $pageview_id: this._currentPageview?.pageViewId }\n }\n\n private _previousPageViewProperties(timestamp: Date, pageviewId: string | undefined): PageViewEventProperties {\n const previousPageView = this._currentPageview\n\n if (!previousPageView) {\n return { $pageview_id: pageviewId }\n }\n\n let properties: PageViewEventProperties = {\n $pageview_id: pageviewId,\n $prev_pageview_id: previousPageView.pageViewId,\n }\n\n const scrollContext = this._instance.scrollManager.getContext()\n\n if (scrollContext && !this._instance.config.disable_scroll_properties) {\n let { maxScrollHeight, lastScrollY, maxScrollY, maxContentHeight, lastContentY, maxContentY } =\n scrollContext\n\n if (\n !isUndefined(maxScrollHeight) &&\n !isUndefined(lastScrollY) &&\n !isUndefined(maxScrollY) &&\n !isUndefined(maxContentHeight) &&\n !isUndefined(lastContentY) &&\n !isUndefined(maxContentY)\n ) {\n // Use ceil, so that e.g. scrolling 999.5px of a 1000px page is considered 100% scrolled\n maxScrollHeight = Math.ceil(maxScrollHeight)\n lastScrollY = Math.ceil(lastScrollY)\n maxScrollY = Math.ceil(maxScrollY)\n maxContentHeight = Math.ceil(maxContentHeight)\n lastContentY = Math.ceil(lastContentY)\n maxContentY = Math.ceil(maxContentY)\n\n // if the maximum scroll height is near 0, then the percentage is 1\n const lastScrollPercentage =\n maxScrollHeight <= 1 ? 1 : clampToRange(lastScrollY / maxScrollHeight, 0, 1, logger)\n const maxScrollPercentage =\n maxScrollHeight <= 1 ? 1 : clampToRange(maxScrollY / maxScrollHeight, 0, 1, logger)\n const lastContentPercentage =\n maxContentHeight <= 1 ? 1 : clampToRange(lastContentY / maxContentHeight, 0, 1, logger)\n const maxContentPercentage =\n maxContentHeight <= 1 ? 1 : clampToRange(maxContentY / maxContentHeight, 0, 1, logger)\n\n properties = extend(properties, {\n $prev_pageview_last_scroll: lastScrollY,\n $prev_pageview_last_scroll_percentage: lastScrollPercentage,\n $prev_pageview_max_scroll: maxScrollY,\n $prev_pageview_max_scroll_percentage: maxScrollPercentage,\n $prev_pageview_last_content: lastContentY,\n $prev_pageview_last_content_percentage: lastContentPercentage,\n $prev_pageview_max_content: maxContentY,\n $prev_pageview_max_content_percentage: maxContentPercentage,\n })\n }\n }\n\n if (previousPageView.pathname) {\n properties.$prev_pageview_pathname = previousPageView.pathname\n }\n if (previousPageView.timestamp) {\n // Use seconds, for consistency with our other duration-related properties like $duration\n properties.$prev_pageview_duration = (timestamp.getTime() - previousPageView.timestamp.getTime()) / 1000\n }\n\n return properties\n }\n}\n","import { PostHog } from './posthog-core'\nimport { Survey } from './posthog-surveys-types'\nimport { ConversationsRemoteConfig } from './posthog-conversations-types'\n\n// only importing types here, so won't affect the bundle\n// eslint-disable-next-line posthog-js/no-external-replay-imports\nimport type { SAMPLED } from './extensions/replay/external/triggerMatching'\n\n// ============================================================================\n// Re-export public types from @posthog/types\n// ============================================================================\n\n// PostHog instance type\nexport type { PostHog as PostHogInterface } from '@posthog/types'\n\n// Common types\nexport type { Property, Properties, JsonType, JsonRecord } from '@posthog/types'\n\n// Capture types\nexport type { KnownEventName, EventName, CaptureResult, CaptureOptions, BeforeSendFn } from '@posthog/types'\n\n// Feature flag types\nexport type {\n FeatureFlagsCallback,\n FeatureFlagDetail,\n FeatureFlagMetadata,\n EvaluationReason,\n RemoteConfigFeatureFlagCallback,\n EarlyAccessFeature,\n EarlyAccessFeatureStage,\n EarlyAccessFeatureCallback,\n EarlyAccessFeatureResponse,\n} from '@posthog/types'\n\n// Request types\nexport type { Headers, RequestResponse, RequestCallback } from '@posthog/types'\n\n// Session recording types\nexport type {\n SessionRecordingCanvasOptions,\n InitiatorType,\n NetworkRequest,\n CapturedNetworkRequest,\n SessionIdChangedCallback,\n SeverityLevel,\n} from '@posthog/types'\n\n// Config types\nexport type {\n AutocaptureCompatibleElement,\n DomAutocaptureEvents,\n AutocaptureConfig,\n RageclickConfig,\n BootstrapConfig,\n SupportedWebVitalsMetrics,\n PerformanceCaptureConfig,\n DeadClickCandidate,\n ExceptionAutoCaptureConfig,\n DeadClicksAutoCaptureConfig,\n HeatmapConfig,\n ConfigDefaults,\n ExternalIntegrationKind,\n ErrorTrackingOptions,\n MaskInputOptions,\n SlimDOMOptions,\n SessionRecordingOptions,\n RequestQueueConfig,\n PostHogConfig,\n} from '@posthog/types'\n\n// Re-export KnownUnsafeEditableEvent from @posthog/core for backwards compatibility\nexport type { KnownUnsafeEditableEvent } from '@posthog/core'\n\n// ============================================================================\n// Browser-specific types that depend on local imports\n// These cannot be moved to @posthog/types as they reference browser-specific code\n// ============================================================================\n\n// Import types for internal use in this file\nimport type {\n SessionRecordingCanvasOptions,\n PerformanceCaptureConfig,\n InitiatorType,\n JsonType,\n Properties,\n EventName,\n CapturedNetworkRequest,\n SessionRecordingOptions,\n FeatureFlagDetail,\n} from '@posthog/types'\n\nexport enum Compression {\n GZipJS = 'gzip-js',\n Base64 = 'base64',\n}\n\n// See https://nextjs.org/docs/app/api-reference/functions/fetch#fetchurl-options\ntype NextOptions = { revalidate: false | 0 | number; tags: string[] }\n\nexport interface RequestWithOptions {\n url: string\n // Data can be a single object or an array of objects when batched\n data?: Record<string, any> | Record<string, any>[]\n headers?: Record<string, any>\n transport?: 'XHR' | 'fetch' | 'sendBeacon'\n method?: 'POST' | 'GET'\n urlQueryArgs?: { compression: Compression }\n callback?: (response: import('@posthog/types').RequestResponse) => void\n timeout?: number\n noRetries?: boolean\n disableTransport?: ('XHR' | 'fetch' | 'sendBeacon')[]\n disableXHRCredentials?: boolean\n compression?: Compression | 'best-available'\n fetchOptions?: {\n cache?: RequestInit['cache']\n next?: NextOptions\n }\n}\n\n// Queued request types - the same as a request but with additional queueing information\nexport interface QueuedRequestWithOptions extends RequestWithOptions {\n /** key of queue, e.g. 'sessionRecording' vs 'event' */\n batchKey?: string\n}\n\n// Used explicitly for retriable requests\nexport interface RetriableRequestWithOptions extends QueuedRequestWithOptions {\n retriesPerformedSoFar?: number\n}\n\nexport type FlagVariant = { flag: string; variant: string }\n\n/** the config stored in persistence when session recording remote config is received */\nexport type SessionRecordingPersistedConfig = Omit<\n SessionRecordingRemoteConfig,\n | 'recordCanvas'\n | 'canvasFps'\n | 'canvasQuality'\n | 'networkPayloadCapture'\n | 'sampleRate'\n | 'minimumDurationMilliseconds'\n> & {\n enabled: boolean\n networkPayloadCapture: SessionRecordingRemoteConfig['networkPayloadCapture'] & {\n capturePerformance: RemoteConfig['capturePerformance']\n }\n canvasRecording: {\n enabled: SessionRecordingRemoteConfig['recordCanvas']\n fps: SessionRecordingRemoteConfig['canvasFps']\n quality: SessionRecordingRemoteConfig['canvasQuality']\n }\n // we don't allow string config here\n sampleRate: number | null\n minimumDurationMilliseconds: number | null | undefined\n}\n\nexport type SessionRecordingRemoteConfig = SessionRecordingCanvasOptions & {\n endpoint?: string\n consoleLogRecordingEnabled?: boolean\n // the API returns a decimal between 0 and 1 as a string\n sampleRate?: string | null\n minimumDurationMilliseconds?: number\n linkedFlag?: string | FlagVariant | null\n networkPayloadCapture?: Pick<NetworkRecordOptions, 'recordBody' | 'recordHeaders'>\n masking?: Pick<SessionRecordingOptions, 'maskAllInputs' | 'maskTextSelector' | 'blockSelector'>\n urlTriggers?: SessionRecordingUrlTrigger[]\n scriptConfig?: { script?: string | undefined }\n urlBlocklist?: SessionRecordingUrlTrigger[]\n eventTriggers?: string[]\n /**\n * Controls how event, url, sampling, and linked flag triggers are combined\n *\n * `any` means that if any of the triggers match, the session will be recorded\n * `all` means that all the triggers must match for the session to be recorded\n *\n * originally it was (event || url) && (sampling || linked flag)\n * which nobody wanted, now the default is all\n */\n triggerMatchType?: 'any' | 'all'\n}\n\n/**\n * Remote configuration for the PostHog instance\n *\n * All of these settings can be configured directly in your PostHog instance\n * Any configuration set in the client overrides the information from the server\n */\nexport interface RemoteConfig {\n /**\n * Supported compression algorithms\n */\n supportedCompression: Compression[]\n\n /**\n * If set, disables autocapture\n */\n autocapture_opt_out?: boolean\n\n /**\n * originally capturePerformance was replay only and so boolean true\n * is equivalent to { network_timing: true }\n * now capture performance can be separately enabled within replay\n * and as a standalone web vitals tracker\n * people can have them enabled separately\n * they work standalone but enhance each other\n * TODO: deprecate this so we make a new config that doesn't need this explanation\n */\n capturePerformance?: boolean | PerformanceCaptureConfig\n\n /**\n * Whether we should use a custom endpoint for analytics\n *\n * @default { endpoint: \"/e\" }\n */\n analytics?: {\n endpoint?: string\n }\n\n /**\n * Whether the `$elements_chain` property should be sent as a string or as an array\n *\n * @default false\n */\n elementsChainAsString?: boolean\n\n /**\n * Error tracking configuration options\n */\n errorTracking?: {\n autocaptureExceptions?: boolean\n captureExtensionExceptions?: boolean\n suppressionRules?: ErrorTrackingSuppressionRule[]\n }\n\n /**\n * This is currently in development and may have breaking changes without a major version bump\n */\n autocaptureExceptions?: boolean | { endpoint?: string }\n\n /**\n * Session recording configuration options\n */\n sessionRecording?: SessionRecordingRemoteConfig | false\n\n /**\n * Whether surveys are enabled\n */\n surveys?: boolean | Survey[]\n\n /**\n * Whether product tours are enabled\n */\n productTours?: boolean\n\n /**\n * Parameters for the toolbar\n */\n toolbarParams: ToolbarParams\n\n /**\n * @deprecated renamed to toolbarParams, still present on older API responses\n */\n editorParams?: ToolbarParams\n\n /**\n * @deprecated, moved to toolbarParams\n */\n toolbarVersion: 'toolbar'\n\n /**\n * Whether the user is authenticated\n */\n isAuthenticated: boolean\n\n /**\n * List of site apps with their IDs and URLs\n */\n siteApps: { id: string; url: string }[]\n\n /**\n * Whether heatmaps are enabled\n */\n heatmaps?: boolean\n\n /**\n * Whether to only capture identified users by default\n */\n defaultIdentifiedOnly?: boolean\n\n /**\n * Whether to capture dead clicks\n */\n captureDeadClicks?: boolean\n\n /**\n * Indicates if the team has any flags enabled (if not we don't need to load them)\n */\n hasFeatureFlags?: boolean\n\n /**\n * Conversations widget configuration\n */\n conversations?: boolean | ConversationsRemoteConfig\n}\n\n/**\n * Flags returns feature flags and their payloads, and optionally returns everything else from the remote config\n * assuming it's called with `config=true`\n */\nexport interface FlagsResponse extends RemoteConfig {\n featureFlags: Record<string, string | boolean>\n featureFlagPayloads: Record<string, JsonType>\n errorsWhileComputingFlags: boolean\n requestId?: string\n flags: Record<string, FeatureFlagDetail>\n evaluatedAt?: number\n}\n\nexport type SiteAppGlobals = {\n event: {\n uuid: string\n event: EventName\n properties: Properties\n timestamp?: Date\n elements_chain?: string\n distinct_id?: string\n }\n person: {\n properties: Properties\n }\n groups: Record<string, { id: string; type: string; properties: Properties }>\n}\n\nexport type SiteAppLoader = {\n id: string\n init: (config: { posthog: PostHog; callback: (success: boolean) => void }) => {\n processEvent?: (globals: SiteAppGlobals) => void\n }\n}\n\nexport type SiteApp = {\n id: string\n loaded: boolean\n errored: boolean\n processedBuffer: boolean\n processEvent?: (globals: SiteAppGlobals) => void\n}\n\nexport interface PersistentStore {\n _is_supported: () => boolean\n _error: (error: any) => void\n _parse: (name: string) => any\n _get: (name: string) => any\n _set: (\n name: string,\n value: any,\n expire_days?: number | null,\n cross_subdomain?: boolean,\n secure?: boolean,\n debug?: boolean\n ) => void\n _remove: (name: string, cross_subdomain?: boolean) => void\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport type Breaker = {}\nexport type EventHandler = (event: Event) => boolean | void\n\nexport type ToolbarUserIntent = 'add-action' | 'edit-action'\nexport type ToolbarSource = 'url' | 'localstorage'\nexport type ToolbarVersion = 'toolbar'\n\n/* sync with posthog */\nexport interface ToolbarParams {\n token?: string /** public posthog-js token */\n temporaryToken?: string /** private temporary user token */\n actionId?: number\n userIntent?: ToolbarUserIntent\n source?: ToolbarSource\n toolbarVersion?: ToolbarVersion\n instrument?: boolean\n distinctId?: string\n userEmail?: string\n dataAttributes?: string[]\n featureFlags?: Record<string, string | boolean>\n}\n\nexport type SnippetArrayItem = [method: string, ...args: any[]]\n\nexport type NetworkRecordOptions = {\n initiatorTypes?: InitiatorType[]\n maskRequestFn?: (data: CapturedNetworkRequest) => CapturedNetworkRequest | undefined\n recordHeaders?: boolean | { request: boolean; response: boolean }\n recordBody?: boolean | string[] | { request: boolean | string[]; response: boolean | string[] }\n recordInitialRequests?: boolean\n /**\n * whether to record PerformanceEntry events for network requests\n */\n recordPerformance?: boolean\n /**\n * the PerformanceObserver will only observe these entry types\n */\n performanceEntryTypeToObserve: string[]\n /**\n * the maximum size of the request/response body to record\n * NB this will be at most 1MB even if set larger\n */\n payloadSizeLimitBytes: number\n /**\n * some domains we should never record the payload\n * for example other companies session replay ingestion payloads aren't super useful but are gigantic\n * if this isn't provided we use a default list\n * if this is provided - we add the provided list to the default list\n * i.e. we never record the payloads on the default deny list\n */\n payloadHostDenyList?: string[]\n}\n\nexport type ErrorEventArgs = [\n event: string | Event,\n source?: string | undefined,\n lineno?: number | undefined,\n colno?: number | undefined,\n error?: Error | undefined,\n]\n\n// levels originally copied from Sentry to work with the sentry integration\n// and to avoid relying on a frequently changing @sentry/types dependency\n// but provided as an array of literal types, so we can constrain the level below\nexport const severityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug'] as const\n\nexport interface SessionRecordingUrlTrigger {\n url: string\n matching: 'regex'\n}\n\nexport type PropertyMatchType = 'regex' | 'not_regex' | 'exact' | 'is_not' | 'icontains' | 'not_icontains'\n\nexport interface ErrorTrackingSuppressionRule {\n type: 'AND' | 'OR'\n values: ErrorTrackingSuppressionRuleValue[]\n}\n\nexport interface ErrorTrackingSuppressionRuleValue {\n key: '$exception_types' | '$exception_values'\n operator: PropertyMatchType\n value: string | string[]\n type: string\n}\n\nexport type SessionStartReason =\n | 'sampling_overridden'\n | 'recording_initialized'\n | 'linked_flag_matched'\n | 'linked_flag_overridden'\n | typeof SAMPLED\n | 'session_id_changed'\n | 'url_trigger_matched'\n | 'event_trigger_matched'\n\nexport type OverrideConfig = {\n sampling: boolean\n linked_flag: boolean\n url_trigger: boolean\n event_trigger: boolean\n}\n","// DEFLATE is a complex format; to read this code, you should probably check the RFC first:\n// https://tools.ietf.org/html/rfc1951\n// You may also wish to take a look at the guide I made about this program:\n// https://gist.github.com/101arrowz/253f31eb5abc3d9275ab943003ffecad\n// Much of the following code is similar to that of UZIP.js:\n// https://github.com/photopea/UZIP.js\n// Many optimizations have been made, so the bundle size is ultimately smaller but performance is similar.\n// Sometimes 0 will appear where -1 would be more appropriate. This is because using a uint\n// is better for memory in most engines (I *think*).\nvar ch2 = {};\nvar wk = (function (c, id, msg, transfer, cb) {\n var u = ch2[id] || (ch2[id] = URL.createObjectURL(new Blob([c], { type: 'text/javascript' })));\n var w = new Worker(u);\n w.onerror = function (e) { return cb(e.error, null); };\n w.onmessage = function (e) { return cb(null, e.data); };\n w.postMessage(msg, transfer);\n return w;\n});\n\n// aliases for shorter compressed code (most minifers don't do this)\nvar u8 = Uint8Array, u16 = Uint16Array, u32 = Uint32Array;\n// fixed length extra bits\nvar fleb = new u8([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, /* unused */ 0, 0, /* impossible */ 0]);\n// fixed distance extra bits\n// see fleb note\nvar fdeb = new u8([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, /* unused */ 0, 0]);\n// code length index map\nvar clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);\n// get base, reverse index map from extra bits\nvar freb = function (eb, start) {\n var b = new u16(31);\n for (var i = 0; i < 31; ++i) {\n b[i] = start += 1 << eb[i - 1];\n }\n // numbers here are at max 18 bits\n var r = new u32(b[30]);\n for (var i = 1; i < 30; ++i) {\n for (var j = b[i]; j < b[i + 1]; ++j) {\n r[j] = ((j - b[i]) << 5) | i;\n }\n }\n return [b, r];\n};\nvar _a = freb(fleb, 2), fl = _a[0], revfl = _a[1];\n// we can ignore the fact that the other numbers are wrong; they never happen anyway\nfl[28] = 258, revfl[258] = 28;\nvar _b = freb(fdeb, 0), fd = _b[0], revfd = _b[1];\n// map of value to reverse (assuming 16 bits)\nvar rev = new u16(32768);\nfor (var i = 0; i < 32768; ++i) {\n // reverse table algorithm from SO\n var x = ((i & 0xAAAA) >>> 1) | ((i & 0x5555) << 1);\n x = ((x & 0xCCCC) >>> 2) | ((x & 0x3333) << 2);\n x = ((x & 0xF0F0) >>> 4) | ((x & 0x0F0F) << 4);\n rev[i] = (((x & 0xFF00) >>> 8) | ((x & 0x00FF) << 8)) >>> 1;\n}\n// create huffman tree from u8 \"map\": index -> code length for code index\n// mb (max bits) must be at most 15\n// TODO: optimize/split up?\nvar hMap = (function (cd, mb, r) {\n var s = cd.length;\n // index\n var i = 0;\n // u16 \"map\": index -> # of codes with bit length = index\n var l = new u16(mb);\n // length of cd must be 288 (total # of codes)\n for (; i < s; ++i)\n ++l[cd[i] - 1];\n // u16 \"map\": index -> minimum code for bit length = index\n var le = new u16(mb);\n for (i = 0; i < mb; ++i) {\n le[i] = (le[i - 1] + l[i - 1]) << 1;\n }\n var co;\n if (r) {\n // u16 \"map\": index -> number of actual bits, symbol for code\n co = new u16(1 << mb);\n // bits to remove for reverser\n var rvb = 15 - mb;\n for (i = 0; i < s; ++i) {\n // ignore 0 lengths\n if (cd[i]) {\n // num encoding both symbol and bits read\n var sv = (i << 4) | cd[i];\n // free bits\n var r_1 = mb - cd[i];\n // start value\n var v = le[cd[i] - 1]++ << r_1;\n // m is end value\n for (var m = v | ((1 << r_1) - 1); v <= m; ++v) {\n // every 16 bit value starting with the code yields the same result\n co[rev[v] >>> rvb] = sv;\n }\n }\n }\n }\n else {\n co = new u16(s);\n for (i = 0; i < s; ++i)\n co[i] = rev[le[cd[i] - 1]++] >>> (15 - cd[i]);\n }\n return co;\n});\n// fixed length tree\nvar flt = new u8(288);\nfor (var i = 0; i < 144; ++i)\n flt[i] = 8;\nfor (var i = 144; i < 256; ++i)\n flt[i] = 9;\nfor (var i = 256; i < 280; ++i)\n flt[i] = 7;\nfor (var i = 280; i < 288; ++i)\n flt[i] = 8;\n// fixed distance tree\nvar fdt = new u8(32);\nfor (var i = 0; i < 32; ++i)\n fdt[i] = 5;\n// fixed length map\nvar flm = /*#__PURE__*/ hMap(flt, 9, 0), flrm = /*#__PURE__*/ hMap(flt, 9, 1);\n// fixed distance map\nvar fdm = /*#__PURE__*/ hMap(fdt, 5, 0), fdrm = /*#__PURE__*/ hMap(fdt, 5, 1);\n// find max of array\nvar max = function (a) {\n var m = a[0];\n for (var i = 1; i < a.length; ++i) {\n if (a[i] > m)\n m = a[i];\n }\n return m;\n};\n// read d, starting at bit p and mask with m\nvar bits = function (d, p, m) {\n var o = (p / 8) >> 0;\n return ((d[o] | (d[o + 1] << 8)) >>> (p & 7)) & m;\n};\n// read d, starting at bit p continuing for at least 16 bits\nvar bits16 = function (d, p) {\n var o = (p / 8) >> 0;\n return ((d[o] | (d[o + 1] << 8) | (d[o + 2] << 16)) >>> (p & 7));\n};\n// get end of byte\nvar shft = function (p) { return ((p / 8) >> 0) + (p & 7 && 1); };\n// typed array slice - allows garbage collector to free original reference,\n// while being more compatible than .slice\nvar slc = function (v, s, e) {\n if (s == null || s < 0)\n s = 0;\n if (e == null || e > v.length)\n e = v.length;\n // can't use .constructor in case user-supplied\n var n = new (v instanceof u16 ? u16 : v instanceof u32 ? u32 : u8)(e - s);\n n.set(v.subarray(s, e));\n return n;\n};\n// expands raw DEFLATE data\nvar inflt = function (dat, buf, st) {\n // source length\n var sl = dat.length;\n // have to estimate size\n var noBuf = !buf || st;\n // no state\n var noSt = !st || st.i;\n if (!st)\n st = {};\n // Assumes roughly 33% compression ratio average\n if (!buf)\n buf = new u8(sl * 3);\n // ensure buffer can fit at least l elements\n var cbuf = function (l) {\n var bl = buf.length;\n // need to increase size to fit\n if (l > bl) {\n // Double or set to necessary, whichever is greater\n var nbuf = new u8(Math.max(bl * 2, l));\n nbuf.set(buf);\n buf = nbuf;\n }\n };\n // last chunk bitpos bytes\n var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;\n // total bits\n var tbts = sl * 8;\n do {\n if (!lm) {\n // BFINAL - this is only 1 when last chunk is next\n st.f = final = bits(dat, pos, 1);\n // type: 0 = no compression, 1 = fixed huffman, 2 = dynamic huffman\n var type = bits(dat, pos + 1, 3);\n pos += 3;\n if (!type) {\n // go to end of byte boundary\n var s = shft(pos) + 4, l = dat[s - 4] | (dat[s - 3] << 8), t = s + l;\n if (t > sl) {\n if (noSt)\n throw 'unexpected EOF';\n break;\n }\n // ensure size\n if (noBuf)\n cbuf(bt + l);\n // Copy over uncompressed data\n buf.set(dat.subarray(s, t), bt);\n // Get new bitpos, update byte count\n st.b = bt += l, st.p = pos = t * 8;\n continue;\n }\n else if (type == 1)\n lm = flrm, dm = fdrm, lbt = 9, dbt = 5;\n else if (type == 2) {\n // literal lengths\n var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;\n var tl = hLit + bits(dat, pos + 5, 31) + 1;\n pos += 14;\n // length+distance tree\n var ldt = new u8(tl);\n // code length tree\n var clt = new u8(19);\n for (var i = 0; i < hcLen; ++i) {\n // use index map to get real code\n clt[clim[i]] = bits(dat, pos + i * 3, 7);\n }\n pos += hcLen * 3;\n // code lengths bits\n var clb = max(clt), clbmsk = (1 << clb) - 1;\n if (!noSt && pos + tl * (clb + 7) > tbts)\n break;\n // code lengths map\n var clm = hMap(clt, clb, 1);\n for (var i = 0; i < tl;) {\n var r = clm[bits(dat, pos, clbmsk)];\n // bits read\n pos += r & 15;\n // symbol\n var s = r >>> 4;\n // code length to copy\n if (s < 16) {\n ldt[i++] = s;\n }\n else {\n // copy count\n var c = 0, n = 0;\n if (s == 16)\n n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];\n else if (s == 17)\n n = 3 + bits(dat, pos, 7), pos += 3;\n else if (s == 18)\n n = 11 + bits(dat, pos, 127), pos += 7;\n while (n--)\n ldt[i++] = c;\n }\n }\n // length tree distance tree\n var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);\n // max length bits\n lbt = max(lt);\n // max dist bits\n dbt = max(dt);\n lm = hMap(lt, lbt, 1);\n dm = hMap(dt, dbt, 1);\n }\n else\n throw 'invalid block type';\n if (pos > tbts)\n throw 'unexpected EOF';\n }\n // Make sure the buffer can hold this + the largest possible addition\n // Maximum chunk size (practically, theoretically infinite) is 2^17;\n if (noBuf)\n cbuf(bt + 131072);\n var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;\n var mxa = lbt + dbt + 18;\n while (noSt || pos + mxa < tbts) {\n // bits read, code\n var c = lm[bits16(dat, pos) & lms], sym = c >>> 4;\n pos += c & 15;\n if (pos > tbts)\n throw 'unexpected EOF';\n if (!c)\n throw 'invalid length/literal';\n if (sym < 256)\n buf[bt++] = sym;\n else if (sym == 256) {\n lm = null;\n break;\n }\n else {\n var add = sym - 254;\n // no extra bits needed if less\n if (sym > 264) {\n // index\n var i = sym - 257, b = fleb[i];\n add = bits(dat, pos, (1 << b) - 1) + fl[i];\n pos += b;\n }\n // dist\n var d = dm[bits16(dat, pos) & dms], dsym = d >>> 4;\n if (!d)\n throw 'invalid distance';\n pos += d & 15;\n var dt = fd[dsym];\n if (dsym > 3) {\n var b = fdeb[dsym];\n dt += bits16(dat, pos) & ((1 << b) - 1), pos += b;\n }\n if (pos > tbts)\n throw 'unexpected EOF';\n if (noBuf)\n cbuf(bt + 131072);\n var end = bt + add;\n for (; bt < end; bt += 4) {\n buf[bt] = buf[bt - dt];\n buf[bt + 1] = buf[bt + 1 - dt];\n buf[bt + 2] = buf[bt + 2 - dt];\n buf[bt + 3] = buf[bt + 3 - dt];\n }\n bt = end;\n }\n }\n st.l = lm, st.p = pos, st.b = bt;\n if (lm)\n final = 1, st.m = lbt, st.d = dm, st.n = dbt;\n } while (!final);\n return bt == buf.length ? buf : slc(buf, 0, bt);\n};\n// starting at p, write the minimum number of bits that can hold v to d\nvar wbits = function (d, p, v) {\n v <<= p & 7;\n var o = (p / 8) >> 0;\n d[o] |= v;\n d[o + 1] |= v >>> 8;\n};\n// starting at p, write the minimum number of bits (>8) that can hold v to d\nvar wbits16 = function (d, p, v) {\n v <<= p & 7;\n var o = (p / 8) >> 0;\n d[o] |= v;\n d[o + 1] |= v >>> 8;\n d[o + 2] |= v >>> 16;\n};\n// creates code lengths from a frequency table\nvar hTree = function (d, mb) {\n // Need extra info to make a tree\n var t = [];\n for (var i = 0; i < d.length; ++i) {\n if (d[i])\n t.push({ s: i, f: d[i] });\n }\n var s = t.length;\n var t2 = t.slice();\n if (!s)\n return [new u8(0), 0];\n if (s == 1) {\n var v = new u8(t[0].s + 1);\n v[t[0].s] = 1;\n return [v, 1];\n }\n t.sort(function (a, b) { return a.f - b.f; });\n // after i2 reaches last ind, will be stopped\n // freq must be greater than largest possible number of symbols\n t.push({ s: -1, f: 25001 });\n var l = t[0], r = t[1], i0 = 0, i1 = 1, i2 = 2;\n t[0] = { s: -1, f: l.f + r.f, l: l, r: r };\n // efficient algorithm from UZIP.js\n // i0 is lookbehind, i2 is lookahead - after processing two low-freq\n // symbols that combined have high freq, will start processing i2 (high-freq,\n // non-composite) symbols instead\n // see https://reddit.com/r/photopea/comments/ikekht/uzipjs_questions/\n while (i1 != s - 1) {\n l = t[t[i0].f < t[i2].f ? i0++ : i2++];\n r = t[i0 != i1 && t[i0].f < t[i2].f ? i0++ : i2++];\n t[i1++] = { s: -1, f: l.f + r.f, l: l, r: r };\n }\n var maxSym = t2[0].s;\n for (var i = 1; i < s; ++i) {\n if (t2[i].s > maxSym)\n maxSym = t2[i].s;\n }\n // code lengths\n var tr = new u16(maxSym + 1);\n // max bits in tree\n var mbt = ln(t[i1 - 1], tr, 0);\n if (mbt > mb) {\n // more algorithms from UZIP.js\n // TODO: find out how this code works (debt)\n // ind debt\n var i = 0, dt = 0;\n // left cost\n var lft = mbt - mb, cst = 1 << lft;\n t2.sort(function (a, b) { return tr[b.s] - tr[a.s] || a.f - b.f; });\n for (; i < s; ++i) {\n var i2_1 = t2[i].s;\n if (tr[i2_1] > mb) {\n dt += cst - (1 << (mbt - tr[i2_1]));\n tr[i2_1] = mb;\n }\n else\n break;\n }\n dt >>>= lft;\n while (dt > 0) {\n var i2_2 = t2[i].s;\n if (tr[i2_2] < mb)\n dt -= 1 << (mb - tr[i2_2]++ - 1);\n else\n ++i;\n }\n for (; i >= 0 && dt; --i) {\n var i2_3 = t2[i].s;\n if (tr[i2_3] == mb) {\n --tr[i2_3];\n ++dt;\n }\n }\n mbt = mb;\n }\n return [new u8(tr), mbt];\n};\n// get the max length and assign length codes\nvar ln = function (n, l, d) {\n return n.s == -1\n ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1))\n : (l[n.s] = d);\n};\n// length codes generation\nvar lc = function (c) {\n var s = c.length;\n // Note that the semicolon was intentional\n while (s && !c[--s])\n ;\n var cl = new u16(++s);\n // ind num streak\n var cli = 0, cln = c[0], cls = 1;\n var w = function (v) { cl[cli++] = v; };\n for (var i = 1; i <= s; ++i) {\n if (c[i] == cln && i != s)\n ++cls;\n else {\n if (!cln && cls > 2) {\n for (; cls > 138; cls -= 138)\n w(32754);\n if (cls > 2) {\n w(cls > 10 ? ((cls - 11) << 5) | 28690 : ((cls - 3) << 5) | 12305);\n cls = 0;\n }\n }\n else if (cls > 3) {\n w(cln), --cls;\n for (; cls > 6; cls -= 6)\n w(8304);\n if (cls > 2)\n w(((cls - 3) << 5) | 8208), cls = 0;\n }\n while (cls--)\n w(cln);\n cls = 1;\n cln = c[i];\n }\n }\n return [cl.subarray(0, cli), s];\n};\n// calculate the length of output from tree, code lengths\nvar clen = function (cf, cl) {\n var l = 0;\n for (var i = 0; i < cl.length; ++i)\n l += cf[i] * cl[i];\n return l;\n};\n// writes a fixed block\n// returns the new bit pos\nvar wfblk = function (out, pos, dat) {\n // no need to write 00 as type: TypedArray defaults to 0\n var s = dat.length;\n var o = shft(pos + 2);\n out[o] = s & 255;\n out[o + 1] = s >>> 8;\n out[o + 2] = out[o] ^ 255;\n out[o + 3] = out[o + 1] ^ 255;\n for (var i = 0; i < s; ++i)\n out[o + i + 4] = dat[i];\n return (o + 4 + s) * 8;\n};\n// writes a block\nvar wblk = function (dat, out, final, syms, lf, df, eb, li, bs, bl, p) {\n wbits(out, p++, final);\n ++lf[256];\n var _a = hTree(lf, 15), dlt = _a[0], mlb = _a[1];\n var _b = hTree(df, 15), ddt = _b[0], mdb = _b[1];\n var _c = lc(dlt), lclt = _c[0], nlc = _c[1];\n var _d = lc(ddt), lcdt = _d[0], ndc = _d[1];\n var lcfreq = new u16(19);\n for (var i = 0; i < lclt.length; ++i)\n lcfreq[lclt[i] & 31]++;\n for (var i = 0; i < lcdt.length; ++i)\n lcfreq[lcdt[i] & 31]++;\n var _e = hTree(lcfreq, 7), lct = _e[0], mlcb = _e[1];\n var nlcc = 19;\n for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)\n ;\n var flen = (bl + 5) << 3;\n var ftlen = clen(lf, flt) + clen(df, fdt) + eb;\n var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + (2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18]);\n if (flen <= ftlen && flen <= dtlen)\n return wfblk(out, p, dat.subarray(bs, bs + bl));\n var lm, ll, dm, dl;\n wbits(out, p, 1 + (dtlen < ftlen)), p += 2;\n if (dtlen < ftlen) {\n lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;\n var llm = hMap(lct, mlcb, 0);\n wbits(out, p, nlc - 257);\n wbits(out, p + 5, ndc - 1);\n wbits(out, p + 10, nlcc - 4);\n p += 14;\n for (var i = 0; i < nlcc; ++i)\n wbits(out, p + 3 * i, lct[clim[i]]);\n p += 3 * nlcc;\n var lcts = [lclt, lcdt];\n for (var it = 0; it < 2; ++it) {\n var clct = lcts[it];\n for (var i = 0; i < clct.length; ++i) {\n var len = clct[i] & 31;\n wbits(out, p, llm[len]), p += lct[len];\n if (len > 15)\n wbits(out, p, (clct[i] >>> 5) & 127), p += clct[i] >>> 12;\n }\n }\n }\n else {\n lm = flm, ll = flt, dm = fdm, dl = fdt;\n }\n for (var i = 0; i < li; ++i) {\n if (syms[i] > 255) {\n var len = (syms[i] >>> 18) & 31;\n wbits16(out, p, lm[len + 257]), p += ll[len + 257];\n if (len > 7)\n wbits(out, p, (syms[i] >>> 23) & 31), p += fleb[len];\n var dst = syms[i] & 31;\n wbits16(out, p, dm[dst]), p += dl[dst];\n if (dst > 3)\n wbits16(out, p, (syms[i] >>> 5) & 8191), p += fdeb[dst];\n }\n else {\n wbits16(out, p, lm[syms[i]]), p += ll[syms[i]];\n }\n }\n wbits16(out, p, lm[256]);\n return p + ll[256];\n};\n// deflate options (nice << 13) | chain\nvar deo = /*#__PURE__*/ new u32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]);\n// empty\nvar et = /*#__PURE__*/ new u8(0);\n// compresses data into a raw DEFLATE buffer\nvar dflt = function (dat, lvl, plvl, pre, post, lst) {\n var s = dat.length;\n var o = new u8(pre + s + 5 * (1 + Math.floor(s / 7000)) + post);\n // writing to this writes to the output buffer\n var w = o.subarray(pre, o.length - post);\n var pos = 0;\n if (!lvl || s < 8) {\n for (var i = 0; i <= s; i += 65535) {\n // end\n var e = i + 65535;\n if (e < s) {\n // write full block\n pos = wfblk(w, pos, dat.subarray(i, e));\n }\n else {\n // write final block\n w[i] = lst;\n pos = wfblk(w, pos, dat.subarray(i, s));\n }\n }\n }\n else {\n var opt = deo[lvl - 1];\n var n = opt >>> 13, c = opt & 8191;\n var msk_1 = (1 << plvl) - 1;\n // prev 2-byte val map curr 2-byte val map\n var prev = new u16(32768), head = new u16(msk_1 + 1);\n var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;\n var hsh = function (i) { return (dat[i] ^ (dat[i + 1] << bs1_1) ^ (dat[i + 2] << bs2_1)) & msk_1; };\n // 24576 is an arbitrary number of maximum symbols per block\n // 424 buffer for last block\n var syms = new u32(25000);\n // length/literal freq distance freq\n var lf = new u16(288), df = new u16(32);\n // l/lcnt exbits index l/lind waitdx bitpos\n var lc_1 = 0, eb = 0, i = 0, li = 0, wi = 0, bs = 0;\n for (; i < s; ++i) {\n // hash value\n var hv = hsh(i);\n // index mod 32768\n var imod = i & 32767;\n // previous index with this value\n var pimod = head[hv];\n prev[imod] = pimod;\n head[hv] = imod;\n // We always should modify head and prev, but only add symbols if\n // this data is not yet processed (\"wait\" for wait index)\n if (wi <= i) {\n // bytes remaining\n var rem = s - i;\n if ((lc_1 > 7000 || li > 24576) && rem > 423) {\n pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);\n li = lc_1 = eb = 0, bs = i;\n for (var j = 0; j < 286; ++j)\n lf[j] = 0;\n for (var j = 0; j < 30; ++j)\n df[j] = 0;\n }\n // len dist chain\n var l = 2, d = 0, ch_1 = c, dif = (imod - pimod) & 32767;\n if (rem > 2 && hv == hsh(i - dif)) {\n var maxn = Math.min(n, rem) - 1;\n var maxd = Math.min(32767, i);\n // max possible length\n // not capped at dif because decompressors implement \"rolling\" index population\n var ml = Math.min(258, rem);\n while (dif <= maxd && --ch_1 && imod != pimod) {\n if (dat[i + l] == dat[i + l - dif]) {\n var nl = 0;\n for (; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl)\n ;\n if (nl > l) {\n l = nl, d = dif;\n // break out early when we reach \"nice\" (we are satisfied enough)\n if (nl > maxn)\n break;\n // now, find the rarest 2-byte sequence within this\n // length of literals and search for that instead.\n // Much faster than just using the start\n var mmd = Math.min(dif, nl - 2);\n var md = 0;\n for (var j = 0; j < mmd; ++j) {\n var ti = (i - dif + j + 32768) & 32767;\n var pti = prev[ti];\n var cd = (ti - pti + 32768) & 32767;\n if (cd > md)\n md = cd, pimod = ti;\n }\n }\n }\n // check the previous match\n imod = pimod, pimod = prev[imod];\n dif += (imod - pimod + 32768) & 32767;\n }\n }\n // d will be nonzero only when a match was found\n if (d) {\n // store both dist and len data in one Uint32\n // Make sure this is recognized as a len/dist with 28th bit (2^28)\n syms[li++] = 268435456 | (revfl[l] << 18) | revfd[d];\n var lin = revfl[l] & 31, din = revfd[d] & 31;\n eb += fleb[lin] + fdeb[din];\n ++lf[257 + lin];\n ++df[din];\n wi = i + l;\n ++lc_1;\n }\n else {\n syms[li++] = dat[i];\n ++lf[dat[i]];\n }\n }\n }\n pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos);\n // this is the easiest way to avoid needing to maintain state\n if (!lst)\n pos = wfblk(w, pos, et);\n }\n return slc(o, 0, pre + shft(pos) + post);\n};\n// CRC32 table\nvar crct = /*#__PURE__*/ (function () {\n var t = new u32(256);\n for (var i = 0; i < 256; ++i) {\n var c = i, k = 9;\n while (--k)\n c = ((c & 1) && 0xEDB88320) ^ (c >>> 1);\n t[i] = c;\n }\n return t;\n})();\n// CRC32\nvar crc = function () {\n var c = 0xFFFFFFFF;\n return {\n p: function (d) {\n // closures have awful performance\n var cr = c;\n for (var i = 0; i < d.length; ++i)\n cr = crct[(cr & 255) ^ d[i]] ^ (cr >>> 8);\n c = cr;\n },\n d: function () { return c ^ 0xFFFFFFFF; }\n };\n};\n// Alder32\nvar adler = function () {\n var a = 1, b = 0;\n return {\n p: function (d) {\n // closures have awful performance\n var n = a, m = b;\n var l = d.length;\n for (var i = 0; i != l;) {\n var e = Math.min(i + 5552, l);\n for (; i < e; ++i)\n n += d[i], m += n;\n n %= 65521, m %= 65521;\n }\n a = n, b = m;\n },\n d: function () { return ((a >>> 8) << 16 | (b & 255) << 8 | (b >>> 8)) + ((a & 255) << 23) * 2; }\n };\n};\n;\n// deflate with opts\nvar dopt = function (dat, opt, pre, post, st) {\n return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : (12 + opt.mem), pre, post, !st);\n};\n// Walmart object spread\nvar mrg = function (a, b) {\n var o = {};\n for (var k in a)\n o[k] = a[k];\n for (var k in b)\n o[k] = b[k];\n return o;\n};\n// worker clone\n// This is possibly the craziest part of the entire codebase, despite how simple it may seem.\n// The only parameter to this function is a closure that returns an array of variables outside of the function scope.\n// We're going to try to figure out the variable names used in the closure as strings because that is crucial for workerization.\n// We will return an object mapping of true variable name to value (basically, the current scope as a JS object).\n// The reason we can't just use the original variable names is minifiers mangling the toplevel scope.\n// This took me three weeks to figure out how to do.\nvar wcln = function (fn, fnStr, td) {\n var dt = fn();\n var st = fn.toString();\n var ks = st.slice(st.indexOf('[') + 1, st.lastIndexOf(']')).replace(/ /g, '').split(',');\n for (var i = 0; i < dt.length; ++i) {\n var v = dt[i], k = ks[i];\n if (typeof v == 'function') {\n fnStr += ';' + k + '=';\n var st_1 = v.toString();\n if (v.prototype) {\n // for global objects\n if (st_1.indexOf('[native code]') != -1) {\n var spInd = st_1.indexOf(' ', 8) + 1;\n fnStr += st_1.slice(spInd, st_1.indexOf('(', spInd));\n }\n else {\n fnStr += st_1;\n for (var t in v.prototype)\n fnStr += ';' + k + '.prototype.' + t + '=' + v.prototype[t].toString();\n }\n }\n else\n fnStr += st_1;\n }\n else\n td[k] = v;\n }\n return [fnStr, td];\n};\nvar ch = [];\n// clone bufs\nvar cbfs = function (v) {\n var tl = [];\n for (var k in v) {\n if (v[k] instanceof u8 || v[k] instanceof u16 || v[k] instanceof u32)\n tl.push((v[k] = new v[k].constructor(v[k])).buffer);\n }\n return tl;\n};\n// use a worker to execute code\nvar wrkr = function (fns, init, id, cb) {\n var _a;\n if (!ch[id]) {\n var fnStr = '', td_1 = {}, m = fns.length - 1;\n for (var i = 0; i < m; ++i)\n _a = wcln(fns[i], fnStr, td_1), fnStr = _a[0], td_1 = _a[1];\n ch[id] = wcln(fns[m], fnStr, td_1);\n }\n var td = mrg({}, ch[id][1]);\n return wk(ch[id][0] + ';onmessage=function(e){for(var k in e.data)self[k]=e.data[k];onmessage=' + init.toString() + '}', id, td, cbfs(td), cb);\n};\n// base async inflate fn\nvar bInflt = function () { return [u8, u16, u32, fleb, fdeb, clim, fl, fd, flrm, fdrm, rev, hMap, max, bits, bits16, shft, slc, inflt, inflateSync, pbf, gu8]; };\nvar bDflt = function () { return [u8, u16, u32, fleb, fdeb, clim, revfl, revfd, flm, flt, fdm, fdt, rev, deo, et, hMap, wbits, wbits16, hTree, ln, lc, clen, wfblk, wblk, shft, slc, dflt, dopt, deflateSync, pbf]; };\n// gzip extra\nvar gze = function () { return [gzh, gzhl, wbytes, crc, crct]; };\n// gunzip extra\nvar guze = function () { return [gzs, gzl]; };\n// zlib extra\nvar zle = function () { return [zlh, wbytes, adler]; };\n// unzlib extra\nvar zule = function () { return [zlv]; };\n// post buf\nvar pbf = function (msg) { return postMessage(msg, [msg.buffer]); };\n// get u8\nvar gu8 = function (o) { return o && o.size && new u8(o.size); };\n// async helper\nvar cbify = function (dat, opts, fns, init, id, cb) {\n var w = wrkr(fns, init, id, function (err, dat) {\n w.terminate();\n cb(err, dat);\n });\n if (!opts.consume)\n dat = new u8(dat);\n w.postMessage([dat, opts], [dat.buffer]);\n return function () { w.terminate(); };\n};\n// auto stream\nvar astrm = function (strm) {\n strm.ondata = function (dat, final) { return postMessage([dat, final], [dat.buffer]); };\n return function (ev) { return strm.push(ev.data[0], ev.data[1]); };\n};\n// async stream attach\nvar astrmify = function (fns, strm, opts, init, id) {\n var t;\n var w = wrkr(fns, init, id, function (err, dat) {\n if (err)\n w.terminate(), strm.ondata.call(strm, err);\n else {\n if (dat[1])\n w.terminate();\n strm.ondata.call(strm, err, dat[0], dat[1]);\n }\n });\n w.postMessage(opts);\n strm.push = function (d, f) {\n if (t)\n throw 'stream finished';\n if (!strm.ondata)\n throw 'no stream handler';\n w.postMessage([d, t = f], [d.buffer]);\n };\n strm.terminate = function () { w.terminate(); };\n};\n// read 2 bytes\nvar b2 = function (d, b) { return d[b] | (d[b + 1] << 8); };\n// read 4 bytes\nvar b4 = function (d, b) { return (d[b] | (d[b + 1] << 8) | (d[b + 2] << 16)) + (d[b + 3] << 23) * 2; };\n// write bytes\nvar wbytes = function (d, b, v) {\n for (; v; ++b)\n d[b] = v, v >>>= 8;\n};\n// gzip header\nvar gzh = function (c, o) {\n var fn = o.filename;\n c[0] = 31, c[1] = 139, c[2] = 8, c[8] = o.level < 2 ? 4 : o.level == 9 ? 2 : 0, c[9] = 3; // assume Unix\n if (o.mtime != 0)\n wbytes(c, 4, Math.floor(new Date(o.mtime || Date.now()) / 1000));\n if (fn) {\n c[3] = 8;\n for (var i = 0; i <= fn.length; ++i)\n c[i + 10] = fn.charCodeAt(i);\n }\n};\n// gzip footer: -8 to -4 = CRC, -4 to -0 is length\n// gzip start\nvar gzs = function (d) {\n if (d[0] != 31 || d[1] != 139 || d[2] != 8)\n throw 'invalid gzip data';\n var flg = d[3];\n var st = 10;\n if (flg & 4)\n st += d[10] | (d[11] << 8) + 2;\n for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++])\n ;\n return st + (flg & 2);\n};\n// gzip length\nvar gzl = function (d) {\n var l = d.length;\n return (d[l - 4] | d[l - 3] << 8 | d[l - 2] << 16) + (2 * (d[l - 1] << 23));\n};\n// gzip header length\nvar gzhl = function (o) { return 10 + ((o.filename && (o.filename.length + 1)) || 0); };\n// zlib header\nvar zlh = function (c, o) {\n var lv = o.level, fl = lv == 0 ? 0 : lv < 6 ? 1 : lv == 9 ? 3 : 2;\n c[0] = 120, c[1] = (fl << 6) | (fl ? (32 - 2 * fl) : 1);\n};\n// zlib valid\nvar zlv = function (d) {\n if ((d[0] & 15) != 8 || (d[0] >>> 4) > 7 || ((d[0] << 8 | d[1]) % 31))\n throw 'invalid zlib data';\n if (d[1] & 32)\n throw 'invalid zlib data: preset dictionaries not supported';\n};\nfunction AsyncCmpStrm(opts, cb) {\n if (!cb && typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n return opts;\n}\n// zlib footer: -4 to -0 is Adler32\n/**\n * Streaming DEFLATE compression\n */\nvar Deflate = /*#__PURE__*/ (function () {\n function Deflate(opts, cb) {\n if (!cb && typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n this.o = opts || {};\n }\n Deflate.prototype.p = function (c, f) {\n this.ondata(dopt(c, this.o, 0, 0, !f), f);\n };\n /**\n * Pushes a chunk to be deflated\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Deflate.prototype.push = function (chunk, final) {\n if (this.d)\n throw 'stream finished';\n if (!this.ondata)\n throw 'no stream handler';\n this.d = final;\n this.p(chunk, final || false);\n };\n return Deflate;\n}());\nexport { Deflate };\n/**\n * Asynchronous streaming DEFLATE compression\n */\nvar AsyncDeflate = /*#__PURE__*/ (function () {\n function AsyncDeflate(opts, cb) {\n astrmify([\n bDflt,\n function () { return [astrm, Deflate]; }\n ], this, AsyncCmpStrm.call(this, opts, cb), function (ev) {\n var strm = new Deflate(ev.data);\n onmessage = astrm(strm);\n }, 6);\n }\n return AsyncDeflate;\n}());\nexport { AsyncDeflate };\nexport function deflate(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return cbify(data, opts, [\n bDflt,\n ], function (ev) { return pbf(deflateSync(ev.data[0], ev.data[1])); }, 0, cb);\n}\n/**\n * Compresses data with DEFLATE without any wrapper\n * @param data The data to compress\n * @param opts The compression options\n * @returns The deflated version of the data\n */\nexport function deflateSync(data, opts) {\n if (opts === void 0) { opts = {}; }\n return dopt(data, opts, 0, 0);\n}\n/**\n * Streaming DEFLATE decompression\n */\nvar Inflate = /*#__PURE__*/ (function () {\n /**\n * Creates an inflation stream\n * @param cb The callback to call whenever data is inflated\n */\n function Inflate(cb) {\n this.s = {};\n this.p = new u8(0);\n this.ondata = cb;\n }\n Inflate.prototype.e = function (c) {\n if (this.d)\n throw 'stream finished';\n if (!this.ondata)\n throw 'no stream handler';\n var l = this.p.length;\n var n = new u8(l + c.length);\n n.set(this.p), n.set(c, l), this.p = n;\n };\n Inflate.prototype.c = function (final) {\n this.d = this.s.i = final || false;\n var bts = this.s.b;\n var dt = inflt(this.p, this.o, this.s);\n this.ondata(slc(dt, bts, this.s.b), this.d);\n this.o = slc(dt, this.s.b - 32768), this.s.b = this.o.length;\n this.p = slc(this.p, (this.s.p / 8) >> 0), this.s.p &= 7;\n };\n /**\n * Pushes a chunk to be inflated\n * @param chunk The chunk to push\n * @param final Whether this is the final chunk\n */\n Inflate.prototype.push = function (chunk, final) {\n this.e(chunk), this.c(final);\n };\n return Inflate;\n}());\nexport { Inflate };\n/**\n * Asynchronous streaming DEFLATE decompression\n */\nvar AsyncInflate = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous inflation stream\n * @param cb The callback to call whenever data is deflated\n */\n function AsyncInflate(cb) {\n this.ondata = cb;\n astrmify([\n bInflt,\n function () { return [astrm, Inflate]; }\n ], this, 0, function () {\n var strm = new Inflate();\n onmessage = astrm(strm);\n }, 7);\n }\n return AsyncInflate;\n}());\nexport { AsyncInflate };\nexport function inflate(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return cbify(data, opts, [\n bInflt\n ], function (ev) { return pbf(inflateSync(ev.data[0], gu8(ev.data[1]))); }, 1, cb);\n}\n/**\n * Expands DEFLATE data with no wrapper\n * @param data The data to decompress\n * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.\n * @returns The decompressed version of the data\n */\nexport function inflateSync(data, out) {\n return inflt(data, out);\n}\n// before you yell at me for not just using extends, my reason is that TS inheritance is hard to workerize.\n/**\n * Streaming GZIP compression\n */\nvar Gzip = /*#__PURE__*/ (function () {\n function Gzip(opts, cb) {\n this.c = crc();\n this.l = 0;\n this.v = 1;\n Deflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be GZIPped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Gzip.prototype.push = function (chunk, final) {\n Deflate.prototype.push.call(this, chunk, final);\n };\n Gzip.prototype.p = function (c, f) {\n this.c.p(c);\n this.l += c.length;\n var raw = dopt(c, this.o, this.v && gzhl(this.o), f && 8, !f);\n if (this.v)\n gzh(raw, this.o), this.v = 0;\n if (f)\n wbytes(raw, raw.length - 8, this.c.d()), wbytes(raw, raw.length - 4, this.l);\n this.ondata(raw, f);\n };\n return Gzip;\n}());\nexport { Gzip };\n/**\n * Asynchronous streaming GZIP compression\n */\nvar AsyncGzip = /*#__PURE__*/ (function () {\n function AsyncGzip(opts, cb) {\n astrmify([\n bDflt,\n gze,\n function () { return [astrm, Deflate, Gzip]; }\n ], this, AsyncCmpStrm.call(this, opts, cb), function (ev) {\n var strm = new Gzip(ev.data);\n onmessage = astrm(strm);\n }, 8);\n }\n return AsyncGzip;\n}());\nexport { AsyncGzip };\nexport function gzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return cbify(data, opts, [\n bDflt,\n gze,\n function () { return [gzipSync]; }\n ], function (ev) { return pbf(gzipSync(ev.data[0], ev.data[1])); }, 2, cb);\n}\n/**\n * Compresses data with GZIP\n * @param data The data to compress\n * @param opts The compression options\n * @returns The gzipped version of the data\n */\nexport function gzipSync(data, opts) {\n if (opts === void 0) { opts = {}; }\n var c = crc(), l = data.length;\n c.p(data);\n var d = dopt(data, opts, gzhl(opts), 8), s = d.length;\n return gzh(d, opts), wbytes(d, s - 8, c.d()), wbytes(d, s - 4, l), d;\n}\n/**\n * Streaming GZIP decompression\n */\nvar Gunzip = /*#__PURE__*/ (function () {\n /**\n * Creates a GUNZIP stream\n * @param cb The callback to call whenever data is inflated\n */\n function Gunzip(cb) {\n this.v = 1;\n Inflate.call(this, cb);\n }\n /**\n * Pushes a chunk to be GUNZIPped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Gunzip.prototype.push = function (chunk, final) {\n Inflate.prototype.e.call(this, chunk);\n if (this.v) {\n var s = gzs(this.p);\n if (s >= this.p.length && !final)\n return;\n this.p = this.p.subarray(s), this.v = 0;\n }\n if (final) {\n if (this.p.length < 8)\n throw 'invalid gzip stream';\n this.p = this.p.subarray(0, -8);\n }\n // necessary to prevent TS from using the closure value\n // This allows for workerization to function correctly\n Inflate.prototype.c.call(this, final);\n };\n return Gunzip;\n}());\nexport { Gunzip };\n/**\n * Asynchronous streaming GZIP decompression\n */\nvar AsyncGunzip = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous GUNZIP stream\n * @param cb The callback to call whenever data is deflated\n */\n function AsyncGunzip(cb) {\n this.ondata = cb;\n astrmify([\n bInflt,\n guze,\n function () { return [astrm, Inflate, Gunzip]; }\n ], this, 0, function () {\n var strm = new Gunzip();\n onmessage = astrm(strm);\n }, 9);\n }\n return AsyncGunzip;\n}());\nexport { AsyncGunzip };\nexport function gunzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return cbify(data, opts, [\n bInflt,\n guze,\n function () { return [gunzipSync]; }\n ], function (ev) { return pbf(gunzipSync(ev.data[0])); }, 3, cb);\n}\n/**\n * Expands GZIP data\n * @param data The data to decompress\n * @param out Where to write the data. GZIP already encodes the output size, so providing this doesn't save memory.\n * @returns The decompressed version of the data\n */\nexport function gunzipSync(data, out) {\n return inflt(data.subarray(gzs(data), -8), out || new u8(gzl(data)));\n}\n/**\n * Streaming Zlib compression\n */\nvar Zlib = /*#__PURE__*/ (function () {\n function Zlib(opts, cb) {\n this.c = adler();\n this.v = 1;\n Deflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be zlibbed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Zlib.prototype.push = function (chunk, final) {\n Deflate.prototype.push.call(this, chunk, final);\n };\n Zlib.prototype.p = function (c, f) {\n this.c.p(c);\n var raw = dopt(c, this.o, this.v && 2, f && 4, !f);\n if (this.v)\n zlh(raw, this.o), this.v = 0;\n if (f)\n wbytes(raw, raw.length - 4, this.c.d());\n this.ondata(raw, f);\n };\n return Zlib;\n}());\nexport { Zlib };\n/**\n * Asynchronous streaming Zlib compression\n */\nvar AsyncZlib = /*#__PURE__*/ (function () {\n function AsyncZlib(opts, cb) {\n astrmify([\n bDflt,\n zle,\n function () { return [astrm, Deflate, Zlib]; }\n ], this, AsyncCmpStrm.call(this, opts, cb), function (ev) {\n var strm = new Zlib(ev.data);\n onmessage = astrm(strm);\n }, 10);\n }\n return AsyncZlib;\n}());\nexport { AsyncZlib };\nexport function zlib(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return cbify(data, opts, [\n bDflt,\n zle,\n function () { return [zlibSync]; }\n ], function (ev) { return pbf(zlibSync(ev.data[0], ev.data[1])); }, 4, cb);\n}\n/**\n * Compress data with Zlib\n * @param data The data to compress\n * @param opts The compression options\n * @returns The zlib-compressed version of the data\n */\nexport function zlibSync(data, opts) {\n if (opts === void 0) { opts = {}; }\n var a = adler();\n a.p(data);\n var d = dopt(data, opts, 2, 4);\n return zlh(d, opts), wbytes(d, d.length - 4, a.d()), d;\n}\n/**\n * Streaming Zlib decompression\n */\nvar Unzlib = /*#__PURE__*/ (function () {\n /**\n * Creates a Zlib decompression stream\n * @param cb The callback to call whenever data is inflated\n */\n function Unzlib(cb) {\n this.v = 1;\n Inflate.call(this, cb);\n }\n /**\n * Pushes a chunk to be unzlibbed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Unzlib.prototype.push = function (chunk, final) {\n Inflate.prototype.e.call(this, chunk);\n if (this.v) {\n if (this.p.length < 2 && !final)\n return;\n this.p = this.p.subarray(2), this.v = 0;\n }\n if (final) {\n if (this.p.length < 4)\n throw 'invalid zlib stream';\n this.p = this.p.subarray(0, -4);\n }\n // necessary to prevent TS from using the closure value\n // This allows for workerization to function correctly\n Inflate.prototype.c.call(this, final);\n };\n return Unzlib;\n}());\nexport { Unzlib };\n/**\n * Asynchronous streaming Zlib decompression\n */\nvar AsyncUnzlib = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous Zlib decompression stream\n * @param cb The callback to call whenever data is deflated\n */\n function AsyncUnzlib(cb) {\n this.ondata = cb;\n astrmify([\n bInflt,\n zule,\n function () { return [astrm, Inflate, Unzlib]; }\n ], this, 0, function () {\n var strm = new Unzlib();\n onmessage = astrm(strm);\n }, 11);\n }\n return AsyncUnzlib;\n}());\nexport { AsyncUnzlib };\nexport function unzlib(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return cbify(data, opts, [\n bInflt,\n zule,\n function () { return [unzlibSync]; }\n ], function (ev) { return pbf(unzlibSync(ev.data[0], gu8(ev.data[1]))); }, 5, cb);\n}\n/**\n * Expands Zlib data\n * @param data The data to decompress\n * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.\n * @returns The decompressed version of the data\n */\nexport function unzlibSync(data, out) {\n return inflt((zlv(data), data.subarray(2, -4)), out);\n}\n// Default algorithm for compression (used because having a known output size allows faster decompression)\nexport { gzip as compress, AsyncGzip as AsyncCompress };\n// Default algorithm for compression (used because having a known output size allows faster decompression)\nexport { gzipSync as compressSync, Gzip as Compress };\n/**\n * Streaming GZIP, Zlib, or raw DEFLATE decompression\n */\nvar Decompress = /*#__PURE__*/ (function () {\n /**\n * Creates a decompression stream\n * @param cb The callback to call whenever data is decompressed\n */\n function Decompress(cb) {\n this.G = Gunzip;\n this.I = Inflate;\n this.Z = Unzlib;\n this.ondata = cb;\n }\n /**\n * Pushes a chunk to be decompressed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Decompress.prototype.push = function (chunk, final) {\n if (!this.ondata)\n throw 'no stream handler';\n if (!this.s) {\n if (this.p && this.p.length) {\n var n = new u8(this.p.length + chunk.length);\n n.set(this.p), n.set(chunk, this.p.length);\n }\n else\n this.p = chunk;\n if (this.p.length > 2) {\n var _this_1 = this;\n var cb = function () { _this_1.ondata.apply(_this_1, arguments); };\n this.s = (this.p[0] == 31 && this.p[1] == 139 && this.p[2] == 8)\n ? new this.G(cb)\n : ((this.p[0] & 15) != 8 || (this.p[0] >> 4) > 7 || ((this.p[0] << 8 | this.p[1]) % 31))\n ? new this.I(cb)\n : new this.Z(cb);\n this.s.push(this.p, final);\n this.p = null;\n }\n }\n else\n this.s.push(chunk, final);\n };\n return Decompress;\n}());\nexport { Decompress };\n/**\n * Asynchronous streaming GZIP, Zlib, or raw DEFLATE decompression\n */\nvar AsyncDecompress = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous decompression stream\n * @param cb The callback to call whenever data is decompressed\n */\n function AsyncDecompress(cb) {\n this.G = AsyncGunzip;\n this.I = AsyncInflate;\n this.Z = AsyncUnzlib;\n this.ondata = cb;\n }\n /**\n * Pushes a chunk to be decompressed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n AsyncDecompress.prototype.push = function (chunk, final) {\n Decompress.prototype.push.call(this, chunk, final);\n };\n return AsyncDecompress;\n}());\nexport { AsyncDecompress };\nexport function decompress(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return (data[0] == 31 && data[1] == 139 && data[2] == 8)\n ? gunzip(data, opts, cb)\n : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31))\n ? inflate(data, opts, cb)\n : unzlib(data, opts, cb);\n}\n/**\n * Expands compressed GZIP, Zlib, or raw DEFLATE data, automatically detecting the format\n * @param data The data to decompress\n * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.\n * @returns The decompressed version of the data\n */\nexport function decompressSync(data, out) {\n return (data[0] == 31 && data[1] == 139 && data[2] == 8)\n ? gunzipSync(data, out)\n : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31))\n ? inflateSync(data, out)\n : unzlibSync(data, out);\n}\n// flatten a directory structure\nvar fltn = function (d, p, t, o) {\n for (var k in d) {\n var val = d[k], n = p + k;\n if (val instanceof u8)\n t[n] = [val, o];\n else if (Array.isArray(val))\n t[n] = [val[0], mrg(o, val[1])];\n else\n fltn(val, n + '/', t, o);\n }\n};\n/**\n * Converts a string into a Uint8Array for use with compression/decompression methods\n * @param str The string to encode\n * @param latin1 Whether or not to interpret the data as Latin-1. This should\n * not need to be true unless decoding a binary string.\n * @returns The string encoded in UTF-8/Latin-1 binary\n */\nexport function strToU8(str, latin1) {\n var l = str.length;\n if (!latin1 && typeof TextEncoder != 'undefined')\n return new TextEncoder().encode(str);\n var ar = new u8(str.length + (str.length >>> 1));\n var ai = 0;\n var w = function (v) { ar[ai++] = v; };\n for (var i = 0; i < l; ++i) {\n if (ai + 5 > ar.length) {\n var n = new u8(ai + 8 + ((l - i) << 1));\n n.set(ar);\n ar = n;\n }\n var c = str.charCodeAt(i);\n if (c < 128 || latin1)\n w(c);\n else if (c < 2048)\n w(192 | (c >>> 6)), w(128 | (c & 63));\n else if (c > 55295 && c < 57344)\n c = 65536 + (c & 1023 << 10) | (str.charCodeAt(++i) & 1023),\n w(240 | (c >>> 18)), w(128 | ((c >>> 12) & 63)), w(128 | ((c >>> 6) & 63)), w(128 | (c & 63));\n else\n w(224 | (c >>> 12)), w(128 | ((c >>> 6) & 63)), w(128 | (c & 63));\n }\n return slc(ar, 0, ai);\n}\n/**\n * Converts a Uint8Array to a string\n * @param dat The data to decode to string\n * @param latin1 Whether or not to interpret the data as Latin-1. This should\n * not need to be true unless encoding to binary string.\n * @returns The original UTF-8/Latin-1 string\n */\nexport function strFromU8(dat, latin1) {\n var r = '';\n if (!latin1 && typeof TextDecoder != 'undefined')\n return new TextDecoder().decode(dat);\n for (var i = 0; i < dat.length;) {\n var c = dat[i++];\n if (c < 128 || latin1)\n r += String.fromCharCode(c);\n else if (c < 224)\n r += String.fromCharCode((c & 31) << 6 | (dat[i++] & 63));\n else if (c < 240)\n r += String.fromCharCode((c & 15) << 12 | (dat[i++] & 63) << 6 | (dat[i++] & 63));\n else\n c = ((c & 15) << 18 | (dat[i++] & 63) << 12 | (dat[i++] & 63) << 6 | (dat[i++] & 63)) - 65536,\n r += String.fromCharCode(55296 | (c >> 10), 56320 | (c & 1023));\n }\n return r;\n}\n;\n// skip local zip header\nvar slzh = function (d, b) { return b + 30 + b2(d, b + 26) + b2(d, b + 28); };\n// read zip header\nvar zh = function (d, b, z) {\n var fnl = b2(d, b + 28), fn = strFromU8(d.subarray(b + 46, b + 46 + fnl), !(b2(d, b + 8) & 2048)), es = b + 46 + fnl;\n var _a = z ? z64e(d, es) : [b4(d, b + 20), b4(d, b + 24), b4(d, b + 42)], sc = _a[0], su = _a[1], off = _a[2];\n return [b2(d, b + 10), sc, su, fn, es + b2(d, b + 30) + b2(d, b + 32), off];\n};\n// read zip64 extra field\nvar z64e = function (d, b) {\n for (; b2(d, b) != 1; b += 4 + b2(d, b + 2))\n ;\n return [b4(d, b + 12), b4(d, b + 4), b4(d, b + 20)];\n};\n// write zip header\nvar wzh = function (d, b, c, cmp, su, fn, u, o, ce, t) {\n var fl = fn.length, l = cmp.length;\n wbytes(d, b, ce != null ? 0x2014B50 : 0x4034B50), b += 4;\n if (ce != null)\n d[b] = 20, b += 2;\n d[b] = 20, b += 2; // spec compliance? what's that?\n d[b++] = (t == 8 && (o.level == 1 ? 6 : o.level < 6 ? 4 : o.level == 9 ? 2 : 0)), d[b++] = u && 8;\n d[b] = t, b += 2;\n var dt = new Date(o.mtime || Date.now()), y = dt.getFullYear() - 1980;\n if (y < 0 || y > 119)\n throw 'date not in range 1980-2099';\n wbytes(d, b, ((y << 24) * 2) | ((dt.getMonth() + 1) << 21) | (dt.getDate() << 16) | (dt.getHours() << 11) | (dt.getMinutes() << 5) | (dt.getSeconds() >>> 1));\n b += 4;\n wbytes(d, b, c);\n wbytes(d, b + 4, l);\n wbytes(d, b + 8, su);\n wbytes(d, b + 12, fl), b += 16; // skip extra field, comment\n if (ce != null)\n wbytes(d, b += 10, ce), b += 4;\n d.set(fn, b);\n b += fl;\n if (ce == null)\n d.set(cmp, b);\n};\n// write zip footer (end of central directory)\nvar wzf = function (o, b, c, d, e) {\n wbytes(o, b, 0x6054B50); // skip disk\n wbytes(o, b + 8, c);\n wbytes(o, b + 10, c);\n wbytes(o, b + 12, d);\n wbytes(o, b + 16, e);\n};\nexport function zip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n var r = {};\n fltn(data, '', r, opts);\n var k = Object.keys(r);\n var lft = k.length, o = 0, tot = 0;\n var slft = lft, files = new Array(lft);\n var term = [];\n var tAll = function () {\n for (var i = 0; i < term.length; ++i)\n term[i]();\n };\n var cbf = function () {\n var out = new u8(tot + 22), oe = o, cdl = tot - o;\n tot = 0;\n for (var i = 0; i < slft; ++i) {\n var f = files[i];\n try {\n wzh(out, tot, f.c, f.d, f.m, f.n, f.u, f.p, null, f.t);\n wzh(out, o, f.c, f.d, f.m, f.n, f.u, f.p, tot, f.t), o += 46 + f.n.length, tot += 30 + f.n.length + f.d.length;\n }\n catch (e) {\n return cb(e, null);\n }\n }\n wzf(out, o, files.length, cdl, oe);\n cb(null, out);\n };\n if (!lft)\n cbf();\n var _loop_1 = function (i) {\n var fn = k[i];\n var _a = r[fn], file = _a[0], p = _a[1];\n var c = crc(), m = file.length;\n c.p(file);\n var n = strToU8(fn), s = n.length;\n var t = p.level == 0 ? 0 : 8;\n var cbl = function (e, d) {\n if (e) {\n tAll();\n cb(e, null);\n }\n else {\n var l = d.length;\n files[i] = {\n t: t,\n d: d,\n m: m,\n c: c.d(),\n u: fn.length != l,\n n: n,\n p: p\n };\n o += 30 + s + l;\n tot += 76 + 2 * s + l;\n if (!--lft)\n cbf();\n }\n };\n if (n.length > 65535)\n cbl('filename too long', null);\n if (!t)\n cbl(null, file);\n else if (m < 160000) {\n try {\n cbl(null, deflateSync(file, p));\n }\n catch (e) {\n cbl(e, null);\n }\n }\n else\n term.push(deflate(file, p, cbl));\n };\n // Cannot use lft because it can decrease\n for (var i = 0; i < slft; ++i) {\n _loop_1(i);\n }\n return tAll;\n}\n/**\n * Synchronously creates a ZIP file. Prefer using `zip` for better performance\n * with more than one file.\n * @param data The directory structure for the ZIP archive\n * @param opts The main options, merged with per-file options\n * @returns The generated ZIP archive\n */\nexport function zipSync(data, opts) {\n if (opts === void 0) { opts = {}; }\n var r = {};\n var files = [];\n fltn(data, '', r, opts);\n var o = 0;\n var tot = 0;\n for (var fn in r) {\n var _a = r[fn], file = _a[0], p = _a[1];\n var t = p.level == 0 ? 0 : 8;\n var n = strToU8(fn), s = n.length;\n if (n.length > 65535)\n throw 'filename too long';\n var d = t ? deflateSync(file, p) : file, l = d.length;\n var c = crc();\n c.p(file);\n files.push({\n t: t,\n d: d,\n m: file.length,\n c: c.d(),\n u: fn.length != s,\n n: n,\n o: o,\n p: p\n });\n o += 30 + s + l;\n tot += 76 + 2 * s + l;\n }\n var out = new u8(tot + 22), oe = o, cdl = tot - o;\n for (var i = 0; i < files.length; ++i) {\n var f = files[i];\n wzh(out, f.o, f.c, f.d, f.m, f.n, f.u, f.p, null, f.t);\n wzh(out, o, f.c, f.d, f.m, f.n, f.u, f.p, f.o, f.t), o += 46 + f.n.length;\n }\n wzf(out, o, files.length, cdl, oe);\n return out;\n}\n/**\n * Asynchronously decompresses a ZIP archive\n * @param data The raw compressed ZIP file\n * @param cb The callback to call with the decompressed files\n * @returns A function that can be used to immediately terminate the unzipping\n */\nexport function unzip(data, cb) {\n if (typeof cb != 'function')\n throw 'no callback';\n var term = [];\n var tAll = function () {\n for (var i = 0; i < term.length; ++i)\n term[i]();\n };\n var files = {};\n var e = data.length - 22;\n for (; b4(data, e) != 0x6054B50; --e) {\n if (!e || data.length - e > 65558) {\n cb('invalid zip file', null);\n return;\n }\n }\n ;\n var lft = b2(data, e + 8);\n if (!lft)\n cb(null, {});\n var c = lft;\n var o = b4(data, e + 16);\n var z = o == 4294967295;\n if (z) {\n e = b4(data, e - 12);\n if (b4(data, e) != 0x6064B50)\n throw 'invalid zip file';\n c = lft = b4(data, e + 32);\n o = b4(data, e + 48);\n }\n var _loop_2 = function (i) {\n var _a = zh(data, o, z), c_1 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off);\n o = no;\n var cbl = function (e, d) {\n if (e) {\n tAll();\n cb(e, null);\n }\n else {\n files[fn] = d;\n if (!--lft)\n cb(null, files);\n }\n };\n if (!c_1)\n cbl(null, slc(data, b, b + sc));\n else if (c_1 == 8) {\n var infl = data.subarray(b, b + sc);\n if (sc < 320000) {\n try {\n cbl(null, inflateSync(infl, new u8(su)));\n }\n catch (e) {\n cbl(e, null);\n }\n }\n else\n term.push(inflate(infl, { size: su }, cbl));\n }\n else\n cbl('unknown compression type ' + c_1, null);\n };\n for (var i = 0; i < c; ++i) {\n _loop_2(i);\n }\n return tAll;\n}\n/**\n * Synchronously decompresses a ZIP archive. Prefer using `unzip` for better\n * performance with more than one file.\n * @param data The raw compressed ZIP file\n * @returns The decompressed files\n */\nexport function unzipSync(data) {\n var files = {};\n var e = data.length - 22;\n for (; b4(data, e) != 0x6054B50; --e) {\n if (!e || data.length - e > 65558)\n throw 'invalid zip file';\n }\n ;\n var c = b2(data, e + 8);\n if (!c)\n return {};\n var o = b4(data, e + 16);\n var z = o == 4294967295;\n if (z) {\n e = b4(data, e - 12);\n if (b4(data, e) != 0x6064B50)\n throw 'invalid zip file';\n c = b4(data, e + 32);\n o = b4(data, e + 48);\n }\n for (var i = 0; i < c; ++i) {\n var _a = zh(data, o, z), c_2 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off);\n o = no;\n if (!c_2)\n files[fn] = slc(data, b, b + sc);\n else if (c_2 == 8)\n files[fn] = inflateSync(data.subarray(b, b + sc), new u8(su));\n else\n throw 'unknown compression type ' + c_2;\n }\n return files;\n}\n","import { isNull } from '@posthog/core'\n\nexport function _base64Encode(data: null): null\nexport function _base64Encode(data: undefined): undefined\nexport function _base64Encode(data: string): string\nexport function _base64Encode(data: string | null | undefined): string | null | undefined {\n const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='\n let o1,\n o2,\n o3,\n h1,\n h2,\n h3,\n h4,\n bits,\n i = 0,\n ac = 0,\n enc = ''\n const tmp_arr: string[] = []\n\n if (!data) {\n return data\n }\n\n data = utf8Encode(data)\n\n do {\n // pack three octets into four hexets\n o1 = data.charCodeAt(i++)\n o2 = data.charCodeAt(i++)\n o3 = data.charCodeAt(i++)\n\n bits = (o1 << 16) | (o2 << 8) | o3\n\n h1 = (bits >> 18) & 0x3f\n h2 = (bits >> 12) & 0x3f\n h3 = (bits >> 6) & 0x3f\n h4 = bits & 0x3f\n\n // use hexets to index into b64, and append result to encoded string\n tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4)\n } while (i < data.length)\n\n enc = tmp_arr.join('')\n\n switch (data.length % 3) {\n case 1:\n enc = enc.slice(0, -2) + '=='\n break\n case 2:\n enc = enc.slice(0, -1) + '='\n break\n }\n\n return enc\n}\n\nexport const utf8Encode = function (string: string): string {\n string = (string + '').replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n')\n\n let utftext = '',\n start,\n end\n let stringl = 0,\n n\n\n start = end = 0\n stringl = string.length\n\n for (n = 0; n < stringl; n++) {\n const c1 = string.charCodeAt(n)\n let enc = null\n\n if (c1 < 128) {\n end++\n } else if (c1 > 127 && c1 < 2048) {\n enc = String.fromCharCode((c1 >> 6) | 192, (c1 & 63) | 128)\n } else {\n enc = String.fromCharCode((c1 >> 12) | 224, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128)\n }\n if (!isNull(enc)) {\n if (end > start) {\n utftext += string.substring(start, end)\n }\n utftext += enc\n start = end = n + 1\n }\n }\n\n if (end > start) {\n utftext += string.substring(start, string.length)\n }\n\n return utftext\n}\n","import { each, find } from './utils'\nimport Config from './config'\nimport { Compression, RequestWithOptions, RequestResponse } from './types'\nimport { formDataToQuery } from './utils/request-utils'\n\nimport { logger } from './utils/logger'\nimport { AbortController, fetch, navigator, XMLHttpRequest } from './utils/globals'\nimport { gzipSync, strToU8 } from 'fflate'\n\nimport { _base64Encode } from './utils/encode-utils'\n\n// eslint-disable-next-line compat/compat\nexport const SUPPORTS_REQUEST = !!XMLHttpRequest || !!fetch\n\nconst CONTENT_TYPE_PLAIN = 'text/plain'\nconst CONTENT_TYPE_JSON = 'application/json'\nconst CONTENT_TYPE_FORM = 'application/x-www-form-urlencoded'\nconst SIXTY_FOUR_KILOBYTES = 64 * 1024\n/*\n fetch will fail if we request keepalive with a body greater than 64kb\n sets the threshold lower than that so that\n any overhead doesn't push over the threshold after checking here\n*/\nconst KEEP_ALIVE_THRESHOLD = SIXTY_FOUR_KILOBYTES * 0.8\ntype EncodedBody = {\n contentType: string\n body: string | BlobPart\n estimatedSize: number\n}\n\n/**\n * Extends a URL with additional query parameters\n * @param url - The URL to extend\n * @param params - The parameters to add\n * @param replace - When true (default), new params overwrite existing ones with same key. When false, existing params are preserved.\n * @returns The URL with extended parameters\n */\nexport const extendURLParams = (url: string, params: Record<string, any>, replace: boolean = true): string => {\n const [baseUrl, search] = url.split('?')\n const newParams = { ...params }\n\n const updatedSearch =\n search?.split('&').map((pair) => {\n const [key, origValue] = pair.split('=')\n const value = replace ? (newParams[key] ?? origValue) : origValue\n delete newParams[key]\n return `${key}=${value}`\n }) ?? []\n\n const remaining = formDataToQuery(newParams)\n if (remaining) {\n updatedSearch.push(remaining)\n }\n\n return `${baseUrl}?${updatedSearch.join('&')}`\n}\n\nexport const jsonStringify = (data: any, space?: string | number): string => {\n // With plain JSON.stringify, we get an exception when a property is a BigInt. This has caused problems for some users,\n // see https://github.com/PostHog/posthog-js/issues/1440\n // To work around this, we convert BigInts to strings before stringifying the data. This is not ideal, as we lose\n // information that this was originally a number, but given ClickHouse doesn't support BigInts, the customer\n // would not be able to operate on these numerically anyway.\n return JSON.stringify(data, (_, value) => (typeof value === 'bigint' ? value.toString() : value), space)\n}\n\nconst encodeToDataString = (data: string | Record<string, any>): string => {\n return 'data=' + encodeURIComponent(typeof data === 'string' ? data : jsonStringify(data))\n}\n\nconst encodePostData = ({ data, compression }: RequestWithOptions): EncodedBody | undefined => {\n if (!data) {\n return\n }\n\n if (compression === Compression.GZipJS) {\n const gzipData = gzipSync(strToU8(jsonStringify(data)), { mtime: 0 })\n const blob = new Blob([gzipData], { type: CONTENT_TYPE_PLAIN })\n return {\n contentType: CONTENT_TYPE_PLAIN,\n body: blob,\n estimatedSize: blob.size,\n }\n }\n\n if (compression === Compression.Base64) {\n const b64data = _base64Encode(jsonStringify(data))\n const encodedBody = encodeToDataString(b64data)\n\n return {\n contentType: CONTENT_TYPE_FORM,\n body: encodedBody,\n estimatedSize: new Blob([encodedBody]).size,\n }\n }\n\n const jsonBody = jsonStringify(data)\n return {\n contentType: CONTENT_TYPE_JSON,\n body: jsonBody,\n estimatedSize: new Blob([jsonBody]).size,\n }\n}\n\nconst xhr = (options: RequestWithOptions) => {\n const req = new XMLHttpRequest!()\n req.open(options.method || 'GET', options.url, true)\n const { contentType, body } = encodePostData(options) ?? {}\n\n each(options.headers, function (headerValue, headerName) {\n req.setRequestHeader(headerName, headerValue)\n })\n\n if (contentType) {\n req.setRequestHeader('Content-Type', contentType)\n }\n\n if (options.timeout) {\n req.timeout = options.timeout\n }\n if (!options.disableXHRCredentials) {\n // send the ph_optout cookie\n // withCredentials cannot be modified until after calling .open on Android and Mobile Safari\n req.withCredentials = true\n }\n req.onreadystatechange = () => {\n // XMLHttpRequest.DONE == 4, except in safari 4\n if (req.readyState === 4) {\n const response: RequestResponse = {\n statusCode: req.status,\n text: req.responseText,\n }\n if (req.status === 200) {\n try {\n response.json = JSON.parse(req.responseText)\n } catch {\n // logger.error(e)\n }\n }\n\n options.callback?.(response)\n }\n }\n req.send(body)\n}\n\nconst _fetch = (options: RequestWithOptions) => {\n const { contentType, body, estimatedSize } = encodePostData(options) ?? {}\n\n // eslint-disable-next-line compat/compat\n const headers = new Headers()\n each(options.headers, function (headerValue, headerName) {\n headers.append(headerName, headerValue)\n })\n\n if (contentType) {\n headers.append('Content-Type', contentType)\n }\n\n const url = options.url\n let aborter: { signal: any; timeout: ReturnType<typeof setTimeout> } | null = null\n\n if (AbortController) {\n const controller = new AbortController()\n aborter = {\n signal: controller.signal,\n timeout: setTimeout(() => controller.abort(), options.timeout),\n }\n }\n\n fetch!(url, {\n method: options?.method || 'GET',\n headers,\n // if body is greater than 64kb, then fetch with keepalive will error\n // see 8:10:5 at https://fetch.spec.whatwg.org/#http-network-or-cache-fetch,\n // but we do want to set keepalive sometimes as it can help with success\n // when e.g. a page is being closed\n // so let's get the best of both worlds and only set keepalive for POST requests\n // where the body is less than 64kb\n // NB this is fetch keepalive and not http keepalive\n keepalive: options.method === 'POST' && (estimatedSize || 0) < KEEP_ALIVE_THRESHOLD,\n body,\n signal: aborter?.signal,\n ...options.fetchOptions,\n })\n .then((response) => {\n return response.text().then((responseText) => {\n const res: RequestResponse = {\n statusCode: response.status,\n text: responseText,\n }\n\n if (response.status === 200) {\n try {\n res.json = JSON.parse(responseText)\n } catch (e) {\n logger.error(e)\n }\n }\n\n options.callback?.(res)\n })\n })\n .catch((error) => {\n logger.error(error)\n options.callback?.({ statusCode: 0, text: error })\n })\n .finally(() => (aborter ? clearTimeout(aborter.timeout) : null))\n\n return\n}\n\nconst _sendBeacon = (options: RequestWithOptions) => {\n // beacon documentation https://w3c.github.io/beacon/\n // beacons format the message and use the type property\n\n const url = extendURLParams(options.url, {\n beacon: '1',\n })\n\n try {\n const { contentType, body } = encodePostData(options) ?? {}\n // sendBeacon requires a blob so we convert it\n const sendBeaconBody = typeof body === 'string' ? new Blob([body], { type: contentType }) : body\n navigator!.sendBeacon!(url, sendBeaconBody)\n } catch {\n // send beacon is a best-effort, fire-and-forget mechanism on page unload,\n // we don't want to throw errors here\n }\n}\n\nconst AVAILABLE_TRANSPORTS: {\n transport: RequestWithOptions['transport']\n method: (options: RequestWithOptions) => void\n}[] = []\n\n// We add the transports in order of preference\nif (fetch) {\n AVAILABLE_TRANSPORTS.push({\n transport: 'fetch',\n method: _fetch,\n })\n}\n\nif (XMLHttpRequest) {\n AVAILABLE_TRANSPORTS.push({\n transport: 'XHR',\n method: xhr,\n })\n}\n\nif (navigator?.sendBeacon) {\n AVAILABLE_TRANSPORTS.push({\n transport: 'sendBeacon',\n method: _sendBeacon,\n })\n}\n\n// This is the entrypoint. It takes care of sanitizing the options and then calls the appropriate request method.\nexport const request = (_options: RequestWithOptions) => {\n // Clone the options so we don't modify the original object\n const options = { ..._options }\n options.timeout = options.timeout || 60000\n\n options.url = extendURLParams(options.url, {\n _: new Date().getTime().toString(),\n ver: Config.LIB_VERSION,\n compression: options.compression,\n })\n\n const transport = options.transport ?? 'fetch'\n\n const availableTransports = AVAILABLE_TRANSPORTS.filter(\n (t) => !options.disableTransport || !t.transport || !options.disableTransport.includes(t.transport)\n )\n\n const transportMethod =\n find(availableTransports, (t) => t.transport === transport)?.method ?? availableTransports[0].method\n\n if (!transportMethod) {\n throw new Error('No available transport method')\n }\n\n transportMethod(options)\n}\n","export const isValidRegex = function (str: string): boolean {\n try {\n new RegExp(str)\n } catch {\n return false\n }\n return true\n}\n\nexport const isMatchingRegex = function (value: string, pattern: string): boolean {\n if (!isValidRegex(pattern)) return false\n\n try {\n return new RegExp(pattern).test(value)\n } catch {\n return false\n }\n}\n","import { isNull, isUndefined } from '@posthog/core'\nimport { jsonStringify } from '../request'\nimport { PropertyFilters, PropertyOperator } from '../posthog-surveys-types'\nimport type { Properties } from '../types'\nimport { isMatchingRegex } from './regex-utils'\n\nexport function getPersonPropertiesHash(\n distinct_id: string,\n userPropertiesToSet?: Properties,\n userPropertiesToSetOnce?: Properties\n): string {\n return jsonStringify({ distinct_id, userPropertiesToSet, userPropertiesToSetOnce })\n}\n\nexport const propertyComparisons: Record<PropertyOperator, (targets: string[], values: string[]) => boolean> = {\n exact: (targets, values) => values.some((value) => targets.some((target) => value === target)),\n is_not: (targets, values) => values.every((value) => targets.every((target) => value !== target)),\n regex: (targets, values) => values.some((value) => targets.some((target) => isMatchingRegex(value, target))),\n not_regex: (targets, values) => values.every((value) => targets.every((target) => !isMatchingRegex(value, target))),\n icontains: (targets, values) =>\n values.map(toLowerCase).some((value) => targets.map(toLowerCase).some((target) => value.includes(target))),\n not_icontains: (targets, values) =>\n values.map(toLowerCase).every((value) => targets.map(toLowerCase).every((target) => !value.includes(target))),\n gt: (targets, values) =>\n values.some((value) => {\n const numValue = parseFloat(value)\n return !isNaN(numValue) && targets.some((t) => numValue > parseFloat(t))\n }),\n lt: (targets, values) =>\n values.some((value) => {\n const numValue = parseFloat(value)\n return !isNaN(numValue) && targets.some((t) => numValue < parseFloat(t))\n }),\n}\n\nconst toLowerCase = (v: string): string => v.toLowerCase()\n\nexport function matchPropertyFilters(\n propertyFilters: PropertyFilters | undefined,\n eventProperties: Properties | undefined\n): boolean {\n // if there are no property filters, it means we're only matching on event name\n if (!propertyFilters) {\n return true\n }\n\n return Object.entries(propertyFilters).every(([propertyName, filter]) => {\n const eventPropertyValue = eventProperties?.[propertyName]\n\n if (isUndefined(eventPropertyValue) || isNull(eventPropertyValue)) {\n return false\n }\n\n // convert event property to string array for comparison\n const eventValues = [String(eventPropertyValue)]\n\n const comparisonFunction = propertyComparisons[filter.operator]\n if (!comparisonFunction) {\n return false\n }\n\n return comparisonFunction(filter.values, eventValues)\n })\n}\n","import { ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS, ERROR_TRACKING_SUPPRESSION_RULES } from './constants'\nimport { PostHog } from './posthog-core'\nimport { CaptureResult, ErrorTrackingSuppressionRule, Properties, RemoteConfig } from './types'\nimport { createLogger } from './utils/logger'\nimport { propertyComparisons } from './utils/property-utils'\nimport { isString, isArray, ErrorTracking, isNullish } from '@posthog/core'\n\nconst logger = createLogger('[Error tracking]')\n\nexport function buildErrorPropertiesBuilder() {\n return new ErrorTracking.ErrorPropertiesBuilder(\n [\n new ErrorTracking.DOMExceptionCoercer(),\n new ErrorTracking.PromiseRejectionEventCoercer(),\n new ErrorTracking.ErrorEventCoercer(),\n new ErrorTracking.ErrorCoercer(),\n new ErrorTracking.EventCoercer(),\n new ErrorTracking.ObjectCoercer(),\n new ErrorTracking.StringCoercer(),\n new ErrorTracking.PrimitiveCoercer(),\n ],\n ErrorTracking.createDefaultStackParser()\n )\n}\nexport class PostHogExceptions {\n private readonly _instance: PostHog\n private _suppressionRules: ErrorTrackingSuppressionRule[] = []\n private _errorPropertiesBuilder: ErrorTracking.ErrorPropertiesBuilder = buildErrorPropertiesBuilder()\n\n constructor(instance: PostHog) {\n this._instance = instance\n this._suppressionRules = this._instance.persistence?.get_property(ERROR_TRACKING_SUPPRESSION_RULES) ?? []\n }\n\n onRemoteConfig(response: RemoteConfig) {\n const suppressionRules = response.errorTracking?.suppressionRules ?? []\n const captureExtensionExceptions = response.errorTracking?.captureExtensionExceptions\n\n // store this in-memory in case persistence is disabled\n this._suppressionRules = suppressionRules\n\n if (this._instance.persistence) {\n this._instance.persistence.register({\n [ERROR_TRACKING_SUPPRESSION_RULES]: this._suppressionRules,\n [ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS]: captureExtensionExceptions,\n })\n }\n }\n\n private get _captureExtensionExceptions() {\n const enabled_server_side = !!this._instance.get_property(ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS)\n const enabled_client_side = this._instance.config.error_tracking.captureExtensionExceptions\n return enabled_client_side ?? enabled_server_side ?? false\n }\n\n buildProperties(\n input: unknown,\n metadata?: { handled?: boolean; syntheticException?: Error }\n ): ErrorTracking.ErrorProperties {\n return this._errorPropertiesBuilder.buildFromUnknown(input, {\n syntheticException: metadata?.syntheticException,\n mechanism: {\n handled: metadata?.handled,\n },\n })\n }\n\n sendExceptionEvent(properties: Properties): CaptureResult | undefined {\n const exceptionList = properties.$exception_list\n\n if (this._isExceptionList(exceptionList)) {\n if (this._matchesSuppressionRule(exceptionList)) {\n logger.info('Skipping exception capture because a suppression rule matched')\n return\n }\n\n if (!this._captureExtensionExceptions && this._isExtensionException(exceptionList)) {\n logger.info('Skipping exception capture because it was thrown by an extension')\n return\n }\n\n if (\n !this._instance.config.error_tracking.__capturePostHogExceptions &&\n this._isPostHogException(exceptionList)\n ) {\n logger.info('Skipping exception capture because it was thrown by the PostHog SDK')\n return\n }\n }\n\n return this._instance.capture('$exception', properties, {\n _noTruncate: true,\n _batchKey: 'exceptionEvent',\n })\n }\n\n private _matchesSuppressionRule(exceptionList: ErrorTracking.ExceptionList): boolean {\n if (exceptionList.length === 0) {\n return false\n }\n\n const exceptionValues = exceptionList.reduce(\n (acc, { type, value }) => {\n if (isString(type) && type.length > 0) {\n acc['$exception_types'].push(type)\n }\n if (isString(value) && value.length > 0) {\n acc['$exception_values'].push(value)\n }\n return acc\n },\n {\n $exception_types: [] as string[],\n $exception_values: [] as string[],\n }\n )\n\n return this._suppressionRules.some((rule) => {\n const results = rule.values.map((v) => {\n const compare = propertyComparisons[v.operator]\n const targets = isArray(v.value) ? v.value : [v.value]\n const values = exceptionValues[v.key] ?? []\n return targets.length > 0 ? compare(targets, values) : false\n })\n return rule.type === 'OR' ? results.some(Boolean) : results.every(Boolean)\n })\n }\n\n private _isExtensionException(exceptionList: ErrorTracking.ExceptionList): boolean {\n const frames = exceptionList.flatMap((e) => e.stacktrace?.frames ?? [])\n return frames.some((f) => f.filename && f.filename.startsWith('chrome-extension://'))\n }\n\n private _isPostHogException(exceptionList: ErrorTracking.ExceptionList): boolean {\n if (exceptionList.length > 0) {\n const exception = exceptionList[0]\n const frames = exception.stacktrace?.frames ?? []\n const lastFrame = frames[frames.length - 1]\n return lastFrame?.filename?.includes('posthog.com/static') ?? false\n }\n\n return false\n }\n\n private _isExceptionList(candidate: unknown): candidate is ErrorTracking.ExceptionList {\n return !isNullish(candidate) && isArray(candidate)\n }\n}\n","import { entries, extend } from './utils'\nimport { PostHog } from './posthog-core'\nimport {\n FlagsResponse,\n FeatureFlagsCallback,\n EarlyAccessFeatureCallback,\n EarlyAccessFeatureResponse,\n Properties,\n JsonType,\n Compression,\n EarlyAccessFeature,\n RemoteConfigFeatureFlagCallback,\n EarlyAccessFeatureStage,\n FeatureFlagDetail,\n} from './types'\nimport { PostHogPersistence } from './posthog-persistence'\n\nimport {\n PERSISTENCE_EARLY_ACCESS_FEATURES,\n PERSISTENCE_FEATURE_FLAG_DETAILS,\n ENABLED_FEATURE_FLAGS,\n STORED_GROUP_PROPERTIES_KEY,\n STORED_PERSON_PROPERTIES_KEY,\n FLAG_CALL_REPORTED,\n} from './constants'\n\nimport { isUndefined, isArray, isNull } from '@posthog/core'\nimport { createLogger } from './utils/logger'\nimport { getTimezone } from './utils/event-utils'\n\nconst logger = createLogger('[FeatureFlags]')\nconst forceDebugLogger = createLogger('[FeatureFlags]', { debugEnabled: true })\n\nconst PERSISTENCE_ACTIVE_FEATURE_FLAGS = '$active_feature_flags'\nconst PERSISTENCE_OVERRIDE_FEATURE_FLAGS = '$override_feature_flags'\nconst PERSISTENCE_FEATURE_FLAG_PAYLOADS = '$feature_flag_payloads'\nconst PERSISTENCE_OVERRIDE_FEATURE_FLAG_PAYLOADS = '$override_feature_flag_payloads'\nconst PERSISTENCE_FEATURE_FLAG_REQUEST_ID = '$feature_flag_request_id'\nconst PERSISTENCE_FEATURE_FLAG_EVALUATED_AT = '$feature_flag_evaluated_at'\n\nexport const filterActiveFeatureFlags = (featureFlags?: Record<string, string | boolean>) => {\n const activeFeatureFlags: Record<string, string | boolean> = {}\n for (const [key, value] of entries(featureFlags || {})) {\n if (value) {\n activeFeatureFlags[key] = value\n }\n }\n return activeFeatureFlags\n}\n\nexport const parseFlagsResponse = (\n response: Partial<FlagsResponse>,\n persistence: PostHogPersistence,\n currentFlags: Record<string, string | boolean> = {},\n currentFlagPayloads: Record<string, JsonType> = {},\n currentFlagDetails: Record<string, FeatureFlagDetail> = {}\n) => {\n const normalizedResponse = normalizeFlagsResponse(response)\n const flagDetails = normalizedResponse.flags\n const featureFlags = normalizedResponse.featureFlags\n const flagPayloads = normalizedResponse.featureFlagPayloads\n\n if (!featureFlags) {\n return // <-- This early return means we don't update anything, which is good.\n }\n\n const requestId = response['requestId']\n const evaluatedAt = response['evaluatedAt']\n\n // using the v1 api\n if (isArray(featureFlags)) {\n logger.warn('v1 of the feature flags endpoint is deprecated. Please use the latest version.')\n const $enabled_feature_flags: Record<string, boolean> = {}\n if (featureFlags) {\n for (let i = 0; i < featureFlags.length; i++) {\n $enabled_feature_flags[featureFlags[i]] = true\n }\n }\n persistence &&\n persistence.register({\n [PERSISTENCE_ACTIVE_FEATURE_FLAGS]: featureFlags,\n [ENABLED_FEATURE_FLAGS]: $enabled_feature_flags,\n })\n return\n }\n\n // using the v2+ api\n let newFeatureFlags = featureFlags\n let newFeatureFlagPayloads = flagPayloads\n let newFeatureFlagDetails = flagDetails\n if (response.errorsWhileComputingFlags) {\n // if not all flags were computed, we upsert flags instead of replacing them\n newFeatureFlags = { ...currentFlags, ...newFeatureFlags }\n newFeatureFlagPayloads = { ...currentFlagPayloads, ...newFeatureFlagPayloads }\n newFeatureFlagDetails = { ...currentFlagDetails, ...newFeatureFlagDetails }\n }\n\n persistence &&\n persistence.register({\n [PERSISTENCE_ACTIVE_FEATURE_FLAGS]: Object.keys(filterActiveFeatureFlags(newFeatureFlags)),\n [ENABLED_FEATURE_FLAGS]: newFeatureFlags || {},\n [PERSISTENCE_FEATURE_FLAG_PAYLOADS]: newFeatureFlagPayloads || {},\n [PERSISTENCE_FEATURE_FLAG_DETAILS]: newFeatureFlagDetails || {},\n ...(requestId ? { [PERSISTENCE_FEATURE_FLAG_REQUEST_ID]: requestId } : {}),\n ...(evaluatedAt ? { [PERSISTENCE_FEATURE_FLAG_EVALUATED_AT]: evaluatedAt } : {}),\n })\n}\n\nconst normalizeFlagsResponse = (response: Partial<FlagsResponse>): Partial<FlagsResponse> => {\n const flagDetails = response['flags']\n\n if (flagDetails) {\n // This is a v=4 request.\n\n // Map of flag keys to flag values: Record<string, string | boolean>\n response.featureFlags = Object.fromEntries(\n Object.keys(flagDetails).map((flag) => [flag, flagDetails[flag].variant ?? flagDetails[flag].enabled])\n )\n // Map of flag keys to flag payloads: Record<string, JsonType>\n response.featureFlagPayloads = Object.fromEntries(\n Object.keys(flagDetails)\n .filter((flag) => flagDetails[flag].enabled)\n .filter((flag) => flagDetails[flag].metadata?.payload)\n .map((flag) => [flag, flagDetails[flag].metadata?.payload])\n )\n } else {\n logger.warn(\n 'Using an older version of the feature flags endpoint. Please upgrade your PostHog server to the latest version'\n )\n }\n return response\n}\n\ntype FeatureFlagOverrides = {\n [flagName: string]: string | boolean\n}\n\ntype FeatureFlagPayloadOverrides = {\n [flagName: string]: JsonType\n}\n\ntype FeatureFlagOverrideOptions = {\n flags?: boolean | string[] | FeatureFlagOverrides\n payloads?: FeatureFlagPayloadOverrides\n suppressWarning?: boolean\n}\n\ntype OverrideFeatureFlagsOptions =\n | boolean // clear all overrides\n | string[] // enable list of flags\n | FeatureFlagOverrides // set variants directly\n | FeatureFlagOverrideOptions\n\nexport enum QuotaLimitedResource {\n FeatureFlags = 'feature_flags',\n Recordings = 'recordings',\n}\n\nexport class PostHogFeatureFlags {\n _override_warning: boolean = false\n featureFlagEventHandlers: FeatureFlagsCallback[]\n $anon_distinct_id: string | undefined\n private _hasLoadedFlags: boolean = false\n private _requestInFlight: boolean = false\n private _reloadingDisabled: boolean = false\n private _additionalReloadRequested: boolean = false\n private _reloadDebouncer?: any\n private _flagsCalled: boolean = false\n private _flagsLoadedFromRemote: boolean = false\n\n constructor(private _instance: PostHog) {\n this.featureFlagEventHandlers = []\n }\n\n private _getValidEvaluationEnvironments(): string[] {\n const envs = this._instance.config.evaluation_environments\n if (!envs?.length) {\n return []\n }\n\n return envs.filter((env) => {\n const isValid = env && typeof env === 'string' && env.trim().length > 0\n if (!isValid) {\n logger.error('Invalid evaluation environment found:', env, 'Expected non-empty string')\n }\n return isValid\n })\n }\n\n private _shouldIncludeEvaluationEnvironments(): boolean {\n return this._getValidEvaluationEnvironments().length > 0\n }\n\n flags(): void {\n if (this._instance.config.__preview_remote_config) {\n // If remote config is enabled we don't call /flags and we mark it as called so that we don't simulate it\n this._flagsCalled = true\n return\n }\n\n // TRICKY: We want to disable flags if we don't have a queued reload, and one of the settings exist for disabling on first load\n const disableFlags =\n !this._reloadDebouncer &&\n (this._instance.config.advanced_disable_feature_flags ||\n this._instance.config.advanced_disable_feature_flags_on_first_load)\n\n this._callFlagsEndpoint({\n disableFlags,\n })\n }\n\n get hasLoadedFlags(): boolean {\n return this._hasLoadedFlags\n }\n\n getFlags(): string[] {\n return Object.keys(this.getFlagVariants())\n }\n\n getFlagsWithDetails(): Record<string, FeatureFlagDetail> {\n const flagDetails = this._instance.get_property(PERSISTENCE_FEATURE_FLAG_DETAILS)\n\n const overridenFlags = this._instance.get_property(PERSISTENCE_OVERRIDE_FEATURE_FLAGS)\n const overriddenPayloads = this._instance.get_property(PERSISTENCE_OVERRIDE_FEATURE_FLAG_PAYLOADS)\n\n if (!overriddenPayloads && !overridenFlags) {\n return flagDetails || {}\n }\n\n const finalDetails = extend({}, flagDetails || {})\n const overriddenKeys = [\n ...new Set([...Object.keys(overriddenPayloads || {}), ...Object.keys(overridenFlags || {})]),\n ]\n for (const key of overriddenKeys) {\n const originalDetail = finalDetails[key]\n const overrideFlagValue = overridenFlags?.[key]\n\n const finalEnabled = isUndefined(overrideFlagValue)\n ? (originalDetail?.enabled ?? false)\n : !!overrideFlagValue\n\n const overrideVariant = isUndefined(overrideFlagValue)\n ? originalDetail.variant\n : typeof overrideFlagValue === 'string'\n ? overrideFlagValue\n : undefined\n\n const overridePayload = overriddenPayloads?.[key]\n\n const overridenDetail = {\n ...originalDetail,\n enabled: finalEnabled,\n // If the flag is not enabled, the variant should be undefined, even if the original has a variant value.\n variant: finalEnabled ? (overrideVariant ?? originalDetail?.variant) : undefined,\n }\n\n // Keep track of the original enabled and variant values so we can send them in the $feature_flag_called event.\n // This will be helpful for debugging and for understanding the impact of overrides.\n if (finalEnabled !== originalDetail?.enabled) {\n overridenDetail.original_enabled = originalDetail?.enabled\n }\n\n if (overrideVariant !== originalDetail?.variant) {\n overridenDetail.original_variant = originalDetail?.variant\n }\n\n if (overridePayload) {\n overridenDetail.metadata = {\n ...originalDetail?.metadata,\n payload: overridePayload,\n original_payload: originalDetail?.metadata?.payload,\n }\n }\n\n finalDetails[key] = overridenDetail\n }\n\n if (!this._override_warning) {\n logger.warn(' Overriding feature flag details!', {\n flagDetails,\n overriddenPayloads,\n finalDetails,\n })\n this._override_warning = true\n }\n return finalDetails\n }\n\n getFlagVariants(): Record<string, string | boolean> {\n const enabledFlags = this._instance.get_property(ENABLED_FEATURE_FLAGS)\n const overriddenFlags = this._instance.get_property(PERSISTENCE_OVERRIDE_FEATURE_FLAGS)\n if (!overriddenFlags) {\n return enabledFlags || {}\n }\n\n const finalFlags = extend({}, enabledFlags)\n const overriddenKeys = Object.keys(overriddenFlags)\n for (let i = 0; i < overriddenKeys.length; i++) {\n finalFlags[overriddenKeys[i]] = overriddenFlags[overriddenKeys[i]]\n }\n if (!this._override_warning) {\n logger.warn(' Overriding feature flags!', {\n enabledFlags,\n overriddenFlags,\n finalFlags,\n })\n this._override_warning = true\n }\n return finalFlags\n }\n\n getFlagPayloads(): Record<string, JsonType> {\n const flagPayloads = this._instance.get_property(PERSISTENCE_FEATURE_FLAG_PAYLOADS)\n const overriddenPayloads = this._instance.get_property(PERSISTENCE_OVERRIDE_FEATURE_FLAG_PAYLOADS)\n\n if (!overriddenPayloads) {\n return flagPayloads || {}\n }\n\n const finalPayloads = extend({}, flagPayloads || {})\n const overriddenKeys = Object.keys(overriddenPayloads)\n for (let i = 0; i < overriddenKeys.length; i++) {\n finalPayloads[overriddenKeys[i]] = overriddenPayloads[overriddenKeys[i]]\n }\n\n if (!this._override_warning) {\n logger.warn(' Overriding feature flag payloads!', {\n flagPayloads,\n overriddenPayloads,\n finalPayloads,\n })\n this._override_warning = true\n }\n return finalPayloads\n }\n\n /**\n * Reloads feature flags asynchronously.\n *\n * Constraints:\n *\n * 1. Avoid parallel requests\n * 2. Delay a few milliseconds after each reloadFeatureFlags call to batch subsequent changes together\n */\n reloadFeatureFlags(): void {\n if (this._reloadingDisabled || this._instance.config.advanced_disable_feature_flags) {\n // If reloading has been explicitly disabled then we don't want to do anything\n // Or if feature flags are disabled\n return\n }\n\n if (this._reloadDebouncer) {\n // If we're already in a debounce then we don't want to do anything\n return\n }\n\n // Debounce multiple calls on the same tick\n this._reloadDebouncer = setTimeout(() => {\n this._callFlagsEndpoint()\n }, 5)\n }\n\n private _clearDebouncer(): void {\n clearTimeout(this._reloadDebouncer)\n this._reloadDebouncer = undefined\n }\n\n ensureFlagsLoaded(): void {\n if (this._hasLoadedFlags || this._requestInFlight || this._reloadDebouncer) {\n // If we are or have already loaded the flags then we don't want to do anything\n return\n }\n\n this.reloadFeatureFlags()\n }\n\n setAnonymousDistinctId(anon_distinct_id: string): void {\n this.$anon_distinct_id = anon_distinct_id\n }\n\n setReloadingPaused(isPaused: boolean): void {\n this._reloadingDisabled = isPaused\n }\n\n /**\n * NOTE: This is used both for flags and remote config. Once the RemoteConfig is fully released this will essentially only\n * be for flags and can eventually be replaced with the new flags endpoint\n */\n _callFlagsEndpoint(options?: { disableFlags?: boolean }): void {\n // Ensure we don't have double queued /flags requests\n this._clearDebouncer()\n if (this._instance._shouldDisableFlags()) {\n // The way this is documented is essentially used to refuse to ever call the /flags endpoint.\n return\n }\n if (this._requestInFlight) {\n this._additionalReloadRequested = true\n return\n }\n const token = this._instance.config.token\n const deviceId = this._instance.get_property('$device_id')\n\n const data: Record<string, any> = {\n token: token,\n distinct_id: this._instance.get_distinct_id(),\n groups: this._instance.getGroups(),\n $anon_distinct_id: this.$anon_distinct_id,\n person_properties: {\n ...(this._instance.persistence?.get_initial_props() || {}),\n ...(this._instance.get_property(STORED_PERSON_PROPERTIES_KEY) || {}),\n },\n group_properties: this._instance.get_property(STORED_GROUP_PROPERTIES_KEY),\n }\n\n // Add device_id if available (handle cookieless mode where it's null)\n if (!isNull(deviceId) && !isUndefined(deviceId)) {\n data.$device_id = deviceId\n }\n\n if (options?.disableFlags || this._instance.config.advanced_disable_feature_flags) {\n data.disable_flags = true\n }\n\n // Add evaluation environments if configured\n if (this._shouldIncludeEvaluationEnvironments()) {\n data.evaluation_environments = this._getValidEvaluationEnvironments()\n }\n\n // flags supports loading config data with the `config` query param, but if you're using remote config, you\n // don't need to add that parameter because all the config data is loaded from the remote config endpoint.\n const useRemoteConfigWithFlags = this._instance.config.__preview_remote_config\n\n const flagsRoute = useRemoteConfigWithFlags ? '/flags/?v=2' : '/flags/?v=2&config=true'\n\n const queryParams = this._instance.config.advanced_only_evaluate_survey_feature_flags\n ? '&only_evaluate_survey_feature_flags=true'\n : ''\n\n const url = this._instance.requestRouter.endpointFor('flags', flagsRoute + queryParams)\n\n if (useRemoteConfigWithFlags) {\n data.timezone = getTimezone()\n }\n\n this._requestInFlight = true\n this._instance._send_request({\n method: 'POST',\n url,\n data,\n compression: this._instance.config.disable_compression ? undefined : Compression.Base64,\n timeout: this._instance.config.feature_flag_request_timeout_ms,\n callback: (response) => {\n let errorsLoading = true\n\n if (response.statusCode === 200) {\n // successful request\n // reset anon_distinct_id after at least a single request with it\n // makes it through\n if (!this._additionalReloadRequested) {\n this.$anon_distinct_id = undefined\n }\n errorsLoading = false\n }\n\n this._requestInFlight = false\n\n // NB: this block is only reached if this._instance.config.__preview_remote_config is false\n if (!this._flagsCalled) {\n this._flagsCalled = true\n this._instance._onRemoteConfig(response.json ?? {})\n }\n\n if (data.disable_flags && !this._additionalReloadRequested) {\n // If flags are disabled then there is no need to call /flags again (flags are the only thing that may change)\n // UNLESS, an additional reload is requested.\n return\n }\n\n this._flagsLoadedFromRemote = !errorsLoading\n\n if (response.json && response.json.quotaLimited?.includes(QuotaLimitedResource.FeatureFlags)) {\n // log a warning and then early return\n logger.warn(\n 'You have hit your feature flags quota limit, and will not be able to load feature flags until the quota is reset. Please visit https://posthog.com/docs/billing/limits-alerts to learn more.'\n )\n return\n }\n\n if (!data.disable_flags) {\n this.receivedFeatureFlags(response.json ?? {}, errorsLoading)\n }\n\n if (this._additionalReloadRequested) {\n this._additionalReloadRequested = false\n this._callFlagsEndpoint()\n }\n },\n })\n }\n\n /*\n * Get feature flag's value for user.\n *\n * ### Usage:\n *\n * if(posthog.getFeatureFlag('my-flag') === 'some-variant') { // do something }\n *\n * @param {Object|String} key Key of the feature flag.\n * @param {Object|String} options (optional) If {send_event: false}, we won't send an $feature_flag_called event to PostHog.\n */\n getFeatureFlag(key: string, options: { send_event?: boolean } = {}): boolean | string | undefined {\n if (!this._hasLoadedFlags && !(this.getFlags() && this.getFlags().length > 0)) {\n logger.warn('getFeatureFlag for key \"' + key + '\" failed. Feature flags didn\\'t load in time.')\n return undefined\n }\n const flagValue = this.getFlagVariants()[key]\n const flagReportValue = `${flagValue}`\n const requestId = this._instance.get_property(PERSISTENCE_FEATURE_FLAG_REQUEST_ID) || undefined\n const evaluatedAt = this._instance.get_property(PERSISTENCE_FEATURE_FLAG_EVALUATED_AT) || undefined\n const flagCallReported: Record<string, string[]> = this._instance.get_property(FLAG_CALL_REPORTED) || {}\n\n if (options.send_event || !('send_event' in options)) {\n if (!(key in flagCallReported) || !flagCallReported[key].includes(flagReportValue)) {\n if (isArray(flagCallReported[key])) {\n flagCallReported[key].push(flagReportValue)\n } else {\n flagCallReported[key] = [flagReportValue]\n }\n this._instance.persistence?.register({ [FLAG_CALL_REPORTED]: flagCallReported })\n\n const flagDetails = this.getFeatureFlagDetails(key)\n\n const properties: Record<string, any | undefined> = {\n $feature_flag: key,\n $feature_flag_response: flagValue,\n $feature_flag_payload: this.getFeatureFlagPayload(key) || null,\n $feature_flag_request_id: requestId,\n $feature_flag_evaluated_at: evaluatedAt,\n $feature_flag_bootstrapped_response: this._instance.config.bootstrap?.featureFlags?.[key] || null,\n $feature_flag_bootstrapped_payload:\n this._instance.config.bootstrap?.featureFlagPayloads?.[key] || null,\n // If we haven't yet received a response from the /flags endpoint, we must have used the bootstrapped value\n $used_bootstrap_value: !this._flagsLoadedFromRemote,\n }\n\n if (!isUndefined(flagDetails?.metadata?.version)) {\n properties.$feature_flag_version = flagDetails.metadata.version\n }\n\n const reason = flagDetails?.reason?.description ?? flagDetails?.reason?.code\n if (reason) {\n properties.$feature_flag_reason = reason\n }\n\n if (flagDetails?.metadata?.id) {\n properties.$feature_flag_id = flagDetails.metadata.id\n }\n\n // It's possible that flag values were overridden by calling overrideFeatureFlags.\n // We want to capture the original values in case someone forgets they were using overrides\n // and is wondering why their app is acting weird.\n if (!isUndefined(flagDetails?.original_variant) || !isUndefined(flagDetails?.original_enabled)) {\n properties.$feature_flag_original_response = !isUndefined(flagDetails.original_variant)\n ? flagDetails.original_variant\n : flagDetails.original_enabled\n }\n\n if (flagDetails?.metadata?.original_payload) {\n properties.$feature_flag_original_payload = flagDetails?.metadata?.original_payload\n }\n\n this._instance.capture('$feature_flag_called', properties)\n }\n }\n return flagValue\n }\n\n /*\n * Retrieves the details for a feature flag.\n *\n * ### Usage:\n *\n * const details = getFeatureFlagDetails(\"my-flag\")\n * console.log(details.metadata.version)\n * console.log(details.reason)\n *\n * @param {String} key Key of the feature flag.\n */\n getFeatureFlagDetails(key: string): FeatureFlagDetail | undefined {\n const details = this.getFlagsWithDetails()\n return details[key]\n }\n\n getFeatureFlagPayload(key: string): JsonType {\n const payloads = this.getFlagPayloads()\n return payloads[key]\n }\n\n /*\n * Fetches the payload for a remote config feature flag. This method will bypass any cached values and fetch the latest\n * value from the PostHog API.\n *\n * Note: Because the posthog-js SDK is primarily used with public project API keys, encrypted remote config payloads will\n * be redacted, never decrypted in the response.\n *\n * ### Usage:\n *\n * getRemoteConfigPayload(\"home-page-welcome-message\", (payload) => console.log(`Fetched remote config: ${payload}`))\n *\n * @param {String} key Key of the feature flag.\n * @param {Function} [callback] The callback function will be called once the remote config feature flag payload has been fetched.\n */\n getRemoteConfigPayload(key: string, callback: RemoteConfigFeatureFlagCallback): void {\n const token = this._instance.config.token\n const data: Record<string, any> = {\n distinct_id: this._instance.get_distinct_id(),\n token,\n }\n\n // Add evaluation environments if configured\n if (this._shouldIncludeEvaluationEnvironments()) {\n data.evaluation_environments = this._getValidEvaluationEnvironments()\n }\n\n this._instance._send_request({\n method: 'POST',\n url: this._instance.requestRouter.endpointFor('flags', '/flags/?v=2&config=true'),\n data,\n compression: this._instance.config.disable_compression ? undefined : Compression.Base64,\n timeout: this._instance.config.feature_flag_request_timeout_ms,\n callback: (response) => {\n const flagPayloads = response.json?.['featureFlagPayloads']\n callback(flagPayloads?.[key] || undefined)\n },\n })\n }\n\n /**\n * See if feature flag is enabled for user.\n *\n * ### Usage:\n *\n * if(posthog.isFeatureEnabled('beta-feature')) { // do something }\n *\n * @param key Key of the feature flag.\n * @param [options] If {send_event: false}, we won't send an $feature_flag_call event to PostHog.\n * @returns A boolean value indicating whether or not the specified feature flag is enabled. If flag information has not yet been loaded,\n * or if the specified feature flag is disabled or does not exist, returns undefined.\n */\n isFeatureEnabled(key: string, options: { send_event?: boolean } = {}): boolean | undefined {\n if (!this._hasLoadedFlags && !(this.getFlags() && this.getFlags().length > 0)) {\n logger.warn('isFeatureEnabled for key \"' + key + '\" failed. Feature flags didn\\'t load in time.')\n return undefined\n }\n const flagValue = this.getFeatureFlag(key, options)\n return isUndefined(flagValue) ? undefined : !!flagValue\n }\n\n addFeatureFlagsHandler(handler: FeatureFlagsCallback): void {\n this.featureFlagEventHandlers.push(handler)\n }\n\n removeFeatureFlagsHandler(handler: FeatureFlagsCallback): void {\n this.featureFlagEventHandlers = this.featureFlagEventHandlers.filter((h) => h !== handler)\n }\n\n receivedFeatureFlags(response: Partial<FlagsResponse>, errorsLoading?: boolean): void {\n if (!this._instance.persistence) {\n return\n }\n this._hasLoadedFlags = true\n\n const currentFlags = this.getFlagVariants()\n const currentFlagPayloads = this.getFlagPayloads()\n const currentFlagDetails = this.getFlagsWithDetails()\n parseFlagsResponse(response, this._instance.persistence, currentFlags, currentFlagPayloads, currentFlagDetails)\n this._fireFeatureFlagsCallbacks(errorsLoading)\n }\n\n /**\n * @deprecated Use overrideFeatureFlags instead. This will be removed in a future version.\n */\n override(flags: boolean | string[] | Record<string, string | boolean>, suppressWarning: boolean = false): void {\n logger.warn('override is deprecated. Please use overrideFeatureFlags instead.')\n this.overrideFeatureFlags({\n flags: flags,\n suppressWarning: suppressWarning,\n })\n }\n\n /**\n * Override feature flags on the client-side. Useful for setting non-persistent feature flags,\n * or for testing/debugging feature flags in the PostHog app.\n *\n * ### Usage:\n *\n * - posthog.featureFlags.overrideFeatureFlags(false) // clear all overrides\n * - posthog.featureFlags.overrideFeatureFlags(['beta-feature']) // enable flags\n * - posthog.featureFlags.overrideFeatureFlags({'beta-feature': 'variant'}) // set variants\n * - posthog.featureFlags.overrideFeatureFlags({ // set both flags and payloads\n * flags: {'beta-feature': 'variant'},\n * payloads: { 'beta-feature': { someData: true } }\n * })\n * - posthog.featureFlags.overrideFeatureFlags({ // only override payloads\n * payloads: { 'beta-feature': { someData: true } }\n * })\n */\n overrideFeatureFlags(overrideOptions: OverrideFeatureFlagsOptions): void {\n if (!this._instance.__loaded || !this._instance.persistence) {\n return logger.uninitializedWarning('posthog.featureFlags.overrideFeatureFlags')\n }\n\n // Clear all overrides if false, lets you do something like posthog.featureFlags.overrideFeatureFlags(false)\n if (overrideOptions === false) {\n this._instance.persistence.unregister(PERSISTENCE_OVERRIDE_FEATURE_FLAGS)\n this._instance.persistence.unregister(PERSISTENCE_OVERRIDE_FEATURE_FLAG_PAYLOADS)\n this._fireFeatureFlagsCallbacks()\n\n return forceDebugLogger.info('All overrides cleared')\n }\n\n if (\n overrideOptions &&\n typeof overrideOptions === 'object' &&\n ('flags' in overrideOptions || 'payloads' in overrideOptions)\n ) {\n const options = overrideOptions\n this._override_warning = Boolean(options.suppressWarning ?? false)\n\n // Handle flags if provided, lets you do something like posthog.featureFlags.overrideFeatureFlags({flags: ['beta-feature']})\n if ('flags' in options) {\n if (options.flags === false) {\n this._instance.persistence.unregister(PERSISTENCE_OVERRIDE_FEATURE_FLAGS)\n forceDebugLogger.info('Flag overrides cleared')\n } else if (options.flags) {\n if (isArray(options.flags)) {\n const flagsObj: Record<string, string | boolean> = {}\n for (let i = 0; i < options.flags.length; i++) {\n flagsObj[options.flags[i]] = true\n }\n this._instance.persistence.register({ [PERSISTENCE_OVERRIDE_FEATURE_FLAGS]: flagsObj })\n } else {\n this._instance.persistence.register({ [PERSISTENCE_OVERRIDE_FEATURE_FLAGS]: options.flags })\n }\n\n forceDebugLogger.info('Flag overrides set', { flags: options.flags })\n }\n }\n\n // Handle payloads independently, lets you do something like posthog.featureFlags.overrideFeatureFlags({payloads: { 'beta-feature': { someData: true } }})\n if ('payloads' in options) {\n if (options.payloads === false) {\n this._instance.persistence.unregister(PERSISTENCE_OVERRIDE_FEATURE_FLAG_PAYLOADS)\n forceDebugLogger.info('Payload overrides cleared')\n } else if (options.payloads) {\n this._instance.persistence.register({\n [PERSISTENCE_OVERRIDE_FEATURE_FLAG_PAYLOADS]: options.payloads,\n })\n forceDebugLogger.info('Payload overrides set', { payloads: options.payloads })\n }\n }\n\n this._fireFeatureFlagsCallbacks()\n return\n }\n\n this._fireFeatureFlagsCallbacks()\n }\n\n /*\n * Register an event listener that runs when feature flags become available or when they change.\n * If there are flags, the listener is called immediately in addition to being called on future changes.\n *\n * ### Usage:\n *\n * posthog.onFeatureFlags(function(featureFlags, featureFlagsVariants, { errorsLoading }) { // do something })\n *\n * @param {Function} [callback] The callback function will be called once the feature flags are ready or when they are updated.\n * It'll return a list of feature flags enabled for the user, the variants,\n * and also a context object indicating whether we succeeded to fetch the flags or not.\n * @returns {Function} A function that can be called to unsubscribe the listener. Used by useEffect when the component unmounts.\n */\n onFeatureFlags(callback: FeatureFlagsCallback): () => void {\n this.addFeatureFlagsHandler(callback)\n if (this._hasLoadedFlags) {\n const { flags, flagVariants } = this._prepareFeatureFlagsForCallbacks()\n callback(flags, flagVariants)\n }\n return () => this.removeFeatureFlagsHandler(callback)\n }\n\n updateEarlyAccessFeatureEnrollment(key: string, isEnrolled: boolean, stage?: string): void {\n const existing_early_access_features: EarlyAccessFeature[] =\n this._instance.get_property(PERSISTENCE_EARLY_ACCESS_FEATURES) || []\n const feature = existing_early_access_features.find((f) => f.flagKey === key)\n\n const enrollmentPersonProp = {\n [`$feature_enrollment/${key}`]: isEnrolled,\n }\n\n const properties: Properties = {\n $feature_flag: key,\n $feature_enrollment: isEnrolled,\n $set: enrollmentPersonProp,\n }\n\n if (feature) {\n properties['$early_access_feature_name'] = feature.name\n }\n\n if (stage) {\n properties['$feature_enrollment_stage'] = stage\n }\n\n this._instance.capture('$feature_enrollment_update', properties)\n this.setPersonPropertiesForFlags(enrollmentPersonProp, false)\n\n const newFlags = { ...this.getFlagVariants(), [key]: isEnrolled }\n this._instance.persistence?.register({\n [PERSISTENCE_ACTIVE_FEATURE_FLAGS]: Object.keys(filterActiveFeatureFlags(newFlags)),\n [ENABLED_FEATURE_FLAGS]: newFlags,\n })\n this._fireFeatureFlagsCallbacks()\n }\n\n getEarlyAccessFeatures(\n callback: EarlyAccessFeatureCallback,\n force_reload = false,\n stages?: EarlyAccessFeatureStage[]\n ): void {\n const existing_early_access_features = this._instance.get_property(PERSISTENCE_EARLY_ACCESS_FEATURES)\n\n const stageParams = stages ? `&${stages.map((s) => `stage=${s}`).join('&')}` : ''\n\n if (!existing_early_access_features || force_reload) {\n this._instance._send_request({\n url: this._instance.requestRouter.endpointFor(\n 'api',\n `/api/early_access_features/?token=${this._instance.config.token}${stageParams}`\n ),\n method: 'GET',\n callback: (response) => {\n if (!response.json) {\n return\n }\n const earlyAccessFeatures = (response.json as EarlyAccessFeatureResponse).earlyAccessFeatures\n // Unregister first to ensure complete replacement, not merge\n // This prevents accumulation of stale features in persistence\n this._instance.persistence?.unregister(PERSISTENCE_EARLY_ACCESS_FEATURES)\n this._instance.persistence?.register({ [PERSISTENCE_EARLY_ACCESS_FEATURES]: earlyAccessFeatures })\n return callback(earlyAccessFeatures)\n },\n })\n } else {\n return callback(existing_early_access_features)\n }\n }\n\n _prepareFeatureFlagsForCallbacks(): { flags: string[]; flagVariants: Record<string, string | boolean> } {\n const flags = this.getFlags()\n const flagVariants = this.getFlagVariants()\n\n // Return truthy\n const truthyFlags = flags.filter((flag) => flagVariants[flag])\n const truthyFlagVariants = Object.keys(flagVariants)\n .filter((variantKey) => flagVariants[variantKey])\n .reduce((res: Record<string, string | boolean>, key) => {\n res[key] = flagVariants[key]\n return res\n }, {})\n\n return {\n flags: truthyFlags,\n flagVariants: truthyFlagVariants,\n }\n }\n\n _fireFeatureFlagsCallbacks(errorsLoading?: boolean): void {\n const { flags, flagVariants } = this._prepareFeatureFlagsForCallbacks()\n this.featureFlagEventHandlers.forEach((handler) => handler(flags, flagVariants, { errorsLoading }))\n }\n\n /**\n * Set override person properties for feature flags.\n * This is used when dealing with new persons / where you don't want to wait for ingestion\n * to update user properties.\n */\n setPersonPropertiesForFlags(properties: Properties, reloadFeatureFlags = true): void {\n // Get persisted person properties\n const existingProperties = this._instance.get_property(STORED_PERSON_PROPERTIES_KEY) || {}\n\n this._instance.register({\n [STORED_PERSON_PROPERTIES_KEY]: {\n ...existingProperties,\n ...properties,\n },\n })\n\n if (reloadFeatureFlags) {\n this._instance.reloadFeatureFlags()\n }\n }\n\n resetPersonPropertiesForFlags(): void {\n this._instance.unregister(STORED_PERSON_PROPERTIES_KEY)\n }\n\n /**\n * Set override group properties for feature flags.\n * This is used when dealing with new groups / where you don't want to wait for ingestion\n * to update properties.\n * Takes in an object, the key of which is the group type.\n * For example:\n * setGroupPropertiesForFlags({'organization': { name: 'CYZ', employees: '11' } })\n */\n setGroupPropertiesForFlags(properties: { [type: string]: Properties }, reloadFeatureFlags = true): void {\n // Get persisted group properties\n const existingProperties = this._instance.get_property(STORED_GROUP_PROPERTIES_KEY) || {}\n\n if (Object.keys(existingProperties).length !== 0) {\n Object.keys(existingProperties).forEach((groupType) => {\n existingProperties[groupType] = {\n ...existingProperties[groupType],\n ...properties[groupType],\n }\n delete properties[groupType]\n })\n }\n\n this._instance.register({\n [STORED_GROUP_PROPERTIES_KEY]: {\n ...existingProperties,\n ...properties,\n },\n })\n\n if (reloadFeatureFlags) {\n this._instance.reloadFeatureFlags()\n }\n }\n\n resetGroupPropertiesForFlags(group_type?: string): void {\n if (group_type) {\n const existingProperties = this._instance.get_property(STORED_GROUP_PROPERTIES_KEY) || {}\n this._instance.register({\n [STORED_GROUP_PROPERTIES_KEY]: { ...existingProperties, [group_type]: {} },\n })\n } else {\n this._instance.unregister(STORED_GROUP_PROPERTIES_KEY)\n }\n }\n\n reset(): void {\n this._hasLoadedFlags = false\n this._requestInFlight = false\n this._reloadingDisabled = false\n this._additionalReloadRequested = false\n this._flagsCalled = false\n this._flagsLoadedFromRemote = false\n this.$anon_distinct_id = undefined\n this._clearDebouncer()\n this._override_warning = false\n }\n}\n","/* eslint camelcase: \"off\" */\n\nimport { each, extend, include, stripEmptyProperties } from './utils'\nimport { cookieStore, createLocalPlusCookieStore, localStore, memoryStore, sessionStore } from './storage'\nimport { PersistentStore, PostHogConfig, Properties } from './types'\nimport {\n ENABLED_FEATURE_FLAGS,\n EVENT_TIMERS_KEY,\n INITIAL_CAMPAIGN_PARAMS,\n INITIAL_PERSON_INFO,\n INITIAL_REFERRER_INFO,\n PERSISTENCE_RESERVED_PROPERTIES,\n} from './constants'\n\nimport { isUndefined } from '@posthog/core'\nimport {\n getCampaignParams,\n getInitialPersonPropsFromInfo,\n getPersonInfo,\n getReferrerInfo,\n getSearchInfo,\n} from './utils/event-utils'\nimport { logger } from './utils/logger'\nimport { stripLeadingDollar, isEmptyObject, isObject } from '@posthog/core'\n\nconst CASE_INSENSITIVE_PERSISTENCE_TYPES: readonly Lowercase<PostHogConfig['persistence']>[] = [\n 'cookie',\n 'localstorage',\n 'localstorage+cookie',\n 'sessionstorage',\n 'memory',\n]\n\nconst parseName = (config: PostHogConfig): string => {\n let token = ''\n if (config['token']) {\n token = config['token'].replace(/\\+/g, 'PL').replace(/\\//g, 'SL').replace(/=/g, 'EQ')\n }\n\n if (config['persistence_name']) {\n return 'ph_' + config['persistence_name']\n } else {\n return 'ph_' + token + '_posthog'\n }\n}\n\nconst isArrayContentsEqual = (arr1: readonly string[], arr2: readonly string[]): boolean => {\n if (arr1.length !== arr2.length) {\n return false\n }\n\n const sortedArr1 = [...arr1].sort()\n const sortedArr2 = [...arr2].sort()\n return sortedArr1.every((item, index) => item === sortedArr2[index])\n}\n\n/**\n * PostHog Persistence Object\n * @constructor\n */\nexport class PostHogPersistence {\n private _config: PostHogConfig\n props: Properties\n private _storage: PersistentStore\n private _campaign_params_saved: boolean\n private readonly _name: string\n _disabled: boolean | undefined\n private _secure: boolean | undefined\n private _expire_days: number | undefined\n private _default_expiry: number | undefined\n private _cross_subdomain: boolean | undefined\n\n /**\n * @param {PostHogConfig} config initial PostHog configuration\n * @param {boolean=} isDisabled should persistence be disabled (e.g. because of consent management)\n */\n constructor(config: PostHogConfig, isDisabled?: boolean) {\n this._config = config\n this.props = {}\n this._campaign_params_saved = false\n this._name = parseName(config)\n this._storage = this._buildStorage(config)\n this.load()\n if (config.debug) {\n logger.info('Persistence loaded', config['persistence'], { ...this.props })\n }\n this.update_config(config, config, isDisabled)\n this.save()\n }\n\n /**\n * Returns whether persistence is disabled. Only available in SDKs > 1.257.1. Do not use on extensions, otherwise\n * it'll break backwards compatibility for any version before 1.257.1.\n */\n public isDisabled?(): boolean {\n return !!this._disabled\n }\n\n private _buildStorage(config: PostHogConfig) {\n if (\n CASE_INSENSITIVE_PERSISTENCE_TYPES.indexOf(\n config['persistence'].toLowerCase() as Lowercase<PostHogConfig['persistence']>\n ) === -1\n ) {\n logger.critical(\n 'Unknown persistence type ' + config['persistence'] + '; falling back to localStorage+cookie'\n )\n config['persistence'] = 'localStorage+cookie'\n }\n\n // Create this before hand to avoid creating it multiple times\n // Creating it inside each individual condition below is too complicated and will break backwards compatibility\n // so create it once for this specific config and use it if necessary\n const localPlusCookieStore = createLocalPlusCookieStore(config['cookie_persisted_properties'] || [])\n\n let store: PersistentStore\n\n // We handle storage type in a case-insensitive way for backwards compatibility\n const storage_type = config['persistence'].toLowerCase() as Lowercase<PostHogConfig['persistence']>\n if (storage_type === 'localstorage' && localStore._is_supported()) {\n store = localStore\n } else if (storage_type === 'localstorage+cookie' && localPlusCookieStore._is_supported()) {\n store = localPlusCookieStore\n } else if (storage_type === 'sessionstorage' && sessionStore._is_supported()) {\n store = sessionStore\n } else if (storage_type === 'memory') {\n store = memoryStore\n } else if (storage_type === 'cookie') {\n store = cookieStore\n } else if (localPlusCookieStore._is_supported()) {\n // selected storage type wasn't supported, fallback to 'localstorage+cookie' if possible\n store = localPlusCookieStore\n } else {\n store = cookieStore\n }\n\n return store\n }\n\n properties(): Properties {\n const p: Properties = {}\n // Filter out reserved properties\n each(this.props, function (v, k) {\n if (k === ENABLED_FEATURE_FLAGS && isObject(v)) {\n const keys = Object.keys(v)\n for (let i = 0; i < keys.length; i++) {\n p[`$feature/${keys[i]}`] = v[keys[i]]\n }\n } else if (!include(PERSISTENCE_RESERVED_PROPERTIES, k)) {\n p[k] = v\n }\n })\n return p\n }\n\n load(): void {\n if (this._disabled) {\n return\n }\n\n const entry = this._storage._parse(this._name)\n\n if (entry) {\n this.props = extend({}, entry)\n }\n }\n\n /**\n * NOTE: Saving frequently causes issues with Recordings and Consent Management Platform (CMP) tools which\n * observe cookie changes, and modify their UI, often causing infinite loops.\n * As such callers of this should ideally check that the data has changed beforehand\n */\n save(): void {\n if (this._disabled) {\n return\n }\n this._storage._set(\n this._name,\n this.props,\n this._expire_days,\n this._cross_subdomain,\n this._secure,\n this._config.debug\n )\n }\n\n remove(): void {\n // remove both domain and subdomain cookies\n this._storage._remove(this._name, false)\n this._storage._remove(this._name, true)\n }\n\n // removes the storage entry and deletes all loaded data\n // forced name for tests\n\n clear(): void {\n this.remove()\n this.props = {}\n }\n\n /**\n * @param {Object} props\n * @param {*=} default_value\n * @param {number=} days\n */\n\n register_once(props: Properties, default_value: any, days?: number): boolean {\n if (isObject(props)) {\n if (isUndefined(default_value)) {\n default_value = 'None'\n }\n this._expire_days = isUndefined(days) ? this._default_expiry : days\n\n let hasChanges = false\n\n each(props, (val, prop) => {\n if (!this.props.hasOwnProperty(prop) || this.props[prop] === default_value) {\n this.props[prop] = val\n hasChanges = true\n }\n })\n\n if (hasChanges) {\n this.save()\n return true\n }\n }\n return false\n }\n\n /**\n * @param {Object} props\n * @param {number=} days\n */\n\n register(props: Properties, days?: number): boolean {\n if (isObject(props)) {\n this._expire_days = isUndefined(days) ? this._default_expiry : days\n\n let hasChanges = false\n\n each(props, (val, prop) => {\n if (props.hasOwnProperty(prop) && this.props[prop] !== val) {\n this.props[prop] = val\n hasChanges = true\n }\n })\n\n if (hasChanges) {\n this.save()\n return true\n }\n }\n return false\n }\n\n unregister(prop: string): void {\n if (prop in this.props) {\n delete this.props[prop]\n this.save()\n }\n }\n\n update_campaign_params(): void {\n if (!this._campaign_params_saved) {\n const campaignParams = getCampaignParams(\n this._config.custom_campaign_params,\n this._config.mask_personal_data_properties,\n this._config.custom_personal_data_properties\n )\n // only save campaign params if there were any\n if (!isEmptyObject(stripEmptyProperties(campaignParams))) {\n this.register(campaignParams)\n }\n this._campaign_params_saved = true\n }\n }\n update_search_keyword(): void {\n this.register(getSearchInfo())\n }\n\n update_referrer_info(): void {\n this.register_once(getReferrerInfo(), undefined)\n }\n\n set_initial_person_info(): void {\n if (this.props[INITIAL_CAMPAIGN_PARAMS] || this.props[INITIAL_REFERRER_INFO]) {\n // the user has initial properties stored the previous way, don't save them again\n return\n }\n\n this.register_once(\n {\n [INITIAL_PERSON_INFO]: getPersonInfo(\n this._config.mask_personal_data_properties,\n this._config.custom_personal_data_properties\n ),\n },\n undefined\n )\n }\n\n get_initial_props(): Properties {\n const p: Properties = {}\n\n // this section isn't written to anymore, but we should keep reading from it for backwards compatibility\n // for a while\n each([INITIAL_REFERRER_INFO, INITIAL_CAMPAIGN_PARAMS], (key) => {\n const initialReferrerInfo = this.props[key]\n if (initialReferrerInfo) {\n each(initialReferrerInfo, function (v, k) {\n p['$initial_' + stripLeadingDollar(k)] = v\n })\n }\n })\n const initialPersonInfo = this.props[INITIAL_PERSON_INFO]\n if (initialPersonInfo) {\n const initialPersonProps = getInitialPersonPropsFromInfo(initialPersonInfo)\n extend(p, initialPersonProps)\n }\n\n return p\n }\n\n // safely fills the passed in object with stored properties,\n // does not override any properties defined in both\n // returns the passed in object\n\n safe_merge(props: Properties): Properties {\n each(this.props, function (val, prop) {\n if (!(prop in props)) {\n props[prop] = val\n }\n })\n\n return props\n }\n\n update_config(config: PostHogConfig, oldConfig: PostHogConfig, isDisabled?: boolean): void {\n this._default_expiry = this._expire_days = config['cookie_expiration']\n this.set_disabled(config['disable_persistence'] || !!isDisabled)\n this.set_cross_subdomain(config['cross_subdomain_cookie'])\n this.set_secure(config['secure_cookie'])\n\n // If the persistence type has changed, we need to migrate the data.\n if (\n config.persistence !== oldConfig.persistence ||\n !isArrayContentsEqual(config.cookie_persisted_properties || [], oldConfig.cookie_persisted_properties || [])\n ) {\n const newStore = this._buildStorage(config)\n const props = this.props\n\n // Clear the old store\n this.clear()\n\n // Set up the new store data\n this._storage = newStore\n this.props = props\n this.save()\n }\n }\n\n set_disabled(disabled: boolean): void {\n this._disabled = disabled\n if (this._disabled) {\n this.remove()\n } else {\n this.save()\n }\n }\n\n set_cross_subdomain(cross_subdomain: boolean): void {\n if (cross_subdomain !== this._cross_subdomain) {\n this._cross_subdomain = cross_subdomain\n this.remove()\n this.save()\n }\n }\n\n set_secure(secure: boolean): void {\n if (secure !== this._secure) {\n this._secure = secure\n this.remove()\n this.save()\n }\n }\n\n set_event_timer(event_name: string, timestamp: number): void {\n const timers = this.props[EVENT_TIMERS_KEY] || {}\n timers[event_name] = timestamp\n this.props[EVENT_TIMERS_KEY] = timers\n this.save()\n }\n\n remove_event_timer(event_name: string): number {\n const timers = this.props[EVENT_TIMERS_KEY] || {}\n const timestamp = timers[event_name]\n if (!isUndefined(timestamp)) {\n delete this.props[EVENT_TIMERS_KEY][event_name]\n this.save()\n }\n return timestamp\n }\n\n get_property(prop: string): any {\n return this.props[prop]\n }\n\n set_property(prop: string, to: any): void {\n this.props[prop] = to\n this.save()\n }\n}\n","import { PostHog } from './posthog-core'\nimport { ProductTour, ProductTourCallback } from './posthog-product-tours-types'\nimport { PRODUCT_TOURS_ENABLED_SERVER_SIDE } from './constants'\nimport { RemoteConfig } from './types'\nimport { createLogger } from './utils/logger'\nimport { isArray, isNullish } from '@posthog/core'\nimport { assignableWindow } from './utils/globals'\n\nconst logger = createLogger('[Product Tours]')\n\nconst PRODUCT_TOURS_STORAGE_KEY = 'ph_product_tours'\n\ninterface ProductTourManagerInterface {\n start: () => void\n stop: () => void\n showTourById: (tourId: string) => void\n previewTour: (tour: ProductTour) => void\n dismissTour: (reason: string) => void\n nextStep: () => void\n previousStep: () => void\n getActiveProductTours: (callback: ProductTourCallback) => void\n resetTour: (tourId: string) => void\n resetAllTours: () => void\n cancelPendingTour: (tourId: string) => void\n}\n\nconst isProductToursEnabled = (instance: PostHog): boolean => {\n if (instance.config.disable_product_tours) {\n return false\n }\n return !!instance.persistence?.get_property(PRODUCT_TOURS_ENABLED_SERVER_SIDE)\n}\n\nexport class PostHogProductTours {\n private _instance: PostHog\n private _productTourManager: ProductTourManagerInterface | null = null\n private _cachedTours: ProductTour[] | null = null\n\n constructor(instance: PostHog) {\n this._instance = instance\n }\n\n onRemoteConfig(response: RemoteConfig): void {\n if (this._instance.persistence) {\n this._instance.persistence.register({\n [PRODUCT_TOURS_ENABLED_SERVER_SIDE]: !!response?.productTours,\n })\n }\n this.loadIfEnabled()\n }\n\n loadIfEnabled(): void {\n if (this._productTourManager || !isProductToursEnabled(this._instance)) {\n return\n }\n this._loadScript(() => this._startProductTours())\n }\n\n private _loadScript(cb: () => void): void {\n if (assignableWindow.__PosthogExtensions__?.generateProductTours) {\n cb()\n return\n }\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(this._instance, 'product-tours', (err) => {\n if (err) {\n logger.error('Could not load product tours script', err)\n return\n }\n cb()\n })\n }\n\n private _startProductTours(): void {\n if (this._productTourManager || !assignableWindow.__PosthogExtensions__?.generateProductTours) {\n return\n }\n this._productTourManager = assignableWindow.__PosthogExtensions__.generateProductTours(this._instance, true)\n }\n\n getProductTours(callback: ProductTourCallback, forceReload: boolean = false): void {\n if (isArray(this._cachedTours) && !forceReload) {\n callback(this._cachedTours, { isLoaded: true })\n return\n }\n\n const persistence = this._instance.persistence\n if (persistence) {\n const storedTours = persistence.props[PRODUCT_TOURS_STORAGE_KEY]\n if (isArray(storedTours) && !forceReload) {\n this._cachedTours = storedTours\n callback(storedTours, { isLoaded: true })\n return\n }\n }\n\n this._instance._send_request({\n url: this._instance.requestRouter.endpointFor(\n 'api',\n `/api/product_tours/?token=${this._instance.config.token}`\n ),\n method: 'GET',\n callback: (response) => {\n const statusCode = response.statusCode\n if (statusCode !== 200 || !response.json) {\n const error = `Product Tours API could not be loaded, status: ${statusCode}`\n logger.error(error)\n callback([], { isLoaded: false, error })\n return\n }\n\n const tours: ProductTour[] = isArray(response.json.product_tours) ? response.json.product_tours : []\n this._cachedTours = tours\n\n if (persistence) {\n persistence.register({ [PRODUCT_TOURS_STORAGE_KEY]: tours })\n }\n\n callback(tours, { isLoaded: true })\n },\n })\n }\n\n getActiveProductTours(callback: ProductTourCallback): void {\n if (isNullish(this._productTourManager)) {\n callback([], { isLoaded: false, error: 'Product tours not loaded' })\n return\n }\n this._productTourManager.getActiveProductTours(callback)\n }\n\n showProductTour(tourId: string): void {\n this._productTourManager?.showTourById(tourId)\n }\n\n // force load product tours extension and render a tour,\n // ignoring all display conditions.\n previewTour(tour: ProductTour): void {\n if (this._productTourManager) {\n this._productTourManager.previewTour(tour)\n return\n }\n\n this._loadScript(() => {\n this._startProductTours()\n this._productTourManager?.previewTour(tour)\n })\n }\n\n dismissProductTour(): void {\n this._productTourManager?.dismissTour('user_clicked_skip')\n }\n\n nextStep(): void {\n this._productTourManager?.nextStep()\n }\n\n previousStep(): void {\n this._productTourManager?.previousStep()\n }\n\n clearCache(): void {\n this._cachedTours = null\n this._instance.persistence?.unregister(PRODUCT_TOURS_STORAGE_KEY)\n }\n\n resetTour(tourId: string): void {\n this._productTourManager?.resetTour(tourId)\n }\n\n resetAllTours(): void {\n this._productTourManager?.resetAllTours()\n }\n\n cancelPendingTour(tourId: string): void {\n this._productTourManager?.cancelPendingTour(tourId)\n }\n}\n","/**\n * Having Survey types in types.ts was confusing tsc\n * and generating an invalid module.d.ts\n * See https://github.com/PostHog/posthog-js/issues/698\n */\n\nimport type { PropertyMatchType } from './types'\nimport type { SurveyAppearance as CoreSurveyAppearance } from '@posthog/core'\n\nexport enum SurveyEventType {\n Activation = 'events',\n Cancellation = 'cancelEvents',\n}\n\n// Extended operator type to include numeric operators not in PropertyMatchType\nexport type PropertyOperator = PropertyMatchType | 'gt' | 'lt'\n\nexport type PropertyFilters = {\n [propertyName: string]: {\n values: string[]\n operator: PropertyOperator\n }\n}\n\nexport interface SurveyEventWithFilters {\n name: string\n propertyFilters?: PropertyFilters\n}\n\nexport enum SurveyWidgetType {\n Button = 'button',\n Tab = 'tab',\n Selector = 'selector',\n}\n\nexport enum SurveyPosition {\n TopLeft = 'top_left',\n TopRight = 'top_right',\n TopCenter = 'top_center',\n MiddleLeft = 'middle_left',\n MiddleRight = 'middle_right',\n MiddleCenter = 'middle_center',\n Left = 'left',\n Center = 'center',\n Right = 'right',\n NextToTrigger = 'next_to_trigger',\n}\n\nexport enum SurveyTabPosition {\n Top = 'top',\n Left = 'left',\n Right = 'right',\n Bottom = 'bottom',\n}\n\n// Extends core SurveyAppearance with browser-specific fields\n// Omit 'position' from core because browser's SurveyPosition has additional values (e.g., NextToTrigger)\nexport interface SurveyAppearance extends Omit<CoreSurveyAppearance, 'position'> {\n // Browser-specific fields not in core\n /** @deprecated - not currently used */\n descriptionTextColor?: string\n ratingButtonHoverColor?: string\n whiteLabel?: boolean\n tabPosition?: SurveyTabPosition\n fontFamily?: string\n maxWidth?: string\n zIndex?: string\n disabledButtonOpacity?: string\n boxPadding?: string\n /** @deprecated Use inputBackground instead (inherited from core) */\n inputBackgroundColor?: string\n // Hide the X (cancel) button - defaults to false (show the button)\n hideCancelButton?: boolean\n // Browser's SurveyPosition has more options than core (e.g., NextToTrigger)\n position?: SurveyPosition\n}\n\nexport enum SurveyType {\n Popover = 'popover',\n API = 'api',\n Widget = 'widget',\n ExternalSurvey = 'external_survey',\n}\n\nexport type SurveyQuestion = BasicSurveyQuestion | LinkSurveyQuestion | RatingSurveyQuestion | MultipleSurveyQuestion\n\nexport type SurveyQuestionDescriptionContentType = 'html' | 'text'\n\ninterface SurveyQuestionBase {\n question: string\n id?: string\n description?: string | null\n descriptionContentType?: SurveyQuestionDescriptionContentType\n optional?: boolean\n buttonText?: string\n branching?: NextQuestionBranching | EndBranching | ResponseBasedBranching | SpecificQuestionBranching\n}\n\nexport interface BasicSurveyQuestion extends SurveyQuestionBase {\n type: SurveyQuestionType.Open\n}\n\nexport interface LinkSurveyQuestion extends SurveyQuestionBase {\n type: SurveyQuestionType.Link\n link?: string | null\n}\n\nexport interface RatingSurveyQuestion extends SurveyQuestionBase {\n type: SurveyQuestionType.Rating\n display: 'number' | 'emoji'\n scale: 3 | 5 | 7 | 10\n lowerBoundLabel: string\n upperBoundLabel: string\n skipSubmitButton?: boolean\n}\n\nexport interface MultipleSurveyQuestion extends SurveyQuestionBase {\n type: SurveyQuestionType.SingleChoice | SurveyQuestionType.MultipleChoice\n choices: string[]\n hasOpenChoice?: boolean\n shuffleOptions?: boolean\n skipSubmitButton?: boolean\n}\n\nexport enum SurveyQuestionType {\n Open = 'open',\n MultipleChoice = 'multiple_choice',\n SingleChoice = 'single_choice',\n Rating = 'rating',\n Link = 'link',\n}\n\nexport enum SurveyQuestionBranchingType {\n NextQuestion = 'next_question',\n End = 'end',\n ResponseBased = 'response_based',\n SpecificQuestion = 'specific_question',\n}\n\ninterface NextQuestionBranching {\n type: SurveyQuestionBranchingType.NextQuestion\n}\n\ninterface EndBranching {\n type: SurveyQuestionBranchingType.End\n}\n\ninterface ResponseBasedBranching {\n type: SurveyQuestionBranchingType.ResponseBased\n responseValues: Record<string, any>\n}\n\ninterface SpecificQuestionBranching {\n type: SurveyQuestionBranchingType.SpecificQuestion\n index: number\n}\n\nexport type SurveyCallback = (surveys: Survey[], context?: { isLoaded: boolean; error?: string }) => void\n\nexport interface SurveyElement {\n text?: string\n $el_text?: string\n tag_name?: string\n href?: string\n attr_id?: string\n attr_class?: string[]\n nth_child?: number\n nth_of_type?: number\n attributes?: Record<string, any>\n event_id?: number\n order?: number\n group_id?: number\n}\nexport interface SurveyRenderReason {\n visible: boolean\n disabledReason?: string\n}\n\nexport enum SurveySchedule {\n Once = 'once',\n Recurring = 'recurring',\n Always = 'always',\n}\n\nexport interface Survey {\n // Sync this with the backend's SurveyAPISerializer!\n id: string\n name: string\n description: string\n type: SurveyType\n feature_flag_keys:\n | {\n key: string\n value?: string\n }[]\n | null\n // the linked flag key is the flag key that is used to link the survey to a flag\n linked_flag_key: string | null\n targeting_flag_key: string | null\n // the internal targeting flag key is the flag key that is used to target users who have seen the survey\n // eg survey-targeting-<survey-id>\n internal_targeting_flag_key: string | null\n questions: SurveyQuestion[]\n appearance: SurveyAppearance | null\n conditions: {\n url?: string\n selector?: string\n seenSurveyWaitPeriodInDays?: number\n urlMatchType?: PropertyMatchType\n /** events that trigger surveys */\n events: {\n repeatedActivation?: boolean\n values: SurveyEventWithFilters[]\n } | null\n /** events that cancel \"pending\" (time-delayed) surveys */\n cancelEvents: {\n values: SurveyEventWithFilters[]\n } | null\n actions: {\n values: SurveyActionType[]\n } | null\n deviceTypes?: string[]\n deviceTypesMatchType?: PropertyMatchType\n linkedFlagVariant?: string\n } | null\n start_date: string | null\n end_date: string | null\n current_iteration: number | null\n current_iteration_start_date: string | null\n schedule?: SurveySchedule | null\n enable_partial_responses?: boolean | null\n}\n\nexport type SurveyWithTypeAndAppearance = Pick<Survey, 'id' | 'type' | 'appearance'>\n\nexport interface SurveyActionType {\n id: number\n name: string | null\n steps?: ActionStepType[]\n}\n\n/** Sync with plugin-server/src/types.ts */\nexport type ActionStepStringMatching = 'contains' | 'exact' | 'regex'\n\nexport interface ActionStepType {\n event?: string | null\n selector?: string | null\n /** pre-compiled regex pattern for matching selector against $elements_chain */\n selector_regex?: string | null\n /** @deprecated Only `selector` should be used now. */\n tag_name?: string\n text?: string | null\n /** @default StringMatching.Exact */\n text_matching?: ActionStepStringMatching | null\n href?: string | null\n /** @default ActionStepStringMatching.Exact */\n href_matching?: ActionStepStringMatching | null\n url?: string | null\n /** @default StringMatching.Contains */\n url_matching?: ActionStepStringMatching | null\n /** Property filters for action step matching */\n properties?: {\n key: string\n value?: string | number | boolean | (string | number | boolean)[] | null\n operator?: PropertyMatchType\n type?: string\n }[]\n}\n\nexport enum SurveyEventName {\n SHOWN = 'survey shown',\n DISMISSED = 'survey dismissed',\n SENT = 'survey sent',\n ABANDONED = 'survey abandoned',\n}\n\nexport enum SurveyEventProperties {\n SURVEY_ID = '$survey_id',\n SURVEY_NAME = '$survey_name',\n SURVEY_RESPONSE = '$survey_response',\n SURVEY_ITERATION = '$survey_iteration',\n SURVEY_ITERATION_START_DATE = '$survey_iteration_start_date',\n SURVEY_PARTIALLY_COMPLETED = '$survey_partially_completed',\n SURVEY_SUBMISSION_ID = '$survey_submission_id',\n SURVEY_QUESTIONS = '$survey_questions',\n SURVEY_COMPLETED = '$survey_completed',\n PRODUCT_TOUR_ID = '$product_tour_id',\n SURVEY_LAST_SEEN_DATE = '$survey_last_seen_date',\n}\n\nexport enum DisplaySurveyType {\n Popover = 'popover',\n Inline = 'inline',\n}\n\ninterface DisplaySurveyOptionsBase {\n ignoreConditions: boolean\n ignoreDelay: boolean\n displayType: DisplaySurveyType\n}\n\ninterface DisplaySurveyPopoverOptions extends DisplaySurveyOptionsBase {\n displayType: DisplaySurveyType.Popover\n}\n\ninterface DisplaySurveyInlineOptions extends DisplaySurveyOptionsBase {\n displayType: DisplaySurveyType.Inline\n selector: string\n}\n\nexport type DisplaySurveyOptions = DisplaySurveyPopoverOptions | DisplaySurveyInlineOptions\n\nexport interface SurveyConfig {\n prefillFromUrl?: boolean\n /**\n * @deprecated No longer used. Surveys will automatically advance past\n * prefilled questions with skipSubmitButton enabled. If partial response\n * collection is enabled, partial responses for pre-filled questions will\n * be submitted automatically on page load.\n */\n autoSubmitIfComplete?: boolean\n /**\n * @deprecated No longer used. Pre-filled responses are now sent\n * immediately when partial responses are enabled, or all required\n * quesions have been pre-filled.\n */\n autoSubmitDelay?: number\n}\n","import { DisplaySurveyOptions, DisplaySurveyType, Survey, SurveyType } from '../posthog-surveys-types'\nimport { createLogger } from '../utils/logger'\n\nexport const SURVEY_LOGGER = createLogger('[Surveys]')\n\nexport function isSurveyRunning(survey: Survey): boolean {\n return !!(survey.start_date && !survey.end_date)\n}\n\nexport function doesSurveyActivateByEvent(survey: Pick<Survey, 'conditions'>): boolean {\n return !!survey.conditions?.events?.values?.length\n}\n\nexport function doesSurveyActivateByAction(survey: Pick<Survey, 'conditions'>): boolean {\n return !!survey.conditions?.actions?.values?.length\n}\n\nexport const SURVEY_SEEN_PREFIX = 'seenSurvey_'\nexport const SURVEY_IN_PROGRESS_PREFIX = 'inProgressSurvey_'\nexport const SURVEY_ABANDONED_PREFIX = 'abandonedSurvey_'\n\nexport const getSurveyInteractionProperty = (\n survey: Pick<Survey, 'id' | 'current_iteration'>,\n action: 'responded' | 'dismissed'\n): string => {\n let surveyProperty = `$survey_${action}/${survey.id}`\n if (survey.current_iteration && survey.current_iteration > 0) {\n surveyProperty = `$survey_${action}/${survey.id}/${survey.current_iteration}`\n }\n\n return surveyProperty\n}\n\nconst getSurveyStorageKey = (prefix: string, survey: Pick<Survey, 'id' | 'current_iteration'>): string => {\n let key = `${prefix}${survey.id}`\n if (survey.current_iteration && survey.current_iteration > 0) {\n key = `${prefix}${survey.id}_${survey.current_iteration}`\n }\n return key\n}\n\nexport const getSurveySeenKey = (survey: Pick<Survey, 'id' | 'current_iteration'>): string => {\n return getSurveyStorageKey(SURVEY_SEEN_PREFIX, survey)\n}\n\nexport const getSurveyAbandonedKey = (survey: Pick<Survey, 'id' | 'current_iteration'>): string => {\n return getSurveyStorageKey(SURVEY_ABANDONED_PREFIX, survey)\n}\n\nexport const setSurveySeenOnLocalStorage = (survey: Pick<Survey, 'id' | 'current_iteration'>) => {\n const isSurveySeen = localStorage.getItem(getSurveySeenKey(survey))\n // if survey is already seen, no need to set it again\n if (isSurveySeen) {\n return\n }\n\n localStorage.setItem(getSurveySeenKey(survey), 'true')\n}\n\n// These surveys are relevant for the getActiveMatchingSurveys method. They are used to\n// display surveys in our customer's application. Any new in-app survey type should be added here.\nexport const IN_APP_SURVEY_TYPES = [SurveyType.Popover, SurveyType.Widget, SurveyType.API]\n\nexport const DEFAULT_DISPLAY_SURVEY_OPTIONS: DisplaySurveyOptions = {\n ignoreConditions: false,\n ignoreDelay: false,\n displayType: DisplaySurveyType.Popover,\n}\n","export class SimpleEventEmitter {\n private _events: { [key: string]: ((...args: any[]) => void)[] } = {}\n\n constructor() {\n this._events = {}\n }\n\n on(event: string, listener: (...args: any[]) => void): () => void {\n if (!this._events[event]) {\n this._events[event] = []\n }\n this._events[event].push(listener)\n\n return () => {\n this._events[event] = this._events[event].filter((x) => x !== listener)\n }\n }\n\n emit(event: string, payload: any): void {\n for (const listener of this._events[event] || []) {\n listener(payload)\n }\n for (const listener of this._events['*'] || []) {\n listener(event, payload)\n }\n }\n}\n","import { isNullish } from '@posthog/core'\n\nexport function extractHref(elementsChain: string): string {\n const match = elementsChain.match(/(?::|\")href=\"(.*?)\"/)\n return match ? match[1] : ''\n}\n\nexport function extractTexts(elementsChain: string): string[] {\n const texts: string[] = []\n const regex = /(?::|\")text=\"(.*?)\"/g\n let match\n while (!isNullish((match = regex.exec(elementsChain)))) {\n if (!texts.includes(match[1])) {\n texts.push(match[1])\n }\n }\n return texts\n}\n\nexport function matchString(\n value: string | undefined | null,\n pattern: string,\n matching: 'exact' | 'contains' | 'regex'\n): boolean {\n if (isNullish(value)) return false\n switch (matching) {\n case 'exact':\n return value === pattern\n case 'contains': {\n // Simulating SQL LIKE behavior (_ = any single character, % = any zero or more characters)\n const likePattern = pattern\n .replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/_/g, '.')\n .replace(/%/g, '.*')\n return new RegExp(likePattern, 'i').test(value)\n }\n case 'regex':\n try {\n return new RegExp(pattern).test(value)\n } catch {\n return false\n }\n default:\n return false\n }\n}\n\nexport function matchTexts(texts: string[], pattern: string, matching: 'exact' | 'contains' | 'regex'): boolean {\n return texts.some((text) => matchString(text, pattern, matching))\n}\n","import { PostHog } from '../../posthog-core'\nimport { ActionStepType, PropertyFilters, SurveyActionType, SurveyElement } from '../../posthog-surveys-types'\nimport { SimpleEventEmitter } from '../../utils/simple-event-emitter'\nimport { CaptureResult, PropertyMatchType } from '../../types'\nimport { isArray, isUndefined } from '@posthog/core'\nimport { matchPropertyFilters } from '../../utils/property-utils'\nimport { extractTexts, extractHref, matchString, matchTexts } from '../../utils/elements-chain-utils'\n\nexport class ActionMatcher {\n private readonly _actionRegistry?: Set<SurveyActionType>\n private readonly _instance?: PostHog\n private readonly _actionEvents: Set<string>\n private _debugEventEmitter = new SimpleEventEmitter()\n\n constructor(instance?: PostHog) {\n this._instance = instance\n this._actionEvents = new Set<string>()\n this._actionRegistry = new Set<SurveyActionType>()\n }\n\n init() {\n if (!isUndefined(this._instance?._addCaptureHook)) {\n const matchEventToAction = (eventName: string, eventPayload: any) => {\n this.on(eventName, eventPayload)\n }\n this._instance?._addCaptureHook(matchEventToAction)\n }\n }\n\n register(actions: SurveyActionType[]): void {\n if (isUndefined(this._instance?._addCaptureHook)) {\n return\n }\n\n actions.forEach((action) => {\n this._actionRegistry?.add(action)\n action.steps?.forEach((step) => {\n this._actionEvents?.add(step?.event || '')\n })\n })\n\n if (this._instance?.autocapture) {\n const selectorsToWatch: Set<string> = new Set<string>()\n actions.forEach((action) => {\n action.steps?.forEach((step) => {\n if (step?.selector) {\n selectorsToWatch.add(step?.selector)\n }\n })\n })\n this._instance?.autocapture.setElementSelectors(selectorsToWatch)\n }\n }\n\n on(eventName: string, eventPayload?: CaptureResult) {\n if (eventPayload == null || eventName.length == 0) {\n return\n }\n\n if (!this._actionEvents.has(eventName) && !this._actionEvents.has(<string>eventPayload?.event)) {\n return\n }\n\n if (this._actionRegistry && this._actionRegistry?.size > 0) {\n this._actionRegistry.forEach((action) => {\n if (this._checkAction(eventPayload, action)) {\n this._debugEventEmitter.emit('actionCaptured', action.name)\n }\n })\n }\n }\n\n _addActionHook(callback: (actionName: string, eventPayload?: any) => void): void {\n this.onAction('actionCaptured', (data) => callback(data))\n }\n\n private _checkAction(event?: CaptureResult, action?: SurveyActionType): boolean {\n if (action?.steps == null) {\n return false\n }\n\n for (const step of action.steps) {\n if (this._checkStep(event, step)) {\n return true\n }\n }\n\n return false\n }\n\n onAction(event: 'actionCaptured', cb: (...args: any[]) => void): () => void {\n return this._debugEventEmitter.on(event, cb)\n }\n\n private _checkStep = (event?: CaptureResult, step?: ActionStepType): boolean => {\n return (\n this._checkStepEvent(event, step) &&\n this._checkStepUrl(event, step) &&\n this._checkStepElement(event, step) &&\n this._checkStepProperties(event, step)\n )\n }\n\n private _checkStepEvent = (event?: CaptureResult, step?: ActionStepType): boolean => {\n // CHECK CONDITIONS, OTHERWISE SKIPPED\n if (step?.event && event?.event !== step?.event) {\n return false // EVENT NAME IS A MISMATCH\n }\n return true\n }\n\n private _checkStepUrl(event?: CaptureResult, step?: ActionStepType): boolean {\n // CHECK CONDITIONS, OTHERWISE SKIPPED\n if (step?.url) {\n const eventUrl = event?.properties?.$current_url\n if (!eventUrl || typeof eventUrl !== 'string') {\n return false\n }\n if (!matchString(eventUrl, step.url, step.url_matching || 'contains')) {\n return false\n }\n }\n return true\n }\n\n private _checkStepElement(event?: CaptureResult, step?: ActionStepType): boolean {\n if (!this._checkStepHref(event, step)) return false\n if (!this._checkStepText(event, step)) return false\n if (!this._checkStepSelector(event, step)) return false\n return true\n }\n\n private _checkStepHref(event?: CaptureResult, step?: ActionStepType): boolean {\n if (!step?.href) return true\n\n const elements = this._getElementsList(event)\n if (elements.length > 0) {\n return elements.some((el) => matchString(el.href, step.href!, step.href_matching || 'exact'))\n }\n\n const chain = (event?.properties?.$elements_chain as string) || ''\n if (chain) {\n return matchString(extractHref(chain), step.href, step.href_matching || 'exact')\n }\n\n return false\n }\n\n private _checkStepText(event?: CaptureResult, step?: ActionStepType): boolean {\n if (!step?.text) return true\n\n const elements = this._getElementsList(event)\n if (elements.length > 0) {\n return elements.some(\n (el) =>\n matchString(el.text, step.text!, step.text_matching || 'exact') ||\n matchString(el.$el_text, step.text!, step.text_matching || 'exact')\n )\n }\n\n const chain = (event?.properties?.$elements_chain as string) || ''\n if (chain) {\n return matchTexts(extractTexts(chain), step.text, step.text_matching || 'exact')\n }\n\n return false\n }\n\n private _checkStepSelector(event?: CaptureResult, step?: ActionStepType): boolean {\n if (!step?.selector) return true\n\n // check exact match on $element_selectors from autocapture\n const elementSelectors = event?.properties?.$element_selectors as string[] | undefined\n if (elementSelectors?.includes(step.selector)) {\n return true\n }\n\n // check against compiled regex\n const chain = (event?.properties?.$elements_chain as string) || ''\n if (step.selector_regex && chain) {\n try {\n return new RegExp(step.selector_regex).test(chain)\n } catch {\n return false\n }\n }\n\n return false\n }\n\n private _getElementsList(event?: CaptureResult): SurveyElement[] {\n if (event?.properties?.$elements == null) {\n return []\n }\n\n return event?.properties.$elements as unknown as SurveyElement[]\n }\n\n private _checkStepProperties(event?: CaptureResult, step?: ActionStepType): boolean {\n if (!step?.properties || step.properties.length === 0) {\n return true\n }\n\n // transform to match same property format as normal events\n const propertyFilters: PropertyFilters = step.properties.reduce<PropertyFilters>((acc, filter) => {\n const values = isArray(filter.value)\n ? filter.value.map(String)\n : filter.value != null\n ? [String(filter.value)]\n : []\n\n acc[filter.key] = {\n values,\n operator: (filter.operator || 'exact') as PropertyMatchType,\n }\n return acc\n }, {})\n\n return matchPropertyFilters(propertyFilters, event?.properties)\n }\n}\n","import { SurveyActionType, SurveyEventType, SurveyEventWithFilters } from '../posthog-surveys-types'\nimport { ActionMatcher } from '../extensions/surveys/action-matcher'\nimport { PostHog } from '../posthog-core'\nimport { CaptureResult } from '../types'\nimport { matchPropertyFilters } from './property-utils'\nimport { isUndefined } from '@posthog/core'\nimport { createLogger } from './logger'\n\n/**\n * Interface for items that can be triggered by events/actions.\n * Both Survey and ProductTour implement this interface.\n */\nexport interface EventTriggerable {\n id: string\n conditions?: {\n events?: { repeatedActivation?: boolean; values: SurveyEventWithFilters[] } | null\n cancelEvents?: { values: SurveyEventWithFilters[] } | null\n actions?: { values: SurveyActionType[] } | null\n } | null\n}\n\n/**\n * Abstract base class for receiving events and matching them to triggerable items.\n * Subclasses implement type-specific behavior for surveys and product tours.\n */\nexport abstract class EventReceiver<T extends EventTriggerable> {\n // eventToItems is a mapping of event name to all the items that are activated by it\n protected _eventToItems: Map<string, string[]>\n // cancelEventToItems is a mapping of event name to all the items that should be cancelled by it\n protected _cancelEventToItems: Map<string, string[]>\n // actionToItems is a mapping of action name to all the items that are activated by it\n protected readonly _actionToItems: Map<string, string[]>\n // actionMatcher can look at CaptureResult payloads and match an event to its corresponding action.\n protected _actionMatcher?: ActionMatcher | null\n protected readonly _instance?: PostHog\n\n constructor(instance: PostHog) {\n this._instance = instance\n this._eventToItems = new Map<string, string[]>()\n this._cancelEventToItems = new Map<string, string[]>()\n this._actionToItems = new Map<string, string[]>()\n }\n\n // Abstract methods for subclasses to implement\n protected abstract _getActivatedKey(): string\n protected abstract _getShownEventName(): string\n protected abstract _getItems(callback: (items: T[]) => void): void\n protected abstract _cancelPendingItem(itemId: string): void\n protected abstract _getLogger(): ReturnType<typeof createLogger>\n /** Check if item is permanently ineligible (e.g. completed/dismissed). Skip adding to activated list. */\n protected abstract _isItemPermanentlyIneligible(itemId?: string): boolean\n\n private _doesEventMatchFilter(\n eventConfig: SurveyEventWithFilters | undefined,\n eventPayload?: CaptureResult\n ): boolean {\n if (!eventConfig) {\n return false\n }\n\n return matchPropertyFilters(eventConfig.propertyFilters, eventPayload?.properties)\n }\n\n private _buildEventToItemMap(items: T[], conditionField: SurveyEventType): Map<string, string[]> {\n const map = new Map<string, string[]>()\n items.forEach((item) => {\n item.conditions?.[conditionField]?.values?.forEach((event) => {\n if (event?.name) {\n const existing = map.get(event.name) || []\n existing.push(item.id)\n map.set(event.name, existing)\n }\n })\n })\n return map\n }\n\n /**\n * build a map of (Event1) => [Item1, Item2, Item3]\n * used for items that should be [activated|cancelled] by Event1\n */\n private _getMatchingItems(\n eventName: string,\n eventPayload: CaptureResult | undefined,\n conditionField: SurveyEventType\n ): T[] {\n const itemIdMap = conditionField === SurveyEventType.Activation ? this._eventToItems : this._cancelEventToItems\n const itemIds = itemIdMap.get(eventName)\n\n let items: T[] = []\n this._getItems((allItems) => {\n items = allItems.filter((item) => itemIds?.includes(item.id))\n })\n\n return items.filter((item) => {\n const eventConfig = item.conditions?.[conditionField]?.values?.find((e) => e.name === eventName)\n return this._doesEventMatchFilter(eventConfig, eventPayload)\n })\n }\n\n register(items: T[]): void {\n if (isUndefined(this._instance?._addCaptureHook)) {\n return\n }\n\n this._setupEventBasedItems(items)\n this._setupActionBasedItems(items)\n }\n\n private _setupActionBasedItems(items: T[]) {\n const actionBasedItems = items.filter(\n (item: T) => item.conditions?.actions && item.conditions?.actions?.values?.length > 0\n )\n\n if (actionBasedItems.length === 0) {\n return\n }\n\n if (this._actionMatcher == null) {\n this._actionMatcher = new ActionMatcher(this._instance)\n this._actionMatcher.init()\n // match any actions to its corresponding item.\n const matchActionToItem = (actionName: string) => {\n this.onAction(actionName)\n }\n\n this._actionMatcher._addActionHook(matchActionToItem)\n }\n\n actionBasedItems.forEach((item) => {\n if (\n item.conditions &&\n item.conditions?.actions &&\n item.conditions?.actions?.values &&\n item.conditions?.actions?.values?.length > 0\n ) {\n // register the known set of actions with\n // the action-matcher so it can match\n // events to actions\n this._actionMatcher?.register(item.conditions.actions.values)\n\n // maintain a mapping of (Action1) => [Item1, Item2, Item3]\n // where Items 1-3 are all activated by Action1\n item.conditions?.actions?.values?.forEach((action) => {\n if (action && action.name) {\n const knownItems: string[] | undefined = this._actionToItems.get(action.name)\n if (knownItems) {\n knownItems.push(item.id)\n }\n this._actionToItems.set(action.name, knownItems || [item.id])\n }\n })\n }\n })\n }\n\n private _setupEventBasedItems(items: T[]) {\n const eventBasedItems = items.filter(\n (item: T) => item.conditions?.events && item.conditions?.events?.values?.length > 0\n )\n\n const itemsWithCancelEvents = items.filter(\n (item: T) => item.conditions?.cancelEvents && item.conditions?.cancelEvents?.values?.length > 0\n )\n\n if (eventBasedItems.length === 0 && itemsWithCancelEvents.length === 0) {\n return\n }\n\n // match any events to its corresponding item.\n const matchEventToItem = (eventName: string, eventPayload?: CaptureResult) => {\n this.onEvent(eventName, eventPayload)\n }\n this._instance?._addCaptureHook(matchEventToItem)\n\n this._eventToItems = this._buildEventToItemMap(items, SurveyEventType.Activation)\n this._cancelEventToItems = this._buildEventToItemMap(items, SurveyEventType.Cancellation)\n }\n\n onEvent(event: string, eventPayload?: CaptureResult): void {\n const logger = this._getLogger()\n const activatedKey = this._getActivatedKey()\n const shownEventName = this._getShownEventName()\n\n const existingActivatedItems: string[] = this._instance?.persistence?.props[activatedKey] || []\n if (shownEventName === event && eventPayload && existingActivatedItems.length > 0) {\n // remove item from activatedItems here.\n logger.info('event matched, removing item from activated items', {\n event,\n eventPayload,\n existingActivatedItems,\n })\n const itemId = eventPayload?.properties?.$survey_id || eventPayload?.properties?.$product_tour_id\n if (itemId) {\n const index = existingActivatedItems.indexOf(itemId)\n if (index >= 0) {\n existingActivatedItems.splice(index, 1)\n this._updateActivatedItems(existingActivatedItems)\n }\n }\n\n return\n }\n\n // check if this event should cancel any pending items\n if (this._cancelEventToItems.has(event)) {\n const itemsToCancel = this._getMatchingItems(event, eventPayload, SurveyEventType.Cancellation)\n\n if (itemsToCancel.length > 0) {\n logger.info('cancel event matched, cancelling items', {\n event,\n itemsToCancel: itemsToCancel.map((s) => s.id),\n })\n\n itemsToCancel.forEach((item) => {\n // remove from activated items\n const index = existingActivatedItems.indexOf(item.id)\n if (index >= 0) {\n existingActivatedItems.splice(index, 1)\n }\n // cancel any pending timeout for this item\n this._cancelPendingItem(item.id)\n })\n\n this._updateActivatedItems(existingActivatedItems)\n }\n }\n\n // if the event is not in the eventToItems map, nothing else to do\n if (!this._eventToItems.has(event)) {\n return\n }\n\n logger.info('event name matched', {\n event,\n eventPayload,\n items: this._eventToItems.get(event),\n })\n\n const matchedItems = this._getMatchingItems(event, eventPayload, SurveyEventType.Activation)\n\n this._updateActivatedItems(existingActivatedItems.concat(matchedItems.map((item) => item.id) || []))\n }\n\n onAction(actionName: string): void {\n const activatedKey = this._getActivatedKey()\n const existingActivatedItems: string[] = this._instance?.persistence?.props[activatedKey] || []\n if (this._actionToItems.has(actionName)) {\n this._updateActivatedItems(existingActivatedItems.concat(this._actionToItems.get(actionName) || []))\n }\n }\n\n private _updateActivatedItems(activatedItems: string[]) {\n const logger = this._getLogger()\n const activatedKey = this._getActivatedKey()\n // Filter out permanently ineligible items and remove duplicates\n const eligibleItems = [...new Set(activatedItems)].filter(\n (itemId) => !this._isItemPermanentlyIneligible(itemId)\n )\n logger.info('updating activated items', {\n activatedItems: eligibleItems,\n })\n\n this._instance?.persistence?.register({\n [activatedKey]: eligibleItems,\n })\n }\n\n getActivatedIds(): string[] {\n const activatedKey = this._getActivatedKey()\n const existingActivatedItems = this._instance?.persistence?.props[activatedKey]\n return existingActivatedItems ? existingActivatedItems : []\n }\n\n getEventToItemsMap(): Map<string, string[]> {\n return this._eventToItems\n }\n\n _getActionMatcher(): ActionMatcher | null | undefined {\n return this._actionMatcher\n }\n}\n","import { SURVEYS_ACTIVATED } from '../constants'\nimport { Survey, SurveyEventName } from '../posthog-surveys-types'\nimport { PostHog } from '../posthog-core'\nimport { SURVEY_LOGGER as logger } from './survey-utils'\nimport { EventReceiver } from './event-receiver'\nimport { createLogger } from './logger'\n\nexport class SurveyEventReceiver extends EventReceiver<Survey> {\n constructor(instance: PostHog) {\n super(instance)\n }\n\n protected _getActivatedKey(): string {\n return SURVEYS_ACTIVATED\n }\n\n protected _getShownEventName(): string {\n return SurveyEventName.SHOWN\n }\n\n protected _getItems(callback: (items: Survey[]) => void): void {\n this._instance?.getSurveys(callback)\n }\n\n protected _cancelPendingItem(itemId: string): void {\n this._instance?.cancelPendingSurvey(itemId)\n }\n\n protected _getLogger(): ReturnType<typeof createLogger> {\n return logger\n }\n\n protected _isItemPermanentlyIneligible(): boolean {\n // Surveys have complex eligibility rules checked at display time\n // For now, we don't filter at activation time\n return false\n }\n\n // Backward compatibility - keep getSurveys() as alias for getActivatedIds()\n getSurveys(): string[] {\n return this.getActivatedIds()\n }\n\n // Backward compatibility - keep getEventToSurveys() as alias\n getEventToSurveys(): Map<string, string[]> {\n return this.getEventToItemsMap()\n }\n}\n","import { SURVEYS } from './constants'\nimport { SurveyManager } from './extensions/surveys'\nimport { PostHog } from './posthog-core'\nimport {\n DisplaySurveyOptions,\n DisplaySurveyType,\n Survey,\n SurveyCallback,\n SurveyRenderReason,\n} from './posthog-surveys-types'\nimport { RemoteConfig } from './types'\nimport { assignableWindow, document } from './utils/globals'\nimport { SurveyEventReceiver } from './utils/survey-event-receiver'\nimport {\n doesSurveyActivateByAction,\n doesSurveyActivateByEvent,\n IN_APP_SURVEY_TYPES,\n isSurveyRunning,\n SURVEY_LOGGER as logger,\n SURVEY_IN_PROGRESS_PREFIX,\n SURVEY_SEEN_PREFIX,\n} from './utils/survey-utils'\nimport { isNullish, isUndefined, isArray } from '@posthog/core'\n\nexport class PostHogSurveys {\n // this is set to undefined until the remote config is loaded\n // then it's set to true if there are surveys to load\n // or false if there are no surveys to load\n // or false if the surveys feature is disabled in the project settings\n private _isSurveysEnabled?: boolean = undefined\n public _surveyEventReceiver: SurveyEventReceiver | null\n private _surveyManager: SurveyManager | null = null\n private _isInitializingSurveys: boolean = false\n private _surveyCallbacks: SurveyCallback[] = []\n // Promise for in-flight survey fetch - allows multiple callers to await the same request\n private _getSurveysInFlightPromise: Promise<{\n surveys: Survey[]\n context: { isLoaded: boolean; error?: string }\n }> | null = null\n\n constructor(private readonly _instance: PostHog) {\n // we set this to undefined here because we need the persistence storage for this type\n // but that's not initialized until loadIfEnabled is called.\n this._surveyEventReceiver = null\n }\n\n onRemoteConfig(response: RemoteConfig) {\n // only load surveys if they are enabled and there are surveys to load\n if (this._instance.config.disable_surveys) {\n return\n }\n\n const surveys = response['surveys']\n if (isNullish(surveys)) {\n return logger.warn('Flags not loaded yet. Not loading surveys.')\n }\n const isArrayResponse = isArray(surveys)\n this._isSurveysEnabled = isArrayResponse ? surveys.length > 0 : surveys\n logger.info(`flags response received, isSurveysEnabled: ${this._isSurveysEnabled}`)\n this.loadIfEnabled()\n }\n\n reset(): void {\n localStorage.removeItem('lastSeenSurveyDate')\n const surveyKeys = []\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i)\n if (key?.startsWith(SURVEY_SEEN_PREFIX) || key?.startsWith(SURVEY_IN_PROGRESS_PREFIX)) {\n surveyKeys.push(key)\n }\n }\n\n surveyKeys.forEach((key) => localStorage.removeItem(key))\n }\n\n loadIfEnabled() {\n // Initial guard clauses\n if (this._surveyManager) {\n return\n } // Already loaded\n if (this._isInitializingSurveys) {\n logger.info('Already initializing surveys, skipping...')\n return\n }\n if (this._instance.config.disable_surveys) {\n logger.info('Disabled. Not loading surveys.')\n return\n }\n if (this._instance.config.cookieless_mode && this._instance.consent.isOptedOut()) {\n logger.info('Not loading surveys in cookieless mode without consent.')\n return\n }\n\n const phExtensions = assignableWindow?.__PosthogExtensions__\n if (!phExtensions) {\n logger.error('PostHog Extensions not found.')\n return\n }\n\n // waiting for remote config to load\n // if surveys is forced enable (like external surveys), ignore the remote config and load surveys\n if (isUndefined(this._isSurveysEnabled) && !this._instance.config.advanced_enable_surveys) {\n return\n }\n\n const isSurveysEnabled = this._isSurveysEnabled || this._instance.config.advanced_enable_surveys\n\n this._isInitializingSurveys = true\n\n try {\n const generateSurveys = phExtensions.generateSurveys\n if (generateSurveys) {\n // Surveys code is already loaded\n this._completeSurveyInitialization(generateSurveys, isSurveysEnabled)\n return\n }\n\n // If we reach here, surveys code is not loaded yet\n const loadExternalDependency = phExtensions.loadExternalDependency\n if (!loadExternalDependency) {\n // Cannot load surveys code\n this._handleSurveyLoadError('PostHog loadExternalDependency extension not found.')\n return\n }\n\n // If we reach here, we need to load the dependency\n loadExternalDependency(this._instance, 'surveys', (err) => {\n if (err || !phExtensions.generateSurveys) {\n this._handleSurveyLoadError('Could not load surveys script', err)\n } else {\n // Need to get the function reference again inside the callback\n this._completeSurveyInitialization(phExtensions.generateSurveys, isSurveysEnabled)\n }\n })\n } catch (e) {\n this._handleSurveyLoadError('Error initializing surveys', e)\n throw e\n } finally {\n // Ensure the flag is always reset\n this._isInitializingSurveys = false\n }\n }\n\n /** Helper to finalize survey initialization */\n private _completeSurveyInitialization(\n generateSurveysFn: (instance: PostHog, isSurveysEnabled: boolean) => any,\n isSurveysEnabled: boolean\n ): void {\n this._surveyManager = generateSurveysFn(this._instance, isSurveysEnabled)\n this._surveyEventReceiver = new SurveyEventReceiver(this._instance)\n logger.info('Surveys loaded successfully')\n this._notifySurveyCallbacks({ isLoaded: true })\n }\n\n /** Helper to handle errors during survey loading */\n private _handleSurveyLoadError(message: string, error?: any): void {\n logger.error(message, error)\n this._notifySurveyCallbacks({ isLoaded: false, error: message })\n }\n\n /**\n * Register a callback that runs when surveys are initialized.\n * ### Usage:\n *\n * posthog.onSurveysLoaded((surveys) => {\n * // You can work with all surveys\n * console.log('All available surveys:', surveys)\n *\n * // Or get active matching surveys\n * posthog.getActiveMatchingSurveys((activeMatchingSurveys) => {\n * if (activeMatchingSurveys.length > 0) {\n * posthog.renderSurvey(activeMatchingSurveys[0].id, '#survey-container')\n * }\n * })\n * })\n *\n * @param {Function} callback The callback function will be called when surveys are loaded or updated.\n * It receives the array of all surveys and a context object with error status.\n * @returns {Function} A function that can be called to unsubscribe the listener.\n */\n onSurveysLoaded(callback: SurveyCallback): () => void {\n this._surveyCallbacks.push(callback)\n\n if (this._surveyManager) {\n this._notifySurveyCallbacks({\n isLoaded: true,\n })\n }\n // Return unsubscribe function\n return () => {\n this._surveyCallbacks = this._surveyCallbacks.filter((cb: SurveyCallback) => cb !== callback)\n }\n }\n\n getSurveys(callback: SurveyCallback, forceReload = false) {\n // In case we manage to load the surveys script, but config says not to load surveys\n // then we shouldn't return survey data\n if (this._instance.config.disable_surveys) {\n logger.info('Disabled. Not loading surveys.')\n return callback([])\n }\n\n const existingSurveys = this._instance.get_property(SURVEYS)\n if (existingSurveys && !forceReload) {\n return callback(existingSurveys, {\n isLoaded: true,\n })\n }\n\n // If a fetch is already in progress and Promise is available, reuse that promise\n // In browsers without Promise (IE11), we skip this optimization and just make concurrent requests\n if (typeof Promise !== 'undefined' && this._getSurveysInFlightPromise) {\n this._getSurveysInFlightPromise.then(({ surveys, context }) => callback(surveys, context))\n return\n }\n\n // Create a new promise for this fetch that other callers can reuse\n // We need to assign the promise before starting the request, because\n // in tests (and potentially in some edge cases) the callback may fire synchronously\n let resolvePromise: (value: { surveys: Survey[]; context: { isLoaded: boolean; error?: string } }) => void\n if (typeof Promise !== 'undefined') {\n this._getSurveysInFlightPromise = new Promise((resolve) => {\n resolvePromise = resolve\n })\n }\n\n this._instance._send_request({\n url: this._instance.requestRouter.endpointFor('api', `/api/surveys/?token=${this._instance.config.token}`),\n method: 'GET',\n timeout: this._instance.config.surveys_request_timeout_ms,\n callback: (response) => {\n this._getSurveysInFlightPromise = null\n\n const statusCode = response.statusCode\n if (statusCode !== 200 || !response.json) {\n const error = `Surveys API could not be loaded, status: ${statusCode}`\n logger.error(error)\n const context = { isLoaded: false, error }\n callback([], context)\n resolvePromise?.({ surveys: [], context })\n return\n }\n const surveys = response.json.surveys || []\n\n const eventOrActionBasedSurveys = surveys.filter(\n (survey: Survey) =>\n isSurveyRunning(survey) &&\n (doesSurveyActivateByEvent(survey) || doesSurveyActivateByAction(survey))\n )\n\n if (eventOrActionBasedSurveys.length > 0) {\n this._surveyEventReceiver?.register(eventOrActionBasedSurveys)\n }\n\n this._instance.persistence?.register({ [SURVEYS]: surveys })\n const context = { isLoaded: true }\n callback(surveys, context)\n resolvePromise?.({ surveys, context })\n },\n })\n }\n\n /** Helper method to notify all registered callbacks */\n private _notifySurveyCallbacks(context: { isLoaded: boolean; error?: string }): void {\n for (const callback of this._surveyCallbacks) {\n try {\n if (!context.isLoaded) {\n return callback([], context)\n }\n this.getSurveys(callback)\n } catch (error) {\n logger.error('Error in survey callback', error)\n }\n }\n }\n\n getActiveMatchingSurveys(callback: SurveyCallback, forceReload = false) {\n if (isNullish(this._surveyManager)) {\n logger.warn('init was not called')\n return\n }\n return this._surveyManager.getActiveMatchingSurveys(callback, forceReload)\n }\n\n private _getSurveyById(surveyId: string): Survey | null {\n let survey: Survey | null = null\n this.getSurveys((surveys) => {\n survey = surveys.find((x) => x.id === surveyId) ?? null\n })\n return survey\n }\n\n private _checkSurveyEligibility(surveyId: string | Survey): { eligible: boolean; reason?: string } {\n if (isNullish(this._surveyManager)) {\n return { eligible: false, reason: 'SDK is not enabled or survey functionality is not yet loaded' }\n }\n const survey = typeof surveyId === 'string' ? this._getSurveyById(surveyId) : surveyId\n if (!survey) {\n return { eligible: false, reason: 'Survey not found' }\n }\n return this._surveyManager.checkSurveyEligibility(survey)\n }\n\n canRenderSurvey(surveyId: string | Survey): SurveyRenderReason {\n if (isNullish(this._surveyManager)) {\n logger.warn('init was not called')\n return { visible: false, disabledReason: 'SDK is not enabled or survey functionality is not yet loaded' }\n }\n const eligibility = this._checkSurveyEligibility(surveyId)\n\n return { visible: eligibility.eligible, disabledReason: eligibility.reason }\n }\n\n canRenderSurveyAsync(surveyId: string, forceReload: boolean): Promise<SurveyRenderReason> {\n // Ensure surveys are loaded before checking\n // Using Promise to wrap the callback-based getSurveys method\n if (isNullish(this._surveyManager)) {\n logger.warn('init was not called')\n return Promise.resolve({\n visible: false,\n disabledReason: 'SDK is not enabled or survey functionality is not yet loaded',\n })\n }\n\n // eslint-disable-next-line compat/compat\n return new Promise<SurveyRenderReason>((resolve) => {\n this.getSurveys((surveys) => {\n const survey = surveys.find((x) => x.id === surveyId) ?? null\n if (!survey) {\n resolve({ visible: false, disabledReason: 'Survey not found' })\n } else {\n const eligibility = this._checkSurveyEligibility(survey)\n resolve({ visible: eligibility.eligible, disabledReason: eligibility.reason })\n }\n }, forceReload)\n })\n }\n\n renderSurvey(surveyId: string | Survey, selector: string) {\n if (isNullish(this._surveyManager)) {\n logger.warn('init was not called')\n return\n }\n const survey = typeof surveyId === 'string' ? this._getSurveyById(surveyId) : surveyId\n if (!survey?.id) {\n logger.warn('Survey not found')\n return\n }\n if (!IN_APP_SURVEY_TYPES.includes(survey.type)) {\n logger.warn(`Surveys of type ${survey.type} cannot be rendered in the app`)\n return\n }\n const elem = document?.querySelector(selector)\n if (!elem) {\n logger.warn('Survey element not found')\n return\n }\n if (survey.appearance?.surveyPopupDelaySeconds) {\n logger.info(\n `Rendering survey ${survey.id} with delay of ${survey.appearance.surveyPopupDelaySeconds} seconds`\n )\n setTimeout(() => {\n logger.info(\n `Rendering survey ${survey.id} with delay of ${survey.appearance?.surveyPopupDelaySeconds} seconds`\n )\n this._surveyManager?.renderSurvey(survey, elem)\n logger.info(`Survey ${survey.id} rendered`)\n }, survey.appearance.surveyPopupDelaySeconds * 1000)\n return\n }\n this._surveyManager.renderSurvey(survey, elem)\n }\n\n displaySurvey(surveyId: string, options: DisplaySurveyOptions) {\n if (isNullish(this._surveyManager)) {\n logger.warn('init was not called')\n return\n }\n const survey = this._getSurveyById(surveyId)\n if (!survey) {\n logger.warn('Survey not found')\n return\n }\n let surveyToDisplay = survey\n if (survey.appearance?.surveyPopupDelaySeconds && options.ignoreDelay) {\n surveyToDisplay = {\n ...survey,\n appearance: {\n ...survey.appearance,\n surveyPopupDelaySeconds: 0,\n },\n }\n }\n if (options.ignoreConditions === false) {\n const canRender = this.canRenderSurvey(survey)\n if (!canRender.visible) {\n logger.warn('Survey is not eligible to be displayed: ', canRender.disabledReason)\n return\n }\n }\n if (options.displayType === DisplaySurveyType.Inline) {\n this.renderSurvey(surveyToDisplay, options.selector)\n return\n }\n this._surveyManager.handlePopoverSurvey(surveyToDisplay)\n }\n\n cancelPendingSurvey(surveyId: string): void {\n if (isNullish(this._surveyManager)) {\n logger.warn('init was not called')\n return\n }\n this._surveyManager.cancelSurvey(surveyId)\n }\n\n handlePageUnload(): void {\n this._surveyManager?.handlePageUnload()\n }\n}\n","import { PostHog } from '../../posthog-core'\nimport {\n ConversationsRemoteConfig,\n GetMessagesResponse,\n GetTicketsOptions,\n GetTicketsResponse,\n MarkAsReadResponse,\n SendMessageResponse,\n UserProvidedTraits,\n} from '../../posthog-conversations-types'\nimport { RemoteConfig } from '../../types'\nimport { assignableWindow, LazyLoadedConversationsInterface } from '../../utils/globals'\nimport { createLogger } from '../../utils/logger'\nimport { isNullish, isUndefined, isBoolean, isNull } from '@posthog/core'\n\nconst logger = createLogger('[Conversations]')\n\nexport type ConversationsManager = LazyLoadedConversationsInterface\n\nexport class PostHogConversations {\n // This is set to undefined until the remote config is loaded\n // then it's set to true if conversations are enabled\n // or false if conversations are disabled in the project settings\n private _isConversationsEnabled?: boolean = undefined\n private _conversationsManager: LazyLoadedConversationsInterface | null = null\n private _isInitializing: boolean = false\n private _remoteConfig: ConversationsRemoteConfig | null = null\n\n constructor(private _instance: PostHog) {}\n\n onRemoteConfig(response: RemoteConfig) {\n // Don't load conversations if disabled via config\n if (this._instance.config.disable_conversations) {\n return\n }\n\n const conversations = response['conversations']\n if (isNullish(conversations)) {\n return\n }\n\n // Handle both boolean and object response\n if (isBoolean(conversations)) {\n this._isConversationsEnabled = conversations\n } else {\n // It's a ConversationsRemoteConfig object\n this._isConversationsEnabled = conversations.enabled\n this._remoteConfig = conversations\n }\n\n this.loadIfEnabled()\n }\n\n reset(): void {\n // Delegate cleanup to the lazy-loaded manager (which knows about persistence keys)\n // If not loaded, there's nothing to reset anyway\n this._conversationsManager?.reset()\n this._conversationsManager = null\n\n // Reset local state\n this._isConversationsEnabled = undefined\n this._remoteConfig = null\n }\n\n loadIfEnabled() {\n if (this._conversationsManager) {\n return\n }\n if (this._isInitializing) {\n return\n }\n if (this._instance.config.disable_conversations) {\n return\n }\n if (this._instance.config.cookieless_mode && this._instance.consent.isOptedOut()) {\n return\n }\n\n const phExtensions = assignableWindow?.__PosthogExtensions__\n if (!phExtensions) {\n return\n }\n\n // Wait for remote config to load\n if (isUndefined(this._isConversationsEnabled)) {\n return\n }\n\n // Check if conversations are enabled\n if (!this._isConversationsEnabled) {\n return\n }\n\n // Check if we have the required config\n if (!this._remoteConfig || !this._remoteConfig.token) {\n logger.error('Conversations enabled but missing token in remote config.')\n return\n }\n\n // Note: Domain check is done in ConversationsManager for widget rendering\n // The conversations API is loaded regardless of domain restrictions\n\n this._isInitializing = true\n\n try {\n const initConversations = phExtensions.initConversations\n if (initConversations) {\n // Conversations code is already loaded\n this._completeInitialization(initConversations)\n this._isInitializing = false\n return\n }\n\n // If we reach here, conversations code is not loaded yet\n const loadExternalDependency = phExtensions.loadExternalDependency\n if (!loadExternalDependency) {\n this._handleLoadError('PostHog loadExternalDependency extension not found.')\n return\n }\n\n // Load the conversations bundle\n loadExternalDependency(this._instance, 'conversations', (err) => {\n if (err || !phExtensions.initConversations) {\n this._handleLoadError('Could not load conversations script', err)\n } else {\n this._completeInitialization(phExtensions.initConversations)\n }\n this._isInitializing = false\n })\n } catch (e) {\n this._handleLoadError('Error initializing conversations', e)\n this._isInitializing = false\n }\n }\n\n /** Helper to finalize conversations initialization */\n private _completeInitialization(\n initConversationsFn: (config: ConversationsRemoteConfig, posthog: PostHog) => LazyLoadedConversationsInterface\n ): void {\n if (!this._remoteConfig) {\n logger.error('Cannot complete initialization: remote config is null')\n return\n }\n\n try {\n // Pass config and PostHog instance to the extension\n this._conversationsManager = initConversationsFn(this._remoteConfig, this._instance)\n logger.info('Conversations loaded successfully')\n } catch (e) {\n this._handleLoadError('Error completing conversations initialization', e)\n }\n }\n\n /** Helper to handle initialization errors */\n private _handleLoadError(message: string, error?: any): void {\n logger.error(message, error)\n this._conversationsManager = null\n this._isInitializing = false\n }\n\n /**\n * Show the conversations widget (button and chat panel)\n */\n show(): void {\n if (!this._conversationsManager) {\n logger.warn('Conversations not loaded yet.')\n return\n }\n this._conversationsManager.show()\n }\n\n /**\n * Hide the conversations widget completely (button and chat panel)\n */\n hide(): void {\n if (!this._conversationsManager) {\n return\n }\n this._conversationsManager.hide()\n }\n\n /**\n * Check if conversations are available (enabled in remote config AND loaded)\n * Use this to check if conversations API can be used.\n */\n isAvailable(): boolean {\n return this._isConversationsEnabled === true && !isNull(this._conversationsManager)\n }\n\n /**\n * Check if the widget is currently visible (rendered and shown)\n */\n isVisible(): boolean {\n return this._conversationsManager?.isVisible() ?? false\n }\n\n /**\n * Send a message programmatically\n * Creates a new ticket if none exists or if newTicket is true\n *\n * @param message - The message text to send\n * @param userTraits - Optional user identification data (name, email)\n * @param newTicket - If true, forces creation of a new ticket (starts new conversation)\n * @returns Promise with response or null if conversations not available yet\n * @note Conversations must be available first (check with isAvailable())\n *\n * @example\n * // Send to existing or create new conversation\n * const response = await posthog.conversations.sendMessage('Hello!', {\n * name: 'John Doe',\n * email: 'john@example.com'\n * })\n *\n * @example\n * // Force creation of a new conversation/ticket\n * const newConvo = await posthog.conversations.sendMessage('Start fresh', undefined, true)\n */\n async sendMessage(\n message: string,\n userTraits?: UserProvidedTraits,\n newTicket?: boolean\n ): Promise<SendMessageResponse | null> {\n if (!this._conversationsManager) {\n logger.warn('Conversations not available yet.')\n return null\n }\n return this._conversationsManager.sendMessage(message, userTraits, newTicket)\n }\n\n /**\n * Get messages for the current or specified ticket\n *\n * @param ticketId - Optional ticket ID (defaults to current active ticket)\n * @param after - Optional ISO timestamp to fetch messages after\n * @returns Promise with messages response or null if conversations not available yet\n * @note Conversations must be available first (check with isAvailable())\n *\n * @example\n * // Get messages for current ticket\n * const messages = await posthog.conversations.getMessages()\n *\n * // Get messages for specific ticket\n * const messages = await posthog.conversations.getMessages('ticket-uuid')\n */\n async getMessages(ticketId?: string, after?: string): Promise<GetMessagesResponse | null> {\n if (!this._conversationsManager) {\n logger.warn('Conversations not available yet.')\n return null\n }\n return this._conversationsManager.getMessages(ticketId, after)\n }\n\n /**\n * Mark messages as read for the current or specified ticket\n *\n * @param ticketId - Optional ticket ID (defaults to current active ticket)\n * @returns Promise with response or null if conversations not available yet\n * @note Conversations must be available first (check with isAvailable())\n *\n * @example\n * await posthog.conversations.markAsRead()\n */\n async markAsRead(ticketId?: string): Promise<MarkAsReadResponse | null> {\n if (!this._conversationsManager) {\n logger.warn('Conversations not available yet.')\n return null\n }\n return this._conversationsManager.markAsRead(ticketId)\n }\n\n /**\n * Get list of tickets for the current widget session\n *\n * @param options - Optional filtering and pagination options\n * @returns Promise with tickets response or null if conversations not available yet\n * @note Conversations must be available first (check with isAvailable())\n *\n * @example\n * const tickets = await posthog.conversations.getTickets({\n * limit: 10,\n * offset: 0,\n * status: 'open'\n * })\n */\n async getTickets(options?: GetTicketsOptions): Promise<GetTicketsResponse | null> {\n if (!this._conversationsManager) {\n logger.warn('Conversations not available yet.')\n return null\n }\n return this._conversationsManager.getTickets(options)\n }\n\n /**\n * Get the current active ticket ID\n * Returns null if no conversation has been started yet or if not available\n *\n * @returns Ticket ID or null\n * @note Safe to call before conversations are available, will return null\n *\n * @example\n * const ticketId = posthog.conversations.getCurrentTicketId()\n * if (ticketId) {\n * console.log('Active conversation:', ticketId)\n * }\n */\n getCurrentTicketId(): string | null {\n return this._conversationsManager?.getCurrentTicketId() ?? null\n }\n\n /**\n * Get the widget session ID (persistent browser identifier)\n * This ID is used for access control and stays the same across page loads\n * Returns null if conversations not available yet\n *\n * @returns Session ID or null if not available\n * @note Safe to call before conversations are available, will return null\n *\n * @example\n * const sessionId = posthog.conversations.getWidgetSessionId()\n * if (!sessionId) {\n * // Conversations not available yet\n * posthog.conversations.show()\n * }\n */\n getWidgetSessionId(): string | null {\n return this._conversationsManager?.getWidgetSessionId() ?? null\n }\n}\n","import { CAPTURE_RATE_LIMIT } from './constants'\nimport type { PostHog } from './posthog-core'\nimport { RequestResponse } from './types'\nimport { createLogger } from './utils/logger'\n\nconst logger = createLogger('[RateLimiter]')\n\nconst ONE_MINUTE_IN_MILLISECONDS = 60 * 1000\nconst RATE_LIMIT_EVENT = '$$client_ingestion_warning'\n\ninterface CaptureResponse {\n quota_limited?: string[]\n}\n\nexport class RateLimiter {\n instance: PostHog\n serverLimits: Record<string, number> = {}\n\n captureEventsPerSecond: number\n captureEventsBurstLimit: number\n lastEventRateLimited = false\n\n constructor(instance: PostHog) {\n this.instance = instance\n\n this.captureEventsPerSecond = instance.config.rate_limiting?.events_per_second || 10\n this.captureEventsBurstLimit = Math.max(\n instance.config.rate_limiting?.events_burst_limit || this.captureEventsPerSecond * 10,\n this.captureEventsPerSecond\n )\n\n this.lastEventRateLimited = this.clientRateLimitContext(true).isRateLimited\n }\n\n public clientRateLimitContext(checkOnly = false): {\n isRateLimited: boolean\n remainingTokens: number\n } {\n // This is primarily to prevent runaway loops from flooding capture with millions of events for a single user.\n // It's as much for our protection as theirs.\n const now = new Date().getTime()\n const bucket = this.instance.persistence?.get_property(CAPTURE_RATE_LIMIT) ?? {\n tokens: this.captureEventsBurstLimit,\n last: now,\n }\n\n bucket.tokens += ((now - bucket.last) / 1000) * this.captureEventsPerSecond\n bucket.last = now\n\n if (bucket.tokens > this.captureEventsBurstLimit) {\n bucket.tokens = this.captureEventsBurstLimit\n }\n\n const isRateLimited = bucket.tokens < 1\n\n if (!isRateLimited && !checkOnly) {\n bucket.tokens = Math.max(0, bucket.tokens - 1)\n }\n\n if (isRateLimited && !this.lastEventRateLimited && !checkOnly) {\n this.instance.capture(\n RATE_LIMIT_EVENT,\n {\n $$client_ingestion_warning_message: `posthog-js client rate limited. Config is set to ${this.captureEventsPerSecond} events per second and ${this.captureEventsBurstLimit} events burst limit.`,\n },\n {\n skip_client_rate_limiting: true,\n }\n )\n }\n\n this.lastEventRateLimited = isRateLimited\n this.instance.persistence?.set_property(CAPTURE_RATE_LIMIT, bucket)\n\n return {\n isRateLimited,\n remainingTokens: bucket.tokens,\n }\n }\n\n public isServerRateLimited(batchKey: string | undefined): boolean {\n const retryAfter = this.serverLimits[batchKey || 'events'] || false\n\n if (retryAfter === false) {\n return false\n }\n return new Date().getTime() < retryAfter\n }\n\n public checkForLimiting = (httpResponse: RequestResponse): void => {\n const text = httpResponse.text\n\n if (!text || !text.length) {\n return\n }\n\n try {\n const response: CaptureResponse = JSON.parse(text)\n const quotaLimitedProducts = response.quota_limited || []\n quotaLimitedProducts.forEach((batchKey) => {\n logger.info(`${batchKey || 'events'} is quota limited.`)\n this.serverLimits[batchKey] = new Date().getTime() + ONE_MINUTE_IN_MILLISECONDS\n })\n } catch (e: any) {\n logger.warn(`could not rate limit - continuing. Error: \"${e?.message}\"`, { text })\n return\n }\n }\n}\n","import { PostHog } from './posthog-core'\nimport { RemoteConfig } from './types'\n\nimport { createLogger } from './utils/logger'\nimport { assignableWindow } from './utils/globals'\n\nconst logger = createLogger('[RemoteConfig]')\n\nexport class RemoteConfigLoader {\n constructor(private readonly _instance: PostHog) {}\n\n get remoteConfig(): RemoteConfig | undefined {\n return assignableWindow._POSTHOG_REMOTE_CONFIG?.[this._instance.config.token]?.config\n }\n\n private _loadRemoteConfigJs(cb: (config?: RemoteConfig) => void): void {\n if (assignableWindow.__PosthogExtensions__?.loadExternalDependency) {\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(this._instance, 'remote-config', () => {\n return cb(this.remoteConfig)\n })\n } else {\n logger.error('PostHog Extensions not found. Cannot load remote config.')\n cb()\n }\n }\n\n private _loadRemoteConfigJSON(cb: (config?: RemoteConfig) => void): void {\n this._instance._send_request({\n method: 'GET',\n url: this._instance.requestRouter.endpointFor('assets', `/array/${this._instance.config.token}/config`),\n callback: (response) => {\n cb(response.json as RemoteConfig | undefined)\n },\n })\n }\n\n load(): void {\n try {\n // Attempt 1 - use the pre-loaded config if it came as part of the token-specific array.js\n if (this.remoteConfig) {\n logger.info('Using preloaded remote config', this.remoteConfig)\n this._onRemoteConfig(this.remoteConfig)\n return\n }\n\n if (this._instance._shouldDisableFlags()) {\n // This setting is essentially saying \"dont call external APIs\" hence we respect it here\n logger.warn('Remote config is disabled. Falling back to local config.')\n return\n }\n\n // Attempt 2 - if we have the external deps loader then lets load the script version of the config that includes site apps\n this._loadRemoteConfigJs((config) => {\n if (!config) {\n logger.info('No config found after loading remote JS config. Falling back to JSON.')\n // Attempt 3 Load the config json instead of the script - we won't get site apps etc. but we will get the config\n this._loadRemoteConfigJSON((config) => {\n this._onRemoteConfig(config)\n })\n return\n }\n\n this._onRemoteConfig(config)\n })\n } catch (error) {\n logger.error('Error loading remote config', error)\n }\n }\n\n private _onRemoteConfig(config?: RemoteConfig): void {\n // NOTE: Once this is rolled out we will remove the /flags related code above. Until then the code duplication is fine.\n if (!config) {\n logger.error('Failed to fetch remote config from PostHog.')\n return\n }\n\n if (!this._instance.config.__preview_remote_config) {\n logger.info('__preview_remote_config is disabled. Logging config instead', config)\n return\n }\n\n this._instance._onRemoteConfig(config)\n\n // We only need to reload if we haven't already loaded the flags or if the request is in flight\n if (config.hasFeatureFlags !== false) {\n // If the config has feature flags, we need to call /flags to get the feature flags\n // This completely separates it from the config logic which is good in terms of separation of concerns\n this._instance.featureFlags.ensureFlagsLoaded()\n }\n }\n}\n","import { QueuedRequestWithOptions, RequestQueueConfig } from './types'\nimport { each } from './utils'\n\nimport { isArray, isUndefined, clampToRange } from '@posthog/core'\nimport { logger } from './utils/logger'\n\nexport const DEFAULT_FLUSH_INTERVAL_MS = 3000\n\nexport class RequestQueue {\n // We start in a paused state and only start flushing when enabled by the parent\n private _isPaused: boolean = true\n private _queue: QueuedRequestWithOptions[] = []\n private _flushTimeout?: ReturnType<typeof setTimeout>\n private _flushTimeoutMs: number\n private _sendRequest: (req: QueuedRequestWithOptions) => void\n\n constructor(sendRequest: (req: QueuedRequestWithOptions) => void, config?: RequestQueueConfig) {\n this._flushTimeoutMs = clampToRange(\n config?.flush_interval_ms || DEFAULT_FLUSH_INTERVAL_MS,\n 250,\n 5000,\n logger.createLogger('flush interval'),\n DEFAULT_FLUSH_INTERVAL_MS\n )\n this._sendRequest = sendRequest\n }\n\n enqueue(req: QueuedRequestWithOptions): void {\n this._queue.push(req)\n\n if (!this._flushTimeout) {\n this._setFlushTimeout()\n }\n }\n\n unload(): void {\n this._clearFlushTimeout()\n const requests = this._queue.length > 0 ? this._formatQueue() : {}\n const requestValues = Object.values(requests)\n\n // Always force events to be sent before recordings, as events are more important, and recordings are bigger and thus less likely to arrive\n const sortedRequests = [\n ...requestValues.filter((r) => r.url.indexOf('/e') === 0),\n ...requestValues.filter((r) => r.url.indexOf('/e') !== 0),\n ]\n sortedRequests.map((req) => {\n this._sendRequest({ ...req, transport: 'sendBeacon' })\n })\n }\n\n enable(): void {\n this._isPaused = false\n this._setFlushTimeout()\n }\n\n private _setFlushTimeout(): void {\n if (this._isPaused) {\n return\n }\n this._flushTimeout = setTimeout(() => {\n this._clearFlushTimeout()\n if (this._queue.length > 0) {\n const requests = this._formatQueue()\n for (const key in requests) {\n const req = requests[key]\n const now = new Date().getTime()\n\n if (req.data && isArray(req.data)) {\n each(req.data, (data) => {\n data['offset'] = Math.abs(data['timestamp'] - now)\n delete data['timestamp']\n })\n }\n this._sendRequest(req)\n }\n }\n }, this._flushTimeoutMs)\n }\n\n private _clearFlushTimeout(): void {\n clearTimeout(this._flushTimeout)\n this._flushTimeout = undefined\n }\n\n private _formatQueue(): Record<string, QueuedRequestWithOptions> {\n const requests: Record<string, QueuedRequestWithOptions> = {}\n each(this._queue, (request: QueuedRequestWithOptions) => {\n const req = request\n const key = (req ? req.batchKey : null) || req.url\n if (isUndefined(requests[key])) {\n // TODO: What about this -it seems to batch data into an array - do we always want that?\n requests[key] = { ...req, data: [] }\n }\n\n requests[key].data?.push(req.data)\n })\n\n this._queue = []\n return requests\n }\n}\n","import { RetriableRequestWithOptions } from './types'\n\nimport { isNumber, isUndefined } from '@posthog/core'\nimport { logger } from './utils/logger'\nimport { window } from './utils/globals'\nimport { PostHog } from './posthog-core'\nimport { extendURLParams } from './request'\nimport { addEventListener } from './utils'\n\nconst thirtyMinutes = 30 * 60 * 1000\n\n/**\n * Generates a jitter-ed exponential backoff delay in milliseconds\n *\n * The base value is 6 seconds, which is doubled with each retry\n * up to the maximum of 30 minutes\n *\n * Each value then has +/- 50% jitter\n *\n * Giving a range of 6 seconds up to 45 minutes\n */\nexport function pickNextRetryDelay(retriesPerformedSoFar: number): number {\n const rawBackoffTime = 3000 * 2 ** retriesPerformedSoFar\n const minBackoff = rawBackoffTime / 2\n const cappedBackoffTime = Math.min(thirtyMinutes, rawBackoffTime)\n const jitterFraction = Math.random() - 0.5 // A random number between -0.5 and 0.5\n const jitter = jitterFraction * (cappedBackoffTime - minBackoff)\n return Math.ceil(cappedBackoffTime + jitter)\n}\n\ninterface RetryQueueElement {\n retryAt: number\n requestOptions: RetriableRequestWithOptions\n}\n\nexport class RetryQueue {\n private _isPolling: boolean = false\n private _poller: number | undefined\n private _pollIntervalMs: number = 3000\n private _queue: RetryQueueElement[] = []\n private _areWeOnline: boolean\n private _onlineListener: (() => void) | undefined\n private _offlineListener: (() => void) | undefined\n\n constructor(private _instance: PostHog) {\n this._queue = []\n this._areWeOnline = true\n\n if (!isUndefined(window) && 'onLine' in window.navigator) {\n this._areWeOnline = window.navigator.onLine\n\n this._onlineListener = () => {\n this._areWeOnline = true\n this._flush()\n }\n\n this._offlineListener = () => {\n this._areWeOnline = false\n }\n\n addEventListener(window, 'online', this._onlineListener)\n addEventListener(window, 'offline', this._offlineListener)\n }\n }\n\n get length() {\n return this._queue.length\n }\n\n retriableRequest({ retriesPerformedSoFar, ...options }: RetriableRequestWithOptions): void {\n if (isNumber(retriesPerformedSoFar) && retriesPerformedSoFar > 0) {\n options.url = extendURLParams(options.url, { retry_count: retriesPerformedSoFar })\n }\n\n this._instance._send_request({\n ...options,\n callback: (response) => {\n if (response.statusCode !== 200 && (response.statusCode < 400 || response.statusCode >= 500)) {\n if ((retriesPerformedSoFar ?? 0) < 10) {\n this._enqueue({\n retriesPerformedSoFar,\n ...options,\n })\n return\n }\n }\n\n options.callback?.(response)\n },\n })\n }\n\n private _enqueue(requestOptions: RetriableRequestWithOptions): void {\n const retriesPerformedSoFar = requestOptions.retriesPerformedSoFar || 0\n requestOptions.retriesPerformedSoFar = retriesPerformedSoFar + 1\n\n const msToNextRetry = pickNextRetryDelay(retriesPerformedSoFar)\n const retryAt = Date.now() + msToNextRetry\n\n this._queue.push({ retryAt, requestOptions })\n\n let logMessage = `Enqueued failed request for retry in ${msToNextRetry}`\n if (!navigator.onLine) {\n logMessage += ' (Browser is offline)'\n }\n logger.warn(logMessage)\n\n if (!this._isPolling) {\n this._isPolling = true\n this._poll()\n }\n }\n\n private _poll(): void {\n this._poller && clearTimeout(this._poller)\n\n if (this._queue.length === 0) {\n this._isPolling = false\n this._poller = undefined\n return\n }\n\n this._poller = setTimeout(() => {\n if (this._areWeOnline && this._queue.length > 0) {\n this._flush()\n }\n this._poll()\n }, this._pollIntervalMs) as any as number\n }\n\n private _flush(): void {\n const now = Date.now()\n const notToFlush: RetryQueueElement[] = []\n const toFlush = this._queue.filter((item) => {\n if (item.retryAt < now) {\n return true\n }\n notToFlush.push(item)\n return false\n })\n\n this._queue = notToFlush\n\n if (toFlush.length > 0) {\n for (const { requestOptions } of toFlush) {\n this.retriableRequest(requestOptions)\n }\n }\n }\n\n unload(): void {\n if (this._poller) {\n clearTimeout(this._poller)\n this._poller = undefined\n }\n\n this._isPolling = false\n\n if (!isUndefined(window)) {\n if (this._onlineListener) {\n window.removeEventListener('online', this._onlineListener)\n this._onlineListener = undefined\n }\n if (this._offlineListener) {\n window.removeEventListener('offline', this._offlineListener)\n this._offlineListener = undefined\n }\n }\n\n for (const { requestOptions } of this._queue) {\n try {\n // we've had send beacon in place for at least 2 years\n // eslint-disable-next-line compat/compat\n this._instance._send_request({\n ...requestOptions,\n transport: 'sendBeacon',\n })\n } catch (e) {\n // Note sendBeacon automatically retries, and after the first retry it will lose reference to contextual `this`.\n // This means in some cases `this.getConfig` will be undefined.\n logger.error(e)\n }\n }\n this._queue = []\n }\n}\n","import { window } from './utils/globals'\nimport { PostHog } from './posthog-core'\nimport { addEventListener } from './utils'\nimport { isArray } from '@posthog/core'\n\nexport interface ScrollContext {\n // scroll is how far down the page the user has scrolled,\n // content is how far down the page the user can view content\n // (e.g. if the page is 1000 tall, but the user's screen is only 500 tall,\n // and they don't scroll at all, then scroll is 0 and content is 500)\n maxScrollHeight?: number\n maxScrollY?: number\n lastScrollY?: number\n maxContentHeight?: number\n maxContentY?: number\n lastContentY?: number\n}\n\n// This class is responsible for tracking scroll events and maintaining the scroll context\nexport class ScrollManager {\n private _context: ScrollContext | undefined\n\n constructor(private _instance: PostHog) {}\n\n getContext(): ScrollContext | undefined {\n return this._context\n }\n\n resetContext(): ScrollContext | undefined {\n const ctx = this._context\n\n // update the scroll properties for the new page, but wait until the next tick\n // of the event loop\n setTimeout(this._updateScrollData, 0)\n\n return ctx\n }\n\n private _updateScrollData = () => {\n if (!this._context) {\n this._context = {}\n }\n\n const el = this.scrollElement()\n\n const scrollY = this.scrollY()\n const scrollHeight = el ? Math.max(0, el.scrollHeight - el.clientHeight) : 0\n const contentY = scrollY + (el?.clientHeight || 0)\n const contentHeight = el?.scrollHeight || 0\n\n this._context.lastScrollY = Math.ceil(scrollY)\n this._context.maxScrollY = Math.max(scrollY, this._context.maxScrollY ?? 0)\n this._context.maxScrollHeight = Math.max(scrollHeight, this._context.maxScrollHeight ?? 0)\n\n this._context.lastContentY = contentY\n this._context.maxContentY = Math.max(contentY, this._context.maxContentY ?? 0)\n this._context.maxContentHeight = Math.max(contentHeight, this._context.maxContentHeight ?? 0)\n }\n\n // `capture: true` is required to get scroll events for other scrollable elements\n // on the page, not just the window\n // see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#usecapture\n startMeasuringScrollPosition() {\n addEventListener(window, 'scroll', this._updateScrollData, { capture: true })\n addEventListener(window, 'scrollend', this._updateScrollData, { capture: true })\n addEventListener(window, 'resize', this._updateScrollData)\n }\n\n public scrollElement(): Element | undefined {\n if (this._instance.config.scroll_root_selector) {\n const selectors = isArray(this._instance.config.scroll_root_selector)\n ? this._instance.config.scroll_root_selector\n : [this._instance.config.scroll_root_selector]\n for (const selector of selectors) {\n const element = window?.document.querySelector(selector)\n if (element) {\n return element\n }\n }\n return undefined\n } else {\n return window?.document.documentElement\n }\n }\n\n public scrollY(): number {\n if (this._instance.config.scroll_root_selector) {\n const element = this.scrollElement()\n return (element && element.scrollTop) || 0\n } else {\n return window ? window.scrollY || window.pageYOffset || window.document.documentElement.scrollTop || 0 : 0\n }\n }\n\n public scrollX(): number {\n if (this._instance.config.scroll_root_selector) {\n const element = this.scrollElement()\n return (element && element.scrollLeft) || 0\n } else {\n return window ? window.scrollX || window.pageXOffset || window.document.documentElement.scrollLeft || 0 : 0\n }\n }\n}\n","/* Store some session-level attribution-related properties in the persistence layer\n *\n * These have the same lifespan as a session_id, meaning that if the session_id changes, these properties will be reset.\n *\n * We only store the entry URL and referrer, and derive many props (such as utm tags) from those.\n *\n * Given that the cookie is limited to 4K bytes, we don't want to store too much data, so we chose not to store device\n * properties (such as browser, OS, etc) here, as usually getting the current value of those from event properties is\n * sufficient.\n */\nimport { getPersonInfo, getPersonPropsFromInfo } from './utils/event-utils'\nimport type { SessionIdManager } from './sessionid'\nimport type { PostHogPersistence } from './posthog-persistence'\nimport { CLIENT_SESSION_PROPS } from './constants'\nimport type { PostHog } from './posthog-core'\nimport { each, stripEmptyProperties } from './utils'\nimport { stripLeadingDollar } from '@posthog/core'\n\ninterface LegacySessionSourceProps {\n initialPathName: string\n referringDomain: string // Is actually referring host, but named referring domain for internal consistency. Should contain a port if there is one.\n utm_medium?: string\n utm_source?: string\n utm_campaign?: string\n utm_content?: string\n utm_term?: string\n}\n\ninterface CurrentSessionSourceProps {\n r: string // Referring host\n u: string | undefined // full URL\n}\n\ninterface StoredSessionSourceProps {\n sessionId: string\n props: LegacySessionSourceProps | CurrentSessionSourceProps\n}\n\nconst generateSessionSourceParams = (posthog?: PostHog): LegacySessionSourceProps | CurrentSessionSourceProps => {\n return getPersonInfo(posthog?.config.mask_personal_data_properties, posthog?.config.custom_personal_data_properties)\n}\n\nexport class SessionPropsManager {\n private readonly _instance: PostHog\n private readonly _sessionIdManager: SessionIdManager\n private readonly _persistence: PostHogPersistence\n private readonly _sessionSourceParamGenerator: (\n instance?: PostHog\n ) => LegacySessionSourceProps | CurrentSessionSourceProps\n\n constructor(\n instance: PostHog,\n sessionIdManager: SessionIdManager,\n persistence: PostHogPersistence,\n sessionSourceParamGenerator?: (instance?: PostHog) => LegacySessionSourceProps | CurrentSessionSourceProps\n ) {\n this._instance = instance\n this._sessionIdManager = sessionIdManager\n this._persistence = persistence\n this._sessionSourceParamGenerator = sessionSourceParamGenerator || generateSessionSourceParams\n\n this._sessionIdManager.onSessionId(this._onSessionIdCallback)\n }\n\n _getStored(): StoredSessionSourceProps | undefined {\n return this._persistence.props[CLIENT_SESSION_PROPS]\n }\n\n _onSessionIdCallback = (sessionId: string) => {\n const stored = this._getStored()\n if (stored && stored.sessionId === sessionId) {\n return\n }\n\n const newProps: StoredSessionSourceProps = {\n sessionId,\n props: this._sessionSourceParamGenerator(this._instance),\n }\n this._persistence.register({ [CLIENT_SESSION_PROPS]: newProps })\n }\n\n getSetOnceProps() {\n const p = this._getStored()?.props\n if (!p) {\n return {}\n }\n if ('r' in p) {\n return getPersonPropsFromInfo(p)\n } else {\n return {\n $referring_domain: p.referringDomain,\n $pathname: p.initialPathName,\n utm_source: p.utm_source,\n utm_campaign: p.utm_campaign,\n utm_medium: p.utm_medium,\n utm_content: p.utm_content,\n utm_term: p.utm_term,\n }\n }\n }\n\n getSessionProps() {\n // it's the same props, but don't include null for unset properties, and add a prefix\n const p: Record<string, any> = {}\n each(stripEmptyProperties(this.getSetOnceProps()), (v, k) => {\n if (k === '$current_url') {\n // $session_entry_current_url would be a weird name, call it $session_entry_url instead\n k = 'url'\n }\n p[`$session_entry_${stripLeadingDollar(k)}`] = v\n })\n return p\n }\n}\n","import { PostHogPersistence } from './posthog-persistence'\nimport { SESSION_ID } from './constants'\nimport { sessionStore } from './storage'\nimport { PostHogConfig, SessionIdChangedCallback } from './types'\nimport { uuid7ToTimestampMs, uuidv7 } from './uuidv7'\nimport { window } from './utils/globals'\n\nimport { createLogger } from './utils/logger'\n\nimport { isArray, isNumber, isUndefined, clampToRange } from '@posthog/core'\nimport { PostHog } from './posthog-core'\nimport { addEventListener } from './utils'\nimport { SimpleEventEmitter } from './utils/simple-event-emitter'\n\nconst logger = createLogger('[SessionId]')\n\nexport const DEFAULT_SESSION_IDLE_TIMEOUT_SECONDS = 30 * 60 // 30 minutes\nexport const MAX_SESSION_IDLE_TIMEOUT_SECONDS = 10 * 60 * 60 // 10 hours\nconst MIN_SESSION_IDLE_TIMEOUT_SECONDS = 60 // 1 minute\nconst SESSION_LENGTH_LIMIT_MILLISECONDS = 24 * 3600 * 1000 // 24 hours\n\nexport class SessionIdManager {\n private readonly _sessionIdGenerator: () => string\n private readonly _windowIdGenerator: () => string\n private _config: Partial<PostHogConfig>\n private _persistence: PostHogPersistence\n private _windowId: string | null | undefined\n private _sessionId: string | null | undefined\n private readonly _window_id_storage_key: string\n private readonly _primary_window_exists_storage_key: string\n private _sessionStartTimestamp: number | null\n\n private _sessionActivityTimestamp: number | null\n private _sessionIdChangedHandlers: SessionIdChangedCallback[] = []\n private readonly _sessionTimeoutMs: number\n\n // we track activity so we can end the session proactively when it has passed the idle timeout\n private _enforceIdleTimeout: ReturnType<typeof setTimeout> | undefined\n\n private _beforeUnloadListener: (() => void) | undefined = undefined\n\n private _eventEmitter: SimpleEventEmitter = new SimpleEventEmitter()\n public on(event: 'forcedIdleReset', handler: () => void): () => void {\n return this._eventEmitter.on(event, handler)\n }\n\n constructor(instance: PostHog, sessionIdGenerator?: () => string, windowIdGenerator?: () => string) {\n if (!instance.persistence) {\n throw new Error('SessionIdManager requires a PostHogPersistence instance')\n }\n if (instance.config.cookieless_mode === 'always') {\n throw new Error('SessionIdManager cannot be used with cookieless_mode=\"always\"')\n }\n\n this._config = instance.config\n this._persistence = instance.persistence\n this._windowId = undefined\n this._sessionId = undefined\n this._sessionStartTimestamp = null\n this._sessionActivityTimestamp = null\n this._sessionIdGenerator = sessionIdGenerator || uuidv7\n this._windowIdGenerator = windowIdGenerator || uuidv7\n\n const persistenceName = this._config['persistence_name'] || this._config['token']\n\n const desiredTimeout = this._config['session_idle_timeout_seconds'] || DEFAULT_SESSION_IDLE_TIMEOUT_SECONDS\n this._sessionTimeoutMs =\n clampToRange(\n desiredTimeout,\n MIN_SESSION_IDLE_TIMEOUT_SECONDS,\n MAX_SESSION_IDLE_TIMEOUT_SECONDS,\n logger.createLogger('session_idle_timeout_seconds'),\n DEFAULT_SESSION_IDLE_TIMEOUT_SECONDS\n ) * 1000\n\n instance.register({ $configured_session_timeout_ms: this._sessionTimeoutMs })\n this._resetIdleTimer()\n\n this._window_id_storage_key = 'ph_' + persistenceName + '_window_id'\n this._primary_window_exists_storage_key = 'ph_' + persistenceName + '_primary_window_exists'\n\n // primary_window_exists is set when the DOM has been loaded and is cleared on unload\n // if it exists here it means there was no unload which suggests this window is opened as a tab duplication, window.open, etc.\n if (this._canUseSessionStorage()) {\n const lastWindowId = sessionStore._parse(this._window_id_storage_key)\n\n const primaryWindowExists = sessionStore._parse(this._primary_window_exists_storage_key)\n if (lastWindowId && !primaryWindowExists) {\n // Persist window from previous storage state\n this._windowId = lastWindowId\n } else {\n // Wipe any reference to previous window id\n sessionStore._remove(this._window_id_storage_key)\n }\n // Flag this session as having a primary window\n sessionStore._set(this._primary_window_exists_storage_key, true)\n }\n\n if (this._config.bootstrap?.sessionID) {\n try {\n const sessionStartTimestamp = uuid7ToTimestampMs(this._config.bootstrap.sessionID)\n this._setSessionId(this._config.bootstrap.sessionID, new Date().getTime(), sessionStartTimestamp)\n } catch (e) {\n logger.error('Invalid sessionID in bootstrap', e)\n }\n }\n\n this._listenToReloadWindow()\n }\n\n get sessionTimeoutMs(): number {\n return this._sessionTimeoutMs\n }\n\n onSessionId(callback: SessionIdChangedCallback): () => void {\n // KLUDGE: when running in tests the handlers array was always undefined\n // it's yucky but safe to set it here so that it's always definitely available\n if (isUndefined(this._sessionIdChangedHandlers)) {\n this._sessionIdChangedHandlers = []\n }\n\n this._sessionIdChangedHandlers.push(callback)\n if (this._sessionId) {\n callback(this._sessionId, this._windowId)\n }\n return () => {\n this._sessionIdChangedHandlers = this._sessionIdChangedHandlers.filter((h) => h !== callback)\n }\n }\n\n private _canUseSessionStorage(): boolean {\n // We only want to use sessionStorage if persistence is enabled and not memory storage\n return this._config.persistence !== 'memory' && !this._persistence._disabled && sessionStore._is_supported()\n }\n\n // Note: this tries to store the windowId in sessionStorage. SessionStorage is unique to the current window/tab,\n // and persists page loads/reloads. So it's uniquely suited for storing the windowId. This function also respects\n // when persistence is disabled (by user config) and when sessionStorage is not supported (it *should* be supported on all browsers),\n // and in that case, it falls back to memory (which sadly, won't persist page loads)\n private _setWindowId(windowId: string): void {\n if (windowId !== this._windowId) {\n this._windowId = windowId\n if (this._canUseSessionStorage()) {\n sessionStore._set(this._window_id_storage_key, windowId)\n }\n }\n }\n\n private _getWindowId(): string | null {\n if (this._windowId) {\n return this._windowId\n }\n if (this._canUseSessionStorage()) {\n return sessionStore._parse(this._window_id_storage_key)\n }\n // New window id will be generated\n return null\n }\n\n // Note: 'this.persistence.register' can be disabled in the config.\n // In that case, this works by storing sessionId and the timestamp in memory.\n private _setSessionId(\n sessionId: string | null,\n sessionActivityTimestamp: number | null,\n sessionStartTimestamp: number | null\n ): void {\n if (\n sessionId !== this._sessionId ||\n sessionActivityTimestamp !== this._sessionActivityTimestamp ||\n sessionStartTimestamp !== this._sessionStartTimestamp\n ) {\n this._sessionStartTimestamp = sessionStartTimestamp\n this._sessionActivityTimestamp = sessionActivityTimestamp\n this._sessionId = sessionId\n\n this._persistence.register({\n [SESSION_ID]: [sessionActivityTimestamp, sessionId, sessionStartTimestamp],\n })\n }\n }\n\n private _getSessionId(): [number, string, number] {\n // Always read from persistence - it's the source of truth\n // The in-memory cache could become stale (e.g., in a frozen tab scenario where\n // time passes but the cache isn't updated)\n const sessionIdInfo = this._persistence.props[SESSION_ID]\n\n if (isArray(sessionIdInfo) && sessionIdInfo.length === 2) {\n // Storage does not yet have a session start time. Add the last activity timestamp as the start time\n sessionIdInfo.push(sessionIdInfo[0])\n }\n\n return sessionIdInfo || [0, null, 0]\n }\n\n // Resets the session id by setting it to null. On the subsequent call to checkAndGetSessionAndWindowId,\n // new ids will be generated.\n resetSessionId(): void {\n this._setSessionId(null, null, null)\n }\n\n /**\n * Cleans up resources used by SessionIdManager.\n * Should be called when the SessionIdManager is no longer needed to prevent memory leaks.\n */\n destroy(): void {\n // Clear the idle timeout timer\n clearTimeout(this._enforceIdleTimeout)\n this._enforceIdleTimeout = undefined\n\n // Remove the beforeunload event listener\n if (this._beforeUnloadListener && window) {\n window.removeEventListener('beforeunload', this._beforeUnloadListener, { capture: false } as any)\n this._beforeUnloadListener = undefined\n }\n\n // Clear session id changed handlers\n this._sessionIdChangedHandlers = []\n }\n\n /*\n * Listens to window unloads and removes the primaryWindowExists key from sessionStorage.\n * Reloaded or fresh tabs created after a DOM unloads (reloading the same tab) WILL NOT have this primaryWindowExists flag in session storage.\n * Cloned sessions (new tab, tab duplication, window.open(), ...) WILL have this primaryWindowExists flag in their copied session storage.\n * We conditionally check the primaryWindowExists value in the constructor to decide if the window id in the last session storage should be carried over.\n */\n private _listenToReloadWindow(): void {\n this._beforeUnloadListener = () => {\n if (this._canUseSessionStorage()) {\n sessionStore._remove(this._primary_window_exists_storage_key)\n }\n }\n addEventListener(window, 'beforeunload', this._beforeUnloadListener, { capture: false })\n }\n\n private _sessionHasBeenIdleTooLong = (timestamp: number, lastActivityTimestamp: number) => {\n return Math.abs(timestamp - lastActivityTimestamp) > this.sessionTimeoutMs\n }\n\n /*\n * This function returns the current sessionId and windowId. It should be used to\n * access these values over directly calling `._sessionId` or `._windowId`.\n * In addition to returning the sessionId and windowId, this function also manages cycling the\n * sessionId and windowId when appropriate by doing the following:\n *\n * 1. If the sessionId or windowId is not set, it will generate a new one and store it.\n * 2. If the readOnly param is set to false, it will:\n * a. Check if it has been > SESSION_CHANGE_THRESHOLD since the last call with this flag set.\n * If so, it will generate a new sessionId and store it.\n * b. Update the timestamp stored with the sessionId to ensure the current session is extended\n * for the appropriate amount of time.\n *\n * @param {boolean} readOnly (optional) Defaults to False. Should be set to True when the call to the function should not extend or cycle the session (e.g. being called for non-user generated events)\n * @param {Number} timestamp (optional) Defaults to the current time. The timestamp to be stored with the sessionId (used when determining if a new sessionId should be generated)\n */\n checkAndGetSessionAndWindowId(readOnly = false, _timestamp: number | null = null) {\n if (this._config.cookieless_mode === 'always') {\n throw new Error('checkAndGetSessionAndWindowId should not be called with cookieless_mode=\"always\"')\n }\n const timestamp = _timestamp || new Date().getTime()\n\n // eslint-disable-next-line prefer-const\n let [lastActivityTimestamp, sessionId, startTimestamp] = this._getSessionId()\n let windowId = this._getWindowId()\n\n const sessionPastMaximumLength =\n isNumber(startTimestamp) &&\n startTimestamp > 0 &&\n Math.abs(timestamp - startTimestamp) > SESSION_LENGTH_LIMIT_MILLISECONDS\n\n let valuesChanged = false\n const noSessionId = !sessionId\n const activityTimeout =\n !noSessionId && !readOnly && this._sessionHasBeenIdleTooLong(timestamp, lastActivityTimestamp)\n if (noSessionId || activityTimeout || sessionPastMaximumLength) {\n sessionId = this._sessionIdGenerator()\n windowId = this._windowIdGenerator()\n logger.info('new session ID generated', {\n sessionId,\n windowId,\n changeReason: { noSessionId, activityTimeout, sessionPastMaximumLength },\n })\n startTimestamp = timestamp\n valuesChanged = true\n } else if (!windowId) {\n windowId = this._windowIdGenerator()\n valuesChanged = true\n }\n\n const newActivityTimestamp =\n lastActivityTimestamp === 0 || !readOnly || sessionPastMaximumLength ? timestamp : lastActivityTimestamp\n const sessionStartTimestamp = startTimestamp === 0 ? new Date().getTime() : startTimestamp\n\n this._setWindowId(windowId)\n this._setSessionId(sessionId, newActivityTimestamp, sessionStartTimestamp)\n\n if (!readOnly) {\n this._resetIdleTimer()\n }\n\n if (valuesChanged) {\n this._sessionIdChangedHandlers.forEach((handler) =>\n handler(\n sessionId,\n windowId,\n valuesChanged ? { noSessionId, activityTimeout, sessionPastMaximumLength } : undefined\n )\n )\n }\n\n return {\n sessionId,\n windowId,\n sessionStartTimestamp,\n changeReason: valuesChanged ? { noSessionId, activityTimeout, sessionPastMaximumLength } : undefined,\n lastActivityTimestamp: lastActivityTimestamp,\n }\n }\n\n private _resetIdleTimer() {\n clearTimeout(this._enforceIdleTimeout)\n this._enforceIdleTimeout = setTimeout(() => {\n // enforce idle timeout a little after the session timeout to ensure the session is reset even without activity\n // we need to check session activity first in case a different window has kept the session active\n // while this window has been idle - and the timer has not progressed - e.g. window memory frozen while hidden\n const [lastActivityTimestamp] = this._getSessionId()\n if (this._sessionHasBeenIdleTooLong(new Date().getTime(), lastActivityTimestamp)) {\n const idleSessionId = this._sessionId\n this.resetSessionId()\n this._eventEmitter.emit('forcedIdleReset', { idleSessionId })\n }\n }, this.sessionTimeoutMs * 1.1)\n }\n}\n","import { PostHog } from './posthog-core'\nimport { CaptureResult, Properties, RemoteConfig, SiteApp, SiteAppGlobals, SiteAppLoader } from './types'\nimport { assignableWindow } from './utils/globals'\nimport { createLogger } from './utils/logger'\n\nconst logger = createLogger('[SiteApps]')\n\nexport class SiteApps {\n apps: Record<string, SiteApp>\n\n private _stopBuffering?: () => void\n private _bufferedInvocations: SiteAppGlobals[]\n\n constructor(private _instance: PostHog) {\n // events captured between loading posthog-js and the site app; up to 1000 events\n this._bufferedInvocations = []\n this.apps = {}\n }\n\n public get isEnabled(): boolean {\n return !!this._instance.config.opt_in_site_apps\n }\n\n private _eventCollector(_eventName: string, eventPayload?: CaptureResult | undefined) {\n if (!eventPayload) {\n return\n }\n const globals = this.globalsForEvent(eventPayload)\n this._bufferedInvocations.push(globals)\n if (this._bufferedInvocations.length > 1000) {\n this._bufferedInvocations = this._bufferedInvocations.slice(10)\n }\n }\n\n get siteAppLoaders(): SiteAppLoader[] | undefined {\n return assignableWindow._POSTHOG_REMOTE_CONFIG?.[this._instance.config.token]?.siteApps\n }\n\n init() {\n if (this.isEnabled) {\n const stop = this._instance._addCaptureHook(this._eventCollector.bind(this))\n this._stopBuffering = () => {\n stop()\n this._bufferedInvocations = []\n this._stopBuffering = undefined\n }\n }\n }\n\n globalsForEvent(event: CaptureResult): SiteAppGlobals {\n if (!event) {\n throw new Error('Event payload is required')\n }\n const groups: SiteAppGlobals['groups'] = {}\n const groupIds = this._instance.get_property('$groups') || []\n const groupProperties: Record<string, Properties> =\n this._instance.get_property('$stored_group_properties') || {}\n for (const [type, properties] of Object.entries(groupProperties)) {\n groups[type] = { id: groupIds[type], type, properties }\n }\n const { $set_once, $set, ..._event } = event\n const globals = {\n event: {\n ..._event,\n properties: {\n ...event.properties,\n ...($set ? { $set: { ...(event.properties?.$set ?? {}), ...$set } } : {}),\n ...($set_once ? { $set_once: { ...(event.properties?.$set_once ?? {}), ...$set_once } } : {}),\n },\n elements_chain: event.properties?.['$elements_chain'] ?? '',\n // TODO:\n // - elements_chain_href: '',\n // - elements_chain_texts: [] as string[],\n // - elements_chain_ids: [] as string[],\n // - elements_chain_elements: [] as string[],\n distinct_id: event.properties?.['distinct_id'],\n },\n person: {\n properties: this._instance.get_property('$stored_person_properties'),\n },\n groups,\n }\n return globals\n }\n\n setupSiteApp(loader: SiteAppLoader) {\n const app = this.apps[loader.id]\n const processBufferedEvents = () => {\n if (!app.errored && this._bufferedInvocations.length) {\n logger.info(`Processing ${this._bufferedInvocations.length} events for site app with id ${loader.id}`)\n this._bufferedInvocations.forEach((globals) => app.processEvent?.(globals))\n app.processedBuffer = true\n }\n\n if (Object.values(this.apps).every((app) => app.processedBuffer || app.errored)) {\n this._stopBuffering?.()\n }\n }\n\n let hasInitReturned = false\n const onLoaded = (success: boolean) => {\n app.errored = !success\n app.loaded = true\n logger.info(`Site app with id ${loader.id} ${success ? 'loaded' : 'errored'}`)\n // ensure that we don't call processBufferedEvents until after init() returns and we've set up processEvent\n if (hasInitReturned) {\n processBufferedEvents()\n }\n }\n\n try {\n const { processEvent } = loader.init({\n posthog: this._instance,\n callback: (success) => {\n onLoaded(success)\n },\n })\n if (processEvent) {\n app.processEvent = processEvent\n }\n hasInitReturned = true\n } catch (e) {\n logger.error(`Error while initializing PostHog app with config id ${loader.id}`, e)\n onLoaded(false)\n }\n\n // if the app loaded synchronously, process the events now\n if (hasInitReturned && app.loaded) {\n try {\n processBufferedEvents()\n } catch (e) {\n logger.error(`Error while processing buffered events PostHog app with config id ${loader.id}`, e)\n app.errored = true\n }\n }\n }\n\n private _setupSiteApps() {\n const siteAppLoaders = this.siteAppLoaders || []\n\n // do this in 2 passes, so that this.apps is populated before we call init\n for (const loader of siteAppLoaders) {\n this.apps[loader.id] = {\n id: loader.id,\n loaded: false,\n errored: false,\n processedBuffer: false,\n }\n }\n for (const loader of siteAppLoaders) {\n this.setupSiteApp(loader)\n }\n }\n\n private _onCapturedEvent(event: CaptureResult) {\n if (Object.keys(this.apps).length === 0) {\n return\n }\n\n const globals = this.globalsForEvent(event)\n\n for (const app of Object.values(this.apps)) {\n try {\n app.processEvent?.(globals)\n } catch (e) {\n logger.error(`Error while processing event ${event.event} for site app ${app.id}`, e)\n }\n }\n }\n\n onRemoteConfig(response: RemoteConfig): void {\n if (this.siteAppLoaders?.length) {\n if (!this.isEnabled) {\n logger.error(`PostHog site apps are disabled. Enable the \"opt_in_site_apps\" config to proceed.`)\n return\n }\n\n this._setupSiteApps()\n\n // NOTE: We could improve this to only fire if we actually have listeners for the event\n this._instance.on('eventCaptured', (event) => this._onCapturedEvent(event))\n\n return\n }\n\n // NOTE: Below this is now only the fallback for legacy site app support. Once we have fully removed to the remote config loader we can get rid of this\n\n this._stopBuffering?.()\n\n if (!response['siteApps']?.length) {\n return\n }\n\n if (!this.isEnabled) {\n logger.error(`PostHog site apps are disabled. Enable the \"opt_in_site_apps\" config to proceed.`)\n return\n }\n\n for (const { id, url } of response['siteApps']) {\n assignableWindow[`__$$ph_site_app_${id}`] = this._instance\n assignableWindow.__PosthogExtensions__?.loadSiteApp?.(this._instance, url, (err) => {\n if (err) {\n return logger.error(`Error while initializing PostHog app with config id ${id}`, err)\n }\n })\n }\n }\n}\n","// Re-export shared bot detection logic from @posthog/core\nimport { isBlockedUA as isBlockedUACore } from '@posthog/core'\nexport { DEFAULT_BLOCKED_UA_STRS, isBlockedUA } from '@posthog/core'\n\n// There's more in the type, but this is all we use. It's currently experimental, see\n// https://developer.mozilla.org/en-US/docs/Web/API/Navigator/userAgentData\n// if you're reading this in the future, when it's no longer experimental, please remove this type and use an official one.\n// Be extremely defensive here to ensure backwards and *forwards* compatibility, and remove this defensiveness in the\n// future when it is safe to do so.\nexport interface NavigatorUAData {\n brands?: {\n brand: string\n version: string\n }[]\n}\ndeclare global {\n interface Navigator {\n userAgentData?: NavigatorUAData\n }\n}\n\nexport const isLikelyBot = function (navigator: Navigator | undefined, customBlockedUserAgents: string[]): boolean {\n if (!navigator) {\n return false\n }\n const ua = navigator.userAgent\n if (ua) {\n if (isBlockedUACore(ua, customBlockedUserAgents)) {\n return true\n }\n }\n try {\n // eslint-disable-next-line compat/compat\n const uaData = navigator?.userAgentData as NavigatorUAData\n if (\n uaData?.brands &&\n uaData.brands.some((brandObj) => isBlockedUACore(brandObj?.brand, customBlockedUserAgents))\n ) {\n return true\n }\n } catch {\n // ignore the error, we were using experimental browser features\n }\n\n return !!navigator.webdriver\n\n // There's some more enhancements we could make in this area, e.g. it's possible to check if Chrome dev tools are\n // open, which will detect some bots that are trying to mask themselves and might get past the checks above.\n // However, this would give false positives for actual humans who have dev tools open.\n\n // We could also use the data in navigator.userAgentData.getHighEntropyValues() to detect bots, but we should wait\n // until this stops being experimental. The MDN docs imply that this might eventually require user permission.\n // See https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData/getHighEntropyValues\n // It would be very bad if posthog-js caused a permission prompt to appear on every page load.\n}\n","import { PostHog } from '../posthog-core'\n\n/**\n * The request router helps simplify the logic to determine which endpoints should be called for which things\n * The basic idea is that for a given region (US or EU), we have a set of endpoints that we should call depending\n * on the type of request (events, replays, flags, etc.) and handle overrides that may come from configs or the flags endpoint\n */\n\nexport enum RequestRouterRegion {\n US = 'us',\n EU = 'eu',\n CUSTOM = 'custom',\n}\n\nexport type RequestRouterTarget = 'api' | 'ui' | 'assets' | 'flags'\n\nconst ingestionDomain = 'i.posthog.com'\n\nexport class RequestRouter {\n instance: PostHog\n private _regionCache: Record<string, RequestRouterRegion> = {}\n\n constructor(instance: PostHog) {\n this.instance = instance\n }\n\n get apiHost(): string {\n const host = this.instance.config.api_host.trim().replace(/\\/$/, '')\n if (host === 'https://app.posthog.com') {\n return 'https://us.i.posthog.com'\n }\n return host\n }\n\n get flagsApiHost(): string {\n const customHost = this.instance.config.flags_api_host\n if (customHost) {\n return customHost.trim().replace(/\\/$/, '')\n }\n // Backwards compatibility: if no custom flags_api_host is set, fall back to the regular apiHost\n return this.apiHost\n }\n\n get uiHost(): string | undefined {\n let host = this.instance.config.ui_host?.replace(/\\/$/, '')\n\n if (!host) {\n // No ui_host set, get it from the api_host. But api_host differs\n // from the actual UI host, so replace the ingestion subdomain with just posthog.com\n host = this.apiHost.replace(`.${ingestionDomain}`, '.posthog.com')\n }\n\n if (host === 'https://app.posthog.com') {\n return 'https://us.posthog.com'\n }\n\n return host\n }\n\n get region(): RequestRouterRegion {\n // We don't need to compute this every time so we cache the result\n if (!this._regionCache[this.apiHost]) {\n if (/https:\\/\\/(app|us|us-assets)(\\.i)?\\.posthog\\.com/i.test(this.apiHost)) {\n this._regionCache[this.apiHost] = RequestRouterRegion.US\n } else if (/https:\\/\\/(eu|eu-assets)(\\.i)?\\.posthog\\.com/i.test(this.apiHost)) {\n this._regionCache[this.apiHost] = RequestRouterRegion.EU\n } else {\n this._regionCache[this.apiHost] = RequestRouterRegion.CUSTOM\n }\n }\n return this._regionCache[this.apiHost]\n }\n\n endpointFor(target: RequestRouterTarget, path: string = ''): string {\n if (path) {\n path = path[0] === '/' ? path : `/${path}`\n }\n\n if (target === 'ui') {\n return this.uiHost + path\n }\n\n if (target === 'flags') {\n return this.flagsApiHost + path\n }\n\n if (this.region === RequestRouterRegion.CUSTOM) {\n return this.apiHost + path\n }\n\n const suffix = ingestionDomain + path\n\n switch (target) {\n case 'assets':\n return `https://${this.region}-assets.${suffix}`\n case 'api':\n return `https://${this.region}.${suffix}`\n }\n }\n}\n","import { PostHog } from './posthog-core'\nimport { navigator, window } from './utils/globals'\nimport {\n WebExperiment,\n WebExperimentsCallback,\n WebExperimentTransform,\n WebExperimentUrlMatchType,\n WebExperimentVariant,\n} from './web-experiments-types'\nimport { WEB_EXPERIMENTS } from './constants'\nimport { isNullish, isString } from '@posthog/core'\nimport { getQueryParam } from './utils/request-utils'\nimport { isMatchingRegex } from './utils/regex-utils'\nimport { logger } from './utils/logger'\nimport { isLikelyBot } from './utils/blocked-uas'\nimport { getCampaignParams } from './utils/event-utils'\n\nexport const webExperimentUrlValidationMap: Record<\n WebExperimentUrlMatchType,\n (conditionsUrl: string, location: Location) => boolean\n> = {\n icontains: (conditionsUrl, location) =>\n !!window && location.href.toLowerCase().indexOf(conditionsUrl.toLowerCase()) > -1,\n not_icontains: (conditionsUrl, location) =>\n !!window && location.href.toLowerCase().indexOf(conditionsUrl.toLowerCase()) === -1,\n regex: (conditionsUrl, location) => !!window && isMatchingRegex(location.href, conditionsUrl),\n not_regex: (conditionsUrl, location) => !!window && !isMatchingRegex(location.href, conditionsUrl),\n exact: (conditionsUrl, location) => location.href === conditionsUrl,\n is_not: (conditionsUrl, location) => location.href !== conditionsUrl,\n}\n\nexport class WebExperiments {\n private _flagToExperiments?: Map<string, WebExperiment>\n\n constructor(private _instance: PostHog) {\n this._instance.onFeatureFlags((flags: string[]) => {\n this.onFeatureFlags(flags)\n })\n }\n\n onFeatureFlags(flags: string[]) {\n if (this._is_bot()) {\n WebExperiments._logInfo('Refusing to render web experiment since the viewer is a likely bot')\n return\n }\n\n if (this._instance.config.disable_web_experiments) {\n return\n }\n\n if (isNullish(this._flagToExperiments)) {\n // Indicates first load so we trigger the loaders\n this._flagToExperiments = new Map<string, WebExperiment>()\n this.loadIfEnabled()\n this.previewWebExperiment()\n return\n }\n\n WebExperiments._logInfo('applying feature flags', flags)\n flags.forEach((flag) => {\n if (this._flagToExperiments && this._flagToExperiments?.has(flag)) {\n const selectedVariant = this._instance.getFeatureFlag(flag) as unknown as string\n const webExperiment = this._flagToExperiments?.get(flag)\n if (selectedVariant && webExperiment?.variants[selectedVariant]) {\n this._applyTransforms(\n webExperiment.name,\n selectedVariant,\n webExperiment.variants[selectedVariant].transforms\n )\n }\n }\n })\n }\n\n previewWebExperiment() {\n const location = WebExperiments.getWindowLocation()\n if (location?.search) {\n const experimentID = getQueryParam(location?.search, '__experiment_id')\n const variant = getQueryParam(location?.search, '__experiment_variant')\n if (experimentID && variant) {\n WebExperiments._logInfo(`previewing web experiments ${experimentID} && ${variant}`)\n this.getWebExperiments(\n (webExperiments) => {\n this._showPreviewWebExperiment(parseInt(experimentID), variant, webExperiments)\n },\n false,\n true\n )\n }\n }\n }\n\n loadIfEnabled() {\n if (this._instance.config.disable_web_experiments) {\n return\n }\n\n this.getWebExperimentsAndEvaluateDisplayLogic()\n }\n\n public getWebExperimentsAndEvaluateDisplayLogic = (forceReload: boolean = false): void => {\n this.getWebExperiments((webExperiments) => {\n WebExperiments._logInfo(`retrieved web experiments from the server`)\n this._flagToExperiments = new Map<string, WebExperiment>()\n\n webExperiments.forEach((webExperiment) => {\n if (webExperiment.feature_flag_key) {\n if (this._flagToExperiments) {\n WebExperiments._logInfo(\n `setting flag key `,\n webExperiment.feature_flag_key,\n ` to web experiment `,\n webExperiment\n )\n this._flagToExperiments?.set(webExperiment.feature_flag_key, webExperiment)\n }\n\n const selectedVariant = this._instance.getFeatureFlag(webExperiment.feature_flag_key)\n if (isString(selectedVariant) && webExperiment.variants[selectedVariant]) {\n this._applyTransforms(\n webExperiment.name,\n selectedVariant,\n webExperiment.variants[selectedVariant].transforms\n )\n }\n } else if (webExperiment.variants) {\n for (const variant in webExperiment.variants) {\n const testVariant = webExperiment.variants[variant]\n const matchTest = WebExperiments._matchesTestVariant(testVariant)\n if (matchTest) {\n this._applyTransforms(webExperiment.name, variant, testVariant.transforms)\n }\n }\n }\n })\n }, forceReload)\n }\n\n public getWebExperiments(callback: WebExperimentsCallback, forceReload: boolean, previewing?: boolean) {\n if (this._instance.config.disable_web_experiments && !previewing) {\n return callback([])\n }\n\n const existingWebExperiments = this._instance.get_property(WEB_EXPERIMENTS)\n if (existingWebExperiments && !forceReload) {\n return callback(existingWebExperiments)\n }\n\n this._instance._send_request({\n url: this._instance.requestRouter.endpointFor(\n 'api',\n `/api/web_experiments/?token=${this._instance.config.token}`\n ),\n method: 'GET',\n callback: (response) => {\n if (response.statusCode !== 200 || !response.json) {\n return callback([])\n }\n const webExperiments = response.json.experiments || []\n return callback(webExperiments)\n },\n })\n }\n\n private _showPreviewWebExperiment(experimentID: number, variant: string, webExperiments: WebExperiment[]) {\n const previewExperiments = webExperiments.filter((exp) => exp.id === experimentID)\n if (previewExperiments && previewExperiments.length > 0) {\n WebExperiments._logInfo(\n `Previewing web experiment [${previewExperiments[0].name}] with variant [${variant}]`\n )\n this._applyTransforms(\n previewExperiments[0].name,\n variant,\n previewExperiments[0].variants[variant].transforms\n )\n }\n }\n private static _matchesTestVariant(testVariant: WebExperimentVariant) {\n if (isNullish(testVariant.conditions)) {\n return false\n }\n return WebExperiments._matchUrlConditions(testVariant) && WebExperiments._matchUTMConditions(testVariant)\n }\n\n private static _matchUrlConditions(testVariant: WebExperimentVariant): boolean {\n if (isNullish(testVariant.conditions) || isNullish(testVariant.conditions?.url)) {\n return true\n }\n\n const location = WebExperiments.getWindowLocation()\n if (location) {\n const urlCheck = testVariant.conditions?.url\n ? webExperimentUrlValidationMap[testVariant.conditions?.urlMatchType ?? 'icontains'](\n testVariant.conditions.url,\n location\n )\n : true\n return urlCheck\n }\n\n return false\n }\n\n public static getWindowLocation(): Location | undefined {\n return window?.location\n }\n\n private static _matchUTMConditions(testVariant: WebExperimentVariant): boolean {\n if (isNullish(testVariant.conditions) || isNullish(testVariant.conditions?.utm)) {\n return true\n }\n const campaignParams = getCampaignParams()\n if (campaignParams['utm_source']) {\n // eslint-disable-next-line compat/compat\n const utmCampaignMatched = testVariant.conditions?.utm?.utm_campaign\n ? testVariant.conditions?.utm?.utm_campaign == campaignParams['utm_campaign']\n : true\n\n const utmSourceMatched = testVariant.conditions?.utm?.utm_source\n ? testVariant.conditions?.utm?.utm_source == campaignParams['utm_source']\n : true\n\n const utmMediumMatched = testVariant.conditions?.utm?.utm_medium\n ? testVariant.conditions?.utm?.utm_medium == campaignParams['utm_medium']\n : true\n\n const utmTermMatched = testVariant.conditions?.utm?.utm_term\n ? testVariant.conditions?.utm?.utm_term == campaignParams['utm_term']\n : true\n\n return utmCampaignMatched && utmMediumMatched && utmTermMatched && utmSourceMatched\n }\n\n return false\n }\n\n private static _logInfo(msg: string, ...args: any[]) {\n logger.info(`[WebExperiments] ${msg}`, args)\n }\n\n private _applyTransforms(experiment: string, variant: string, transforms: WebExperimentTransform[]) {\n if (this._is_bot()) {\n WebExperiments._logInfo('Refusing to render web experiment since the viewer is a likely bot')\n return\n }\n\n if (variant === 'control') {\n WebExperiments._logInfo('Control variants leave the page unmodified.')\n return\n }\n\n transforms.forEach((transform) => {\n if (transform.selector) {\n WebExperiments._logInfo(\n `applying transform of variant ${variant} for experiment ${experiment} `,\n transform\n )\n\n // eslint-disable-next-line no-restricted-globals\n const elements = document?.querySelectorAll(transform.selector)\n elements?.forEach((element) => {\n const htmlElement = element as HTMLElement\n if (transform.html) {\n htmlElement.innerHTML = transform.html\n }\n\n if (transform.css) {\n htmlElement.setAttribute('style', transform.css)\n }\n })\n }\n })\n }\n\n _is_bot(): boolean | undefined {\n if (navigator && this._instance) {\n return isLikelyBot(navigator, this._instance.config.custom_blocked_useragents)\n } else {\n return undefined\n }\n }\n}\n","import { PostHog } from '../posthog-core'\nimport { ExternalIntegrationKind } from '../types'\nimport { assignableWindow, ExternalExtensionKind } from '../utils/globals'\nimport { createLogger } from '../utils/logger'\n\nconst logger = createLogger('[PostHog ExternalIntegrations]')\n\nconst MAPPED_INTEGRATIONS: Record<ExternalIntegrationKind, ExternalExtensionKind> = {\n intercom: 'intercom-integration',\n crispChat: 'crisp-chat-integration',\n}\n\nexport class ExternalIntegrations {\n constructor(private readonly _instance: PostHog) {}\n\n private _loadScript(name: ExternalExtensionKind, cb: () => void): void {\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(this._instance, name, (err) => {\n if (err) {\n return logger.error('failed to load script', err)\n }\n cb()\n })\n }\n\n public startIfEnabledOrStop() {\n for (const [key, value] of Object.entries(this._instance.config.integrations ?? {})) {\n // if the integration is enabled, and not present, then load it\n if (value && !assignableWindow.__PosthogExtensions__?.integrations?.[key as ExternalIntegrationKind]) {\n this._loadScript(MAPPED_INTEGRATIONS[key as ExternalIntegrationKind], () => {\n assignableWindow.__PosthogExtensions__?.integrations?.[key as ExternalIntegrationKind]?.start(\n this._instance\n )\n })\n }\n // if the integration is disabled, and present, then stop it\n if (!value && assignableWindow.__PosthogExtensions__?.integrations?.[key as ExternalIntegrationKind]) {\n assignableWindow.__PosthogExtensions__?.integrations?.[key as ExternalIntegrationKind]?.stop()\n }\n }\n }\n}\n","import {\n SESSION_RECORDING_EVENT_TRIGGER_ACTIVATED_SESSION,\n SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION,\n} from '../../../constants'\nimport { PostHog } from '../../../posthog-core'\nimport { FlagVariant, RemoteConfig, SessionRecordingPersistedConfig, SessionRecordingUrlTrigger } from '../../../types'\nimport { isNullish, isBoolean, isString, isObject } from '@posthog/core'\nimport { window } from '../../../utils/globals'\n\nexport const DISABLED = 'disabled'\nexport const SAMPLED = 'sampled'\nexport const ACTIVE = 'active'\nexport const BUFFERING = 'buffering'\nexport const PAUSED = 'paused'\nexport const LAZY_LOADING = 'lazy_loading'\n\nconst TRIGGER = 'trigger'\nexport const TRIGGER_ACTIVATED = TRIGGER + '_activated'\nexport const TRIGGER_PENDING = TRIGGER + '_pending'\nexport const TRIGGER_DISABLED = TRIGGER + '_' + DISABLED\n\nexport interface RecordingTriggersStatus {\n get receivedFlags(): boolean\n get isRecordingEnabled(): false | true | undefined\n get isSampled(): false | true | null\n get urlTriggerMatching(): URLTriggerMatching\n get eventTriggerMatching(): EventTriggerMatching\n get linkedFlagMatching(): LinkedFlagMatching\n get sessionId(): string\n}\n\nexport type TriggerType = 'url' | 'event'\n/* \ntriggers can have one of three statuses:\n * - trigger_activated: the trigger met conditions to start recording\n * - trigger_pending: the trigger is present, but the conditions are not yet met\n * - trigger_disabled: the trigger is not present\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst triggerStatuses = [TRIGGER_ACTIVATED, TRIGGER_PENDING, TRIGGER_DISABLED] as const\nexport type TriggerStatus = (typeof triggerStatuses)[number]\n\n/**\n * Session recording starts in buffering mode while waiting for \"flags response\".\n * Once the response is received, it might be disabled, active or sampled.\n * When \"sampled\" that means a sample rate is set, and the last time the session ID rotated\n * the sample rate determined this session should be sent to the server.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst sessionRecordingStatuses = [DISABLED, SAMPLED, ACTIVE, BUFFERING, PAUSED, LAZY_LOADING] as const\nexport type SessionRecordingStatus = (typeof sessionRecordingStatuses)[number]\n\n// while we have both lazy and eager loaded replay we might get either type of config\ntype ReplayConfigType = RemoteConfig | SessionRecordingPersistedConfig\n\nfunction sessionRecordingUrlTriggerMatches(url: string, triggers: SessionRecordingUrlTrigger[]) {\n return triggers.some((trigger) => {\n switch (trigger.matching) {\n case 'regex':\n return new RegExp(trigger.url).test(url)\n default:\n return false\n }\n })\n}\n\nexport interface TriggerStatusMatching {\n triggerStatus(sessionId: string): TriggerStatus\n stop(): void\n}\nexport class OrTriggerMatching implements TriggerStatusMatching {\n constructor(private readonly _matchers: TriggerStatusMatching[]) {}\n\n triggerStatus(sessionId: string): TriggerStatus {\n const statuses = this._matchers.map((m) => m.triggerStatus(sessionId))\n if (statuses.includes(TRIGGER_ACTIVATED)) {\n return TRIGGER_ACTIVATED\n }\n if (statuses.includes(TRIGGER_PENDING)) {\n return TRIGGER_PENDING\n }\n return TRIGGER_DISABLED\n }\n\n stop(): void {\n this._matchers.forEach((m) => m.stop())\n }\n}\n\nexport class AndTriggerMatching implements TriggerStatusMatching {\n constructor(private readonly _matchers: TriggerStatusMatching[]) {}\n\n triggerStatus(sessionId: string): TriggerStatus {\n const statuses = new Set<TriggerStatus>()\n for (const matcher of this._matchers) {\n statuses.add(matcher.triggerStatus(sessionId))\n }\n\n // trigger_disabled means no config\n statuses.delete(TRIGGER_DISABLED)\n switch (statuses.size) {\n case 0:\n return TRIGGER_DISABLED\n case 1:\n return Array.from(statuses)[0]\n default:\n return TRIGGER_PENDING\n }\n }\n\n stop(): void {\n this._matchers.forEach((m) => m.stop())\n }\n}\n\nexport class PendingTriggerMatching implements TriggerStatusMatching {\n triggerStatus(): TriggerStatus {\n return TRIGGER_PENDING\n }\n\n stop(): void {\n // no-op\n }\n}\n\nconst isEagerLoadedConfig = (x: ReplayConfigType): x is RemoteConfig => {\n return 'sessionRecording' in x\n}\n\nexport class URLTriggerMatching implements TriggerStatusMatching {\n _urlTriggers: SessionRecordingUrlTrigger[] = []\n _urlBlocklist: SessionRecordingUrlTrigger[] = []\n\n urlBlocked: boolean = false\n\n constructor(private readonly _instance: PostHog) {}\n\n onConfig(config: ReplayConfigType) {\n this._urlTriggers =\n (isEagerLoadedConfig(config)\n ? isObject(config.sessionRecording)\n ? config.sessionRecording?.urlTriggers\n : []\n : config?.urlTriggers) || []\n this._urlBlocklist =\n (isEagerLoadedConfig(config)\n ? isObject(config.sessionRecording)\n ? config.sessionRecording?.urlBlocklist\n : []\n : config?.urlBlocklist) || []\n }\n\n /**\n * @deprecated Use onConfig instead\n */\n onRemoteConfig(response: RemoteConfig) {\n this.onConfig(response)\n }\n\n private _urlTriggerStatus(sessionId: string): TriggerStatus {\n if (this._urlTriggers.length === 0) {\n return TRIGGER_DISABLED\n }\n\n const currentTriggerSession = this._instance?.get_property(SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION)\n return currentTriggerSession === sessionId ? TRIGGER_ACTIVATED : TRIGGER_PENDING\n }\n\n triggerStatus(sessionId: string): TriggerStatus {\n const urlTriggerStatus = this._urlTriggerStatus(sessionId)\n const eitherIsActivated = urlTriggerStatus === TRIGGER_ACTIVATED\n const eitherIsPending = urlTriggerStatus === TRIGGER_PENDING\n\n const result = eitherIsActivated ? TRIGGER_ACTIVATED : eitherIsPending ? TRIGGER_PENDING : TRIGGER_DISABLED\n this._instance.register_for_session({\n $sdk_debug_replay_url_trigger_status: result,\n })\n return result\n }\n\n checkUrlTriggerConditions(\n onPause: () => void,\n onResume: () => void,\n onActivate: (triggerType: TriggerType) => void,\n sessionId: string\n ) {\n if (typeof window === 'undefined' || !window.location.href) {\n return\n }\n\n const url = window.location.href\n\n const wasBlocked = this.urlBlocked\n const isNowBlocked = sessionRecordingUrlTriggerMatches(url, this._urlBlocklist)\n\n if (wasBlocked && isNowBlocked) {\n return\n }\n\n if (isNowBlocked && !wasBlocked) {\n onPause()\n } else if (!isNowBlocked && wasBlocked) {\n onResume()\n }\n\n const isActivated = this._urlTriggerStatus(sessionId) === TRIGGER_ACTIVATED\n const urlMatches = sessionRecordingUrlTriggerMatches(url, this._urlTriggers)\n\n if (!isActivated && urlMatches) {\n onActivate('url')\n }\n }\n\n stop(): void {\n // no-op\n }\n}\n\nexport class LinkedFlagMatching implements TriggerStatusMatching {\n linkedFlag: string | FlagVariant | null = null\n linkedFlagSeen: boolean = false\n private _flagListenerCleanup: () => void = () => {}\n constructor(private readonly _instance: PostHog) {}\n\n triggerStatus(): TriggerStatus {\n let result = TRIGGER_PENDING\n if (isNullish(this.linkedFlag)) {\n result = TRIGGER_DISABLED\n }\n if (this.linkedFlagSeen) {\n result = TRIGGER_ACTIVATED\n }\n this._instance.register_for_session({\n $sdk_debug_replay_linked_flag_trigger_status: result,\n })\n return result\n }\n\n onConfig(config: ReplayConfigType, onStarted: (flag: string, variant: string | null) => void) {\n this.linkedFlag =\n (isEagerLoadedConfig(config)\n ? isObject(config.sessionRecording)\n ? config.sessionRecording?.linkedFlag\n : null\n : config?.linkedFlag) || null\n\n if (!isNullish(this.linkedFlag) && !this.linkedFlagSeen) {\n const linkedFlag = isString(this.linkedFlag) ? this.linkedFlag : this.linkedFlag.flag\n const linkedVariant = isString(this.linkedFlag) ? null : this.linkedFlag.variant\n this._flagListenerCleanup = this._instance.onFeatureFlags((_flags, variants) => {\n const flagIsPresent = isObject(variants) && linkedFlag in variants\n let linkedFlagMatches = false\n if (flagIsPresent) {\n const variantForFlagKey = variants[linkedFlag]\n if (isBoolean(variantForFlagKey)) {\n linkedFlagMatches = variantForFlagKey === true\n } else if (linkedVariant) {\n linkedFlagMatches = variantForFlagKey === linkedVariant\n } else {\n // then this is a variant flag and we want to match any string\n linkedFlagMatches = !!variantForFlagKey\n }\n }\n this.linkedFlagSeen = linkedFlagMatches\n if (linkedFlagMatches) {\n onStarted(linkedFlag, linkedVariant)\n }\n })\n }\n }\n\n /**\n * @deprecated Use onConfig instead\n */\n onRemoteConfig(response: RemoteConfig, onStarted: (flag: string, variant: string | null) => void) {\n this.onConfig(response, onStarted)\n }\n\n stop(): void {\n this._flagListenerCleanup()\n }\n}\n\nexport class EventTriggerMatching implements TriggerStatusMatching {\n _eventTriggers: string[] = []\n\n constructor(private readonly _instance: PostHog) {}\n\n onConfig(config: ReplayConfigType) {\n this._eventTriggers =\n (isEagerLoadedConfig(config)\n ? isObject(config.sessionRecording)\n ? config.sessionRecording?.eventTriggers\n : []\n : config?.eventTriggers) || []\n }\n\n /**\n * @deprecated Use onConfig instead\n */\n onRemoteConfig(response: RemoteConfig) {\n this.onConfig(response)\n }\n\n private _eventTriggerStatus(sessionId: string): TriggerStatus {\n if (this._eventTriggers.length === 0) {\n return TRIGGER_DISABLED\n }\n\n const currentTriggerSession = this._instance?.get_property(SESSION_RECORDING_EVENT_TRIGGER_ACTIVATED_SESSION)\n return currentTriggerSession === sessionId ? TRIGGER_ACTIVATED : TRIGGER_PENDING\n }\n\n triggerStatus(sessionId: string): TriggerStatus {\n const eventTriggerStatus = this._eventTriggerStatus(sessionId)\n const result =\n eventTriggerStatus === TRIGGER_ACTIVATED\n ? TRIGGER_ACTIVATED\n : eventTriggerStatus === TRIGGER_PENDING\n ? TRIGGER_PENDING\n : TRIGGER_DISABLED\n this._instance.register_for_session({\n $sdk_debug_replay_event_trigger_status: result,\n })\n return result\n }\n\n stop(): void {\n // no-op\n }\n}\n\n// we need a no-op matcher before we can lazy-load the other matches, since all matchers wait on remote config anyway\nexport function nullMatchSessionRecordingStatus(triggersStatus: RecordingTriggersStatus): SessionRecordingStatus {\n if (!triggersStatus.isRecordingEnabled) {\n return DISABLED\n }\n\n return BUFFERING\n}\n\nexport function anyMatchSessionRecordingStatus(triggersStatus: RecordingTriggersStatus): SessionRecordingStatus {\n if (!triggersStatus.receivedFlags) {\n return BUFFERING\n }\n\n if (!triggersStatus.isRecordingEnabled) {\n return DISABLED\n }\n\n if (triggersStatus.urlTriggerMatching.urlBlocked) {\n return PAUSED\n }\n\n const sampledActive = triggersStatus.isSampled === true\n const triggerMatches = new OrTriggerMatching([\n triggersStatus.eventTriggerMatching,\n triggersStatus.urlTriggerMatching,\n triggersStatus.linkedFlagMatching,\n ]).triggerStatus(triggersStatus.sessionId)\n\n if (sampledActive) {\n return SAMPLED\n }\n\n if (triggerMatches === TRIGGER_ACTIVATED) {\n return ACTIVE\n }\n\n if (triggerMatches === TRIGGER_PENDING) {\n // even if sampled active is false, we should still be buffering\n // since a pending trigger could override it\n return BUFFERING\n }\n\n // if sampling is set and the session is already decided to not be sampled\n // then we should never be active\n if (triggersStatus.isSampled === false) {\n return DISABLED\n }\n\n return ACTIVE\n}\n\nexport function allMatchSessionRecordingStatus(triggersStatus: RecordingTriggersStatus): SessionRecordingStatus {\n if (!triggersStatus.receivedFlags) {\n return BUFFERING\n }\n\n if (!triggersStatus.isRecordingEnabled) {\n return DISABLED\n }\n\n if (triggersStatus.urlTriggerMatching.urlBlocked) {\n return PAUSED\n }\n\n const andTriggerMatch = new AndTriggerMatching([\n triggersStatus.eventTriggerMatching,\n triggersStatus.urlTriggerMatching,\n triggersStatus.linkedFlagMatching,\n ])\n const currentTriggerStatus = andTriggerMatch.triggerStatus(triggersStatus.sessionId)\n const hasTriggersConfigured = currentTriggerStatus !== TRIGGER_DISABLED\n\n const hasSamplingConfigured = isBoolean(triggersStatus.isSampled)\n\n if (hasTriggersConfigured && currentTriggerStatus === TRIGGER_PENDING) {\n return BUFFERING\n }\n\n if (hasTriggersConfigured && currentTriggerStatus === TRIGGER_DISABLED) {\n return DISABLED\n }\n\n // sampling can't ever cause buffering, it's always determined right away or not configured\n if (hasSamplingConfigured && !triggersStatus.isSampled) {\n return DISABLED\n }\n\n // If sampling is configured and set to true, return sampled\n if (triggersStatus.isSampled === true) {\n return SAMPLED\n }\n\n return ACTIVE\n}\n","import {\n SESSION_RECORDING_IS_SAMPLED,\n SESSION_RECORDING_OVERRIDE_SAMPLING,\n SESSION_RECORDING_OVERRIDE_LINKED_FLAG,\n SESSION_RECORDING_OVERRIDE_EVENT_TRIGGER,\n SESSION_RECORDING_OVERRIDE_URL_TRIGGER,\n SESSION_RECORDING_REMOTE_CONFIG,\n} from '../../constants'\nimport { PostHog } from '../../posthog-core'\nimport { Properties, RemoteConfig, SessionRecordingPersistedConfig, SessionStartReason } from '../../types'\nimport { type eventWithTime } from './types/rrweb-types'\n\nimport { isNullish, isUndefined } from '@posthog/core'\nimport { createLogger } from '../../utils/logger'\nimport {\n assignableWindow,\n LazyLoadedSessionRecordingInterface,\n PostHogExtensionKind,\n window,\n} from '../../utils/globals'\nimport { DISABLED, LAZY_LOADING, SessionRecordingStatus, TriggerType } from './external/triggerMatching'\n\nconst LOGGER_PREFIX = '[SessionRecording]'\nconst logger = createLogger(LOGGER_PREFIX)\n\nexport class SessionRecording {\n _forceAllowLocalhostNetworkCapture: boolean = false\n\n private _receivedFlags: boolean = false\n\n private _persistFlagsOnSessionListener: (() => void) | undefined = undefined\n private _lazyLoadedSessionRecording: LazyLoadedSessionRecordingInterface | undefined\n\n public get started(): boolean {\n return !!this._lazyLoadedSessionRecording?.isStarted\n }\n\n /**\n * defaults to buffering mode until a flags response is received\n * once a flags response is received status can be disabled, active or sampled\n */\n get status(): SessionRecordingStatus {\n if (this._lazyLoadedSessionRecording) {\n return this._lazyLoadedSessionRecording.status\n }\n\n if (this._receivedFlags && !this._isRecordingEnabled) {\n return DISABLED\n }\n\n return LAZY_LOADING\n }\n\n constructor(private readonly _instance: PostHog) {\n if (!this._instance.sessionManager) {\n logger.error('started without valid sessionManager')\n throw new Error(LOGGER_PREFIX + ' started without valid sessionManager. This is a bug.')\n }\n\n if (this._instance.config.cookieless_mode === 'always') {\n throw new Error(LOGGER_PREFIX + ' cannot be used with cookieless_mode=\"always\"')\n }\n }\n\n private get _isRecordingEnabled() {\n const enabled_server_side = !!this._instance.get_property(SESSION_RECORDING_REMOTE_CONFIG)?.enabled\n const enabled_client_side = !this._instance.config.disable_session_recording\n const isDisabled = this._instance.config.disable_session_recording || this._instance.consent.isOptedOut()\n return window && enabled_server_side && enabled_client_side && !isDisabled\n }\n\n startIfEnabledOrStop(startReason?: SessionStartReason) {\n if (this._isRecordingEnabled && this._lazyLoadedSessionRecording?.isStarted) {\n return\n }\n\n // According to the rrweb docs, rrweb is not supported on IE11 and below:\n // \"rrweb does not support IE11 and below because it uses the MutationObserver API, which was supported by these browsers.\"\n // https://github.com/rrweb-io/rrweb/blob/master/guide.md#compatibility-note\n //\n // However, MutationObserver does exist on IE11, it just doesn't work well and does not detect all changes.\n // Instead, when we load \"recorder.js\", the first JS error is about \"Object.assign\" and \"Array.from\" being undefined.\n // Thus instead of MutationObserver, we look for this function and block recording if it's undefined.\n const canRunReplay = !isUndefined(Object.assign) && !isUndefined(Array.from)\n if (this._isRecordingEnabled && canRunReplay) {\n this._lazyLoadAndStart(startReason)\n logger.info('starting')\n } else {\n this.stopRecording()\n }\n }\n\n /**\n * session recording waits until it receives remote config before loading the script\n * this is to ensure we can control the script name remotely\n * and because we wait until we have local and remote config to determine if we should start at all\n * if start is called and there is no remote config then we wait until there is\n */\n private _lazyLoadAndStart(startReason?: SessionStartReason) {\n // by checking `_isRecordingEnabled` here we know that\n // we have stored remote config and client config to read\n // replay waits for both local and remote config before starting\n if (!this._isRecordingEnabled) {\n return\n }\n\n // If recorder.js is already loaded (if array.full.js snippet is used or posthog-js/dist/recorder is\n // imported), don't load the script. Otherwise, remotely import recorder.js from cdn since it hasn't been loaded.\n if (\n !assignableWindow?.__PosthogExtensions__?.rrweb?.record ||\n !assignableWindow.__PosthogExtensions__?.initSessionRecording\n ) {\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(\n this._instance,\n this._scriptName,\n (err) => {\n if (err) {\n return logger.error('could not load recorder', err)\n }\n this._onScriptLoaded(startReason)\n }\n )\n } else {\n this._onScriptLoaded(startReason)\n }\n }\n\n stopRecording() {\n this._persistFlagsOnSessionListener?.()\n this._persistFlagsOnSessionListener = undefined\n this._lazyLoadedSessionRecording?.stop()\n }\n\n private _resetSampling() {\n this._instance.persistence?.unregister(SESSION_RECORDING_IS_SAMPLED)\n }\n\n private _persistRemoteConfig(response: RemoteConfig): void {\n if (this._instance.persistence) {\n const persistence = this._instance.persistence\n\n const persistResponse = () => {\n const sessionRecordingConfigResponse =\n response.sessionRecording === false ? undefined : response.sessionRecording\n\n const receivedSampleRate = sessionRecordingConfigResponse?.sampleRate\n\n const parsedSampleRate = isNullish(receivedSampleRate) ? null : parseFloat(receivedSampleRate)\n if (isNullish(parsedSampleRate)) {\n this._resetSampling()\n }\n\n const receivedMinimumDuration = sessionRecordingConfigResponse?.minimumDurationMilliseconds\n\n persistence.register({\n [SESSION_RECORDING_REMOTE_CONFIG]: {\n enabled: !!sessionRecordingConfigResponse,\n ...sessionRecordingConfigResponse,\n networkPayloadCapture: {\n capturePerformance: response.capturePerformance,\n ...sessionRecordingConfigResponse?.networkPayloadCapture,\n },\n canvasRecording: {\n enabled: sessionRecordingConfigResponse?.recordCanvas,\n fps: sessionRecordingConfigResponse?.canvasFps,\n quality: sessionRecordingConfigResponse?.canvasQuality,\n },\n sampleRate: parsedSampleRate,\n minimumDurationMilliseconds: isUndefined(receivedMinimumDuration)\n ? null\n : receivedMinimumDuration,\n endpoint: sessionRecordingConfigResponse?.endpoint,\n triggerMatchType: sessionRecordingConfigResponse?.triggerMatchType,\n masking: sessionRecordingConfigResponse?.masking,\n urlTriggers: sessionRecordingConfigResponse?.urlTriggers,\n } satisfies SessionRecordingPersistedConfig,\n })\n }\n\n persistResponse()\n\n // in case we see multiple flags responses, we should only use the response from the most recent one\n this._persistFlagsOnSessionListener?.()\n // we 100% know there is a session manager by this point\n this._persistFlagsOnSessionListener = this._instance.sessionManager?.onSessionId(persistResponse)\n }\n }\n\n onRemoteConfig(response: RemoteConfig) {\n if (!('sessionRecording' in response)) {\n // if sessionRecording is not in the response, we do nothing\n logger.info('skipping remote config with no sessionRecording', response)\n return\n }\n if (response.sessionRecording === false) {\n // remotely disabled\n this._receivedFlags = true\n return\n }\n\n this._persistRemoteConfig(response)\n this._receivedFlags = true\n this.startIfEnabledOrStop()\n }\n\n log(message: string, level: 'log' | 'warn' | 'error' = 'log') {\n if (this._lazyLoadedSessionRecording?.log) {\n this._lazyLoadedSessionRecording.log(message, level)\n } else {\n logger.warn('log called before recorder was ready')\n }\n }\n\n private get _scriptName(): PostHogExtensionKind {\n const remoteConfig: SessionRecordingPersistedConfig | undefined = this._instance?.persistence?.get_property(\n SESSION_RECORDING_REMOTE_CONFIG\n )\n return (remoteConfig?.scriptConfig?.script as PostHogExtensionKind) || 'lazy-recorder'\n }\n\n private _onScriptLoaded(startReason?: SessionStartReason) {\n if (!assignableWindow.__PosthogExtensions__?.initSessionRecording) {\n throw Error('Called on script loaded before session recording is available')\n }\n\n if (!this._lazyLoadedSessionRecording) {\n this._lazyLoadedSessionRecording = assignableWindow.__PosthogExtensions__?.initSessionRecording(\n this._instance\n )\n ;(this._lazyLoadedSessionRecording as any)._forceAllowLocalhostNetworkCapture =\n this._forceAllowLocalhostNetworkCapture\n }\n\n this._lazyLoadedSessionRecording.start(startReason)\n }\n\n /**\n * this is maintained on the public API only because it has always been on the public API\n * if you are calling this directly you are certainly doing something wrong\n * @deprecated\n */\n onRRwebEmit(rawEvent: eventWithTime) {\n this._lazyLoadedSessionRecording?.onRRwebEmit?.(rawEvent)\n }\n\n /**\n * this ignores the linked flag config and (if other conditions are met) causes capture to start\n *\n * It is not usual to call this directly,\n * instead call `posthog.startSessionRecording({linked_flag: true})`\n * */\n public overrideLinkedFlag() {\n if (!this._lazyLoadedSessionRecording) {\n this._instance.persistence?.register({\n [SESSION_RECORDING_OVERRIDE_LINKED_FLAG]: true,\n })\n }\n\n this._lazyLoadedSessionRecording?.overrideLinkedFlag()\n }\n\n /**\n * this ignores the sampling config and (if other conditions are met) causes capture to start\n *\n * It is not usual to call this directly,\n * instead call `posthog.startSessionRecording({sampling: true})`\n * */\n public overrideSampling() {\n if (!this._lazyLoadedSessionRecording) {\n this._instance.persistence?.register({\n [SESSION_RECORDING_OVERRIDE_SAMPLING]: true,\n })\n }\n\n this._lazyLoadedSessionRecording?.overrideSampling()\n }\n\n /**\n * this ignores the URL/Event trigger config and (if other conditions are met) causes capture to start\n *\n * It is not usual to call this directly,\n * instead call `posthog.startSessionRecording({trigger: 'url' | 'event'})`\n * */\n public overrideTrigger(triggerType: TriggerType) {\n if (!this._lazyLoadedSessionRecording) {\n this._instance.persistence?.register({\n [triggerType === 'url'\n ? SESSION_RECORDING_OVERRIDE_URL_TRIGGER\n : SESSION_RECORDING_OVERRIDE_EVENT_TRIGGER]: true,\n })\n }\n\n this._lazyLoadedSessionRecording?.overrideTrigger(triggerType)\n }\n\n /*\n * whenever we capture an event, we add these properties to the event\n * these are used to debug issues with the session recording\n * when looking at the event feed for a session\n */\n get sdkDebugProperties(): Properties {\n return (\n this._lazyLoadedSessionRecording?.sdkDebugProperties || {\n $recording_status: this.status,\n }\n )\n }\n\n /**\n * This adds a custom event to the session recording\n *\n * It is not intended for arbitrary public use - playback only displays known custom events\n * And is exposed on the public interface only so that other parts of the SDK are able to use it\n *\n * if you are calling this from client code, you're probably looking for `posthog.capture('$custom_event', {...})`\n */\n tryAddCustomEvent(tag: string, payload: any): boolean {\n return !!this._lazyLoadedSessionRecording?.tryAddCustomEvent(tag, payload)\n }\n}\n","import { Autocapture } from './autocapture'\nimport Config from './config'\nimport { ConsentManager, ConsentStatus } from './consent'\nimport {\n ALIAS_ID_KEY,\n COOKIELESS_MODE_FLAG_PROPERTY,\n COOKIELESS_SENTINEL_VALUE,\n ENABLE_PERSON_PROCESSING,\n FLAG_CALL_REPORTED,\n PEOPLE_DISTINCT_ID_KEY,\n SURVEYS_REQUEST_TIMEOUT_MS,\n USER_STATE,\n} from './constants'\nimport { DeadClicksAutocapture, isDeadClicksEnabledForAutocapture } from './extensions/dead-clicks-autocapture'\nimport { ExceptionObserver } from './extensions/exception-autocapture'\nimport { HistoryAutocapture } from './extensions/history-autocapture'\nimport { setupSegmentIntegration } from './extensions/segment-integration'\nimport { SentryIntegration, sentryIntegration, SentryIntegrationOptions } from './extensions/sentry-integration'\nimport { Toolbar } from './extensions/toolbar'\nimport { TracingHeaders } from './extensions/tracing-headers'\nimport { WebVitalsAutocapture } from './extensions/web-vitals'\nimport { Heatmaps } from './heatmaps'\nimport { PageViewManager } from './page-view'\nimport { PostHogExceptions } from './posthog-exceptions'\nimport { PostHogFeatureFlags } from './posthog-featureflags'\nimport { PostHogPersistence } from './posthog-persistence'\nimport { PostHogProductTours } from './posthog-product-tours'\nimport { PostHogSurveys } from './posthog-surveys'\nimport { PostHogConversations } from './extensions/conversations/posthog-conversations'\nimport {\n DisplaySurveyOptions,\n SurveyCallback,\n SurveyEventName,\n SurveyEventProperties,\n SurveyRenderReason,\n} from './posthog-surveys-types'\nimport { RateLimiter } from './rate-limiter'\nimport { RemoteConfigLoader } from './remote-config'\nimport { extendURLParams, request, SUPPORTS_REQUEST } from './request'\nimport { DEFAULT_FLUSH_INTERVAL_MS, RequestQueue } from './request-queue'\nimport { RetryQueue } from './retry-queue'\nimport { ScrollManager } from './scroll-manager'\nimport { SessionPropsManager } from './session-props'\nimport { SessionIdManager } from './sessionid'\nimport { SiteApps } from './site-apps'\nimport { localStore } from './storage'\nimport {\n CaptureOptions,\n CaptureResult,\n Compression,\n ConfigDefaults,\n EarlyAccessFeatureCallback,\n EarlyAccessFeatureStage,\n EventName,\n ExceptionAutoCaptureConfig,\n FeatureFlagDetail,\n FeatureFlagsCallback,\n JsonType,\n OverrideConfig,\n PostHogConfig,\n Properties,\n Property,\n QueuedRequestWithOptions,\n RemoteConfig,\n RequestCallback,\n SessionIdChangedCallback,\n SnippetArrayItem,\n ToolbarParams,\n PostHogInterface,\n} from './types'\nimport {\n _copyAndTruncateStrings,\n addEventListener,\n each,\n eachArray,\n extend,\n isCrossDomainCookie,\n migrateConfigField,\n safewrapClass,\n} from './utils'\nimport { isLikelyBot } from './utils/blocked-uas'\nimport { getEventProperties } from './utils/event-utils'\nimport { assignableWindow, document, location, navigator, userAgent, window } from './utils/globals'\nimport { logger } from './utils/logger'\nimport { getPersonPropertiesHash } from './utils/property-utils'\nimport { RequestRouter, RequestRouterRegion } from './utils/request-router'\nimport { SimpleEventEmitter } from './utils/simple-event-emitter'\nimport {\n DEFAULT_DISPLAY_SURVEY_OPTIONS,\n getSurveyInteractionProperty,\n setSurveySeenOnLocalStorage,\n} from './utils/survey-utils'\nimport {\n isEmptyString,\n isFunction,\n isKnownUnsafeEditableEvent,\n isNullish,\n isNumber,\n isString,\n isUndefined,\n includes,\n isDistinctIdStringLike,\n isArray,\n isEmptyObject,\n isObject,\n isBoolean,\n} from '@posthog/core'\nimport { uuidv7 } from './uuidv7'\nimport { WebExperiments } from './web-experiments'\nimport { ExternalIntegrations } from './extensions/external-integration'\nimport { SessionRecording } from './extensions/replay/session-recording'\n\n/*\nSIMPLE STYLE GUIDE:\n\nUse TypeScript accessibility modifiers, e.g. private/protected\n\nIf something is not part of the public interface:\n* prefix it with _ to allow mangling\n* prefix it with __ to disable mangling, but signal that it is internal\n\nGlobals should be all caps\n*/\n\n/* posthog.init is called with `Partial<PostHogConfig>`\n * and we want to ensure that only valid keys are passed to the config object.\n * TypeScript does not enforce that the object passed does not have extra keys.\n * So someone can call with { bootstrap: { distinctId: '123'} }\n * which is not a valid key. They should have passed distinctID (upper case D).\n * That's a really tricky mistake to spot.\n * The OnlyValidKeys type ensures that only keys that are valid in the PostHogConfig type are allowed.\n */\ntype OnlyValidKeys<T, Shape> = T extends Shape ? (Exclude<keyof T, keyof Shape> extends never ? T : never) : never\n\nconst instances: Record<string, PostHog> = {}\n\n// some globals for comparisons\nconst __NOOP = () => {}\n\nconst PRIMARY_INSTANCE_NAME = 'posthog'\n\n/*\n * Dynamic... constants? Is that an oxymoron?\n */\n// http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/\n// https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#withCredentials\n\n// IE<10 does not support cross-origin XHR's but script tags\n// with defer won't block window.onload; ENQUEUE_REQUESTS\n// should only be true for Opera<12\nlet ENQUEUE_REQUESTS = !SUPPORTS_REQUEST && userAgent?.indexOf('MSIE') === -1 && userAgent?.indexOf('Mozilla') === -1\n\nconst defaultsThatVaryByConfig = (\n defaults?: ConfigDefaults\n): Pick<PostHogConfig, 'rageclick' | 'capture_pageview' | 'session_recording'> => ({\n rageclick: defaults && defaults >= '2025-11-30' ? { content_ignorelist: true } : true,\n capture_pageview: defaults && defaults >= '2025-05-24' ? 'history_change' : true,\n session_recording: defaults && defaults >= '2025-11-30' ? { strictMinimumDuration: true } : {},\n})\n\n// NOTE: Remember to update `types.ts` when changing a default value\n// to guarantee documentation is up to date, make sure to also update our website docs\n// NOTE²: This shouldn't ever change because we try very hard to be backwards-compatible\nexport const defaultConfig = (defaults?: ConfigDefaults): PostHogConfig => ({\n api_host: 'https://us.i.posthog.com',\n flags_api_host: null,\n ui_host: null,\n token: '',\n autocapture: true,\n cross_subdomain_cookie: isCrossDomainCookie(document?.location),\n persistence: 'localStorage+cookie', // up to 1.92.0 this was 'cookie'. It's easy to migrate as 'localStorage+cookie' will migrate data from cookie storage\n persistence_name: '',\n cookie_persisted_properties: [],\n loaded: __NOOP,\n save_campaign_params: true,\n custom_campaign_params: [],\n custom_blocked_useragents: [],\n save_referrer: true,\n capture_pageleave: 'if_capture_pageview', // We'll only capture pageleave events if capture_pageview is also true\n defaults: defaults ?? 'unset',\n __preview_deferred_init_extensions: false, // Opt-in only for now\n debug: (location && isString(location?.search) && location.search.indexOf('__posthog_debug=true') !== -1) || false,\n cookie_expiration: 365,\n upgrade: false,\n disable_session_recording: false,\n disable_persistence: false,\n disable_web_experiments: true, // disabled in beta.\n disable_surveys: false,\n disable_surveys_automatic_display: false,\n disable_conversations: false,\n disable_product_tours: true,\n disable_external_dependency_loading: false,\n enable_recording_console_log: undefined, // When undefined, it falls back to the server-side setting\n secure_cookie: window?.location?.protocol === 'https:',\n ip: false,\n opt_out_capturing_by_default: false,\n opt_out_persistence_by_default: false,\n opt_out_useragent_filter: false,\n opt_out_capturing_persistence_type: 'localStorage',\n consent_persistence_name: null,\n opt_out_capturing_cookie_prefix: null,\n opt_in_site_apps: false,\n property_denylist: [],\n respect_dnt: false,\n sanitize_properties: null,\n request_headers: {}, // { header: value, header2: value }\n request_batching: true,\n properties_string_max_length: 65535,\n mask_all_element_attributes: false,\n mask_all_text: false,\n mask_personal_data_properties: false,\n custom_personal_data_properties: [],\n advanced_disable_flags: false,\n advanced_disable_decide: false,\n advanced_disable_feature_flags: false,\n advanced_disable_feature_flags_on_first_load: false,\n advanced_only_evaluate_survey_feature_flags: false,\n advanced_enable_surveys: false,\n advanced_disable_toolbar_metrics: false,\n feature_flag_request_timeout_ms: 3000,\n surveys_request_timeout_ms: SURVEYS_REQUEST_TIMEOUT_MS,\n on_request_error: (res) => {\n const error = 'Bad HTTP status: ' + res.statusCode + ' ' + res.text\n logger.error(error)\n },\n get_device_id: (uuid) => uuid,\n capture_performance: undefined,\n name: 'posthog',\n bootstrap: {},\n disable_compression: false,\n session_idle_timeout_seconds: 30 * 60, // 30 minutes\n person_profiles: 'identified_only',\n before_send: undefined,\n request_queue_config: { flush_interval_ms: DEFAULT_FLUSH_INTERVAL_MS },\n error_tracking: {},\n\n // Used for internal testing\n _onCapture: __NOOP,\n\n // make the default be lazy loading replay\n __preview_eager_load_replay: false,\n\n ...defaultsThatVaryByConfig(defaults),\n})\n\nexport const configRenames = (origConfig: Partial<PostHogConfig>): Partial<PostHogConfig> => {\n const renames: Partial<PostHogConfig> = {}\n if (!isUndefined(origConfig.process_person)) {\n renames.person_profiles = origConfig.process_person\n }\n if (!isUndefined(origConfig.xhr_headers)) {\n renames.request_headers = origConfig.xhr_headers\n }\n if (!isUndefined(origConfig.cookie_name)) {\n renames.persistence_name = origConfig.cookie_name\n }\n if (!isUndefined(origConfig.disable_cookie)) {\n renames.disable_persistence = origConfig.disable_cookie\n }\n if (!isUndefined(origConfig.store_google)) {\n renames.save_campaign_params = origConfig.store_google\n }\n if (!isUndefined(origConfig.verbose)) {\n renames.debug = origConfig.verbose\n }\n // on_xhr_error is not present, as the type is different to on_request_error\n\n // the original config takes priority over the renames\n const newConfig = extend({}, renames, origConfig)\n\n // merge property_blacklist into property_denylist\n if (isArray(origConfig.property_blacklist)) {\n if (isUndefined(origConfig.property_denylist)) {\n newConfig.property_denylist = origConfig.property_blacklist\n } else if (isArray(origConfig.property_denylist)) {\n newConfig.property_denylist = [...origConfig.property_blacklist, ...origConfig.property_denylist]\n } else {\n logger.error('Invalid value for property_denylist config: ' + origConfig.property_denylist)\n }\n }\n\n return newConfig\n}\n\nclass DeprecatedWebPerformanceObserver {\n get _forceAllowLocalhost(): boolean {\n return this.__forceAllowLocalhost\n }\n\n set _forceAllowLocalhost(value: boolean) {\n logger.error(\n 'WebPerformanceObserver is deprecated and has no impact on network capture. Use `_forceAllowLocalhostNetworkCapture` on `posthog.sessionRecording`'\n )\n this.__forceAllowLocalhost = value\n }\n\n private __forceAllowLocalhost: boolean = false\n}\n\n/**\n *\n * This is the SDK reference for the PostHog JavaScript Web SDK.\n * You can learn more about example usage in the\n * [JavaScript Web SDK documentation](/docs/libraries/js).\n * You can also follow [framework specific guides](/docs/frameworks)\n * to integrate PostHog into your project.\n *\n * This SDK is designed for browser environments.\n * Use the PostHog [Node.js SDK](/docs/libraries/node) for server-side usage.\n *\n * @constructor\n */\nexport class PostHog implements PostHogInterface {\n __loaded: boolean\n config: PostHogConfig\n _originalUserConfig?: Partial<PostHogConfig>\n\n rateLimiter: RateLimiter\n scrollManager: ScrollManager\n pageViewManager: PageViewManager\n featureFlags: PostHogFeatureFlags\n surveys: PostHogSurveys\n conversations: PostHogConversations\n experiments: WebExperiments\n toolbar: Toolbar\n exceptions: PostHogExceptions\n consent: ConsentManager\n\n // These are instance-specific state created after initialisation\n persistence?: PostHogPersistence\n sessionPersistence?: PostHogPersistence\n sessionManager?: SessionIdManager\n sessionPropsManager?: SessionPropsManager\n requestRouter: RequestRouter\n siteApps?: SiteApps\n autocapture?: Autocapture\n heatmaps?: Heatmaps\n webVitalsAutocapture?: WebVitalsAutocapture\n exceptionObserver?: ExceptionObserver\n deadClicksAutocapture?: DeadClicksAutocapture\n historyAutocapture?: HistoryAutocapture\n productTours?: PostHogProductTours\n\n _requestQueue?: RequestQueue\n _retryQueue?: RetryQueue\n sessionRecording?: SessionRecording\n externalIntegrations?: ExternalIntegrations\n webPerformance = new DeprecatedWebPerformanceObserver()\n\n _initialPageviewCaptured: boolean\n _visibilityStateListener: (() => void) | null\n _personProcessingSetOncePropertiesSent: boolean = false\n _triggered_notifs: any\n compression?: Compression\n __request_queue: QueuedRequestWithOptions[]\n _pendingRemoteConfig?: RemoteConfig\n analyticsDefaultEndpoint: string\n version: string = Config.LIB_VERSION\n _initialPersonProfilesConfig: 'always' | 'never' | 'identified_only' | null\n _cachedPersonProperties: string | null\n\n SentryIntegration: typeof SentryIntegration\n sentryIntegration: (options?: SentryIntegrationOptions) => ReturnType<typeof sentryIntegration>\n\n private _internalEventEmitter = new SimpleEventEmitter()\n\n // Legacy property to support existing usage - this isn't technically correct but it's what it has always been - a proxy for flags being loaded\n /** @deprecated Use `flagsEndpointWasHit` instead. We migrated to using a new feature flag endpoint and the new method is more semantically accurate */\n public get decideEndpointWasHit(): boolean {\n return this.featureFlags?.hasLoadedFlags ?? false\n }\n\n public get flagsEndpointWasHit(): boolean {\n return this.featureFlags?.hasLoadedFlags ?? false\n }\n\n /** DEPRECATED: We keep this to support existing usage but now one should just call .setPersonProperties */\n people: {\n set: (prop: string | Properties, to?: string, callback?: RequestCallback) => void\n set_once: (prop: string | Properties, to?: string, callback?: RequestCallback) => void\n }\n\n constructor() {\n this.config = defaultConfig()\n\n this.SentryIntegration = SentryIntegration\n this.sentryIntegration = (options?: SentryIntegrationOptions) => sentryIntegration(this, options)\n this.__request_queue = []\n this.__loaded = false\n this.analyticsDefaultEndpoint = '/e/'\n this._initialPageviewCaptured = false\n this._visibilityStateListener = null\n this._initialPersonProfilesConfig = null\n this._cachedPersonProperties = null\n this.featureFlags = new PostHogFeatureFlags(this)\n this.toolbar = new Toolbar(this)\n this.scrollManager = new ScrollManager(this)\n this.pageViewManager = new PageViewManager(this)\n this.surveys = new PostHogSurveys(this)\n this.conversations = new PostHogConversations(this)\n this.experiments = new WebExperiments(this)\n this.exceptions = new PostHogExceptions(this)\n this.rateLimiter = new RateLimiter(this)\n this.requestRouter = new RequestRouter(this)\n this.consent = new ConsentManager(this)\n this.externalIntegrations = new ExternalIntegrations(this)\n // NOTE: See the property definition for deprecation notice\n this.people = {\n set: (prop: string | Properties, to?: string, callback?: RequestCallback) => {\n const setProps = isString(prop) ? { [prop]: to } : prop\n this.setPersonProperties(setProps)\n callback?.({} as any)\n },\n set_once: (prop: string | Properties, to?: string, callback?: RequestCallback) => {\n const setProps = isString(prop) ? { [prop]: to } : prop\n this.setPersonProperties(undefined, setProps)\n callback?.({} as any)\n },\n }\n\n this.on('eventCaptured', (data) => logger.info(`send \"${data?.event}\"`, data))\n }\n\n // Initialization methods\n\n /**\n * Initializes a new instance of the PostHog capturing object.\n *\n * @remarks\n * All new instances are added to the main posthog object as sub properties (such as\n * `posthog.library_name`) and also returned by this function. [Learn more about configuration options](https://github.com/posthog/posthog-js/blob/6e0e873/src/posthog-core.js#L57-L91)\n *\n * @example\n * ```js\n * // basic initialization\n * posthog.init('<ph_project_api_key>', {\n * api_host: '<ph_client_api_host>'\n * })\n * ```\n *\n * @example\n * ```js\n * // multiple instances\n * posthog.init('<ph_project_api_key>', {}, 'project1')\n * posthog.init('<ph_project_api_key>', {}, 'project2')\n * ```\n *\n * @public\n *\n * @param token - Your PostHog API token\n * @param config - A dictionary of config options to override\n * @param name - The name for the new posthog instance that you want created\n *\n * {@label Initialization}\n *\n * @returns The newly initialized PostHog instance\n */\n init(\n token: string,\n config?: OnlyValidKeys<Partial<PostHogConfig>, Partial<PostHogConfig>>,\n name?: string\n ): PostHog {\n if (!name || name === PRIMARY_INSTANCE_NAME) {\n // This means we are initializing the primary instance (i.e. this)\n return this._init(token, config, name)\n } else {\n const namedPosthog = instances[name] ?? new PostHog()\n namedPosthog._init(token, config, name)\n instances[name] = namedPosthog\n\n // Add as a property to the primary instance (this isn't type-safe but it is how it was always done)\n ;(instances[PRIMARY_INSTANCE_NAME] as any)[name] = namedPosthog\n\n return namedPosthog\n }\n }\n\n // posthog._init(token:string, config:object, name:string)\n //\n // This function sets up the current instance of the posthog\n // library. The difference between this method and the init(...)\n // method is this one initializes the actual instance, whereas the\n // init(...) method sets up a new library and calls _init on it.\n //\n // Note that there are operations that can be asynchronous, so we\n // accept a callback that is called when all the asynchronous work\n // is done. Note that we do not use promises because we want to be\n // IE11 compatible. We could use polyfills, which would make the\n // code a bit cleaner, but will add some overhead.\n //\n _init(token: string, config: Partial<PostHogConfig> = {}, name?: string): PostHog {\n if (isUndefined(token) || isEmptyString(token)) {\n logger.critical(\n 'PostHog was initialized without a token. This likely indicates a misconfiguration. Please check the first argument passed to posthog.init()'\n )\n return this\n }\n\n if (this.__loaded) {\n // need to be able to log before having processed debug config\n // eslint-disable-next-line no-console\n console.warn('[PostHog.js]', 'You have already initialized PostHog! Re-initializing is a no-op')\n return this\n }\n\n this.__loaded = true\n this.config = {} as PostHogConfig // will be set right below\n config.debug = this._checkLocalStorageForDebug(config.debug)\n this._originalUserConfig = config // Store original user config for migration\n\n this._triggered_notifs = []\n\n if (config.person_profiles) {\n this._initialPersonProfilesConfig = config.person_profiles\n }\n\n this.set_config(\n extend({}, defaultConfig(config.defaults), configRenames(config), {\n name: name,\n token: token,\n })\n )\n\n if (this.config.on_xhr_error) {\n logger.error('on_xhr_error is deprecated. Use on_request_error instead')\n }\n\n this.compression = config.disable_compression ? undefined : Compression.GZipJS\n\n const persistenceDisabled = this._is_persistence_disabled()\n\n this.persistence = new PostHogPersistence(this.config, persistenceDisabled)\n this.sessionPersistence =\n this.config.persistence === 'sessionStorage' || this.config.persistence === 'memory'\n ? this.persistence\n : new PostHogPersistence({ ...this.config, persistence: 'sessionStorage' }, persistenceDisabled)\n\n // should I store the initial person profiles config in persistence?\n const initialPersistenceProps = { ...this.persistence.props }\n const initialSessionProps = { ...this.sessionPersistence.props }\n\n this.register({ $initialization_time: new Date().toISOString() })\n\n this._requestQueue = new RequestQueue(\n (req) => this._send_retriable_request(req),\n this.config.request_queue_config\n )\n this._retryQueue = new RetryQueue(this)\n this.__request_queue = []\n\n const startInCookielessMode =\n this.config.cookieless_mode === 'always' ||\n (this.config.cookieless_mode === 'on_reject' && this.consent.isExplicitlyOptedOut())\n\n if (!startInCookielessMode) {\n this.sessionManager = new SessionIdManager(this)\n this.sessionPropsManager = new SessionPropsManager(this, this.sessionManager, this.persistence)\n }\n\n // Conditionally defer extension initialization based on config\n if (this.config.__preview_deferred_init_extensions) {\n // EXPERIMENTAL: Defer non-critical extension initialization to next tick\n // This reduces main thread blocking during init\n // while keeping critical path (persistence, sessions, capture) synchronous\n logger.info('Deferring extension initialization to improve startup performance')\n setTimeout(() => {\n this._initExtensions(startInCookielessMode)\n }, 0)\n } else {\n // Legacy synchronous initialization (default for now)\n logger.info('Initializing extensions synchronously')\n this._initExtensions(startInCookielessMode)\n }\n\n // if any instance on the page has debug = true, we set the\n // global debug to be true\n Config.DEBUG = Config.DEBUG || this.config.debug\n if (Config.DEBUG) {\n logger.info('Starting in debug mode', {\n this: this,\n config,\n thisC: { ...this.config },\n p: initialPersistenceProps,\n s: initialSessionProps,\n })\n }\n\n // isUndefined doesn't provide typehint here so wouldn't reduce bundle as we'd need to assign\n // eslint-disable-next-line posthog-js/no-direct-undefined-check\n if (config.bootstrap?.distinctID !== undefined) {\n const uuid = this.config.get_device_id(uuidv7())\n const deviceID = config.bootstrap?.isIdentifiedID ? uuid : config.bootstrap.distinctID\n this.persistence.set_property(USER_STATE, config.bootstrap?.isIdentifiedID ? 'identified' : 'anonymous')\n this.register({\n distinct_id: config.bootstrap.distinctID,\n $device_id: deviceID,\n })\n }\n\n if (this._hasBootstrappedFeatureFlags()) {\n const activeFlags = Object.keys(config.bootstrap?.featureFlags || {})\n .filter((flag) => !!config.bootstrap?.featureFlags?.[flag])\n .reduce((res: Record<string, string | boolean>, key) => {\n res[key] = config.bootstrap?.featureFlags?.[key] || false\n return res\n }, {})\n const featureFlagPayloads = Object.keys(config.bootstrap?.featureFlagPayloads || {})\n .filter((key) => activeFlags[key])\n .reduce((res: Record<string, JsonType>, key) => {\n if (config.bootstrap?.featureFlagPayloads?.[key]) {\n res[key] = config.bootstrap?.featureFlagPayloads?.[key]\n }\n return res\n }, {})\n\n this.featureFlags.receivedFeatureFlags({ featureFlags: activeFlags, featureFlagPayloads })\n }\n\n if (startInCookielessMode) {\n this.register_once(\n {\n distinct_id: COOKIELESS_SENTINEL_VALUE,\n $device_id: null,\n },\n ''\n )\n } else if (!this.get_distinct_id()) {\n // There is no need to set the distinct id\n // or the device id if something was already stored\n // in the persistence\n const uuid = this.config.get_device_id(uuidv7())\n\n this.register_once(\n {\n distinct_id: uuid,\n $device_id: uuid,\n },\n ''\n )\n // distinct id == $device_id is a proxy for anonymous user\n this.persistence.set_property(USER_STATE, 'anonymous')\n }\n // Set up event handler for pageleave\n // Use `onpagehide` if available, see https://calendar.perfplanet.com/2020/beaconing-in-practice/#beaconing-reliability-avoiding-abandons\n //\n // Not making it passive to try and force the browser to handle this before the page is unloaded\n addEventListener(window, 'onpagehide' in self ? 'pagehide' : 'unload', this._handle_unload.bind(this), {\n passive: false,\n })\n\n this.toolbar.maybeLoadToolbar()\n\n // We want to avoid promises for IE11 compatibility, so we use callbacks here\n if (config.segment) {\n setupSegmentIntegration(this, () => this._loaded())\n } else {\n this._loaded()\n }\n\n if (isFunction(this.config._onCapture) && this.config._onCapture !== __NOOP) {\n logger.warn('onCapture is deprecated. Please use `before_send` instead')\n this.on('eventCaptured', (data) => this.config._onCapture(data.event, data))\n }\n\n if (this.config.ip) {\n logger.warn(\n 'The `ip` config option has NO EFFECT AT ALL and has been deprecated. Use a custom transformation or \"Discard IP data\" project setting instead. See https://posthog.com/tutorials/web-redact-properties#hiding-customer-ip-address for more information.'\n )\n }\n\n return this\n }\n\n private _initExtensions(startInCookielessMode: boolean): void {\n // we don't support IE11 anymore, so performance.now is safe\n // eslint-disable-next-line compat/compat\n const initStartTime = performance.now()\n\n this.historyAutocapture = new HistoryAutocapture(this)\n this.historyAutocapture.startIfEnabled()\n\n // Build queue of extension initialization tasks\n const initTasks: Array<() => void> = []\n\n initTasks.push(() => {\n new TracingHeaders(this).startIfEnabledOrStop()\n })\n\n initTasks.push(() => {\n this.siteApps = new SiteApps(this)\n this.siteApps?.init()\n })\n\n if (!startInCookielessMode) {\n initTasks.push(() => {\n this.sessionRecording = new SessionRecording(this)\n this.sessionRecording.startIfEnabledOrStop()\n })\n }\n\n if (!this.config.disable_scroll_properties) {\n initTasks.push(() => {\n this.scrollManager.startMeasuringScrollPosition()\n })\n }\n\n initTasks.push(() => {\n this.autocapture = new Autocapture(this)\n this.autocapture.startIfEnabled()\n })\n\n initTasks.push(() => {\n this.surveys.loadIfEnabled()\n })\n\n initTasks.push(() => {\n this.conversations.loadIfEnabled()\n })\n\n initTasks.push(() => {\n this.productTours = new PostHogProductTours(this)\n this.productTours.loadIfEnabled()\n })\n\n initTasks.push(() => {\n this.heatmaps = new Heatmaps(this)\n this.heatmaps.startIfEnabled()\n })\n\n initTasks.push(() => {\n this.webVitalsAutocapture = new WebVitalsAutocapture(this)\n })\n\n initTasks.push(() => {\n this.exceptionObserver = new ExceptionObserver(this)\n this.exceptionObserver.startIfEnabledOrStop()\n })\n\n initTasks.push(() => {\n this.deadClicksAutocapture = new DeadClicksAutocapture(this, isDeadClicksEnabledForAutocapture)\n this.deadClicksAutocapture.startIfEnabled()\n })\n\n // Replay any pending remote config that arrived before extensions were ready\n initTasks.push(() => {\n if (this._pendingRemoteConfig) {\n const config = this._pendingRemoteConfig\n this._pendingRemoteConfig = undefined // Clear before replaying to avoid re-storing\n this._onRemoteConfig(config)\n }\n })\n\n // Process tasks with time-slicing to avoid blocking\n this._processInitTaskQueue(initTasks, initStartTime)\n }\n\n private _processInitTaskQueue(queue: Array<() => void>, initStartTime: number): void {\n const TIME_BUDGET_MS = 30 // Respect frame budget (~60fps = 16ms, but we're already deferred)\n\n while (queue.length > 0) {\n // Only time-slice if deferred init is enabled, otherwise run synchronously\n if (this.config.__preview_deferred_init_extensions) {\n // we don't support IE11 anymore, so performance.now is safe\n // eslint-disable-next-line compat/compat\n const elapsed = performance.now() - initStartTime\n\n // Check if we've exceeded our time budget\n if (elapsed >= TIME_BUDGET_MS && queue.length > 0) {\n // Yield to browser, then continue processing\n setTimeout(() => {\n this._processInitTaskQueue(queue, initStartTime)\n }, 0)\n return\n }\n }\n\n // Process next task\n const task = queue.shift()\n if (task) {\n try {\n task()\n } catch (error) {\n logger.error('Error initializing extension:', error)\n }\n }\n }\n\n // All tasks complete - record timing for both sync and deferred modes\n // we don't support IE11 anymore, so performance.now is safe\n // eslint-disable-next-line compat/compat\n const taskInitTiming = Math.round(performance.now() - initStartTime)\n this.register_for_session({\n $sdk_debug_extensions_init_method: this.config.__preview_deferred_init_extensions\n ? 'deferred'\n : 'synchronous',\n $sdk_debug_extensions_init_time_ms: taskInitTiming,\n })\n if (this.config.__preview_deferred_init_extensions) {\n logger.info(`PostHog extensions initialized (${taskInitTiming}ms)`)\n }\n }\n\n _onRemoteConfig(config: RemoteConfig) {\n if (!(document && document.body)) {\n logger.info('document not ready yet, trying again in 500 milliseconds...')\n setTimeout(() => {\n this._onRemoteConfig(config)\n }, 500)\n return\n }\n\n // Store config in case extensions aren't initialized yet (only needed for deferred init)\n if (this.config.__preview_deferred_init_extensions) {\n this._pendingRemoteConfig = config\n }\n\n this.compression = undefined\n if (config.supportedCompression && !this.config.disable_compression) {\n this.compression = includes(config['supportedCompression'], Compression.GZipJS)\n ? Compression.GZipJS\n : includes(config['supportedCompression'], Compression.Base64)\n ? Compression.Base64\n : undefined\n }\n\n if (config.analytics?.endpoint) {\n this.analyticsDefaultEndpoint = config.analytics.endpoint\n }\n\n this.set_config({\n person_profiles: this._initialPersonProfilesConfig ? this._initialPersonProfilesConfig : 'identified_only',\n })\n\n this.siteApps?.onRemoteConfig(config)\n this.sessionRecording?.onRemoteConfig(config)\n this.autocapture?.onRemoteConfig(config)\n this.heatmaps?.onRemoteConfig(config)\n this.surveys.onRemoteConfig(config)\n this.conversations.onRemoteConfig(config)\n this.productTours?.onRemoteConfig(config)\n this.webVitalsAutocapture?.onRemoteConfig(config)\n this.exceptionObserver?.onRemoteConfig(config)\n this.exceptions.onRemoteConfig(config)\n this.deadClicksAutocapture?.onRemoteConfig(config)\n }\n\n _loaded(): void {\n try {\n this.config.loaded(this)\n } catch (err) {\n logger.critical('`loaded` function failed', err)\n }\n\n this._start_queue_if_opted_in()\n\n // this happens after \"loaded\" so a user can call identify or any other things before the pageview fires\n if (this.config.capture_pageview) {\n // NOTE: We want to fire this on the next tick as the previous implementation had this side effect\n // and some clients may rely on it\n setTimeout(() => {\n if (this.consent.isOptedIn() || this.config.cookieless_mode === 'always') {\n this._captureInitialPageview()\n }\n }, 1)\n }\n\n new RemoteConfigLoader(this).load()\n this.featureFlags.flags()\n }\n\n _start_queue_if_opted_in(): void {\n if (this.is_capturing()) {\n if (this.config.request_batching) {\n this._requestQueue?.enable()\n }\n }\n }\n\n _dom_loaded(): void {\n if (this.is_capturing()) {\n eachArray(this.__request_queue, (item) => this._send_retriable_request(item))\n }\n\n this.__request_queue = []\n this._start_queue_if_opted_in()\n }\n\n _handle_unload(): void {\n this.surveys.handlePageUnload()\n\n if (!this.config.request_batching) {\n if (this._shouldCapturePageleave()) {\n this.capture('$pageleave', null, { transport: 'sendBeacon' })\n }\n return\n }\n\n if (this._shouldCapturePageleave()) {\n this.capture('$pageleave')\n }\n\n this._requestQueue?.unload()\n this._retryQueue?.unload()\n }\n\n _send_request(options: QueuedRequestWithOptions): void {\n if (!this.__loaded) {\n return\n }\n\n if (ENQUEUE_REQUESTS) {\n this.__request_queue.push(options)\n return\n }\n\n if (this.rateLimiter.isServerRateLimited(options.batchKey)) {\n return\n }\n\n options.transport = options.transport || this.config.api_transport\n options.url = extendURLParams(options.url, {\n // Whether to detect ip info or not\n ip: this.config.ip ? 1 : 0,\n })\n options.headers = {\n ...this.config.request_headers,\n ...options.headers,\n }\n options.compression = options.compression === 'best-available' ? this.compression : options.compression\n options.disableXHRCredentials = this.config.__preview_disable_xhr_credentials\n if (this.config.__preview_disable_beacon) {\n options.disableTransport = ['sendBeacon']\n }\n\n // Specially useful if you're doing SSR with NextJS\n // Users must be careful when tweaking `cache` because they might get out-of-date feature flags\n options.fetchOptions = options.fetchOptions || this.config.fetch_options\n\n request({\n ...options,\n callback: (response) => {\n this.rateLimiter.checkForLimiting(response)\n\n if (response.statusCode >= 400) {\n this.config.on_request_error?.(response)\n }\n\n options.callback?.(response)\n },\n })\n }\n\n _send_retriable_request(options: QueuedRequestWithOptions): void {\n if (this._retryQueue) {\n this._retryQueue.retriableRequest(options)\n } else {\n this._send_request(options)\n }\n }\n\n /**\n * _execute_array() deals with processing any posthog function\n * calls that were called before the PostHog library were loaded\n * (and are thus stored in an array so they can be called later)\n *\n * Note: we fire off all the posthog function calls && user defined\n * functions BEFORE we fire off posthog capturing calls. This is so\n * identify/register/set_config calls can properly modify early\n * capturing calls.\n *\n * @param {Array} array\n */\n _execute_array(array: SnippetArrayItem[]): void {\n let fn_name\n const alias_calls: SnippetArrayItem[] = []\n const other_calls: SnippetArrayItem[] = []\n const capturing_calls: SnippetArrayItem[] = []\n eachArray(array, (item) => {\n if (item) {\n fn_name = item[0]\n if (isArray(fn_name)) {\n capturing_calls.push(item) // chained call e.g. posthog.get_group().set()\n } else if (isFunction(item)) {\n ;(item as any).call(this)\n } else if (isArray(item) && fn_name === 'alias') {\n alias_calls.push(item)\n } else if (isArray(item) && fn_name.indexOf('capture') !== -1 && isFunction((this as any)[fn_name])) {\n capturing_calls.push(item)\n } else {\n other_calls.push(item)\n }\n }\n })\n\n const execute = function (calls: SnippetArrayItem[], thisArg: any) {\n eachArray(\n calls,\n function (item) {\n if (isArray(item[0])) {\n // chained call\n let caller = thisArg\n each(item, function (call) {\n caller = caller[call[0]].apply(caller, call.slice(1))\n })\n } else {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this[item[0]].apply(this, item.slice(1))\n }\n },\n thisArg\n )\n }\n\n execute(alias_calls, this)\n execute(other_calls, this)\n execute(capturing_calls, this)\n }\n\n _hasBootstrappedFeatureFlags(): boolean {\n return (\n (this.config.bootstrap?.featureFlags && Object.keys(this.config.bootstrap?.featureFlags).length > 0) ||\n false\n )\n }\n\n /**\n * push() keeps the standard async-array-push\n * behavior around after the lib is loaded.\n * This is only useful for external integrations that\n * do not wish to rely on our convenience methods\n * (created in the snippet).\n *\n * @example\n * ```js\n * posthog.push(['register', { a: 'b' }]);\n * ```\n *\n * @param {Array} item A [function_name, args...] array to be executed\n */\n push(item: SnippetArrayItem): void {\n this._execute_array([item])\n }\n\n /**\n * Captures an event with optional properties and configuration.\n *\n * @remarks\n * You can capture arbitrary object-like values as events. [Learn about capture best practices](/docs/product-analytics/capture-events)\n *\n * @example\n * ```js\n * // basic event capture\n * posthog.capture('cta-button-clicked', {\n * button_name: 'Get Started',\n * page: 'homepage'\n * })\n * ```\n *\n * {@label Capture}\n *\n * @public\n *\n * @param event_name - The name of the event (e.g., 'Sign Up', 'Button Click', 'Purchase')\n * @param properties - Properties to include with the event describing the user or event details\n * @param options - Optional configuration for the capture request\n *\n * @returns The capture result containing event data, or undefined if capture failed\n */\n capture(\n event_name: EventName,\n properties?: Properties | null,\n options?: CaptureOptions\n ): CaptureResult | undefined {\n // While developing, a developer might purposefully _not_ call init(),\n // in this case, we would like capture to be a noop.\n if (!this.__loaded || !this.persistence || !this.sessionPersistence || !this._requestQueue) {\n logger.uninitializedWarning('posthog.capture')\n return\n }\n\n if (!this.is_capturing()) {\n return\n }\n\n // typing doesn't prevent interesting data\n if (isUndefined(event_name) || !isString(event_name)) {\n logger.error('No event name provided to posthog.capture')\n return\n }\n\n const isBot = !this.config.opt_out_useragent_filter && this._is_bot()\n const shouldDropBotEvent = isBot && !this.config.__preview_capture_bot_pageviews\n\n // We drop bot events unless the preview flag to send bot pageviews is enabled\n // or the user has explicitly opted out of useragent filtering\n if (shouldDropBotEvent) {\n return\n }\n\n const clientRateLimitContext = !options?.skip_client_rate_limiting\n ? this.rateLimiter.clientRateLimitContext()\n : undefined\n\n if (clientRateLimitContext?.isRateLimited) {\n logger.critical('This capture call is ignored due to client rate limiting.')\n return\n }\n\n if (properties?.$current_url && !isString(properties?.$current_url)) {\n logger.error(\n 'Invalid `$current_url` property provided to `posthog.capture`. Input must be a string. Ignoring provided value.'\n )\n delete properties?.$current_url\n }\n\n // update persistence\n this.sessionPersistence.update_search_keyword()\n\n // The initial campaign/referrer props need to be stored in the regular persistence, as they are there to mimic\n // the person-initial props. The non-initial versions are stored in the sessionPersistence, as they are sent\n // with every event and used by the session table to create session-initial props.\n if (this.config.save_campaign_params) {\n this.sessionPersistence.update_campaign_params()\n }\n if (this.config.save_referrer) {\n this.sessionPersistence.update_referrer_info()\n }\n\n if (this.config.save_campaign_params || this.config.save_referrer) {\n this.persistence.set_initial_person_info()\n }\n\n const systemTime = new Date()\n const timestamp = options?.timestamp || systemTime\n\n const uuid = uuidv7()\n let data: CaptureResult = {\n uuid,\n event: event_name,\n properties: this.calculateEventProperties(event_name, properties || {}, timestamp, uuid),\n }\n\n // Route pageviews to $bot_pageview when bot detected and preview flag enabled\n if (event_name === '$pageview' && this.config.__preview_capture_bot_pageviews && isBot) {\n data.event = '$bot_pageview'\n // While it's obvious that a $bot_pageview is (likely) from a bot, we explicitly set $browser_type\n // to make it easy to filter and test bot pageviews in the product\n data.properties.$browser_type = 'bot'\n }\n\n if (clientRateLimitContext) {\n data.properties['$lib_rate_limit_remaining_tokens'] = clientRateLimitContext.remainingTokens\n }\n\n const setProperties = options?.$set\n if (setProperties) {\n data.$set = options?.$set\n }\n // $groupidentify doesn't process person $set_once on the server, so don't mark\n // initial person props as sent. This ensures they're included with subsequent\n // $identify calls.\n const markSetOnceAsSent = event_name !== '$groupidentify'\n const setOnceProperties = this._calculate_set_once_properties(options?.$set_once, markSetOnceAsSent)\n if (setOnceProperties) {\n data.$set_once = setOnceProperties\n }\n\n data = _copyAndTruncateStrings(data, options?._noTruncate ? null : this.config.properties_string_max_length)\n data.timestamp = timestamp\n if (!isUndefined(options?.timestamp)) {\n data.properties['$event_time_override_provided'] = true\n data.properties['$event_time_override_system_time'] = systemTime\n }\n\n if (event_name === SurveyEventName.DISMISSED || event_name === SurveyEventName.SENT) {\n const surveyId = properties?.[SurveyEventProperties.SURVEY_ID]\n const surveyIteration = properties?.[SurveyEventProperties.SURVEY_ITERATION]\n setSurveySeenOnLocalStorage({ id: surveyId, current_iteration: surveyIteration })\n data.$set = {\n ...data.$set,\n [getSurveyInteractionProperty(\n { id: surveyId, current_iteration: surveyIteration },\n event_name === SurveyEventName.SENT ? 'responded' : 'dismissed'\n )]: true,\n }\n } else if (event_name === SurveyEventName.SHOWN) {\n data.$set = {\n ...data.$set,\n [SurveyEventProperties.SURVEY_LAST_SEEN_DATE]: new Date().toISOString(),\n }\n }\n\n // Top-level $set overriding values from the one from properties is taken from the plugin-server normalizeEvent\n // This doesn't handle $set_once, because posthog-people doesn't either\n const finalSet = { ...data.properties['$set'], ...data['$set'] }\n if (!isEmptyObject(finalSet)) {\n this.setPersonPropertiesForFlags(finalSet)\n }\n\n if (!isNullish(this.config.before_send)) {\n const beforeSendResult = this._runBeforeSend(data)\n if (!beforeSendResult) {\n return\n } else {\n data = beforeSendResult\n }\n }\n\n this._internalEventEmitter.emit('eventCaptured', data)\n\n const requestOptions: QueuedRequestWithOptions = {\n method: 'POST',\n url: options?._url ?? this.requestRouter.endpointFor('api', this.analyticsDefaultEndpoint),\n data,\n compression: 'best-available',\n batchKey: options?._batchKey,\n }\n\n if (this.config.request_batching && (!options || options?._batchKey) && !options?.send_instantly) {\n this._requestQueue.enqueue(requestOptions)\n } else {\n this._send_retriable_request(requestOptions)\n }\n\n return data\n }\n\n _addCaptureHook(callback: (eventName: string, eventPayload?: CaptureResult) => void): () => void {\n return this.on('eventCaptured', (data) => callback(data.event, data))\n }\n\n /**\n * This method is used internally to calculate the event properties before sending it to PostHog. It can also be\n * used by integrations (e.g. Segment) to enrich events with PostHog properties before sending them to Segment,\n * which is required for some PostHog products to work correctly. (e.g. to have a correct $session_id property).\n *\n * @param {String} eventName The name of the event. This can be anything the user does - 'Button Click', 'Sign Up', '$pageview', etc.\n * @param {Object} eventProperties The properties to include with the event.\n * @param {Date} [timestamp] The timestamp of the event, e.g. for calculating time on page. If not set, it'll automatically be set to the current time.\n * @param {String} [uuid] The uuid of the event, e.g. for storing the $pageview ID.\n * @param {Boolean} [readOnly] Set this if you do not intend to actually send the event, and therefore do not want to update internal state e.g. session timeout\n *\n * @internal\n */\n public calculateEventProperties(\n eventName: string,\n eventProperties: Properties,\n timestamp?: Date,\n uuid?: string,\n readOnly?: boolean\n ): Properties {\n timestamp = timestamp || new Date()\n if (!this.persistence || !this.sessionPersistence) {\n return eventProperties\n }\n\n // set defaults\n const startTimestamp = readOnly ? undefined : this.persistence.remove_event_timer(eventName)\n let properties = { ...eventProperties }\n properties['token'] = this.config.token\n properties['$config_defaults'] = this.config.defaults\n\n if (\n this.config.cookieless_mode == 'always' ||\n (this.config.cookieless_mode == 'on_reject' && this.consent.isExplicitlyOptedOut())\n ) {\n // Set a flag to tell the plugin server to use cookieless server hash mode\n properties[COOKIELESS_MODE_FLAG_PROPERTY] = true\n }\n\n if (eventName === '$snapshot') {\n const persistenceProps = { ...this.persistence.properties(), ...this.sessionPersistence.properties() }\n properties['distinct_id'] = persistenceProps.distinct_id\n if (\n // we spotted one customer that was managing to send `false` for ~9k events a day\n !(isString(properties['distinct_id']) || isNumber(properties['distinct_id'])) ||\n isEmptyString(properties['distinct_id'])\n ) {\n logger.error('Invalid distinct_id for replay event. This indicates a bug in your implementation')\n }\n return properties\n }\n\n const infoProperties = getEventProperties(\n this.config.mask_personal_data_properties,\n this.config.custom_personal_data_properties\n )\n\n if (this.sessionManager) {\n const { sessionId, windowId } = this.sessionManager.checkAndGetSessionAndWindowId(\n readOnly,\n timestamp.getTime()\n )\n properties['$session_id'] = sessionId\n properties['$window_id'] = windowId\n }\n if (this.sessionPropsManager) {\n extend(properties, this.sessionPropsManager.getSessionProps())\n }\n\n try {\n if (this.sessionRecording) {\n extend(properties, this.sessionRecording.sdkDebugProperties)\n }\n properties['$sdk_debug_retry_queue_size'] = this._retryQueue?.length\n } catch (e: any) {\n properties['$sdk_debug_error_capturing_properties'] = String(e)\n }\n\n if (this.requestRouter.region === RequestRouterRegion.CUSTOM) {\n properties['$lib_custom_api_host'] = this.config.api_host\n }\n\n let pageviewProperties: Record<string, any>\n if (eventName === '$pageview' && !readOnly) {\n pageviewProperties = this.pageViewManager.doPageView(timestamp, uuid)\n } else if (eventName === '$pageleave' && !readOnly) {\n pageviewProperties = this.pageViewManager.doPageLeave(timestamp)\n } else {\n pageviewProperties = this.pageViewManager.doEvent()\n }\n properties = extend(properties, pageviewProperties)\n\n if (eventName === '$pageview' && document) {\n properties['title'] = document.title\n }\n\n // set $duration if time_event was previously called for this event\n if (!isUndefined(startTimestamp)) {\n const duration_in_ms = timestamp.getTime() - startTimestamp\n properties['$duration'] = parseFloat((duration_in_ms / 1000).toFixed(3))\n }\n\n // this is only added when this.config.opt_out_useragent_filter is true,\n // or it would always add \"browser\"\n if (userAgent && this.config.opt_out_useragent_filter) {\n properties['$browser_type'] = this._is_bot() ? 'bot' : 'browser'\n }\n\n // note: extend writes to the first object, so lets make sure we\n // don't write to the persistence properties object and info\n // properties object by passing in a new object\n\n // update properties with pageview info and super-properties\n properties = extend(\n {},\n infoProperties,\n this.persistence.properties(),\n this.sessionPersistence.properties(),\n properties\n )\n\n properties['$is_identified'] = this._isIdentified()\n\n if (isArray(this.config.property_denylist)) {\n each(this.config.property_denylist, function (denylisted_prop) {\n delete properties[denylisted_prop]\n })\n } else {\n logger.error(\n 'Invalid value for property_denylist config: ' +\n this.config.property_denylist +\n ' or property_blacklist config: ' +\n this.config.property_blacklist\n )\n }\n\n const sanitize_properties = this.config.sanitize_properties\n if (sanitize_properties) {\n logger.error('sanitize_properties is deprecated. Use before_send instead')\n properties = sanitize_properties(properties, eventName)\n }\n\n // add person processing flag as very last step, so it cannot be overridden\n const hasPersonProcessing = this._hasPersonProcessing()\n properties['$process_person_profile'] = hasPersonProcessing\n // if the event has person processing, ensure that all future events will too, even if the setting changes\n if (hasPersonProcessing && !readOnly) {\n this._requirePersonProcessing('_calculate_event_properties')\n }\n\n return properties\n }\n\n /** @deprecated - deprecated in 1.241.0, use `calculateEventProperties` instead */\n _calculate_event_properties = this.calculateEventProperties.bind(this)\n\n /**\n * Add additional set_once properties to the event when creating a person profile. This allows us to create the\n * profile with mostly-accurate properties, despite earlier events not setting them. We do this by storing them in\n * persistence.\n * @param dataSetOnce\n * @param markAsSent - if true, marks the properties as sent so they won't be included in future events.\n * Set to false for events like $groupidentify where the server doesn't process person props.\n */\n _calculate_set_once_properties(dataSetOnce?: Properties, markAsSent: boolean = true): Properties | undefined {\n if (!this.persistence || !this._hasPersonProcessing()) {\n return dataSetOnce\n }\n\n if (this._personProcessingSetOncePropertiesSent) {\n // We only need to send these properties once. Sending them with later events would be redundant and would\n // just require extra work on the server to process them.\n return dataSetOnce\n }\n // if we're an identified person, send initial params with every event\n const initialProps = this.persistence.get_initial_props()\n const sessionProps = this.sessionPropsManager?.getSetOnceProps()\n let setOnceProperties = extend({}, initialProps, sessionProps || {}, dataSetOnce || {})\n const sanitize_properties = this.config.sanitize_properties\n if (sanitize_properties) {\n logger.error('sanitize_properties is deprecated. Use before_send instead')\n setOnceProperties = sanitize_properties(setOnceProperties, '$set_once')\n }\n if (markAsSent) {\n this._personProcessingSetOncePropertiesSent = true\n }\n if (isEmptyObject(setOnceProperties)) {\n return undefined\n }\n return setOnceProperties\n }\n\n /**\n * Registers super properties that are included with all events.\n *\n * @remarks\n * Super properties are stored in persistence and automatically added to every event you capture.\n * These values will overwrite any existing super properties with the same keys.\n *\n * @example\n * ```js\n * // register a single property\n * posthog.register({ plan: 'premium' })\n * ```\n *\n * {@label Capture}\n *\n * @example\n * ```js\n * // register multiple properties\n * posthog.register({\n * email: 'user@example.com',\n * account_type: 'business',\n * signup_date: '2023-01-15'\n * })\n * ```\n *\n * @example\n * ```js\n * // register with custom expiration\n * posthog.register({ campaign: 'summer_sale' }, 7) // expires in 7 days\n * ```\n *\n * @public\n *\n * @param {Object} properties properties to store about the user\n * @param {Number} [days] How many days since the user's last visit to store the super properties\n */\n register(properties: Properties, days?: number): void {\n this.persistence?.register(properties, days)\n }\n\n /**\n * Registers super properties only if they haven't been set before.\n *\n * @remarks\n * Unlike `register()`, this method will not overwrite existing super properties.\n * Use this for properties that should only be set once, like signup date or initial referrer.\n *\n * {@label Capture}\n *\n * @example\n * ```js\n * // register once-only properties\n * posthog.register_once({\n * first_login_date: new Date().toISOString(),\n * initial_referrer: document.referrer\n * })\n * ```\n *\n * @example\n * ```js\n * // override existing value if it matches default\n * posthog.register_once(\n * { user_type: 'premium' },\n * 'unknown' // overwrite if current value is 'unknown'\n * )\n * ```\n *\n * @public\n *\n * @param {Object} properties An associative array of properties to store about the user\n * @param {*} [default_value] Value to override if already set in super properties (ex: 'False') Default: 'None'\n * @param {Number} [days] How many days since the users last visit to store the super properties\n */\n register_once(properties: Properties, default_value?: Property, days?: number): void {\n this.persistence?.register_once(properties, default_value, days)\n }\n\n /**\n * Registers super properties for the current session only.\n *\n * @remarks\n * Session super properties are automatically added to all events during the current browser session.\n * Unlike regular super properties, these are cleared when the session ends and are stored in sessionStorage.\n *\n * {@label Capture}\n *\n * @example\n * ```js\n * // register session-specific properties\n * posthog.register_for_session({\n * current_page_type: 'checkout',\n * ab_test_variant: 'control'\n * })\n * ```\n *\n * @example\n * ```js\n * // register properties for user flow tracking\n * posthog.register_for_session({\n * selected_plan: 'pro',\n * completed_steps: 3,\n * flow_id: 'signup_flow_v2'\n * })\n * ```\n *\n * @public\n *\n * @param {Object} properties An associative array of properties to store about the user\n */\n register_for_session(properties: Properties): void {\n this.sessionPersistence?.register(properties)\n }\n\n /**\n * Removes a super property from persistent storage.\n *\n * @remarks\n * This will stop the property from being automatically included in future events.\n * The property will be permanently removed from the user's profile.\n *\n * {@label Capture}\n *\n * @example\n * ```js\n * // remove a super property\n * posthog.unregister('plan_type')\n * ```\n *\n * @public\n *\n * @param {String} property The name of the super property to remove\n */\n unregister(property: string): void {\n this.persistence?.unregister(property)\n }\n\n /**\n * Removes a session super property from the current session.\n *\n * @remarks\n * This will stop the property from being automatically included in future events for this session.\n * The property is removed from sessionStorage.\n *\n * {@label Capture}\n *\n * @example\n * ```js\n * // remove a session property\n * posthog.unregister_for_session('current_flow')\n * ```\n *\n * @public\n *\n * @param {String} property The name of the session super property to remove\n */\n unregister_for_session(property: string): void {\n this.sessionPersistence?.unregister(property)\n }\n\n _register_single(prop: string, value: Property) {\n this.register({ [prop]: value })\n }\n\n /**\n * Gets the value of a feature flag for the current user.\n *\n * @remarks\n * Returns the feature flag value which can be a boolean, string, or undefined.\n * Supports multivariate flags that can return custom string values.\n *\n * {@label Feature flags}\n *\n * @example\n * ```js\n * // check boolean flag\n * if (posthog.getFeatureFlag('new-feature')) {\n * // show new feature\n * }\n * ```\n *\n * @example\n * ```js\n * // check multivariate flag\n * const variant = posthog.getFeatureFlag('button-color')\n * if (variant === 'red') {\n * // show red button\n * }\n * ```\n *\n * @public\n *\n * @param {Object|String} prop Key of the feature flag.\n * @param {Object|String} options (optional) If {send_event: false}, we won't send an $feature_flag_call event to PostHog.\n */\n getFeatureFlag(key: string, options?: { send_event?: boolean }): boolean | string | undefined {\n return this.featureFlags.getFeatureFlag(key, options)\n }\n\n /**\n * Get feature flag payload value matching key for user (supports multivariate flags).\n *\n * {@label Feature flags}\n *\n * @example\n * ```js\n * if(posthog.getFeatureFlag('beta-feature') === 'some-value') {\n * const someValue = posthog.getFeatureFlagPayload('beta-feature')\n * // do something\n * }\n * ```\n *\n * @public\n *\n * @param {Object|String} prop Key of the feature flag.\n */\n getFeatureFlagPayload(key: string): JsonType {\n const payload = this.featureFlags.getFeatureFlagPayload(key)\n try {\n return JSON.parse(payload as any)\n } catch {\n return payload\n }\n }\n\n /**\n * Checks if a feature flag is enabled for the current user.\n *\n * @remarks\n * Returns true if the flag is enabled, false if disabled, or undefined if not found.\n * This is a convenience method that treats any truthy value as enabled.\n *\n * {@label Feature flags}\n *\n * @example\n * ```js\n * // simple feature flag check\n * if (posthog.isFeatureEnabled('new-checkout')) {\n * showNewCheckout()\n * }\n * ```\n *\n * @example\n * ```js\n * // disable event tracking\n * if (posthog.isFeatureEnabled('feature', { send_event: false })) {\n * // flag checked without sending $feature_flag_call event\n * }\n * ```\n *\n * @public\n *\n * @param {Object|String} prop Key of the feature flag.\n * @param {Object|String} options (optional) If {send_event: false}, we won't send an $feature_flag_call event to PostHog.\n */\n isFeatureEnabled(key: string, options?: { send_event: boolean }): boolean | undefined {\n return this.featureFlags.isFeatureEnabled(key, options)\n }\n\n /**\n * Feature flag values are cached. If something has changed with your user and you'd like to refetch their flag values, call this method.\n *\n * {@label Feature flags}\n *\n * @example\n * ```js\n * posthog.reloadFeatureFlags()\n * ```\n *\n * @public\n */\n reloadFeatureFlags(): void {\n this.featureFlags.reloadFeatureFlags()\n }\n\n /**\n * Manually update feature flag values without making a network request.\n *\n * This is useful when you have feature flag values from an external source\n * (e.g., server-side evaluation, edge middleware) and want to inject them\n * into the client SDK.\n *\n * {@label Feature flags}\n *\n * @example\n * ```js\n * // Replace all flags with server-evaluated values\n * posthog.updateFlags({\n * 'my-flag': true,\n * 'my-experiment': 'variant-a'\n * })\n *\n * // Merge with existing flags (update only specified flags)\n * posthog.updateFlags(\n * { 'my-flag': true },\n * undefined,\n * { merge: true }\n * )\n *\n * // With payloads\n * posthog.updateFlags(\n * { 'my-flag': true },\n * { 'my-flag': { some: 'data' } }\n * )\n * ```\n *\n * @param flags - An object mapping flag keys to their values (boolean or string variant)\n * @param payloads - Optional object mapping flag keys to their JSON payloads\n * @param options - Optional settings. Use `{ merge: true }` to merge with existing flags instead of replacing.\n * @public\n */\n updateFlags(\n flags: Record<string, boolean | string>,\n payloads?: Record<string, JsonType>,\n options?: { merge?: boolean }\n ): void {\n // If merging, combine with existing flags\n const existingFlags = options?.merge ? this.featureFlags.getFlagVariants() : {}\n const existingPayloads = options?.merge ? this.featureFlags.getFlagPayloads() : {}\n const finalFlags = { ...existingFlags, ...flags }\n const finalPayloads = { ...existingPayloads, ...payloads }\n\n // Convert simple flags to v4 format to avoid deprecation warning\n const flagDetails: Record<string, FeatureFlagDetail> = {}\n for (const [key, value] of Object.entries(finalFlags)) {\n const isVariant = typeof value === 'string'\n flagDetails[key] = {\n key,\n enabled: isVariant ? true : Boolean(value),\n variant: isVariant ? value : undefined,\n reason: undefined,\n // id: 0 indicates manually injected flags (not from server evaluation)\n metadata: !isUndefined(finalPayloads?.[key])\n ? { id: 0, version: undefined, description: undefined, payload: finalPayloads[key] }\n : undefined,\n }\n }\n\n this.featureFlags.receivedFeatureFlags({\n flags: flagDetails,\n })\n }\n\n /**\n * Opt the user in or out of an early access feature. [Learn more in the docs](/docs/feature-flags/early-access-feature-management#option-2-custom-implementation)\n *\n * {@label Feature flags}\n *\n * @example\n * ```js\n * const toggleBeta = (betaKey) => {\n * if (activeBetas.some(\n * beta => beta.flagKey === betaKey\n * )) {\n * posthog.updateEarlyAccessFeatureEnrollment(\n * betaKey,\n * false\n * )\n * setActiveBetas(\n * prevActiveBetas => prevActiveBetas.filter(\n * item => item.flagKey !== betaKey\n * )\n * );\n * return\n * }\n *\n * posthog.updateEarlyAccessFeatureEnrollment(\n * betaKey,\n * true\n * )\n * setInactiveBetas(\n * prevInactiveBetas => prevInactiveBetas.filter(\n * item => item.flagKey !== betaKey\n * )\n * );\n * }\n *\n * const registerInterest = (featureKey) => {\n * posthog.updateEarlyAccessFeatureEnrollment(\n * featureKey,\n * true\n * )\n * // Update UI to show user has registered\n * }\n * ```\n *\n * @public\n *\n * @param {String} key The key of the feature flag to update.\n * @param {Boolean} isEnrolled Whether the user is enrolled in the feature.\n * @param {String} [stage] The stage of the feature flag to update.\n */\n updateEarlyAccessFeatureEnrollment(key: string, isEnrolled: boolean, stage?: string): void {\n this.featureFlags.updateEarlyAccessFeatureEnrollment(key, isEnrolled, stage)\n }\n\n /**\n * Get the list of early access features. To check enrollment status, use `isFeatureEnabled`. [Learn more in the docs](/docs/feature-flags/early-access-feature-management#option-2-custom-implementation)\n *\n * {@label Feature flags}\n *\n * @example\n * ```js\n * const posthog = usePostHog()\n * const activeFlags = useActiveFeatureFlags()\n *\n * const [activeBetas, setActiveBetas] = useState([])\n * const [inactiveBetas, setInactiveBetas] = useState([])\n * const [comingSoonFeatures, setComingSoonFeatures] = useState([])\n *\n * useEffect(() => {\n * posthog.getEarlyAccessFeatures((features) => {\n * // Filter features by stage\n * const betaFeatures = features.filter(feature => feature.stage === 'beta')\n * const conceptFeatures = features.filter(feature => feature.stage === 'concept')\n *\n * setComingSoonFeatures(conceptFeatures)\n *\n * if (!activeFlags || activeFlags.length === 0) {\n * setInactiveBetas(betaFeatures)\n * return\n * }\n *\n * const activeBetas = betaFeatures.filter(\n * beta => activeFlags.includes(beta.flagKey)\n * );\n * const inactiveBetas = betaFeatures.filter(\n * beta => !activeFlags.includes(beta.flagKey)\n * );\n * setActiveBetas(activeBetas)\n * setInactiveBetas(inactiveBetas)\n * }, true, ['concept', 'beta'])\n * }, [activeFlags])\n * ```\n *\n * @public\n *\n * @param {Function} callback The callback function will be called when the early access features are loaded.\n * @param {Boolean} [force_reload] Whether to force a reload of the early access features.\n * @param {String[]} [stages] The stages of the early access features to load.\n */\n getEarlyAccessFeatures(\n callback: EarlyAccessFeatureCallback,\n force_reload = false,\n stages?: EarlyAccessFeatureStage[]\n ): void {\n return this.featureFlags.getEarlyAccessFeatures(callback, force_reload, stages)\n }\n\n /**\n * Exposes a set of events that PostHog will emit.\n * e.g. `eventCaptured` is emitted immediately before trying to send an event\n *\n * Unlike `onFeatureFlags` and `onSessionId` these are not called when the\n * listener is registered, the first callback will be the next event\n * _after_ registering a listener\n *\n * {@label Capture}\n *\n * @example\n * ```js\n * posthog.on('eventCaptured', (event) => {\n * console.log(event)\n * })\n * ```\n *\n * @public\n *\n * @param {String} event The event to listen for.\n * @param {Function} cb The callback function to call when the event is emitted.\n * @returns {Function} A function that can be called to unsubscribe the listener.\n */\n on(event: 'eventCaptured', cb: (...args: any[]) => void): () => void {\n return this._internalEventEmitter.on(event, cb)\n }\n\n /**\n * Register an event listener that runs when feature flags become available or when they change.\n * If there are flags, the listener is called immediately in addition to being called on future changes.\n * Note that this is not called only when we fetch feature flags from the server, but also when they change in the browser.\n *\n * {@label Feature flags}\n *\n * @example\n * ```js\n * posthog.onFeatureFlags(function(featureFlags, featureFlagsVariants, { errorsLoading }) {\n * // do something\n * })\n * ```\n *\n * @param callback - The callback function will be called once the feature flags are ready or when they are updated.\n * It'll return a list of feature flags enabled for the user, the variants,\n * and also a context object indicating whether we succeeded to fetch the flags or not.\n * @returns A function that can be called to unsubscribe the listener. Used by `useEffect` when the component unmounts.\n */\n onFeatureFlags(callback: FeatureFlagsCallback): () => void {\n return this.featureFlags.onFeatureFlags(callback)\n }\n\n /**\n * Register an event listener that runs when surveys are loaded.\n *\n * Callback parameters:\n * - surveys: Survey[]: An array containing all survey objects fetched from PostHog using the getSurveys method\n * - context: { isLoaded: boolean, error?: string }: An object indicating if the surveys were loaded successfully\n *\n * {@label Surveys}\n *\n * @example\n * ```js\n * posthog.onSurveysLoaded((surveys, context) => { // do something })\n * ```\n *\n *\n * @param {Function} callback The callback function will be called when surveys are loaded or updated.\n * @returns {Function} A function that can be called to unsubscribe the listener.\n */\n onSurveysLoaded(callback: SurveyCallback): () => void {\n return this.surveys.onSurveysLoaded(callback)\n }\n\n /**\n * Register an event listener that runs whenever the session id or window id change.\n * If there is already a session id, the listener is called immediately in addition to being called on future changes.\n *\n * Can be used, for example, to sync the PostHog session id with a backend session.\n *\n * {@label Identification}\n *\n * @example\n * ```js\n * posthog.onSessionId(function(sessionId, windowId) { // do something })\n * ```\n *\n * @param {Function} [callback] The callback function will be called once a session id is present or when it or the window id are updated.\n * @returns {Function} A function that can be called to unsubscribe the listener. E.g. Used by `useEffect` when the component unmounts.\n */\n onSessionId(callback: SessionIdChangedCallback): () => void {\n return this.sessionManager?.onSessionId(callback) ?? (() => {})\n }\n\n /**\n * Get list of all surveys.\n *\n * {@label Surveys}\n *\n * @example\n * ```js\n * function callback(surveys, context) {\n * // do something\n * }\n *\n * posthog.getSurveys(callback, false)\n * ```\n *\n * @public\n *\n * @param {Function} [callback] Function that receives the array of surveys\n * @param {Boolean} [forceReload] Optional boolean to force an API call for updated surveys\n */\n getSurveys(callback: SurveyCallback, forceReload = false): void {\n this.surveys.getSurveys(callback, forceReload)\n }\n\n /**\n * Get surveys that should be enabled for the current user. See [fetching surveys documentation](/docs/surveys/implementing-custom-surveys#fetching-surveys-manually) for more details.\n *\n * {@label Surveys}\n *\n * @example\n * ```js\n * posthog.getActiveMatchingSurveys((surveys) => {\n * // do something\n * })\n * ```\n *\n * @public\n *\n * @param {Function} [callback] The callback function will be called when the surveys are loaded or updated.\n * @param {Boolean} [forceReload] Whether to force a reload of the surveys.\n */\n getActiveMatchingSurveys(callback: SurveyCallback, forceReload = false): void {\n this.surveys.getActiveMatchingSurveys(callback, forceReload)\n }\n\n /**\n * Although we recommend using popover surveys and display conditions,\n * if you want to show surveys programmatically without setting up all\n * the extra logic needed for API surveys, you can render surveys\n * programmatically with the renderSurvey method.\n *\n * This takes a survey ID and an HTML selector to render an unstyled survey.\n *\n * {@label Surveys}\n *\n * @example\n * ```js\n * posthog.renderSurvey(coolSurveyID, '#survey-container')\n * ```\n *\n * @deprecated Use displaySurvey instead - it's more complete and also supports popover surveys.\n *\n * @public\n *\n * @param {String} surveyId The ID of the survey to render.\n * @param {String} selector The selector of the HTML element to render the survey on.\n */\n renderSurvey(surveyId: string, selector: string): void {\n this.surveys.renderSurvey(surveyId, selector)\n }\n\n /**\n * Display a survey programmatically as either a popover or inline element.\n *\n * @param {string} surveyId - The survey ID to display\n * @param {DisplaySurveyOptions} options - Display configuration\n *\n * @example\n * ```js\n * // Display as popover (respects all conditions defined in the dashboard)\n * posthog.displaySurvey('survey-id-123')\n * ```\n *\n * @example\n * ```js\n * // Display inline in a specific element\n * posthog.displaySurvey('survey-id-123', {\n * displayType: DisplaySurveyType.Inline,\n * selector: '#survey-container'\n * })\n * ```\n *\n * @example\n * ```js\n * // Force display ignoring conditions and delays\n * posthog.displaySurvey('survey-id-123', {\n * displayType: DisplaySurveyType.Popover,\n * ignoreConditions: true,\n * ignoreDelay: true\n * })\n * ```\n *\n * {@label Surveys}\n */\n displaySurvey(surveyId: string, options: DisplaySurveyOptions = DEFAULT_DISPLAY_SURVEY_OPTIONS): void {\n this.surveys.displaySurvey(surveyId, options)\n }\n\n /**\n * Cancels a pending survey that is waiting to be displayed (e.g., due to a popup delay).\n *\n * {@label Surveys}\n */\n cancelPendingSurvey(surveyId: string): void {\n this.surveys.cancelPendingSurvey(surveyId)\n }\n\n /**\n * Checks the feature flags associated with this Survey to see if the survey can be rendered.\n * This method is deprecated because it's synchronous and won't return the correct result if surveys are not loaded.\n * Use `canRenderSurveyAsync` instead.\n *\n * {@label Surveys}\n *\n *\n * @deprecated\n *\n * @param surveyId The ID of the survey to check.\n * @returns A SurveyRenderReason object indicating if the survey can be rendered.\n */\n canRenderSurvey(surveyId: string): SurveyRenderReason | null {\n return this.surveys.canRenderSurvey(surveyId)\n }\n\n /**\n * Checks the feature flags associated with this Survey to see if the survey can be rendered.\n *\n * {@label Surveys}\n *\n * @example\n * ```js\n * posthog.canRenderSurveyAsync(surveyId).then((result) => {\n * if (result.visible) {\n * // Survey can be rendered\n * console.log('Survey can be rendered')\n * } else {\n * // Survey cannot be rendered\n * console.log('Survey cannot be rendered:', result.disabledReason)\n * }\n * })\n * ```\n *\n * @public\n *\n * @param surveyId The ID of the survey to check.\n * @param forceReload If true, the survey will be reloaded from the server, Default: false\n * @returns A SurveyRenderReason object indicating if the survey can be rendered.\n */\n canRenderSurveyAsync(surveyId: string, forceReload = false): Promise<SurveyRenderReason> {\n return this.surveys.canRenderSurveyAsync(surveyId, forceReload)\n }\n\n /**\n * Associates a user with a unique identifier instead of an auto-generated ID.\n * Learn more about [identifying users](/docs/product-analytics/identify)\n *\n * {@label Identification}\n *\n * @remarks\n * By default, PostHog assigns each user a randomly generated `distinct_id`. Use this method to\n * replace that ID with your own unique identifier (like a user ID from your database).\n *\n * @example\n * ```js\n * // basic identification\n * posthog.identify('user_12345')\n * ```\n *\n * @example\n * ```js\n * // identify with user properties\n * posthog.identify('user_12345', {\n * email: 'user@example.com',\n * plan: 'premium'\n * })\n * ```\n *\n * @example\n * ```js\n * // identify with set and set_once properties\n * posthog.identify('user_12345',\n * { last_login: new Date() }, // updates every time\n * { signup_date: new Date() } // sets only once\n * )\n * ```\n *\n * @public\n *\n * @param {String} [new_distinct_id] A string that uniquely identifies a user. If not provided, the distinct_id currently in the persistent store (cookie or localStorage) will be used.\n * @param {Object} [userPropertiesToSet] Optional: An associative array of properties to store about the user. Note: For feature flag evaluations, if the same key is present in the userPropertiesToSetOnce,\n * it will be overwritten by the value in userPropertiesToSet.\n * @param {Object} [userPropertiesToSetOnce] Optional: An associative array of properties to store about the user. If property is previously set, this does not override that value.\n */\n identify(new_distinct_id?: string, userPropertiesToSet?: Properties, userPropertiesToSetOnce?: Properties): void {\n if (!this.__loaded || !this.persistence) {\n return logger.uninitializedWarning('posthog.identify')\n }\n if (isNumber(new_distinct_id)) {\n new_distinct_id = (new_distinct_id as number).toString()\n logger.warn(\n 'The first argument to posthog.identify was a number, but it should be a string. It has been converted to a string.'\n )\n }\n\n //if the new_distinct_id has not been set ignore the identify event\n if (!new_distinct_id) {\n logger.error('Unique user id has not been set in posthog.identify')\n return\n }\n\n if (isDistinctIdStringLike(new_distinct_id)) {\n logger.critical(\n `The string \"${new_distinct_id}\" was set in posthog.identify which indicates an error. This ID should be unique to the user and not a hardcoded string.`\n )\n return\n }\n if (new_distinct_id === COOKIELESS_SENTINEL_VALUE) {\n logger.critical(\n `The string \"${COOKIELESS_SENTINEL_VALUE}\" was set in posthog.identify which indicates an error. This ID is only used as a sentinel value.`\n )\n return\n }\n\n if (!this._requirePersonProcessing('posthog.identify')) {\n return\n }\n\n const previous_distinct_id = this.get_distinct_id()\n this.register({ $user_id: new_distinct_id })\n\n if (!this.get_property('$device_id')) {\n // The persisted distinct id might not actually be a device id at all\n // it might be a distinct id of the user from before\n const device_id = previous_distinct_id\n this.register_once(\n {\n $had_persisted_distinct_id: true,\n $device_id: device_id,\n },\n ''\n )\n }\n\n // if the previous distinct id had an alias stored, then we clear it\n if (new_distinct_id !== previous_distinct_id && new_distinct_id !== this.get_property(ALIAS_ID_KEY)) {\n this.unregister(ALIAS_ID_KEY)\n this.register({ distinct_id: new_distinct_id })\n }\n\n const isKnownAnonymous = (this.persistence.get_property(USER_STATE) || 'anonymous') === 'anonymous'\n\n // send an $identify event any time the distinct_id is changing and the old ID is an anonymous ID\n // - logic on the server will determine whether or not to do anything with it.\n if (new_distinct_id !== previous_distinct_id && isKnownAnonymous) {\n this.persistence.set_property(USER_STATE, 'identified')\n\n // Update current user properties\n this.setPersonPropertiesForFlags(\n { ...(userPropertiesToSetOnce || {}), ...(userPropertiesToSet || {}) },\n false\n )\n\n this.capture(\n '$identify',\n {\n distinct_id: new_distinct_id,\n $anon_distinct_id: previous_distinct_id,\n },\n { $set: userPropertiesToSet || {}, $set_once: userPropertiesToSetOnce || {} }\n )\n\n this._cachedPersonProperties = getPersonPropertiesHash(\n new_distinct_id,\n userPropertiesToSet,\n userPropertiesToSetOnce\n )\n\n // let the reload feature flag request know to send this previous distinct id\n // for flag consistency\n this.featureFlags.setAnonymousDistinctId(previous_distinct_id)\n } else if (userPropertiesToSet || userPropertiesToSetOnce) {\n // If the distinct_id is not changing, but we have user properties to set, we can check if they have changed\n // and if so, send a $set event\n\n this.setPersonProperties(userPropertiesToSet, userPropertiesToSetOnce)\n }\n\n // Reload active feature flags if the user identity changes.\n // Note we don't reload this on property changes as these get processed async\n if (new_distinct_id !== previous_distinct_id) {\n this.reloadFeatureFlags()\n // also clear any stored flag calls\n this.unregister(FLAG_CALL_REPORTED)\n }\n }\n\n /**\n * Sets properties on the person profile associated with the current `distinct_id`.\n * Learn more about [identifying users](/docs/product-analytics/identify)\n *\n * {@label Identification}\n *\n * @remarks\n * Updates user properties that are stored with the person profile in PostHog.\n * If `person_profiles` is set to `identified_only` and no profile exists, this will create one.\n *\n * @example\n * ```js\n * // set user properties\n * posthog.setPersonProperties({\n * email: 'user@example.com',\n * plan: 'premium'\n * })\n * ```\n *\n * @example\n * ```js\n * // set properties\n * posthog.setPersonProperties(\n * { name: 'Max Hedgehog' }, // $set properties\n * { initial_url: '/blog' } // $set_once properties\n * )\n * ```\n *\n * @public\n *\n * @param {Object} [userPropertiesToSet] Optional: An associative array of properties to store about the user. Note: For feature flag evaluations, if the same key is present in the userPropertiesToSetOnce,\n * it will be overwritten by the value in userPropertiesToSet.\n * @param {Object} [userPropertiesToSetOnce] Optional: An associative array of properties to store about the user. If property is previously set, this does not override that value.\n */\n setPersonProperties(userPropertiesToSet?: Properties, userPropertiesToSetOnce?: Properties): void {\n if (!userPropertiesToSet && !userPropertiesToSetOnce) {\n return\n }\n\n if (!this._requirePersonProcessing('posthog.setPersonProperties')) {\n return\n }\n\n const hash = getPersonPropertiesHash(this.get_distinct_id(), userPropertiesToSet, userPropertiesToSetOnce)\n\n // if exactly this $set call has been sent before, don't send it again - determine based on hash of properties\n if (this._cachedPersonProperties === hash) {\n logger.info('A duplicate setPersonProperties call was made with the same properties. It has been ignored.')\n return\n }\n\n // Update current user properties\n this.setPersonPropertiesForFlags({ ...(userPropertiesToSetOnce || {}), ...(userPropertiesToSet || {}) })\n\n this.capture('$set', { $set: userPropertiesToSet || {}, $set_once: userPropertiesToSetOnce || {} })\n\n this._cachedPersonProperties = hash\n }\n\n /**\n * Associates the user with a group for group-based analytics.\n * Learn more about [groups](/docs/product-analytics/group-analytics)\n *\n * {@label Identification}\n *\n * @remarks\n * Groups allow you to analyze users collectively (e.g., by organization, team, or account).\n * This sets the group association for all subsequent events and reloads feature flags.\n *\n * @example\n * ```js\n * // associate user with an organization\n * posthog.group('organization', 'org_12345', {\n * name: 'Acme Corp',\n * plan: 'enterprise'\n * })\n * ```\n *\n * @example\n * ```js\n * // associate with multiple group types\n * posthog.group('organization', 'org_12345')\n * posthog.group('team', 'team_67890')\n * ```\n *\n * @public\n *\n * @param {String} groupType Group type (example: 'organization')\n * @param {String} groupKey Group key (example: 'org::5')\n * @param {Object} groupPropertiesToSet Optional properties to set for group\n */\n group(groupType: string, groupKey: string, groupPropertiesToSet?: Properties): void {\n if (!groupType || !groupKey) {\n logger.error('posthog.group requires a group type and group key')\n return\n }\n\n const existingGroups = this.getGroups()\n\n // if group key changes, remove stored group properties\n if (existingGroups[groupType] !== groupKey) {\n this.resetGroupPropertiesForFlags(groupType)\n }\n\n this.register({ $groups: { ...existingGroups, [groupType]: groupKey } })\n\n if (groupPropertiesToSet) {\n this.capture('$groupidentify', {\n $group_type: groupType,\n $group_key: groupKey,\n $group_set: groupPropertiesToSet,\n })\n this.setGroupPropertiesForFlags({ [groupType]: groupPropertiesToSet })\n }\n\n // If groups change and no properties change, reload feature flags.\n // The property change reload case is handled in setGroupPropertiesForFlags.\n if (existingGroups[groupType] !== groupKey && !groupPropertiesToSet) {\n this.reloadFeatureFlags()\n }\n }\n\n /**\n * Resets only the group properties of the user currently logged in.\n * Learn more about [groups](/docs/product-analytics/group-analytics)\n *\n * {@label Identification}\n *\n * @example\n * ```js\n * posthog.resetGroups()\n * ```\n *\n * @public\n */\n resetGroups(): void {\n this.register({ $groups: {} })\n this.resetGroupPropertiesForFlags()\n\n // If groups changed, reload feature flags.\n this.reloadFeatureFlags()\n }\n\n /**\n * Sometimes, you might want to evaluate feature flags using properties that haven't been ingested yet,\n * or were set incorrectly earlier. You can do so by setting properties the flag depends on with these calls:\n *\n * {@label Feature flags}\n *\n * @example\n * ```js\n * // Set properties\n * posthog.setPersonPropertiesForFlags({'property1': 'value', property2: 'value2'})\n * ```\n *\n * @example\n * ```js\n * // Set properties without reloading\n * posthog.setPersonPropertiesForFlags({'property1': 'value', property2: 'value2'}, false)\n * ```\n *\n * @public\n *\n * @param {Object} properties The properties to override.\n * @param {Boolean} [reloadFeatureFlags] Whether to reload feature flags.\n */\n setPersonPropertiesForFlags(properties: Properties, reloadFeatureFlags = true): void {\n this.featureFlags.setPersonPropertiesForFlags(properties, reloadFeatureFlags)\n }\n\n /**\n * Resets the person properties for feature flags.\n *\n * {@label Feature flags}\n *\n * @public\n *\n * @example\n * ```js\n * posthog.resetPersonPropertiesForFlags()\n * ```\n */\n resetPersonPropertiesForFlags(): void {\n this.featureFlags.resetPersonPropertiesForFlags()\n }\n\n /**\n * Set override group properties for feature flags.\n * This is used when dealing with new groups / where you don't want to wait for ingestion\n * to update properties.\n * Takes in an object, the key of which is the group type.\n *\n * {@label Feature flags}\n *\n * @public\n *\n * @example\n * ```js\n * // Set properties with reload\n * posthog.setGroupPropertiesForFlags({'organization': { name: 'CYZ', employees: '11' } })\n * ```\n *\n * @example\n * ```js\n * // Set properties without reload\n * posthog.setGroupPropertiesForFlags({'organization': { name: 'CYZ', employees: '11' } }, false)\n * ```\n *\n * @param {Object} properties The properties to override, the key of which is the group type.\n * @param {Boolean} [reloadFeatureFlags] Whether to reload feature flags.\n */\n setGroupPropertiesForFlags(properties: { [type: string]: Properties }, reloadFeatureFlags = true): void {\n if (!this._requirePersonProcessing('posthog.setGroupPropertiesForFlags')) {\n return\n }\n this.featureFlags.setGroupPropertiesForFlags(properties, reloadFeatureFlags)\n }\n\n /**\n * Resets the group properties for feature flags.\n *\n * {@label Feature flags}\n *\n * @public\n *\n * @example\n * ```js\n * posthog.resetGroupPropertiesForFlags()\n * ```\n */\n resetGroupPropertiesForFlags(group_type?: string): void {\n this.featureFlags.resetGroupPropertiesForFlags(group_type)\n }\n\n /**\n * Resets all user data and starts a fresh session.\n *\n * ⚠️ **Warning**: Only call this when a user logs out. Calling at the wrong time can cause split sessions.\n *\n * This clears:\n * - Session ID and super properties\n * - User identification (sets new random distinct_id)\n * - Cached data and consent settings\n *\n * {@label Identification}\n * @example\n * ```js\n * // reset on user logout\n * function logout() {\n * posthog.reset()\n * // redirect to login page\n * }\n * ```\n *\n * @example\n * ```js\n * // reset and generate new device ID\n * posthog.reset(true) // also resets device_id\n * ```\n *\n * @public\n */\n reset(reset_device_id?: boolean): void {\n logger.info('reset')\n if (!this.__loaded) {\n return logger.uninitializedWarning('posthog.reset')\n }\n const device_id = this.get_property('$device_id')\n this.consent.reset()\n this.persistence?.clear()\n this.sessionPersistence?.clear()\n this.surveys.reset()\n this.featureFlags.reset()\n this.persistence?.set_property(USER_STATE, 'anonymous')\n this.sessionManager?.resetSessionId()\n this._cachedPersonProperties = null\n if (this.config.cookieless_mode === 'always') {\n this.register_once(\n {\n distinct_id: COOKIELESS_SENTINEL_VALUE,\n $device_id: null,\n },\n ''\n )\n } else {\n const uuid = this.config.get_device_id(uuidv7())\n this.register_once(\n {\n distinct_id: uuid,\n $device_id: reset_device_id ? uuid : device_id,\n },\n ''\n )\n }\n\n this.register(\n {\n $last_posthog_reset: new Date().toISOString(),\n },\n 1\n )\n }\n\n /**\n * Returns the current distinct ID for the user.\n *\n * @remarks\n * This is either the auto-generated ID or the ID set via `identify()`.\n * The distinct ID is used to associate events with users in PostHog.\n *\n * {@label Identification}\n *\n * @example\n * ```js\n * // get the current user ID\n * const userId = posthog.get_distinct_id()\n * console.log('Current user:', userId)\n * ```\n *\n * @example\n * ```js\n * // use in loaded callback\n * posthog.init('token', {\n * loaded: (posthog) => {\n * const id = posthog.get_distinct_id()\n * // use the ID\n * }\n * })\n * ```\n *\n * @public\n *\n * @returns The current distinct ID\n */\n get_distinct_id(): string {\n return this.get_property('distinct_id')\n }\n\n /**\n * Returns the current groups.\n *\n * {@label Identification}\n *\n * @public\n *\n * @returns The current groups\n */\n getGroups(): Record<string, any> {\n return this.get_property('$groups') || {}\n }\n\n /**\n * Returns the current session_id.\n *\n * @remarks\n * This should only be used for informative purposes.\n * Any actual internal use case for the session_id should be handled by the sessionManager.\n *\n * @public\n *\n * @returns The stored session ID for the current session. This may be an empty string if the client is not yet fully initialized.\n */\n get_session_id(): string {\n return this.sessionManager?.checkAndGetSessionAndWindowId(true).sessionId ?? ''\n }\n\n /**\n * Returns the Replay url for the current session.\n *\n * {@label Session replay}\n *\n * @public\n *\n * @example\n * ```js\n * // basic usage\n * posthog.get_session_replay_url()\n *\n * @example\n * ```js\n * // timestamp\n * posthog.get_session_replay_url({ withTimestamp: true })\n * ```\n *\n * @example\n * ```js\n * // timestamp and lookback\n * posthog.get_session_replay_url({\n * withTimestamp: true,\n * timestampLookBack: 30 // look back 30 seconds\n * })\n * ```\n *\n * @param options Options for the url\n * @param options.withTimestamp Whether to include the timestamp in the url (defaults to false)\n * @param options.timestampLookBack How many seconds to look back for the timestamp (defaults to 10)\n */\n get_session_replay_url(options?: { withTimestamp?: boolean; timestampLookBack?: number }): string {\n if (!this.sessionManager) {\n return ''\n }\n const { sessionId, sessionStartTimestamp } = this.sessionManager.checkAndGetSessionAndWindowId(true)\n let url = this.requestRouter.endpointFor('ui', `/project/${this.config.token}/replay/${sessionId}`)\n if (options?.withTimestamp && sessionStartTimestamp) {\n const LOOK_BACK = options.timestampLookBack ?? 10\n if (!sessionStartTimestamp) {\n return url\n }\n const recordingStartTime = Math.max(\n Math.floor((new Date().getTime() - sessionStartTimestamp) / 1000) - LOOK_BACK,\n 0\n )\n url += `?t=${recordingStartTime}`\n }\n\n return url\n }\n\n /**\n * Creates an alias linking two distinct user identifiers. Learn more about [identifying users](/docs/product-analytics/identify)\n *\n * {@label Identification}\n *\n * @remarks\n * PostHog will use this to link two distinct_ids going forward (not retroactively).\n * Call this when a user signs up to connect their anonymous session with their account.\n *\n *\n * @example\n * ```js\n * // link anonymous user to account on signup\n * posthog.alias('user_12345')\n * ```\n *\n * @example\n * ```js\n * // explicit alias with original ID\n * posthog.alias('user_12345', 'anonymous_abc123')\n * ```\n *\n * @public\n *\n * @param {String} alias A unique identifier that you want to use for this user in the future.\n * @param {String} [original] The current identifier being used for this user.\n */\n alias(alias: string, original?: string): CaptureResult | void | number {\n // If the $people_distinct_id key exists in persistence, there has been a previous\n // posthog.people.identify() call made for this user. It is VERY BAD to make an alias with\n // this ID, as it will duplicate users.\n if (alias === this.get_property(PEOPLE_DISTINCT_ID_KEY)) {\n logger.critical('Attempting to create alias for existing People user - aborting.')\n return -2\n }\n if (!this._requirePersonProcessing('posthog.alias')) {\n return\n }\n\n if (isUndefined(original)) {\n original = this.get_distinct_id()\n }\n if (alias !== original) {\n this._register_single(ALIAS_ID_KEY, alias)\n return this.capture('$create_alias', { alias: alias, distinct_id: original })\n } else {\n logger.warn('alias matches current distinct_id - skipping api call.')\n this.identify(alias)\n return -1\n }\n }\n\n /**\n * Updates the configuration of the PostHog instance.\n *\n * {@label Initialization}\n *\n * @public\n *\n * @param {Partial<PostHogConfig>} config A dictionary of new configuration values to update\n */\n set_config(config: Partial<PostHogConfig>): void {\n const oldConfig = { ...this.config }\n if (isObject(config)) {\n extend(this.config, configRenames(config))\n\n const isPersistenceDisabled = this._is_persistence_disabled()\n this.persistence?.update_config(this.config, oldConfig, isPersistenceDisabled)\n this.sessionPersistence =\n this.config.persistence === 'sessionStorage' || this.config.persistence === 'memory'\n ? this.persistence\n : new PostHogPersistence({ ...this.config, persistence: 'sessionStorage' }, isPersistenceDisabled)\n\n const debugConfigFromLocalStorage = this._checkLocalStorageForDebug(this.config.debug)\n if (isBoolean(debugConfigFromLocalStorage)) {\n this.config.debug = debugConfigFromLocalStorage\n }\n\n if (isBoolean(this.config.debug)) {\n if (this.config.debug) {\n Config.DEBUG = true\n localStore._is_supported() && localStore._set('ph_debug', 'true')\n logger.info('set_config', {\n config,\n oldConfig,\n newConfig: { ...this.config },\n })\n } else {\n Config.DEBUG = false\n localStore._is_supported() && localStore._remove('ph_debug')\n }\n }\n\n this.exceptionObserver?.onConfigChange()\n\n this.sessionRecording?.startIfEnabledOrStop()\n this.autocapture?.startIfEnabled()\n this.heatmaps?.startIfEnabled()\n this.exceptionObserver?.startIfEnabledOrStop()\n this.surveys.loadIfEnabled()\n this._sync_opt_out_with_persistence()\n this.externalIntegrations?.startIfEnabledOrStop()\n }\n }\n\n /**\n * turns session recording on, and updates the config option `disable_session_recording` to false\n *\n * {@label Session replay}\n *\n * @public\n *\n * @example\n * ```js\n * // Start and ignore controls\n * posthog.startSessionRecording(true)\n * ```\n *\n * @example\n * ```js\n * // Start and override controls\n * posthog.startSessionRecording({\n * // you don't have to send all of these\n * sampling: true || false,\n * linked_flag: true || false,\n * url_trigger: true || false,\n * event_trigger: true || false\n * })\n * ```\n *\n * @param override.sampling - optional boolean to override the default sampling behavior - ensures the next session recording to start will not be skipped by sampling config.\n * @param override.linked_flag - optional boolean to override the default linked_flag behavior - ensures the next session recording to start will not be skipped by linked_flag config.\n * @param override.url_trigger - optional boolean to override the default url_trigger behavior - ensures the next session recording to start will not be skipped by url_trigger config.\n * @param override.event_trigger - optional boolean to override the default event_trigger behavior - ensures the next session recording to start will not be skipped by event_trigger config.\n * @param override - optional boolean to override the default sampling behavior - ensures the next session recording to start will not be skipped by sampling or linked_flag config. `true` is shorthand for { sampling: true, linked_flag: true }\n */\n startSessionRecording(\n override?: { sampling?: boolean; linked_flag?: boolean; url_trigger?: true; event_trigger?: true } | true\n ): void {\n const overrideAll = override === true\n const overrideConfig: OverrideConfig = {\n sampling: overrideAll || !!override?.sampling,\n linked_flag: overrideAll || !!override?.linked_flag,\n url_trigger: overrideAll || !!override?.url_trigger,\n event_trigger: overrideAll || !!override?.event_trigger,\n }\n\n if (Object.values(overrideConfig).some(Boolean)) {\n // allow the session id check to rotate session id if necessary\n this.sessionManager?.checkAndGetSessionAndWindowId()\n\n if (overrideConfig.sampling) {\n this.sessionRecording?.overrideSampling()\n }\n\n if (overrideConfig.linked_flag) {\n this.sessionRecording?.overrideLinkedFlag()\n }\n\n if (overrideConfig.url_trigger) {\n this.sessionRecording?.overrideTrigger('url')\n }\n\n if (overrideConfig.event_trigger) {\n this.sessionRecording?.overrideTrigger('event')\n }\n }\n\n this.set_config({ disable_session_recording: false })\n }\n\n /**\n * turns session recording off, and updates the config option\n * disable_session_recording to true\n *\n * {@label Session replay}\n *\n * @public\n *\n * @example\n * ```js\n * // Stop session recording\n * posthog.stopSessionRecording()\n * ```\n */\n stopSessionRecording(): void {\n this.set_config({ disable_session_recording: true })\n }\n\n /**\n * returns a boolean indicating whether session recording\n * is currently running\n *\n * {@label Session replay}\n *\n * @public\n *\n * @example\n * ```js\n * // Stop session recording if it's running\n * if (posthog.sessionRecordingStarted()) {\n * posthog.stopSessionRecording()\n * }\n * ```\n */\n sessionRecordingStarted(): boolean {\n return !!this.sessionRecording?.started\n }\n\n /**\n * Capture a caught exception manually\n *\n * {@label Error tracking}\n *\n * @public\n *\n * @example\n * ```js\n * // Capture a caught exception\n * try {\n * // something that might throw\n * } catch (error) {\n * posthog.captureException(error)\n * }\n * ```\n *\n * @example\n * ```js\n * // With additional properties\n * posthog.captureException(error, {\n * customProperty: 'value',\n * anotherProperty: ['I', 'can be a list'],\n * ...\n * })\n * ```\n *\n * @param {Error} error The error to capture\n * @param {Object} [additionalProperties] Any additional properties to add to the error event\n * @returns {CaptureResult} The result of the capture\n */\n captureException(error: unknown, additionalProperties?: Properties): CaptureResult | undefined {\n const syntheticException = new Error('PostHog syntheticException')\n const errorToProperties = this.exceptions.buildProperties(error, {\n handled: true,\n syntheticException,\n })\n return this.exceptions.sendExceptionEvent({\n ...errorToProperties,\n ...additionalProperties,\n })\n }\n\n /**\n * turns exception autocapture on, and updates the config option `capture_exceptions` to the provided config (or `true`)\n *\n * {@label Error tracking}\n *\n * @public\n *\n * @example\n * ```js\n * // Start with default exception autocapture rules. No-op if already enabled\n * posthog.startExceptionAutocapture()\n * ```\n *\n * @example\n * ```js\n * // Start and override controls\n * posthog.startExceptionAutocapture({\n * // you don't have to send all of these (unincluded values will use the default)\n * capture_unhandled_errors: true || false,\n * capture_unhandled_rejections: true || false,\n * capture_console_errors: true || false\n * })\n * ```\n *\n * @param config - optional configuration option to control the exception autocapture behavior\n */\n startExceptionAutocapture(config?: ExceptionAutoCaptureConfig): void {\n this.set_config({ capture_exceptions: config ?? true })\n }\n\n /**\n * turns exception autocapture off by updating the config option `capture_exceptions` to `false`\n *\n * {@label Error tracking}\n *\n * @public\n *\n * @example\n * ```js\n * // Stop capturing exceptions automatically\n * posthog.stopExceptionAutocapture()\n * ```\n */\n stopExceptionAutocapture(): void {\n this.set_config({ capture_exceptions: false })\n }\n\n /**\n * returns a boolean indicating whether the [toolbar](/docs/toolbar) loaded\n *\n * {@label Toolbar}\n *\n * @public\n *\n * @param toolbarParams\n * @returns {boolean} Whether the toolbar loaded\n */\n\n loadToolbar(params: ToolbarParams): boolean {\n return this.toolbar.loadToolbar(params)\n }\n\n /**\n * Returns the value of a super property. Returns undefined if the property doesn't exist.\n *\n * {@label Identification}\n *\n * @remarks\n * get_property() can only be called after the PostHog library has finished loading.\n * init() has a loaded function available to handle this automatically.\n *\n * @example\n * ```js\n * // grab value for '$user_id' after the posthog library has loaded\n * posthog.init('<YOUR PROJECT TOKEN>', {\n * loaded: function(posthog) {\n * user_id = posthog.get_property('$user_id');\n * }\n * });\n * ```\n * @public\n *\n * @param {String} property_name The name of the super property you want to retrieve\n */\n get_property(property_name: string): Property | undefined {\n return this.persistence?.props[property_name]\n }\n\n /**\n * Returns the value of the session super property named property_name. If no such\n * property is set, getSessionProperty() will return the undefined value.\n *\n * {@label Identification}\n *\n * @remarks\n * This is based on browser-level `sessionStorage`, NOT the PostHog session.\n * getSessionProperty() can only be called after the PostHog library has finished loading.\n * init() has a loaded function available to handle this automatically.\n *\n * @example\n * ```js\n * // grab value for 'user_id' after the posthog library has loaded\n * posthog.init('YOUR PROJECT TOKEN', {\n * loaded: function(posthog) {\n * user_id = posthog.getSessionProperty('user_id');\n * }\n * });\n * ```\n *\n * @param {String} property_name The name of the session super property you want to retrieve\n */\n getSessionProperty(property_name: string): Property | undefined {\n return this.sessionPersistence?.props[property_name]\n }\n\n /**\n * Returns a string representation of the PostHog instance.\n *\n * {@label Initialization}\n *\n * @internal\n */\n toString(): string {\n let name = this.config.name ?? PRIMARY_INSTANCE_NAME\n if (name !== PRIMARY_INSTANCE_NAME) {\n name = PRIMARY_INSTANCE_NAME + '.' + name\n }\n return name\n }\n\n _isIdentified(): boolean {\n return (\n this.persistence?.get_property(USER_STATE) === 'identified' ||\n this.sessionPersistence?.get_property(USER_STATE) === 'identified'\n )\n }\n\n _hasPersonProcessing(): boolean {\n return !(\n this.config.person_profiles === 'never' ||\n (this.config.person_profiles === 'identified_only' &&\n !this._isIdentified() &&\n isEmptyObject(this.getGroups()) &&\n !this.persistence?.props?.[ALIAS_ID_KEY] &&\n !this.persistence?.props?.[ENABLE_PERSON_PROCESSING])\n )\n }\n\n _shouldCapturePageleave(): boolean {\n return (\n this.config.capture_pageleave === true ||\n (this.config.capture_pageleave === 'if_capture_pageview' &&\n (this.config.capture_pageview === true || this.config.capture_pageview === 'history_change'))\n )\n }\n\n /**\n * Creates a person profile for the current user, if they don't already have one and config.person_profiles is set\n * to 'identified_only'. Produces a warning and does not create a profile if config.person_profiles is set to\n * 'never'. Learn more about [person profiles](/docs/product-analytics/identify)\n *\n * {@label Identification}\n *\n * @public\n *\n * @example\n * ```js\n * posthog.createPersonProfile()\n * ```\n */\n createPersonProfile(): void {\n if (this._hasPersonProcessing()) {\n // if a person profile already exists, don't send an event when we don't need to\n return\n }\n if (!this._requirePersonProcessing('posthog.createPersonProfile')) {\n return\n }\n // sent a $set event. We don't set any properties here, but attribution props will be added later\n this.setPersonProperties({}, {})\n }\n\n /**\n * Enables person processing if possible, returns true if it does so or already enabled, false otherwise\n *\n * @param function_name\n */\n _requirePersonProcessing(function_name: string): boolean {\n if (this.config.person_profiles === 'never') {\n logger.error(\n function_name + ' was called, but process_person is set to \"never\". This call will be ignored.'\n )\n return false\n }\n this._register_single(ENABLE_PERSON_PROCESSING, true)\n return true\n }\n\n private _is_persistence_disabled(): boolean {\n if (this.config.cookieless_mode === 'always') {\n return true\n }\n const isOptedOut = this.consent.isOptedOut()\n const defaultPersistenceDisabled =\n this.config.opt_out_persistence_by_default || this.config.cookieless_mode === 'on_reject'\n\n // TRICKY: We want a deterministic state for persistence so that a new pageload has the same persistence\n return this.config.disable_persistence || (isOptedOut && !!defaultPersistenceDisabled)\n }\n\n private _sync_opt_out_with_persistence(): boolean {\n const persistenceDisabled = this._is_persistence_disabled()\n\n if (this.persistence?._disabled !== persistenceDisabled) {\n this.persistence?.set_disabled(persistenceDisabled)\n }\n if (this.sessionPersistence?._disabled !== persistenceDisabled) {\n this.sessionPersistence?.set_disabled(persistenceDisabled)\n }\n return persistenceDisabled\n }\n\n /**\n * Opts the user into data capturing and persistence.\n *\n * {@label Privacy}\n *\n * @remarks\n * Enables event tracking and data persistence (cookies/localStorage) for this PostHog instance.\n * By default, captures an `$opt_in` event unless disabled.\n *\n * @example\n * ```js\n * // simple opt-in\n * posthog.opt_in_capturing()\n * ```\n *\n * @example\n * ```js\n * // opt-in with custom event and properties\n * posthog.opt_in_capturing({\n * captureEventName: 'Privacy Accepted',\n * captureProperties: { source: 'banner' }\n * })\n * ```\n *\n * @example\n * ```js\n * // opt-in without capturing event\n * posthog.opt_in_capturing({\n * captureEventName: false\n * })\n * ```\n *\n * @public\n *\n * @param {Object} [config] A dictionary of config options to override\n * @param {string} [config.capture_event_name=$opt_in] Event name to be used for capturing the opt-in action. Set to `null` or `false` to skip capturing the optin event\n * @param {Object} [config.capture_properties] Set of properties to be captured along with the opt-in action\n */\n opt_in_capturing(options?: {\n captureEventName?: EventName | null | false /** event name to be used for capturing the opt-in action */\n captureProperties?: Properties /** set of properties to be captured along with the opt-in action */\n }): void {\n if (this.config.cookieless_mode === 'always') {\n logger.warn('Consent opt in/out is not valid with cookieless_mode=\"always\" and will be ignored')\n return\n }\n if (this.config.cookieless_mode === 'on_reject' && this.consent.isExplicitlyOptedOut()) {\n // If the user has explicitly opted out on_reject mode, then before we can start sending regular non-cookieless events\n // we need to reset the instance to ensure that there is no leaking of state or data between the cookieless and regular events\n this.reset(true)\n this.sessionManager?.destroy()\n this.pageViewManager?.destroy()\n this.sessionManager = new SessionIdManager(this)\n this.pageViewManager = new PageViewManager(this)\n if (this.persistence) {\n this.sessionPropsManager = new SessionPropsManager(this, this.sessionManager, this.persistence)\n }\n this.sessionRecording = new SessionRecording(this)\n this.sessionRecording.startIfEnabledOrStop()\n }\n\n this.consent.optInOut(true)\n this._sync_opt_out_with_persistence()\n\n // Start queue after opting in\n this._start_queue_if_opted_in()\n\n // Restart session recording if it should now be enabled\n // (this handles the case where opt_out_capturing_by_default or cookieless_mode prevented it from starting)\n this.sessionRecording?.startIfEnabledOrStop()\n\n // Reinitialize surveys if we're in cookieless mode and just opted in\n if (this.config.cookieless_mode == 'on_reject') {\n this.surveys.loadIfEnabled()\n }\n\n // Don't capture if captureEventName is null or false\n if (isUndefined(options?.captureEventName) || options?.captureEventName) {\n this.capture(options?.captureEventName ?? '$opt_in', options?.captureProperties, { send_instantly: true })\n }\n\n if (this.config.capture_pageview) {\n this._captureInitialPageview()\n }\n }\n\n /**\n * Opts the user out of data capturing and persistence.\n *\n * {@label Privacy}\n *\n * @remarks\n * Disables event tracking and data persistence (cookies/localStorage) for this PostHog instance.\n * If `opt_out_persistence_by_default` is true, SDK persistence will also be disabled.\n *\n * @example\n * ```js\n * // opt user out (e.g., on privacy settings page)\n * posthog.opt_out_capturing()\n * ```\n *\n * @public\n */\n opt_out_capturing(): void {\n if (this.config.cookieless_mode === 'always') {\n logger.warn('Consent opt in/out is not valid with cookieless_mode=\"always\" and will be ignored')\n return\n }\n\n if (this.config.cookieless_mode === 'on_reject' && this.consent.isOptedIn()) {\n // If the user has opted in, we need to reset the instance to ensure that there is no leaking of state or data between the cookieless and regular events\n this.reset(true)\n }\n\n this.consent.optInOut(false)\n this._sync_opt_out_with_persistence()\n\n if (this.config.cookieless_mode === 'on_reject') {\n // If cookieless_mode is 'on_reject', we start capturing events in cookieless mode\n this.register({\n distinct_id: COOKIELESS_SENTINEL_VALUE,\n $device_id: null,\n })\n this.sessionManager?.destroy()\n this.pageViewManager?.destroy()\n this.sessionManager = undefined\n this.sessionPropsManager = undefined\n this.sessionRecording?.stopRecording()\n this.sessionRecording = undefined\n this._captureInitialPageview()\n }\n }\n\n /**\n * Checks if the user has opted into data capturing.\n *\n * {@label Privacy}\n *\n * @remarks\n * Returns the current consent status for event tracking and data persistence.\n *\n * @example\n * ```js\n * if (posthog.has_opted_in_capturing()) {\n * // show analytics features\n * }\n * ```\n *\n * @public\n *\n * @returns {boolean} current opt-in status\n */\n has_opted_in_capturing(): boolean {\n return this.consent.isOptedIn()\n }\n\n /**\n * Checks if the user has opted out of data capturing.\n *\n * {@label Privacy}\n *\n * @remarks\n * Returns the current consent status for event tracking and data persistence.\n *\n * @example\n * ```js\n * if (posthog.has_opted_out_capturing()) {\n * // disable analytics features\n * }\n * ```\n *\n * @public\n *\n * @returns {boolean} current opt-out status\n */\n has_opted_out_capturing(): boolean {\n return this.consent.isOptedOut()\n }\n\n /**\n * Returns the explicit consent status of the user.\n *\n * @remarks\n * This can be used to check if the user has explicitly opted in or out of data capturing, or neither. This does not\n * take the default config options into account, only whether the user has made an explicit choice, so this can be\n * used to determine whether to show an initial cookie banner or not.\n *\n * @example\n * ```js\n * const consentStatus = posthog.get_explicit_consent_status()\n * if (consentStatus === \"granted\") {\n * // user has explicitly opted in\n * } else if (consentStatus === \"denied\") {\n * // user has explicitly opted out\n * } else if (consentStatus === \"pending\"){\n * // user has not made a choice, show consent banner\n * }\n * ```\n *\n * @public\n *\n * @returns {boolean | null} current explicit consent status\n */\n get_explicit_consent_status(): 'granted' | 'denied' | 'pending' {\n const consent = this.consent.consent\n return consent === ConsentStatus.GRANTED ? 'granted' : consent === ConsentStatus.DENIED ? 'denied' : 'pending'\n }\n\n /**\n * Checks whether the PostHog library is currently capturing events.\n *\n * Usually this means that the user has not opted out of capturing, but the exact behaviour can be controlled by\n * some config options.\n *\n * Additionally, if the cookieless_mode is set to 'on_reject', we will capture events in cookieless mode if the\n * user has explicitly opted out.\n *\n * {@label Privacy}\n *\n * @see {PostHogConfig.cookieless_mode}\n * @see {PostHogConfig.opt_out_persistence_by_default}\n * @see {PostHogConfig.respect_dnt}\n *\n * @returns {boolean} whether the posthog library is capturing events\n */\n is_capturing(): boolean {\n if (this.config.cookieless_mode === 'always') {\n return true\n }\n if (this.config.cookieless_mode === 'on_reject') {\n return this.consent.isExplicitlyOptedOut() || this.consent.isOptedIn()\n } else {\n return !this.has_opted_out_capturing()\n }\n }\n\n /**\n * Clear the user's opt in/out status of data capturing and cookies/localstorage for this PostHog instance\n *\n * {@label Privacy}\n *\n * @public\n *\n */\n clear_opt_in_out_capturing(): void {\n this.consent.reset()\n this._sync_opt_out_with_persistence()\n }\n\n _is_bot(): boolean | undefined {\n if (navigator) {\n return isLikelyBot(navigator, this.config.custom_blocked_useragents)\n } else {\n return undefined\n }\n }\n\n _captureInitialPageview(): void {\n if (!document) {\n return\n }\n\n // If page is not visible, add a listener to detect when the page becomes visible\n // and trigger the pageview only then\n // This is useful to avoid `prerender` calls from Chrome/Wordpress/SPAs\n // that are not visible to the user\n\n if (document.visibilityState !== 'visible') {\n if (!this._visibilityStateListener) {\n this._visibilityStateListener = this._captureInitialPageview.bind(this)\n addEventListener(document, 'visibilitychange', this._visibilityStateListener)\n }\n\n return\n }\n\n // Extra check here to guarantee we only ever trigger a single `$pageview` event\n if (!this._initialPageviewCaptured) {\n this._initialPageviewCaptured = true\n this.capture('$pageview', { title: document.title }, { send_instantly: true })\n\n // After we've captured the initial pageview, we can remove the listener\n if (this._visibilityStateListener) {\n document.removeEventListener('visibilitychange', this._visibilityStateListener)\n this._visibilityStateListener = null\n }\n }\n }\n\n /**\n * Enables or disables debug mode for detailed logging.\n *\n * @remarks\n * Debug mode logs all PostHog calls to the browser console for troubleshooting.\n * Can also be enabled by adding `?__posthog_debug=true` to the URL.\n *\n * {@label Initialization}\n *\n * @example\n * ```js\n * // enable debug mode\n * posthog.debug(true)\n * ```\n *\n * @example\n * ```js\n * // disable debug mode\n * posthog.debug(false)\n * ```\n *\n * @public\n *\n * @param {boolean} [debug] If true, will enable debug mode.\n */\n debug(debug?: boolean): void {\n if (debug === false) {\n window?.console.log(\"You've disabled debug mode.\")\n this.set_config({ debug: false })\n } else {\n window?.console.log(\n \"You're now in debug mode. All calls to PostHog will be logged in your console.\\nYou can disable this with `posthog.debug(false)`.\"\n )\n this.set_config({ debug: true })\n }\n }\n\n /**\n * Helper method to check if external API calls (flags/decide) should be disabled\n * Handles migration from old `advanced_disable_decide` to new `advanced_disable_flags`\n */\n _shouldDisableFlags(): boolean {\n // Check if advanced_disable_flags was explicitly set in original config\n const originalConfig = this._originalUserConfig || {}\n if ('advanced_disable_flags' in originalConfig) {\n return !!originalConfig.advanced_disable_flags\n }\n\n // Check if advanced_disable_flags was set post-init (different from default false)\n if (this.config.advanced_disable_flags !== false) {\n return !!this.config.advanced_disable_flags\n }\n\n // Check for post-init changes to advanced_disable_decide\n if (this.config.advanced_disable_decide === true) {\n logger.warn(\n \"Config field 'advanced_disable_decide' is deprecated. Please use 'advanced_disable_flags' instead. \" +\n 'The old field will be removed in a future major version.'\n )\n return true\n }\n\n // Fall back to migration logic for original user config\n return migrateConfigField(originalConfig, 'advanced_disable_flags', 'advanced_disable_decide', false, logger)\n }\n\n private _runBeforeSend(data: CaptureResult): CaptureResult | null {\n if (isNullish(this.config.before_send)) {\n return data\n }\n\n const fns = isArray(this.config.before_send) ? this.config.before_send : [this.config.before_send]\n let beforeSendResult: CaptureResult | null = data\n for (const fn of fns) {\n beforeSendResult = fn(beforeSendResult)\n if (isNullish(beforeSendResult)) {\n const logMessage = `Event '${data.event}' was rejected in beforeSend function`\n if (isKnownUnsafeEditableEvent(data.event)) {\n logger.warn(`${logMessage}. This can cause unexpected behavior.`)\n } else {\n logger.info(logMessage)\n }\n return null\n }\n if (!beforeSendResult.properties || isEmptyObject(beforeSendResult.properties)) {\n logger.warn(\n `Event '${data.event}' has no properties after beforeSend function, this is likely an error.`\n )\n }\n }\n return beforeSendResult\n }\n\n /**\n * Returns the current page view ID.\n *\n * {@label Initialization}\n *\n * @public\n *\n * @returns {string} The current page view ID\n */\n public getPageViewId(): string | undefined {\n return this.pageViewManager._currentPageview?.pageViewId\n }\n\n /**\n * Capture written user feedback for a LLM trace. Numeric values are converted to strings.\n *\n * {@label LLM analytics}\n *\n * @public\n *\n * @param traceId The trace ID to capture feedback for.\n * @param userFeedback The feedback to capture.\n */\n captureTraceFeedback(traceId: string | number, userFeedback: string) {\n this.capture('$ai_feedback', {\n $ai_trace_id: String(traceId),\n $ai_feedback_text: userFeedback,\n })\n }\n\n /**\n * Capture a metric for a LLM trace. Numeric values are converted to strings.\n *\n * {@label LLM analytics}\n *\n * @public\n *\n * @param traceId The trace ID to capture the metric for.\n * @param metricName The name of the metric to capture.\n * @param metricValue The value of the metric to capture.\n */\n captureTraceMetric(traceId: string | number, metricName: string, metricValue: string | number | boolean) {\n this.capture('$ai_metric', {\n $ai_trace_id: String(traceId),\n $ai_metric_name: metricName,\n $ai_metric_value: String(metricValue),\n })\n }\n\n private _checkLocalStorageForDebug(debugConfig: boolean | undefined) {\n const explicitlyFalse = isBoolean(debugConfig) && !debugConfig\n const isTrueInLocalStorage = localStore._is_supported() && localStore._get('ph_debug') === 'true'\n return explicitlyFalse ? false : isTrueInLocalStorage ? true : debugConfig\n }\n}\n\nsafewrapClass(PostHog, ['identify'])\n\nconst add_dom_loaded_handler = function () {\n // Cross browser DOM Loaded support\n function dom_loaded_handler() {\n // function flag since we only want to execute this once\n if ((dom_loaded_handler as any).done) {\n return\n }\n ;(dom_loaded_handler as any).done = true\n\n ENQUEUE_REQUESTS = false\n\n each(instances, function (inst: PostHog) {\n inst._dom_loaded()\n })\n }\n\n if (document?.addEventListener) {\n if (document.readyState === 'complete') {\n // safari 4 can fire the DOMContentLoaded event before loading all\n // external JS (including this file). you will see some copypasta\n // on the internet that checks for 'complete' and 'loaded', but\n // 'loaded' is an IE thing\n dom_loaded_handler()\n } else {\n addEventListener(document, 'DOMContentLoaded', dom_loaded_handler, { capture: false })\n }\n\n return\n }\n\n // Only IE6-8 don't support `document.addEventListener` and we don't support them\n // so let's simply log an error stating PostHog couldn't be initialized\n // We're checking for `window` to avoid erroring out on a SSR context\n if (window) {\n logger.error(\"Browser doesn't support `document.addEventListener` so PostHog couldn't be initialized\")\n }\n}\n\nexport function init_from_snippet(): void {\n const posthogMain = (instances[PRIMARY_INSTANCE_NAME] = new PostHog())\n\n const snippetPostHog = assignableWindow['posthog']\n\n if (snippetPostHog) {\n /**\n * The snippet uses some clever tricks to allow deferred loading of array.js (this code)\n *\n * window.posthog is an array which the queue of calls made before the lib is loaded\n * It has methods attached to it to simulate the posthog object so for instance\n *\n * window.posthog.init(\"TOKEN\", {api_host: \"foo\" })\n * window.posthog.capture(\"my-event\", {foo: \"bar\" })\n *\n * ... will mean that window.posthog will look like this:\n * window.posthog == [\n * [\"my-event\", {foo: \"bar\"}]\n * ]\n *\n * window.posthog[_i] == [\n * [\"TOKEN\", {api_host: \"foo\" }, \"posthog\"]\n * ]\n *\n * If a name is given to the init function then the same as above is true but as a sub-property on the object:\n *\n * window.posthog.init(\"TOKEN\", {}, \"ph2\")\n * window.posthog.ph2.people.set({foo: \"bar\"})\n *\n * window.posthog.ph2 == []\n * window.posthog.people == [\n * [\"set\", {foo: \"bar\"}]\n * ]\n *\n */\n\n // Call all pre-loaded init calls properly\n\n each(snippetPostHog['_i'], function (item: [token: string, config: Partial<PostHogConfig>, name: string]) {\n if (item && isArray(item)) {\n const instance = posthogMain.init(item[0], item[1], item[2])\n\n const instanceSnippet = snippetPostHog[item[2]] || snippetPostHog\n\n if (instance) {\n // Crunch through the people queue first - we queue this data up &\n // flush on identify, so it's better to do all these operations first\n instance._execute_array.call(instance.people, instanceSnippet.people)\n instance._execute_array(instanceSnippet)\n }\n }\n })\n }\n\n assignableWindow['posthog'] = posthogMain\n\n add_dom_loaded_handler()\n}\n\nexport function init_as_module(): PostHog {\n const posthogMain = (instances[PRIMARY_INSTANCE_NAME] = new PostHog())\n\n add_dom_loaded_handler()\n\n return posthogMain\n}\n","import { PropertyMatchType } from './types'\nimport { SurveyActionType, SurveyEventWithFilters } from './posthog-surveys-types'\nimport type { InferredSelector } from './extensions/product-tours/element-inference'\n\nexport interface JSONContent {\n type?: string\n attrs?: Record<string, any>\n content?: JSONContent[]\n marks?: { type: string; attrs?: Record<string, any> }[]\n text?: string\n}\n\nexport type ProductTourStepType = 'element' | 'modal' | 'survey'\n\nexport type ProductTourSurveyQuestionType = 'open' | 'rating'\n\nexport interface ProductTourSurveyQuestion {\n type: ProductTourSurveyQuestionType\n questionText: string\n /** Rating display type - emoji or number */\n display?: 'emoji' | 'number'\n /** Rating scale - 3 or 5 for emoji, 5 or 10 for number */\n scale?: 3 | 5 | 10\n /** Label for low end of rating scale (e.g., \"Not likely\") */\n lowerBoundLabel?: string\n /** Label for high end of rating scale (e.g., \"Very likely\") */\n upperBoundLabel?: string\n}\n\nexport interface ProductTourStep {\n id: string\n type: ProductTourStepType\n selector?: string\n progressionTrigger: 'button' | 'click'\n content: JSONContent | null\n /** Pre-rendered HTML content from the editor. If present, SDK should use this instead of rendering from JSONContent. */\n contentHtml?: string\n /** Inline survey question config - if present, this is a survey step */\n survey?: ProductTourSurveyQuestion\n /** ID of the auto-created survey for this step (set by backend) */\n linkedSurveyId?: string\n /** ID of the survey question (set by backend, used for event tracking) */\n linkedSurveyQuestionId?: string\n /** Enhanced element data for more reliable lookup at runtime */\n inferenceData?: InferredSelector\n /** Maximum tooltip width in pixels (defaults to 320px) */\n maxWidth?: number\n}\n\nexport interface ProductTourConditions {\n url?: string\n urlMatchType?: PropertyMatchType\n selector?: string\n autoShowDelaySeconds?: number\n events?: {\n values: SurveyEventWithFilters[]\n } | null\n cancelEvents?: {\n values: SurveyEventWithFilters[]\n } | null\n actions?: {\n values: SurveyActionType[]\n } | null\n}\n\nexport interface ProductTourAppearance {\n backgroundColor?: string\n textColor?: string\n buttonColor?: string\n borderRadius?: number\n buttonBorderRadius?: number\n borderColor?: string\n fontFamily?: string\n boxShadow?: string\n showOverlay?: boolean\n whiteLabel?: boolean\n}\n\nexport interface ProductTour {\n id: string\n name: string\n description?: string\n type: 'product_tour'\n auto_launch?: boolean\n start_date: string | null\n end_date: string | null\n current_iteration?: number\n conditions?: ProductTourConditions\n appearance?: ProductTourAppearance\n steps: ProductTourStep[]\n internal_targeting_flag_key?: string\n linked_flag_key?: string\n}\n\nexport type ProductTourCallback = (tours: ProductTour[], context?: { isLoaded: boolean; error?: string }) => void\n\nexport type ProductTourSelectorError = 'not_found' | 'multiple_matches' | 'not_visible'\n\nexport type ProductTourDismissReason =\n | 'user_clicked_skip'\n | 'user_clicked_outside'\n | 'escape_key'\n | 'element_unavailable'\n\nexport type ProductTourRenderReason = 'auto' | 'api' | 'trigger' | 'event'\n\nexport const DEFAULT_PRODUCT_TOUR_APPEARANCE: Required<ProductTourAppearance> = {\n backgroundColor: '#ffffff',\n textColor: '#1d1f27',\n buttonColor: '#1d1f27',\n borderRadius: 8,\n buttonBorderRadius: 6,\n borderColor: '#e5e7eb',\n fontFamily: 'system-ui',\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',\n showOverlay: true,\n whiteLabel: false,\n}\n\nexport interface ShowTourOptions {\n reason?: ProductTourRenderReason\n enableStrictValidation?: boolean\n}\n","import { init_as_module } from '../posthog-core'\nexport { PostHog } from '../posthog-core'\nexport * from '../types'\nexport * from '../posthog-surveys-types'\nexport * from '../posthog-product-tours-types'\nexport * from '../posthog-conversations-types'\nexport const posthog = init_as_module()\nexport default posthog\n"],"names":["win","window","undefined","global","globalThis","self","File","ArrayProto","Array","prototype","nativeForEach","forEach","nativeIndexOf","indexOf","navigator","document","location","fetch","XMLHttpRequest","AbortController","userAgent","assignableWindow","Config","DEBUG","LIB_VERSION","DEFAULT_BLOCKED_UA_STRS","isBlockedUA","ua","customBlockedUserAgents","uaLower","toLowerCase","concat","some","blockedUA","blockedUaLower","knownUnsafeEditableEvent","includes","str","needle","trim","stripLeadingDollar","s","replace","nativeIsArray","isArray","ObjProto","Object","type_utils_hasOwnProperty","hasOwnProperty","type_utils_toString","toString","obj","call","isFunction","x","isObject","isEmptyObject","key","isUndefined","isString","isEmptyString","length","isNull","isNullish","isNumber","isBoolean","isFormData","FormData","isKnownUnsafeEditableEvent","isPrimitive","value","isBuiltin","candidate","className","isEvent","Event","base","_unused","isInstanceOf","yesLikeValues","isYesLike","val","noLikeValues","clampToRange","min","max","logger","fallbackValue","warn","BucketedRateLimiter","constructor","options","this","_buckets","_onBucketRateLimited","_bucketSize","bucketSize","_logger","_refillRate","refillRate","_refillInterval","refillInterval","_applyRefill","bucket","now","elapsedMs","lastAccess","refillIntervals","Math","floor","tokensToAdd","tokens","consumeRateLimit","_this$_onBucketRateLi","Date","keyStr","String","stop","MOBILE","IOS","ANDROID","TABLET","ANDROID_TABLET","IPAD","APPLE","APPLE_WATCH","SAFARI","BLACKBERRY","SAMSUNG","SAMSUNG_BROWSER","SAMSUNG_INTERNET","CHROME","CHROME_OS","CHROME_IOS","INTERNET_EXPLORER","INTERNET_EXPLORER_MOBILE","OPERA","OPERA_MINI","EDGE","MICROSOFT_EDGE","FIREFOX","FIREFOX_IOS","NINTENDO","PLAYSTATION","XBOX","ANDROID_MOBILE","MOBILE_SAFARI","WINDOWS","WINDOWS_PHONE","NOKIA","OUYA","GENERIC","GENERIC_MOBILE","GENERIC_TABLET","KONQUEROR","BROWSER_VERSION_REGEX_SUFFIX","DEFAULT_BROWSER_VERSION_REGEX","RegExp","XBOX_REGEX","PLAYSTATION_REGEX","NINTENDO_REGEX","BLACKBERRY_REGEX","windowsVersionMap","parsedStackResults","lastKeysCount","cachedFilenameChunkIds","safariCheck","vendor","isSafari","detectBrowser","user_agent","test","FACEBOOK","versionRegexes","Mozilla","detectBrowserVersion","browser","regexes","i","regex","matches","match","parseFloat","osMatchers","_","exec","version","osVersion","versionParts","join","result","detectDevice","isError","Error","getFilenameToChunkIdMap","stackParser","chunkIdMap","_posthogChunkIds","chunkIdKeys","keys","reduce","acc","stackKey","parsedStack","stackFrame","filename","chunkId","ErrorPropertiesBuilder","coercers","modifiers","buildFromUnknown","input","hint","mechanism","handled","type","exceptionWithCause","buildCoercingContext","apply","parsingContext","buildParsingContext","exceptionWithStack","parseStacktrace","$exception_list","convertToExceptionList","$exception_level","modifyFrames","exceptionList","_this","_asyncToGenerator","exc","stacktrace","frames","applyModifiers","coerceFallback","ctx","_ctx$syntheticExcepti","stack","syntheticException","synthetic","err","cause","applyChunkIds","_extends","map","frame","chunk_id","applyCoercers","adapter","coerce","_this2","newFrames","modifier","_mechanism$type","_mechanism$handled","_exceptionWithStack$s","currentException","push","depth","next","UNKNOWN_FUNCTION","createFrame","platform","func","lineno","colno","function","in_app","extractSafariExtensionDetails","isSafariExtension","isSafariWebExtension","split","chromeRegexNoFnName","chromeRegex","chromeEvalRegex","chromeStackLineParser","line","noFnParts","col","parts","subMatch","geckoREgex","geckoEvalRegex","geckoStackLineParser","WEBPACK_ERROR_REGEXP","STACKTRACE_FRAME_LIMIT","createDefaultStackParser","_len","arguments","parsers","_key","skipFirstLines","lines","cleanedLine","parser","localStack","from","reverse","slice","arr","reverseAndStripFrames","createStackParser","DOMExceptionCoercer","isDOMException","isDOMError","hasStack","getType","getValue","name","message","ErrorCoercer","isPlainError","getMessage","getStack","_ctx","error","ErrorEventCoercer","exceptionLike","ERROR_TYPES_PATTERN","StringCoercer","getInfos","groups","severityLevels","extractExceptionKeysForMessage","maxLength","sort","serialized","ObjectCoercer","errorProperty","getErrorPropertyFromObject","level","isSeverityLevel","getObjectClassName","prop","getPrototypeOf","e","EventCoercer","evt","constructorName","PrimitiveCoercer","PromiseRejectionEventCoercer","reason","getUnhandledRejectionReason","detail","_createLogger","prefix","_temp","debugEnabled","_log","POSTHOG_DEBUG","console","consoleLog","args","info","_len2","_key2","_len3","_key3","_len4","_key4","critical","_len5","_key5","uninitializedWarning","methodName","createLogger","additionalPrefix","loadScript","posthog","url","callback","config","disable_external_dependency_loading","existingScripts","querySelectorAll","_ret","_loop","src","alreadyExistingScriptTag","__posthog_loading_callback_fired","v","addEventListener","event","onerror","addScript","scriptTag","createElement","crossOrigin","onload","prepare_external_dependency_script","_scripts$0$parentNode","scripts","parentNode","insertBefore","body","appendChild","__PosthogExtensions__","loadExternalDependency","kind","scriptUrlToLoad","token","fiveMinutesInMillis","requestRouter","endpointFor","loadSiteApp","scriptUrl","breaker","eachArray","iterator","thisArg","l","each","pair","entries","extend","source","extendArray","item","ownProps","resArray","trySafe","fn","safewrap","f","stripEmptyProperties","p","ret","k","_copyAndTruncateStrings","object","maxStringLength","customizer","COPY_IN_PROGRESS_SET","Set","internalDeepCircularCopy","has","add","it","EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE","isCrossDomainCookie","documentLocation","hostname","lastTwoParts","excluded","find","predicate","element","capture","passive","PEOPLE_DISTINCT_ID_KEY","ALIAS_ID_KEY","EVENT_TIMERS_KEY","AUTOCAPTURE_DISABLED_SERVER_SIDE","HEATMAPS_ENABLED_SERVER_SIDE","EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE","ERROR_TRACKING_SUPPRESSION_RULES","ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS","WEB_VITALS_ENABLED_SERVER_SIDE","DEAD_CLICKS_ENABLED_SERVER_SIDE","PRODUCT_TOURS_ENABLED_SERVER_SIDE","WEB_VITALS_ALLOWED_METRICS","SESSION_RECORDING_REMOTE_CONFIG","SESSION_ID","SESSION_RECORDING_IS_SAMPLED","ENABLED_FEATURE_FLAGS","PERSISTENCE_EARLY_ACCESS_FEATURES","PERSISTENCE_FEATURE_FLAG_DETAILS","STORED_PERSON_PROPERTIES_KEY","STORED_GROUP_PROPERTIES_KEY","SURVEYS","FLAG_CALL_REPORTED","USER_STATE","CLIENT_SESSION_PROPS","CAPTURE_RATE_LIMIT","INITIAL_CAMPAIGN_PARAMS","INITIAL_REFERRER_INFO","INITIAL_PERSON_INFO","ENABLE_PERSON_PROCESSING","TOOLBAR_ID","COOKIELESS_SENTINEL_VALUE","PERSISTENCE_RESERVED_PROPERTIES","isElementInToolbar","el","Element","id","closest","isElementNode","nodeType","isTag","tag","tagName","isTextNode","isDocumentFragment","splitClassString","checkForURLMatches","urlsList","href","getClassNames","baseVal","getAttribute","makeSafeText","filter","shouldCaptureValue","substring","getSafeText","elText","shouldCaptureElement","isSensitiveElement","childNodes","child","_makeSafeText","textContent","getEventTarget","target","srcElement","_e$target","shadowRoot","composedPath","autocaptureCompatibleElements","checkIfElementsMatchCSSSelector","elements","selectorList","_ret2","_loop2","selector","getParentElement","curEl","DEFAULT_CONTENT_IGNORELIST","MAX_CONTENT_IGNORELIST_ENTRIES","DEFAULT_RAGE_CLICK_IGNORE_LIST","shouldCaptureRageclick","_config","cannotCheckForAutocapture","selectorIgnoreList","contentIgnorelist","_config$css_selector_","css_selector_ignorelist","content_ignorelist","targetElementList","getElementAndParentsForElement","elementsWithText","keywords","_ref","safeText","ariaLabel","keyword","shouldIgnoreByContent","_element$getAttribute","captureOnAnyElement","parentIsUsefulElement","host","compStyles","getComputedStyle","getPropertyValue","shouldCaptureDomEvent","autocaptureConfig","allowedEventTypes","_autocaptureConfig","_autocaptureConfig2","_autocaptureConfig3","_autocaptureConfig4","url_allowlist","url_ignorelist","dom_event_allowlist","allowlist","eventType","element_allowlist","elementType","checkIfElementTreePassesElementAllowList","css_selector_allowlist","classes","coreCCPattern","anchoredCCRegex","unanchoredCCRegex","coreSSNPattern","anchoredSSNRegex","unanchoredSSNRegex","anchorRegexes","getDirectAndNestedSpanText","text","getNestedSpanText","_child$tagName","spanText","getElementsChainString","_element$nth_child","_element$nth_of_type","el_string","tag_name","attr_class","single_class","attributes","nth_child","nth_of_type","attr_id","sortedAttributes","_ref2","_ref3","a","b","localeCompare","_ref4","escapeQuotes","_ref5","elementsToString","_el$$el_text","_el$attr__href","response","extractAttrClass","_ref6","_ref7","extractElements","RageClick","rageclickConfig","disabled","conf","thresholdPx","threshold_px","timeoutMs","timeout_ms","clickCount","click_count","clicks","isRageClick","y","timestamp","lastClick","abs","convertToURL","formDataToQuery","formdata","arg_separator","use_val","use_key","tph_arr","encodeURIComponent","isFile","getQueryParam","param","keyValuePair","queryParts","decodeURIComponent","maskQueryParams","maskedParams","mask","splitHash","withoutHash","hash","splitQuery","queryString","urlWithoutQueryAndHash","paramStrings","_getHashParam","COPY_AUTOCAPTURE_EVENT","limitText","previousElementSibling","_el","previousSibling","getPropertiesFromElement","elem","maskAllAttributes","maskText","elementAttributeIgnorelist","props","c","attr","attributeName","nthChild","nthOfType","currentElem","autocapturePropertiesForElement","_elementsJson$","_elementsJson$2","maskAllElementAttributes","maskAllText","elementAttributeIgnoreList","elementsChainAsString","externalHref","elementsJson","autocaptureAugmentProperties","explicitNoCapture","shouldCaptureEl","augmentProperties","propertyKey","propertyValue","getAugmentPropertiesFromElement","_convertToURL","_window$location","hrefHost","locationHost","$event_type","$ce_version","$elements","$elements_chain","$el_text","$external_click_url","Autocapture","instance","_initialized","_isDisabledServerSide","_elementsChainAsString","rageclicks","rageclick","_elementSelectors","_config$url_allowlist","_config$url_ignorelis","autocapture","_addDomEventHandlers","isBrowserSupported","handler","_captureEvent","capture_copied_text","copiedTextHandler","startIfEnabled","isEnabled","onRemoteConfig","persistence","register","setElementSelectors","selectors","getElementSelectors","_this$_elementSelecto","elementSelectors","matchedElements","matchedElement","_this$instance$persis","_this$_isDisabledServ","persistedServerDisabled","memoryDisabled","_shouldDisableFlags","disabledServer","eventName","_this$rageclicks","MouseEvent","clientX","clientY","timeStamp","getTime","isCopyAutocapture","mask_all_element_attributes","mask_all_text","element_attribute_ignorelist","_window$getSelection","selectedContent","getSelection","clipType","trunc","ceil","Number","isInteger","isFinite","DIGITS","UUID","bytes","TypeError","fromFieldsV7","unixTsMs","randA","randBHi","randBLo","RangeError","Uint8Array","pow","charAt","clone","equals","other","compareTo","diff","sign","V7Generator","_timestamp","_counter","_random","DefaultRandom","generate","generateOrAbort","valueAfterReset","ts","_resetCounter","nextUint32","defaultGenerator","getRandomValues","buffer","UUIDV7_DENY_WEAK_RNG","random","crypto","_buffer","Uint32Array","_cursor","Infinity","uuidv7","uuidv7obj","firstNonPublicSubDomain","DOMAIN_MATCH_REGEX","chooseCookieDomain","cross_subdomain","matchedSubDomain","cookieJar","list","len","candidateCookieValue","cookie","seekFirstNonPublicSubDomain","originalMatch","originalCookieDomainFn","cookieStore","_is_supported","_error","msg","_get","nameEQ","ca","_parse","JSON","parse","_unused2","_set","days","is_secure","expires","secure","cdomain","date","setTime","toUTCString","new_cookie_val","stringify","_unused3","_remove","_unused4","_localStorage_supported","localStore","supported","_unused5","localStorage","getItem","_unused6","setItem","removeItem","COOKIE_PERSISTED_PROPERTIES","memoryStorage","memoryStore","sessionStorageSupported","sessionStore","_unused9","sessionStorage","_unused0","ConsentStatus","ConsentManager","_instance","consent","_getDnt","DENIED","_storedConsent","isOptedOut","cookieless_mode","PENDING","opt_out_capturing_by_default","isOptedIn","isExplicitlyOptedOut","optInOut","_storage","_storageKey","cookie_expiration","cross_subdomain_cookie","secure_cookie","reset","opt_out_capturing_cookie_prefix","consent_persistence_name","GRANTED","_persistentStore","persistenceType","opt_out_capturing_persistence_type","otherStorage","respect_dnt","doNotTrack","dntValue","isDeadClicksEnabledForHeatmaps","isDeadClicksEnabledForAutocapture","_instance$instance$pe","isRemoteEnabled","get_property","clientConfig","capture_dead_clicks","DeadClicksAutocapture","lazyLoadedDeadClicksAutocapture","_lazyLoadedDeadClicksAutocapture","onCapture","captureDeadClicks","_loadScript","_start","cb","_assignableWindow$__P","_assignableWindow$__P2","initDeadClicksAutocapture","_assignableWindow$__P3","__onCapture","start","ExceptionObserver","_this$_instance$persi","_this$_instance$confi","_this$_instance$confi2","_startCapturing","errorWrappingFunctions","wrapOnError","wrapUnhandledRejection","wrapConsoleError","_unwrapOnError","capture_unhandled_errors","captureException","bind","_unwrapUnhandledRejection","capture_unhandled_rejections","_unwrapConsoleError","capture_console_errors","_stopCapturing","_remoteEnabled","_rateLimiter","error_tracking","__exceptionRateLimiterRefillRate","__exceptionRateLimiterBucketSize","_requiredConfig","startIfEnabledOrStop","providedConfig","capture_exceptions","_this$_unwrapOnError","_this$_unwrapUnhandle","_this$_unwrapConsoleE","autocaptureExceptionsResponse","autocaptureExceptions","onConfigChange","errorProperties","_errorProperties$$exc","_errorProperties$$exc2","exceptionType","exception","exceptions","sendExceptionEvent","patch","replacement","original","wrapped","defineProperties","__posthog_wrapped__","enumerable","HistoryAutocapture","_lastPathname","pathname","capture_pageview","monitorHistoryChanges","_popstateListener","_window$history$pushS","_window$history$repla","history","pushState","originalPushState","state","title","_capturePageview","replaceState","originalReplaceState","_setupPopstateListener","navigationType","_window$location2","currentPathname","navigation_type","removeEventListener","setupSegmentIntegration","done","segment","bootstrapUser","user","getSegmentAnonymousId","anonymousId","get_device_id","distinct_id","$device_id","set_property","segmentUser","then","setupPostHogFromSegment","Promise","resolve","enrichEvent","userId","get_distinct_id","identify","additionalProperties","calculateEventProperties","properties","assign","isLoaded","load","track","page","screen","createSegmentIntegration","NAME","createEventProcessor","_posthog","organization","projectId","severityAllowList","sendExceptionsToPostHog","_event$exception","_exceptions$","_exceptions$2","_exceptions$3","_exceptions$4","__loaded","tags","personUrl","sessionRecordingStarted","get_session_replay_url","withTimestamp","values","data","$exception_message","$exception_type","$sentry_event_id","event_id","$sentry_exception","$sentry_exception_message","$sentry_exception_type","$sentry_tags","SentryIntegration","setupOnce","addGlobalEventProcessor","STATE_FROM_WINDOW","LOCALSTORAGE_KEY","ToolbarState","Toolbar","_setToolbarState","_getToolbarState","_assignableWindow$ph_","UNINITIALIZED","maybeLoadToolbar","toolbarParams","stateHash","atob","search","userIntent","loadToolbar","_callLoadToolbar","params","loadFn","toolbarRunning","getElementById","disableToolbarMetrics","region","advanced_disable_toolbar_metrics","apiURL","instrument","LOADED","LOADING","_loadEditor","maybeLoadEditor","TracingHeaders","_restoreXHRPatch","_restoreFetchPatch","tracingHeadersPatchFns","_patchXHR","__add_tracing_headers","sessionManager","_patchFetch","_assignableWindow$__P4","_this$_restoreXHRPatc","_this$_restoreFetchPa","URL_REGEX_PREFIX","PERSONAL_DATA_CAMPAIGN_PARAMS","CAMPAIGN_PARAMS","MASKED","COOKIE_CAMPAIGN_PARAMS","getCampaignParams","customTrackedParams","maskPersonalDataProperties","customPersonalDataProperties","paramsToMask","urlCampaignParams","_getCampaignParamsFromUrl","URL","cookieCampaignParams","kwkey","kw","customParams","campaign_keywords","_getSearchInfoFromReferrer","referrer","_getSearchEngine","getBrowserLanguage","language","userLanguage","getReferrer","getPersonInfo","r","u","getPersonPropsFromInfo","_convertToURL2","$referrer","$referring_domain","campaignParams","searchInfo","getTimezone","Intl","DateTimeFormat","resolvedOptions","timeZone","getTimezoneOffset","getEventProperties","lang","device","os_name","os_version","rgex","resultOrFn","detectOS","$os","$os_version","$browser","$device","$device_type","$timezone","$timezone_offset","$current_url","$host","$pathname","$raw_user_agent","$browser_version","$browser_language","$browser_language_prefix","$screen_height","height","$screen_width","width","$viewport_height","innerHeight","$viewport_width","innerWidth","$lib","$lib_version","$insert_id","$time","FIFTEEN_MINUTES_IN_MILLIS","WebVitalsAutocapture","_enabledServerSide","metrics","firstMetricTimestamp","_flushToCapture","clearTimeout","_delayedFlushTimer","metric","_addToBuffer","_this$_instance$sessi","sessionIds","checkAndGetSessionAndWindowId","$currentUrl","_currentURL","_maxAllowedValue","setTimeout","flushToCaptureTimeoutMs","attribution","interactionTargetElement","$session_id","sessionId","$window_id","windowId","allowedMetrics","onLCP","onCLS","onFCP","onINP","posthogExtensions","postHogWebVitalsCallbacks","_this$_instance$persi2","clientConfigMetricAllowList","capture_performance","web_vitals_allowed_metrics","web_vitals_delayed_flush_ms","configured","__web_vitals_max_value","protocol","web_vitals","webVitalsOptIn","capturePerformance","mask_personal_data_properties","custom_personal_data_properties","isValidMouseEvent","Heatmaps","_flushInterval","flushIntervalMilliseconds","flushInterval","capture_heatmaps","flush_interval_milliseconds","enable_heatmaps","_setupListeners","_onVisibilityChange","_this$_flushInterval","clearInterval","_removeListeners","getAndClearBuffer","optIn","_onDeadClick","click","_onClick","originalEvent","visibilityState","shouldPoll","setInterval","_flush","_flushHandler","_onClickHandler","_onMouseMoveHandler","_onMouseMove","_deadClicksCapture","_onVisibilityChange_handler","_this$_deadClicksCapt","_mouseMoveTimeout","_getProperties","scrollY","scrollManager","scrollX","scrollElement","isFixedOrSticky","breakOnElement","position","elementOrParentPositionMatches","target_fixed","_capture","$heatmap_data","PageViewManager","_onSessionIdChange","_windowId","changeReason","noSessionId","activityTimeout","sessionPastMaximumLength","_currentPageview","resetContext","_setupSessionRotationHandler","_unsubscribeSessionId","onSessionId","destroy","_this$_unsubscribeSes","doPageView","pageViewId","_window$location$path","_previousPageViewProperties","doPageLeave","_this$_currentPagevie","doEvent","_this$_currentPagevie2","$pageview_id","pageviewId","previousPageView","$prev_pageview_id","scrollContext","getContext","disable_scroll_properties","maxScrollHeight","lastScrollY","maxScrollY","maxContentHeight","lastContentY","maxContentY","lastScrollPercentage","maxScrollPercentage","lastContentPercentage","maxContentPercentage","$prev_pageview_last_scroll","$prev_pageview_last_scroll_percentage","$prev_pageview_max_scroll","$prev_pageview_max_scroll_percentage","$prev_pageview_last_content","$prev_pageview_last_content_percentage","$prev_pageview_max_content","$prev_pageview_max_content_percentage","$prev_pageview_pathname","$prev_pageview_duration","Compression","u8","u16","Uint16Array","u32","fleb","fdeb","clim","freb","eb","j","_a","fl","revfl","revfd","rev","hMap","cd","mb","co","le","rvb","sv","r_1","m","flt","fdt","flm","fdm","shft","slc","n","set","subarray","wbits","d","o","wbits16","hTree","t","t2","i0","i1","i2","maxSym","tr","mbt","ln","dt","lft","cst","i2_1","i2_2","i2_3","lc","cl","cli","cln","cls","w","clen","cf","wfblk","out","pos","dat","wblk","final","syms","lf","df","li","bs","bl","dlt","mlb","_b","ddt","mdb","_c","lclt","nlc","_d","lcdt","ndc","lcfreq","_e","lct","mlcb","nlcc","lm","ll","dm","dl","flen","ftlen","dtlen","llm","lcts","clct","dst","deo","crct","dopt","opt","pre","post","st","lvl","plvl","lst","msk_1","prev","head","bs1_1","bs2_1","hsh","lc_1","wi","hv","imod","pimod","rem","ch_1","dif","maxn","maxd","ml","nl","mmd","md","ti","lin","din","dflt","mem","log","wbytes","gzipSync","opts","cr","crc","mtime","charCodeAt","gzh","utf8Encode","string","end","stringl","utftext","c1","enc","fromCharCode","SUPPORTS_REQUEST","CONTENT_TYPE_PLAIN","extendURLParams","_search$split$map","baseUrl","newParams","updatedSearch","_newParams$key","origValue","remaining","jsonStringify","space","encodePostData","compression","GZipJS","gzipData","latin1","TextEncoder","encode","ar","ai","strToU8","blob","Blob","contentType","estimatedSize","size","Base64","b64data","h1","h2","h3","h4","bits","b64","ac","tmp_arr","_base64Encode","encodedBody","encodeToDataString","jsonBody","AVAILABLE_TRANSPORTS","transport","method","_encodePostData2","_aborter","headers","Headers","headerValue","headerName","append","aborter","controller","signal","timeout","abort","keepalive","SIXTY_FOUR_KILOBYTES","fetchOptions","responseText","res","statusCode","status","json","catch","finally","_encodePostData","req","open","setRequestHeader","disableXHRCredentials","withCredentials","onreadystatechange","readyState","send","sendBeacon","beacon","_encodePostData3","sendBeaconBody","isMatchingRegex","pattern","isValidRegex","getPersonPropertiesHash","userPropertiesToSet","userPropertiesToSetOnce","propertyComparisons","exact","targets","is_not","every","not_regex","icontains","not_icontains","gt","numValue","isNaN","lt","matchPropertyFilters","propertyFilters","eventProperties","propertyName","eventPropertyValue","eventValues","comparisonFunction","operator","PostHogExceptions","_suppressionRules","_errorPropertiesBuilder","ErrorTracking","_response$errorTracki","_response$errorTracki2","_response$errorTracki3","suppressionRules","errorTracking","captureExtensionExceptions","_captureExtensionExceptions","enabled_server_side","enabled_client_side","buildProperties","metadata","_isExceptionList","_matchesSuppressionRule","_isExtensionException","__capturePostHogExceptions","_isPostHogException","_noTruncate","_batchKey","exceptionValues","$exception_types","$exception_values","rule","results","_exceptionValues$v$ke","compare","Boolean","flatMap","_e$stacktrace$frames","_e$stacktrace","startsWith","_exception$stacktrace","_exception$stacktrace2","_lastFrame$filename$i","_lastFrame$filename","lastFrame","forceDebugLogger","PERSISTENCE_ACTIVE_FEATURE_FLAGS","PERSISTENCE_OVERRIDE_FEATURE_FLAGS","PERSISTENCE_FEATURE_FLAG_PAYLOADS","PERSISTENCE_OVERRIDE_FEATURE_FLAG_PAYLOADS","PERSISTENCE_FEATURE_FLAG_REQUEST_ID","PERSISTENCE_FEATURE_FLAG_EVALUATED_AT","filterActiveFeatureFlags","featureFlags","activeFeatureFlags","normalizeFlagsResponse","flagDetails","fromEntries","flag","_flagDetails$flag$var","variant","enabled","featureFlagPayloads","_flagDetails$flag$met","payload","_flagDetails$flag$met2","QuotaLimitedResource","PostHogFeatureFlags","_override_warning","_hasLoadedFlags","_requestInFlight","_reloadingDisabled","_additionalReloadRequested","_flagsCalled","_flagsLoadedFromRemote","featureFlagEventHandlers","_getValidEvaluationEnvironments","envs","evaluation_environments","env","isValid","_shouldIncludeEvaluationEnvironments","flags","__preview_remote_config","disableFlags","_reloadDebouncer","advanced_disable_feature_flags","advanced_disable_feature_flags_on_first_load","_callFlagsEndpoint","hasLoadedFlags","getFlags","getFlagVariants","getFlagsWithDetails","overridenFlags","overriddenPayloads","finalDetails","overriddenKeys","_originalDetail$enabl","_originalDetail$metad","originalDetail","overrideFlagValue","finalEnabled","overrideVariant","overridePayload","overridenDetail","original_enabled","original_variant","original_payload","enabledFlags","overriddenFlags","finalFlags","getFlagPayloads","flagPayloads","finalPayloads","reloadFeatureFlags","_clearDebouncer","ensureFlagsLoaded","setAnonymousDistinctId","anon_distinct_id","$anon_distinct_id","setReloadingPaused","isPaused","deviceId","getGroups","person_properties","get_initial_props","group_properties","disable_flags","useRemoteConfigWithFlags","flagsRoute","queryParams","advanced_only_evaluate_survey_feature_flags","timezone","_send_request","disable_compression","feature_flag_request_timeout_ms","_response$json$quotaL","_response$json","errorsLoading","_onRemoteConfig","quotaLimited","FeatureFlags","_response$json2","receivedFeatureFlags","getFeatureFlag","flagValue","flagReportValue","requestId","evaluatedAt","flagCallReported","send_event","_flagDetails$metadata","_flagDetails$reason$d","_flagDetails$reason","_flagDetails$reason2","_flagDetails$metadata2","_flagDetails$metadata3","getFeatureFlagDetails","$feature_flag","$feature_flag_response","$feature_flag_payload","getFeatureFlagPayload","$feature_flag_request_id","$feature_flag_evaluated_at","$feature_flag_bootstrapped_response","bootstrap","$feature_flag_bootstrapped_payload","$used_bootstrap_value","$feature_flag_version","_flagDetails$metadata4","description","code","$feature_flag_reason","$feature_flag_id","$feature_flag_original_response","$feature_flag_original_payload","getRemoteConfigPayload","_response$json3","isFeatureEnabled","addFeatureFlagsHandler","removeFeatureFlagsHandler","h","currentFlags","currentFlagPayloads","currentFlagDetails","normalizedResponse","$enabled_feature_flags","newFeatureFlags","newFeatureFlagPayloads","newFeatureFlagDetails","errorsWhileComputingFlags","parseFlagsResponse","_fireFeatureFlagsCallbacks","override","suppressWarning","overrideFeatureFlags","overrideOptions","unregister","_options$suppressWarn","flagsObj","payloads","onFeatureFlags","flagVariants","_prepareFeatureFlagsForCallbacks","updateEarlyAccessFeatureEnrollment","isEnrolled","stage","_this$_instance$persi3","feature","flagKey","enrollmentPersonProp","$feature_enrollment","$set","setPersonPropertiesForFlags","newFlags","getEarlyAccessFeatures","force_reload","stages","existing_early_access_features","stageParams","_this$_instance$persi4","_this$_instance$persi5","earlyAccessFeatures","variantKey","existingProperties","resetPersonPropertiesForFlags","setGroupPropertiesForFlags","groupType","resetGroupPropertiesForFlags","group_type","CASE_INSENSITIVE_PERSISTENCE_TYPES","PostHogPersistence","isDisabled","_campaign_params_saved","_name","parseName","_buildStorage","debug","update_config","save","_disabled","localPlusCookieStore","customCookieProperties","cookiePropertiesToPersist","cookieProperties","_unused7","_unused8","cookiePersistedProperties","createLocalPlusCookieStore","storage_type","found","entry","_expire_days","_cross_subdomain","_secure","remove","clear","register_once","default_value","_default_expiry","hasChanges","update_campaign_params","custom_campaign_params","update_search_keyword","update_referrer_info","set_initial_person_info","initialReferrerInfo","personProps","initialPersonInfo","initialPersonProps","safe_merge","oldConfig","set_disabled","set_cross_subdomain","set_secure","isArrayContentsEqual","arr1","arr2","sortedArr1","sortedArr2","index","cookie_persisted_properties","newStore","set_event_timer","event_name","timers","remove_event_timer","to","PRODUCT_TOURS_STORAGE_KEY","PostHogProductTours","_productTourManager","_cachedTours","productTours","loadIfEnabled","_instance$persistence","disable_product_tours","_startProductTours","generateProductTours","getProductTours","forceReload","storedTours","tours","product_tours","getActiveProductTours","showProductTour","tourId","_this$_productTourMan","showTourById","previewTour","tour","_this$_productTourMan2","dismissProductTour","_this$_productTourMan3","dismissTour","nextStep","_this$_productTourMan4","previousStep","_this$_productTourMan5","clearCache","resetTour","_this$_productTourMan6","resetAllTours","_this$_productTourMan7","cancelPendingTour","_this$_productTourMan8","SurveyEventType","SurveyWidgetType","SurveyPosition","SurveyTabPosition","SurveyType","SurveyQuestionType","SurveyQuestionBranchingType","SurveySchedule","SurveyEventName","SurveyEventProperties","DisplaySurveyType","SURVEY_LOGGER","SURVEY_SEEN_PREFIX","getSurveyInteractionProperty","survey","action","surveyProperty","current_iteration","getSurveySeenKey","getSurveyStorageKey","IN_APP_SURVEY_TYPES","Popover","Widget","API","DEFAULT_DISPLAY_SURVEY_OPTIONS","ignoreConditions","ignoreDelay","displayType","SimpleEventEmitter","_events","on","listener","emit","matchString","matching","likePattern","ActionMatcher","_debugEventEmitter","_checkStep","step","_checkStepEvent","_checkStepUrl","_checkStepElement","_checkStepProperties","_actionEvents","_actionRegistry","init","_this$_instance","_addCaptureHook","_this$_instance2","matchEventToAction","eventPayload","actions","_this$_instance3","_this$_instance4","_this$_actionRegistry","_action$steps","steps","_this$_actionEvents","_this$_instance5","selectorsToWatch","_action$steps2","_this$_actionRegistry2","_checkAction","_addActionHook","onAction","_event$properties","eventUrl","url_matching","_checkStepHref","_checkStepText","_checkStepSelector","_event$properties2","_getElementsList","href_matching","chain","_event$properties3","text_matching","texts","elementsChain","extractTexts","_event$properties4","_event$properties5","$element_selectors","selector_regex","_event$properties6","EventReceiver","_eventToItems","Map","_cancelEventToItems","_actionToItems","_doesEventMatchFilter","eventConfig","_buildEventToItemMap","items","conditionField","_item$conditions","conditions","existing","get","_getMatchingItems","itemIds","Activation","_getItems","allItems","_item$conditions2","_setupEventBasedItems","_setupActionBasedItems","actionBasedItems","_item$conditions3","_item$conditions4","_actionMatcher","actionName","_item$conditions5","_item$conditions6","_item$conditions7","_this$_actionMatcher","_item$conditions8","knownItems","eventBasedItems","_item$conditions9","_item$conditions0","events","itemsWithCancelEvents","_item$conditions1","_item$conditions10","cancelEvents","matchEventToItem","onEvent","Cancellation","_getLogger","activatedKey","_getActivatedKey","shownEventName","_getShownEventName","existingActivatedItems","_eventPayload$propert","_eventPayload$propert2","itemId","$survey_id","$product_tour_id","splice","_updateActivatedItems","itemsToCancel","_cancelPendingItem","matchedItems","activatedItems","eligibleItems","_isItemPermanentlyIneligible","getActivatedIds","_this$_instance6","getEventToItemsMap","_getActionMatcher","SurveyEventReceiver","super","SHOWN","getSurveys","cancelPendingSurvey","getEventToSurveys","PostHogSurveys","_isSurveysEnabled","_surveyManager","_isInitializingSurveys","_surveyCallbacks","_getSurveysInFlightPromise","_surveyEventReceiver","disable_surveys","surveys","isArrayResponse","surveyKeys","phExtensions","advanced_enable_surveys","isSurveysEnabled","generateSurveys","_completeSurveyInitialization","_handleSurveyLoadError","generateSurveysFn","_notifySurveyCallbacks","onSurveysLoaded","resolvePromise","existingSurveys","context","surveys_request_timeout_ms","_this$_surveyEventRec","eventOrActionBasedSurveys","start_date","end_date","isSurveyRunning","_survey$conditions","doesSurveyActivateByEvent","_survey$conditions2","doesSurveyActivateByAction","getActiveMatchingSurveys","_getSurveyById","surveyId","_surveys$find","_checkSurveyEligibility","eligible","checkSurveyEligibility","canRenderSurvey","visible","disabledReason","eligibility","canRenderSurveyAsync","_surveys$find2","renderSurvey","_survey$appearance","querySelector","appearance","surveyPopupDelaySeconds","_survey$appearance2","_this$_surveyManager","displaySurvey","_survey$appearance3","surveyToDisplay","canRender","Inline","handlePopoverSurvey","cancelSurvey","handlePageUnload","_this$_surveyManager2","PostHogConversations","_isConversationsEnabled","_conversationsManager","_isInitializing","_remoteConfig","disable_conversations","conversations","_this$_conversationsM","initConversations","_completeInitialization","_handleLoadError","initConversationsFn","show","hide","isAvailable","isVisible","_this$_conversationsM2","_this$_conversationsM3","sendMessage","userTraits","newTicket","getMessages","ticketId","after","markAsRead","_this3","getTickets","_this4","getCurrentTicketId","_this$_conversationsM4","_this$_conversationsM5","getWidgetSessionId","_this$_conversationsM6","_this$_conversationsM7","RateLimiter","_instance$config$rate","_instance$config$rate2","serverLimits","lastEventRateLimited","checkForLimiting","httpResponse","quota_limited","batchKey","captureEventsPerSecond","rate_limiting","events_per_second","captureEventsBurstLimit","events_burst_limit","clientRateLimitContext","isRateLimited","checkOnly","_this$instance$persis2","_this$instance$persis3","last","$$client_ingestion_warning_message","skip_client_rate_limiting","remainingTokens","isServerRateLimited","retryAfter","RemoteConfigLoader","remoteConfig","_assignableWindow$_PO","_POSTHOG_REMOTE_CONFIG","_loadRemoteConfigJs","_loadRemoteConfigJSON","hasFeatureFlags","DEFAULT_FLUSH_INTERVAL_MS","RequestQueue","sendRequest","_isPaused","_queue","_flushTimeoutMs","flush_interval_ms","_sendRequest","enqueue","_flushTimeout","_setFlushTimeout","unload","_clearFlushTimeout","requests","_formatQueue","requestValues","enable","request","_requests$key$data","RetryQueue","_isPolling","_pollIntervalMs","_areWeOnline","onLine","_onlineListener","_offlineListener","retriableRequest","retriesPerformedSoFar","_objectWithoutPropertiesLoose","_excluded","retry_count","_enqueue","requestOptions","msToNextRetry","rawBackoffTime","minBackoff","cappedBackoffTime","jitter","pickNextRetryDelay","retryAt","logMessage","_poll","_poller","notToFlush","toFlush","ScrollManager","_updateScrollData","_this$_context$maxScr","_this$_context$maxScr2","_this$_context$maxCon","_this$_context$maxCon2","_context","scrollHeight","clientHeight","contentY","contentHeight","startMeasuringScrollPosition","scroll_root_selector","documentElement","scrollTop","pageYOffset","scrollLeft","pageXOffset","generateSessionSourceParams","SessionPropsManager","sessionIdManager","sessionSourceParamGenerator","_onSessionIdCallback","stored","_getStored","newProps","_sessionSourceParamGenerator","_persistence","_sessionIdManager","getSetOnceProps","_this$_getStored","referringDomain","initialPathName","utm_source","utm_campaign","utm_medium","utm_content","utm_term","getSessionProps","SessionIdManager","_eventEmitter","sessionIdGenerator","windowIdGenerator","_this$_config$bootstr","_sessionIdChangedHandlers","_beforeUnloadListener","_sessionHasBeenIdleTooLong","lastActivityTimestamp","sessionTimeoutMs","_sessionId","_sessionStartTimestamp","_sessionActivityTimestamp","_sessionIdGenerator","_windowIdGenerator","persistenceName","desiredTimeout","_sessionTimeoutMs","$configured_session_timeout_ms","_resetIdleTimer","_window_id_storage_key","_primary_window_exists_storage_key","_canUseSessionStorage","lastWindowId","primaryWindowExists","sessionID","sessionStartTimestamp","uuid","hex","parseInt","uuid7ToTimestampMs","_setSessionId","_listenToReloadWindow","_setWindowId","_getWindowId","sessionActivityTimestamp","_getSessionId","sessionIdInfo","resetSessionId","_enforceIdleTimeout","readOnly","startTimestamp","valuesChanged","newActivityTimestamp","idleSessionId","SiteApps","_bufferedInvocations","apps","opt_in_site_apps","_eventCollector","_eventName","globals","globalsForEvent","siteAppLoaders","siteApps","_stopBuffering","_event$properties$$se","_event$properties$$se2","_event$properties$$el","groupIds","groupProperties","$set_once","elements_chain","person","setupSiteApp","loader","app","processBufferedEvents","_this$_stopBuffering","errored","processEvent","processedBuffer","hasInitReturned","onLoaded","success","loaded","_setupSiteApps","_onCapturedEvent","_this$siteAppLoaders","_this$_stopBuffering2","_response$siteApps","isLikelyBot","isBlockedUACore","uaData","userAgentData","brands","brandObj","brand","webdriver","RequestRouterRegion","ingestionDomain","RequestRouter","_regionCache","apiHost","api_host","flagsApiHost","customHost","flags_api_host","uiHost","_this$instance$config","ui_host","US","EU","CUSTOM","path","suffix","webExperimentUrlValidationMap","conditionsUrl","WebExperiments","getWebExperimentsAndEvaluateDisplayLogic","getWebExperiments","webExperiments","_logInfo","_flagToExperiments","webExperiment","feature_flag_key","_this$_flagToExperime","selectedVariant","variants","_applyTransforms","transforms","testVariant","_matchesTestVariant","_is_bot","disable_web_experiments","previewWebExperiment","_this$_flagToExperime2","_this$_flagToExperime3","getWindowLocation","experimentID","_showPreviewWebExperiment","previewing","existingWebExperiments","experiments","previewExperiments","exp","_matchUrlConditions","_matchUTMConditions","_testVariant$conditio","_testVariant$conditio2","_testVariant$conditio3","_testVariant$conditio4","urlMatchType","_testVariant$conditio5","utm","_testVariant$conditio6","_testVariant$conditio7","_testVariant$conditio8","_testVariant$conditio9","_testVariant$conditio0","_testVariant$conditio1","_testVariant$conditio10","_testVariant$conditio11","utmCampaignMatched","utmSourceMatched","utmMediumMatched","utmTermMatched","experiment","transform","_document","htmlElement","html","innerHTML","css","setAttribute","custom_blocked_useragents","MAPPED_INTEGRATIONS","intercom","crispChat","ExternalIntegrations","_assignableWindow$__P5","integrations","LOGGER_PREFIX","SessionRecording","started","_this$_lazyLoadedSess","_lazyLoadedSessionRecording","isStarted","_receivedFlags","_isRecordingEnabled","_forceAllowLocalhostNetworkCapture","_persistFlagsOnSessionListener","_this$_instance$get_p","disable_session_recording","startReason","_this$_lazyLoadedSess2","canRunReplay","_lazyLoadAndStart","stopRecording","rrweb","record","initSessionRecording","_onScriptLoaded","_scriptName","_this$_persistFlagsOn","_this$_lazyLoadedSess3","_resetSampling","_persistRemoteConfig","_this$_persistFlagsOn2","persistResponse","sessionRecordingConfigResponse","sessionRecording","receivedSampleRate","sampleRate","parsedSampleRate","receivedMinimumDuration","minimumDurationMilliseconds","networkPayloadCapture","canvasRecording","recordCanvas","fps","canvasFps","quality","canvasQuality","endpoint","triggerMatchType","masking","urlTriggers","_this$_lazyLoadedSess4","_remoteConfig$scriptC","scriptConfig","script","onRRwebEmit","rawEvent","_this$_lazyLoadedSess5","overrideLinkedFlag","_this$_lazyLoadedSess6","$replay_override_linked_flag","overrideSampling","_this$_lazyLoadedSess7","$replay_override_sampling","overrideTrigger","triggerType","_this$_lazyLoadedSess8","sdkDebugProperties","_this$_lazyLoadedSess9","$recording_status","tryAddCustomEvent","_this$_lazyLoadedSess0","instances","__NOOP","PRIMARY_INSTANCE_NAME","ENQUEUE_REQUESTS","defaultConfig","defaults","persistence_name","save_campaign_params","save_referrer","capture_pageleave","__preview_deferred_init_extensions","upgrade","disable_persistence","disable_surveys_automatic_display","enable_recording_console_log","ip","opt_out_persistence_by_default","opt_out_useragent_filter","property_denylist","sanitize_properties","request_headers","request_batching","properties_string_max_length","advanced_disable_flags","advanced_disable_decide","on_request_error","session_idle_timeout_seconds","person_profiles","before_send","request_queue_config","_onCapture","__preview_eager_load_replay","session_recording","strictMinimumDuration","defaultsThatVaryByConfig","configRenames","origConfig","renames","process_person","xhr_headers","cookie_name","disable_cookie","store_google","verbose","newConfig","property_blacklist","DeprecatedWebPerformanceObserver","__forceAllowLocalhost","_forceAllowLocalhost","PostHog","decideEndpointWasHit","_this$featureFlags$ha","_this$featureFlags","flagsEndpointWasHit","_this$featureFlags$ha2","_this$featureFlags2","webPerformance","_personProcessingSetOncePropertiesSent","_internalEventEmitter","_calculate_event_properties","sentryIntegration","processor","__request_queue","analyticsDefaultEndpoint","_initialPageviewCaptured","_visibilityStateListener","_initialPersonProfilesConfig","_cachedPersonProperties","toolbar","pageViewManager","rateLimiter","externalIntegrations","people","setProps","setPersonProperties","set_once","_instances$name","namedPosthog","_init","_config$bootstrap","_checkLocalStorageForDebug","_originalUserConfig","_triggered_notifs","set_config","on_xhr_error","persistenceDisabled","_is_persistence_disabled","sessionPersistence","initialPersistenceProps","initialSessionProps","$initialization_time","toISOString","_requestQueue","_send_retriable_request","_retryQueue","startInCookielessMode","sessionPropsManager","_initExtensions","thisC","distinctID","_config$bootstrap2","_config$bootstrap3","deviceID","isIdentifiedID","_hasBootstrappedFeatureFlags","_config$bootstrap4","_config$bootstrap7","activeFlags","_config$bootstrap5","_config$bootstrap6","_config$bootstrap8","_config$bootstrap9","_handle_unload","_loaded","initStartTime","performance","historyAutocapture","initTasks","_this$siteApps","heatmaps","webVitalsAutocapture","exceptionObserver","deadClicksAutocapture","_pendingRemoteConfig","_processInitTaskQueue","queue","task","shift","taskInitTiming","round","register_for_session","$sdk_debug_extensions_init_method","$sdk_debug_extensions_init_time_ms","_config$analytics","_this$siteApps2","_this$sessionRecordin","_this$autocapture","_this$heatmaps","_this$productTours","_this$webVitalsAutoca","_this$exceptionObserv","_this$deadClicksAutoc","supportedCompression","analytics","_start_queue_if_opted_in","_captureInitialPageview","_this$_requestQueue","is_capturing","_dom_loaded","_this$_requestQueue2","_this$_retryQueue","_shouldCapturePageleave","api_transport","__preview_disable_xhr_credentials","__preview_disable_beacon","disableTransport","fetch_options","_options","_options$transport","_find$method","_find","ver","availableTransports","transportMethod","_this$config$on_reque","_this$config","_execute_array","array","fn_name","alias_calls","other_calls","capturing_calls","execute","calls","caller","_this$config$bootstra","_this$config$bootstra2","_options$_url","isBot","__preview_capture_bot_pageviews","systemTime","$browser_type","markSetOnceAsSent","setOnceProperties","_calculate_set_once_properties","DISMISSED","SENT","SURVEY_ID","surveyIteration","SURVEY_ITERATION","SURVEY_LAST_SEEN_DATE","finalSet","beforeSendResult","_runBeforeSend","_url","send_instantly","persistenceProps","pageviewProperties","infoProperties","_this$_retryQueue2","duration_in_ms","toFixed","_isIdentified","denylisted_prop","hasPersonProcessing","_hasPersonProcessing","_requirePersonProcessing","dataSetOnce","markAsSent","_this$sessionPropsMan","initialProps","sessionProps","_this$persistence","_this$persistence2","_this$sessionPersiste","property","_this$persistence3","unregister_for_session","_this$sessionPersiste2","_register_single","updateFlags","existingFlags","merge","existingPayloads","isVariant","_this$sessionManager$","_this$sessionManager","new_distinct_id","previous_distinct_id","$user_id","device_id","$had_persisted_distinct_id","isKnownAnonymous","group","groupKey","groupPropertiesToSet","existingGroups","$groups","$group_type","$group_key","$group_set","resetGroups","reset_device_id","_this$persistence4","_this$sessionPersiste3","_this$persistence5","_this$sessionManager2","$last_posthog_reset","get_session_id","_this$sessionManager$2","_this$sessionManager3","_options$timestampLoo","LOOK_BACK","timestampLookBack","alias","_this$persistence6","_this$exceptionObserv2","_this$sessionRecordin2","_this$autocapture2","_this$heatmaps2","_this$exceptionObserv3","_this$externalIntegra","isPersistenceDisabled","debugConfigFromLocalStorage","_sync_opt_out_with_persistence","startSessionRecording","overrideAll","overrideConfig","sampling","linked_flag","url_trigger","event_trigger","_this$sessionManager4","_this$sessionRecordin3","_this$sessionRecordin4","_this$sessionRecordin5","_this$sessionRecordin6","stopSessionRecording","_this$sessionRecordin7","errorToProperties","startExceptionAutocapture","stopExceptionAutocapture","property_name","_this$persistence7","getSessionProperty","_this$sessionPersiste4","_this$config$name","_this$persistence8","_this$sessionPersiste5","_this$persistence9","_this$persistence0","createPersonProfile","function_name","defaultPersistenceDisabled","_this$persistence1","_this$sessionPersiste6","_this$persistence10","_this$sessionPersiste7","opt_in_capturing","_this$sessionRecordin8","_this$sessionManager5","_this$pageViewManager","_options$captureEvent","captureEventName","captureProperties","opt_out_capturing","_this$sessionManager6","_this$pageViewManager2","_this$sessionRecordin9","has_opted_in_capturing","has_opted_out_capturing","get_explicit_consent_status","clear_opt_in_out_capturing","newField","oldField","defaultValue","loggerInstance","hasNewField","hasOldField","originalConfig","fns","getPageViewId","_this$pageViewManager3","captureTraceFeedback","traceId","userFeedback","$ai_trace_id","$ai_feedback_text","captureTraceMetric","metricName","metricValue","$ai_metric_name","$ai_metric_value","debugConfig","explicitlyFalse","isTrueInLocalStorage","klass","functions","safewrapClass","posthogMain","DEFAULT_PRODUCT_TOUR_APPEARANCE","backgroundColor","textColor","buttonColor","borderRadius","buttonBorderRadius","borderColor","fontFamily","boxShadow","showOverlay","whiteLabel","dom_loaded_handler","inst","add_dom_loaded_handler"],"mappings":"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","x_google_ignoreList":[52]}