{"mappings":"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","sources":["node_modules/@growthbook/growthbook/src/feature-repository.ts","node_modules/node_modules/dom-mutator/dist/dom-mutator.esm.js","node_modules/@growthbook/growthbook/src/util.ts","node_modules/@growthbook/growthbook/src/mongrule.ts","node_modules/@growthbook/growthbook/src/GrowthBook.ts","node_modules/@growthbook/growthbook/src/sticky-bucket-service.ts"],"sourcesContent":["import {\n Attributes,\n CacheSettings,\n FeatureApiResponse,\n Helpers,\n Polyfills,\n} from \"./types/growthbook\";\nimport type { GrowthBook } from \".\";\n\ntype CacheEntry = {\n data: FeatureApiResponse;\n sse?: boolean;\n version: string;\n staleAt: Date;\n};\ntype ScopedChannel = {\n src: EventSource | null;\n cb: (event: MessageEvent) => void;\n host: string;\n clientKey: string;\n headers?: Record;\n errors: number;\n state: \"active\" | \"idle\" | \"disabled\";\n};\n\n// Config settings\nconst cacheSettings: CacheSettings = {\n // Consider a fetch stale after 1 minute\n staleTTL: 1000 * 60,\n // Max time to keep a fetch in cache (24 hours default)\n maxAge: 1000 * 60 * 60 * 24,\n cacheKey: \"gbFeaturesCache\",\n backgroundSync: true,\n maxEntries: 10,\n disableIdleStreams: false,\n idleStreamInterval: 20000,\n};\nconst polyfills: Polyfills = {\n fetch: globalThis.fetch ? globalThis.fetch.bind(globalThis) : undefined,\n SubtleCrypto: globalThis.crypto ? globalThis.crypto.subtle : undefined,\n EventSource: globalThis.EventSource,\n};\nexport const helpers: Helpers = {\n fetchFeaturesCall: ({ host, clientKey, headers }) => {\n return (polyfills.fetch as typeof globalThis.fetch)(\n `${host}/api/features/${clientKey}`,\n { headers }\n );\n },\n fetchRemoteEvalCall: ({ host, clientKey, payload, headers }) => {\n const options = {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...headers },\n body: JSON.stringify(payload),\n };\n return (polyfills.fetch as typeof globalThis.fetch)(\n `${host}/api/eval/${clientKey}`,\n options\n );\n },\n eventSourceCall: ({ host, clientKey, headers }) => {\n if (headers) {\n return new polyfills.EventSource(`${host}/sub/${clientKey}`, {\n headers,\n });\n }\n return new polyfills.EventSource(`${host}/sub/${clientKey}`);\n },\n startIdleListener: () => {\n let idleTimeout: number | undefined;\n const isBrowser =\n typeof window !== \"undefined\" && typeof document !== \"undefined\";\n if (!isBrowser) return;\n const onVisibilityChange = () => {\n if (document.visibilityState === \"visible\") {\n window.clearTimeout(idleTimeout);\n onVisible();\n } else if (document.visibilityState === \"hidden\") {\n idleTimeout = window.setTimeout(\n onHidden,\n cacheSettings.idleStreamInterval\n );\n }\n };\n document.addEventListener(\"visibilitychange\", onVisibilityChange);\n return () =>\n document.removeEventListener(\"visibilitychange\", onVisibilityChange);\n },\n stopIdleListener: () => {\n // No-op, replaced by startIdleListener\n },\n};\n\ntry {\n if (globalThis.localStorage) {\n polyfills.localStorage = globalThis.localStorage;\n }\n} catch (e) {\n // Ignore localStorage errors\n}\n\n// Global state\nconst subscribedInstances: Map> = new Map();\nlet cacheInitialized = false;\nconst cache: Map = new Map();\nconst activeFetches: Map> = new Map();\nconst streams: Map = new Map();\nconst supportsSSE: Set = new Set();\n\n// Public functions\nexport function setPolyfills(overrides: Partial): void {\n Object.assign(polyfills, overrides);\n}\nexport function configureCache(overrides: Partial): void {\n Object.assign(cacheSettings, overrides);\n if (!cacheSettings.backgroundSync) {\n clearAutoRefresh();\n }\n}\n\nexport async function clearCache(): Promise {\n cache.clear();\n activeFetches.clear();\n clearAutoRefresh();\n cacheInitialized = false;\n await updatePersistentCache();\n}\n\nexport async function refreshFeatures(\n instance: GrowthBook,\n timeout?: number,\n skipCache?: boolean,\n allowStale?: boolean,\n updateInstance?: boolean,\n backgroundSync?: boolean\n): Promise {\n if (!backgroundSync) {\n cacheSettings.backgroundSync = false;\n }\n\n const data = await fetchFeaturesWithCache(\n instance,\n allowStale,\n timeout,\n skipCache\n );\n updateInstance && data && (await refreshInstance(instance, data));\n}\n\n// Subscribe a GrowthBook instance to feature changes\nexport function subscribe(instance: GrowthBook): void {\n const key = getKey(instance);\n const subs = subscribedInstances.get(key) || new Set();\n subs.add(instance);\n subscribedInstances.set(key, subs);\n}\nexport function unsubscribe(instance: GrowthBook): void {\n subscribedInstances.forEach((s) => s.delete(instance));\n}\n\nexport function onHidden() {\n streams.forEach((channel) => {\n if (!channel) return;\n channel.state = \"idle\";\n disableChannel(channel);\n });\n}\n\nexport function onVisible() {\n streams.forEach((channel) => {\n if (!channel) return;\n if (channel.state !== \"idle\") return;\n enableChannel(channel);\n });\n}\n\n// Private functions\n\nasync function updatePersistentCache() {\n try {\n if (!polyfills.localStorage) return;\n await polyfills.localStorage.setItem(\n cacheSettings.cacheKey,\n JSON.stringify(Array.from(cache.entries()))\n );\n } catch (e) {\n // Ignore localStorage errors\n }\n}\n\nasync function fetchFeaturesWithCache(\n instance: GrowthBook,\n allowStale?: boolean,\n timeout?: number,\n skipCache?: boolean\n): Promise {\n const key = getKey(instance);\n const cacheKey = getCacheKey(instance);\n const now = new Date();\n\n const minStaleAt = new Date(\n now.getTime() - cacheSettings.maxAge + cacheSettings.staleTTL\n );\n\n await initializeCache();\n const existing = cache.get(cacheKey);\n if (\n existing &&\n !skipCache &&\n (allowStale || existing.staleAt > now) &&\n existing.staleAt > minStaleAt\n ) {\n // Restore from cache whether SSE is supported\n if (existing.sse) supportsSSE.add(key);\n\n // Reload features in the background if stale\n if (existing.staleAt < now) {\n fetchFeatures(instance);\n }\n // Otherwise, if we don't need to refresh now, start a background sync\n else {\n startAutoRefresh(instance);\n }\n return existing.data;\n } else {\n return await promiseTimeout(fetchFeatures(instance), timeout);\n }\n}\n\nfunction getKey(instance: GrowthBook): string {\n const [apiHost, clientKey] = instance.getApiInfo();\n return `${apiHost}||${clientKey}`;\n}\n\nfunction getCacheKey(instance: GrowthBook): string {\n const baseKey = getKey(instance);\n if (!instance.isRemoteEval()) return baseKey;\n\n const attributes = instance.getAttributes();\n const cacheKeyAttributes =\n instance.getCacheKeyAttributes() || Object.keys(instance.getAttributes());\n const ca: Attributes = {};\n cacheKeyAttributes.forEach((key) => {\n ca[key] = attributes[key];\n });\n\n const fv = instance.getForcedVariations();\n const url = instance.getUrl();\n\n return `${baseKey}||${JSON.stringify({\n ca,\n fv,\n url,\n })}`;\n}\n\n// Guarantee the promise always resolves within {timeout} ms\n// Resolved value will be `null` when there's an error or it takes too long\n// Note: The promise will continue running in the background, even if the timeout is hit\nfunction promiseTimeout(\n promise: Promise,\n timeout?: number\n): Promise {\n return new Promise((resolve) => {\n let resolved = false;\n let timer: unknown;\n const finish = (data?: T) => {\n if (resolved) return;\n resolved = true;\n timer && clearTimeout(timer as NodeJS.Timer);\n resolve(data || null);\n };\n\n if (timeout) {\n timer = setTimeout(() => finish(), timeout);\n }\n\n promise.then((data) => finish(data)).catch(() => finish());\n });\n}\n\n// Populate cache from localStorage (if available)\nasync function initializeCache(): Promise {\n if (cacheInitialized) return;\n cacheInitialized = true;\n try {\n if (polyfills.localStorage) {\n const value = await polyfills.localStorage.getItem(\n cacheSettings.cacheKey\n );\n if (value) {\n const parsed: [string, CacheEntry][] = JSON.parse(value);\n if (parsed && Array.isArray(parsed)) {\n parsed.forEach(([key, data]) => {\n cache.set(key, {\n ...data,\n staleAt: new Date(data.staleAt),\n });\n });\n }\n cleanupCache();\n }\n }\n } catch (e) {\n // Ignore localStorage errors\n }\n if (!cacheSettings.disableIdleStreams) {\n const cleanupFn = helpers.startIdleListener();\n if (cleanupFn) {\n helpers.stopIdleListener = cleanupFn;\n }\n }\n}\n\n// Enforce the maxEntries limit\nfunction cleanupCache() {\n const entriesWithTimestamps = Array.from(cache.entries())\n .map(([key, value]) => ({\n key,\n staleAt: value.staleAt.getTime(),\n }))\n .sort((a, b) => a.staleAt - b.staleAt);\n\n const entriesToRemoveCount = Math.min(\n Math.max(0, cache.size - cacheSettings.maxEntries),\n cache.size\n );\n\n for (let i = 0; i < entriesToRemoveCount; i++) {\n cache.delete(entriesWithTimestamps[i].key);\n }\n}\n\n// Called whenever new features are fetched from the API\nfunction onNewFeatureData(\n key: string,\n cacheKey: string,\n data: FeatureApiResponse\n): void {\n // If contents haven't changed, ignore the update, extend the stale TTL\n const version = data.dateUpdated || \"\";\n const staleAt = new Date(Date.now() + cacheSettings.staleTTL);\n const existing = cache.get(cacheKey);\n if (existing && version && existing.version === version) {\n existing.staleAt = staleAt;\n updatePersistentCache();\n return;\n }\n\n // Update in-memory cache\n cache.set(cacheKey, {\n data,\n version,\n staleAt,\n sse: supportsSSE.has(key),\n });\n cleanupCache();\n // Update local storage (don't await this, just update asynchronously)\n updatePersistentCache();\n\n // Update features for all subscribed GrowthBook instances\n const instances = subscribedInstances.get(key);\n instances && instances.forEach((instance) => refreshInstance(instance, data));\n}\n\nasync function refreshInstance(\n instance: GrowthBook,\n data: FeatureApiResponse\n): Promise {\n data = await instance.decryptPayload(data, undefined, polyfills.SubtleCrypto);\n\n await instance.refreshStickyBuckets(data);\n instance.setFeatures(data.features || instance.getFeatures());\n instance.setExperiments(data.experiments || instance.getExperiments());\n}\n\nasync function fetchFeatures(\n instance: GrowthBook\n): Promise {\n const { apiHost, apiRequestHeaders } = instance.getApiHosts();\n const clientKey = instance.getClientKey();\n const remoteEval = instance.isRemoteEval();\n const key = getKey(instance);\n const cacheKey = getCacheKey(instance);\n\n let promise = activeFetches.get(cacheKey);\n if (!promise) {\n const fetcher: Promise = remoteEval\n ? helpers.fetchRemoteEvalCall({\n host: apiHost,\n clientKey,\n payload: {\n attributes: instance.getAttributes(),\n forcedVariations: instance.getForcedVariations(),\n forcedFeatures: Array.from(instance.getForcedFeatures().entries()),\n url: instance.getUrl(),\n },\n headers: apiRequestHeaders,\n })\n : helpers.fetchFeaturesCall({\n host: apiHost,\n clientKey,\n headers: apiRequestHeaders,\n });\n\n // TODO: auto-retry if status code indicates a temporary error\n promise = fetcher\n .then((res) => {\n if (!res.ok) {\n throw new Error(`HTTP error: ${res.status}`);\n }\n if (res.headers.get(\"x-sse-support\") === \"enabled\") {\n supportsSSE.add(key);\n }\n return res.json();\n })\n .then((data: FeatureApiResponse) => {\n onNewFeatureData(key, cacheKey, data);\n startAutoRefresh(instance);\n activeFetches.delete(cacheKey);\n return data;\n })\n .catch((e) => {\n process.env.NODE_ENV !== \"production\" &&\n instance.log(\"Error fetching features\", {\n apiHost,\n clientKey,\n error: e ? e.message : null,\n });\n activeFetches.delete(cacheKey);\n return Promise.resolve({});\n });\n activeFetches.set(cacheKey, promise);\n }\n return await promise;\n}\n\n// Watch a feature endpoint for changes\n// Will prefer SSE if enabled, otherwise fall back to cron\nfunction startAutoRefresh(instance: GrowthBook): void {\n const key = getKey(instance);\n const cacheKey = getCacheKey(instance);\n const { streamingHost, streamingHostRequestHeaders } = instance.getApiHosts();\n const clientKey = instance.getClientKey();\n if (\n cacheSettings.backgroundSync &&\n supportsSSE.has(key) &&\n polyfills.EventSource\n ) {\n if (streams.has(key)) return;\n const channel: ScopedChannel = {\n src: null,\n host: streamingHost,\n clientKey,\n headers: streamingHostRequestHeaders,\n cb: (event: MessageEvent) => {\n try {\n if (event.type === \"features-updated\") {\n const instances = subscribedInstances.get(key);\n instances &&\n instances.forEach((instance) => {\n fetchFeatures(instance);\n });\n } else if (event.type === \"features\") {\n const json: FeatureApiResponse = JSON.parse(event.data);\n onNewFeatureData(key, cacheKey, json);\n }\n // Reset error count on success\n channel.errors = 0;\n } catch (e) {\n process.env.NODE_ENV !== \"production\" &&\n instance.log(\"SSE Error\", {\n streamingHost,\n clientKey,\n error: e ? (e as Error).message : null,\n });\n onSSEError(channel);\n }\n },\n errors: 0,\n state: \"active\",\n };\n streams.set(key, channel);\n enableChannel(channel);\n }\n}\n\nfunction onSSEError(channel: ScopedChannel) {\n if (channel.state === \"idle\") return;\n channel.errors++;\n if (channel.errors > 3 || (channel.src && channel.src.readyState === 2)) {\n // exponential backoff after 4 errors, with jitter\n const delay =\n Math.pow(3, channel.errors - 3) * (1000 + Math.random() * 1000);\n disableChannel(channel);\n setTimeout(() => {\n if ([\"idle\", \"active\"].includes(channel.state)) return;\n enableChannel(channel);\n }, Math.min(delay, 300000)); // 5 minutes max\n }\n}\n\nfunction disableChannel(channel: ScopedChannel) {\n if (!channel.src) return;\n channel.src.onopen = null;\n channel.src.onerror = null;\n channel.src.close();\n channel.src = null;\n if (channel.state === \"active\") {\n channel.state = \"disabled\";\n }\n}\n\nfunction enableChannel(channel: ScopedChannel) {\n channel.src = helpers.eventSourceCall({\n host: channel.host,\n clientKey: channel.clientKey,\n headers: channel.headers,\n }) as EventSource;\n channel.state = \"active\";\n channel.src.addEventListener(\"features\", channel.cb);\n channel.src.addEventListener(\"features-updated\", channel.cb);\n channel.src.onerror = () => onSSEError(channel);\n channel.src.onopen = () => {\n channel.errors = 0;\n };\n}\n\nfunction destroyChannel(channel: ScopedChannel, key: string) {\n disableChannel(channel);\n streams.delete(key);\n}\n\nfunction clearAutoRefresh() {\n // Clear list of which keys are auto-updated\n supportsSSE.clear();\n\n // Stop listening for any SSE events\n streams.forEach(destroyChannel);\n\n // Remove all references to GrowthBook instances\n subscribedInstances.clear();\n\n // Run the idle stream cleanup function\n helpers.stopIdleListener();\n}\n","var validAttributeName = /^[a-zA-Z:_][a-zA-Z0-9:_.-]*$/;\nvar nullController = {\n revert: function revert() {}\n};\nvar elements = /*#__PURE__*/new Map();\nvar mutations = /*#__PURE__*/new Set();\n\nfunction getObserverInit(attr) {\n return attr === 'html' ? {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true\n } : {\n childList: false,\n subtree: false,\n attributes: true,\n attributeFilter: [attr]\n };\n}\n\nfunction getElementRecord(element) {\n var record = elements.get(element);\n\n if (!record) {\n record = {\n element: element,\n attributes: {}\n };\n elements.set(element, record);\n }\n\n return record;\n}\n\nfunction createElementPropertyRecord(el, attr, getCurrentValue, setValue, mutationRunner) {\n var currentValue = getCurrentValue(el);\n var record = {\n isDirty: false,\n originalValue: currentValue,\n virtualValue: currentValue,\n mutations: [],\n el: el,\n _positionTimeout: null,\n observer: new MutationObserver(function () {\n // enact a 1 second timeout that blocks subsequent firing of the\n // observer until the timeout is complete. This will prevent multiple\n // mutations from firing in quick succession, which can cause the\n // mutation to be reverted before the DOM has a chance to update.\n if (attr === 'position' && record._positionTimeout) return;else if (attr === 'position') record._positionTimeout = setTimeout(function () {\n record._positionTimeout = null;\n }, 1000);\n var currentValue = getCurrentValue(el);\n if (attr === 'position' && currentValue.parentNode === record.virtualValue.parentNode && currentValue.insertBeforeNode === record.virtualValue.insertBeforeNode) return;\n if (currentValue === record.virtualValue) return;\n record.originalValue = currentValue;\n mutationRunner(record);\n }),\n mutationRunner: mutationRunner,\n setValue: setValue,\n getCurrentValue: getCurrentValue\n };\n\n if (attr === 'position' && el.parentNode) {\n record.observer.observe(el.parentNode, {\n childList: true,\n subtree: true,\n attributes: false,\n characterData: false\n });\n } else {\n record.observer.observe(el, getObserverInit(attr));\n }\n\n return record;\n}\n\nfunction queueIfNeeded(val, record) {\n var currentVal = record.getCurrentValue(record.el);\n record.virtualValue = val;\n\n if (val && typeof val !== 'string') {\n if (!currentVal || val.parentNode !== currentVal.parentNode || val.insertBeforeNode !== currentVal.insertBeforeNode) {\n record.isDirty = true;\n runDOMUpdates();\n }\n } else if (val !== currentVal) {\n record.isDirty = true;\n runDOMUpdates();\n }\n}\n\nfunction htmlMutationRunner(record) {\n var val = record.originalValue;\n record.mutations.forEach(function (m) {\n return val = m.mutate(val);\n });\n queueIfNeeded(getTransformedHTML(val), record);\n}\n\nfunction classMutationRunner(record) {\n var val = new Set(record.originalValue.split(/\\s+/).filter(Boolean));\n record.mutations.forEach(function (m) {\n return m.mutate(val);\n });\n queueIfNeeded(Array.from(val).filter(Boolean).join(' '), record);\n}\n\nfunction attrMutationRunner(record) {\n var val = record.originalValue;\n record.mutations.forEach(function (m) {\n return val = m.mutate(val);\n });\n queueIfNeeded(val, record);\n}\n\nfunction _loadDOMNodes(_ref) {\n var parentSelector = _ref.parentSelector,\n insertBeforeSelector = _ref.insertBeforeSelector;\n var parentNode = document.querySelector(parentSelector);\n if (!parentNode) return null;\n var insertBeforeNode = insertBeforeSelector ? document.querySelector(insertBeforeSelector) : null;\n if (insertBeforeSelector && !insertBeforeNode) return null;\n return {\n parentNode: parentNode,\n insertBeforeNode: insertBeforeNode\n };\n}\n\nfunction positionMutationRunner(record) {\n var val = record.originalValue;\n record.mutations.forEach(function (m) {\n var selectors = m.mutate();\n\n var newNodes = _loadDOMNodes(selectors);\n\n val = newNodes || val;\n });\n queueIfNeeded(val, record);\n}\n\nvar getHTMLValue = function getHTMLValue(el) {\n return el.innerHTML;\n};\n\nvar setHTMLValue = function setHTMLValue(el, value) {\n return el.innerHTML = value;\n};\n\nfunction getElementHTMLRecord(element) {\n var elementRecord = getElementRecord(element);\n\n if (!elementRecord.html) {\n elementRecord.html = createElementPropertyRecord(element, 'html', getHTMLValue, setHTMLValue, htmlMutationRunner);\n }\n\n return elementRecord.html;\n}\n\nvar getElementPosition = function getElementPosition(el) {\n return {\n parentNode: el.parentElement,\n insertBeforeNode: el.nextElementSibling\n };\n};\n\nvar setElementPosition = function setElementPosition(el, value) {\n if (value.insertBeforeNode && !value.parentNode.contains(value.insertBeforeNode)) {\n // skip position mutation - insertBeforeNode not a child of parent. happens\n // when mutation observer for indvidual element fires out of order\n return;\n }\n\n value.parentNode.insertBefore(el, value.insertBeforeNode);\n};\n\nfunction getElementPositionRecord(element) {\n var elementRecord = getElementRecord(element);\n\n if (!elementRecord.position) {\n elementRecord.position = createElementPropertyRecord(element, 'position', getElementPosition, setElementPosition, positionMutationRunner);\n }\n\n return elementRecord.position;\n}\n\nvar setClassValue = function setClassValue(el, val) {\n return val ? el.className = val : el.removeAttribute('class');\n};\n\nvar getClassValue = function getClassValue(el) {\n return el.className;\n};\n\nfunction getElementClassRecord(el) {\n var elementRecord = getElementRecord(el);\n\n if (!elementRecord.classes) {\n elementRecord.classes = createElementPropertyRecord(el, 'class', getClassValue, setClassValue, classMutationRunner);\n }\n\n return elementRecord.classes;\n}\n\nvar getAttrValue = function getAttrValue(attrName) {\n return function (el) {\n var _el$getAttribute;\n\n return (_el$getAttribute = el.getAttribute(attrName)) != null ? _el$getAttribute : null;\n };\n};\n\nvar setAttrValue = function setAttrValue(attrName) {\n return function (el, val) {\n return val !== null ? el.setAttribute(attrName, val) : el.removeAttribute(attrName);\n };\n};\n\nfunction getElementAttributeRecord(el, attr) {\n var elementRecord = getElementRecord(el);\n\n if (!elementRecord.attributes[attr]) {\n elementRecord.attributes[attr] = createElementPropertyRecord(el, attr, getAttrValue(attr), setAttrValue(attr), attrMutationRunner);\n }\n\n return elementRecord.attributes[attr];\n}\n\nfunction deleteElementPropertyRecord(el, attr) {\n var element = elements.get(el);\n if (!element) return;\n\n if (attr === 'html') {\n var _element$html, _element$html$observe;\n\n (_element$html = element.html) == null ? void 0 : (_element$html$observe = _element$html.observer) == null ? void 0 : _element$html$observe.disconnect();\n delete element.html;\n } else if (attr === 'class') {\n var _element$classes, _element$classes$obse;\n\n (_element$classes = element.classes) == null ? void 0 : (_element$classes$obse = _element$classes.observer) == null ? void 0 : _element$classes$obse.disconnect();\n delete element.classes;\n } else if (attr === 'position') {\n var _element$position, _element$position$obs;\n\n (_element$position = element.position) == null ? void 0 : (_element$position$obs = _element$position.observer) == null ? void 0 : _element$position$obs.disconnect();\n delete element.position;\n } else {\n var _element$attributes, _element$attributes$a, _element$attributes$a2;\n\n (_element$attributes = element.attributes) == null ? void 0 : (_element$attributes$a = _element$attributes[attr]) == null ? void 0 : (_element$attributes$a2 = _element$attributes$a.observer) == null ? void 0 : _element$attributes$a2.disconnect();\n delete element.attributes[attr];\n }\n}\n\nvar transformContainer;\n\nfunction getTransformedHTML(html) {\n if (!transformContainer) {\n transformContainer = document.createElement('div');\n }\n\n transformContainer.innerHTML = html;\n return transformContainer.innerHTML;\n}\n\nfunction setPropertyValue(el, attr, m) {\n if (!m.isDirty) return;\n m.isDirty = false;\n var val = m.virtualValue;\n\n if (!m.mutations.length) {\n deleteElementPropertyRecord(el, attr);\n }\n\n m.setValue(el, val);\n}\n\nfunction setValue(m, el) {\n m.html && setPropertyValue(el, 'html', m.html);\n m.classes && setPropertyValue(el, 'class', m.classes);\n m.position && setPropertyValue(el, 'position', m.position);\n Object.keys(m.attributes).forEach(function (attr) {\n setPropertyValue(el, attr, m.attributes[attr]);\n });\n}\n\nfunction runDOMUpdates() {\n elements.forEach(setValue);\n} // find or create ElementPropertyRecord, add mutation to it, then run\n\n\nfunction startMutating(mutation, element) {\n var record = null;\n\n if (mutation.kind === 'html') {\n record = getElementHTMLRecord(element);\n } else if (mutation.kind === 'class') {\n record = getElementClassRecord(element);\n } else if (mutation.kind === 'attribute') {\n record = getElementAttributeRecord(element, mutation.attribute);\n } else if (mutation.kind === 'position') {\n record = getElementPositionRecord(element);\n }\n\n if (!record) return;\n record.mutations.push(mutation);\n record.mutationRunner(record);\n} // get (existing) ElementPropertyRecord, remove mutation from it, then run\n\n\nfunction stopMutating(mutation, el) {\n var record = null;\n\n if (mutation.kind === 'html') {\n record = getElementHTMLRecord(el);\n } else if (mutation.kind === 'class') {\n record = getElementClassRecord(el);\n } else if (mutation.kind === 'attribute') {\n record = getElementAttributeRecord(el, mutation.attribute);\n } else if (mutation.kind === 'position') {\n record = getElementPositionRecord(el);\n }\n\n if (!record) return;\n var index = record.mutations.indexOf(mutation);\n if (index !== -1) record.mutations.splice(index, 1);\n record.mutationRunner(record);\n} // maintain list of elements associated with mutation\n\n\nfunction refreshElementsSet(mutation) {\n // if a position mutation has already found an element to move, don't move\n // any more elements\n if (mutation.kind === 'position' && mutation.elements.size === 1) return;\n var existingElements = new Set(mutation.elements);\n var matchingElements = document.querySelectorAll(mutation.selector);\n matchingElements.forEach(function (el) {\n if (!existingElements.has(el)) {\n mutation.elements.add(el);\n startMutating(mutation, el);\n }\n });\n}\n\nfunction revertMutation(mutation) {\n mutation.elements.forEach(function (el) {\n return stopMutating(mutation, el);\n });\n mutation.elements.clear();\n mutations[\"delete\"](mutation);\n}\n\nfunction refreshAllElementSets() {\n mutations.forEach(refreshElementsSet);\n} // Observer for elements that don't exist in the DOM yet\n\n\nvar observer;\nfunction disconnectGlobalObserver() {\n observer && observer.disconnect();\n}\nfunction connectGlobalObserver() {\n if (typeof document === 'undefined') return;\n\n if (!observer) {\n observer = new MutationObserver(function () {\n refreshAllElementSets();\n });\n }\n\n refreshAllElementSets();\n observer.observe(document.documentElement, {\n childList: true,\n subtree: true,\n attributes: false,\n characterData: false\n });\n} // run on init\n\nconnectGlobalObserver();\n\nfunction newMutation(m) {\n // Not in a browser\n if (typeof document === 'undefined') return nullController; // add to global index of mutations\n\n mutations.add(m); // run refresh on init to establish list of elements associated w/ mutation\n\n refreshElementsSet(m);\n return {\n revert: function revert() {\n revertMutation(m);\n }\n };\n}\n\nfunction html(selector, mutate) {\n return newMutation({\n kind: 'html',\n elements: new Set(),\n mutate: mutate,\n selector: selector\n });\n}\n\nfunction position(selector, mutate) {\n return newMutation({\n kind: 'position',\n elements: new Set(),\n mutate: mutate,\n selector: selector\n });\n}\n\nfunction classes(selector, mutate) {\n return newMutation({\n kind: 'class',\n elements: new Set(),\n mutate: mutate,\n selector: selector\n });\n}\n\nfunction attribute(selector, attribute, mutate) {\n if (!validAttributeName.test(attribute)) return nullController;\n\n if (attribute === 'class' || attribute === 'className') {\n return classes(selector, function (classnames) {\n var mutatedClassnames = mutate(Array.from(classnames).join(' '));\n classnames.clear();\n if (!mutatedClassnames) return;\n mutatedClassnames.split(/\\s+/g).filter(Boolean).forEach(function (c) {\n return classnames.add(c);\n });\n });\n }\n\n return newMutation({\n kind: 'attribute',\n attribute: attribute,\n elements: new Set(),\n mutate: mutate,\n selector: selector\n });\n}\n\nfunction declarative(_ref2) {\n var selector = _ref2.selector,\n action = _ref2.action,\n value = _ref2.value,\n attr = _ref2.attribute,\n parentSelector = _ref2.parentSelector,\n insertBeforeSelector = _ref2.insertBeforeSelector;\n\n if (attr === 'html') {\n if (action === 'append') {\n return html(selector, function (val) {\n return val + (value != null ? value : '');\n });\n } else if (action === 'set') {\n return html(selector, function () {\n return value != null ? value : '';\n });\n }\n } else if (attr === 'class') {\n if (action === 'append') {\n return classes(selector, function (val) {\n if (value) val.add(value);\n });\n } else if (action === 'remove') {\n return classes(selector, function (val) {\n if (value) val[\"delete\"](value);\n });\n } else if (action === 'set') {\n return classes(selector, function (val) {\n val.clear();\n if (value) val.add(value);\n });\n }\n } else if (attr === 'position') {\n if (action === 'set' && parentSelector) {\n return position(selector, function () {\n return {\n insertBeforeSelector: insertBeforeSelector,\n parentSelector: parentSelector\n };\n });\n }\n } else {\n if (action === 'append') {\n return attribute(selector, attr, function (val) {\n return val !== null ? val + (value != null ? value : '') : value != null ? value : '';\n });\n } else if (action === 'set') {\n return attribute(selector, attr, function () {\n return value != null ? value : '';\n });\n } else if (action === 'remove') {\n return attribute(selector, attr, function () {\n return null;\n });\n }\n }\n\n return nullController;\n}\n\nvar index = {\n html: html,\n classes: classes,\n attribute: attribute,\n position: position,\n declarative: declarative\n};\n\nexport default index;\nexport { connectGlobalObserver, disconnectGlobalObserver, validAttributeName };\n//# sourceMappingURL=dom-mutator.esm.js.map\n","import { UrlTarget, UrlTargetType, VariationRange } from \"./types/growthbook\";\n\nfunction hashFnv32a(str: string): number {\n let hval = 0x811c9dc5;\n const l = str.length;\n\n for (let i = 0; i < l; i++) {\n hval ^= str.charCodeAt(i);\n hval +=\n (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);\n }\n return hval >>> 0;\n}\n\nexport function hash(\n seed: string,\n value: string,\n version: number\n): number | null {\n // New unbiased hashing algorithm\n if (version === 2) {\n return (hashFnv32a(hashFnv32a(seed + value) + \"\") % 10000) / 10000;\n }\n // Original biased hashing algorithm (keep for backwards compatibility)\n if (version === 1) {\n return (hashFnv32a(value + seed) % 1000) / 1000;\n }\n\n // Unknown hash version\n return null;\n}\n\nexport function getEqualWeights(n: number): number[] {\n if (n <= 0) return [];\n return new Array(n).fill(1 / n);\n}\n\nexport function inRange(n: number, range: VariationRange): boolean {\n return n >= range[0] && n < range[1];\n}\n\nexport function inNamespace(\n hashValue: string,\n namespace: [string, number, number]\n): boolean {\n const n = hash(\"__\" + namespace[0], hashValue, 1);\n if (n === null) return false;\n return n >= namespace[1] && n < namespace[2];\n}\n\nexport function chooseVariation(n: number, ranges: VariationRange[]): number {\n for (let i = 0; i < ranges.length; i++) {\n if (inRange(n, ranges[i])) {\n return i;\n }\n }\n return -1;\n}\n\nexport function getUrlRegExp(regexString: string): RegExp | undefined {\n try {\n const escaped = regexString.replace(/([^\\\\])\\//g, \"$1\\\\/\");\n return new RegExp(escaped);\n } catch (e) {\n console.error(e);\n return undefined;\n }\n}\n\nexport function isURLTargeted(url: string, targets: UrlTarget[]) {\n if (!targets.length) return false;\n let hasIncludeRules = false;\n let isIncluded = false;\n\n for (let i = 0; i < targets.length; i++) {\n const match = _evalURLTarget(url, targets[i].type, targets[i].pattern);\n if (targets[i].include === false) {\n if (match) return false;\n } else {\n hasIncludeRules = true;\n if (match) isIncluded = true;\n }\n }\n\n return isIncluded || !hasIncludeRules;\n}\n\nfunction _evalSimpleUrlPart(\n actual: string,\n pattern: string,\n isPath: boolean\n): boolean {\n try {\n // Escape special regex characters and change wildcard `_____` to `.*`\n let escaped = pattern\n .replace(/[*.+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n .replace(/_____/g, \".*\");\n\n if (isPath) {\n // When matching pathname, make leading/trailing slashes optional\n escaped = \"\\\\/?\" + escaped.replace(/(^\\/|\\/$)/g, \"\") + \"\\\\/?\";\n }\n\n const regex = new RegExp(\"^\" + escaped + \"$\", \"i\");\n return regex.test(actual);\n } catch (e) {\n return false;\n }\n}\n\nfunction _evalSimpleUrlTarget(actual: URL, pattern: string) {\n try {\n // If a protocol is missing, but a host is specified, add `https://` to the front\n // Use \"_____\" as the wildcard since `*` is not a valid hostname in some browsers\n const expected = new URL(\n pattern.replace(/^([^:/?]*)\\./i, \"https://$1.\").replace(/\\*/g, \"_____\"),\n \"https://_____\"\n );\n\n // Compare each part of the URL separately\n const comps: Array<[string, string, boolean]> = [\n [actual.host, expected.host, false],\n [actual.pathname, expected.pathname, true],\n ];\n // We only want to compare hashes if it's explicitly being targeted\n if (expected.hash) {\n comps.push([actual.hash, expected.hash, false]);\n }\n\n expected.searchParams.forEach((v, k) => {\n comps.push([actual.searchParams.get(k) || \"\", v, false]);\n });\n\n // If any comparisons fail, the whole thing fails\n return !comps.some(\n (data) => !_evalSimpleUrlPart(data[0], data[1], data[2])\n );\n } catch (e) {\n return false;\n }\n}\n\nfunction _evalURLTarget(\n url: string,\n type: UrlTargetType,\n pattern: string\n): boolean {\n try {\n const parsed = new URL(url, \"https://_\");\n\n if (type === \"regex\") {\n const regex = getUrlRegExp(pattern);\n if (!regex) return false;\n return (\n regex.test(parsed.href) ||\n regex.test(parsed.href.substring(parsed.origin.length))\n );\n } else if (type === \"simple\") {\n return _evalSimpleUrlTarget(parsed, pattern);\n }\n\n return false;\n } catch (e) {\n return false;\n }\n}\n\nexport function getBucketRanges(\n numVariations: number,\n coverage: number | undefined,\n weights?: number[]\n): VariationRange[] {\n coverage = coverage === undefined ? 1 : coverage;\n\n // Make sure coverage is within bounds\n if (coverage < 0) {\n if (process.env.NODE_ENV !== \"production\") {\n console.error(\"Experiment.coverage must be greater than or equal to 0\");\n }\n coverage = 0;\n } else if (coverage > 1) {\n if (process.env.NODE_ENV !== \"production\") {\n console.error(\"Experiment.coverage must be less than or equal to 1\");\n }\n coverage = 1;\n }\n\n // Default to equal weights if missing or invalid\n const equal = getEqualWeights(numVariations);\n weights = weights || equal;\n if (weights.length !== numVariations) {\n if (process.env.NODE_ENV !== \"production\") {\n console.error(\n \"Experiment.weights array must be the same length as Experiment.variations\"\n );\n }\n weights = equal;\n }\n\n // If weights don't add up to 1 (or close to it), default to equal weights\n const totalWeight = weights.reduce((w, sum) => sum + w, 0);\n if (totalWeight < 0.99 || totalWeight > 1.01) {\n if (process.env.NODE_ENV !== \"production\") {\n console.error(\"Experiment.weights must add up to 1\");\n }\n weights = equal;\n }\n\n // Covert weights to ranges\n let cumulative = 0;\n return weights.map((w) => {\n const start = cumulative;\n cumulative += w;\n return [start, start + (coverage as number) * w];\n }) as VariationRange[];\n}\n\nexport function getQueryStringOverride(\n id: string,\n url: string,\n numVariations: number\n) {\n if (!url) {\n return null;\n }\n\n const search = url.split(\"?\")[1];\n if (!search) {\n return null;\n }\n\n const match = search\n .replace(/#.*/, \"\") // Get rid of anchor\n .split(\"&\") // Split into key/value pairs\n .map((kv) => kv.split(\"=\", 2))\n .filter(([k]) => k === id) // Look for key that matches the experiment id\n .map(([, v]) => parseInt(v)); // Parse the value into an integer\n\n if (match.length > 0 && match[0] >= 0 && match[0] < numVariations)\n return match[0];\n\n return null;\n}\n\nexport function isIncluded(include: () => boolean) {\n try {\n return include();\n } catch (e) {\n console.error(e);\n return false;\n }\n}\n\nconst base64ToBuf = (b: string) =>\n Uint8Array.from(atob(b), (c) => c.charCodeAt(0));\n\nexport async function decrypt(\n encryptedString: string,\n decryptionKey?: string,\n subtle?: SubtleCrypto\n): Promise {\n decryptionKey = decryptionKey || \"\";\n subtle = subtle || (globalThis.crypto && globalThis.crypto.subtle);\n if (!subtle) {\n throw new Error(\"No SubtleCrypto implementation found\");\n }\n try {\n const key = await subtle.importKey(\n \"raw\",\n base64ToBuf(decryptionKey),\n { name: \"AES-CBC\", length: 128 },\n true,\n [\"encrypt\", \"decrypt\"]\n );\n const [iv, cipherText] = encryptedString.split(\".\");\n const plainTextBuffer = await subtle.decrypt(\n { name: \"AES-CBC\", iv: base64ToBuf(iv) },\n key,\n base64ToBuf(cipherText)\n );\n\n return new TextDecoder().decode(plainTextBuffer);\n } catch (e) {\n throw new Error(\"Failed to decrypt\");\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function toString(input: any): string {\n if (typeof input === \"string\") return input;\n return JSON.stringify(input);\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function paddedVersionString(input: any): string {\n if (typeof input === \"number\") {\n input = input + \"\";\n }\n if (!input || typeof input !== \"string\") {\n input = \"0\";\n }\n // Remove build info and leading `v` if any\n // Split version into parts (both core version numbers and pre-release tags)\n // \"v1.2.3-rc.1+build123\" -> [\"1\",\"2\",\"3\",\"rc\",\"1\"]\n const parts = (input as string).replace(/(^v|\\+.*$)/g, \"\").split(/[-.]/);\n\n // If it's SemVer without a pre-release, add `~` to the end\n // [\"1\",\"0\",\"0\"] -> [\"1\",\"0\",\"0\",\"~\"]\n // \"~\" is the largest ASCII character, so this will make \"1.0.0\" greater than \"1.0.0-beta\" for example\n if (parts.length === 3) {\n parts.push(\"~\");\n }\n\n // Left pad each numeric part with spaces so string comparisons will work (\"9\">\"10\", but \" 9\"<\"10\")\n // Then, join back together into a single string\n return parts\n .map((v) => (v.match(/^[0-9]+$/) ? v.padStart(5, \" \") : v))\n .join(\"-\");\n}\n\nexport function loadSDKVersion(): string {\n let version: string;\n try {\n // @ts-expect-error right-hand value to be replaced by build with string literal\n version = __SDK_VERSION__;\n } catch (e) {\n version = \"\";\n }\n return version;\n}\n\nexport function mergeQueryStrings(oldUrl: string, newUrl: string): string {\n let currUrl: URL;\n let redirectUrl: URL;\n try {\n currUrl = new URL(oldUrl);\n redirectUrl = new URL(newUrl);\n } catch (e) {\n console.error(`Unable to merge query strings: ${e}`);\n return newUrl;\n }\n\n currUrl.searchParams.forEach((value, key) => {\n // skip if search param already exists in redirectUrl\n if (redirectUrl.searchParams.has(key)) {\n return;\n }\n redirectUrl.searchParams.set(key, value);\n });\n\n return redirectUrl.toString();\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport {\n ConditionInterface,\n TestedObj,\n ConditionValue,\n Operator,\n OperatorConditionValue,\n VarType,\n} from \"./types/mongrule\";\nimport { paddedVersionString } from \"./util\";\n\nconst _regexCache: { [key: string]: RegExp } = {};\n\n// The top-level condition evaluation function\nexport function evalCondition(\n obj: TestedObj,\n condition: ConditionInterface\n): boolean {\n // Recursive condition\n if (\"$or\" in condition) {\n return evalOr(obj, condition[\"$or\"] as ConditionInterface[]);\n }\n if (\"$nor\" in condition) {\n return !evalOr(obj, condition[\"$nor\"] as ConditionInterface[]);\n }\n if (\"$and\" in condition) {\n return evalAnd(obj, condition[\"$and\"] as ConditionInterface[]);\n }\n if (\"$not\" in condition) {\n return !evalCondition(obj, condition[\"$not\"] as ConditionInterface);\n }\n\n // Condition is an object, keys are object paths, values are the condition for that path\n for (const [k, v] of Object.entries(condition)) {\n if (!evalConditionValue(v, getPath(obj, k))) return false;\n }\n return true;\n}\n\n// Return value at dot-separated path of an object\nfunction getPath(obj: TestedObj, path: string) {\n const parts = path.split(\".\");\n let current: any = obj;\n for (let i = 0; i < parts.length; i++) {\n if (current && typeof current === \"object\" && parts[i] in current) {\n current = current[parts[i]];\n } else {\n return null;\n }\n }\n return current;\n}\n\n// Transform a regex string into a real RegExp object\nfunction getRegex(regex: string): RegExp {\n if (!_regexCache[regex]) {\n _regexCache[regex] = new RegExp(regex.replace(/([^\\\\])\\//g, \"$1\\\\/\"));\n }\n return _regexCache[regex];\n}\n\n// Evaluate a single value against a condition\nfunction evalConditionValue(condition: ConditionValue, value: any) {\n // Simple equality comparisons\n if (typeof condition === \"string\") {\n return value + \"\" === condition;\n }\n if (typeof condition === \"number\") {\n return value * 1 === condition;\n }\n if (typeof condition === \"boolean\") {\n return !!value === condition;\n }\n\n if (condition === null) {\n return value === null;\n }\n\n if (Array.isArray(condition) || !isOperatorObject(condition)) {\n return JSON.stringify(value) === JSON.stringify(condition);\n }\n\n // This is a special operator condition and we should evaluate each one separately\n for (const op in condition) {\n if (\n !evalOperatorCondition(\n op as Operator,\n value,\n condition[op as keyof OperatorConditionValue]\n )\n ) {\n return false;\n }\n }\n return true;\n}\n\n// If the object has only keys that start with '$'\nfunction isOperatorObject(obj: any): boolean {\n const keys = Object.keys(obj);\n return (\n keys.length > 0 && keys.filter((k) => k[0] === \"$\").length === keys.length\n );\n}\n\n// Return the data type of a value\nfunction getType(v: any): VarType | \"unknown\" {\n if (v === null) return \"null\";\n if (Array.isArray(v)) return \"array\";\n const t = typeof v;\n if ([\"string\", \"number\", \"boolean\", \"object\", \"undefined\"].includes(t)) {\n return t as VarType;\n }\n return \"unknown\";\n}\n\n// At least one element of actual must match the expected condition/value\nfunction elemMatch(actual: any, expected: any) {\n if (!Array.isArray(actual)) return false;\n const check = isOperatorObject(expected)\n ? (v: any) => evalConditionValue(expected, v)\n : (v: any) => evalCondition(v, expected);\n for (let i = 0; i < actual.length; i++) {\n if (actual[i] && check(actual[i])) {\n return true;\n }\n }\n return false;\n}\n\nfunction isIn(actual: any, expected: Array): boolean {\n // Do an intersection is attribute is an array\n if (Array.isArray(actual)) {\n return actual.some((el) => expected.includes(el));\n }\n return expected.includes(actual);\n}\n\n// Evaluate a single operator condition\nfunction evalOperatorCondition(\n operator: Operator,\n actual: any,\n expected: any\n): boolean {\n switch (operator) {\n case \"$veq\":\n return paddedVersionString(actual) === paddedVersionString(expected);\n case \"$vne\":\n return paddedVersionString(actual) !== paddedVersionString(expected);\n case \"$vgt\":\n return paddedVersionString(actual) > paddedVersionString(expected);\n case \"$vgte\":\n return paddedVersionString(actual) >= paddedVersionString(expected);\n case \"$vlt\":\n return paddedVersionString(actual) < paddedVersionString(expected);\n case \"$vlte\":\n return paddedVersionString(actual) <= paddedVersionString(expected);\n case \"$eq\":\n return actual === expected;\n case \"$ne\":\n return actual !== expected;\n case \"$lt\":\n return actual < expected;\n case \"$lte\":\n return actual <= expected;\n case \"$gt\":\n return actual > expected;\n case \"$gte\":\n return actual >= expected;\n case \"$exists\":\n // Using `!=` and `==` instead of strict checks so it also matches for undefined\n return expected ? actual != null : actual == null;\n case \"$in\":\n if (!Array.isArray(expected)) return false;\n return isIn(actual, expected);\n case \"$nin\":\n if (!Array.isArray(expected)) return false;\n return !isIn(actual, expected);\n case \"$not\":\n return !evalConditionValue(expected, actual);\n case \"$size\":\n if (!Array.isArray(actual)) return false;\n return evalConditionValue(expected, actual.length);\n case \"$elemMatch\":\n return elemMatch(actual, expected);\n case \"$all\":\n if (!Array.isArray(actual)) return false;\n for (let i = 0; i < expected.length; i++) {\n let passed = false;\n for (let j = 0; j < actual.length; j++) {\n if (evalConditionValue(expected[i], actual[j])) {\n passed = true;\n break;\n }\n }\n if (!passed) return false;\n }\n return true;\n case \"$regex\":\n try {\n return getRegex(expected).test(actual);\n } catch (e) {\n return false;\n }\n case \"$type\":\n return getType(actual) === expected;\n default:\n console.error(\"Unknown operator: \" + operator);\n return false;\n }\n}\n\n// Recursive $or rule\nfunction evalOr(obj: TestedObj, conditions: ConditionInterface[]): boolean {\n if (!conditions.length) return true;\n for (let i = 0; i < conditions.length; i++) {\n if (evalCondition(obj, conditions[i])) {\n return true;\n }\n }\n return false;\n}\n\n// Recursive $and rule\nfunction evalAnd(obj: TestedObj, conditions: ConditionInterface[]): boolean {\n for (let i = 0; i < conditions.length; i++) {\n if (!evalCondition(obj, conditions[i])) {\n return false;\n }\n }\n return true;\n}\n","import mutate, { DeclarativeMutation } from \"dom-mutator\";\nimport type {\n ApiHost,\n Attributes,\n AutoExperiment,\n AutoExperimentVariation,\n ClientKey,\n Context,\n Experiment,\n FeatureApiResponse,\n FeatureDefinition,\n FeatureResult,\n FeatureResultSource,\n Filter,\n LoadFeaturesOptions,\n RealtimeUsageData,\n RefreshFeaturesOptions,\n RenderFunction,\n Result,\n StickyAssignments,\n StickyAssignmentsDocument,\n StickyAttributeKey,\n StickyExperimentKey,\n SubscriptionFunction,\n TrackingCallback,\n TrackingData,\n VariationMeta,\n VariationRange,\n WidenPrimitives,\n} from \"./types/growthbook\";\nimport type { ConditionInterface } from \"./types/mongrule\";\nimport {\n chooseVariation,\n decrypt,\n getBucketRanges,\n getQueryStringOverride,\n getUrlRegExp,\n hash,\n inNamespace,\n inRange,\n isIncluded,\n isURLTargeted,\n loadSDKVersion,\n mergeQueryStrings,\n toString,\n} from \"./util\";\nimport { evalCondition } from \"./mongrule\";\nimport { refreshFeatures, subscribe, unsubscribe } from \"./feature-repository\";\nimport { FeatureEvalContext } from \"./types/growthbook\";\n\nconst isBrowser =\n typeof window !== \"undefined\" && typeof document !== \"undefined\";\n\nconst SDK_VERSION = loadSDKVersion();\n\nexport class GrowthBook<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n AppFeatures extends Record = Record\n> {\n // context is technically private, but some tools depend on it so we can't mangle the name\n // _ctx below is a clone of this property that we use internally\n private context: Context;\n public debug: boolean;\n public ready: boolean;\n public version: string;\n\n // Properties and methods that start with \"_\" are mangled by Terser (saves ~150 bytes)\n private _ctx: Context;\n private _renderer: null | RenderFunction;\n private _redirectedUrl: string;\n private _trackedExperiments: Set;\n private _trackedFeatures: Record;\n private _subscriptions: Set;\n private _rtQueue: RealtimeUsageData[];\n private _rtTimer: number;\n private _assigned: Map<\n string,\n {\n // eslint-disable-next-line\n experiment: Experiment;\n // eslint-disable-next-line\n result: Result;\n }\n >;\n // eslint-disable-next-line\n private _forcedFeatureValues: Map;\n private _attributeOverrides: Attributes;\n private _activeAutoExperiments: Map<\n AutoExperiment,\n { valueHash: string; undo: () => void }\n >;\n private _triggeredExpKeys: Set;\n private _loadFeaturesCalled: boolean;\n private _deferredTrackingCalls: TrackingData[];\n\n constructor(context?: Context) {\n context = context || {};\n // These properties are all initialized in the constructor instead of above\n // This saves ~80 bytes in the final output\n this.version = SDK_VERSION;\n this._ctx = this.context = context;\n this._renderer = null;\n this._trackedExperiments = new Set();\n this._trackedFeatures = {};\n this.debug = false;\n this._subscriptions = new Set();\n this._rtQueue = [];\n this._rtTimer = 0;\n this.ready = false;\n this._assigned = new Map();\n this._forcedFeatureValues = new Map();\n this._attributeOverrides = {};\n this._activeAutoExperiments = new Map();\n this._triggeredExpKeys = new Set();\n this._loadFeaturesCalled = false;\n this._redirectedUrl = \"\";\n this._deferredTrackingCalls = [];\n\n if (context.renderer) {\n this._renderer = context.renderer;\n }\n\n if (context.remoteEval) {\n if (context.decryptionKey) {\n throw new Error(\"Encryption is not available for remoteEval\");\n }\n if (!context.clientKey) {\n throw new Error(\"Missing clientKey\");\n }\n let isGbHost = false;\n try {\n isGbHost = !!new URL(context.apiHost || \"\").hostname.match(\n /growthbook\\.io$/i\n );\n } catch (e) {\n // ignore invalid URLs\n }\n if (isGbHost) {\n throw new Error(\"Cannot use remoteEval on GrowthBook Cloud\");\n }\n } else {\n if (context.cacheKeyAttributes) {\n throw new Error(\"cacheKeyAttributes are only used for remoteEval\");\n }\n }\n\n if (context.features) {\n this.ready = true;\n }\n\n if (isBrowser && context.enableDevMode) {\n window._growthbook = this;\n document.dispatchEvent(new Event(\"gbloaded\"));\n }\n\n if (context.experiments) {\n this.ready = true;\n this._updateAllAutoExperiments();\n } else if (context.antiFlicker) {\n this._setAntiFlicker();\n }\n\n if (context.clientKey && !context.remoteEval) {\n this._refresh({}, true, false);\n }\n }\n\n public async loadFeatures(options?: LoadFeaturesOptions): Promise {\n if (options && options.autoRefresh) {\n // interpret deprecated autoRefresh option as subscribeToChanges\n this._ctx.subscribeToChanges = true;\n }\n this._loadFeaturesCalled = true;\n\n await this._refresh(options, true, true);\n\n if (this._canSubscribe()) {\n subscribe(this);\n }\n }\n\n public async refreshFeatures(\n options?: RefreshFeaturesOptions\n ): Promise {\n await this._refresh(options, false, true);\n }\n\n public getApiInfo(): [ApiHost, ClientKey] {\n return [this.getApiHosts().apiHost, this.getClientKey()];\n }\n public getApiHosts(): {\n apiHost: string;\n streamingHost: string;\n apiRequestHeaders?: Record;\n streamingHostRequestHeaders?: Record;\n } {\n const defaultHost = this._ctx.apiHost || \"https://cdn.growthbook.io\";\n return {\n apiHost: defaultHost.replace(/\\/*$/, \"\"),\n streamingHost: (this._ctx.streamingHost || defaultHost).replace(\n /\\/*$/,\n \"\"\n ),\n apiRequestHeaders: this._ctx.apiHostRequestHeaders,\n streamingHostRequestHeaders: this._ctx.streamingHostRequestHeaders,\n };\n }\n public getClientKey(): string {\n return this._ctx.clientKey || \"\";\n }\n\n public isRemoteEval(): boolean {\n return this._ctx.remoteEval || false;\n }\n\n public getCacheKeyAttributes(): (keyof Attributes)[] | undefined {\n return this._ctx.cacheKeyAttributes;\n }\n\n private async _refresh(\n options?: RefreshFeaturesOptions,\n allowStale?: boolean,\n updateInstance?: boolean\n ) {\n options = options || {};\n if (!this._ctx.clientKey) {\n throw new Error(\"Missing clientKey\");\n }\n await refreshFeatures(\n this,\n options.timeout,\n options.skipCache || this._ctx.enableDevMode,\n allowStale,\n updateInstance,\n this._ctx.backgroundSync !== false\n );\n }\n\n private _render() {\n if (this._renderer) {\n try {\n this._renderer();\n } catch (e) {\n console.error(\"Failed to render\", e);\n }\n }\n }\n\n public setFeatures(features: Record) {\n this._ctx.features = features;\n this.ready = true;\n this._render();\n }\n\n public async setEncryptedFeatures(\n encryptedString: string,\n decryptionKey?: string,\n subtle?: SubtleCrypto\n ): Promise {\n const featuresJSON = await decrypt(\n encryptedString,\n decryptionKey || this._ctx.decryptionKey,\n subtle\n );\n this.setFeatures(\n JSON.parse(featuresJSON) as Record\n );\n }\n\n public setExperiments(experiments: AutoExperiment[]): void {\n this._ctx.experiments = experiments;\n this.ready = true;\n this._updateAllAutoExperiments();\n }\n\n public async setEncryptedExperiments(\n encryptedString: string,\n decryptionKey?: string,\n subtle?: SubtleCrypto\n ): Promise {\n const experimentsJSON = await decrypt(\n encryptedString,\n decryptionKey || this._ctx.decryptionKey,\n subtle\n );\n this.setExperiments(JSON.parse(experimentsJSON) as AutoExperiment[]);\n }\n\n public async decryptPayload(\n data: FeatureApiResponse,\n decryptionKey?: string,\n subtle?: SubtleCrypto\n ): Promise {\n if (data.encryptedFeatures) {\n data.features = JSON.parse(\n await decrypt(\n data.encryptedFeatures,\n decryptionKey || this._ctx.decryptionKey,\n subtle\n )\n );\n delete data.encryptedFeatures;\n }\n if (data.encryptedExperiments) {\n data.experiments = JSON.parse(\n await decrypt(\n data.encryptedExperiments,\n decryptionKey || this._ctx.decryptionKey,\n subtle\n )\n );\n delete data.encryptedExperiments;\n }\n return data;\n }\n\n public async setAttributes(attributes: Attributes) {\n this._ctx.attributes = attributes;\n if (this._ctx.stickyBucketService) {\n await this.refreshStickyBuckets();\n }\n if (this._ctx.remoteEval) {\n await this._refreshForRemoteEval();\n return;\n }\n this._render();\n this._updateAllAutoExperiments();\n }\n\n public async updateAttributes(attributes: Attributes) {\n return this.setAttributes({ ...this._ctx.attributes, ...attributes });\n }\n\n public async setAttributeOverrides(overrides: Attributes) {\n this._attributeOverrides = overrides;\n if (this._ctx.stickyBucketService) {\n await this.refreshStickyBuckets();\n }\n if (this._ctx.remoteEval) {\n await this._refreshForRemoteEval();\n return;\n }\n this._render();\n this._updateAllAutoExperiments();\n }\n\n public async setForcedVariations(vars: Record) {\n this._ctx.forcedVariations = vars || {};\n if (this._ctx.remoteEval) {\n await this._refreshForRemoteEval();\n return;\n }\n this._render();\n this._updateAllAutoExperiments();\n }\n\n // eslint-disable-next-line\n public setForcedFeatures(map: Map) {\n this._forcedFeatureValues = map;\n this._render();\n }\n\n public async setURL(url: string) {\n this._ctx.url = url;\n this._redirectedUrl = \"\";\n if (this._ctx.remoteEval) {\n await this._refreshForRemoteEval();\n this._updateAllAutoExperiments(true);\n return;\n }\n this._updateAllAutoExperiments(true);\n }\n\n public getAttributes() {\n return { ...this._ctx.attributes, ...this._attributeOverrides };\n }\n\n public getForcedVariations() {\n return this._ctx.forcedVariations || {};\n }\n\n public getForcedFeatures() {\n // eslint-disable-next-line\n return this._forcedFeatureValues || new Map();\n }\n\n public getStickyBucketAssignmentDocs() {\n return this._ctx.stickyBucketAssignmentDocs || {};\n }\n\n public getUrl() {\n return this._ctx.url || \"\";\n }\n\n public getFeatures() {\n return this._ctx.features || {};\n }\n\n public getExperiments() {\n return this._ctx.experiments || [];\n }\n\n public subscribe(cb: SubscriptionFunction): () => void {\n this._subscriptions.add(cb);\n return () => {\n this._subscriptions.delete(cb);\n };\n }\n\n private _canSubscribe() {\n return this._ctx.backgroundSync !== false && this._ctx.subscribeToChanges;\n }\n\n private async _refreshForRemoteEval() {\n if (!this._ctx.remoteEval) return;\n if (!this._loadFeaturesCalled) return;\n await this._refresh({}, false, true).catch(() => {\n // Ignore errors\n });\n }\n\n public getAllResults() {\n return new Map(this._assigned);\n }\n\n public destroy() {\n // Release references to save memory\n this._subscriptions.clear();\n this._assigned.clear();\n this._trackedExperiments.clear();\n this._trackedFeatures = {};\n this._rtQueue = [];\n if (this._rtTimer) {\n clearTimeout(this._rtTimer);\n }\n unsubscribe(this);\n\n if (isBrowser && window._growthbook === this) {\n delete window._growthbook;\n }\n\n // Undo any active auto experiments\n this._activeAutoExperiments.forEach((exp) => {\n exp.undo();\n });\n this._activeAutoExperiments.clear();\n this._triggeredExpKeys.clear();\n }\n\n public setRenderer(renderer: null | RenderFunction) {\n this._renderer = renderer;\n }\n\n public forceVariation(key: string, variation: number) {\n this._ctx.forcedVariations = this._ctx.forcedVariations || {};\n this._ctx.forcedVariations[key] = variation;\n if (this._ctx.remoteEval) {\n this._refreshForRemoteEval();\n return;\n }\n this._updateAllAutoExperiments();\n this._render();\n }\n\n public run(experiment: Experiment): Result {\n const result = this._run(experiment, null);\n this._fireSubscriptions(experiment, result);\n return result;\n }\n\n public triggerExperiment(key: string) {\n this._triggeredExpKeys.add(key);\n if (!this._ctx.experiments) return null;\n const experiments = this._ctx.experiments.filter((exp) => exp.key === key);\n return experiments\n .map((exp) => {\n if (!exp.manual) return null;\n return this._runAutoExperiment(exp);\n })\n .filter((res) => res !== null);\n }\n\n private _runAutoExperiment(experiment: AutoExperiment, forceRerun?: boolean) {\n const existing = this._activeAutoExperiments.get(experiment);\n\n // If this is a manual experiment and it's not already running, skip\n if (\n experiment.manual &&\n !this._triggeredExpKeys.has(experiment.key) &&\n !existing\n )\n return null;\n\n // Run the experiment\n const result = this.run(experiment);\n\n // A hash to quickly tell if the assigned value changed\n const valueHash = JSON.stringify(result.value);\n\n // If the changes are already active, no need to re-apply them\n if (\n !forceRerun &&\n result.inExperiment &&\n existing &&\n existing.valueHash === valueHash\n ) {\n return result;\n }\n\n // Undo any existing changes\n if (existing) this._undoActiveAutoExperiment(experiment);\n\n // Apply new changes\n if (result.inExperiment) {\n if (result.value.urlRedirect && experiment.urlPatterns) {\n const url = experiment.persistQueryString\n ? mergeQueryStrings(this._getContextUrl(), result.value.urlRedirect)\n : result.value.urlRedirect;\n\n if (isURLTargeted(url, experiment.urlPatterns)) {\n this.log(\n \"Skipping redirect because original URL matches redirect URL\",\n {\n id: experiment.key,\n }\n );\n return result;\n }\n this._redirectedUrl = url;\n const navigate = this._getNavigateFunction();\n if (navigate) {\n if (isBrowser) {\n this._setAntiFlicker();\n window.setTimeout(() => {\n try {\n navigate(url);\n } catch (e) {\n console.error(e);\n }\n }, this._ctx.navigateDelay ?? 100);\n } else {\n try {\n navigate(url);\n } catch (e) {\n console.error(e);\n }\n }\n }\n } else {\n const undo = this._applyDOMChanges(result.value);\n if (undo) {\n this._activeAutoExperiments.set(experiment, {\n undo,\n valueHash,\n });\n }\n }\n }\n\n return result;\n }\n\n private _undoActiveAutoExperiment(exp: AutoExperiment) {\n const data = this._activeAutoExperiments.get(exp);\n if (data) {\n data.undo();\n this._activeAutoExperiments.delete(exp);\n }\n }\n\n private _isRedirectExperiment(exp: AutoExperiment) {\n return exp.variations.some((v) => Object.keys(v).includes(\"urlRedirect\"));\n }\n\n private _updateAllAutoExperiments(forceRerun?: boolean) {\n const experiments = this._ctx.experiments || [];\n\n // Stop any experiments that are no longer defined\n const keys = new Set(experiments);\n this._activeAutoExperiments.forEach((v, k) => {\n if (!keys.has(k)) {\n v.undo();\n this._activeAutoExperiments.delete(k);\n }\n });\n\n // Re-run all new/updated experiments\n for (const exp of experiments) {\n const result = this._runAutoExperiment(exp, forceRerun);\n\n // Once you're in a redirect experiment, break out of the loop and don't run any further experiments\n if (result?.inExperiment && this._isRedirectExperiment(exp)) {\n break;\n }\n }\n }\n\n private _fireSubscriptions(experiment: Experiment, result: Result) {\n const key = experiment.key;\n\n // If assigned variation has changed, fire subscriptions\n const prev = this._assigned.get(key);\n // TODO: what if the experiment definition has changed?\n if (\n !prev ||\n prev.result.inExperiment !== result.inExperiment ||\n prev.result.variationId !== result.variationId\n ) {\n this._assigned.set(key, { experiment, result });\n this._subscriptions.forEach((cb) => {\n try {\n cb(experiment, result);\n } catch (e) {\n console.error(e);\n }\n });\n }\n }\n\n private _trackFeatureUsage(key: string, res: FeatureResult): void {\n // Don't track feature usage that was forced via an override\n if (res.source === \"override\") return;\n\n // Only track a feature once, unless the assigned value changed\n const stringifiedValue = JSON.stringify(res.value);\n if (this._trackedFeatures[key] === stringifiedValue) return;\n this._trackedFeatures[key] = stringifiedValue;\n\n // Fire user-supplied callback\n if (this._ctx.onFeatureUsage) {\n try {\n this._ctx.onFeatureUsage(key, res);\n } catch (e) {\n // Ignore feature usage callback errors\n }\n }\n\n // In browser environments, queue up feature usage to be tracked in batches\n if (!isBrowser || !window.fetch) return;\n this._rtQueue.push({\n key,\n on: res.on,\n });\n if (!this._rtTimer) {\n this._rtTimer = window.setTimeout(() => {\n // Reset the queue\n this._rtTimer = 0;\n const q = [...this._rtQueue];\n this._rtQueue = [];\n\n // Skip logging if a real-time usage key is not configured\n if (!this._ctx.realtimeKey) return;\n\n window\n .fetch(\n `https://rt.growthbook.io/?key=${\n this._ctx.realtimeKey\n }&events=${encodeURIComponent(JSON.stringify(q))}`,\n\n {\n cache: \"no-cache\",\n mode: \"no-cors\",\n }\n )\n .catch(() => {\n // TODO: retry in case of network errors?\n });\n }, this._ctx.realtimeInterval || 2000);\n }\n }\n\n private _getFeatureResult(\n key: string,\n value: T,\n source: FeatureResultSource,\n ruleId?: string,\n experiment?: Experiment,\n result?: Result\n ): FeatureResult {\n const ret: FeatureResult = {\n value,\n on: !!value,\n off: !value,\n source,\n ruleId: ruleId || \"\",\n };\n if (experiment) ret.experiment = experiment;\n if (result) ret.experimentResult = result;\n\n // Track the usage of this feature in real-time\n this._trackFeatureUsage(key, ret);\n\n return ret;\n }\n\n public isOn(key: K): boolean {\n return this.evalFeature(key).on;\n }\n\n public isOff(key: K): boolean {\n return this.evalFeature(key).off;\n }\n\n public getFeatureValue<\n V extends AppFeatures[K],\n K extends string & keyof AppFeatures = string\n >(key: K, defaultValue: V): WidenPrimitives {\n const value = this.evalFeature, K>(key).value;\n return value === null ? (defaultValue as WidenPrimitives) : value;\n }\n\n /**\n * @deprecated Use {@link evalFeature}\n * @param id\n */\n // eslint-disable-next-line\n public feature<\n V extends AppFeatures[K],\n K extends string & keyof AppFeatures = string\n >(id: K): FeatureResult {\n return this.evalFeature(id);\n }\n\n public evalFeature<\n V extends AppFeatures[K],\n K extends string & keyof AppFeatures = string\n >(id: K): FeatureResult {\n return this._evalFeature(id);\n }\n\n private _evalFeature<\n V extends AppFeatures[K],\n K extends string & keyof AppFeatures = string\n >(id: K, evalCtx?: FeatureEvalContext): FeatureResult {\n evalCtx = evalCtx || { evaluatedFeatures: new Set() };\n\n if (evalCtx.evaluatedFeatures.has(id)) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\n `evalFeature: circular dependency detected: ${evalCtx.id} -> ${id}`,\n { from: evalCtx.id, to: id }\n );\n return this._getFeatureResult(id, null, \"cyclicPrerequisite\");\n }\n evalCtx.evaluatedFeatures.add(id);\n evalCtx.id = id;\n\n // Global override\n if (this._forcedFeatureValues.has(id)) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Global override\", {\n id,\n value: this._forcedFeatureValues.get(id),\n });\n return this._getFeatureResult(\n id,\n this._forcedFeatureValues.get(id),\n \"override\"\n );\n }\n\n // Unknown feature id\n if (!this._ctx.features || !this._ctx.features[id]) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Unknown feature\", { id });\n return this._getFeatureResult(id, null, \"unknownFeature\");\n }\n\n // Get the feature\n const feature: FeatureDefinition = this._ctx.features[id];\n\n // Loop through the rules\n if (feature.rules) {\n rules: for (const rule of feature.rules) {\n // If there are prerequisite flag(s), evaluate them\n if (rule.parentConditions) {\n for (const parentCondition of rule.parentConditions) {\n const parentResult = this._evalFeature(parentCondition.id, evalCtx);\n // break out for cyclic prerequisites\n if (parentResult.source === \"cyclicPrerequisite\") {\n return this._getFeatureResult(id, null, \"cyclicPrerequisite\");\n }\n\n const evalObj = { value: parentResult.value };\n const evaled = evalCondition(\n evalObj,\n parentCondition.condition || {}\n );\n if (!evaled) {\n // blocking prerequisite eval failed: feature evaluation fails\n if (parentCondition.gate) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Feature blocked by prerequisite\", { id, rule });\n return this._getFeatureResult(id, null, \"prerequisite\");\n }\n // non-blocking prerequisite eval failed: break out of parentConditions loop, jump to the next rule\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip rule because prerequisite evaluation fails\", {\n id,\n rule,\n });\n continue rules;\n }\n }\n }\n\n // If there are filters for who is included (e.g. namespaces)\n if (rule.filters && this._isFilteredOut(rule.filters)) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip rule because of filters\", {\n id,\n rule,\n });\n continue;\n }\n\n // Feature value is being forced\n if (\"force\" in rule) {\n // If it's a conditional rule, skip if the condition doesn't pass\n if (rule.condition && !this._conditionPasses(rule.condition)) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip rule because of condition ff\", {\n id,\n rule,\n });\n continue;\n }\n\n // If this is a percentage rollout, skip if not included\n if (\n !this._isIncludedInRollout(\n rule.seed || id,\n rule.hashAttribute,\n this._ctx.stickyBucketService && !rule.disableStickyBucketing\n ? rule.fallbackAttribute\n : undefined,\n rule.range,\n rule.coverage,\n rule.hashVersion\n )\n ) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip rule because user not included in rollout\", {\n id,\n rule,\n });\n continue;\n }\n\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Force value from rule\", {\n id,\n rule,\n });\n\n // If this was a remotely evaluated experiment, fire the tracking callbacks\n if (rule.tracks) {\n rule.tracks.forEach((t) => {\n this._track(t.experiment, t.result);\n });\n }\n\n return this._getFeatureResult(id, rule.force as V, \"force\", rule.id);\n }\n if (!rule.variations) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip invalid rule\", {\n id,\n rule,\n });\n\n continue;\n }\n\n // For experiment rules, run an experiment\n const exp: Experiment = {\n variations: rule.variations as [V, V, ...V[]],\n key: rule.key || id,\n };\n if (\"coverage\" in rule) exp.coverage = rule.coverage;\n if (rule.weights) exp.weights = rule.weights;\n if (rule.hashAttribute) exp.hashAttribute = rule.hashAttribute;\n if (rule.fallbackAttribute)\n exp.fallbackAttribute = rule.fallbackAttribute;\n if (rule.disableStickyBucketing)\n exp.disableStickyBucketing = rule.disableStickyBucketing;\n if (rule.bucketVersion !== undefined)\n exp.bucketVersion = rule.bucketVersion;\n if (rule.minBucketVersion !== undefined)\n exp.minBucketVersion = rule.minBucketVersion;\n if (rule.namespace) exp.namespace = rule.namespace;\n if (rule.meta) exp.meta = rule.meta;\n if (rule.ranges) exp.ranges = rule.ranges;\n if (rule.name) exp.name = rule.name;\n if (rule.phase) exp.phase = rule.phase;\n if (rule.seed) exp.seed = rule.seed;\n if (rule.hashVersion) exp.hashVersion = rule.hashVersion;\n if (rule.filters) exp.filters = rule.filters;\n if (rule.condition) exp.condition = rule.condition;\n\n // Only return a value if the user is part of the experiment\n const res = this._run(exp, id);\n this._fireSubscriptions(exp, res);\n if (res.inExperiment && !res.passthrough) {\n return this._getFeatureResult(\n id,\n res.value,\n \"experiment\",\n rule.id,\n exp,\n res\n );\n }\n }\n }\n\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Use default value\", {\n id,\n value: feature.defaultValue,\n });\n\n // Fall back to using the default value\n return this._getFeatureResult(\n id,\n feature.defaultValue === undefined ? null : feature.defaultValue,\n \"defaultValue\"\n );\n }\n\n private _isIncludedInRollout(\n seed: string,\n hashAttribute: string | undefined,\n fallbackAttribute: string | undefined,\n range: VariationRange | undefined,\n coverage: number | undefined,\n hashVersion: number | undefined\n ): boolean {\n if (!range && coverage === undefined) return true;\n\n const { hashValue } = this._getHashAttribute(\n hashAttribute,\n fallbackAttribute\n );\n if (!hashValue) {\n return false;\n }\n\n const n = hash(seed, hashValue, hashVersion || 1);\n if (n === null) return false;\n\n return range\n ? inRange(n, range)\n : coverage !== undefined\n ? n <= coverage\n : true;\n }\n\n private _conditionPasses(condition: ConditionInterface): boolean {\n return evalCondition(this.getAttributes(), condition);\n }\n\n private _isFilteredOut(filters: Filter[]): boolean {\n return filters.some((filter) => {\n const { hashValue } = this._getHashAttribute(filter.attribute);\n if (!hashValue) return true;\n const n = hash(filter.seed, hashValue, filter.hashVersion || 2);\n if (n === null) return true;\n return !filter.ranges.some((r) => inRange(n, r));\n });\n }\n\n private _run(\n experiment: Experiment,\n featureId: string | null\n ): Result {\n const key = experiment.key;\n const numVariations = experiment.variations.length;\n\n // 1. If experiment has less than 2 variations, return immediately\n if (numVariations < 2) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Invalid experiment\", { id: key });\n return this._getResult(experiment, -1, false, featureId);\n }\n\n // 2. If the context is disabled, return immediately\n if (this._ctx.enabled === false) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Context disabled\", { id: key });\n return this._getResult(experiment, -1, false, featureId);\n }\n\n // 2.5. Merge in experiment overrides from the context\n experiment = this._mergeOverrides(experiment);\n\n // 2.6 New, more powerful URL targeting\n if (\n experiment.urlPatterns &&\n !isURLTargeted(this._getContextUrl(), experiment.urlPatterns)\n ) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip because of url targeting\", {\n id: key,\n });\n return this._getResult(experiment, -1, false, featureId);\n }\n\n // 3. If a variation is forced from a querystring, return the forced variation\n const qsOverride = getQueryStringOverride(\n key,\n this._getContextUrl(),\n numVariations\n );\n if (qsOverride !== null) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Force via querystring\", {\n id: key,\n variation: qsOverride,\n });\n return this._getResult(experiment, qsOverride, false, featureId);\n }\n\n // 4. If a variation is forced in the context, return the forced variation\n if (this._ctx.forcedVariations && key in this._ctx.forcedVariations) {\n const variation = this._ctx.forcedVariations[key];\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Force via dev tools\", {\n id: key,\n variation,\n });\n return this._getResult(experiment, variation, false, featureId);\n }\n\n // 5. Exclude if a draft experiment or not active\n if (experiment.status === \"draft\" || experiment.active === false) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip because inactive\", {\n id: key,\n });\n return this._getResult(experiment, -1, false, featureId);\n }\n\n // 6. Get the hash attribute and return if empty\n const { hashAttribute, hashValue } = this._getHashAttribute(\n experiment.hashAttribute,\n this._ctx.stickyBucketService && !experiment.disableStickyBucketing\n ? experiment.fallbackAttribute\n : undefined\n );\n if (!hashValue) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip because missing hashAttribute\", {\n id: key,\n });\n return this._getResult(experiment, -1, false, featureId);\n }\n\n let assigned = -1;\n\n let foundStickyBucket = false;\n let stickyBucketVersionIsBlocked = false;\n if (this._ctx.stickyBucketService && !experiment.disableStickyBucketing) {\n const { variation, versionIsBlocked } = this._getStickyBucketVariation(\n experiment.key,\n experiment.bucketVersion,\n experiment.minBucketVersion,\n experiment.meta\n );\n foundStickyBucket = variation >= 0;\n assigned = variation;\n stickyBucketVersionIsBlocked = !!versionIsBlocked;\n }\n\n // Some checks are not needed if we already have a sticky bucket\n if (!foundStickyBucket) {\n // 7. Exclude if user is filtered out (used to be called \"namespace\")\n if (experiment.filters) {\n if (this._isFilteredOut(experiment.filters)) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip because of filters\", {\n id: key,\n });\n return this._getResult(experiment, -1, false, featureId);\n }\n } else if (\n experiment.namespace &&\n !inNamespace(hashValue, experiment.namespace)\n ) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip because of namespace\", {\n id: key,\n });\n return this._getResult(experiment, -1, false, featureId);\n }\n\n // 7.5. Exclude if experiment.include returns false or throws\n if (experiment.include && !isIncluded(experiment.include)) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip because of include function\", {\n id: key,\n });\n return this._getResult(experiment, -1, false, featureId);\n }\n\n // 8. Exclude if condition is false\n if (\n experiment.condition &&\n !this._conditionPasses(experiment.condition)\n ) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip because of condition exp\", {\n id: key,\n });\n return this._getResult(experiment, -1, false, featureId);\n }\n\n // 8.05. Exclude if prerequisites are not met\n if (experiment.parentConditions) {\n for (const parentCondition of experiment.parentConditions) {\n const parentResult = this._evalFeature(parentCondition.id);\n // break out for cyclic prerequisites\n if (parentResult.source === \"cyclicPrerequisite\") {\n return this._getResult(experiment, -1, false, featureId);\n }\n\n const evalObj = { value: parentResult.value };\n if (!evalCondition(evalObj, parentCondition.condition || {})) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip because prerequisite evaluation fails\", {\n id: key,\n });\n return this._getResult(experiment, -1, false, featureId);\n }\n }\n }\n\n // 8.1. Exclude if user is not in a required group\n if (\n experiment.groups &&\n !this._hasGroupOverlap(experiment.groups as string[])\n ) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip because of groups\", {\n id: key,\n });\n return this._getResult(experiment, -1, false, featureId);\n }\n }\n\n // 8.2. Old style URL targeting\n if (experiment.url && !this._urlIsValid(experiment.url as RegExp)) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip because of url\", {\n id: key,\n });\n return this._getResult(experiment, -1, false, featureId);\n }\n\n // 9. Get the variation from the sticky bucket or get bucket ranges and choose variation\n const n = hash(\n experiment.seed || key,\n hashValue,\n experiment.hashVersion || 1\n );\n if (n === null) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip because of invalid hash version\", {\n id: key,\n });\n return this._getResult(experiment, -1, false, featureId);\n }\n\n if (!foundStickyBucket) {\n const ranges =\n experiment.ranges ||\n getBucketRanges(\n numVariations,\n experiment.coverage === undefined ? 1 : experiment.coverage,\n experiment.weights\n );\n assigned = chooseVariation(n, ranges);\n }\n\n // 9.5 Unenroll if any prior sticky buckets are blocked by version\n if (stickyBucketVersionIsBlocked) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip because sticky bucket version is blocked\", {\n id: key,\n });\n return this._getResult(experiment, -1, false, featureId, undefined, true);\n }\n\n // 10. Return if not in experiment\n if (assigned < 0) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip because of coverage\", {\n id: key,\n });\n return this._getResult(experiment, -1, false, featureId);\n }\n\n // 11. Experiment has a forced variation\n if (\"force\" in experiment) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Force variation\", {\n id: key,\n variation: experiment.force,\n });\n return this._getResult(\n experiment,\n experiment.force === undefined ? -1 : experiment.force,\n false,\n featureId\n );\n }\n\n // 12. Exclude if in QA mode\n if (this._ctx.qaMode) {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip because QA mode\", {\n id: key,\n });\n return this._getResult(experiment, -1, false, featureId);\n }\n\n // 12.5. Exclude if experiment is stopped\n if (experiment.status === \"stopped\") {\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"Skip because stopped\", {\n id: key,\n });\n return this._getResult(experiment, -1, false, featureId);\n }\n\n // 13. Build the result object\n const result = this._getResult(\n experiment,\n assigned,\n true,\n featureId,\n n,\n foundStickyBucket\n );\n\n // 13.5. Persist sticky bucket\n if (this._ctx.stickyBucketService && !experiment.disableStickyBucketing) {\n const {\n changed,\n key: attrKey,\n doc,\n } = this._generateStickyBucketAssignmentDoc(\n hashAttribute,\n toString(hashValue),\n {\n [this._getStickyBucketExperimentKey(\n experiment.key,\n experiment.bucketVersion\n )]: result.key,\n }\n );\n if (changed) {\n // update local docs\n this._ctx.stickyBucketAssignmentDocs =\n this._ctx.stickyBucketAssignmentDocs || {};\n this._ctx.stickyBucketAssignmentDocs[attrKey] = doc;\n // save doc\n this._ctx.stickyBucketService.saveAssignments(doc);\n }\n }\n\n // 14. Fire the tracking callback\n this._track(experiment, result);\n\n // 15. Return the result\n process.env.NODE_ENV !== \"production\" &&\n this.log(\"In experiment\", {\n id: key,\n variation: result.variationId,\n });\n return result;\n }\n\n log(msg: string, ctx: Record) {\n if (!this.debug) return;\n if (this._ctx.log) this._ctx.log(msg, ctx);\n else console.log(msg, ctx);\n }\n\n public getDeferredTrackingCalls() {\n return this._deferredTrackingCalls;\n }\n\n public setDeferredTrackingCalls(calls: TrackingData[]) {\n this._deferredTrackingCalls = calls;\n }\n\n public fireDeferredTrackingCalls() {\n let hasInvalidTrackingCall = false;\n this._deferredTrackingCalls.forEach((call: TrackingData) => {\n if (!call || !call.experiment || !call.result) {\n console.error(\"Invalid deferred tracking call\", { call: call });\n hasInvalidTrackingCall = true;\n } else {\n this._track(call.experiment, call.result);\n }\n });\n\n this._deferredTrackingCalls = [];\n\n if (hasInvalidTrackingCall) {\n throw new Error(\"Invalid tracking data\");\n }\n }\n\n public setTrackingCallback(callback: TrackingCallback) {\n this._ctx.trackingCallback = callback;\n\n try {\n this.fireDeferredTrackingCalls();\n } catch (e) {\n console.error(e);\n }\n }\n\n private _track(experiment: Experiment, result: Result) {\n if (!this._ctx.trackingCallback) {\n this._deferredTrackingCalls.push({ experiment, result });\n return;\n }\n\n const key = experiment.key;\n\n // Make sure a tracking callback is only fired once per unique experiment\n const k =\n result.hashAttribute + result.hashValue + key + result.variationId;\n if (this._trackedExperiments.has(k)) return;\n this._trackedExperiments.add(k);\n\n try {\n this._ctx.trackingCallback(experiment, result);\n } catch (e) {\n console.error(e);\n }\n }\n\n private _mergeOverrides(experiment: Experiment): Experiment {\n const key = experiment.key;\n const o = this._ctx.overrides;\n if (o && o[key]) {\n experiment = Object.assign({}, experiment, o[key]);\n if (typeof experiment.url === \"string\") {\n experiment.url = getUrlRegExp(\n // eslint-disable-next-line\n experiment.url as any\n );\n }\n }\n\n return experiment;\n }\n\n private _getHashAttribute(attr?: string, fallback?: string) {\n let hashAttribute = attr || \"id\";\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let hashValue: any = \"\";\n\n if (this._attributeOverrides[hashAttribute]) {\n hashValue = this._attributeOverrides[hashAttribute];\n } else if (this._ctx.attributes) {\n hashValue = this._ctx.attributes[hashAttribute] || \"\";\n } else if (this._ctx.user) {\n hashValue = this._ctx.user[hashAttribute] || \"\";\n }\n\n // if no match, try fallback\n if (!hashValue && fallback) {\n if (this._attributeOverrides[fallback]) {\n hashValue = this._attributeOverrides[fallback];\n } else if (this._ctx.attributes) {\n hashValue = this._ctx.attributes[fallback] || \"\";\n } else if (this._ctx.user) {\n hashValue = this._ctx.user[fallback] || \"\";\n }\n if (hashValue) {\n hashAttribute = fallback;\n }\n }\n\n return { hashAttribute, hashValue };\n }\n\n private _getResult(\n experiment: Experiment,\n variationIndex: number,\n hashUsed: boolean,\n featureId: string | null,\n bucket?: number,\n stickyBucketUsed?: boolean\n ): Result {\n let inExperiment = true;\n // If assigned variation is not valid, use the baseline and mark the user as not in the experiment\n if (variationIndex < 0 || variationIndex >= experiment.variations.length) {\n variationIndex = 0;\n inExperiment = false;\n }\n\n const { hashAttribute, hashValue } = this._getHashAttribute(\n experiment.hashAttribute,\n this._ctx.stickyBucketService && !experiment.disableStickyBucketing\n ? experiment.fallbackAttribute\n : undefined\n );\n\n const meta: Partial = experiment.meta\n ? experiment.meta[variationIndex]\n : {};\n\n const res: Result = {\n key: meta.key || \"\" + variationIndex,\n featureId,\n inExperiment,\n hashUsed,\n variationId: variationIndex,\n value: experiment.variations[variationIndex],\n hashAttribute,\n hashValue,\n stickyBucketUsed: !!stickyBucketUsed,\n };\n\n if (meta.name) res.name = meta.name;\n if (bucket !== undefined) res.bucket = bucket;\n if (meta.passthrough) res.passthrough = meta.passthrough;\n\n return res;\n }\n\n private _getContextUrl() {\n return this._ctx.url || (isBrowser ? window.location.href : \"\");\n }\n\n private _urlIsValid(urlRegex: RegExp): boolean {\n const url = this._getContextUrl();\n if (!url) return false;\n\n const pathOnly = url.replace(/^https?:\\/\\//, \"\").replace(/^[^/]*\\//, \"/\");\n\n if (urlRegex.test(url)) return true;\n if (urlRegex.test(pathOnly)) return true;\n return false;\n }\n\n private _hasGroupOverlap(expGroups: string[]): boolean {\n const groups = this._ctx.groups || {};\n for (let i = 0; i < expGroups.length; i++) {\n if (groups[expGroups[i]]) return true;\n }\n return false;\n }\n\n public getRedirectUrl(): string {\n return this._redirectedUrl;\n }\n\n private _getNavigateFunction():\n | null\n | ((url: string) => void | Promise) {\n if (this._ctx.navigate) {\n return this._ctx.navigate;\n } else if (isBrowser) {\n return (url: string) => {\n window.location.replace(url);\n };\n }\n return null;\n }\n\n private _setAntiFlicker() {\n if (!this._ctx.antiFlicker || !isBrowser) return;\n try {\n const styleTag = document.createElement(\"style\");\n styleTag.innerHTML =\n \".gb-anti-flicker { opacity: 0 !important; pointer-events: none; }\";\n document.head.appendChild(styleTag);\n document.documentElement.classList.add(\"gb-anti-flicker\");\n\n // Fallback if GrowthBook fails to load in specified time or 3.5 seconds\n setTimeout(() => {\n document.documentElement.classList.remove(\"gb-anti-flicker\");\n }, this._ctx.antiFlickerTimeout ?? 3500);\n } catch (e) {\n console.error(e);\n }\n }\n\n private _applyDOMChanges(changes: AutoExperimentVariation) {\n if (!isBrowser) return;\n const undo: (() => void)[] = [];\n if (changes.css) {\n const s = document.createElement(\"style\");\n s.innerHTML = changes.css;\n document.head.appendChild(s);\n undo.push(() => s.remove());\n }\n if (changes.js) {\n const script = document.createElement(\"script\");\n script.innerHTML = changes.js;\n document.head.appendChild(script);\n undo.push(() => script.remove());\n }\n if (changes.domMutations) {\n changes.domMutations.forEach((mutation) => {\n undo.push(mutate.declarative(mutation as DeclarativeMutation).revert);\n });\n }\n return () => {\n undo.forEach((fn) => fn());\n };\n }\n\n private _deriveStickyBucketIdentifierAttributes(data?: FeatureApiResponse) {\n const attributes = new Set();\n const features = data && data.features ? data.features : this.getFeatures();\n const experiments =\n data && data.experiments ? data.experiments : this.getExperiments();\n Object.keys(features).forEach((id) => {\n const feature = features[id];\n if (feature.rules) {\n for (const rule of feature.rules) {\n if (rule.variations) {\n attributes.add(rule.hashAttribute || \"id\");\n if (rule.fallbackAttribute) {\n attributes.add(rule.fallbackAttribute);\n }\n }\n }\n }\n });\n experiments.map((experiment) => {\n attributes.add(experiment.hashAttribute || \"id\");\n if (experiment.fallbackAttribute) {\n attributes.add(experiment.fallbackAttribute);\n }\n });\n return Array.from(attributes);\n }\n\n public async refreshStickyBuckets(data?: FeatureApiResponse) {\n if (this._ctx.stickyBucketService) {\n const attributes = this._getStickyBucketAttributes(data);\n this._ctx.stickyBucketAssignmentDocs = await this._ctx.stickyBucketService.getAllAssignments(\n attributes\n );\n }\n }\n\n private _getStickyBucketAssignments(): StickyAssignments {\n const mergedAssignments: StickyAssignments = {};\n Object.values(this._ctx.stickyBucketAssignmentDocs || {}).forEach((doc) => {\n if (doc.assignments) Object.assign(mergedAssignments, doc.assignments);\n });\n return mergedAssignments;\n }\n\n private _getStickyBucketVariation(\n experimentKey: string,\n experimentBucketVersion?: number,\n minExperimentBucketVersion?: number,\n meta?: VariationMeta[]\n ): {\n variation: number;\n versionIsBlocked?: boolean;\n } {\n experimentBucketVersion = experimentBucketVersion || 0;\n minExperimentBucketVersion = minExperimentBucketVersion || 0;\n meta = meta || [];\n const id = this._getStickyBucketExperimentKey(\n experimentKey,\n experimentBucketVersion\n );\n const assignments = this._getStickyBucketAssignments();\n\n // users with any blocked bucket version (0 to minExperimentBucketVersion) are excluded from the test\n if (minExperimentBucketVersion > 0) {\n for (let i = 0; i <= minExperimentBucketVersion; i++) {\n const blockedKey = this._getStickyBucketExperimentKey(experimentKey, i);\n if (assignments[blockedKey] !== undefined) {\n return {\n variation: -1,\n versionIsBlocked: true,\n };\n }\n }\n }\n const variationKey = assignments[id];\n if (variationKey === undefined)\n // no assignment found\n return { variation: -1 };\n const variation = meta.findIndex((m) => m.key === variationKey);\n if (variation < 0)\n // invalid assignment, treat as \"no assignment found\"\n return { variation: -1 };\n\n return { variation };\n }\n\n private _getStickyBucketExperimentKey(\n experimentKey: string,\n experimentBucketVersion?: number\n ): StickyExperimentKey {\n experimentBucketVersion = experimentBucketVersion || 0;\n return `${experimentKey}__${experimentBucketVersion}`;\n }\n\n private _getStickyBucketAttributes(\n data?: FeatureApiResponse\n ): Record {\n const attributes: Record = {};\n this._ctx.stickyBucketIdentifierAttributes = !this._ctx\n .stickyBucketIdentifierAttributes\n ? this._deriveStickyBucketIdentifierAttributes(data)\n : this._ctx.stickyBucketIdentifierAttributes;\n this._ctx.stickyBucketIdentifierAttributes.forEach((attr) => {\n const { hashValue } = this._getHashAttribute(attr);\n attributes[attr] = toString(hashValue);\n });\n return attributes;\n }\n\n private _generateStickyBucketAssignmentDoc(\n attributeName: string,\n attributeValue: string,\n assignments: StickyAssignments\n ): {\n key: StickyAttributeKey;\n doc: StickyAssignmentsDocument;\n changed: boolean;\n } {\n const key = `${attributeName}||${attributeValue}`;\n const existingAssignments =\n this._ctx.stickyBucketAssignmentDocs &&\n this._ctx.stickyBucketAssignmentDocs[key]\n ? this._ctx.stickyBucketAssignmentDocs[key].assignments || {}\n : {};\n const newAssignments = { ...existingAssignments, ...assignments };\n const changed =\n JSON.stringify(existingAssignments) !== JSON.stringify(newAssignments);\n\n return {\n key,\n doc: {\n attributeName,\n attributeValue,\n assignments: newAssignments,\n },\n changed,\n };\n }\n}\n","import {\n LocalStorageCompat,\n StickyAssignmentsDocument,\n StickyAttributeKey,\n} from \"./types/growthbook\";\n\nexport interface CookieAttributes {\n expires?: number | Date | undefined;\n path?: string | undefined;\n domain?: string | undefined;\n secure?: boolean | undefined;\n sameSite?: \"strict\" | \"Strict\" | \"lax\" | \"Lax\" | \"none\" | \"None\" | undefined;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [property: string]: any;\n}\nexport interface JsCookiesCompat {\n set(\n name: string,\n value: string | T,\n options?: CookieAttributes\n ): string | undefined;\n get(name: string): string | T | undefined;\n get(): { [key: string]: string };\n remove(name: string, options?: CookieAttributes): void;\n}\n\nexport interface IORedisCompat {\n mget(...keys: string[]): Promise;\n set(key: string, value: string): Promise;\n}\n\nexport interface RequestCompat {\n cookies: Record;\n [key: string]: unknown;\n}\nexport interface ResponseCompat {\n cookie(\n name: string,\n value: string,\n options?: CookieAttributes\n ): ResponseCompat;\n [key: string]: unknown;\n}\n\n/**\n * Responsible for reading and writing documents which describe sticky bucket assignments.\n */\nexport abstract class StickyBucketService {\n abstract getAssignments(\n attributeName: string,\n attributeValue: string\n ): Promise;\n\n abstract saveAssignments(doc: StickyAssignmentsDocument): Promise;\n\n /**\n * The SDK calls getAllAssignments to populate sticky buckets. This in turn will\n * typically loop through individual getAssignments calls. However, some StickyBucketService\n * instances (i.e. Redis) will instead perform a multi-query inside getAllAssignments instead.\n */\n async getAllAssignments(\n attributes: Record\n ): Promise> {\n const docs: Record = {};\n (\n await Promise.all(\n Object.entries(attributes).map(([attributeName, attributeValue]) =>\n this.getAssignments(attributeName, attributeValue)\n )\n )\n ).forEach((doc) => {\n if (doc) {\n const key = `${doc.attributeName}||${doc.attributeValue}`;\n docs[key] = doc;\n }\n });\n return docs;\n }\n}\n\nexport class LocalStorageStickyBucketService extends StickyBucketService {\n private prefix: string;\n private localStorage: LocalStorageCompat | undefined;\n constructor(opts?: { prefix?: string; localStorage?: LocalStorageCompat }) {\n opts = opts || {};\n super();\n this.prefix = opts.prefix || \"gbStickyBuckets__\";\n try {\n this.localStorage = opts.localStorage || globalThis.localStorage;\n } catch (e) {\n // Ignore localStorage errors\n }\n }\n async getAssignments(attributeName: string, attributeValue: string) {\n const key = `${attributeName}||${attributeValue}`;\n let doc: StickyAssignmentsDocument | null = null;\n if (!this.localStorage) return doc;\n try {\n const raw = (await this.localStorage.getItem(this.prefix + key)) || \"{}\";\n const data = JSON.parse(raw);\n if (data.attributeName && data.attributeValue && data.assignments) {\n doc = data;\n }\n } catch (e) {\n // Ignore localStorage errors\n }\n return doc;\n }\n async saveAssignments(doc: StickyAssignmentsDocument) {\n const key = `${doc.attributeName}||${doc.attributeValue}`;\n if (!this.localStorage) return;\n try {\n await this.localStorage.setItem(this.prefix + key, JSON.stringify(doc));\n } catch (e) {\n // Ignore localStorage errors\n }\n }\n}\n\nexport class ExpressCookieStickyBucketService extends StickyBucketService {\n /**\n * Intended to be used with cookieParser() middleware from npm: 'cookie-parser'.\n * Assumes:\n * - reading a cookie is automatically decoded via decodeURIComponent() or similar\n * - writing a cookie name & value must be manually encoded via encodeURIComponent() or similar\n * - all cookie bodies are JSON encoded strings and are manually encoded/decoded\n */\n private prefix: string;\n private req: RequestCompat;\n private res: ResponseCompat;\n private cookieAttributes: CookieAttributes;\n constructor({\n prefix = \"gbStickyBuckets__\",\n req,\n res,\n cookieAttributes = {},\n }: {\n prefix?: string;\n req: RequestCompat;\n res: ResponseCompat;\n cookieAttributes?: CookieAttributes;\n }) {\n super();\n this.prefix = prefix;\n this.req = req;\n this.res = res;\n this.cookieAttributes = cookieAttributes;\n }\n async getAssignments(attributeName: string, attributeValue: string) {\n const key = `${attributeName}||${attributeValue}`;\n let doc: StickyAssignmentsDocument | null = null;\n if (!this.req) return doc;\n try {\n const raw = this.req.cookies[this.prefix + key] || \"{}\";\n const data = JSON.parse(raw);\n if (data.attributeName && data.attributeValue && data.assignments) {\n doc = data;\n }\n } catch (e) {\n // Ignore cookie errors\n }\n return doc;\n }\n async saveAssignments(doc: StickyAssignmentsDocument) {\n const key = `${doc.attributeName}||${doc.attributeValue}`;\n if (!this.res) return;\n const str = JSON.stringify(doc);\n this.res.cookie(\n encodeURIComponent(this.prefix + key),\n encodeURIComponent(str),\n this.cookieAttributes\n );\n }\n}\n\nexport class BrowserCookieStickyBucketService extends StickyBucketService {\n /**\n * Intended to be used with npm: 'js-cookie'.\n * Assumes:\n * - reading a cookie is automatically decoded via decodeURIComponent() or similar\n * - writing a cookie name & value is automatically encoded via encodeURIComponent() or similar\n * - all cookie bodies are JSON encoded strings and are manually encoded/decoded\n */\n private prefix: string;\n private jsCookie: JsCookiesCompat;\n private cookieAttributes: CookieAttributes;\n constructor({\n prefix = \"gbStickyBuckets__\",\n jsCookie,\n cookieAttributes = {},\n }: {\n prefix?: string;\n jsCookie: JsCookiesCompat;\n cookieAttributes?: CookieAttributes;\n }) {\n super();\n this.prefix = prefix;\n this.jsCookie = jsCookie;\n this.cookieAttributes = cookieAttributes;\n }\n async getAssignments(attributeName: string, attributeValue: string) {\n const key = `${attributeName}||${attributeValue}`;\n let doc: StickyAssignmentsDocument | null = null;\n if (!this.jsCookie) return doc;\n try {\n const raw = this.jsCookie.get(this.prefix + key);\n const data = JSON.parse(raw || \"{}\");\n if (data.attributeName && data.attributeValue && data.assignments) {\n doc = data;\n }\n } catch (e) {\n // Ignore cookie errors\n }\n return doc;\n }\n async saveAssignments(doc: StickyAssignmentsDocument) {\n const key = `${doc.attributeName}||${doc.attributeValue}`;\n if (!this.jsCookie) return;\n const str = JSON.stringify(doc);\n this.jsCookie.set(this.prefix + key, str, this.cookieAttributes);\n }\n}\n\nexport class RedisStickyBucketService extends StickyBucketService {\n /** Intended to be used with npm: 'ioredis'. **/\n private redis: IORedisCompat | undefined;\n constructor({ redis }: { redis: IORedisCompat }) {\n super();\n this.redis = redis;\n }\n\n async getAllAssignments(\n attributes: Record\n ): Promise> {\n const docs: Record = {};\n const keys = Object.entries(attributes).map(\n ([attributeName, attributeValue]) => `${attributeName}||${attributeValue}`\n );\n if (!this.redis) return docs;\n await this.redis.mget(...keys).then((values) => {\n values.forEach((raw) => {\n try {\n const data = JSON.parse(raw || \"{}\");\n if (data.attributeName && data.attributeValue && data.assignments) {\n const key = `${data.attributeName}||${data.attributeValue}`;\n docs[key] = data;\n }\n } catch (e) {\n // ignore redis doc parse errors\n }\n });\n });\n return docs;\n }\n\n async getAssignments(_attributeName: string, _attributeValue: string) {\n // not implemented\n return null;\n }\n\n async saveAssignments(doc: StickyAssignmentsDocument) {\n const key = `${doc.attributeName}||${doc.attributeValue}`;\n if (!this.redis) return;\n await this.redis.set(key, JSON.stringify(doc));\n }\n}\n"],"names":["growthbook","t","cacheSettings","staleTTL","maxAge","cacheKey","backgroundSync","maxEntries","disableIdleStreams","idleStreamInterval","polyfills","fetch","globalThis","bind","SubtleCrypto","crypto","subtle","EventSource","helpers","fetchFeaturesCall","_ref","host","clientKey","headers","concat","fetchRemoteEvalCall","_ref2","payload","options","method","body","JSON","stringify","eventSourceCall","_ref3","startIdleListener","idleTimeout","window","document","onVisibilityChange","visibilityState","clearTimeout","onVisible","setTimeout","onHidden","addEventListener","removeEventListener","stopIdleListener","localStorage","e","subscribedInstances","Map","cacheInitialized","cache","activeFetches","streams","supportsSSE","Set","forEach","channel","state","disableChannel","enableChannel","async","updatePersistentCache","setItem","Array","from","entries","getKey","instance","apiHost","getApiInfo","getCacheKey","baseKey","isRemoteEval","attributes","getAttributes","cacheKeyAttributes","getCacheKeyAttributes","Object","keys","ca","key","fv","getForcedVariations","url","getUrl","cleanupCache","entriesWithTimestamps","map","_ref5","value","staleAt","getTime","sort","a","b","entriesToRemoveCount","Math","min","max","size","i","delete","onNewFeatureData","data","version","dateUpdated","Date","now","existing","get","set","sse","has","instances","refreshInstance","decryptPayload","refreshStickyBuckets","setFeatures","features","getFeatures","setExperiments","experiments","getExperiments","fetchFeatures","apiRequestHeaders","getApiHosts","getClientKey","remoteEval","promise","forcedVariations","forcedFeatures","getForcedFeatures","then","res","ok","Error","status","add","json","startAutoRefresh","catch","Promise","resolve","streamingHost","streamingHostRequestHeaders","src","cb","event","type","parse","errors","onSSEError","readyState","delay","pow","random","includes","onopen","onerror","close","destroyChannel","clearAutoRefresh","clear","validAttributeName","nullController","revert","elements","mutations","getElementRecord","element","record","createElementPropertyRecord","el","attr","getCurrentValue","setValue","mutationRunner","currentValue","isDirty","originalValue","virtualValue","_positionTimeout","observer","MutationObserver","parentNode","insertBeforeNode","observe","childList","subtree","characterData","attributeFilter","queueIfNeeded","val","currentVal","runDOMUpdates","htmlMutationRunner","m","mutate","html","transformContainer","createElement","innerHTML","classMutationRunner","split","filter","Boolean","join","attrMutationRunner","positionMutationRunner","newNodes","parentSelector","insertBeforeSelector","querySelector","getHTMLValue","setHTMLValue","getElementHTMLRecord","elementRecord","getElementPosition","parentElement","nextElementSibling","setElementPosition","contains","insertBefore","getElementPositionRecord","position","setClassValue","className","removeAttribute","getClassValue","getElementClassRecord","classes","getElementAttributeRecord","attrName","_el$getAttribute","getAttribute","setAttribute","setPropertyValue","length","_element$html","_element$html$observe","disconnect","_element$classes","_element$classes$obse","_element$position","_element$position$obs","_element$attributes","_element$attributes$a","_element$attributes$a2","refreshElementsSet","mutation","kind","existingElements","querySelectorAll","selector","attribute","push","refreshAllElementSets","newMutation","index","indexOf","splice","test","classnames","mutatedClassnames","c","hashFnv32a","str","hval","l","charCodeAt","hash","seed","inRange","n","range","getUrlRegExp","regexString","escaped","replace","RegExp","console","error","isURLTargeted","targets","hasIncludeRules","isIncluded","match","_evalURLTarget","pattern","include","parsed","URL","regex","href","substring","origin","actual","expected","comps","pathname","searchParams","v","k","some","isPath","documentElement","base64ToBuf","Uint8Array","atob","decrypt","encryptedString","decryptionKey","importKey","name","iv","cipherText","plainTextBuffer","TextDecoder","decode","toString","input","paddedVersionString","parts","padStart","_regexCache","evalCondition","obj","condition","evalOr","$or","$nor","conditions","$and","$not","evalConditionValue","getPath","path","current","isArray","isOperatorObject","op","evalOperatorCondition","isIn","operator","check","passed","j","isBrowser","SDK_VERSION","StickyBucketService","docs","all","attributeName","attributeValue","this","getAssignments","doc","BrowserCookieStickyBucketService","constructor","prefix","jsCookie","cookieAttributes","super","raw","assignments","ExpressCookieStickyBucketService","req","cookies","cookie","encodeURIComponent","GrowthBook","context","_ctx","_renderer","_trackedExperiments","_trackedFeatures","debug","_subscriptions","_rtQueue","_rtTimer","ready","_assigned","_forcedFeatureValues","_attributeOverrides","_activeAutoExperiments","_triggeredExpKeys","_loadFeaturesCalled","_redirectedUrl","_deferredTrackingCalls","renderer","isGbHost","hostname","enableDevMode","_growthbook","dispatchEvent","Event","_updateAllAutoExperiments","antiFlicker","_setAntiFlicker","_refresh","autoRefresh","subscribeToChanges","_canSubscribe","subs","defaultHost","apiHostRequestHeaders","allowStale","updateInstance","timeout","skipCache","minStaleAt","getItem","_ref4","cleanupFn","timer","resolved","finish","_render","featuresJSON","experimentsJSON","encryptedFeatures","encryptedExperiments","stickyBucketService","_refreshForRemoteEval","setAttributes","overrides","vars","setForcedFeatures","getStickyBucketAssignmentDocs","stickyBucketAssignmentDocs","subscribe","getAllResults","destroy","s","exp","undo","setRenderer","forceVariation","variation","run","experiment","result","_run","_fireSubscriptions","triggerExperiment","manual","_runAutoExperiment","forceRerun","valueHash","inExperiment","_undoActiveAutoExperiment","urlRedirect","urlPatterns","persistQueryString","oldUrl","newUrl","currUrl","redirectUrl","_getContextUrl","log","id","navigate","_getNavigateFunction","_this$_ctx$navigateDe","navigateDelay","_applyDOMChanges","_isRedirectExperiment","variations","prev","variationId","_trackFeatureUsage","source","stringifiedValue","onFeatureUsage","on","q","realtimeKey","mode","realtimeInterval","_getFeatureResult","ruleId","ret","off","experimentResult","isOn","evalFeature","isOff","getFeatureValue","defaultValue","feature","_evalFeature","evalCtx","evaluatedFeatures","rules","rule","parentConditions","parentCondition","parentResult","gate","filters","_isFilteredOut","_conditionPasses","_isIncludedInRollout","hashAttribute","disableStickyBucketing","fallbackAttribute","coverage","hashVersion","tracks","_track","force","weights","bucketVersion","minBucketVersion","namespace","meta","ranges","phase","passthrough","hashValue","_getHashAttribute","r","featureId","numVariations","_getResult","enabled","_mergeOverrides","qsOverride","search","kv","parseInt","active","assigned","foundStickyBucket","stickyBucketVersionIsBlocked","versionIsBlocked","_getStickyBucketVariation","groups","_hasGroupOverlap","_urlIsValid","equal","fill","totalWeight","reduce","w","sum","cumulative","start","undefined","qaMode","changed","attrKey","_generateStickyBucketAssignmentDoc","_getStickyBucketExperimentKey","saveAssignments","msg","ctx","getDeferredTrackingCalls","setDeferredTrackingCalls","calls","fireDeferredTrackingCalls","hasInvalidTrackingCall","call","setTrackingCallback","callback","trackingCallback","o","assign","fallback","user","variationIndex","hashUsed","bucket","stickyBucketUsed","location","urlRegex","pathOnly","expGroups","getRedirectUrl","_this$_ctx$antiFlicke","styleTag","head","appendChild","classList","remove","antiFlickerTimeout","changes","css","js","script","domMutations","action","fn","_deriveStickyBucketIdentifierAttributes","_getStickyBucketAttributes","getAllAssignments","_getStickyBucketAssignments","mergedAssignments","values","experimentKey","experimentBucketVersion","minExperimentBucketVersion","variationKey","findIndex","stickyBucketIdentifierAttributes","existingAssignments","newAssignments","LocalStorageStickyBucketService","opts","RedisStickyBucketService","redis","mget","_attributeName","_attributeValue","At","clearCache","configureCache","yt","ot","h","setPolyfills","defineProperty"],"version":3,"file":"free-mastercard-gold.7c1795d0.js.map"}