From dfef00ef77f5181d1d8a4f7cc88f7b7c0514dd34 Mon Sep 17 00:00:00 2001 From: shakyShane Date: Thu, 21 Nov 2024 16:10:57 +0000 Subject: [PATCH] Release build 6.39.0 [ci release] --- CHANGELOG.txt | 5 +- .../ContentScopeScripts/dist/contentScope.js | 2 +- .../dist/contentScopeIsolated.js | 292 +++++++++++++++--- build/android/autofillPasswordImport.js | 2 +- build/android/contentScope.js | 2 +- build/chrome-mv3/inject.js | 2 +- build/chrome/inject.js | 4 +- build/firefox/inject.js | 2 +- build/integration/contentScope.js | 292 +++++++++++++++--- build/windows/contentScope.js | 292 +++++++++++++++--- .../broker-protection.spec.js | 75 +++++ ...conditional-clicks-hard-coded-default.json | 26 ++ ...tional-clicks-hard-coded-null-default.json | 22 ++ ...conditional-clicks-hard-coded-success.json | 26 ++ ...l-clicks-hard-coded-undefined-default.json | 26 ++ ...nditional-clicks-interpolated-default.json | 33 ++ ...nditional-clicks-interpolated-success.json | 33 ++ ...ctation-actions-conditional-subaction.json | 43 +++ .../pages/conditional-clicks.html | 26 ++ .../pages/expectation-actions.html | 17 +- injected/src/captured-globals.js | 2 +- injected/src/features/broker-protection.js | 114 +++++-- .../actions/build-url-transforms.js | 7 +- .../broker-protection/actions/click.js | 149 ++++++++- .../broker-protection/actions/expectation.js | 24 +- .../src/features/broker-protection/execute.js | 2 +- .../src/features/broker-protection/types.js | 1 + injected/unit-test/broker-protection.js | 27 ++ 28 files changed, 1328 insertions(+), 220 deletions(-) create mode 100644 injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-hard-coded-default.json create mode 100644 injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-hard-coded-null-default.json create mode 100644 injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-hard-coded-success.json create mode 100644 injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-hard-coded-undefined-default.json create mode 100644 injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-interpolated-default.json create mode 100644 injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-interpolated-success.json create mode 100644 injected/integration-test/test-pages/broker-protection/actions/expectation-actions-conditional-subaction.json create mode 100644 injected/integration-test/test-pages/broker-protection/pages/conditional-clicks.html diff --git a/CHANGELOG.txt b/CHANGELOG.txt index d51c550ff..1507c0f43 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,2 @@ -- adding debugging+performance helpers (#1247) -- ntp: send source index in move action (#1250) -- messaging: windows special pages (#1216) \ No newline at end of file +- fix: randomUUID is absent in none-secure contexts (#1254) +- Support Conditional Clicking in Broker Protection (#1141) \ No newline at end of file diff --git a/Sources/ContentScopeScripts/dist/contentScope.js b/Sources/ContentScopeScripts/dist/contentScope.js index 1d39e1569..98dbada8e 100644 --- a/Sources/ContentScopeScripts/dist/contentScope.js +++ b/Sources/ContentScopeScripts/dist/contentScope.js @@ -37,7 +37,7 @@ const String$1 = globalThis.String; const Map$1 = globalThis.Map; const Error$2 = globalThis.Error; - const randomUUID = globalThis.crypto?.randomUUID.bind(globalThis.crypto); + const randomUUID = globalThis.crypto?.randomUUID?.bind(globalThis.crypto); var capturedGlobals = /* @__PURE__ */ Object.freeze({ __proto__: null, CustomEvent: CustomEvent$1, diff --git a/Sources/ContentScopeScripts/dist/contentScopeIsolated.js b/Sources/ContentScopeScripts/dist/contentScopeIsolated.js index 49dd4f648..f09d15b64 100644 --- a/Sources/ContentScopeScripts/dist/contentScopeIsolated.js +++ b/Sources/ContentScopeScripts/dist/contentScopeIsolated.js @@ -27,7 +27,7 @@ const String$1 = globalThis.String; const Map$1 = globalThis.Map; const Error$1 = globalThis.Error; - const randomUUID = globalThis.crypto?.randomUUID.bind(globalThis.crypto); + const randomUUID = globalThis.crypto?.randomUUID?.bind(globalThis.crypto); var capturedGlobals = /*#__PURE__*/Object.freeze({ __proto__: null, @@ -7160,6 +7160,7 @@ /** * @typedef {{url: string} & Record} BuildUrlAction + * @typedef {Record} BuildActionWithoutUrl * @typedef {Record} UserData */ @@ -7206,7 +7207,7 @@ * Example, `/a/b/${name|capitalize}` -> applies the `capitalize` transform * to the name field * - * @type {Map string)>} + * @type {Map string)>} */ const optionalTransforms = new Map([ ['hyphenated', (value) => value.split(' ').join('-')], @@ -7291,7 +7292,7 @@ * allowing the function to replace them with corresponding data from `userData` after applying any specified transformations. * * @param {string} input - * @param {BuildUrlAction} action + * @param {BuildUrlAction | BuildActionWithoutUrl} action * @param {Record} userData */ function processTemplateStringWithUserData(input, action, userData) { @@ -7311,7 +7312,7 @@ * @param {string} dataKey * @param {string|number} value * @param {string[]} transformNames - * @param {BuildUrlAction} action + * @param {BuildUrlAction | BuildActionWithoutUrl} action */ function applyTransforms(dataKey, value, transformNames, action) { const subject = String(value || ''); @@ -7366,6 +7367,7 @@ * @param {string} params.actionID * @param {string} params.actionType * @param {any} params.response + * @param {import("./actions/extract").Action[]} [params.next] * @param {Record} [params.meta] - optional meta data */ constructor(params) { @@ -11463,9 +11465,44 @@ * @return {import('../types.js').ActionResponse} */ function click(action, userData, root = document) { + /** @type {Array | null} */ + let elements = []; + + if (action.choices?.length) { + const choices = evaluateChoices(action, userData); + + // If we returned null, the intention is to skip execution, so return success + if (choices === null) { + return new SuccessResponse({ actionID: action.id, actionType: action.actionType, response: null }); + } else if ('error' in choices) { + return new ErrorResponse({ actionID: action.id, message: `Unable to evaluate choices: ${choices.error}` }); + } else if (!('elements' in choices)) { + return new ErrorResponse({ actionID: action.id, message: 'No elements provided to click action' }); + } + + elements = choices.elements; + } else { + if (!('elements' in action)) { + return new ErrorResponse({ actionID: action.id, message: 'No elements provided to click action' }); + } + + elements = action.elements; + } + + if (!elements || !elements.length) { + return new ErrorResponse({ actionID: action.id, message: 'No elements provided to click action' }); + } + // there can be multiple elements provided by the action - for (const element of action.elements) { - const rootElement = selectRootElement(element, userData, root); + for (const element of elements) { + let rootElement; + + try { + rootElement = selectRootElement(element, userData, root); + } catch (error) { + return new ErrorResponse({ actionID: action.id, message: `Could not find root element: ${error.message}` }); + } + const elements = getElements(rootElement, element.selector); if (!elements?.length) { @@ -11520,12 +11557,120 @@ } /** + * Evaluate a comparator and return the appropriate function + * @param {string} operator + * @returns {(a: any, b: any) => boolean} + */ + function getComparisonFunction(operator) { + switch (operator) { + case '=': + case '==': + case '===': + return (a, b) => a === b; + case '!=': + case '!==': + return (a, b) => a !== b; + case '<': + return (a, b) => a < b; + case '<=': + return (a, b) => a <= b; + case '>': + return (a, b) => a > b; + case '>=': + return (a, b) => a >= b; + default: + throw new Error(`Invalid operator: ${operator}`); + } + } + + /** + * Evaluates the defined choices (and/or the default) and returns an array of the elements to be clicked + * + * @param {Record} action + * @param {Record} userData + * @returns {{ elements: [Record] } | { error: String } | null} + */ + function evaluateChoices(action, userData) { + if ('elements' in action) { + return { error: 'Elements should be nested inside of choices' }; + } + + for (const choice of action.choices) { + if (!('condition' in choice) || !('elements' in choice)) { + return { error: 'All choices must have a condition and elements' }; + } + + const comparison = runComparison(choice, action, userData); + + if ('error' in comparison) { + return { error: comparison.error }; + } else if ('result' in comparison && comparison.result === true) { + return { elements: choice.elements }; + } + } + + // If there's no default defined, return an error. + if (!('default' in action)) { + return { error: 'All conditions failed and no default action was provided' }; + } + + // If there is a default and it's null (meaning skip any further action) return success. + if (action.default === null) { + // Nothing else to do, return null + return null; + } + + // If the default is defined and not null (without elements), return an error. + if (!('elements' in action.default)) { + return { error: 'Default action must have elements' }; + } + + return { elements: action.default.elements }; + } + + /** + * Attempts to turn a choice definition into an executable comparison and returns the result + * + * @param {Record} choice * @param {Record} action * @param {Record} userData + * @returns {{ result: Boolean } | { error: String }} + */ + function runComparison(choice, action, userData) { + let compare; + let left; + let right; + + try { + compare = getComparisonFunction(choice.condition.operation); + } catch (error) { + return { error: `Unable to get comparison function: ${error.message}` }; + } + + try { + left = processTemplateStringWithUserData(choice.condition.left, action, userData); + right = processTemplateStringWithUserData(choice.condition.right, action, userData); + } catch (error) { + return { error: `Unable to resolve left/right comparison arguments: ${error.message}` }; + } + + let result; + + try { + result = compare(left, right); + } catch (error) { + return { error: `Comparison failed with the following error: ${error.message}` }; + } + + return { result }; + } + + /** + * @param {Record} action * @param {Document} root - * @return {Promise} + * @return {import('../types.js').ActionResponse} */ - async function expectation(action, userData, root = document) { + function expectation(action, root = document) { const results = expectMany(action.expectations, root); // filter out good results + silent failures, leaving only fatal errors @@ -11545,20 +11690,14 @@ // only run later actions if every expectation was met const runActions = results.every((x) => x.result === true); - const secondaryErrors = []; if (action.actions?.length && runActions) { - for (const subAction of action.actions) { - const result = await execute(subAction, userData, root); - - if ('error' in result) { - secondaryErrors.push(result.error); - } - } - - if (secondaryErrors.length > 0) { - return new ErrorResponse({ actionID: action.id, message: secondaryErrors.join(', ') }); - } + return new SuccessResponse({ + actionID: action.id, + actionType: action.actionType, + response: null, + next: action.actions, + }); } return new SuccessResponse({ actionID: action.id, actionType: action.actionType, response: null }); @@ -11705,7 +11844,7 @@ case 'click': return click(action, data(action, inputData, 'userProfile'), root); case 'expectation': - return await expectation(action, data(action, inputData, 'userProfile'), root); + return expectation(action, root); case 'fillForm': return fillForm(action, data(action, inputData, 'extractedProfile'), root); case 'getCaptchaInfo': @@ -11783,7 +11922,6 @@ /** * @typedef {import("./broker-protection/types.js").ActionResponse} ActionResponse */ - class BrokerProtection extends ContentFeature { init() { this.messaging.subscribe('onActionReceived', async (/** @type {any} */ params) => { @@ -11795,40 +11933,30 @@ return this.messaging.notify('actionError', { error: 'No action found.' }); } - /** - * Note: We're not currently guarding against concurrent actions here - * since the native side contains the scheduling logic to prevent it. - */ - let retryConfig = action.retry?.environment === 'web' ? action.retry : undefined; + const { results, exceptions } = await this.exec(action, data); - /** - * Special case for the exact action - */ - if (!retryConfig && action.actionType === 'extract') { - retryConfig = { - interval: { ms: 1000 }, - maxAttempts: 30, - }; - } + if (results) { + // there might only be a single result. + const parent = results[0]; + const errors = results.filter((x) => 'error' in x); - /** - * Special case for when expectation contains a check for an element, retry it - */ - if (!retryConfig && action.actionType === 'expectation') { - if (action.expectations.some((x) => x.type === 'element')) { - retryConfig = { - interval: { ms: 1000 }, - maxAttempts: 30, - }; + // if there are no secondary actions, or just no errors in general, just report the parent action + if (results.length === 1 || errors.length === 0) { + return this.messaging.notify('actionCompleted', { result: parent }); } - } - const { result, exceptions } = await retry(() => execute(action, data), retryConfig); + // here we must have secondary actions that failed. + // so we want to create an error response with the parent ID, but with the errors messages from + // the children + const joinedErrors = errors.map((x) => x.error.message).join(', '); + const response = new ErrorResponse({ + actionID: action.id, + message: 'Secondary actions failed: ' + joinedErrors, + }); - if (result) { - this.messaging.notify('actionCompleted', { result }); + return this.messaging.notify('actionCompleted', { result: response }); } else { - this.messaging.notify('actionError', { error: 'No response found, exceptions: ' + exceptions.join(', ') }); + return this.messaging.notify('actionError', { error: 'No response found, exceptions: ' + exceptions.join(', ') }); } } catch (e) { console.log('unhandled exception: ', e); @@ -11836,6 +11964,70 @@ } }); } + + /** + * Recursively execute actions with the same dataset, collecting all results/exceptions for + * later analysis + * @param {any} action + * @param {Record} data + * @return {Promise<{results: ActionResponse[], exceptions: string[]}>} + */ + async exec(action, data) { + const retryConfig = this.retryConfigFor(action); + const { result, exceptions } = await retry(() => execute(action, data), retryConfig); + + if (result) { + if ('success' in result && Array.isArray(result.success.next)) { + const nextResults = []; + const nextExceptions = []; + + for (const nextAction of result.success.next) { + const { results: subResults, exceptions: subExceptions } = await this.exec(nextAction, data); + + nextResults.push(...subResults); + nextExceptions.push(...subExceptions); + } + return { results: [result, ...nextResults], exceptions: exceptions.concat(nextExceptions) }; + } + return { results: [result], exceptions: [] }; + } + return { results: [], exceptions }; + } + + /** + * Define default retry configurations for certain actions + * + * @param {any} action + * @returns + */ + retryConfigFor(action) { + /** + * Note: We're not currently guarding against concurrent actions here + * since the native side contains the scheduling logic to prevent it. + */ + const retryConfig = action.retry?.environment === 'web' ? action.retry : undefined; + /** + * Special case for the exact action + */ + if (!retryConfig && action.actionType === 'extract') { + return { + interval: { ms: 1000 }, + maxAttempts: 30, + }; + } + /** + * Special case for when expectation contains a check for an element, retry it + */ + if (!retryConfig && action.actionType === 'expectation') { + if (action.expectations.some((x) => x.type === 'element')) { + return { + interval: { ms: 1000 }, + maxAttempts: 30, + }; + } + } + return retryConfig; + } } /** diff --git a/build/android/autofillPasswordImport.js b/build/android/autofillPasswordImport.js index 79ed76c56..01a0e11d1 100644 --- a/build/android/autofillPasswordImport.js +++ b/build/android/autofillPasswordImport.js @@ -16,7 +16,7 @@ globalThis.dispatchEvent?.bind(globalThis); globalThis.addEventListener?.bind(globalThis); globalThis.removeEventListener?.bind(globalThis); - globalThis.crypto?.randomUUID.bind(globalThis.crypto); + globalThis.crypto?.randomUUID?.bind(globalThis.crypto); /* eslint-disable no-redeclare, no-global-assign */ /* global cloneInto, exportFunction, false */ diff --git a/build/android/contentScope.js b/build/android/contentScope.js index f4a28256d..e7e7b4a54 100644 --- a/build/android/contentScope.js +++ b/build/android/contentScope.js @@ -27,7 +27,7 @@ const String$1 = globalThis.String; const Map$1 = globalThis.Map; const Error$2 = globalThis.Error; - const randomUUID = globalThis.crypto?.randomUUID.bind(globalThis.crypto); + const randomUUID = globalThis.crypto?.randomUUID?.bind(globalThis.crypto); var capturedGlobals = /*#__PURE__*/Object.freeze({ __proto__: null, diff --git a/build/chrome-mv3/inject.js b/build/chrome-mv3/inject.js index 7ea287ae7..79249f208 100644 --- a/build/chrome-mv3/inject.js +++ b/build/chrome-mv3/inject.js @@ -27,7 +27,7 @@ const String$1 = globalThis.String; const Map$1 = globalThis.Map; const Error$2 = globalThis.Error; - const randomUUID = globalThis.crypto?.randomUUID.bind(globalThis.crypto); + const randomUUID = globalThis.crypto?.randomUUID?.bind(globalThis.crypto); var capturedGlobals = /*#__PURE__*/Object.freeze({ __proto__: null, diff --git a/build/chrome/inject.js b/build/chrome/inject.js index 38f1bce7c..f8da6e30a 100644 --- a/build/chrome/inject.js +++ b/build/chrome/inject.js @@ -28,7 +28,7 @@ globalThis.dispatchEvent?.bind(globalThis); globalThis.addEventListener?.bind(globalThis); globalThis.removeEventListener?.bind(globalThis); - globalThis.crypto?.randomUUID.bind(globalThis.crypto); + globalThis.crypto?.randomUUID?.bind(globalThis.crypto); /* eslint-disable no-redeclare, no-global-assign */ /* global cloneInto, exportFunction, false */ @@ -137,7 +137,7 @@ const reusableSecret = '_r' + randomString(); const siteObject = computeLimitedSiteObject(); const initialScript = ` - ${decodeURI("/*!%20%C2%A9%20DuckDuckGo%20ContentScopeScripts%20protections%20https://github.com/duckduckgo/content-scope-scripts/%20*/%0Avar%20contentScopeFeatures%20=%20(function%20(exports)%20%7B%0A%20%20%20%20'use%20strict';%0A%0A%20%20%20%20/*%20eslint-disable%20no-redeclare%20*/%0A%20%20%20%20const%20Set$1%20=%20globalThis.Set;%0A%20%20%20%20const%20Reflect$1%20=%20globalThis.Reflect;%0A%20%20%20%20const%20customElementsGet%20=%20globalThis.customElements?.get.bind(globalThis.customElements);%0A%20%20%20%20const%20customElementsDefine%20=%20globalThis.customElements?.define.bind(globalThis.customElements);%0A%20%20%20%20const%20getOwnPropertyDescriptor%20=%20Object.getOwnPropertyDescriptor;%0A%20%20%20%20const%20getOwnPropertyDescriptors%20=%20Object.getOwnPropertyDescriptors;%0A%20%20%20%20const%20toString%20=%20Object.prototype.toString;%0A%20%20%20%20const%20objectKeys%20=%20Object.keys;%0A%20%20%20%20const%20objectEntries%20=%20Object.entries;%0A%20%20%20%20const%20objectDefineProperty%20=%20Object.defineProperty;%0A%20%20%20%20const%20URL$1%20=%20globalThis.URL;%0A%20%20%20%20const%20Proxy$1%20=%20globalThis.Proxy;%0A%20%20%20%20const%20functionToString%20=%20Function.prototype.toString;%0A%20%20%20%20const%20TypeError$1%20=%20globalThis.TypeError;%0A%20%20%20%20const%20Symbol%20=%20globalThis.Symbol;%0A%20%20%20%20const%20hasOwnProperty%20=%20Object.prototype.hasOwnProperty;%0A%20%20%20%20const%20dispatchEvent%20=%20globalThis.dispatchEvent?.bind(globalThis);%0A%20%20%20%20const%20addEventListener%20=%20globalThis.addEventListener?.bind(globalThis);%0A%20%20%20%20const%20removeEventListener%20=%20globalThis.removeEventListener?.bind(globalThis);%0A%20%20%20%20const%20CustomEvent$1%20=%20globalThis.CustomEvent;%0A%20%20%20%20const%20Promise$1%20=%20globalThis.Promise;%0A%20%20%20%20const%20String$1%20=%20globalThis.String;%0A%20%20%20%20const%20Map$1%20=%20globalThis.Map;%0A%20%20%20%20const%20Error$2%20=%20globalThis.Error;%0A%20%20%20%20const%20randomUUID%20=%20globalThis.crypto?.randomUUID.bind(globalThis.crypto);%0A%0A%20%20%20%20var%20capturedGlobals%20=%20/*#__PURE__*/Object.freeze(%7B%0A%20%20%20%20%20%20%20%20__proto__:%20null,%0A%20%20%20%20%20%20%20%20CustomEvent:%20CustomEvent$1,%0A%20%20%20%20%20%20%20%20Error:%20Error$2,%0A%20%20%20%20%20%20%20%20Map:%20Map$1,%0A%20%20%20%20%20%20%20%20Promise:%20Promise$1,%0A%20%20%20%20%20%20%20%20Proxy:%20Proxy$1,%0A%20%20%20%20%20%20%20%20Reflect:%20Reflect$1,%0A%20%20%20%20%20%20%20%20Set:%20Set$1,%0A%20%20%20%20%20%20%20%20String:%20String$1,%0A%20%20%20%20%20%20%20%20Symbol:%20Symbol,%0A%20%20%20%20%20%20%20%20TypeError:%20TypeError$1,%0A%20%20%20%20%20%20%20%20URL:%20URL$1,%0A%20%20%20%20%20%20%20%20addEventListener:%20addEventListener,%0A%20%20%20%20%20%20%20%20customElementsDefine:%20customElementsDefine,%0A%20%20%20%20%20%20%20%20customElementsGet:%20customElementsGet,%0A%20%20%20%20%20%20%20%20dispatchEvent:%20dispatchEvent,%0A%20%20%20%20%20%20%20%20functionToString:%20functionToString,%0A%20%20%20%20%20%20%20%20getOwnPropertyDescriptor:%20getOwnPropertyDescriptor,%0A%20%20%20%20%20%20%20%20getOwnPropertyDescriptors:%20getOwnPropertyDescriptors,%0A%20%20%20%20%20%20%20%20hasOwnProperty:%20hasOwnProperty,%0A%20%20%20%20%20%20%20%20objectDefineProperty:%20objectDefineProperty,%0A%20%20%20%20%20%20%20%20objectEntries:%20objectEntries,%0A%20%20%20%20%20%20%20%20objectKeys:%20objectKeys,%0A%20%20%20%20%20%20%20%20randomUUID:%20randomUUID,%0A%20%20%20%20%20%20%20%20removeEventListener:%20removeEventListener,%0A%20%20%20%20%20%20%20%20toString:%20toString%0A%20%20%20%20%7D);%0A%0A%20%20%20%20/*%20eslint-disable%20no-redeclare,%20no-global-assign%20*/%0A%20%20%20%20/*%20global%20cloneInto,%20exportFunction,%20false%20*/%0A%0A%20%20%20%20//%20Only%20use%20globalThis%20for%20testing%20this%20breaks%20window.wrappedJSObject%20code%20in%20Firefox%0A%0A%20%20%20%20let%20globalObj%20=%20typeof%20window%20===%20'undefined'%20?%20globalThis%20:%20window;%0A%20%20%20%20let%20Error$1%20=%20globalObj.Error;%0A%20%20%20%20let%20messageSecret;%0A%0A%20%20%20%20//%20save%20a%20reference%20to%20original%20CustomEvent%20amd%20dispatchEvent%20so%20they%20can't%20be%20overriden%20to%20forge%20messages%0A%20%20%20%20const%20OriginalCustomEvent%20=%20typeof%20CustomEvent%20===%20'undefined'%20?%20null%20:%20CustomEvent;%0A%20%20%20%20const%20originalWindowDispatchEvent%20=%20typeof%20window%20===%20'undefined'%20?%20null%20:%20window.dispatchEvent.bind(window);%0A%20%20%20%20function%20registerMessageSecret(secret)%20%7B%0A%20%20%20%20%20%20%20%20messageSecret%20=%20secret;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@returns%20%7BHTMLElement%7D%20the%20element%20to%20inject%20the%20script%20into%0A%20%20%20%20%20*/%0A%20%20%20%20function%20getInjectionElement()%20%7B%0A%20%20%20%20%20%20%20%20return%20document.head%20%7C%7C%20document.documentElement;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Creates%20a%20script%20element%20with%20the%20given%20code%20to%20avoid%20Firefox%20CSP%20restrictions.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20css%0A%20%20%20%20%20*%20@returns%20%7BHTMLLinkElement%20%7C%20HTMLStyleElement%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20createStyleElement(css)%20%7B%0A%20%20%20%20%20%20%20%20let%20style;%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20style%20=%20document.createElement('style');%0A%20%20%20%20%20%20%20%20%20%20%20%20style.innerText%20=%20css;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20style;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Injects%20a%20script%20into%20the%20page,%20avoiding%20CSP%20restrictions%20if%20possible.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20injectGlobalStyles(css)%20%7B%0A%20%20%20%20%20%20%20%20const%20style%20=%20createStyleElement(css);%0A%20%20%20%20%20%20%20%20getInjectionElement().appendChild(style);%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20linear%20feedback%20shift%20register%20to%20find%20a%20random%20approximation%0A%20%20%20%20function%20nextRandom(v)%20%7B%0A%20%20%20%20%20%20%20%20return%20Math.abs((v%20%3E%3E%201)%20%7C%20(((v%20%3C%3C%2062)%20%5E%20(v%20%3C%3C%2061))%20&%20(~(~0%20%3C%3C%2063)%20%3C%3C%2062)));%0A%20%20%20%20%7D%0A%0A%20%20%20%20const%20exemptionLists%20=%20%7B%7D;%0A%20%20%20%20function%20shouldExemptUrl(type,%20url)%20%7B%0A%20%20%20%20%20%20%20%20for%20(const%20regex%20of%20exemptionLists%5Btype%5D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(regex.test(url))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20let%20debug%20=%20false;%0A%0A%20%20%20%20function%20initStringExemptionLists(args)%20%7B%0A%20%20%20%20%20%20%20%20const%20%7B%20stringExemptionLists%20%7D%20=%20args;%0A%20%20%20%20%20%20%20%20debug%20=%20args.debug;%0A%20%20%20%20%20%20%20%20for%20(const%20type%20in%20stringExemptionLists)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20exemptionLists%5Btype%5D%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20stringExemption%20of%20stringExemptionLists%5Btype%5D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20exemptionLists%5Btype%5D.push(new%20RegExp(stringExemption));%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Best%20guess%20effort%20if%20the%20document%20is%20being%20framed%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%20if%20we%20infer%20the%20document%20is%20framed%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isBeingFramed()%20%7B%0A%20%20%20%20%20%20%20%20if%20(globalThis.location%20&&%20'ancestorOrigins'%20in%20globalThis.location)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20globalThis.location.ancestorOrigins.length%20%3E%200;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20globalThis.top%20!==%20globalThis.window;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Best%20guess%20effort%20if%20the%20document%20is%20third%20party%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%20if%20we%20infer%20the%20document%20is%20third%20party%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isThirdPartyFrame()%20%7B%0A%20%20%20%20%20%20%20%20if%20(!isBeingFramed())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20const%20tabHostname%20=%20getTabHostname();%0A%20%20%20%20%20%20%20%20//%20If%20we%20can't%20get%20the%20tab%20hostname,%20assume%20it's%20third%20party%0A%20%20%20%20%20%20%20%20if%20(!tabHostname)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20!matchHostname(globalThis.location.hostname,%20tabHostname);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Best%20guess%20effort%20of%20the%20tabs%20hostname;%20where%20possible%20always%20prefer%20the%20args.site.domain%0A%20%20%20%20%20*%20@returns%20%7Bstring%7Cnull%7D%20inferred%20tab%20hostname%0A%20%20%20%20%20*/%0A%20%20%20%20function%20getTabHostname()%20%7B%0A%20%20%20%20%20%20%20%20let%20framingOrigin%20=%20null;%0A%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20globalThis.top%20is%20possibly%20'null'%20here%0A%20%20%20%20%20%20%20%20%20%20%20%20framingOrigin%20=%20globalThis.top.location.href;%0A%20%20%20%20%20%20%20%20%7D%20catch%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20framingOrigin%20=%20globalThis.document.referrer;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Not%20supported%20in%20Firefox%0A%20%20%20%20%20%20%20%20if%20('ancestorOrigins'%20in%20globalThis.location%20&&%20globalThis.location.ancestorOrigins.length)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20ancestorOrigins%20is%20reverse%20order,%20with%20the%20last%20item%20being%20the%20top%20frame%0A%20%20%20%20%20%20%20%20%20%20%20%20framingOrigin%20=%20globalThis.location.ancestorOrigins.item(globalThis.location.ancestorOrigins.length%20-%201);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20framingOrigin%20is%20possibly%20'null'%20here%0A%20%20%20%20%20%20%20%20%20%20%20%20framingOrigin%20=%20new%20URL(framingOrigin).hostname;%0A%20%20%20%20%20%20%20%20%7D%20catch%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20framingOrigin%20=%20null;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20framingOrigin;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Returns%20true%20if%20hostname%20is%20a%20subset%20of%20exceptionDomain%20or%20an%20exact%20match.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20hostname%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20exceptionDomain%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20matchHostname(hostname,%20exceptionDomain)%20%7B%0A%20%20%20%20%20%20%20%20return%20hostname%20===%20exceptionDomain%20%7C%7C%20hostname.endsWith(%60.$%7BexceptionDomain%7D%60);%0A%20%20%20%20%7D%0A%0A%20%20%20%20const%20lineTest%20=%20/(%5C()?(https?:%5B%5E)%5D+):%5B0-9%5D+:%5B0-9%5D+(%5C))?/;%0A%20%20%20%20function%20getStackTraceUrls(stack)%20%7B%0A%20%20%20%20%20%20%20%20const%20urls%20=%20new%20Set$1();%0A%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20errorLines%20=%20stack.split('%5Cn');%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Should%20cater%20for%20Chrome%20and%20Firefox%20stacks,%20we%20only%20care%20about%20https?%20resources.%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20line%20of%20errorLines)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20res%20=%20line.match(lineTest);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(res)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20urls.add(new%20URL(res%5B2%5D,%20location.href));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Fall%20through%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20urls;%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20getStackTraceOrigins(stack)%20%7B%0A%20%20%20%20%20%20%20%20const%20urls%20=%20getStackTraceUrls(stack);%0A%20%20%20%20%20%20%20%20const%20origins%20=%20new%20Set$1();%0A%20%20%20%20%20%20%20%20for%20(const%20url%20of%20urls)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20origins.add(url.hostname);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20origins;%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20Checks%20the%20stack%20trace%20if%20there%20are%20known%20libraries%20that%20are%20broken.%0A%20%20%20%20function%20shouldExemptMethod(type)%20%7B%0A%20%20%20%20%20%20%20%20//%20Short%20circuit%20stack%20tracing%20if%20we%20don't%20have%20checks%0A%20%20%20%20%20%20%20%20if%20(!(type%20in%20exemptionLists)%20%7C%7C%20exemptionLists%5Btype%5D.length%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20const%20stack%20=%20getStack();%0A%20%20%20%20%20%20%20%20const%20errorFiles%20=%20getStackTraceUrls(stack);%0A%20%20%20%20%20%20%20%20for%20(const%20path%20of%20errorFiles)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(shouldExemptUrl(type,%20path.href))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20Iterate%20through%20the%20key,%20passing%20an%20item%20index%20and%20a%20byte%20to%20be%20modified%0A%20%20%20%20function%20iterateDataKey(key,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20let%20item%20=%20key.charCodeAt(0);%0A%20%20%20%20%20%20%20%20for%20(const%20i%20in%20key)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20byte%20=%20key.charCodeAt(i);%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(let%20j%20=%208;%20j%20%3E=%200;%20j--)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20res%20=%20callback(item,%20byte);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Exit%20early%20if%20callback%20returns%20null%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(res%20===%20null)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20find%20next%20item%20to%20perturb%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20item%20=%20nextRandom(item);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Right%20shift%20as%20we%20use%20the%20least%20significant%20bit%20of%20it%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20byte%20=%20byte%20%3E%3E%201;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20isFeatureBroken(args,%20feature)%20%7B%0A%20%20%20%20%20%20%20%20return%20isPlatformSpecificFeature(feature)%0A%20%20%20%20%20%20%20%20%20%20%20%20?%20!args.site.enabledFeatures.includes(feature)%0A%20%20%20%20%20%20%20%20%20%20%20%20:%20args.site.isBroken%20%7C%7C%20args.site.allowlisted%20%7C%7C%20!args.site.enabledFeatures.includes(feature);%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20camelcase(dashCaseText)%20%7B%0A%20%20%20%20%20%20%20%20return%20dashCaseText.replace(/-(.)/g,%20(match,%20letter)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20letter.toUpperCase();%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20We%20use%20this%20method%20to%20detect%20M1%20macs%20and%20set%20appropriate%20API%20values%20to%20prevent%20sites%20from%20detecting%20fingerprinting%20protections%0A%20%20%20%20function%20isAppleSilicon()%20%7B%0A%20%20%20%20%20%20%20%20const%20canvas%20=%20document.createElement('canvas');%0A%20%20%20%20%20%20%20%20const%20gl%20=%20canvas.getContext('webgl');%0A%0A%20%20%20%20%20%20%20%20//%20Best%20guess%20if%20the%20device%20is%20an%20Apple%20Silicon%0A%20%20%20%20%20%20%20%20//%20https://stackoverflow.com/a/65412357%0A%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Object%20is%20possibly%20'null'%0A%20%20%20%20%20%20%20%20return%20gl.getSupportedExtensions().indexOf('WEBGL_compressed_texture_etc')%20!==%20-1;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Take%20configSeting%20which%20should%20be%20an%20array%20of%20possible%20values.%0A%20%20%20%20%20*%20If%20a%20value%20contains%20a%20criteria%20that%20is%20a%20match%20for%20this%20environment%20then%20return%20that%20value.%0A%20%20%20%20%20*%20Otherwise%20return%20the%20first%20value%20that%20doesn't%20have%20a%20criteria.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@param%20%7BConfigSetting%5B%5D%7D%20configSetting%20-%20Config%20setting%20which%20should%20contain%20a%20list%20of%20possible%20values%0A%20%20%20%20%20*%20@returns%20%7B*%7Cundefined%7D%20-%20The%20value%20from%20the%20list%20that%20best%20matches%20the%20criteria%20in%20the%20config%0A%20%20%20%20%20*/%0A%20%20%20%20function%20processAttrByCriteria(configSetting)%20%7B%0A%20%20%20%20%20%20%20%20let%20bestOption;%0A%20%20%20%20%20%20%20%20for%20(const%20item%20of%20configSetting)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(item.criteria)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(item.criteria.arch%20===%20'AppleSilicon'%20&&%20isAppleSilicon())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20bestOption%20=%20item;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20bestOption%20=%20item;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20bestOption;%0A%20%20%20%20%7D%0A%0A%20%20%20%20const%20functionMap%20=%20%7B%0A%20%20%20%20%20%20%20%20/**%20Useful%20for%20debugging%20APIs%20in%20the%20wild,%20shouldn't%20be%20used%20*/%0A%20%20%20%20%20%20%20%20debug:%20(...args)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20console.log('debugger',%20...args);%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20no-debugger%0A%20%20%20%20%20%20%20%20%20%20%20%20debugger;%0A%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20noop:%20()%20=%3E%20%7B%7D,%0A%20%20%20%20%7D;%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7Bobject%7D%20ConfigSetting%0A%20%20%20%20%20*%20@property%20%7B'undefined'%20%7C%20'number'%20%7C%20'string'%20%7C%20'function'%20%7C%20'boolean'%20%7C%20'null'%20%7C%20'array'%20%7C%20'object'%7D%20type%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20%5BfunctionName%5D%0A%20%20%20%20%20*%20@property%20%7Bboolean%20%7C%20string%20%7C%20number%7D%20value%0A%20%20%20%20%20*%20@property%20%7Bobject%7D%20%5Bcriteria%5D%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20criteria.arch%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Processes%20a%20structured%20config%20setting%20and%20returns%20the%20value%20according%20to%20its%20type%0A%20%20%20%20%20*%20@param%20%7BConfigSetting%7D%20configSetting%0A%20%20%20%20%20*%20@param%20%7B*%7D%20%5BdefaultValue%5D%0A%20%20%20%20%20*%20@returns%0A%20%20%20%20%20*/%0A%20%20%20%20function%20processAttr(configSetting,%20defaultValue)%20%7B%0A%20%20%20%20%20%20%20%20if%20(configSetting%20===%20undefined)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20defaultValue;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20configSettingType%20=%20typeof%20configSetting;%0A%20%20%20%20%20%20%20%20switch%20(configSettingType)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20'object':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(Array.isArray(configSetting))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configSetting%20=%20processAttrByCriteria(configSetting);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(configSetting%20===%20undefined)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20defaultValue;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!configSetting.type)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20defaultValue;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(configSetting.type%20===%20'function')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(configSetting.functionName%20&&%20functionMap%5BconfigSetting.functionName%5D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20functionMap%5BconfigSetting.functionName%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(configSetting.type%20===%20'undefined')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20undefined;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20All%20JSON%20expressable%20types%20are%20handled%20here%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20configSetting.value;%0A%20%20%20%20%20%20%20%20%20%20%20%20default:%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20defaultValue;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20getStack()%20%7B%0A%20%20%20%20%20%20%20%20return%20new%20Error$1().stack;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7B*%5B%5D%7D%20argsArray%0A%20%20%20%20%20*%20@returns%20%7Bstring%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20debugSerialize(argsArray)%20%7B%0A%20%20%20%20%20%20%20%20const%20maxSerializedSize%20=%201000;%0A%20%20%20%20%20%20%20%20const%20serializedArgs%20=%20argsArray.map((arg)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20serializableOut%20=%20JSON.stringify(arg);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(serializableOut.length%20%3E%20maxSerializedSize)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%60%3Ctruncated,%20length:%20$%7BserializableOut.length%7D,%20value:%20$%7BserializableOut.substring(0,%20maxSerializedSize)%7D...%3E%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20serializableOut;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Sometimes%20this%20happens%20when%20we%20can't%20serialize%20an%20object%20to%20string%20but%20we%20still%20wish%20to%20log%20it%20and%20make%20other%20args%20readable%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20'%3Cunserializable%3E';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20return%20JSON.stringify(serializedArgs);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@template%20%7Bobject%7D%20P%0A%20%20%20%20%20*%20@typedef%20%7Bobject%7D%20ProxyObject%3CP%3E%0A%20%20%20%20%20*%20@property%20%7B(target?:%20object,%20thisArg?:%20P,%20args?:%20object)%20=%3E%20void%7D%20apply%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@template%20%5BP=object%5D%0A%20%20%20%20%20*/%0A%20%20%20%20class%20DDGProxy%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('./content-feature').default%7D%20feature%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BP%7D%20objectScope%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20property%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BProxyObject%3CP%3E%7D%20proxyObject%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(feature,%20objectScope,%20property,%20proxyObject)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.objectScope%20=%20objectScope;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.property%20=%20property;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.feature%20=%20feature;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20feature.name;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.camelFeatureName%20=%20camelcase(this.featureName);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20outputHandler%20=%20(...args)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.feature.addDebugFlag();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20isExempt%20=%20shouldExemptMethod(this.camelFeatureName);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Keep%20this%20here%20as%20getStack()%20is%20expensive%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(debug)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20postDebugMessage(this.camelFeatureName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20isProxy:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20action:%20isExempt%20?%20'ignore'%20:%20'restrict',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20kind:%20this.property,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20documentUrl:%20document.location.href,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20stack:%20getStack(),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20args:%20debugSerialize(args%5B2%5D),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20The%20normal%20return%20value%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(isExempt)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(...args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20proxyObject.apply(...args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20getMethod%20=%20(target,%20prop,%20receiver)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.feature.addDebugFlag();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(prop%20===%20'toString')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20method%20=%20Reflect.get(target,%20prop,%20receiver).bind(target);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Object.defineProperty(method,%20'toString',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value:%20String.toString.bind(String.toString),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20method;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.get(target,%20prop,%20receiver);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._native%20=%20objectScope%5Bproperty%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20handler%20=%20%7B%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20handler.apply%20=%20outputHandler;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20handler.get%20=%20getMethod;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.internal%20=%20new%20globalObj.Proxy(objectScope%5Bproperty%5D,%20handler);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Actually%20apply%20the%20proxy%20to%20the%20native%20property%0A%20%20%20%20%20%20%20%20overload()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.objectScope%5Bthis.property%5D%20=%20this.internal;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20overloadDescriptor()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20TODO:%20this%20is%20not%20always%20correct!%20Use%20wrap*%20or%20shim*%20methods%20instead%0A%20%20%20%20%20%20%20%20%20%20%20%20this.feature.defineProperty(this.objectScope,%20this.property,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value:%20this.internal,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20writable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20const%20maxCounter%20=%20new%20Map();%0A%20%20%20%20function%20numberOfTimesDebugged(feature)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!maxCounter.has(feature))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20maxCounter.set(feature,%201);%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20maxCounter.set(feature,%20maxCounter.get(feature)%20+%201);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20maxCounter.get(feature);%0A%20%20%20%20%7D%0A%0A%20%20%20%20const%20DEBUG_MAX_TIMES%20=%205000;%0A%0A%20%20%20%20function%20postDebugMessage(feature,%20message,%20allowNonDebug%20=%20false)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!debug%20&&%20!allowNonDebug)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(numberOfTimesDebugged(feature)%20%3E%20DEBUG_MAX_TIMES)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(message.stack)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20scriptOrigins%20=%20%5B...getStackTraceOrigins(message.stack)%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20message.scriptOrigins%20=%20scriptOrigins;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20globalObj.postMessage(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20action:%20feature,%0A%20%20%20%20%20%20%20%20%20%20%20%20message,%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20let%20DDGReflect;%0A%20%20%20%20let%20DDGPromise;%0A%0A%20%20%20%20//%20Exports%20for%20usage%20where%20we%20have%20to%20cross%20the%20xray%20boundary:%20https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Sharing_objects_with_page_scripts%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20DDGPromise%20=%20globalObj.Promise;%0A%20%20%20%20%20%20%20%20DDGReflect%20=%20globalObj.Reflect;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7Bstring%20%7C%20null%7D%20topLevelHostname%0A%20%20%20%20%20*%20@param%20%7Bobject%5B%5D%7D%20featureList%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isUnprotectedDomain(topLevelHostname,%20featureList)%20%7B%0A%20%20%20%20%20%20%20%20let%20unprotectedDomain%20=%20false;%0A%20%20%20%20%20%20%20%20if%20(!topLevelHostname)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20const%20domainParts%20=%20topLevelHostname.split('.');%0A%0A%20%20%20%20%20%20%20%20//%20walk%20up%20the%20domain%20to%20see%20if%20it's%20unprotected%0A%20%20%20%20%20%20%20%20while%20(domainParts.length%20%3E%201%20&&%20!unprotectedDomain)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20partialDomain%20=%20domainParts.join('.');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20unprotectedDomain%20=%20featureList.filter((domain)%20=%3E%20domain.domain%20===%20partialDomain).length%20%3E%200;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20domainParts.shift();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20unprotectedDomain;%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20parseVersionString(versionString)%20%7B%0A%20%20%20%20%20%20%20%20return%20versionString.split('.').map(Number);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20minVersionString%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20applicationVersionString%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20satisfiesMinVersion(minVersionString,%20applicationVersionString)%20%7B%0A%20%20%20%20%20%20%20%20const%20minVersions%20=%20parseVersionString(minVersionString);%0A%20%20%20%20%20%20%20%20const%20currentVersions%20=%20parseVersionString(applicationVersionString);%0A%20%20%20%20%20%20%20%20const%20maxLength%20=%20Math.max(minVersions.length,%20currentVersions.length);%0A%20%20%20%20%20%20%20%20for%20(let%20i%20=%200;%20i%20%3C%20maxLength;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20minNumberPart%20=%20minVersions%5Bi%5D%20%7C%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20currentVersionPart%20=%20currentVersions%5Bi%5D%20%7C%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(currentVersionPart%20%3E%20minNumberPart)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(currentVersionPart%20%3C%20minNumberPart)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7Bstring%20%7C%20number%20%7C%20undefined%7D%20minSupportedVersion%0A%20%20%20%20%20*%20@param%20%7Bstring%20%7C%20number%20%7C%20undefined%7D%20currentVersion%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isSupportedVersion(minSupportedVersion,%20currentVersion)%20%7B%0A%20%20%20%20%20%20%20%20if%20(typeof%20currentVersion%20===%20'string'%20&&%20typeof%20minSupportedVersion%20===%20'string')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(satisfiesMinVersion(minSupportedVersion,%20currentVersion))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(typeof%20currentVersion%20===%20'number'%20&&%20typeof%20minSupportedVersion%20===%20'number')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(minSupportedVersion%20%3C=%20currentVersion)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Retutns%20a%20list%20of%20enabled%20features%0A%20%20%20%20%20*%20@param%20%7BRemoteConfig%7D%20data%0A%20%20%20%20%20*%20@param%20%7Bstring%20%7C%20null%7D%20topLevelHostname%0A%20%20%20%20%20*%20@param%20%7BPlatform%5B'version'%5D%7D%20platformVersion%0A%20%20%20%20%20*%20@param%20%7Bstring%5B%5D%7D%20platformSpecificFeatures%0A%20%20%20%20%20*%20@returns%20%7Bstring%5B%5D%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20computeEnabledFeatures(data,%20topLevelHostname,%20platformVersion,%20platformSpecificFeatures%20=%20%5B%5D)%20%7B%0A%20%20%20%20%20%20%20%20const%20remoteFeatureNames%20=%20Object.keys(data.features);%0A%20%20%20%20%20%20%20%20const%20platformSpecificFeaturesNotInRemoteConfig%20=%20platformSpecificFeatures.filter(%0A%20%20%20%20%20%20%20%20%20%20%20%20(featureName)%20=%3E%20!remoteFeatureNames.includes(featureName),%0A%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20const%20enabledFeatures%20=%20remoteFeatureNames%0A%20%20%20%20%20%20%20%20%20%20%20%20.filter((featureName)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20feature%20=%20data.features%5BfeatureName%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Check%20that%20the%20platform%20supports%20minSupportedVersion%20checks%20and%20that%20the%20feature%20has%20a%20minSupportedVersion%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(feature.minSupportedVersion%20&&%20platformVersion)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isSupportedVersion(feature.minSupportedVersion,%20platformVersion))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20feature.state%20===%20'enabled'%20&&%20!isUnprotectedDomain(topLevelHostname,%20feature.exceptions);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20%20%20%20%20%20%20.concat(platformSpecificFeaturesNotInRemoteConfig);%20//%20only%20disable%20platform%20specific%20features%20if%20it's%20explicitly%20disabled%20in%20remote%20config%0A%20%20%20%20%20%20%20%20return%20enabledFeatures;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Returns%20the%20relevant%20feature%20settings%20for%20the%20enabled%20features%0A%20%20%20%20%20*%20@param%20%7BRemoteConfig%7D%20data%0A%20%20%20%20%20*%20@param%20%7Bstring%5B%5D%7D%20enabledFeatures%0A%20%20%20%20%20*%20@returns%20%7BRecord%3Cstring,%20unknown%3E%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20parseFeatureSettings(data,%20enabledFeatures)%20%7B%0A%20%20%20%20%20%20%20%20/**%20@type%20%7BRecord%3Cstring,%20unknown%3E%7D%20*/%0A%20%20%20%20%20%20%20%20const%20featureSettings%20=%20%7B%7D;%0A%20%20%20%20%20%20%20%20const%20remoteFeatureNames%20=%20Object.keys(data.features);%0A%20%20%20%20%20%20%20%20remoteFeatureNames.forEach((featureName)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!enabledFeatures.includes(featureName))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20featureSettings%5BfeatureName%5D%20=%20data.features%5BfeatureName%5D.settings;%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20return%20featureSettings;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@import%20%7BFeatureName%7D%20from%20%22./features%22;%0A%20%20%20%20%20*%20@type%20%7BFeatureName%5B%5D%7D%0A%20%20%20%20%20*/%0A%20%20%20%20const%20platformSpecificFeatures%20=%20%5B'windowsPermissionUsage',%20'messageBridge'%5D;%0A%0A%20%20%20%20function%20isPlatformSpecificFeature(featureName)%20%7B%0A%20%20%20%20%20%20%20%20return%20platformSpecificFeatures.includes(featureName);%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20createCustomEvent(eventName,%20eventDetail)%20%7B%0A%0A%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20possibly%20null%0A%20%20%20%20%20%20%20%20return%20new%20OriginalCustomEvent(eventName,%20eventDetail);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%20@deprecated%20*/%0A%20%20%20%20function%20legacySendMessage(messageType,%20options)%20%7B%0A%20%20%20%20%20%20%20%20//%20FF%20&%20Chrome%0A%20%20%20%20%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20originalWindowDispatchEvent%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20originalWindowDispatchEvent(createCustomEvent('sendMessageProxy'%20+%20messageSecret,%20%7B%20detail:%20%7B%20messageType,%20options%20%7D%20%7D))%0A%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20//%20TBD%20other%20platforms%0A%20%20%20%20%7D%0A%0A%20%20%20%20const%20baseFeatures%20=%20/**%20@type%20%7Bconst%7D%20*/%20(%5B%0A%20%20%20%20%20%20%20%20'fingerprintingAudio',%0A%20%20%20%20%20%20%20%20'fingerprintingBattery',%0A%20%20%20%20%20%20%20%20'fingerprintingCanvas',%0A%20%20%20%20%20%20%20%20'googleRejected',%0A%20%20%20%20%20%20%20%20'gpc',%0A%20%20%20%20%20%20%20%20'fingerprintingHardware',%0A%20%20%20%20%20%20%20%20'referrer',%0A%20%20%20%20%20%20%20%20'fingerprintingScreenSize',%0A%20%20%20%20%20%20%20%20'fingerprintingTemporaryStorage',%0A%20%20%20%20%20%20%20%20'navigatorInterface',%0A%20%20%20%20%20%20%20%20'elementHiding',%0A%20%20%20%20%20%20%20%20'exceptionHandler',%0A%20%20%20%20%20%20%20%20'apiManipulation',%0A%20%20%20%20%5D);%0A%0A%20%20%20%20const%20otherFeatures%20=%20/**%20@type%20%7Bconst%7D%20*/%20(%5B%0A%20%20%20%20%20%20%20%20'clickToLoad',%0A%20%20%20%20%20%20%20%20'cookie',%0A%20%20%20%20%20%20%20%20'messageBridge',%0A%20%20%20%20%20%20%20%20'duckPlayer',%0A%20%20%20%20%20%20%20%20'harmfulApis',%0A%20%20%20%20%20%20%20%20'webCompat',%0A%20%20%20%20%20%20%20%20'windowsPermissionUsage',%0A%20%20%20%20%20%20%20%20'brokerProtection',%0A%20%20%20%20%20%20%20%20'performanceMetrics',%0A%20%20%20%20%20%20%20%20'breakageReporting',%0A%20%20%20%20%20%20%20%20'autofillPasswordImport',%0A%20%20%20%20%5D);%0A%0A%20%20%20%20/**%20@typedef%20%7BbaseFeatures%5Bnumber%5D%7CotherFeatures%5Bnumber%5D%7D%20FeatureName%20*/%0A%20%20%20%20/**%20@type%20%7BRecord%3Cstring,%20FeatureName%5B%5D%3E%7D%20*/%0A%20%20%20%20const%20platformSupport%20=%20%7B%0A%20%20%20%20%20%20%20%20apple:%20%5B'webCompat',%20...baseFeatures%5D,%0A%20%20%20%20%20%20%20%20'apple-isolated':%20%5B'duckPlayer',%20'brokerProtection',%20'performanceMetrics',%20'clickToLoad',%20'messageBridge'%5D,%0A%20%20%20%20%20%20%20%20android:%20%5B...baseFeatures,%20'webCompat',%20'clickToLoad',%20'breakageReporting',%20'duckPlayer'%5D,%0A%20%20%20%20%20%20%20%20'android-autofill-password-import':%20%5B'autofillPasswordImport'%5D,%0A%20%20%20%20%20%20%20%20windows:%20%5B'cookie',%20...baseFeatures,%20'windowsPermissionUsage',%20'duckPlayer',%20'brokerProtection',%20'breakageReporting'%5D,%0A%20%20%20%20%20%20%20%20firefox:%20%5B'cookie',%20...baseFeatures,%20'clickToLoad'%5D,%0A%20%20%20%20%20%20%20%20chrome:%20%5B'cookie',%20...baseFeatures,%20'clickToLoad'%5D,%0A%20%20%20%20%20%20%20%20'chrome-mv3':%20%5B'cookie',%20...baseFeatures,%20'clickToLoad'%5D,%0A%20%20%20%20%20%20%20%20integration:%20%5B...baseFeatures,%20...otherFeatures%5D,%0A%20%20%20%20%7D;%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Performance%20monitor,%20holds%20reference%20to%20PerformanceMark%20instances.%0A%20%20%20%20%20*/%0A%20%20%20%20class%20PerformanceMonitor%20%7B%0A%20%20%20%20%20%20%20%20constructor()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.marks%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Create%20performance%20marker%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20name%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPerformanceMark%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20mark(name)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20mark%20=%20new%20PerformanceMark(name);%0A%20%20%20%20%20%20%20%20%20%20%20%20this.marks.push(mark);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20mark;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Measure%20all%20performance%20markers%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20measureAll()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.marks.forEach((mark)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mark.measure();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Tiny%20wrapper%20around%20performance.mark%20and%20performance.measure%0A%20%20%20%20%20*/%0A%20%20%20%20//%20eslint-disable-next-line%20no-redeclare%0A%20%20%20%20class%20PerformanceMark%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20name%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(name)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.name%20=%20name;%0A%20%20%20%20%20%20%20%20%20%20%20%20performance.mark(this.name%20+%20'Start');%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20end()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20performance.mark(this.name%20+%20'End');%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20measure()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20performance.measure(this.name,%20this.name%20+%20'Start',%20this.name%20+%20'End');%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20Cookie%20%7B%0A%20%20%20%20%20%20%20%20constructor(cookieString)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.parts%20=%20cookieString.split(';');%0A%20%20%20%20%20%20%20%20%20%20%20%20this.parse();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20parse()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20EXTRACT_ATTRIBUTES%20=%20new%20Set(%5B'max-age',%20'expires',%20'domain'%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20this.attrIdx%20=%20%7B%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.parts.forEach((part,%20index)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20kv%20=%20part.split('=',%201);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20attribute%20=%20kv%5B0%5D.trim();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20value%20=%20part.slice(kv%5B0%5D.length%20+%201);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(index%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.name%20=%20attribute;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.value%20=%20value;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(EXTRACT_ATTRIBUTES.has(attribute.toLowerCase()))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this%5Battribute.toLowerCase()%5D%20=%20value;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Object%20is%20possibly%20'undefined'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.attrIdx%5Battribute.toLowerCase()%5D%20=%20index;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20getExpiry()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20expires%20is%20not%20defined%20in%20the%20type%20definition%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this.maxAge%20&&%20!this.expires)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20NaN;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20expiry%20=%20this.maxAge%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20?%20parseInt(this.maxAge)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20:%20//%20@ts-expect-error%20expires%20is%20not%20defined%20in%20the%20type%20definition%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(new%20Date(this.expires)%20-%20new%20Date())%20/%201000;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20expiry;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20get%20maxAge()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this%5B'max-age'%5D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20set%20maxAge(value)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Object%20is%20possibly%20'undefined'.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.attrIdx%5B'max-age'%5D%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Object%20is%20possibly%20'undefined'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.parts.splice(this.attrIdx%5B'max-age'%5D,%201,%20%60max-age=$%7Bvalue%7D%60);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.parts.push(%60max-age=$%7Bvalue%7D%60);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20this.parse();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20toString()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.parts.join(';');%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20isJSONArray(value)%20%7B%0A%20%20%20%20%20%20return%20Array.isArray(value);%0A%20%20%20%20%7D%0A%20%20%20%20function%20isJSONObject(value)%20%7B%0A%20%20%20%20%20%20return%20value%20!==%20null%20&&%20typeof%20value%20===%20'object'%20&&%20(value.constructor%20===%20undefined%20%7C%7C%0A%20%20%20%20%20%20//%20for%20example%20Object.create(null)%0A%20%20%20%20%20%20value.constructor.name%20===%20'Object')%20//%20do%20not%20match%20on%20classes%20or%20Array%0A%20%20%20%20%20%20;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Test%20deep%20equality%20of%20two%20JSON%20values,%20objects,%20or%20arrays%0A%20%20%20%20%20*/%0A%20%20%20%20//%20TODO:%20write%20unit%20tests%0A%20%20%20%20function%20isEqual(a,%20b)%20%7B%0A%20%20%20%20%20%20//%20FIXME:%20this%20function%20will%20return%20false%20for%20two%20objects%20with%20the%20same%20keys%0A%20%20%20%20%20%20//%20%20but%20different%20order%20of%20keys%0A%20%20%20%20%20%20return%20JSON.stringify(a)%20===%20JSON.stringify(b);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Get%20all%20but%20the%20last%20items%20from%20an%20array%0A%20%20%20%20%20*/%0A%20%20%20%20//%20TODO:%20write%20unit%20tests%0A%20%20%20%20function%20initial(array)%20%7B%0A%20%20%20%20%20%20return%20array.slice(0,%20array.length%20-%201);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Get%20the%20last%20item%20from%20an%20array%0A%20%20%20%20%20*/%0A%20%20%20%20//%20TODO:%20write%20unit%20tests%0A%20%20%20%20function%20last(array)%20%7B%0A%20%20%20%20%20%20return%20array%5Barray.length%20-%201%5D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Test%20whether%20a%20value%20is%20an%20Object%20or%20an%20Array%20(and%20not%20a%20primitive%20JSON%20value)%0A%20%20%20%20%20*/%0A%20%20%20%20//%20TODO:%20write%20unit%20tests%0A%20%20%20%20function%20isObjectOrArray(value)%20%7B%0A%20%20%20%20%20%20return%20typeof%20value%20===%20'object'%20&&%20value%20!==%20null;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Immutability%20helpers%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20inspiration:%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20https://www.npmjs.com/package/seamless-immutable%0A%20%20%20%20%20*%20https://www.npmjs.com/package/ih%0A%20%20%20%20%20*%20https://www.npmjs.com/package/mutatis%0A%20%20%20%20%20*%20https://github.com/mariocasciaro/object-path-immutable%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Shallow%20clone%20of%20an%20Object,%20Array,%20or%20value%0A%20%20%20%20%20*%20Symbols%20are%20cloned%20too.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20shallowClone(value)%20%7B%0A%20%20%20%20%20%20if%20(isJSONArray(value))%20%7B%0A%20%20%20%20%20%20%20%20//%20copy%20array%20items%0A%20%20%20%20%20%20%20%20const%20copy%20=%20value.slice();%0A%0A%20%20%20%20%20%20%20%20//%20copy%20all%20symbols%0A%20%20%20%20%20%20%20%20Object.getOwnPropertySymbols(value).forEach(symbol%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20%20%20%20%20copy%5Bsymbol%5D%20=%20value%5Bsymbol%5D;%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20return%20copy;%0A%20%20%20%20%20%20%7D%20else%20if%20(isJSONObject(value))%20%7B%0A%20%20%20%20%20%20%20%20//%20copy%20object%20properties%0A%20%20%20%20%20%20%20%20const%20copy%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20...value%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20//%20copy%20all%20symbols%0A%20%20%20%20%20%20%20%20Object.getOwnPropertySymbols(value).forEach(symbol%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20%20%20%20%20copy%5Bsymbol%5D%20=%20value%5Bsymbol%5D;%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20return%20copy;%0A%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20return%20value;%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Update%20a%20value%20in%20an%20object%20in%20an%20immutable%20way.%0A%20%20%20%20%20*%20If%20the%20value%20is%20unchanged,%20the%20original%20object%20will%20be%20returned%0A%20%20%20%20%20*/%0A%20%20%20%20function%20applyProp(object,%20key,%20value)%20%7B%0A%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20if%20(object%5Bkey%5D%20===%20value)%20%7B%0A%20%20%20%20%20%20%20%20//%20return%20original%20object%20unchanged%20when%20the%20new%20value%20is%20identical%20to%20the%20old%20one%0A%20%20%20%20%20%20%20%20return%20object;%0A%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20const%20updatedObject%20=%20shallowClone(object);%0A%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20%20%20updatedObject%5Bkey%5D%20=%20value;%0A%20%20%20%20%20%20%20%20return%20updatedObject;%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20helper%20function%20to%20get%20a%20nested%20property%20in%20an%20object%20or%20array%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@return%20Returns%20the%20field%20when%20found,%20or%20undefined%20when%20the%20path%20doesn't%20exist%0A%20%20%20%20%20*/%0A%20%20%20%20function%20getIn(object,%20path)%20%7B%0A%20%20%20%20%20%20let%20value%20=%20object;%0A%20%20%20%20%20%20let%20i%20=%200;%0A%20%20%20%20%20%20while%20(i%20%3C%20path.length)%20%7B%0A%20%20%20%20%20%20%20%20if%20(isJSONObject(value))%20%7B%0A%20%20%20%20%20%20%20%20%20%20value%20=%20value%5Bpath%5Bi%5D%5D;%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(isJSONArray(value))%20%7B%0A%20%20%20%20%20%20%20%20%20%20value%20=%20value%5BparseInt(path%5Bi%5D)%5D;%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20value%20=%20undefined;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20i++;%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20return%20value;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20helper%20function%20to%20replace%20a%20nested%20property%20in%20an%20object%20with%20a%20new%20value%0A%20%20%20%20%20*%20without%20mutating%20the%20object%20itself.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@param%20object%0A%20%20%20%20%20*%20@param%20path%0A%20%20%20%20%20*%20@param%20value%0A%20%20%20%20%20*%20@param%20%5BcreatePath=false%5D%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20If%20true,%20%60path%60%20will%20be%20created%20when%20(partly)%20missing%20in%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20the%20object.%20For%20correctly%20creating%20nested%20Arrays%20or%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Objects,%20the%20function%20relies%20on%20%60path%60%20containing%20number%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20in%20case%20of%20array%20indexes.%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20If%20false%20(default),%20an%20error%20will%20be%20thrown%20when%20the%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20path%20doesn't%20exist.%0A%20%20%20%20%20*%20@return%20Returns%20a%20new,%20updated%20object%20or%20array%0A%20%20%20%20%20*/%0A%20%20%20%20function%20setIn(object,%20path,%20value)%20%7B%0A%20%20%20%20%20%20let%20createPath%20=%20arguments.length%20%3E%203%20&&%20arguments%5B3%5D%20!==%20undefined%20?%20arguments%5B3%5D%20:%20false;%0A%20%20%20%20%20%20if%20(path.length%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20return%20value;%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20const%20key%20=%20path%5B0%5D;%0A%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20const%20updatedValue%20=%20setIn(object%20?%20object%5Bkey%5D%20:%20undefined,%20path.slice(1),%20value,%20createPath);%0A%20%20%20%20%20%20if%20(isJSONObject(object)%20%7C%7C%20isJSONArray(object))%20%7B%0A%20%20%20%20%20%20%20%20return%20applyProp(object,%20key,%20updatedValue);%0A%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20if%20(createPath)%20%7B%0A%20%20%20%20%20%20%20%20%20%20const%20newObject%20=%20IS_INTEGER_REGEX.test(key)%20?%20%5B%5D%20:%20%7B%7D;%0A%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20%20%20%20%20newObject%5Bkey%5D%20=%20updatedValue;%0A%20%20%20%20%20%20%20%20%20%20return%20newObject;%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('Path%20does%20not%20exist');%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20const%20IS_INTEGER_REGEX%20=%20/%5E%5Cd+$/;%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20helper%20function%20to%20replace%20a%20nested%20property%20in%20an%20object%20with%20a%20new%20value%0A%20%20%20%20%20*%20without%20mutating%20the%20object%20itself.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@return%20%20Returns%20a%20new,%20updated%20object%20or%20array%0A%20%20%20%20%20*/%0A%20%20%20%20function%20updateIn(object,%20path,%20transform)%20%7B%0A%20%20%20%20%20%20if%20(path.length%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20return%20transform(object);%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20if%20(!isObjectOrArray(object))%20%7B%0A%20%20%20%20%20%20%20%20throw%20new%20Error('Path%20doesn%5C't%20exist');%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20const%20key%20=%20path%5B0%5D;%0A%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20const%20updatedValue%20=%20updateIn(object%5Bkey%5D,%20path.slice(1),%20transform);%0A%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20return%20applyProp(object,%20key,%20updatedValue);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20helper%20function%20to%20delete%20a%20nested%20property%20in%20an%20object%0A%20%20%20%20%20*%20without%20mutating%20the%20object%20itself.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@return%20Returns%20a%20new,%20updated%20object%20or%20array%0A%20%20%20%20%20*/%0A%20%20%20%20function%20deleteIn(object,%20path)%20%7B%0A%20%20%20%20%20%20if%20(path.length%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20return%20object;%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20if%20(!isObjectOrArray(object))%20%7B%0A%20%20%20%20%20%20%20%20throw%20new%20Error('Path%20does%20not%20exist');%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20if%20(path.length%20===%201)%20%7B%0A%20%20%20%20%20%20%20%20const%20key%20=%20path%5B0%5D;%0A%20%20%20%20%20%20%20%20if%20(!(key%20in%20object))%20%7B%0A%20%20%20%20%20%20%20%20%20%20//%20key%20doesn't%20exist.%20return%20object%20unchanged%0A%20%20%20%20%20%20%20%20%20%20return%20object;%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20const%20updatedObject%20=%20shallowClone(object);%0A%20%20%20%20%20%20%20%20%20%20if%20(isJSONArray(updatedObject))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20updatedObject.splice(parseInt(key),%201);%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20if%20(isJSONObject(updatedObject))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20delete%20updatedObject%5Bkey%5D;%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20return%20updatedObject;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20const%20key%20=%20path%5B0%5D;%0A%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20const%20updatedValue%20=%20deleteIn(object%5Bkey%5D,%20path.slice(1));%0A%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20return%20applyProp(object,%20key,%20updatedValue);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Insert%20a%20new%20item%20in%20an%20array%20at%20a%20specific%20index.%0A%20%20%20%20%20*%20Example%20usage:%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%20%20%20%20insertAt(%7Barr:%20%5B1,2,3%5D%7D,%20%5B'arr',%20'2'%5D,%20'inserted')%20%20//%20%5B1,2,'inserted',3%5D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20insertAt(document,%20path,%20value)%20%7B%0A%20%20%20%20%20%20const%20parentPath%20=%20path.slice(0,%20path.length%20-%201);%0A%20%20%20%20%20%20const%20index%20=%20path%5Bpath.length%20-%201%5D;%0A%20%20%20%20%20%20return%20updateIn(document,%20parentPath,%20items%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20if%20(!Array.isArray(items))%20%7B%0A%20%20%20%20%20%20%20%20%20%20throw%20new%20TypeError('Array%20expected%20at%20path%20'%20+%20JSON.stringify(parentPath));%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20const%20updatedItems%20=%20shallowClone(items);%0A%20%20%20%20%20%20%20%20updatedItems.splice(parseInt(index),%200,%20value);%0A%20%20%20%20%20%20%20%20return%20updatedItems;%0A%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Test%20whether%20a%20path%20exists%20in%20a%20JSON%20object%0A%20%20%20%20%20*%20@return%20Returns%20true%20if%20the%20path%20exists,%20else%20returns%20false%0A%20%20%20%20%20*/%0A%20%20%20%20function%20existsIn(document,%20path)%20%7B%0A%20%20%20%20%20%20if%20(document%20===%20undefined)%20%7B%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20if%20(path.length%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20if%20(document%20===%20null)%20%7B%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20return%20existsIn(document%5Bpath%5B0%5D%5D,%20path.slice(1));%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Parse%20a%20JSON%20Pointer%0A%20%20%20%20%20*/%0A%20%20%20%20function%20parseJSONPointer(pointer)%20%7B%0A%20%20%20%20%20%20const%20path%20=%20pointer.split('/');%0A%20%20%20%20%20%20path.shift();%20//%20remove%20the%20first%20empty%20entry%0A%0A%20%20%20%20%20%20return%20path.map(p%20=%3E%20p.replace(/~1/g,%20'/').replace(/~0/g,%20'~'));%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Compile%20a%20JSON%20Pointer%0A%20%20%20%20%20*/%0A%20%20%20%20function%20compileJSONPointer(path)%20%7B%0A%20%20%20%20%20%20return%20path.map(compileJSONPointerProp).join('');%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Compile%20a%20single%20path%20property%20from%20a%20JSONPath%0A%20%20%20%20%20*/%0A%20%20%20%20function%20compileJSONPointerProp(pathProp)%20%7B%0A%20%20%20%20%20%20return%20'/'%20+%20String(pathProp).replace(/~/g,%20'~0').replace(/%5C//g,%20'~1');%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Apply%20a%20patch%20to%20a%20JSON%20object%0A%20%20%20%20%20*%20The%20original%20JSON%20object%20will%20not%20be%20changed,%0A%20%20%20%20%20*%20instead,%20the%20patch%20is%20applied%20in%20an%20immutable%20way%0A%20%20%20%20%20*/%0A%20%20%20%20function%20immutableJSONPatch(document,%20operations,%20options)%20%7B%0A%20%20%20%20%20%20let%20updatedDocument%20=%20document;%0A%20%20%20%20%20%20for%20(let%20i%20=%200;%20i%20%3C%20operations.length;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20validateJSONPatchOperation(operations%5Bi%5D);%0A%20%20%20%20%20%20%20%20let%20operation%20=%20operations%5Bi%5D;%0A%20%20%20%20%20%20%20%20const%20path%20=%20parsePath(updatedDocument,%20operation.path);%0A%20%20%20%20%20%20%20%20if%20(operation.op%20===%20'add')%20%7B%0A%20%20%20%20%20%20%20%20%20%20updatedDocument%20=%20add(updatedDocument,%20path,%20operation.value);%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(operation.op%20===%20'remove')%20%7B%0A%20%20%20%20%20%20%20%20%20%20updatedDocument%20=%20remove(updatedDocument,%20path);%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(operation.op%20===%20'replace')%20%7B%0A%20%20%20%20%20%20%20%20%20%20updatedDocument%20=%20replace(updatedDocument,%20path,%20operation.value);%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(operation.op%20===%20'copy')%20%7B%0A%20%20%20%20%20%20%20%20%20%20updatedDocument%20=%20copy(updatedDocument,%20path,%20parseFrom(operation.from));%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(operation.op%20===%20'move')%20%7B%0A%20%20%20%20%20%20%20%20%20%20updatedDocument%20=%20move(updatedDocument,%20path,%20parseFrom(operation.from));%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(operation.op%20===%20'test')%20%7B%0A%20%20%20%20%20%20%20%20%20%20test(updatedDocument,%20path,%20operation.value);%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('Unknown%20JSONPatch%20operation%20'%20+%20JSON.stringify(operation));%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20return%20updatedDocument;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Replace%20an%20existing%20item%0A%20%20%20%20%20*/%0A%20%20%20%20function%20replace(document,%20path,%20value)%20%7B%0A%20%20%20%20%20%20return%20setIn(document,%20path,%20value);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Remove%20an%20item%20or%20property%0A%20%20%20%20%20*/%0A%20%20%20%20function%20remove(document,%20path)%20%7B%0A%20%20%20%20%20%20return%20deleteIn(document,%20path);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Add%20an%20item%20or%20property%0A%20%20%20%20%20*/%0A%20%20%20%20function%20add(document,%20path,%20value)%20%7B%0A%20%20%20%20%20%20if%20(isArrayItem(document,%20path))%20%7B%0A%20%20%20%20%20%20%20%20return%20insertAt(document,%20path,%20value);%0A%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20return%20setIn(document,%20path,%20value);%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Copy%20a%20value%0A%20%20%20%20%20*/%0A%20%20%20%20function%20copy(document,%20path,%20from)%20%7B%0A%20%20%20%20%20%20const%20value%20=%20getIn(document,%20from);%0A%20%20%20%20%20%20if%20(isArrayItem(document,%20path))%20%7B%0A%20%20%20%20%20%20%20%20return%20insertAt(document,%20path,%20value);%0A%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20const%20value%20=%20getIn(document,%20from);%0A%20%20%20%20%20%20%20%20return%20setIn(document,%20path,%20value);%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Move%20a%20value%0A%20%20%20%20%20*/%0A%20%20%20%20function%20move(document,%20path,%20from)%20%7B%0A%20%20%20%20%20%20const%20value%20=%20getIn(document,%20from);%0A%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20const%20removedJson%20=%20deleteIn(document,%20from);%0A%20%20%20%20%20%20return%20isArrayItem(removedJson,%20path)%20?%20insertAt(removedJson,%20path,%20value)%20:%20setIn(removedJson,%20path,%20value);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Test%20whether%20the%20data%20contains%20the%20provided%20value%20at%20the%20specified%20path.%0A%20%20%20%20%20*%20Throws%20an%20error%20when%20the%20test%20fails%0A%20%20%20%20%20*/%0A%20%20%20%20function%20test(document,%20path,%20value)%20%7B%0A%20%20%20%20%20%20if%20(value%20===%20undefined)%20%7B%0A%20%20%20%20%20%20%20%20throw%20new%20Error(%60Test%20failed:%20no%20value%20provided%20(path:%20%22$%7BcompileJSONPointer(path)%7D%22)%60);%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20if%20(!existsIn(document,%20path))%20%7B%0A%20%20%20%20%20%20%20%20throw%20new%20Error(%60Test%20failed:%20path%20not%20found%20(path:%20%22$%7BcompileJSONPointer(path)%7D%22)%60);%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20const%20actualValue%20=%20getIn(document,%20path);%0A%20%20%20%20%20%20if%20(!isEqual(actualValue,%20value))%20%7B%0A%20%20%20%20%20%20%20%20throw%20new%20Error(%60Test%20failed,%20value%20differs%20(path:%20%22$%7BcompileJSONPointer(path)%7D%22)%60);%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20function%20isArrayItem(document,%20path)%20%7B%0A%20%20%20%20%20%20if%20(path.length%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20const%20parent%20=%20getIn(document,%20initial(path));%0A%20%20%20%20%20%20return%20Array.isArray(parent);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Resolve%20the%20path%20index%20of%20an%20array,%20resolves%20indexes%20'-'%0A%20%20%20%20%20*%20@returns%20Returns%20the%20resolved%20path%0A%20%20%20%20%20*/%0A%20%20%20%20function%20resolvePathIndex(document,%20path)%20%7B%0A%20%20%20%20%20%20if%20(last(path)%20!==%20'-')%20%7B%0A%20%20%20%20%20%20%20%20return%20path;%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20const%20parentPath%20=%20initial(path);%0A%20%20%20%20%20%20const%20parent%20=%20getIn(document,%20parentPath);%0A%0A%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20return%20parentPath.concat(parent.length);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Validate%20a%20JSONPatch%20operation.%0A%20%20%20%20%20*%20Throws%20an%20error%20when%20there%20is%20an%20issue%0A%20%20%20%20%20*/%0A%20%20%20%20function%20validateJSONPatchOperation(operation)%20%7B%0A%20%20%20%20%20%20//%20TODO:%20write%20unit%20tests%0A%20%20%20%20%20%20const%20ops%20=%20%5B'add',%20'remove',%20'replace',%20'copy',%20'move',%20'test'%5D;%0A%20%20%20%20%20%20if%20(!ops.includes(operation.op))%20%7B%0A%20%20%20%20%20%20%20%20throw%20new%20Error('Unknown%20JSONPatch%20op%20'%20+%20JSON.stringify(operation.op));%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20if%20(typeof%20operation.path%20!==%20'string')%20%7B%0A%20%20%20%20%20%20%20%20throw%20new%20Error('Required%20property%20%22path%22%20missing%20or%20not%20a%20string%20in%20operation%20'%20+%20JSON.stringify(operation));%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20if%20(operation.op%20===%20'copy'%20%7C%7C%20operation.op%20===%20'move')%20%7B%0A%20%20%20%20%20%20%20%20if%20(typeof%20operation.from%20!==%20'string')%20%7B%0A%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('Required%20property%20%22from%22%20missing%20or%20not%20a%20string%20in%20operation%20'%20+%20JSON.stringify(operation));%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20function%20parsePath(document,%20pointer)%20%7B%0A%20%20%20%20%20%20return%20resolvePathIndex(document,%20parseJSONPointer(pointer));%0A%20%20%20%20%7D%0A%20%20%20%20function%20parseFrom(fromPointer)%20%7B%0A%20%20%20%20%20%20return%20parseJSONPointer(fromPointer);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/*%20global%20false,%20cloneInto,%20exportFunction%20*/%0A%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Like%20Object.defineProperty,%20but%20with%20support%20for%20Firefox's%20mozProxies.%0A%20%20%20%20%20*%20@param%20%7Bany%7D%20object%20-%20object%20whose%20property%20we%20are%20wrapping%20(most%20commonly%20a%20prototype,%20e.g.%20globalThis.BatteryManager.prototype)%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20propertyName%0A%20%20%20%20%20*%20@param%20%7Bimport('./wrapper-utils').StrictPropertyDescriptor%7D%20descriptor%20-%20requires%20all%20descriptor%20options%20to%20be%20defined%20because%20we%20can't%20validate%20correctness%20based%20on%20TS%20types%0A%20%20%20%20%20*/%0A%20%20%20%20function%20defineProperty(object,%20propertyName,%20descriptor)%20%7B%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20objectDefineProperty(object,%20propertyName,%20descriptor);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20return%20a%20proxy%20to%20%60newFn%60%20that%20fakes%20.toString()%20and%20.toString.toString()%20to%20resemble%20the%20%60origFn%60.%0A%20%20%20%20%20*%20WARNING:%20do%20NOT%20proxy%20toString%20multiple%20times,%20as%20it%20will%20not%20work%20as%20expected.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@param%20%7B*%7D%20newFn%0A%20%20%20%20%20*%20@param%20%7B*%7D%20origFn%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BmockValue%5D%20-%20when%20provided,%20.toString()%20will%20return%20this%20value%0A%20%20%20%20%20*/%0A%20%20%20%20function%20wrapToString(newFn,%20origFn,%20mockValue)%20%7B%0A%20%20%20%20%20%20%20%20if%20(typeof%20newFn%20!==%20'function'%20%7C%7C%20typeof%20origFn%20!==%20'function')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20newFn;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20new%20Proxy(newFn,%20%7B%20get:%20toStringGetTrap(origFn,%20mockValue)%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20generate%20a%20proxy%20handler%20trap%20that%20fakes%20.toString()%20and%20.toString.toString()%20to%20resemble%20the%20%60targetFn%60.%0A%20%20%20%20%20*%20Note%20that%20it%20should%20be%20used%20as%20the%20get()%20trap.%0A%20%20%20%20%20*%20@param%20%7B*%7D%20targetFn%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BmockValue%5D%20-%20when%20provided,%20.toString()%20will%20return%20this%20value%0A%20%20%20%20%20*%20@returns%20%7B%20(target:%20any,%20prop:%20string,%20receiver:%20any)%20=%3E%20any%20%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20toStringGetTrap(targetFn,%20mockValue)%20%7B%0A%20%20%20%20%20%20%20%20//%20We%20wrap%20two%20levels%20deep%20to%20handle%20toString.toString()%20calls%0A%20%20%20%20%20%20%20%20return%20function%20get(target,%20prop,%20receiver)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(prop%20===%20'toString')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20origToString%20=%20Reflect.get(targetFn,%20'toString',%20targetFn);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20toStringProxy%20=%20new%20Proxy(origToString,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20argumentsList)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20only%20mock%20toString()%20when%20called%20on%20the%20proxy%20itself.%20If%20the%20method%20is%20applied%20to%20some%20other%20object,%20it%20should%20behave%20as%20a%20normal%20toString()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(thisArg%20===%20receiver)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(mockValue)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20mockValue;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20Reflect.apply(target,%20targetFn,%20argumentsList);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20Reflect.apply(target,%20thisArg,%20argumentsList);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get(target,%20prop,%20receiver)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20handle%20toString.toString()%20result%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(prop%20===%20'toString')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20origToStringToString%20=%20Reflect.get(origToString,%20'toString',%20origToString);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20toStringToStringProxy%20=%20new%20Proxy(origToStringToString,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20argumentsList)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(thisArg%20===%20toStringProxy)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20Reflect.apply(target,%20origToString,%20argumentsList);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20Reflect.apply(target,%20thisArg,%20argumentsList);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20toStringToStringProxy;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20Reflect.get(target,%20prop,%20receiver);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20toStringProxy;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20Reflect.get(target,%20prop,%20receiver);%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Wrap%20a%20%60get%60/%60set%60%20or%20%60value%60%20property%20descriptor.%20Only%20for%20data%20properties.%20For%20methods,%20use%20wrapMethod().%20For%20constructors,%20use%20wrapConstructor().%0A%20%20%20%20%20*%20@param%20%7Bany%7D%20object%20-%20object%20whose%20property%20we%20are%20wrapping%20(most%20commonly%20a%20prototype,%20e.g.%20globalThis.Screen.prototype)%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20propertyName%0A%20%20%20%20%20*%20@param%20%7BPartial%3CPropertyDescriptor%3E%7D%20descriptor%0A%20%20%20%20%20*%20@param%20%7Btypeof%20Object.defineProperty%7D%20definePropertyFn%20-%20function%20to%20use%20for%20defining%20the%20property%0A%20%20%20%20%20*%20@returns%20%7BPropertyDescriptor%7Cundefined%7D%20original%20property%20descriptor,%20or%20undefined%20if%20it's%20not%20found%0A%20%20%20%20%20*/%0A%20%20%20%20function%20wrapProperty(object,%20propertyName,%20descriptor,%20definePropertyFn)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!object)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%20@type%20%7BStrictPropertyDescriptor%7D%20*/%0A%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20we%20check%20for%20undefined%20below%0A%20%20%20%20%20%20%20%20const%20origDescriptor%20=%20getOwnPropertyDescriptor(object,%20propertyName);%0A%20%20%20%20%20%20%20%20if%20(!origDescriptor)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20this%20happens%20if%20the%20property%20is%20not%20implemented%20in%20the%20browser%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20('value'%20in%20origDescriptor%20&&%20'value'%20in%20descriptor)%20%7C%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20('get'%20in%20origDescriptor%20&&%20'get'%20in%20descriptor)%20%7C%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20('set'%20in%20origDescriptor%20&&%20'set'%20in%20descriptor)%0A%20%20%20%20%20%20%20%20)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20definePropertyFn(object,%20propertyName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20...origDescriptor,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20...descriptor,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20origDescriptor;%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20if%20the%20property%20is%20defined%20with%20get/set%20it%20must%20be%20wrapped%20with%20a%20get/set.%20If%20it's%20defined%20with%20a%20%60value%60,%20it%20must%20be%20wrapped%20with%20a%20%60value%60%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error(%60Property%20descriptor%20for%20$%7BpropertyName%7D%20may%20only%20include%20the%20following%20keys:%20$%7BobjectKeys(origDescriptor)%7D%60);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Wrap%20a%20method%20descriptor.%20Only%20for%20function%20properties.%20For%20data%20properties,%20use%20wrapProperty().%20For%20constructors,%20use%20wrapConstructor().%0A%20%20%20%20%20*%20@param%20%7Bany%7D%20object%20-%20object%20whose%20property%20we%20are%20wrapping%20(most%20commonly%20a%20prototype,%20e.g.%20globalThis.Bluetooth.prototype)%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20propertyName%0A%20%20%20%20%20*%20@param%20%7B(originalFn,%20...args)%20=%3E%20any%20%7D%20wrapperFn%20-%20wrapper%20function%20receives%20the%20original%20function%20as%20the%20first%20argument%0A%20%20%20%20%20*%20@param%20%7BDefinePropertyFn%7D%20definePropertyFn%20-%20function%20to%20use%20for%20defining%20the%20property%0A%20%20%20%20%20*%20@returns%20%7BPropertyDescriptor%7Cundefined%7D%20original%20property%20descriptor,%20or%20undefined%20if%20it's%20not%20found%0A%20%20%20%20%20*/%0A%20%20%20%20function%20wrapMethod(object,%20propertyName,%20wrapperFn,%20definePropertyFn)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!object)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%20@type%20%7BStrictPropertyDescriptor%7D%20*/%0A%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20we%20check%20for%20undefined%20below%0A%20%20%20%20%20%20%20%20const%20origDescriptor%20=%20getOwnPropertyDescriptor(object,%20propertyName);%0A%20%20%20%20%20%20%20%20if%20(!origDescriptor)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20this%20happens%20if%20the%20property%20is%20not%20implemented%20in%20the%20browser%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20we%20check%20for%20undefined%20below%0A%20%20%20%20%20%20%20%20const%20origFn%20=%20origDescriptor.value;%0A%20%20%20%20%20%20%20%20if%20(!origFn%20%7C%7C%20typeof%20origFn%20!==%20'function')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20method%20properties%20are%20expected%20to%20be%20defined%20with%20a%20%60value%60%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error(%60Property%20$%7BpropertyName%7D%20does%20not%20look%20like%20a%20method%60);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20newFn%20=%20wrapToString(function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20wrapperFn.call(this,%20origFn,%20...arguments);%0A%20%20%20%20%20%20%20%20%7D,%20origFn);%0A%0A%20%20%20%20%20%20%20%20definePropertyFn(object,%20propertyName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20...origDescriptor,%0A%20%20%20%20%20%20%20%20%20%20%20%20value:%20newFn,%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20return%20origDescriptor;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@template%20%7Bkeyof%20typeof%20globalThis%7D%20StandardInterfaceName%0A%20%20%20%20%20*%20@param%20%7BStandardInterfaceName%7D%20interfaceName%20-%20the%20name%20of%20the%20interface%20to%20shim%20(must%20be%20some%20known%20standard%20API,%20e.g.%20'MediaSession')%0A%20%20%20%20%20*%20@param%20%7Btypeof%20globalThis%5BStandardInterfaceName%5D%7D%20ImplClass%20-%20the%20class%20to%20use%20as%20the%20shim%20implementation%0A%20%20%20%20%20*%20@param%20%7BDefineInterfaceOptions%7D%20options%20-%20options%20for%20defining%20the%20interface%0A%20%20%20%20%20*%20@param%20%7BDefinePropertyFn%7D%20definePropertyFn%20-%20function%20to%20use%20for%20defining%20the%20property%0A%20%20%20%20%20*/%0A%20%20%20%20function%20shimInterface(interfaceName,%20ImplClass,%20options,%20definePropertyFn)%20%7B%0A%0A%20%20%20%20%20%20%20%20/**%20@type%20%7BDefineInterfaceOptions%7D%20*/%0A%20%20%20%20%20%20%20%20const%20defaultOptions%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20allowConstructorCall:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20disallowConstructor:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20constructorErrorMessage:%20'Illegal%20constructor',%0A%20%20%20%20%20%20%20%20%20%20%20%20wrapToString:%20true,%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20const%20fullOptions%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20interfaceDescriptorOptions:%20%7B%20writable:%20true,%20enumerable:%20false,%20configurable:%20true,%20value:%20ImplClass%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20...defaultOptions,%0A%20%20%20%20%20%20%20%20%20%20%20%20...options,%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20//%20In%20some%20cases%20we%20can%20get%20away%20without%20a%20full%20proxy,%20but%20in%20many%20cases%20below%20we%20need%20it.%0A%20%20%20%20%20%20%20%20//%20For%20example,%20we%20can't%20redefine%20%60prototype%60%20property%20on%20ES6%20classes.%0A%20%20%20%20%20%20%20%20//%20Se%20we%20just%20always%20wrap%20the%20class%20to%20make%20the%20code%20more%20maintaibnable%0A%0A%20%20%20%20%20%20%20%20/**%20@type%20%7BProxyHandler%3CFunction%3E%7D%20*/%0A%20%20%20%20%20%20%20%20const%20proxyHandler%20=%20%7B%7D;%0A%0A%20%20%20%20%20%20%20%20//%20handle%20the%20case%20where%20the%20constructor%20is%20called%20without%20new%0A%20%20%20%20%20%20%20%20if%20(fullOptions.allowConstructorCall)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20make%20the%20constructor%20function%20callable%20without%20new%0A%20%20%20%20%20%20%20%20%20%20%20%20proxyHandler.apply%20=%20function%20(target,%20thisArg,%20argumentsList)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20Reflect.construct(target,%20argumentsList,%20target);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20make%20the%20constructor%20function%20throw%20when%20called%20without%20new%0A%20%20%20%20%20%20%20%20if%20(fullOptions.disallowConstructor)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20proxyHandler.construct%20=%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20TypeError(fullOptions.constructorErrorMessage);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if%20(fullOptions.wrapToString)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20mask%20toString()%20on%20class%20methods.%20%60ImplClass.prototype%60%20is%20non-configurable:%20we%20can't%20override%20or%20proxy%20it,%20so%20we%20have%20to%20wrap%20each%20method%20individually%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20%5Bprop,%20descriptor%5D%20of%20objectEntries(getOwnPropertyDescriptors(ImplClass.prototype)))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(prop%20!==%20'constructor'%20&&%20descriptor.writable%20&&%20typeof%20descriptor.value%20===%20'function')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ImplClass.prototype%5Bprop%5D%20=%20new%20Proxy(descriptor.value,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20toStringGetTrap(descriptor.value,%20%60function%20$%7Bprop%7D()%20%7B%20%5Bnative%20code%5D%20%7D%60),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20wrap%20toString%20on%20the%20constructor%20function%20itself%0A%20%20%20%20%20%20%20%20%20%20%20%20Object.assign(proxyHandler,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20toStringGetTrap(ImplClass,%20%60function%20$%7BinterfaceName%7D()%20%7B%20%5Bnative%20code%5D%20%7D%60),%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Note%20that%20instanceof%20should%20still%20work,%20since%20the%20%60.prototype%60%20object%20is%20proxied%20too:%0A%20%20%20%20%20%20%20%20//%20Interface()%20instanceof%20Interface%20===%20true%0A%20%20%20%20%20%20%20%20//%20ImplClass()%20instanceof%20Interface%20===%20true%0A%20%20%20%20%20%20%20%20const%20Interface%20=%20new%20Proxy(ImplClass,%20proxyHandler);%0A%0A%20%20%20%20%20%20%20%20//%20Make%20sure%20that%20Interface().constructor%20===%20Interface%20(not%20ImplClass)%0A%20%20%20%20%20%20%20%20if%20(ImplClass.prototype?.constructor%20===%20ImplClass)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7BStrictDataDescriptor%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20As%20long%20as%20ImplClass%20is%20a%20normal%20class,%20it%20should%20have%20the%20prototype%20property%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20descriptor%20=%20getOwnPropertyDescriptor(ImplClass.prototype,%20'constructor');%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(descriptor.writable)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ImplClass.prototype.constructor%20=%20Interface;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20mock%20the%20name%20property%0A%20%20%20%20%20%20%20%20definePropertyFn(ImplClass,%20'name',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20value:%20interfaceName,%0A%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20writable:%20false,%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20//%20interfaces%20are%20exposed%20directly%20on%20the%20global%20object,%20not%20on%20its%20prototype%0A%20%20%20%20%20%20%20%20definePropertyFn(globalThis,%20interfaceName,%20%7B%20...fullOptions.interfaceDescriptorOptions,%20value:%20Interface%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Define%20a%20missing%20standard%20property%20on%20a%20global%20(prototype)%20object.%20Only%20for%20data%20properties.%0A%20%20%20%20%20*%20For%20constructors,%20use%20shimInterface().%0A%20%20%20%20%20*%20Most%20of%20the%20time,%20you'd%20want%20to%20call%20shimInterface()%20first%20to%20shim%20the%20class%20itself%20(MediaSession),%20and%20then%20shimProperty()%20for%20the%20global%20singleton%20instance%20(Navigator.prototype.mediaSession).%0A%20%20%20%20%20*%20@template%20Base%0A%20%20%20%20%20*%20@template%20%7Bkeyof%20Base%20&%20string%7D%20K%0A%20%20%20%20%20*%20@param%20%7BBase%7D%20baseObject%20-%20object%20whose%20property%20we%20are%20shimming%20(most%20commonly%20a%20prototype%20object,%20e.g.%20Navigator.prototype)%0A%20%20%20%20%20*%20@param%20%7BK%7D%20propertyName%20-%20name%20of%20the%20property%20to%20shim%20(e.g.%20'mediaSession')%0A%20%20%20%20%20*%20@param%20%7BBase%5BK%5D%7D%20implInstance%20-%20instance%20to%20use%20as%20the%20shim%20(e.g.%20new%20MyMediaSession())%0A%20%20%20%20%20*%20@param%20%7Bboolean%7D%20readOnly%20-%20whether%20the%20property%20should%20be%20read-only%0A%20%20%20%20%20*%20@param%20%7BDefinePropertyFn%7D%20definePropertyFn%20-%20function%20to%20use%20for%20defining%20the%20property%0A%20%20%20%20%20*/%0A%20%20%20%20function%20shimProperty(baseObject,%20propertyName,%20implInstance,%20readOnly,%20definePropertyFn)%20%7B%0A%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20implInstance%20is%20a%20class%20instance%0A%20%20%20%20%20%20%20%20const%20ImplClass%20=%20implInstance.constructor;%0A%0A%20%20%20%20%20%20%20%20//%20mask%20toString()%20and%20toString.toString()%20on%20the%20instance%0A%20%20%20%20%20%20%20%20const%20proxiedInstance%20=%20new%20Proxy(implInstance,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20get:%20toStringGetTrap(implInstance,%20%60%5Bobject%20$%7BImplClass.name%7D%5D%60),%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20/**%20@type%20%7BStrictPropertyDescriptor%7D%20*/%0A%20%20%20%20%20%20%20%20let%20descriptor;%0A%0A%20%20%20%20%20%20%20%20//%20Note%20that%20we%20only%20cover%20most%20common%20cases:%20a%20getter%20for%20%22readonly%22%20properties,%20and%20a%20value%20descriptor%20for%20writable%20properties.%0A%20%20%20%20%20%20%20%20//%20But%20there%20could%20be%20other%20cases,%20e.g.%20a%20property%20with%20both%20a%20getter%20and%20a%20setter.%20These%20could%20be%20defined%20with%20a%20raw%20defineProperty()%20call.%0A%20%20%20%20%20%20%20%20//%20Important:%20make%20sure%20to%20cover%20each%20new%20shim%20with%20a%20test%20that%20verifies%20that%20all%20descriptors%20match%20the%20standard%20API.%0A%20%20%20%20%20%20%20%20if%20(readOnly)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20getter%20=%20function%20get()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20proxiedInstance;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20proxiedGetter%20=%20new%20Proxy(getter,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20toStringGetTrap(getter,%20%60function%20get%20$%7BpropertyName%7D()%20%7B%20%5Bnative%20code%5D%20%7D%60),%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20descriptor%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20proxiedGetter,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20descriptor%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20writable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value:%20proxiedInstance,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20definePropertyFn(baseObject,%20propertyName,%20descriptor);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@callback%20DefinePropertyFn%0A%20%20%20%20%20*%20@param%20%7Bobject%7D%20baseObj%0A%20%20%20%20%20*%20@param%20%7BPropertyKey%7D%20propertyName%0A%20%20%20%20%20*%20@param%20%7BStrictPropertyDescriptor%7D%20descriptor%0A%20%20%20%20%20*%20@returns%20%7Bobject%7D%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7BObject%7D%20BaseStrictPropertyDescriptor%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20configurable%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20enumerable%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7BBaseStrictPropertyDescriptor%20&%20%7B%20value:%20any;%20writable:%20boolean%20%7D%7D%20StrictDataDescriptor%0A%20%20%20%20%20*%20@typedef%20%7BBaseStrictPropertyDescriptor%20&%20%7B%20get:%20()%20=%3E%20any;%20set:%20(v:%20any)%20=%3E%20void%20%7D%7D%20StrictAccessorDescriptor%0A%20%20%20%20%20*%20@typedef%20%7BBaseStrictPropertyDescriptor%20&%20%7B%20get:%20()%20=%3E%20any%20%7D%7D%20StrictGetDescriptor%0A%20%20%20%20%20*%20@typedef%20%7BBaseStrictPropertyDescriptor%20&%20%7B%20set:%20(v:%20any)%20=%3E%20void%20%7D%7D%20StrictSetDescriptor%0A%20%20%20%20%20*%20@typedef%20%7BStrictDataDescriptor%20%7C%20StrictAccessorDescriptor%20%7C%20StrictGetDescriptor%20%7C%20StrictSetDescriptor%7D%20StrictPropertyDescriptor%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7BObject%7D%20BaseDefineInterfaceOptions%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20%5BconstructorErrorMessage%5D%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20wrapToString%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7B%7B%20allowConstructorCall:%20true;%20disallowConstructor:%20false%20%7D%7D%20DefineInterfaceOptionsWithAllowConstructorCallMixin%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7B%7B%20allowConstructorCall:%20false;%20disallowConstructor:%20true%20%7D%7D%20DefineInterfaceOptionsWithDisallowConstructorMixin%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7B%7B%20allowConstructorCall:%20false;%20disallowConstructor:%20false%20%7D%7D%20DefineInterfaceOptionsDefaultMixin%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7BBaseDefineInterfaceOptions%20&%20(DefineInterfaceOptionsWithAllowConstructorCallMixin%20%7C%20DefineInterfaceOptionsWithDisallowConstructorMixin%20%7C%20DefineInterfaceOptionsDefaultMixin)%7D%20DefineInterfaceOptions%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20A%20wrapper%20for%20messaging%20on%20Windows.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20This%20requires%203%20methods%20to%20be%20available,%20see%20%7B@link%20WindowsMessagingConfig%7D%20for%20details%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@document%20messaging/lib/examples/windows.example.js%0A%20%20%20%20%20*%0A%20%20%20%20%20*/%0A%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/no-unused-vars%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20An%20implementation%20of%20%7B@link%20MessagingTransport%7D%20for%20Windows%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20All%20messages%20go%20through%20%60window.chrome.webview%60%20APIs%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@implements%20%7BMessagingTransport%7D%0A%20%20%20%20%20*/%0A%20%20%20%20class%20WindowsMessagingTransport%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BWindowsMessagingConfig%7D%20config%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../index.js').MessagingContext%7D%20messagingContext%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(config,%20messagingContext)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messagingContext%20=%20messagingContext;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.config%20=%20config;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.globals%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20window,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20JSONparse:%20window.JSON.parse,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20JSONstringify:%20window.JSON.stringify,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Promise:%20window.Promise,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Error:%20window.Error,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20String:%20window.String,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20%5BmethodName,%20fn%5D%20of%20Object.entries(this.config.methods))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20fn%20!==%20'function')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('cannot%20create%20WindowsMessagingTransport,%20missing%20the%20method:%20'%20+%20methodName);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../index.js').NotificationMessage%7D%20msg%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20notify(msg)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20data%20=%20this.globals.JSONparse(this.globals.JSONstringify(msg.params%20%7C%7C%20%7B%7D));%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20notification%20=%20WindowsNotification.fromNotification(msg,%20data);%0A%20%20%20%20%20%20%20%20%20%20%20%20this.config.methods.postMessage(notification);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../index.js').RequestMessage%7D%20msg%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B%7Bsignal?:%20AbortSignal%7D%7D%20opts%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7BPromise%3Cany%3E%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20request(msg,%20opts%20=%20%7B%7D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20convert%20the%20message%20to%20window-specific%20naming%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20data%20=%20this.globals.JSONparse(this.globals.JSONstringify(msg.params%20%7C%7C%20%7B%7D));%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20outgoing%20=%20WindowsRequestMessage.fromRequest(msg,%20data);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20send%20the%20message%0A%20%20%20%20%20%20%20%20%20%20%20%20this.config.methods.postMessage(outgoing);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20compare%20incoming%20messages%20against%20the%20%60msg.id%60%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20comparator%20=%20(eventData)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20eventData.featureName%20===%20msg.featureName%20&&%20eventData.context%20===%20msg.context%20&&%20eventData.id%20===%20msg.id;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20data%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7Bdata%20is%20import('../index.js').MessageResponse%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20isMessageResponse(data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('result'%20in%20data)%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('error'%20in%20data)%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20now%20wait%20for%20a%20matching%20message%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20this.globals.Promise((resolve,%20reject)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._subscribe(comparator,%20opts,%20(value,%20unsubscribe)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unsubscribe();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isMessageResponse(value))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.warn('unknown%20response%20type',%20value);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20reject(new%20this.globals.Error('unknown%20response'));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(value.result)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20resolve(value.result);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20message%20=%20this.globals.String(value.error?.message%20%7C%7C%20'unknown%20error');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20reject(new%20this.globals.Error(message));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20reject(e);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../index.js').Subscription%7D%20msg%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(value:%20unknown%20%7C%20undefined)%20=%3E%20void%7D%20callback%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20subscribe(msg,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20compare%20incoming%20messages%20against%20the%20%60msg.subscriptionName%60%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20comparator%20=%20(eventData)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20eventData.featureName%20===%20msg.featureName%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20eventData.context%20===%20msg.context%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20eventData.subscriptionName%20===%20msg.subscriptionName%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20only%20forward%20the%20'params'%20from%20a%20SubscriptionEvent%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cb%20=%20(eventData)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20callback(eventData.params);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20now%20listen%20for%20matching%20incoming%20messages.%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this._subscribe(comparator,%20%7B%7D,%20cb);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@typedef%20%7Bimport('../index.js').MessageResponse%20%7C%20import('../index.js').SubscriptionEvent%7D%20Incoming%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(eventData:%20any)%20=%3E%20boolean%7D%20comparator%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B%7Bsignal?:%20AbortSignal%7D%7D%20options%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(value:%20Incoming,%20unsubscribe:%20(()=%3Evoid))%20=%3E%20void%7D%20callback%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_subscribe(comparator,%20options,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20if%20already%20aborted,%20reject%20immediately%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(options?.signal?.aborted)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20DOMException('Aborted',%20'AbortError');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7B(()=%3Evoid)%20%7C%20undefined%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20prefer-const%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20teardown;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BMessageEvent%7D%20event%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20idHandler%20=%20(event)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.messagingContext.env%20===%20'production')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(event.origin%20!==%20null%20&&%20event.origin%20!==%20undefined)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.warn('ignoring%20because%20evt.origin%20is%20not%20%60null%60%20or%20%60undefined%60');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!event.data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.warn('data%20absent%20from%20message');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(comparator(event.data))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!teardown)%20throw%20new%20Error('unreachable');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20callback(event.data,%20teardown);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20what%20to%20do%20if%20this%20promise%20is%20aborted%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20abortHandler%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20teardown?.();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20DOMException('Aborted',%20'AbortError');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20console.log('DEBUG:%20handler%20setup',%20%7B%20config,%20comparator%20%7D)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.config.methods.addEventListener('message',%20idHandler);%0A%20%20%20%20%20%20%20%20%20%20%20%20options?.signal?.addEventListener('abort',%20abortHandler);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20teardown%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20console.log('DEBUG:%20handler%20teardown',%20%7B%20config,%20comparator%20%7D)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.config.methods.removeEventListener('message',%20idHandler);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20options?.signal?.removeEventListener('abort',%20abortHandler);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20teardown?.();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20To%20construct%20this%20configuration%20object,%20you%20need%20access%20to%203%20methods%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20-%20%60postMessage%60%0A%20%20%20%20%20*%20-%20%60addEventListener%60%0A%20%20%20%20%20*%20-%20%60removeEventListener%60%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20These%20would%20normally%20be%20available%20on%20Windows%20via%20the%20following:%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20-%20%60window.chrome.webview.postMessage%60%0A%20%20%20%20%20*%20-%20%60window.chrome.webview.addEventListener%60%0A%20%20%20%20%20*%20-%20%60window.chrome.webview.removeEventListener%60%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20Depending%20on%20where%20the%20script%20is%20running,%20we%20may%20want%20to%20restrict%20access%20to%20those%20globals.%20On%20the%20native%0A%20%20%20%20%20*%20side%20those%20handlers%20%60window.chrome.webview%60%20handlers%20might%20be%20deleted%20and%20replaces%20with%20in-scope%20variables,%20such%20as:%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%5BExample%5D(./examples/windows.example.js)%0A%20%20%20%20%20*%0A%20%20%20%20%20*/%0A%20%20%20%20class%20WindowsMessagingConfig%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BWindowsInteropMethods%7D%20params.methods%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20methods%20required%20for%20communication%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.methods%20=%20params.methods;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7B'windows'%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.platform%20=%20'windows';%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20This%20data%20type%20represents%20a%20message%20sent%20to%20the%20Windows%0A%20%20%20%20%20*%20platform%20via%20%60window.chrome.webview.postMessage%60.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20**NOTE**:%20This%20is%20sent%20when%20a%20response%20is%20*not*%20expected%0A%20%20%20%20%20*/%0A%20%20%20%20class%20WindowsNotification%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.Feature%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.SubFeatureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.Name%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bparams.Data%5D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Alias%20for:%20%7B@link%20NotificationMessage.context%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.Feature%20=%20params.Feature;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Alias%20for:%20%7B@link%20NotificationMessage.featureName%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.SubFeatureName%20=%20params.SubFeatureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Alias%20for:%20%7B@link%20NotificationMessage.method%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.Name%20=%20params.Name;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Alias%20for:%20%7B@link%20NotificationMessage.params%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.Data%20=%20params.Data;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Helper%20to%20convert%20a%20%7B@link%20NotificationMessage%7D%20to%20a%20format%20that%20Windows%20can%20support%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BNotificationMessage%7D%20notification%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BWindowsNotification%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20fromNotification(notification,%20data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7BWindowsNotification%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20output%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Data:%20data,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Feature:%20notification.context,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20SubFeatureName:%20notification.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Name:%20notification.method,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20output;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20This%20data%20type%20represents%20a%20message%20sent%20to%20the%20Windows%0A%20%20%20%20%20*%20platform%20via%20%60window.chrome.webview.postMessage%60%20when%20it%0A%20%20%20%20%20*%20expects%20a%20response%0A%20%20%20%20%20*/%0A%20%20%20%20class%20WindowsRequestMessage%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.Feature%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.SubFeatureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.Name%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bparams.Data%5D%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5Bparams.Id%5D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.Feature%20=%20params.Feature;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.SubFeatureName%20=%20params.SubFeatureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.Name%20=%20params.Name;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.Data%20=%20params.Data;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.Id%20=%20params.Id;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Helper%20to%20convert%20a%20%7B@link%20RequestMessage%7D%20to%20a%20format%20that%20Windows%20can%20support%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRequestMessage%7D%20msg%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20data%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BWindowsRequestMessage%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20fromRequest(msg,%20data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7BWindowsRequestMessage%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20output%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Data:%20data,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Feature:%20msg.context,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20SubFeatureName:%20msg.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Name:%20msg.method,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Id:%20msg.id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20output;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20These%20are%20all%20the%20shared%20data%20types%20used%20throughout.%20Transports%20receive%20these%20types%20and%0A%20%20%20%20%20*%20can%20choose%20how%20to%20deliver%20the%20message%20to%20their%20respective%20native%20platforms.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20-%20Notifications%20via%20%7B@link%20NotificationMessage%7D%0A%20%20%20%20%20*%20-%20Request%20-%3E%20Response%20via%20%7B@link%20RequestMessage%7D%20and%20%7B@link%20MessageResponse%7D%0A%20%20%20%20%20*%20-%20Subscriptions%20via%20%7B@link%20Subscription%7D%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20Note:%20For%20backwards%20compatibility,%20some%20platforms%20may%20alter%20the%20data%20shape%20within%20the%20transport.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@module%20Messaging%20Schema%0A%20%20%20%20%20*%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20This%20is%20the%20format%20of%20an%20outgoing%20message.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20-%20See%20%7B@link%20MessageResponse%7D%20for%20what's%20expected%20in%20a%20response%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20**NOTE**:%0A%20%20%20%20%20*%20-%20Windows%20will%20alter%20this%20before%20it's%20sent,%20see:%20%7B@link%20Messaging.WindowsRequestMessage%7D%0A%20%20%20%20%20*/%0A%20%20%20%20class%20RequestMessage%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.context%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.method%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.id%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bparams.params%5D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20global%20context%20for%20this%20message.%20For%20example,%20something%20like%20%60contentScopeScripts%60%20or%20%60specialPages%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7Bstring%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.context%20=%20params.context;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20name%20of%20the%20sub-feature,%20such%20as%20%60duckPlayer%60%20or%20%60clickToLoad%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7Bstring%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20name%20of%20the%20handler%20to%20be%20executed%20on%20the%20native%20side%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.method%20=%20params.method;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20%60id%60%20that%20native%20sides%20can%20use%20when%20sending%20back%20a%20response%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.id%20=%20params.id;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Optional%20data%20payload%20-%20must%20be%20a%20plain%20key/value%20object%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.params%20=%20params.params;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20**NOTE**:%0A%20%20%20%20%20*%20-%20Windows%20will%20alter%20this%20before%20it's%20sent,%20see:%20%7B@link%20Messaging.WindowsNotification%7D%0A%20%20%20%20%20*/%0A%20%20%20%20class%20NotificationMessage%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.context%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.method%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bparams.params%5D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20global%20context%20for%20this%20message.%20For%20example,%20something%20like%20%60contentScopeScripts%60%20or%20%60specialPages%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.context%20=%20params.context;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20name%20of%20the%20sub-feature,%20such%20as%20%60duckPlayer%60%20or%20%60clickToLoad%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20name%20of%20the%20handler%20to%20be%20executed%20on%20the%20native%20side%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.method%20=%20params.method;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20An%20optional%20payload%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.params%20=%20params.params;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20Subscription%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.context%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.subscriptionName%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.context%20=%20params.context;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.subscriptionName%20=%20params.subscriptionName;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7BRequestMessage%7D%20request%0A%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20data%0A%20%20%20%20%20*%20@return%20%7Bdata%20is%20MessageResponse%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isResponseFor(request,%20data)%20%7B%0A%20%20%20%20%20%20%20%20if%20('result'%20in%20data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20data.featureName%20===%20request.featureName%20&&%20data.context%20===%20request.context%20&&%20data.id%20===%20request.id;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20('error'%20in%20data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20('message'%20in%20data.error)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7BSubscription%7D%20sub%0A%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20data%0A%20%20%20%20%20*%20@return%20%7Bdata%20is%20SubscriptionEvent%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isSubscriptionEventFor(sub,%20data)%20%7B%0A%20%20%20%20%20%20%20%20if%20('subscriptionName'%20in%20data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20data.featureName%20===%20sub.featureName%20&&%20data.context%20===%20sub.context%20&&%20data.subscriptionName%20===%20sub.subscriptionName;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20A%20wrapper%20for%20messaging%20on%20WebKit%20platforms.%20It%20supports%20modern%20WebKit%20messageHandlers%0A%20%20%20%20%20*%20along%20with%20encryption%20for%20older%20versions%20(like%20macOS%20Catalina)%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20Note:%20If%20you%20wish%20to%20support%20Catalina%20then%20you'll%20need%20to%20implement%20the%20native%0A%20%20%20%20%20*%20part%20of%20the%20message%20handling,%20see%20%7B@link%20WebkitMessagingTransport%7D%20for%20details.%0A%20%20%20%20%20*/%0A%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/no-unused-vars%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@example%0A%20%20%20%20%20*%20On%20macOS%2011+,%20this%20will%20just%20call%20through%20to%20%60window.webkit.messageHandlers.x.postMessage%60%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20Eg:%20for%20a%20%60foo%60%20message%20defined%20in%20Swift%20that%20accepted%20the%20payload%20%60%7B%22bar%22:%20%22baz%22%7D%60,%20the%20following%0A%20%20%20%20%20*%20would%20occur:%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%60%60%60js%0A%20%20%20%20%20*%20const%20json%20=%20await%20window.webkit.messageHandlers.foo.postMessage(%7B%20bar:%20%22baz%22%20%7D);%0A%20%20%20%20%20*%20const%20response%20=%20JSON.parse(json)%0A%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@example%0A%20%20%20%20%20*%20On%20macOS%2010%20however,%20the%20process%20is%20a%20little%20more%20involved.%20A%20method%20will%20be%20appended%20to%20%60window%60%0A%20%20%20%20%20*%20that%20allows%20the%20response%20to%20be%20delivered%20there%20instead.%20It's%20not%20exactly%20this,%20but%20you%20can%20visualize%20the%20flow%0A%20%20%20%20%20*%20as%20being%20something%20along%20the%20lines%20of:%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%60%60%60js%0A%20%20%20%20%20*%20//%20add%20the%20window%20method%0A%20%20%20%20%20*%20window%5B%22_0123456%22%5D%20=%20(response)%20=%3E%20%7B%0A%20%20%20%20%20*%20%20%20%20//%20decrypt%20%60response%60%20and%20deliver%20the%20result%20to%20the%20caller%20here%0A%20%20%20%20%20*%20%20%20%20//%20then%20remove%20the%20temporary%20method%0A%20%20%20%20%20*%20%20%20%20delete%20window%5B'_0123456'%5D%0A%20%20%20%20%20*%20%7D;%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20//%20send%20the%20data%20+%20%60messageHanding%60%20values%0A%20%20%20%20%20*%20window.webkit.messageHandlers.foo.postMessage(%7B%0A%20%20%20%20%20*%20%20%20bar:%20%22baz%22,%0A%20%20%20%20%20*%20%20%20messagingHandling:%20%7B%0A%20%20%20%20%20*%20%20%20%20%20methodName:%20%22_0123456%22,%0A%20%20%20%20%20*%20%20%20%20%20secret:%20%22super-secret%22,%0A%20%20%20%20%20*%20%20%20%20%20key:%20%5B1,%202,%2045,%202%5D,%0A%20%20%20%20%20*%20%20%20%20%20iv:%20%5B34,%204,%2043%5D,%0A%20%20%20%20%20*%20%20%20%7D%0A%20%20%20%20%20*%20%7D);%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20//%20later%20in%20swift,%20the%20following%20JavaScript%20snippet%20will%20be%20executed%0A%20%20%20%20%20*%20(()%20=%3E%20%7B%0A%20%20%20%20%20*%20%20%20window%5B'_0123456'%5D(%7B%0A%20%20%20%20%20*%20%20%20%20%20ciphertext:%20%5B12,%2013,%204%5D,%0A%20%20%20%20%20*%20%20%20%20%20tag:%20%5B3,%205,%2067,%2056%5D%0A%20%20%20%20%20*%20%20%20%7D)%0A%20%20%20%20%20*%20%7D)()%0A%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20*%20@implements%20%7BMessagingTransport%7D%0A%20%20%20%20%20*/%0A%20%20%20%20class%20WebkitMessagingTransport%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BWebkitMessagingConfig%7D%20config%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../index.js').MessagingContext%7D%20messagingContext%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(config,%20messagingContext)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messagingContext%20=%20messagingContext;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.config%20=%20config;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.globals%20=%20captureGlobals();%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this.config.hasModernWebkitAPI)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.captureWebkitHandlers(this.config.webkitMessageHandlerNames);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Sends%20message%20to%20the%20webkit%20layer%20(fire%20and%20forget)%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BString%7D%20handler%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B*%7D%20data%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20wkSend(handler,%20data%20=%20%7B%7D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!(handler%20in%20this.globals.window.webkit.messageHandlers))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20MissingHandler(%60Missing%20webkit%20handler:%20'$%7Bhandler%7D'%60,%20handler);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this.config.hasModernWebkitAPI)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20outgoing%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20...data,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20messageHandling:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20...data.messageHandling,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20secret:%20this.config.secret,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!(handler%20in%20this.globals.capturedWebkitHandlers))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20MissingHandler(%60cannot%20continue,%20method%20$%7Bhandler%7D%20not%20captured%20on%20macos%20%3C%2011%60,%20handler);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this.globals.capturedWebkitHandlers%5Bhandler%5D(outgoing);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.globals.window.webkit.messageHandlers%5Bhandler%5D.postMessage?.(data);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Sends%20message%20to%20the%20webkit%20layer%20and%20waits%20for%20the%20specified%20response%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BString%7D%20handler%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../index.js').RequestMessage%7D%20data%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPromise%3C*%3E%7D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20async%20wkSendAndWait(handler,%20data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.config.hasModernWebkitAPI)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20response%20=%20await%20this.wkSend(handler,%20data);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this.globals.JSONparse(response%20%7C%7C%20'%7B%7D');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20randMethodName%20=%20this.createRandMethodName();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20key%20=%20await%20this.createRandKey();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20iv%20=%20this.createRandIv();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20ciphertext,%20tag%20%7D%20=%20await%20new%20this.globals.Promise((/**%20@type%20%7Bany%7D%20*/%20resolve)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.generateRandomMethod(randMethodName,%20resolve);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20this%20is%20a%20carve-out%20for%20catalina%20that%20will%20be%20removed%20soon%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20data.messageHandling%20=%20new%20SecureMessagingParams(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20methodName:%20randMethodName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20secret:%20this.config.secret,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20key:%20this.globals.Arrayfrom(key),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20iv:%20this.globals.Arrayfrom(iv),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.wkSend(handler,%20data);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20cipher%20=%20new%20this.globals.Uint8Array(%5B...ciphertext,%20...tag%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20decrypted%20=%20await%20this.decrypt(cipher,%20key,%20iv);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this.globals.JSONparse(decrypted%20%7C%7C%20'%7B%7D');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20re-throw%20when%20the%20error%20is%20just%20a%20'MissingHandler'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(e%20instanceof%20MissingHandler)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20e;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.error('decryption%20failed',%20e);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.error(e);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%20error:%20e%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../index.js').NotificationMessage%7D%20msg%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20notify(msg)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wkSend(msg.context,%20msg);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../index.js').RequestMessage%7D%20msg%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20async%20request(msg)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20data%20=%20await%20this.wkSendAndWait(msg.context,%20msg);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(isResponseFor(msg,%20data))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(data.result)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20data.result%20%7C%7C%20%7B%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20forward%20the%20error%20if%20one%20was%20given%20explicity%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(data.error)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error(data.error.message);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('an%20unknown%20error%20occurred');%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Generate%20a%20random%20method%20name%20and%20adds%20it%20to%20the%20global%20scope%0A%20%20%20%20%20%20%20%20%20*%20The%20native%20layer%20will%20use%20this%20method%20to%20send%20the%20response%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%20%7C%20number%7D%20randomMethodName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BFunction%7D%20callback%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20generateRandomMethod(randomMethodName,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.globals.ObjectDefineProperty(this.globals.window,%20randomMethodName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20configurable,%20To%20allow%20for%20deletion%20later%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20writable:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7Bany%5B%5D%7D%20args%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value:%20(...args)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20callback(...args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20this.globals.window%5BrandomMethodName%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7Bstring%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20randomString()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20''%20+%20this.globals.getRandomValues(new%20this.globals.Uint32Array(1))%5B0%5D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7Bstring%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20createRandMethodName()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20'_'%20+%20this.randomString();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@type%20%7B%7Bname:%20string,%20length:%20number%7D%7D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20algoObj%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20name:%20'AES-GCM',%0A%20%20%20%20%20%20%20%20%20%20%20%20length:%20256,%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPromise%3CUint8Array%3E%7D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20async%20createRandKey()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20key%20=%20await%20this.globals.generateKey(this.algoObj,%20true,%20%5B'encrypt',%20'decrypt'%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20exportedKey%20=%20await%20this.globals.exportKey('raw',%20key);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20this.globals.Uint8Array(exportedKey);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BUint8Array%7D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20createRandIv()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.globals.getRandomValues(new%20this.globals.Uint8Array(12));%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BBufferSource%7D%20ciphertext%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BBufferSource%7D%20key%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BUint8Array%7D%20iv%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPromise%3Cstring%3E%7D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20async%20decrypt(ciphertext,%20key,%20iv)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cryptoKey%20=%20await%20this.globals.importKey('raw',%20key,%20'AES-GCM',%20false,%20%5B'decrypt'%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20algo%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20'AES-GCM',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20iv,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20decrypted%20=%20await%20this.globals.decrypt(algo,%20cryptoKey,%20ciphertext);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20dec%20=%20new%20this.globals.TextDecoder();%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20dec.decode(decrypted);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20When%20required%20(such%20as%20on%20macos%2010.x),%20capture%20the%20%60postMessage%60%20method%20on%0A%20%20%20%20%20%20%20%20%20*%20each%20webkit%20messageHandler%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%5B%5D%7D%20handlerNames%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20captureWebkitHandlers(handlerNames)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20handlers%20=%20window.webkit.messageHandlers;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!handlers)%20throw%20new%20MissingHandler('window.webkit.messageHandlers%20was%20absent',%20'all');%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20webkitMessageHandlerName%20of%20handlerNames)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20handlers%5BwebkitMessageHandlerName%5D?.postMessage%20===%20'function')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20%60bind%60%20is%20used%20here%20to%20ensure%20future%20calls%20to%20the%20captured%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20%60postMessage%60%20have%20the%20correct%20%60this%60%20context%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20original%20=%20handlers%5BwebkitMessageHandlerName%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20bound%20=%20handlers%5BwebkitMessageHandlerName%5D.postMessage?.bind(original);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.globals.capturedWebkitHandlers%5BwebkitMessageHandlerName%5D%20=%20bound;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20handlers%5BwebkitMessageHandlerName%5D.postMessage;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../index.js').Subscription%7D%20msg%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(value:%20unknown)%20=%3E%20void%7D%20callback%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20subscribe(msg,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20for%20now,%20bail%20if%20there's%20already%20a%20handler%20setup%20for%20this%20subscription%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(msg.subscriptionName%20in%20this.globals.window)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20this.globals.Error(%60A%20subscription%20with%20the%20name%20$%7Bmsg.subscriptionName%7D%20already%20exists%60);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20this.globals.ObjectDefineProperty(this.globals.window,%20msg.subscriptionName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20writable:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value:%20(data)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(data%20&&%20isSubscriptionEventFor(msg,%20data))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20callback(data.params);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.warn('Received%20a%20message%20that%20did%20not%20match%20the%20subscription',%20data);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.globals.ReflectDeleteProperty(this.globals.window,%20msg.subscriptionName);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Use%20this%20configuration%20to%20create%20an%20instance%20of%20%7B@link%20Messaging%7D%20for%20WebKit%20platforms%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20We%20support%20modern%20WebKit%20environments%20*and*%20macOS%20Catalina.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20Please%20see%20%7B@link%20WebkitMessagingTransport%7D%20for%20details%20on%20how%20messages%20are%20sent/received%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%5BExample%5D(./examples/webkit.example.js)%0A%20%20%20%20%20*/%0A%20%20%20%20class%20WebkitMessagingConfig%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean%7D%20params.hasModernWebkitAPI%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%5B%5D%7D%20params.webkitMessageHandlerNames%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.secret%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Whether%20or%20not%20the%20current%20WebKit%20Platform%20supports%20secure%20messaging%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20by%20default%20(eg:%20macOS%2011+)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.hasModernWebkitAPI%20=%20params.hasModernWebkitAPI;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20A%20list%20of%20WebKit%20message%20handler%20names%20that%20a%20user%20script%20can%20send.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20For%20example,%20if%20the%20native%20platform%20can%20receive%20messages%20through%20this:%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20%60%60%60js%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20window.webkit.messageHandlers.foo.postMessage('...')%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20then,%20this%20property%20would%20be:%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20%60%60%60js%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20webkitMessageHandlerNames:%20%5B'foo'%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.webkitMessageHandlerNames%20=%20params.webkitMessageHandlerNames;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20A%20string%20provided%20by%20native%20platforms%20to%20be%20sent%20with%20future%20outgoing%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20messages.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.secret%20=%20params.secret;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20This%20is%20the%20additional%20payload%20that%20gets%20appended%20to%20outgoing%20messages.%0A%20%20%20%20%20*%20It's%20used%20in%20the%20Swift%20side%20to%20encrypt%20the%20response%20that%20comes%20back%0A%20%20%20%20%20*/%0A%20%20%20%20class%20SecureMessagingParams%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.methodName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.secret%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bnumber%5B%5D%7D%20params.key%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bnumber%5B%5D%7D%20params.iv%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20method%20that's%20been%20appended%20to%20%60window%60%20to%20be%20called%20later%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.methodName%20=%20params.methodName;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20secret%20used%20to%20ensure%20message%20sender%20validity%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.secret%20=%20params.secret;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20CipherKey%20as%20number%5B%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.key%20=%20params.key;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20Initial%20Vector%20as%20number%5B%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.iv%20=%20params.iv;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Capture%20some%20globals%20used%20for%20messaging%20handling%20to%20prevent%20page%0A%20%20%20%20%20*%20scripts%20from%20tampering%20with%20this%0A%20%20%20%20%20*/%0A%20%20%20%20function%20captureGlobals()%20%7B%0A%20%20%20%20%20%20%20%20//%20Create%20base%20with%20null%20prototype%0A%20%20%20%20%20%20%20%20const%20globals%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20window,%0A%20%20%20%20%20%20%20%20%20%20%20%20getRandomValues:%20window.crypto.getRandomValues.bind(window.crypto),%0A%20%20%20%20%20%20%20%20%20%20%20%20TextEncoder,%0A%20%20%20%20%20%20%20%20%20%20%20%20TextDecoder,%0A%20%20%20%20%20%20%20%20%20%20%20%20Uint8Array,%0A%20%20%20%20%20%20%20%20%20%20%20%20Uint16Array,%0A%20%20%20%20%20%20%20%20%20%20%20%20Uint32Array,%0A%20%20%20%20%20%20%20%20%20%20%20%20JSONstringify:%20window.JSON.stringify,%0A%20%20%20%20%20%20%20%20%20%20%20%20JSONparse:%20window.JSON.parse,%0A%20%20%20%20%20%20%20%20%20%20%20%20Arrayfrom:%20window.Array.from,%0A%20%20%20%20%20%20%20%20%20%20%20%20Promise:%20window.Promise,%0A%20%20%20%20%20%20%20%20%20%20%20%20Error:%20window.Error,%0A%20%20%20%20%20%20%20%20%20%20%20%20ReflectDeleteProperty:%20window.Reflect.deleteProperty.bind(window.Reflect),%0A%20%20%20%20%20%20%20%20%20%20%20%20ObjectDefineProperty:%20window.Object.defineProperty,%0A%20%20%20%20%20%20%20%20%20%20%20%20addEventListener:%20window.addEventListener.bind(window),%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7BRecord%3Cstring,%20any%3E%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20capturedWebkitHandlers:%20%7B%7D,%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20if%20(isSecureContext)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20skip%20for%20HTTP%20content%20since%20window.crypto.subtle%20is%20unavailable%0A%20%20%20%20%20%20%20%20%20%20%20%20globals.generateKey%20=%20window.crypto.subtle.generateKey.bind(window.crypto.subtle);%0A%20%20%20%20%20%20%20%20%20%20%20%20globals.exportKey%20=%20window.crypto.subtle.exportKey.bind(window.crypto.subtle);%0A%20%20%20%20%20%20%20%20%20%20%20%20globals.importKey%20=%20window.crypto.subtle.importKey.bind(window.crypto.subtle);%0A%20%20%20%20%20%20%20%20%20%20%20%20globals.encrypt%20=%20window.crypto.subtle.encrypt.bind(window.crypto.subtle);%0A%20%20%20%20%20%20%20%20%20%20%20%20globals.decrypt%20=%20window.crypto.subtle.decrypt.bind(window.crypto.subtle);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20globals;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20A%20wrapper%20for%20messaging%20on%20Android.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20You%20must%20share%20a%20%7B@link%20AndroidMessagingConfig%7D%20instance%20between%20features%0A%20%20%20%20%20*%0A%20%20%20%20%20*/%0A%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/no-unused-vars%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7Bimport('../index.js').Subscription%7D%20Subscription%0A%20%20%20%20%20*%20@typedef%20%7Bimport('../index.js').MessagingContext%7D%20MessagingContext%0A%20%20%20%20%20*%20@typedef%20%7Bimport('../index.js').RequestMessage%7D%20RequestMessage%0A%20%20%20%20%20*%20@typedef%20%7Bimport('../index.js').NotificationMessage%7D%20NotificationMessage%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20An%20implementation%20of%20%7B@link%20MessagingTransport%7D%20for%20Android%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20All%20messages%20go%20through%20%60window.chrome.webview%60%20APIs%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@implements%20%7BMessagingTransport%7D%0A%20%20%20%20%20*/%0A%20%20%20%20class%20AndroidMessagingTransport%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BAndroidMessagingConfig%7D%20config%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BMessagingContext%7D%20messagingContext%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(config,%20messagingContext)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messagingContext%20=%20messagingContext;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.config%20=%20config;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BNotificationMessage%7D%20msg%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20notify(msg)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.config.sendMessageThrows?.(JSON.stringify(msg));%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.error('.notify%20failed',%20e);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRequestMessage%7D%20msg%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7BPromise%3Cany%3E%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20request(msg)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20Promise((resolve,%20reject)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20subscribe%20early%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20unsub%20=%20this.config.subscribe(msg.id,%20handler);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.config.sendMessageThrows?.(JSON.stringify(msg));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unsub();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20reject(new%20Error('request%20failed%20to%20send:%20'%20+%20e.message%20%7C%7C%20'unknown%20error'));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20function%20handler(data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(isResponseFor(msg,%20data))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20success%20case,%20forward%20.result%20only%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(data.result)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resolve(data.result%20%7C%7C%20%7B%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20unsub();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20error%20case,%20forward%20the%20error%20as%20a%20regular%20promise%20rejection%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(data.error)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20reject(new%20Error(data.error.message));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20unsub();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20getting%20here%20is%20undefined%20behavior%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unsub();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('unreachable:%20must%20have%20%60result%60%20or%20%60error%60%20key%20by%20this%20point');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BSubscription%7D%20msg%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(value:%20unknown%20%7C%20undefined)%20=%3E%20void%7D%20callback%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20subscribe(msg,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20unsub%20=%20this.config.subscribe(msg.subscriptionName,%20(data)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(isSubscriptionEventFor(msg,%20data))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20callback(data.params%20%7C%7C%20%7B%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unsub();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Android%20shared%20messaging%20configuration.%20This%20class%20should%20be%20constructed%20once%20and%20then%20shared%0A%20%20%20%20%20*%20between%20features%20(because%20of%20the%20way%20it%20modifies%20globals).%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20For%20example,%20if%20Android%20is%20injecting%20a%20JavaScript%20module%20like%20C-S-S%20which%20contains%20multiple%20'sub-features',%20then%0A%20%20%20%20%20*%20this%20class%20would%20be%20instantiated%20once%20and%20then%20shared%20between%20all%20sub-features.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20The%20following%20example%20shows%20all%20the%20fields%20that%20are%20required%20to%20be%20passed%20in:%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%60%60%60js%0A%20%20%20%20%20*%20const%20config%20=%20new%20AndroidMessagingConfig(%7B%0A%20%20%20%20%20*%20%20%20%20%20//%20a%20value%20that%20native%20has%20injected%20into%20the%20script%0A%20%20%20%20%20*%20%20%20%20%20messageSecret:%20'abc',%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%20%20%20%20//%20the%20name%20of%20the%20window%20method%20that%20android%20will%20deliver%20responses%20through%0A%20%20%20%20%20*%20%20%20%20%20messageCallback:%20'callback_123',%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%20%20%20%20//%20the%20%60@JavascriptInterface%60%20name%20from%20native%20that%20will%20be%20used%20to%20receive%20messages%0A%20%20%20%20%20*%20%20%20%20%20javascriptInterface:%20%22ARandomValue%22,%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%20%20%20%20//%20the%20global%20object%20where%20methods%20will%20be%20registered%0A%20%20%20%20%20*%20%20%20%20%20target:%20globalThis%0A%20%20%20%20%20*%20%7D);%0A%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20*%20Once%20an%20instance%20of%20%7B@link%20AndroidMessagingConfig%7D%20is%20created,%20you%20can%20then%20use%20it%20to%20construct%0A%20%20%20%20%20*%20many%20instances%20of%20%7B@link%20Messaging%7D%20(one%20per%20feature).%20See%20%60examples/android.example.js%60%20for%20an%20example.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20##%20Native%20integration%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20Assuming%20you%20have%20the%20following:%0A%20%20%20%20%20*%20%20-%20a%20%60@JavascriptInterface%60%20named%20%60%22ContentScopeScripts%22%60%0A%20%20%20%20%20*%20%20-%20a%20sub-feature%20called%20%60%22featureA%22%60%0A%20%20%20%20%20*%20%20-%20and%20a%20method%20on%20%60%22featureA%22%60%20called%20%60%22helloWorld%22%60%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20Then%20delivering%20a%20%7B@link%20NotificationMessage%7D%20to%20it,%20would%20be%20roughly%20this%20in%20JavaScript%20(remember%20%60params%60%20is%20optional%20though)%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20*%20const%20secret%20=%20%22abc%22;%0A%20%20%20%20%20*%20const%20json%20=%20JSON.stringify(%7B%0A%20%20%20%20%20*%20%20%20%20%20context:%20%22ContentScopeScripts%22,%0A%20%20%20%20%20*%20%20%20%20%20featureName:%20%22featureA%22,%0A%20%20%20%20%20*%20%20%20%20%20method:%20%22helloWorld%22,%0A%20%20%20%20%20*%20%20%20%20%20params:%20%7B%20%22foo%22:%20%22bar%22%20%7D%0A%20%20%20%20%20*%20%7D);%0A%20%20%20%20%20*%20window.ContentScopeScripts.process(json,%20secret)%0A%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20*%20When%20you%20receive%20the%20JSON%20payload%20(note%20that%20it%20will%20be%20a%20string),%20you'll%20need%20to%20deserialize/verify%20it%20according%20to%20%7B@link%20%22Messaging%20Implementation%20Guide%22%7D%0A%20%20%20%20%20*%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20##%20Responding%20to%20a%20%7B@link%20RequestMessage%7D,%20or%20pushing%20a%20%7B@link%20SubscriptionEvent%7D%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20If%20you%20receive%20a%20%7B@link%20RequestMessage%7D,%20you'll%20need%20to%20deliver%20a%20%7B@link%20MessageResponse%7D.%0A%20%20%20%20%20*%20Similarly,%20if%20you%20want%20to%20push%20new%20data,%20you%20need%20to%20deliver%20a%20%7B@link%20SubscriptionEvent%7D.%20In%20both%0A%20%20%20%20%20*%20cases%20you'll%20do%20this%20through%20a%20global%20%60window%60%20method.%20Given%20the%20snippet%20below,%20this%20is%20how%20it%20would%20relate%0A%20%20%20%20%20*%20to%20the%20%7B@link%20AndroidMessagingConfig%7D:%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20-%20%60$messageCallback%60%20matches%20%7B@link%20AndroidMessagingConfig.messageCallback%7D%0A%20%20%20%20%20*%20-%20%60$messageSecret%60%20matches%20%7B@link%20AndroidMessagingConfig.messageSecret%7D%0A%20%20%20%20%20*%20-%20%60$message%60%20is%20JSON%20string%20that%20represents%20one%20of%20%7B@link%20MessageResponse%7D%20or%20%7B@link%20SubscriptionEvent%7D%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20*%20object%20ReplyHandler%20%7B%0A%20%20%20%20%20*%20%20%20%20%20fun%20constructReply(message:%20String,%20messageCallback:%20String,%20messageSecret:%20String):%20String%20%7B%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20return%20%22%22%22%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20(function()%20%7B%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20window%5B'$messageCallback'%5D('$messageSecret',%20$message);%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%7D)();%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%22%22%22.trimIndent()%0A%20%20%20%20%20*%20%20%20%20%20%7D%0A%20%20%20%20%20*%20%7D%0A%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20*/%0A%20%20%20%20class%20AndroidMessagingConfig%20%7B%0A%20%20%20%20%20%20%20%20/**%20@type%20%7B(json:%20string,%20secret:%20string)%20=%3E%20void%7D%20*/%0A%20%20%20%20%20%20%20%20_capturedHandler;%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20params.target%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean%7D%20params.debug%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.messageSecret%20-%20a%20secret%20to%20ensure%20that%20messages%20are%20only%0A%20%20%20%20%20%20%20%20%20*%20processed%20by%20the%20correct%20handler%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.javascriptInterface%20-%20the%20name%20of%20the%20javascript%20interface%0A%20%20%20%20%20%20%20%20%20*%20registered%20on%20the%20native%20side%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.messageCallback%20-%20the%20name%20of%20the%20callback%20that%20the%20native%0A%20%20%20%20%20%20%20%20%20*%20side%20will%20use%20to%20send%20messages%20back%20to%20the%20javascript%20side%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.target%20=%20params.target;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.debug%20=%20params.debug;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.javascriptInterface%20=%20params.javascriptInterface;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messageSecret%20=%20params.messageSecret;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messageCallback%20=%20params.messageCallback;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7BMap%3Cstring,%20(msg:%20MessageResponse%20%7C%20SubscriptionEvent)%20=%3E%20void%3E%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.listeners%20=%20new%20globalThis.Map();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Capture%20the%20global%20handler%20and%20remove%20it%20from%20the%20global%20object.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this._captureGlobalHandler();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Assign%20the%20incoming%20handler%20method%20to%20the%20global%20object.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this._assignHandlerMethod();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20The%20transport%20can%20call%20this%20to%20transmit%20a%20JSON%20payload%20along%20with%20a%20secret%0A%20%20%20%20%20%20%20%20%20*%20to%20the%20native%20Android%20handler.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20Note:%20This%20can%20throw%20-%20it's%20up%20to%20the%20transport%20to%20handle%20the%20error.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@type%20%7B(json:%20string)%20=%3E%20void%7D%0A%20%20%20%20%20%20%20%20%20*%20@throws%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20sendMessageThrows(json)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this._capturedHandler(json,%20this.messageSecret);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20A%20subscription%20on%20Android%20is%20just%20a%20named%20listener.%20All%20messages%20from%0A%20%20%20%20%20%20%20%20%20*%20android%20-%3E%20are%20delivered%20through%20a%20single%20function,%20and%20this%20mapping%20is%20used%0A%20%20%20%20%20%20%20%20%20*%20to%20route%20the%20messages%20to%20the%20correct%20listener.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20Note:%20Use%20this%20to%20implement%20request-%3Eresponse%20by%20unsubscribing%20after%20the%20first%0A%20%20%20%20%20%20%20%20%20*%20response.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20id%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(msg:%20MessageResponse%20%7C%20SubscriptionEvent)%20=%3E%20void%7D%20callback%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7B()%20=%3E%20void%7D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20subscribe(id,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.listeners.set(id,%20callback);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.listeners.delete(id);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Accept%20incoming%20messages%20and%20try%20to%20deliver%20it%20to%20a%20registered%20listener.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20This%20code%20is%20defensive%20to%20prevent%20any%20single%20handler%20from%20affecting%20another%20if%0A%20%20%20%20%20%20%20%20%20*%20it%20throws%20(producer%20interference).%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BMessageResponse%20%7C%20SubscriptionEvent%7D%20payload%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_dispatch(payload)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20do%20nothing%20if%20the%20response%20is%20empty%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20this%20prevents%20the%20next%20%60in%60%20checks%20from%20throwing%20in%20test/debug%20scenarios%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!payload)%20return%20this._log('no%20response');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20if%20the%20payload%20has%20an%20'id'%20field,%20then%20it's%20a%20message%20response%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20('id'%20in%20payload)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.listeners.has(payload.id))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._tryCatch(()%20=%3E%20this.listeners.get(payload.id)?.(payload));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._log('no%20listeners%20for%20',%20payload);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20if%20the%20payload%20has%20an%20'subscriptionName'%20field,%20then%20it's%20a%20push%20event%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20('subscriptionName'%20in%20payload)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.listeners.has(payload.subscriptionName))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._tryCatch(()%20=%3E%20this.listeners.get(payload.subscriptionName)?.(payload));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._log('no%20subscription%20listeners%20for%20',%20payload);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(...args:%20any%5B%5D)%20=%3E%20any%7D%20fn%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5Bcontext%5D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_tryCatch(fn,%20context%20=%20'none')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20fn();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.debug)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.error('AndroidMessagingConfig%20error:',%20context);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.error(e);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B...any%7D%20args%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_log(...args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.debug)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.log('AndroidMessagingConfig',%20...args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Capture%20the%20global%20handler%20and%20remove%20it%20from%20the%20global%20object.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_captureGlobalHandler()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20target,%20javascriptInterface%20%7D%20=%20this;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(Object.prototype.hasOwnProperty.call(target,%20javascriptInterface))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._capturedHandler%20=%20target%5BjavascriptInterface%5D.process.bind(target%5BjavascriptInterface%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20target%5BjavascriptInterface%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._capturedHandler%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._log('Android%20messaging%20interface%20not%20available',%20javascriptInterface);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Assign%20the%20incoming%20handler%20method%20to%20the%20global%20object.%0A%20%20%20%20%20%20%20%20%20*%20This%20is%20the%20method%20that%20Android%20will%20call%20to%20deliver%20messages.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_assignHandlerMethod()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7B(secret:%20string,%20response:%20MessageResponse%20%7C%20SubscriptionEvent)%20=%3E%20void%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20responseHandler%20=%20(providedSecret,%20response)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(providedSecret%20===%20this.messageSecret)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._dispatch(response);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20Object.defineProperty(this.target,%20this.messageCallback,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value:%20responseHandler,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20An%20abstraction%20for%20communications%20between%20JavaScript%20and%20host%20platforms.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%201)%20First%20you%20construct%20your%20platform-specific%20configuration%20(eg:%20%7B@link%20WebkitMessagingConfig%7D)%0A%20%20%20%20%20*%202)%20Then%20use%20that%20to%20get%20an%20instance%20of%20the%20Messaging%20utility%20which%20allows%0A%20%20%20%20%20*%20you%20to%20send%20and%20receive%20data%20in%20a%20unified%20way%0A%20%20%20%20%20*%203)%20Each%20platform%20implements%20%7B@link%20MessagingTransport%7D%20along%20with%20its%20own%20Configuration%0A%20%20%20%20%20*%20%20%20%20%20-%20For%20example,%20to%20learn%20what%20configuration%20is%20required%20for%20Webkit,%20see:%20%7B@link%20WebkitMessagingConfig%7D%0A%20%20%20%20%20*%20%20%20%20%20-%20Or,%20to%20learn%20about%20how%20messages%20are%20sent%20and%20received%20in%20Webkit,%20see%20%7B@link%20WebkitMessagingTransport%7D%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20##%20Links%0A%20%20%20%20%20*%20Please%20see%20the%20following%20links%20for%20examples%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20-%20Windows:%20%7B@link%20WindowsMessagingConfig%7D%0A%20%20%20%20%20*%20-%20Webkit:%20%7B@link%20WebkitMessagingConfig%7D%0A%20%20%20%20%20*%20-%20Android:%20%7B@link%20AndroidMessagingConfig%7D%0A%20%20%20%20%20*%20-%20Schema:%20%7B@link%20%22Messaging%20Schema%22%7D%0A%20%20%20%20%20*%20-%20Implementation%20Guide:%20%7B@link%20%22Messaging%20Implementation%20Guide%22%7D%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@module%20Messaging%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Common%20options/config%20that%20are%20*not*%20transport%20specific.%0A%20%20%20%20%20*/%0A%20%20%20%20class%20MessagingContext%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.context%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B%22production%22%20%7C%20%22development%22%7D%20params.env%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.context%20=%20params.context;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.env%20=%20params.env;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7BWebkitMessagingConfig%20%7C%20WindowsMessagingConfig%20%7C%20AndroidMessagingConfig%20%7C%20TestTransportConfig%7D%20MessagingConfig%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%0A%20%20%20%20%20*/%0A%20%20%20%20class%20Messaging%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BMessagingContext%7D%20messagingContext%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BMessagingConfig%7D%20config%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(messagingContext,%20config)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messagingContext%20=%20messagingContext;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.transport%20=%20getTransport(config,%20this.messagingContext);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Send%20a%20'fire-and-forget'%20message.%0A%20%20%20%20%20%20%20%20%20*%20@throws%20%7BMissingHandler%7D%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@example%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60ts%0A%20%20%20%20%20%20%20%20%20*%20const%20messaging%20=%20new%20Messaging(config)%0A%20%20%20%20%20%20%20%20%20*%20messaging.notify(%22foo%22,%20%7Bbar:%20%22baz%22%7D)%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20name%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bdata%5D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20notify(name,%20data%20=%20%7B%7D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20message%20=%20new%20NotificationMessage(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20context:%20this.messagingContext.context,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName:%20this.messagingContext.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20method:%20name,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params:%20data,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20this.transport.notify(message);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Send%20a%20request,%20and%20wait%20for%20a%20response%0A%20%20%20%20%20%20%20%20%20*%20@throws%20%7BMissingHandler%7D%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@example%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20%20%20%20%20*%20const%20messaging%20=%20new%20Messaging(config)%0A%20%20%20%20%20%20%20%20%20*%20const%20response%20=%20await%20messaging.request(%22foo%22,%20%7Bbar:%20%22baz%22%7D)%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20name%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bdata%5D%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7BPromise%3Cany%3E%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20request(name,%20data%20=%20%7B%7D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20id%20=%20globalThis?.crypto?.randomUUID?.()%20%7C%7C%20name%20+%20'.response';%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20message%20=%20new%20RequestMessage(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20context:%20this.messagingContext.context,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName:%20this.messagingContext.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20method:%20name,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params:%20data,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.transport.request(message);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20name%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(value:%20unknown)%20=%3E%20void%7D%20callback%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7B()%20=%3E%20void%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20subscribe(name,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20msg%20=%20new%20Subscription(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20context:%20this.messagingContext.context,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName:%20this.messagingContext.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20subscriptionName:%20name,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.transport.subscribe(msg,%20callback);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Use%20this%20to%20create%20testing%20transport%20on%20the%20fly.%0A%20%20%20%20%20*%20It's%20useful%20for%20debugging,%20and%20for%20enabling%20scripts%20to%20run%20in%0A%20%20%20%20%20*%20other%20environments%20-%20for%20example,%20testing%20in%20a%20browser%20without%20the%20need%0A%20%20%20%20%20*%20for%20a%20full%20integration%0A%20%20%20%20%20*/%0A%20%20%20%20class%20TestTransportConfig%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BMessagingTransport%7D%20impl%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(impl)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.impl%20=%20impl;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@implements%20%7BMessagingTransport%7D%0A%20%20%20%20%20*/%0A%20%20%20%20class%20TestTransport%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BTestTransportConfig%7D%20config%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BMessagingContext%7D%20messagingContext%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(config,%20messagingContext)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.config%20=%20config;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messagingContext%20=%20messagingContext;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20notify(msg)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.config.impl.notify(msg);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20request(msg)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.config.impl.request(msg);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20subscribe(msg,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.config.impl.subscribe(msg,%20callback);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7BWebkitMessagingConfig%20%7C%20WindowsMessagingConfig%20%7C%20AndroidMessagingConfig%20%7C%20TestTransportConfig%7D%20config%0A%20%20%20%20%20*%20@param%20%7BMessagingContext%7D%20messagingContext%0A%20%20%20%20%20*%20@returns%20%7BMessagingTransport%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20getTransport(config,%20messagingContext)%20%7B%0A%20%20%20%20%20%20%20%20if%20(config%20instanceof%20WebkitMessagingConfig)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20WebkitMessagingTransport(config,%20messagingContext);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(config%20instanceof%20WindowsMessagingConfig)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20WindowsMessagingTransport(config,%20messagingContext);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(config%20instanceof%20AndroidMessagingConfig)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20AndroidMessagingTransport(config,%20messagingContext);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(config%20instanceof%20TestTransportConfig)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20TestTransport(config,%20messagingContext);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20throw%20new%20Error('unreachable');%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Thrown%20when%20a%20handler%20cannot%20be%20found%0A%20%20%20%20%20*/%0A%20%20%20%20class%20MissingHandler%20extends%20Error%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20message%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20handlerName%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(message,%20handlerName)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20super(message);%0A%20%20%20%20%20%20%20%20%20%20%20%20this.handlerName%20=%20handlerName;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Workaround%20defining%20MessagingTransport%20locally%20because%20%22import()%22%20is%20not%20working%20in%20%60@implements%60%0A%20%20%20%20%20*%20@typedef%20%7Bimport('@duckduckgo/messaging').MessagingTransport%7D%20MessagingTransport%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@deprecated%20-%20A%20temporary%20constructor%20for%20the%20extension%20to%20make%20the%20messaging%20config%0A%20%20%20%20%20*/%0A%20%20%20%20function%20extensionConstructMessagingConfig()%20%7B%0A%20%20%20%20%20%20%20%20const%20messagingTransport%20=%20new%20SendMessageMessagingTransport();%0A%20%20%20%20%20%20%20%20return%20new%20TestTransportConfig(messagingTransport);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20A%20temporary%20implementation%20of%20%7B@link%20MessagingTransport%7D%20to%20communicate%20with%20Extensions.%0A%20%20%20%20%20*%20It%20wraps%20the%20current%20messaging%20system%20that%20calls%20%60sendMessage%60%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@implements%20%7BMessagingTransport%7D%0A%20%20%20%20%20*%20@deprecated%20-%20Use%20this%20only%20to%20communicate%20with%20Android%20and%20the%20Extension%20while%20support%20to%20%7B@link%20Messaging%7D%0A%20%20%20%20%20*%20is%20not%20ready%20and%20we%20need%20to%20use%20%60sendMessage()%60.%0A%20%20%20%20%20*/%0A%20%20%20%20class%20SendMessageMessagingTransport%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Queue%20of%20callbacks%20to%20be%20called%20with%20messages%20sent%20from%20the%20Platform.%0A%20%20%20%20%20%20%20%20%20*%20This%20is%20used%20to%20connect%20requests%20with%20responses%20and%20to%20trigger%20subscriptions%20callbacks.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_queue%20=%20new%20Set();%0A%0A%20%20%20%20%20%20%20%20constructor()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.globals%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20window:%20globalThis,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20globalThis,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20JSONparse:%20globalThis.JSON.parse,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20JSONstringify:%20globalThis.JSON.stringify,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Promise:%20globalThis.Promise,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Error:%20globalThis.Error,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20String:%20globalThis.String,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Callback%20for%20update()%20handler.%20This%20connects%20messages%20sent%20from%20the%20Platform%0A%20%20%20%20%20%20%20%20%20*%20with%20callback%20functions%20in%20the%20_queue.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bany%7D%20response%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20onResponse(response)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this._queue.forEach((subscription)%20=%3E%20subscription(response));%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('@duckduckgo/messaging').NotificationMessage%7D%20msg%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20notify(msg)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20params%20=%20msg.params;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Unwrap%20'setYoutubePreviewsEnabled'%20params%20to%20match%20expected%20payload%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20for%20sendMessage()%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(msg.method%20===%20'setYoutubePreviewsEnabled')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params%20=%20msg.params?.youtubePreviewsEnabled;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Unwrap%20'updateYouTubeCTLAddedFlag'%20params%20to%20match%20expected%20payload%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20for%20sendMessage()%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(msg.method%20===%20'updateYouTubeCTLAddedFlag')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params%20=%20msg.params?.youTubeCTLAddedFlag;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20legacySendMessage(msg.method,%20params);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('@duckduckgo/messaging').RequestMessage%7D%20req%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7BPromise%3Cany%3E%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20request(req)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20comparator%20=%20(eventData)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20eventData.responseMessageType%20===%20req.method;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20params%20=%20req.params;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Adapts%20request%20for%20'getYouTubeVideoDetails'%20by%20identifying%20the%20correct%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20response%20for%20each%20request%20and%20updating%20params%20to%20expect%20current%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20implementation%20specifications.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(req.method%20===%20'getYouTubeVideoDetails')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20comparator%20=%20(eventData)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20eventData.responseMessageType%20===%20req.method%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20eventData.response%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20eventData.response.videoURL%20===%20req.params?.videoURL%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params%20=%20req.params?.videoURL;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20legacySendMessage(req.method,%20params);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20this.globals.Promise((resolve)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._subscribe(comparator,%20(msgRes,%20unsubscribe)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unsubscribe();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20resolve(msgRes.response);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('@duckduckgo/messaging').Subscription%7D%20msg%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(value:%20unknown%20%7C%20undefined)%20=%3E%20void%7D%20callback%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20subscribe(msg,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20comparator%20=%20(eventData)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20eventData.messageType%20===%20msg.subscriptionName%20%7C%7C%20eventData.responseMessageType%20===%20msg.subscriptionName;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20only%20forward%20the%20'params'%20('response'%20in%20current%20format),%20to%20match%20expected%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20callback%20from%20a%20SubscriptionEvent%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cb%20=%20(eventData)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20callback(eventData.response);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this._subscribe(comparator,%20cb);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(eventData:%20any)%20=%3E%20boolean%7D%20comparator%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(value:%20any,%20unsubscribe:%20(()=%3Evoid))%20=%3E%20void%7D%20callback%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_subscribe(comparator,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7B(()=%3Evoid)%20%7C%20undefined%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20prefer-const%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20teardown;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BMessageEvent%7D%20event%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20idHandler%20=%20(event)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!event)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.warn('no%20message%20available');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(comparator(event))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!teardown)%20throw%20new%20this.globals.Error('unreachable');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20callback(event,%20teardown);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20this._queue.add(idHandler);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20teardown%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._queue.delete(idHandler);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20teardown?.();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7Bobject%7D%20AssetConfig%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20regularFontUrl%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20boldFontUrl%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7Bobject%7D%20Site%0A%20%20%20%20%20*%20@property%20%7Bstring%20%7C%20null%7D%20domain%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20%5BisBroken%5D%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20%5Ballowlisted%5D%0A%20%20%20%20%20*%20@property%20%7Bstring%5B%5D%7D%20%5BenabledFeatures%5D%0A%20%20%20%20%20*/%0A%0A%20%20%20%20class%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20/**%20@type%20%7Bimport('./utils.js').RemoteConfig%20%7C%20undefined%7D%20*/%0A%20%20%20%20%20%20%20%20#bundledConfig;%0A%20%20%20%20%20%20%20%20/**%20@type%20%7Bobject%20%7C%20undefined%7D%20*/%0A%20%20%20%20%20%20%20%20#trackerLookup;%0A%20%20%20%20%20%20%20%20/**%20@type%20%7Bboolean%20%7C%20undefined%7D%20*/%0A%20%20%20%20%20%20%20%20#documentOriginIsTracker;%0A%20%20%20%20%20%20%20%20/**%20@type%20%7BRecord%3Cstring,%20unknown%3E%20%7C%20undefined%7D%20*/%0A%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20no-unused-private-class-members%0A%20%20%20%20%20%20%20%20#bundledfeatureSettings;%0A%20%20%20%20%20%20%20%20/**%20@type%20%7Bimport('../../messaging').Messaging%7D%20*/%0A%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20no-unused-private-class-members%0A%20%20%20%20%20%20%20%20#messaging;%0A%20%20%20%20%20%20%20%20/**%20@type%20%7Bboolean%7D%20*/%0A%20%20%20%20%20%20%20%20#isDebugFlagSet%20=%20false;%0A%0A%20%20%20%20%20%20%20%20/**%20@type%20%7B%7B%20debug?:%20boolean,%20desktopModeEnabled?:%20boolean,%20forcedZoomEnabled?:%20boolean,%20featureSettings?:%20Record%3Cstring,%20unknown%3E,%20assets?:%20AssetConfig%20%7C%20undefined,%20site:%20Site,%20messagingConfig?:%20import('@duckduckgo/messaging').MessagingConfig%20%7D%20%7C%20null%7D%20*/%0A%20%20%20%20%20%20%20%20#args;%0A%0A%20%20%20%20%20%20%20%20constructor(featureName)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.name%20=%20featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.#args%20=%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.monitor%20=%20new%20PerformanceMonitor();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20get%20isDebug()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.#args?.debug%20%7C%7C%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20get%20desktopModeEnabled()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.#args?.desktopModeEnabled%20%7C%7C%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20get%20forcedZoomEnabled()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.#args?.forcedZoomEnabled%20%7C%7C%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('./utils').Platform%7D%20platform%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20set%20platform(platform)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this._platform%20=%20platform;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20get%20platform()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Type%20'Platform%20%7C%20undefined'%20is%20not%20assignable%20to%20type%20'Platform'%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this._platform;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@type%20%7BAssetConfig%20%7C%20undefined%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20get%20assetConfig()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.#args?.assets;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20get%20documentOriginIsTracker()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20!!this.#documentOriginIsTracker;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bobject%7D%0A%20%20%20%20%20%20%20%20%20**/%0A%20%20%20%20%20%20%20%20get%20trackerLookup()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.#trackerLookup%20%7C%7C%20%7B%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bimport('./utils.js').RemoteConfig%20%7C%20undefined%7D%0A%20%20%20%20%20%20%20%20%20**/%0A%20%20%20%20%20%20%20%20get%20bundledConfig()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.#bundledConfig;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@deprecated%20as%20we%20should%20make%20this%20internal%20to%20the%20class%20and%20not%20used%20externally%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7BMessagingContext%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_createMessagingContext()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20contextName%20=%20'contentScopeScripts';%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20MessagingContext(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20context:%20contextName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20env:%20this.isDebug%20?%20'development'%20:%20'production',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName:%20this.name,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Lazily%20create%20a%20messaging%20instance%20for%20the%20given%20Platform%20+%20feature%20combo%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7Bimport('@duckduckgo/messaging').Messaging%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20get%20messaging()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this._messaging)%20return%20this._messaging;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20messagingContext%20=%20this._createMessagingContext();%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20messagingConfig%20=%20this.#args?.messagingConfig;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!messagingConfig)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.platform?.name%20!==%20'extension')%20throw%20new%20Error('Only%20extension%20messaging%20supported,%20all%20others%20should%20be%20passed%20in');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20messagingConfig%20=%20extensionConstructMessagingConfig();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20this._messaging%20=%20new%20Messaging(messagingContext,%20messagingConfig);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this._messaging;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Get%20the%20value%20of%20a%20config%20setting.%0A%20%20%20%20%20%20%20%20%20*%20If%20the%20value%20is%20not%20set,%20return%20the%20default%20value.%0A%20%20%20%20%20%20%20%20%20*%20If%20the%20value%20is%20not%20an%20object,%20return%20the%20value.%0A%20%20%20%20%20%20%20%20%20*%20If%20the%20value%20is%20an%20object,%20check%20its%20type%20property.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20attrName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bany%7D%20defaultValue%20-%20The%20default%20value%20to%20use%20if%20the%20config%20setting%20is%20not%20set%0A%20%20%20%20%20%20%20%20%20*%20@returns%20The%20value%20of%20the%20config%20setting%20or%20the%20default%20value%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20getFeatureAttr(attrName,%20defaultValue)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20configSetting%20=%20this.getFeatureSetting(attrName);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20processAttr(configSetting,%20defaultValue);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Return%20a%20specific%20setting%20from%20the%20feature%20settings%0A%20%20%20%20%20%20%20%20%20*%20If%20the%20%22settings%22%20key%20within%20the%20config%20has%20a%20%22domains%22%20key,%20it%20will%20be%20used%20to%20override%20the%20settings.%0A%20%20%20%20%20%20%20%20%20*%20This%20uses%20JSONPatch%20to%20apply%20the%20patches%20to%20settings%20before%20getting%20the%20setting%20value.%0A%20%20%20%20%20%20%20%20%20*%20For%20example.com%20getFeatureSettings('val')%20will%20return%201:%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60json%0A%20%20%20%20%20%20%20%20%20*%20%20%7B%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%22settings%22:%20%7B%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%22domains%22:%20%5B%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22domain%22:%20%22example.com%22,%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22patchSettings%22:%20%5B%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20%22op%22:%20%22replace%22,%20%22path%22:%20%22/val%22,%20%22value%22:%201%20%7D%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20*%20%20%7D%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20%20%20%20%20*%20%22domain%22%20can%20either%20be%20a%20string%20or%20an%20array%20of%20strings.%0A%0A%20%20%20%20%20%20%20%20%20*%20For%20boolean%20states%20you%20should%20consider%20using%20getFeatureSettingEnabled.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20featureKeyName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BfeatureName%5D%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bany%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20getFeatureSetting(featureKeyName,%20featureName)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20result%20=%20this._getFeatureSettings(featureName);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(featureKeyName%20===%20'domains')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('domains%20is%20a%20reserved%20feature%20setting%20key%20name');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20domainMatch%20=%20%5B...this.matchDomainFeatureSetting('domains')%5D.sort((a,%20b)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20a.domain.length%20-%20b.domain.length;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20match%20of%20domainMatch)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(match.patchSettings%20===%20undefined)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result%20=%20immutableJSONPatch(result,%20match.patchSettings);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.error('Error%20applying%20patch%20settings',%20e);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20result?.%5BfeatureKeyName%5D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Return%20the%20settings%20object%20for%20a%20feature%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BfeatureName%5D%20-%20The%20name%20of%20the%20feature%20to%20get%20the%20settings%20for;%20defaults%20to%20the%20name%20of%20the%20feature%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bany%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_getFeatureSettings(featureName)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20camelFeatureName%20=%20featureName%20%7C%7C%20camelcase(this.name);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.#args?.featureSettings?.%5BcamelFeatureName%5D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20For%20simple%20boolean%20settings,%20return%20true%20if%20the%20setting%20is%20'enabled'%0A%20%20%20%20%20%20%20%20%20*%20For%20objects,%20verify%20the%20'state'%20field%20is%20'enabled'.%0A%20%20%20%20%20%20%20%20%20*%20This%20allows%20for%20future%20forwards%20compatibility%20with%20more%20complex%20settings%20if%20required.%0A%20%20%20%20%20%20%20%20%20*%20For%20example:%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60json%0A%20%20%20%20%20%20%20%20%20*%20%7B%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%22toggle%22:%20%22enabled%22%0A%20%20%20%20%20%20%20%20%20*%20%7D%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20%20%20%20%20*%20Could%20become%20later%20(without%20breaking%20changes):%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60json%0A%20%20%20%20%20%20%20%20%20*%20%7B%0A%20%20%20%20%20%20%20%20%20*%20%20%20%22toggle%22:%20%7B%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%22state%22:%20%22enabled%22,%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%22someOtherKey%22:%201%0A%20%20%20%20%20%20%20%20%20*%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20*%20%7D%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20%20%20%20%20*%20This%20also%20supports%20domain%20overrides%20as%20per%20%60getFeatureSetting%60.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20featureKeyName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BfeatureName%5D%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20getFeatureSettingEnabled(featureKeyName,%20featureName)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20result%20=%20this.getFeatureSetting(featureKeyName,%20featureName);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20result%20===%20'object')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20result.state%20===%20'enabled';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20result%20===%20'enabled';%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Given%20a%20config%20key,%20interpret%20the%20value%20as%20a%20list%20of%20domain%20overrides,%20and%20return%20the%20elements%20that%20match%20the%20current%20page%0A%20%20%20%20%20%20%20%20%20*%20Consider%20using%20patchSettings%20instead%20as%20per%20%60getFeatureSetting%60.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20featureKeyName%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7Bany%5B%5D%7D%0A%20%20%20%20%20%20%20%20%20*%20@private%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20matchDomainFeatureSetting(featureKeyName)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20domain%20=%20this.#args?.site.domain;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!domain)%20return%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20domains%20=%20this._getFeatureSettings()?.%5BfeatureKeyName%5D%20%7C%7C%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20domains.filter((rule)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(Array.isArray(rule.domain))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20rule.domain.some((domainRule)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20matchHostname(domain,%20domainRule);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20matchHostname(domain,%20rule.domain);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20init(args)%20%7B%7D%0A%0A%20%20%20%20%20%20%20%20callInit(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20mark%20=%20this.monitor.mark(this.name%20+%20'CallInit');%0A%20%20%20%20%20%20%20%20%20%20%20%20this.#args%20=%20args;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.platform%20=%20args.platform;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.init(args);%0A%20%20%20%20%20%20%20%20%20%20%20%20mark.end();%0A%20%20%20%20%20%20%20%20%20%20%20%20this.measure();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20load(args)%20%7B%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20This%20is%20a%20wrapper%20around%20%60this.messaging.notify%60%20that%20applies%20the%0A%20%20%20%20%20%20%20%20%20*%20auto-generated%20types%20from%20the%20%60src/types%60%20folder.%20It's%20used%0A%20%20%20%20%20%20%20%20%20*%20to%20provide%20per-feature%20type%20information%20based%20on%20the%20schemas%0A%20%20%20%20%20%20%20%20%20*%20in%20%60src/messages%60%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@type%20%7Bimport(%22@duckduckgo/messaging%22).Messaging%5B'notify'%5D%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20notify(...args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%5Bname,%20params%5D%20=%20args;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messaging.notify(name,%20params);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20This%20is%20a%20wrapper%20around%20%60this.messaging.request%60%20that%20applies%20the%0A%20%20%20%20%20%20%20%20%20*%20auto-generated%20types%20from%20the%20%60src/types%60%20folder.%20It's%20used%0A%20%20%20%20%20%20%20%20%20*%20to%20provide%20per-feature%20type%20information%20based%20on%20the%20schemas%0A%20%20%20%20%20%20%20%20%20*%20in%20%60src/messages%60%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@type%20%7Bimport(%22@duckduckgo/messaging%22).Messaging%5B'request'%5D%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20request(...args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%5Bname,%20params%5D%20=%20args;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.messaging.request(name,%20params);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20This%20is%20a%20wrapper%20around%20%60this.messaging.subscribe%60%20that%20applies%20the%0A%20%20%20%20%20%20%20%20%20*%20auto-generated%20types%20from%20the%20%60src/types%60%20folder.%20It's%20used%0A%20%20%20%20%20%20%20%20%20*%20to%20provide%20per-feature%20type%20information%20based%20on%20the%20schemas%0A%20%20%20%20%20%20%20%20%20*%20in%20%60src/messages%60%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@type%20%7Bimport(%22@duckduckgo/messaging%22).Messaging%5B'subscribe'%5D%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20subscribe(...args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%5Bname,%20cb%5D%20=%20args;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.messaging.subscribe(name,%20cb);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('./content-scope-features.js').LoadArgs%7D%20args%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20callLoad(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20mark%20=%20this.monitor.mark(this.name%20+%20'CallLoad');%0A%20%20%20%20%20%20%20%20%20%20%20%20this.#args%20=%20args;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.platform%20=%20args.platform;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.#bundledConfig%20=%20args.bundledConfig;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20we%20have%20a%20bundled%20config,%20treat%20it%20as%20a%20regular%20config%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20This%20will%20be%20overriden%20by%20the%20remote%20config%20if%20it%20is%20available%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.#bundledConfig%20&&%20this.#args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20enabledFeatures%20=%20computeEnabledFeatures(args.bundledConfig,%20args.site.domain,%20this.platform.version);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.#args.featureSettings%20=%20parseFeatureSettings(args.bundledConfig,%20enabledFeatures);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20this.#trackerLookup%20=%20args.trackerLookup;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.#documentOriginIsTracker%20=%20args.documentOriginIsTracker;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.load(args);%0A%20%20%20%20%20%20%20%20%20%20%20%20mark.end();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20measure()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.#args?.debug)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.monitor.measureAll();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20update()%20%7B%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Register%20a%20flag%20that%20will%20be%20added%20to%20page%20breakage%20reports%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20addDebugFlag()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.#isDebugFlagSet)%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.#isDebugFlagSet%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messaging?.notify('addDebugFlag',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20flag:%20this.name,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Define%20a%20property%20descriptor%20with%20debug%20flags.%0A%20%20%20%20%20%20%20%20%20*%20Mainly%20used%20for%20defining%20new%20properties.%20For%20overriding%20existing%20properties,%20consider%20using%20wrapProperty(),%20wrapMethod()%20and%20wrapConstructor().%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bany%7D%20object%20-%20object%20whose%20property%20we%20are%20wrapping%20(most%20commonly%20a%20prototype,%20e.g.%20globalThis.BatteryManager.prototype)%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20propertyName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('./wrapper-utils').StrictPropertyDescriptor%7D%20descriptor%20-%20requires%20all%20descriptor%20options%20to%20be%20defined%20because%20we%20can't%20validate%20correctness%20based%20on%20TS%20types%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20defineProperty(object,%20propertyName,%20descriptor)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20make%20sure%20to%20send%20a%20debug%20flag%20when%20the%20property%20is%20used%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20NOTE:%20properties%20passing%20data%20in%20%60value%60%20would%20not%20be%20caught%20by%20this%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B'value',%20'get',%20'set'%5D.forEach((k)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20descriptorProp%20=%20descriptor%5Bk%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20descriptorProp%20===%20'function')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20addDebugFlag%20=%20this.addDebugFlag.bind(this);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20wrapper%20=%20new%20Proxy$1(descriptorProp,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20argumentsList)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20addDebugFlag();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20Reflect$1.apply(descriptorProp,%20thisArg,%20argumentsList);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20descriptor%5Bk%5D%20=%20wrapToString(wrapper,%20descriptorProp);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20defineProperty(object,%20propertyName,%20descriptor);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Wrap%20a%20%60get%60/%60set%60%20or%20%60value%60%20property%20descriptor.%20Only%20for%20data%20properties.%20For%20methods,%20use%20wrapMethod().%20For%20constructors,%20use%20wrapConstructor().%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bany%7D%20object%20-%20object%20whose%20property%20we%20are%20wrapping%20(most%20commonly%20a%20prototype,%20e.g.%20globalThis.Screen.prototype)%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20propertyName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BPartial%3CPropertyDescriptor%3E%7D%20descriptor%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPropertyDescriptor%7Cundefined%7D%20original%20property%20descriptor,%20or%20undefined%20if%20it's%20not%20found%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20wrapProperty(object,%20propertyName,%20descriptor)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20wrapProperty(object,%20propertyName,%20descriptor,%20this.defineProperty.bind(this));%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Wrap%20a%20method%20descriptor.%20Only%20for%20function%20properties.%20For%20data%20properties,%20use%20wrapProperty().%20For%20constructors,%20use%20wrapConstructor().%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bany%7D%20object%20-%20object%20whose%20property%20we%20are%20wrapping%20(most%20commonly%20a%20prototype,%20e.g.%20globalThis.Bluetooth.prototype)%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20propertyName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(originalFn,%20...args)%20=%3E%20any%20%7D%20wrapperFn%20-%20wrapper%20function%20receives%20the%20original%20function%20as%20the%20first%20argument%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPropertyDescriptor%7Cundefined%7D%20original%20property%20descriptor,%20or%20undefined%20if%20it's%20not%20found%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20wrapMethod(object,%20propertyName,%20wrapperFn)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20wrapMethod(object,%20propertyName,%20wrapperFn,%20this.defineProperty.bind(this));%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@template%20%7Bkeyof%20typeof%20globalThis%7D%20StandardInterfaceName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BStandardInterfaceName%7D%20interfaceName%20-%20the%20name%20of%20the%20interface%20to%20shim%20(must%20be%20some%20known%20standard%20API,%20e.g.%20'MediaSession')%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Btypeof%20globalThis%5BStandardInterfaceName%5D%7D%20ImplClass%20-%20the%20class%20to%20use%20as%20the%20shim%20implementation%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('./wrapper-utils').DefineInterfaceOptions%7D%20options%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20shimInterface(interfaceName,%20ImplClass,%20options)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20shimInterface(interfaceName,%20ImplClass,%20options,%20this.defineProperty.bind(this));%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Define%20a%20missing%20standard%20property%20on%20a%20global%20(prototype)%20object.%20Only%20for%20data%20properties.%0A%20%20%20%20%20%20%20%20%20*%20For%20constructors,%20use%20shimInterface().%0A%20%20%20%20%20%20%20%20%20*%20Most%20of%20the%20time,%20you'd%20want%20to%20call%20shimInterface()%20first%20to%20shim%20the%20class%20itself%20(MediaSession),%20and%20then%20shimProperty()%20for%20the%20global%20singleton%20instance%20(Navigator.prototype.mediaSession).%0A%20%20%20%20%20%20%20%20%20*%20@template%20Base%0A%20%20%20%20%20%20%20%20%20*%20@template%20%7Bkeyof%20Base%20&%20string%7D%20K%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BBase%7D%20instanceHost%20-%20object%20whose%20property%20we%20are%20shimming%20(most%20commonly%20a%20prototype%20object,%20e.g.%20Navigator.prototype)%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BK%7D%20instanceProp%20-%20name%20of%20the%20property%20to%20shim%20(e.g.%20'mediaSession')%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BBase%5BK%5D%7D%20implInstance%20-%20instance%20to%20use%20as%20the%20shim%20(e.g.%20new%20MyMediaSession())%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean%7D%20%5BreadOnly%5D%20-%20whether%20the%20property%20should%20be%20read-only%20(default:%20false)%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20shimProperty(instanceHost,%20instanceProp,%20implInstance,%20readOnly%20=%20false)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20shimProperty(instanceHost,%20instanceProp,%20implInstance,%20readOnly,%20this.defineProperty.bind(this));%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Check%20if%20the%20current%20document%20origin%20is%20on%20the%20tracker%20list,%20using%20the%20provided%20lookup%20trie.%0A%20%20%20%20%20*%20@param%20%7Bobject%7D%20trackerLookup%20Trie%20lookup%20of%20tracker%20domains%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%20True%20iff%20the%20origin%20is%20a%20tracker.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isTrackerOrigin(trackerLookup,%20originHostname%20=%20document.location.hostname)%20%7B%0A%20%20%20%20%20%20%20%20const%20parts%20=%20originHostname.split('.').reverse();%0A%20%20%20%20%20%20%20%20let%20node%20=%20trackerLookup;%0A%20%20%20%20%20%20%20%20for%20(const%20sub%20of%20parts)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(node%5Bsub%5D%20===%201)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(node%5Bsub%5D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20node%20=%20node%5Bsub%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20ExtensionCookiePolicy%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20isFrame%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20isTracker%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20shouldBlock%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20isThirdPartyFrame%0A%20%20%20%20%20*/%0A%0A%20%20%20%20function%20initialShouldBlockTrackerCookie()%20%7B%0A%20%20%20%20%20%20%20%20const%20injectName%20=%20%22chrome%22;%0A%20%20%20%20%20%20%20%20return%20injectName%20===%20'chrome';%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20Initial%20cookie%20policy%20pre%20init%0A%20%20%20%20let%20cookiePolicy%20=%20%7B%0A%20%20%20%20%20%20%20%20debug:%20false,%0A%20%20%20%20%20%20%20%20isFrame:%20isBeingFramed(),%0A%20%20%20%20%20%20%20%20isTracker:%20false,%0A%20%20%20%20%20%20%20%20shouldBlock:%20true,%0A%20%20%20%20%20%20%20%20shouldBlockTrackerCookie:%20initialShouldBlockTrackerCookie(),%0A%20%20%20%20%20%20%20%20shouldBlockNonTrackerCookie:%20false,%0A%20%20%20%20%20%20%20%20isThirdPartyFrame:%20isThirdPartyFrame(),%0A%20%20%20%20%20%20%20%20policy:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20threshold:%20604800,%20//%207%20days%0A%20%20%20%20%20%20%20%20%20%20%20%20maxAge:%20604800,%20//%207%20days%0A%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20trackerPolicy:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20threshold:%2086400,%20//%201%20day%0A%20%20%20%20%20%20%20%20%20%20%20%20maxAge:%2086400,%20//%201%20day%0A%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20allowlist:%20/**%20@type%20%7B%7B%20host:%20string%20%7D%5B%5D%7D%20*/%20(%5B%5D),%0A%20%20%20%20%7D;%0A%20%20%20%20let%20trackerLookup%20=%20%7B%7D;%0A%0A%20%20%20%20let%20loadedPolicyResolve;%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7B'ignore'%20%7C%20'block'%20%7C%20'restrict'%7D%20action%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20reason%0A%20%20%20%20%20*%20@param%20%7Bany%7D%20ctx%0A%20%20%20%20%20*/%0A%20%20%20%20function%20debugHelper(action,%20reason,%20ctx)%20%7B%0A%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/no-unused-expressions%0A%20%20%20%20%20%20%20%20cookiePolicy.debug%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20postDebugMessage('jscookie',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20action,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20reason,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20stack:%20ctx.stack,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20documentUrl:%20globalThis.document.location.href,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value:%20ctx.value,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20shouldBlockTrackingCookie()%20%7B%0A%20%20%20%20%20%20%20%20return%20cookiePolicy.shouldBlock%20&&%20cookiePolicy.shouldBlockTrackerCookie%20&&%20isTrackingCookie();%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20shouldBlockNonTrackingCookie()%20%7B%0A%20%20%20%20%20%20%20%20return%20cookiePolicy.shouldBlock%20&&%20cookiePolicy.shouldBlockNonTrackerCookie%20&&%20isNonTrackingCookie();%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7BSet%3Cstring%3E%7D%20scriptOrigins%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isFirstPartyTrackerScript(scriptOrigins)%20%7B%0A%20%20%20%20%20%20%20%20let%20matched%20=%20false;%0A%20%20%20%20%20%20%20%20for%20(const%20scriptOrigin%20of%20scriptOrigins)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(cookiePolicy.allowlist.find((allowlistOrigin)%20=%3E%20matchHostname(allowlistOrigin.host,%20scriptOrigin)))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(isTrackerOrigin(trackerLookup,%20scriptOrigin))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20matched%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20matched;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isTrackingCookie()%20%7B%0A%20%20%20%20%20%20%20%20return%20cookiePolicy.isFrame%20&&%20cookiePolicy.isTracker%20&&%20cookiePolicy.isThirdPartyFrame;%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20isNonTrackingCookie()%20%7B%0A%20%20%20%20%20%20%20%20return%20cookiePolicy.isFrame%20&&%20!cookiePolicy.isTracker%20&&%20cookiePolicy.isThirdPartyFrame;%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20CookieFeature%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20load()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.documentOriginIsTracker)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookiePolicy.isTracker%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.trackerLookup)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20trackerLookup%20=%20this.trackerLookup;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.bundledConfig?.features?.cookie)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20use%20the%20bundled%20config%20to%20get%20a%20best-effort%20at%20the%20policy,%20before%20the%20background%20sends%20the%20real%20one%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20exceptions,%20settings%20%7D%20=%20this.bundledConfig.features.cookie;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20tabHostname%20=%20getTabHostname();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20tabExempted%20=%20true;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(tabHostname%20!=%20null)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tabExempted%20=%20exceptions.some((exception)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20matchHostname(tabHostname,%20exception.domain);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20frameExempted%20=%20settings.excludedCookieDomains.some((exception)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20matchHostname(globalThis.location.hostname,%20exception.domain);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookiePolicy.shouldBlock%20=%20!frameExempted%20&&%20!tabExempted;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookiePolicy.policy%20=%20settings.firstPartyCookiePolicy;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookiePolicy.trackerPolicy%20=%20settings.firstPartyTrackerCookiePolicy;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Allows%20for%20ad%20click%20conversion%20detection%20as%20described%20by%20https://help.duckduckgo.com/duckduckgo-help-pages/privacy/web-tracking-protections/.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20This%20only%20applies%20when%20the%20resources%20that%20would%20set%20these%20cookies%20are%20unblocked.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookiePolicy.allowlist%20=%20this.getFeatureSetting('allowlist',%20'adClickAttribution')%20%7C%7C%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20The%20cookie%20policy%20is%20injected%20into%20every%20frame%20immediately%20so%20that%20no%20cookie%20will%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20be%20missed.%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20document%20=%20globalThis.document;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Object%20is%20possibly%20'undefined'.%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cookieSetter%20=%20Object.getOwnPropertyDescriptor(globalThis.Document.prototype,%20'cookie').set;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Object%20is%20possibly%20'undefined'.%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cookieGetter%20=%20Object.getOwnPropertyDescriptor(globalThis.Document.prototype,%20'cookie').get;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20loadPolicy%20=%20new%20Promise((resolve)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loadedPolicyResolve%20=%20resolve;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Create%20the%20then%20callback%20now%20-%20this%20ensures%20that%20Promise.prototype.then%20changes%20won't%20break%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20this%20call.%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20loadPolicyThen%20=%20loadPolicy.then.bind(loadPolicy);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20getCookiePolicy()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20getCookieContext%20=%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(cookiePolicy.debug)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20stack%20=%20getStack();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20getCookieContext%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20stack,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value:%20'getter',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(shouldBlockTrackingCookie()%20%7C%7C%20shouldBlockNonTrackingCookie())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debugHelper('block',%20'3p%20frame',%20getCookieContext);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20'';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(isTrackingCookie()%20%7C%7C%20isNonTrackingCookie())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debugHelper('ignore',%20'3p%20frame',%20getCookieContext);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'cookieGetter'%20is%20possibly%20'undefined'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20cookieGetter.call(this);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7Bany%7D%20argValue%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20setCookiePolicy(argValue)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20setCookieContext%20=%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!argValue?.toString%20%7C%7C%20typeof%20argValue.toString()%20!==%20'string')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20not%20a%20string,%20or%20string-like%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20value%20=%20argValue.toString();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(cookiePolicy.debug)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20stack%20=%20getStack();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20setCookieContext%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20stack,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(shouldBlockTrackingCookie()%20%7C%7C%20shouldBlockNonTrackingCookie())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debugHelper('block',%20'3p%20frame',%20setCookieContext);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(isTrackingCookie()%20%7C%7C%20isNonTrackingCookie())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debugHelper('ignore',%20'3p%20frame',%20setCookieContext);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20call%20the%20native%20document.cookie%20implementation.%20This%20will%20set%20the%20cookie%20immediately%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20if%20the%20value%20is%20valid.%20We%20will%20override%20this%20set%20later%20if%20the%20policy%20dictates%20that%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20the%20expiry%20should%20be%20changed.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'cookieSetter'%20is%20possibly%20'undefined'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookieSetter.call(this,%20argValue);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20wait%20for%20config%20before%20doing%20same-site%20tests%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loadPolicyThen(()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20shouldBlock,%20policy,%20trackerPolicy%20%7D%20=%20cookiePolicy;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20stack%20=%20getStack();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20scriptOrigins%20=%20getStackTraceOrigins(stack);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20chosenPolicy%20=%20isFirstPartyTrackerScript(scriptOrigins)%20?%20trackerPolicy%20:%20policy;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!shouldBlock)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debugHelper('ignore',%20'disabled',%20setCookieContext);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20extract%20cookie%20expiry%20from%20cookie%20string%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20cookie%20=%20new%20Cookie(value);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20apply%20cookie%20policy%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(cookie.getExpiry()%20%3E%20chosenPolicy.threshold)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20check%20if%20the%20cookie%20still%20exists%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(document.cookie.split(';').findIndex((kv)%20=%3E%20kv.trim().startsWith(cookie.parts%5B0%5D.trim()))%20!==%20-1)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookie.maxAge%20=%20chosenPolicy.maxAge;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debugHelper('restrict',%20'expiry',%20setCookieContext);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'cookieSetter'%20is%20possibly%20'undefined'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookieSetter.apply(document,%20%5Bcookie.toString()%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debugHelper('ignore',%20'dissappeared',%20setCookieContext);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debugHelper('ignore',%20'expiry',%20setCookieContext);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debugHelper('ignore',%20'error',%20setCookieContext);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20suppress%20error%20in%20cookie%20override%20to%20avoid%20breakage%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.warn('Error%20in%20cookie%20override',%20e);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Document.prototype,%20'cookie',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20set:%20setCookiePolicy,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20getCookiePolicy,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20init(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20restOfPolicy%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debug:%20this.isDebug,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20shouldBlockTrackerCookie:%20this.getFeatureSettingEnabled('trackerCookie'),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20shouldBlockNonTrackerCookie:%20this.getFeatureSettingEnabled('nonTrackerCookie'),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20allowlist:%20this.getFeatureSetting('allowlist',%20'adClickAttribution')%20%7C%7C%20%5B%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20policy:%20this.getFeatureSetting('firstPartyCookiePolicy'),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20trackerPolicy:%20this.getFeatureSetting('firstPartyTrackerCookiePolicy'),%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20The%20extension%20provides%20some%20additional%20info%20about%20the%20cookie%20policy,%20let's%20use%20that%20over%20our%20guesses%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(args.cookie)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20extensionCookiePolicy%20=%20/**%20@type%20%7BExtensionCookiePolicy%7D%20*/%20(args.cookie);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookiePolicy%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20...extensionCookiePolicy,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20...restOfPolicy,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20copy%20non-null%20entries%20from%20restOfPolicy%20to%20cookiePolicy%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Object.keys(restOfPolicy).forEach((key)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(restOfPolicy%5Bkey%5D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookiePolicy%5Bkey%5D%20=%20restOfPolicy%5Bkey%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20loadedPolicyResolve();%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20@ts-nocheck%0A%20%20%20%20const%20sjcl%20=%20(()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20/*jslint%20indent:%202,%20bitwise:%20false,%20nomen:%20false,%20plusplus:%20false,%20white:%20false,%20regexp:%20false%20*/%0A%20%20%20%20%20%20%20%20/*global%20document,%20window,%20escape,%20unescape,%20module,%20require,%20Uint32Array%20*/%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20The%20Stanford%20Javascript%20Crypto%20Library,%20top-level%20namespace.%0A%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20var%20sjcl%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Symmetric%20ciphers.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20cipher:%20%7B%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Hash%20functions.%20%20Right%20now%20only%20SHA256%20is%20implemented.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20hash:%20%7B%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Key%20exchange%20functions.%20%20Right%20now%20only%20SRP%20is%20implemented.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20keyexchange:%20%7B%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Cipher%20modes%20of%20operation.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20mode:%20%7B%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Miscellaneous.%20%20HMAC%20and%20PBKDF2.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20misc:%20%7B%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Bit%20array%20encoders%20and%20decoders.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@description%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20members%20of%20this%20namespace%20are%20functions%20which%20translate%20between%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20SJCL's%20bitArrays%20and%20other%20objects%20(usually%20strings).%20%20Because%20it%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20isn't%20always%20clear%20which%20direction%20is%20encoding%20and%20which%20is%20decoding,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20the%20method%20names%20are%20%22fromBits%22%20and%20%22toBits%22.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20codec:%20%7B%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Exceptions.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20exception:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Ciphertext%20is%20corrupt.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@constructor%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20corrupt:%20function%20(message)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.toString%20=%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20'CORRUPT:%20'%20+%20this.message;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.message%20=%20message;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Invalid%20parameter.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@constructor%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20invalid:%20function%20(message)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.toString%20=%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20'INVALID:%20'%20+%20this.message;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.message%20=%20message;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Bug%20or%20missing%20feature%20in%20SJCL.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@constructor%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20bug:%20function%20(message)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.toString%20=%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20'BUG:%20'%20+%20this.message;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.message%20=%20message;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Something%20isn't%20ready.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@constructor%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20notReady:%20function%20(message)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.toString%20=%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20'NOT%20READY:%20'%20+%20this.message;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.message%20=%20message;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20/**%20@fileOverview%20Arrays%20of%20bits,%20encoded%20as%20arrays%20of%20Numbers.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@author%20Emily%20Stark%0A%20%20%20%20%20%20%20%20%20*%20@author%20Mike%20Hamburg%0A%20%20%20%20%20%20%20%20%20*%20@author%20Dan%20Boneh%0A%20%20%20%20%20%20%20%20%20*/%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Arrays%20of%20bits,%20encoded%20as%20arrays%20of%20Numbers.%0A%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20*%20@description%0A%20%20%20%20%20%20%20%20%20*%20%3Cp%3E%0A%20%20%20%20%20%20%20%20%20*%20These%20objects%20are%20the%20currency%20accepted%20by%20SJCL's%20crypto%20functions.%0A%20%20%20%20%20%20%20%20%20*%20%3C/p%3E%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20%3Cp%3E%0A%20%20%20%20%20%20%20%20%20*%20Most%20of%20our%20crypto%20primitives%20operate%20on%20arrays%20of%204-byte%20words%20internally,%0A%20%20%20%20%20%20%20%20%20*%20but%20many%20of%20them%20can%20take%20arguments%20that%20are%20not%20a%20multiple%20of%204%20bytes.%0A%20%20%20%20%20%20%20%20%20*%20This%20library%20encodes%20arrays%20of%20bits%20(whose%20size%20need%20not%20be%20a%20multiple%20of%208%0A%20%20%20%20%20%20%20%20%20*%20bits)%20as%20arrays%20of%2032-bit%20words.%20%20The%20bits%20are%20packed,%20big-endian,%20into%20an%0A%20%20%20%20%20%20%20%20%20*%20array%20of%20words,%2032%20bits%20at%20a%20time.%20%20Since%20the%20words%20are%20double-precision%0A%20%20%20%20%20%20%20%20%20*%20floating%20point%20numbers,%20they%20fit%20some%20extra%20data.%20%20We%20use%20this%20(in%20a%20private,%0A%20%20%20%20%20%20%20%20%20*%20possibly-changing%20manner)%20to%20encode%20the%20number%20of%20bits%20actually%20%20present%0A%20%20%20%20%20%20%20%20%20*%20in%20the%20last%20word%20of%20the%20array.%0A%20%20%20%20%20%20%20%20%20*%20%3C/p%3E%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20%3Cp%3E%0A%20%20%20%20%20%20%20%20%20*%20Because%20bitwise%20ops%20clear%20this%20out-of-band%20data,%20these%20arrays%20can%20be%20passed%0A%20%20%20%20%20%20%20%20%20*%20to%20ciphers%20like%20AES%20which%20want%20arrays%20of%20words.%0A%20%20%20%20%20%20%20%20%20*%20%3C/p%3E%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20sjcl.bitArray%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Array%20slices%20in%20units%20of%20bits.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20a%20The%20array%20to%20slice.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20bstart%20The%20offset%20to%20the%20start%20of%20the%20slice,%20in%20bits.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20bend%20The%20offset%20to%20the%20end%20of%20the%20slice,%20in%20bits.%20%20If%20this%20is%20undefined,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20slice%20until%20the%20end%20of%20the%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7BbitArray%7D%20The%20requested%20slice.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20bitSlice:%20function%20(a,%20bstart,%20bend)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%20=%20sjcl.bitArray._shiftRight(a.slice(bstart%20/%2032),%2032%20-%20(bstart%20&%2031)).slice(1);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20bend%20===%20undefined%20?%20a%20:%20sjcl.bitArray.clamp(a,%20bend%20-%20bstart);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Extract%20a%20number%20packed%20into%20a%20bit%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20a%20The%20array%20to%20slice.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20bstart%20The%20offset%20to%20the%20start%20of%20the%20slice,%20in%20bits.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20blength%20The%20length%20of%20the%20number%20to%20extract.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7BNumber%7D%20The%20requested%20slice.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20extract:%20function%20(a,%20bstart,%20blength)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20FIXME:%20this%20Math.floor%20is%20not%20necessary%20at%20all,%20but%20for%20some%20reason%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20seems%20to%20suppress%20a%20bug%20in%20the%20Chromium%20JIT.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20x,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sh%20=%20Math.floor((-bstart%20-%20blength)%20&%2031);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(((bstart%20+%20blength%20-%201)%20%5E%20bstart)%20&%20-32)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20it%20crosses%20a%20boundary%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%20=%20(a%5B(bstart%20/%2032)%20%7C%200%5D%20%3C%3C%20(32%20-%20sh))%20%5E%20(a%5B(bstart%20/%2032%20+%201)%20%7C%200%5D%20%3E%3E%3E%20sh);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20within%20a%20single%20word%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%20=%20a%5B(bstart%20/%2032)%20%7C%200%5D%20%3E%3E%3E%20sh;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20x%20&%20((1%20%3C%3C%20blength)%20-%201);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Concatenate%20two%20bit%20arrays.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20a1%20The%20first%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20a2%20The%20second%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7BbitArray%7D%20The%20concatenation%20of%20a1%20and%20a2.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20concat:%20function%20(a1,%20a2)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(a1.length%20===%200%20%7C%7C%20a2.length%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20a1.concat(a2);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20last%20=%20a1%5Ba1.length%20-%201%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20shift%20=%20sjcl.bitArray.getPartial(last);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(shift%20===%2032)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20a1.concat(a2);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20sjcl.bitArray._shiftRight(a2,%20shift,%20last%20%7C%200,%20a1.slice(0,%20a1.length%20-%201));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Find%20the%20length%20of%20an%20array%20of%20bits.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20a%20The%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7BNumber%7D%20The%20length%20of%20a,%20in%20bits.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20bitLength:%20function%20(a)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20l%20=%20a.length,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(l%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%20=%20a%5Bl%20-%201%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20(l%20-%201)%20*%2032%20+%20sjcl.bitArray.getPartial(x);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Truncate%20an%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20a%20The%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20len%20The%20length%20to%20truncate%20to,%20in%20bits.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7BbitArray%7D%20A%20new%20array,%20truncated%20to%20len%20bits.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20clamp:%20function%20(a,%20len)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(a.length%20*%2032%20%3C%20len)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20a;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%20=%20a.slice(0,%20Math.ceil(len%20/%2032));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20l%20=%20a.length;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20len%20=%20len%20&%2031;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(l%20%3E%200%20&&%20len)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%5Bl%20-%201%5D%20=%20sjcl.bitArray.partial(len,%20a%5Bl%20-%201%5D%20&%20(0x80000000%20%3E%3E%20(len%20-%201)),%201);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20a;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Make%20a%20partial%20word%20for%20a%20bit%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20len%20The%20number%20of%20bits%20in%20the%20word.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20x%20The%20bits.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20%5B_end=0%5D%20Pass%201%20if%20x%20has%20already%20been%20shifted%20to%20the%20high%20side.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7BNumber%7D%20The%20partial%20word.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20partial:%20function%20(len,%20x,%20_end)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(len%20===%2032)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20x;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20(_end%20?%20x%20%7C%200%20:%20x%20%3C%3C%20(32%20-%20len))%20+%20len%20*%200x10000000000;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Get%20the%20number%20of%20bits%20used%20by%20a%20partial%20word.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20x%20The%20partial%20word.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7BNumber%7D%20The%20number%20of%20bits%20used%20by%20the%20partial%20word.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20getPartial:%20function%20(x)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20Math.round(x%20/%200x10000000000)%20%7C%7C%2032;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Compare%20two%20arrays%20for%20equality%20in%20a%20predictable%20amount%20of%20time.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20a%20The%20first%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20b%20The%20second%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7Bboolean%7D%20true%20if%20a%20==%20b;%20false%20otherwise.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20equal:%20function%20(a,%20b)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(sjcl.bitArray.bitLength(a)%20!==%20sjcl.bitArray.bitLength(b))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20x%20=%200,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20i;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%200;%20i%20%3C%20a.length;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%20%7C=%20a%5Bi%5D%20%5E%20b%5Bi%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20x%20===%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20Shift%20an%20array%20right.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20a%20The%20array%20to%20shift.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20shift%20The%20number%20of%20bits%20to%20shift.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20%5Bcarry=0%5D%20A%20byte%20to%20carry%20in%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20%5Bout=%5B%5D%5D%20An%20array%20to%20prepend%20to%20the%20output.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@private%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20_shiftRight:%20function%20(a,%20shift,%20carry,%20out)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20i,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20last2%20=%200,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20shift2;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(out%20===%20undefined)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(;%20shift%20%3E=%2032;%20shift%20-=%2032)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out.push(carry);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20carry%20=%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(shift%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20out.concat(a);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%200;%20i%20%3C%20a.length;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out.push(carry%20%7C%20(a%5Bi%5D%20%3E%3E%3E%20shift));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20carry%20=%20a%5Bi%5D%20%3C%3C%20(32%20-%20shift);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20last2%20=%20a.length%20?%20a%5Ba.length%20-%201%5D%20:%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20shift2%20=%20sjcl.bitArray.getPartial(last2);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out.push(sjcl.bitArray.partial((shift%20+%20shift2)%20&%2031,%20shift%20+%20shift2%20%3E%2032%20?%20carry%20:%20out.pop(),%201));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20out;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20xor%20a%20block%20of%204%20words%20together.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@private%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20_xor4:%20function%20(x,%20y)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%5Bx%5B0%5D%20%5E%20y%5B0%5D,%20x%5B1%5D%20%5E%20y%5B1%5D,%20x%5B2%5D%20%5E%20y%5B2%5D,%20x%5B3%5D%20%5E%20y%5B3%5D%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20byteswap%20a%20word%20array%20inplace.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20(does%20not%20handle%20partial%20words)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7Bsjcl.bitArray%7D%20a%20word%20array%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7Bsjcl.bitArray%7D%20byteswapped%20array%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20byteswapM:%20function%20(a)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20i,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20m%20=%200xff00;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%200;%20i%20%3C%20a.length;%20++i)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v%20=%20a%5Bi%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%5Bi%5D%20=%20(v%20%3E%3E%3E%2024)%20%7C%20((v%20%3E%3E%3E%208)%20&%20m)%20%7C%20((v%20&%20m)%20%3C%3C%208)%20%7C%20(v%20%3C%3C%2024);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20a;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20/**%20@fileOverview%20Bit%20array%20codec%20implementations.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@author%20Emily%20Stark%0A%20%20%20%20%20%20%20%20%20*%20@author%20Mike%20Hamburg%0A%20%20%20%20%20%20%20%20%20*%20@author%20Dan%20Boneh%0A%20%20%20%20%20%20%20%20%20*/%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20UTF-8%20strings%0A%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20sjcl.codec.utf8String%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20Convert%20from%20a%20bitArray%20to%20a%20UTF-8%20string.%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20fromBits:%20function%20(arr)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20out%20=%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20bl%20=%20sjcl.bitArray.bitLength(arr),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20i,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%200;%20i%20%3C%20bl%20/%208;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20((i%20&%203)%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp%20=%20arr%5Bi%20/%204%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out%20+=%20String.fromCharCode(((tmp%20%3E%3E%3E%208)%20%3E%3E%3E%208)%20%3E%3E%3E%208);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp%20%3C%3C=%208;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20decodeURIComponent(escape(out));%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20Convert%20from%20a%20UTF-8%20string%20to%20a%20bitArray.%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20toBits:%20function%20(str)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20str%20=%20unescape(encodeURIComponent(str));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20out%20=%20%5B%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20i,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp%20=%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%200;%20i%20%3C%20str.length;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp%20=%20(tmp%20%3C%3C%208)%20%7C%20str.charCodeAt(i);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20((i%20&%203)%20===%203)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out.push(tmp);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp%20=%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(i%20&%203)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out.push(sjcl.bitArray.partial(8%20*%20(i%20&%203),%20tmp));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20out;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20/**%20@fileOverview%20Bit%20array%20codec%20implementations.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@author%20Emily%20Stark%0A%20%20%20%20%20%20%20%20%20*%20@author%20Mike%20Hamburg%0A%20%20%20%20%20%20%20%20%20*%20@author%20Dan%20Boneh%0A%20%20%20%20%20%20%20%20%20*/%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Hexadecimal%0A%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20sjcl.codec.hex%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20Convert%20from%20a%20bitArray%20to%20a%20hex%20string.%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20fromBits:%20function%20(arr)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20out%20=%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20i;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%200;%20i%20%3C%20arr.length;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out%20+=%20((arr%5Bi%5D%20%7C%200)%20+%200xf00000000000).toString(16).substr(4);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20out.substr(0,%20sjcl.bitArray.bitLength(arr)%20/%204);%20//.replace(/(.%7B8%7D)/g,%20%22$1%20%22);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20Convert%20from%20a%20hex%20string%20to%20a%20bitArray.%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20toBits:%20function%20(str)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20i,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out%20=%20%5B%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20len;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20str%20=%20str.replace(/%5Cs%7C0x/g,%20'');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20len%20=%20str.length;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20str%20=%20str%20+%20'00000000';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%200;%20i%20%3C%20str.length;%20i%20+=%208)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out.push(parseInt(str.substr(i,%208),%2016)%20%5E%200);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20sjcl.bitArray.clamp(out,%20len%20*%204);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%20@fileOverview%20Javascript%20SHA-256%20implementation.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20An%20older%20version%20of%20this%20implementation%20is%20available%20in%20the%20public%0A%20%20%20%20%20%20%20%20%20*%20domain,%20but%20this%20one%20is%20(c)%20Emily%20Stark,%20Mike%20Hamburg,%20Dan%20Boneh,%0A%20%20%20%20%20%20%20%20%20*%20Stanford%20University%202008-2010%20and%20BSD-licensed%20for%20liability%0A%20%20%20%20%20%20%20%20%20*%20reasons.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20Special%20thanks%20to%20Aldo%20Cortesi%20for%20pointing%20out%20several%20bugs%20in%0A%20%20%20%20%20%20%20%20%20*%20this%20code.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@author%20Emily%20Stark%0A%20%20%20%20%20%20%20%20%20*%20@author%20Mike%20Hamburg%0A%20%20%20%20%20%20%20%20%20*%20@author%20Dan%20Boneh%0A%20%20%20%20%20%20%20%20%20*/%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Context%20for%20a%20SHA-256%20operation%20in%20progress.%0A%20%20%20%20%20%20%20%20%20*%20@constructor%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20sjcl.hash.sha256%20=%20function%20(hash)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this._key%5B0%5D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._precompute();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(hash)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._h%20=%20hash._h.slice(0);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._buffer%20=%20hash._buffer.slice(0);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._length%20=%20hash._length;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.reset();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Hash%20a%20string%20or%20an%20array%20of%20words.%0A%20%20%20%20%20%20%20%20%20*%20@static%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7CString%7D%20data%20the%20data%20to%20hash.%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7BbitArray%7D%20The%20hash%20value,%20an%20array%20of%2016%20big-endian%20words.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20sjcl.hash.sha256.hash%20=%20function%20(data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20sjcl.hash.sha256().update(data).finalize();%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20sjcl.hash.sha256.prototype%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20hash's%20block%20size,%20in%20bits.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@constant%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20blockSize:%20512,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Reset%20the%20hash%20state.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20this%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20reset:%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._h%20=%20this._init.slice(0);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._buffer%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._length%20=%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Input%20several%20words%20to%20the%20hash.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7CString%7D%20data%20the%20data%20to%20hash.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20this%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20update:%20function%20(data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20data%20===%20'string')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20data%20=%20sjcl.codec.utf8String.toBits(data);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20i,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b%20=%20(this._buffer%20=%20sjcl.bitArray.concat(this._buffer,%20data)),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ol%20=%20this._length,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20nl%20=%20(this._length%20=%20ol%20+%20sjcl.bitArray.bitLength(data));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(nl%20%3E%209007199254740991)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20sjcl.exception.invalid('Cannot%20hash%20more%20than%202%5E53%20-%201%20bits');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20Uint32Array%20!==%20'undefined')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20c%20=%20new%20Uint32Array(b);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20j%20=%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%20512%20+%20ol%20-%20((512%20+%20ol)%20&%20511);%20i%20%3C=%20nl;%20i%20+=%20512)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._block(c.subarray(16%20*%20j,%2016%20*%20(j%20+%201)));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20j%20+=%201;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b.splice(0,%2016%20*%20j);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%20512%20+%20ol%20-%20((512%20+%20ol)%20&%20511);%20i%20%3C=%20nl;%20i%20+=%20512)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._block(b.splice(0,%2016));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Complete%20hashing%20and%20output%20the%20hash%20value.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7BbitArray%7D%20The%20hash%20value,%20an%20array%20of%208%20big-endian%20words.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20finalize:%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20i,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b%20=%20this._buffer,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%20=%20this._h;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Round%20out%20and%20push%20the%20buffer%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b%20=%20sjcl.bitArray.concat(b,%20%5Bsjcl.bitArray.partial(1,%201)%5D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Round%20out%20the%20buffer%20to%20a%20multiple%20of%2016%20words,%20less%20the%202%20length%20words.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%20b.length%20+%202;%20i%20&%2015;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b.push(0);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20append%20the%20length%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b.push(Math.floor(this._length%20/%200x100000000));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b.push(this._length%20%7C%200);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20while%20(b.length)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._block(b.splice(0,%2016));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.reset();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20h;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20SHA-256%20initialization%20vector,%20to%20be%20precomputed.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@private%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20_init:%20%5B%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20/*%0A%20%20%20%20%20%20_init:%5B0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19%5D,%0A%20%20%20%20%20%20*/%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20SHA-256%20hash%20key,%20to%20be%20precomputed.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@private%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20_key:%20%5B%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20/*%0A%20%20%20%20%20%20_key:%0A%20%20%20%20%20%20%20%20%5B0x428a2f98,%200x71374491,%200xb5c0fbcf,%200xe9b5dba5,%200x3956c25b,%200x59f111f1,%200x923f82a4,%200xab1c5ed5,%0A%20%20%20%20%20%20%20%20%200xd807aa98,%200x12835b01,%200x243185be,%200x550c7dc3,%200x72be5d74,%200x80deb1fe,%200x9bdc06a7,%200xc19bf174,%0A%20%20%20%20%20%20%20%20%200xe49b69c1,%200xefbe4786,%200x0fc19dc6,%200x240ca1cc,%200x2de92c6f,%200x4a7484aa,%200x5cb0a9dc,%200x76f988da,%0A%20%20%20%20%20%20%20%20%200x983e5152,%200xa831c66d,%200xb00327c8,%200xbf597fc7,%200xc6e00bf3,%200xd5a79147,%200x06ca6351,%200x14292967,%0A%20%20%20%20%20%20%20%20%200x27b70a85,%200x2e1b2138,%200x4d2c6dfc,%200x53380d13,%200x650a7354,%200x766a0abb,%200x81c2c92e,%200x92722c85,%0A%20%20%20%20%20%20%20%20%200xa2bfe8a1,%200xa81a664b,%200xc24b8b70,%200xc76c51a3,%200xd192e819,%200xd6990624,%200xf40e3585,%200x106aa070,%0A%20%20%20%20%20%20%20%20%200x19a4c116,%200x1e376c08,%200x2748774c,%200x34b0bcb5,%200x391c0cb3,%200x4ed8aa4a,%200x5b9cca4f,%200x682e6ff3,%0A%20%20%20%20%20%20%20%20%200x748f82ee,%200x78a5636f,%200x84c87814,%200x8cc70208,%200x90befffa,%200xa4506ceb,%200xbef9a3f7,%200xc67178f2%5D,%0A%20%20%20%20%20%20*/%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Function%20to%20precompute%20_init%20and%20_key.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@private%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20_precompute:%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20i%20=%200,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20prime%20=%202,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20factor,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20isPrime;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20function%20frac(x)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20((x%20-%20Math.floor(x))%20*%200x100000000)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(;%20i%20%3C%2064;%20prime++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20isPrime%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(factor%20=%202;%20factor%20*%20factor%20%3C=%20prime;%20factor++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(prime%20%25%20factor%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20isPrime%20=%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(isPrime)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(i%20%3C%208)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._init%5Bi%5D%20=%20frac(Math.pow(prime,%201%20/%202));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._key%5Bi%5D%20=%20frac(Math.pow(prime,%201%20/%203));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20i++;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Perform%20one%20cycle%20of%20SHA-256.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BUint32Array%7CbitArray%7D%20w%20one%20block%20of%20words.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@private%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20_block:%20function%20(w)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20i,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%20=%20this._h,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20k%20=%20this._key,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h0%20=%20h%5B0%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h1%20=%20h%5B1%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h2%20=%20h%5B2%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h3%20=%20h%5B3%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h4%20=%20h%5B4%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h5%20=%20h%5B5%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h6%20=%20h%5B6%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h7%20=%20h%5B7%5D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/*%20Rationale%20for%20placement%20of%20%7C0%20:%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20If%20a%20value%20can%20overflow%20is%20original%2032%20bits%20by%20a%20factor%20of%20more%20than%20a%20few%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20million%20(2%5E23%20ish),%20there%20is%20a%20possibility%20that%20it%20might%20overflow%20the%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%2053-bit%20mantissa%20and%20lose%20precision.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20To%20avoid%20this,%20we%20clamp%20back%20to%2032%20bits%20by%20%7C'ing%20with%200%20on%20any%20value%20that%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20propagates%20around%20the%20loop,%20and%20on%20the%20hash%20state%20h%5B%5D.%20%20I%20don't%20believe%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20that%20the%20clamps%20on%20h4%20and%20on%20h0%20are%20strictly%20necessary,%20but%20it's%20close%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20(for%20h4%20anyway),%20and%20better%20safe%20than%20sorry.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20clamps%20on%20h%5B%5D%20are%20necessary%20for%20the%20output%20to%20be%20correct%20even%20in%20the%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20common%20case%20and%20for%20short%20inputs.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%200;%20i%20%3C%2064;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20load%20up%20the%20input%20word%20for%20this%20round%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(i%20%3C%2016)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp%20=%20w%5Bi%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%20=%20w%5B(i%20+%201)%20&%2015%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b%20=%20w%5B(i%20+%2014)%20&%2015%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp%20=%20w%5Bi%20&%2015%5D%20=%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(((a%20%3E%3E%3E%207)%20%5E%20(a%20%3E%3E%3E%2018)%20%5E%20(a%20%3E%3E%3E%203)%20%5E%20(a%20%3C%3C%2025)%20%5E%20(a%20%3C%3C%2014))%20+%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20((b%20%3E%3E%3E%2017)%20%5E%20(b%20%3E%3E%3E%2019)%20%5E%20(b%20%3E%3E%3E%2010)%20%5E%20(b%20%3C%3C%2015)%20%5E%20(b%20%3C%3C%2013))%20+%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20w%5Bi%20&%2015%5D%20+%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20w%5B(i%20+%209)%20&%2015%5D)%20%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp%20=%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp%20+%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h7%20+%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20((h4%20%3E%3E%3E%206)%20%5E%20(h4%20%3E%3E%3E%2011)%20%5E%20(h4%20%3E%3E%3E%2025)%20%5E%20(h4%20%3C%3C%2026)%20%5E%20(h4%20%3C%3C%2021)%20%5E%20(h4%20%3C%3C%207))%20+%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(h6%20%5E%20(h4%20&%20(h5%20%5E%20h6)))%20+%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20k%5Bi%5D;%20//%20%7C%200;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20shift%20register%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h7%20=%20h6;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h6%20=%20h5;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h5%20=%20h4;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h4%20=%20(h3%20+%20tmp)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h3%20=%20h2;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h2%20=%20h1;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h1%20=%20h0;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h0%20=%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(tmp%20+%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20((h1%20&%20h2)%20%5E%20(h3%20&%20(h1%20%5E%20h2)))%20+%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20((h1%20%3E%3E%3E%202)%20%5E%20(h1%20%3E%3E%3E%2013)%20%5E%20(h1%20%3E%3E%3E%2022)%20%5E%20(h1%20%3C%3C%2030)%20%5E%20(h1%20%3C%3C%2019)%20%5E%20(h1%20%3C%3C%2010)))%20%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%5B0%5D%20=%20(h%5B0%5D%20+%20h0)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%5B1%5D%20=%20(h%5B1%5D%20+%20h1)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%5B2%5D%20=%20(h%5B2%5D%20+%20h2)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%5B3%5D%20=%20(h%5B3%5D%20+%20h3)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%5B4%5D%20=%20(h%5B4%5D%20+%20h4)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%5B5%5D%20=%20(h%5B5%5D%20+%20h5)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%5B6%5D%20=%20(h%5B6%5D%20+%20h6)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%5B7%5D%20=%20(h%5B7%5D%20+%20h7)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%20@fileOverview%20HMAC%20implementation.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@author%20Emily%20Stark%0A%20%20%20%20%20%20%20%20%20*%20@author%20Mike%20Hamburg%0A%20%20%20%20%20%20%20%20%20*%20@author%20Dan%20Boneh%0A%20%20%20%20%20%20%20%20%20*/%0A%0A%20%20%20%20%20%20%20%20/**%20HMAC%20with%20the%20specified%20hash%20function.%0A%20%20%20%20%20%20%20%20%20*%20@constructor%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20key%20the%20key%20for%20HMAC.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BObject%7D%20%5BHash=sjcl.hash.sha256%5D%20The%20hash%20function%20to%20use.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20sjcl.misc.hmac%20=%20function%20(key,%20Hash)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this._hash%20=%20Hash%20=%20Hash%20%7C%7C%20sjcl.hash.sha256;%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20exKey%20=%20%5B%5B%5D,%20%5B%5D%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20i,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20bs%20=%20Hash.prototype.blockSize%20/%2032;%0A%20%20%20%20%20%20%20%20%20%20%20%20this._baseHash%20=%20%5Bnew%20Hash(),%20new%20Hash()%5D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(key.length%20%3E%20bs)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20key%20=%20Hash.hash(key);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%200;%20i%20%3C%20bs;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20exKey%5B0%5D%5Bi%5D%20=%20key%5Bi%5D%20%5E%200x36363636;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20exKey%5B1%5D%5Bi%5D%20=%20key%5Bi%5D%20%5E%200x5c5c5c5c;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this._baseHash%5B0%5D.update(exKey%5B0%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20this._baseHash%5B1%5D.update(exKey%5B1%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20this._resultHash%20=%20new%20Hash(this._baseHash%5B0%5D);%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%20HMAC%20with%20the%20specified%20hash%20function.%20%20Also%20called%20encrypt%20since%20it's%20a%20prf.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7CString%7D%20data%20The%20data%20to%20mac.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20sjcl.misc.hmac.prototype.encrypt%20=%20sjcl.misc.hmac.prototype.mac%20=%20function%20(data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this._updated)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.update(data);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this.digest(data);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20sjcl.exception.invalid('encrypt%20on%20already%20updated%20hmac%20called!');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20sjcl.misc.hmac.prototype.reset%20=%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this._resultHash%20=%20new%20this._hash(this._baseHash%5B0%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20this._updated%20=%20false;%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20sjcl.misc.hmac.prototype.update%20=%20function%20(data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this._updated%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20this._resultHash.update(data);%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20sjcl.misc.hmac.prototype.digest%20=%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20w%20=%20this._resultHash.finalize(),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result%20=%20new%20this._hash(this._baseHash%5B1%5D).update(w).finalize();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.reset();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20result;%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20return%20sjcl;%0A%20%20%20%20%7D)();%0A%0A%20%20%20%20function%20getDataKeySync(sessionKey,%20domainKey,%20inputData)%20%7B%0A%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20new-cap%0A%20%20%20%20%20%20%20%20const%20hmac%20=%20new%20sjcl.misc.hmac(sjcl.codec.utf8String.toBits(sessionKey%20+%20domainKey),%20sjcl.hash.sha256);%0A%20%20%20%20%20%20%20%20return%20sjcl.codec.hex.fromBits(hmac.encrypt(inputData));%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20FingerprintingAudio%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20sessionKey,%20site%20%7D%20=%20args;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20domainKey%20=%20site.domain;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20In%20place%20modify%20array%20data%20to%20remove%20fingerprinting%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20transformArrayData(channelData,%20domainKey,%20sessionKey,%20thisArg)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20%7B%20audioKey%20%7D%20=%20getCachedResponse(thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!audioKey)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20cdSum%20=%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20k%20in%20channelData)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cdSum%20+=%20channelData%5Bk%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20the%20buffer%20is%20blank,%20skip%20adding%20data%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(cdSum%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20audioKey%20=%20getDataKeySync(sessionKey,%20domainKey,%20cdSum);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20setCache(thisArg,%20args,%20audioKey);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20iterateDataKey(audioKey,%20(item,%20byte)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20itemAudioIndex%20=%20item%20%25%20channelData.length;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20factor%20=%20byte%20*%200.0000001;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(byte%20%5E%200x1)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20factor%20=%200%20-%20factor;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20channelData%5BitemAudioIndex%5D%20=%20channelData%5BitemAudioIndex%5D%20+%20factor;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20copyFromChannelProxy%20=%20new%20DDGProxy(this,%20AudioBuffer.prototype,%20'copyFromChannel',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%5Bsource,%20channelNumber,%20startInChannel%5D%20=%20args;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20This%20is%20implemented%20in%20a%20different%20way%20to%20canvas%20purely%20because%20calling%20the%20function%20copied%20the%20original%20value,%20which%20is%20not%20ideal%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20channelNumber%20is%20longer%20than%20arrayBuffer%20number%20of%20channels%20then%20call%20the%20default%20method%20to%20throw%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20channelNumber%20%3E%20thisArg.numberOfChannels%20%7C%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20startInChannel%20is%20longer%20than%20the%20arrayBuffer%20length%20then%20call%20the%20default%20method%20to%20throw%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20startInChannel%20%3E%20thisArg.length%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20The%20normal%20return%20value%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Call%20the%20protected%20getChannelData%20we%20implement,%20slice%20from%20the%20startInChannel%20value%20and%20assign%20to%20the%20source%20array%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20thisArg%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.getChannelData(channelNumber)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.slice(startInChannel)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.forEach((val,%20index)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20source%5Bindex%5D%20=%20val;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20copyFromChannelProxy.overload();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cacheExpiry%20=%2060;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cacheData%20=%20new%20WeakMap();%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20getCachedResponse(thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20data%20=%20cacheData.get(thisArg);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20timeNow%20=%20Date.now();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(data%20&&%20data.args%20===%20JSON.stringify(args)%20&&%20data.expires%20%3E%20timeNow)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20data.expires%20=%20timeNow%20+%20cacheExpiry;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cacheData.set(thisArg,%20data);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20data;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%20audioKey:%20null%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20setCache(thisArg,%20args,%20audioKey)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cacheData.set(thisArg,%20%7B%20args:%20JSON.stringify(args),%20expires:%20Date.now()%20+%20cacheExpiry,%20audioKey%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20getChannelDataProxy%20=%20new%20DDGProxy(this,%20AudioBuffer.prototype,%20'getChannelData',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20The%20normal%20return%20value%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20channelData%20=%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Anything%20we%20do%20here%20should%20be%20caught%20and%20ignored%20silently%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20transformArrayData(channelData,%20domainKey,%20sessionKey,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20%7B%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20channelData;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20getChannelDataProxy.overload();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20audioMethods%20=%20%5B'getByteTimeDomainData',%20'getFloatTimeDomainData',%20'getByteFrequencyData',%20'getFloatFrequencyData'%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20methodName%20of%20audioMethods)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20proxy%20=%20new%20DDGProxy(this,%20AnalyserNode.prototype,%20methodName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Anything%20we%20do%20here%20should%20be%20caught%20and%20ignored%20silently%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20transformArrayData(args%5B0%5D,%20domainKey,%20sessionKey,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20%7B%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20proxy.overload();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Overwrites%20the%20Battery%20API%20if%20present%20in%20the%20browser.%0A%20%20%20%20%20*%20It%20will%20return%20the%20values%20defined%20in%20the%20getBattery%20function%20to%20the%20client,%0A%20%20%20%20%20*%20as%20well%20as%20prevent%20any%20script%20from%20listening%20to%20events.%0A%20%20%20%20%20*/%0A%20%20%20%20class%20FingerprintingBattery%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(globalThis.navigator.getBattery)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20BatteryManager%20=%20globalThis.BatteryManager;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20spoofedValues%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20charging:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20chargingTime:%200,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20dischargingTime:%20Infinity,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20level:%201,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20eventProperties%20=%20%5B'onchargingchange',%20'onchargingtimechange',%20'ondischargingtimechange',%20'onlevelchange'%5D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20%5Bprop,%20val%5D%20of%20Object.entries(spoofedValues))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.defineProperty(BatteryManager.prototype,%20prop,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20val;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20eventProp%20of%20eventProperties)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.defineProperty(BatteryManager.prototype,%20eventProp,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20set:%20(x)%20=%3E%20x,%20//%20noop%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20getDefaultExportFromCjs%20(x)%20%7B%0A%20%20%20%20%09return%20x%20&&%20x.__esModule%20&&%20Object.prototype.hasOwnProperty.call(x,%20'default')%20?%20x%5B'default'%5D%20:%20x;%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20alea$1%20=%20%7Bexports:%20%7B%7D%7D;%0A%0A%20%20%20%20var%20alea%20=%20alea$1.exports;%0A%0A%20%20%20%20var%20hasRequiredAlea;%0A%0A%20%20%20%20function%20requireAlea%20()%20%7B%0A%20%20%20%20%09if%20(hasRequiredAlea)%20return%20alea$1.exports;%0A%20%20%20%20%09hasRequiredAlea%20=%201;%0A%20%20%20%20%09(function%20(module)%20%7B%0A%20%20%20%20%09%09//%20A%20port%20of%20an%20algorithm%20by%20Johannes%20Baag%C3%B8e%20%3Cbaagoe@baagoe.com%3E,%202010%0A%20%20%20%20%09%09//%20http://baagoe.com/en/RandomMusings/javascript/%0A%20%20%20%20%09%09//%20https://github.com/nquinlan/better-random-numbers-for-javascript-mirror%0A%20%20%20%20%09%09//%20Original%20work%20is%20under%20MIT%20license%20-%0A%0A%20%20%20%20%09%09//%20Copyright%20(C)%202010%20by%20Johannes%20Baag%C3%B8e%20%3Cbaagoe@baagoe.org%3E%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20Permission%20is%20hereby%20granted,%20free%20of%20charge,%20to%20any%20person%20obtaining%20a%20copy%0A%20%20%20%20%09%09//%20of%20this%20software%20and%20associated%20documentation%20files%20(the%20%22Software%22),%20to%20deal%0A%20%20%20%20%09%09//%20in%20the%20Software%20without%20restriction,%20including%20without%20limitation%20the%20rights%0A%20%20%20%20%09%09//%20to%20use,%20copy,%20modify,%20merge,%20publish,%20distribute,%20sublicense,%20and/or%20sell%0A%20%20%20%20%09%09//%20copies%20of%20the%20Software,%20and%20to%20permit%20persons%20to%20whom%20the%20Software%20is%0A%20%20%20%20%09%09//%20furnished%20to%20do%20so,%20subject%20to%20the%20following%20conditions:%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20The%20above%20copyright%20notice%20and%20this%20permission%20notice%20shall%20be%20included%20in%0A%20%20%20%20%09%09//%20all%20copies%20or%20substantial%20portions%20of%20the%20Software.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20THE%20SOFTWARE%20IS%20PROVIDED%20%22AS%20IS%22,%20WITHOUT%20WARRANTY%20OF%20ANY%20KIND,%20EXPRESS%20OR%0A%20%20%20%20%09%09//%20IMPLIED,%20INCLUDING%20BUT%20NOT%20LIMITED%20TO%20THE%20WARRANTIES%20OF%20MERCHANTABILITY,%0A%20%20%20%20%09%09//%20FITNESS%20FOR%20A%20PARTICULAR%20PURPOSE%20AND%20NONINFRINGEMENT.%20IN%20NO%20EVENT%20SHALL%20THE%0A%20%20%20%20%09%09//%20AUTHORS%20OR%20COPYRIGHT%20HOLDERS%20BE%20LIABLE%20FOR%20ANY%20CLAIM,%20DAMAGES%20OR%20OTHER%0A%20%20%20%20%09%09//%20LIABILITY,%20WHETHER%20IN%20AN%20ACTION%20OF%20CONTRACT,%20TORT%20OR%20OTHERWISE,%20ARISING%20FROM,%0A%20%20%20%20%09%09//%20OUT%20OF%20OR%20IN%20CONNECTION%20WITH%20THE%20SOFTWARE%20OR%20THE%20USE%20OR%20OTHER%20DEALINGS%20IN%0A%20%20%20%20%09%09//%20THE%20SOFTWARE.%0A%0A%0A%0A%20%20%20%20%09%09(function(global,%20module,%20define)%20%7B%0A%0A%20%20%20%20%09%09function%20Alea(seed)%20%7B%0A%20%20%20%20%09%09%20%20var%20me%20=%20this,%20mash%20=%20Mash();%0A%0A%20%20%20%20%09%09%20%20me.next%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20t%20=%202091639%20*%20me.s0%20+%20me.c%20*%202.3283064365386963e-10;%20//%202%5E-32%0A%20%20%20%20%09%09%20%20%20%20me.s0%20=%20me.s1;%0A%20%20%20%20%09%09%20%20%20%20me.s1%20=%20me.s2;%0A%20%20%20%20%09%09%20%20%20%20return%20me.s2%20=%20t%20-%20(me.c%20=%20t%20%7C%200);%0A%20%20%20%20%09%09%20%20%7D;%0A%0A%20%20%20%20%09%09%20%20//%20Apply%20the%20seeding%20algorithm%20from%20Baagoe.%0A%20%20%20%20%09%09%20%20me.c%20=%201;%0A%20%20%20%20%09%09%20%20me.s0%20=%20mash('%20');%0A%20%20%20%20%09%09%20%20me.s1%20=%20mash('%20');%0A%20%20%20%20%09%09%20%20me.s2%20=%20mash('%20');%0A%20%20%20%20%09%09%20%20me.s0%20-=%20mash(seed);%0A%20%20%20%20%09%09%20%20if%20(me.s0%20%3C%200)%20%7B%20me.s0%20+=%201;%20%7D%0A%20%20%20%20%09%09%20%20me.s1%20-=%20mash(seed);%0A%20%20%20%20%09%09%20%20if%20(me.s1%20%3C%200)%20%7B%20me.s1%20+=%201;%20%7D%0A%20%20%20%20%09%09%20%20me.s2%20-=%20mash(seed);%0A%20%20%20%20%09%09%20%20if%20(me.s2%20%3C%200)%20%7B%20me.s2%20+=%201;%20%7D%0A%20%20%20%20%09%09%20%20mash%20=%20null;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20copy(f,%20t)%20%7B%0A%20%20%20%20%09%09%20%20t.c%20=%20f.c;%0A%20%20%20%20%09%09%20%20t.s0%20=%20f.s0;%0A%20%20%20%20%09%09%20%20t.s1%20=%20f.s1;%0A%20%20%20%20%09%09%20%20t.s2%20=%20f.s2;%0A%20%20%20%20%09%09%20%20return%20t;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20impl(seed,%20opts)%20%7B%0A%20%20%20%20%09%09%20%20var%20xg%20=%20new%20Alea(seed),%0A%20%20%20%20%09%09%20%20%20%20%20%20state%20=%20opts%20&&%20opts.state,%0A%20%20%20%20%09%09%20%20%20%20%20%20prng%20=%20xg.next;%0A%20%20%20%20%09%09%20%20prng.int32%20=%20function()%20%7B%20return%20(xg.next()%20*%200x100000000)%20%7C%200;%20%7D;%0A%20%20%20%20%09%09%20%20prng.double%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20return%20prng()%20+%20(prng()%20*%200x200000%20%7C%200)%20*%201.1102230246251565e-16;%20//%202%5E-53%0A%20%20%20%20%09%09%20%20%7D;%0A%20%20%20%20%09%09%20%20prng.quick%20=%20prng;%0A%20%20%20%20%09%09%20%20if%20(state)%20%7B%0A%20%20%20%20%09%09%20%20%20%20if%20(typeof(state)%20==%20'object')%20copy(state,%20xg);%0A%20%20%20%20%09%09%20%20%20%20prng.state%20=%20function()%20%7B%20return%20copy(xg,%20%7B%7D);%20%7D;%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20return%20prng;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20Mash()%20%7B%0A%20%20%20%20%09%09%20%20var%20n%20=%200xefc8249d;%0A%0A%20%20%20%20%09%09%20%20var%20mash%20=%20function(data)%20%7B%0A%20%20%20%20%09%09%20%20%20%20data%20=%20String(data);%0A%20%20%20%20%09%09%20%20%20%20for%20(var%20i%20=%200;%20i%20%3C%20data.length;%20i++)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20n%20+=%20data.charCodeAt(i);%0A%20%20%20%20%09%09%20%20%20%20%20%20var%20h%20=%200.02519603282416938%20*%20n;%0A%20%20%20%20%09%09%20%20%20%20%20%20n%20=%20h%20%3E%3E%3E%200;%0A%20%20%20%20%09%09%20%20%20%20%20%20h%20-=%20n;%0A%20%20%20%20%09%09%20%20%20%20%20%20h%20*=%20n;%0A%20%20%20%20%09%09%20%20%20%20%20%20n%20=%20h%20%3E%3E%3E%200;%0A%20%20%20%20%09%09%20%20%20%20%20%20h%20-=%20n;%0A%20%20%20%20%09%09%20%20%20%20%20%20n%20+=%20h%20*%200x100000000;%20//%202%5E32%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20return%20(n%20%3E%3E%3E%200)%20*%202.3283064365386963e-10;%20//%202%5E-32%0A%20%20%20%20%09%09%20%20%7D;%0A%0A%20%20%20%20%09%09%20%20return%20mash;%0A%20%20%20%20%09%09%7D%0A%0A%0A%20%20%20%20%09%09if%20(module%20&&%20module.exports)%20%7B%0A%20%20%20%20%09%09%20%20module.exports%20=%20impl;%0A%20%20%20%20%09%09%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20this.alea%20=%20impl;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09%7D)(%0A%20%20%20%20%09%09%20%20alea,%0A%20%20%20%20%09%09%20%20module);%20%0A%20%20%20%20%09%7D%20(alea$1));%0A%20%20%20%20%09return%20alea$1.exports;%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20xor128$1%20=%20%7Bexports:%20%7B%7D%7D;%0A%0A%20%20%20%20var%20xor128%20=%20xor128$1.exports;%0A%0A%20%20%20%20var%20hasRequiredXor128;%0A%0A%20%20%20%20function%20requireXor128%20()%20%7B%0A%20%20%20%20%09if%20(hasRequiredXor128)%20return%20xor128$1.exports;%0A%20%20%20%20%09hasRequiredXor128%20=%201;%0A%20%20%20%20%09(function%20(module)%20%7B%0A%20%20%20%20%09%09//%20A%20Javascript%20implementaion%20of%20the%20%22xor128%22%20prng%20algorithm%20by%0A%20%20%20%20%09%09//%20George%20Marsaglia.%20%20See%20http://www.jstatsoft.org/v08/i14/paper%0A%0A%20%20%20%20%09%09(function(global,%20module,%20define)%20%7B%0A%0A%20%20%20%20%09%09function%20XorGen(seed)%20%7B%0A%20%20%20%20%09%09%20%20var%20me%20=%20this,%20strseed%20=%20'';%0A%0A%20%20%20%20%09%09%20%20me.x%20=%200;%0A%20%20%20%20%09%09%20%20me.y%20=%200;%0A%20%20%20%20%09%09%20%20me.z%20=%200;%0A%20%20%20%20%09%09%20%20me.w%20=%200;%0A%0A%20%20%20%20%09%09%20%20//%20Set%20up%20generator%20function.%0A%20%20%20%20%09%09%20%20me.next%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20t%20=%20me.x%20%5E%20(me.x%20%3C%3C%2011);%0A%20%20%20%20%09%09%20%20%20%20me.x%20=%20me.y;%0A%20%20%20%20%09%09%20%20%20%20me.y%20=%20me.z;%0A%20%20%20%20%09%09%20%20%20%20me.z%20=%20me.w;%0A%20%20%20%20%09%09%20%20%20%20return%20me.w%20%5E=%20(me.w%20%3E%3E%3E%2019)%20%5E%20t%20%5E%20(t%20%3E%3E%3E%208);%0A%20%20%20%20%09%09%20%20%7D;%0A%0A%20%20%20%20%09%09%20%20if%20(seed%20===%20(seed%20%7C%200))%20%7B%0A%20%20%20%20%09%09%20%20%20%20//%20Integer%20seed.%0A%20%20%20%20%09%09%20%20%20%20me.x%20=%20seed;%0A%20%20%20%20%09%09%20%20%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20%20%20//%20String%20seed.%0A%20%20%20%20%09%09%20%20%20%20strseed%20+=%20seed;%0A%20%20%20%20%09%09%20%20%7D%0A%0A%20%20%20%20%09%09%20%20//%20Mix%20in%20string%20seed,%20then%20discard%20an%20initial%20batch%20of%2064%20values.%0A%20%20%20%20%09%09%20%20for%20(var%20k%20=%200;%20k%20%3C%20strseed.length%20+%2064;%20k++)%20%7B%0A%20%20%20%20%09%09%20%20%20%20me.x%20%5E=%20strseed.charCodeAt(k)%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20me.next();%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20copy(f,%20t)%20%7B%0A%20%20%20%20%09%09%20%20t.x%20=%20f.x;%0A%20%20%20%20%09%09%20%20t.y%20=%20f.y;%0A%20%20%20%20%09%09%20%20t.z%20=%20f.z;%0A%20%20%20%20%09%09%20%20t.w%20=%20f.w;%0A%20%20%20%20%09%09%20%20return%20t;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20impl(seed,%20opts)%20%7B%0A%20%20%20%20%09%09%20%20var%20xg%20=%20new%20XorGen(seed),%0A%20%20%20%20%09%09%20%20%20%20%20%20state%20=%20opts%20&&%20opts.state,%0A%20%20%20%20%09%09%20%20%20%20%20%20prng%20=%20function()%20%7B%20return%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000;%20%7D;%0A%20%20%20%20%09%09%20%20prng.double%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20do%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20var%20top%20=%20xg.next()%20%3E%3E%3E%2011,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20bot%20=%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20result%20=%20(top%20+%20bot)%20/%20(1%20%3C%3C%2021);%0A%20%20%20%20%09%09%20%20%20%20%7D%20while%20(result%20===%200);%0A%20%20%20%20%09%09%20%20%20%20return%20result;%0A%20%20%20%20%09%09%20%20%7D;%0A%20%20%20%20%09%09%20%20prng.int32%20=%20xg.next;%0A%20%20%20%20%09%09%20%20prng.quick%20=%20prng;%0A%20%20%20%20%09%09%20%20if%20(state)%20%7B%0A%20%20%20%20%09%09%20%20%20%20if%20(typeof(state)%20==%20'object')%20copy(state,%20xg);%0A%20%20%20%20%09%09%20%20%20%20prng.state%20=%20function()%20%7B%20return%20copy(xg,%20%7B%7D);%20%7D;%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20return%20prng;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09if%20(module%20&&%20module.exports)%20%7B%0A%20%20%20%20%09%09%20%20module.exports%20=%20impl;%0A%20%20%20%20%09%09%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20this.xor128%20=%20impl;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09%7D)(%0A%20%20%20%20%09%09%20%20xor128,%0A%20%20%20%20%09%09%20%20module);%20%0A%20%20%20%20%09%7D%20(xor128$1));%0A%20%20%20%20%09return%20xor128$1.exports;%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20xorwow$1%20=%20%7Bexports:%20%7B%7D%7D;%0A%0A%20%20%20%20var%20xorwow%20=%20xorwow$1.exports;%0A%0A%20%20%20%20var%20hasRequiredXorwow;%0A%0A%20%20%20%20function%20requireXorwow%20()%20%7B%0A%20%20%20%20%09if%20(hasRequiredXorwow)%20return%20xorwow$1.exports;%0A%20%20%20%20%09hasRequiredXorwow%20=%201;%0A%20%20%20%20%09(function%20(module)%20%7B%0A%20%20%20%20%09%09//%20A%20Javascript%20implementaion%20of%20the%20%22xorwow%22%20prng%20algorithm%20by%0A%20%20%20%20%09%09//%20George%20Marsaglia.%20%20See%20http://www.jstatsoft.org/v08/i14/paper%0A%0A%20%20%20%20%09%09(function(global,%20module,%20define)%20%7B%0A%0A%20%20%20%20%09%09function%20XorGen(seed)%20%7B%0A%20%20%20%20%09%09%20%20var%20me%20=%20this,%20strseed%20=%20'';%0A%0A%20%20%20%20%09%09%20%20//%20Set%20up%20generator%20function.%0A%20%20%20%20%09%09%20%20me.next%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20t%20=%20(me.x%20%5E%20(me.x%20%3E%3E%3E%202));%0A%20%20%20%20%09%09%20%20%20%20me.x%20=%20me.y;%20me.y%20=%20me.z;%20me.z%20=%20me.w;%20me.w%20=%20me.v;%0A%20%20%20%20%09%09%20%20%20%20return%20(me.d%20=%20(me.d%20+%20362437%20%7C%200))%20+%0A%20%20%20%20%09%09%20%20%20%20%20%20%20(me.v%20=%20(me.v%20%5E%20(me.v%20%3C%3C%204))%20%5E%20(t%20%5E%20(t%20%3C%3C%201)))%20%7C%200;%0A%20%20%20%20%09%09%20%20%7D;%0A%0A%20%20%20%20%09%09%20%20me.x%20=%200;%0A%20%20%20%20%09%09%20%20me.y%20=%200;%0A%20%20%20%20%09%09%20%20me.z%20=%200;%0A%20%20%20%20%09%09%20%20me.w%20=%200;%0A%20%20%20%20%09%09%20%20me.v%20=%200;%0A%0A%20%20%20%20%09%09%20%20if%20(seed%20===%20(seed%20%7C%200))%20%7B%0A%20%20%20%20%09%09%20%20%20%20//%20Integer%20seed.%0A%20%20%20%20%09%09%20%20%20%20me.x%20=%20seed;%0A%20%20%20%20%09%09%20%20%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20%20%20//%20String%20seed.%0A%20%20%20%20%09%09%20%20%20%20strseed%20+=%20seed;%0A%20%20%20%20%09%09%20%20%7D%0A%0A%20%20%20%20%09%09%20%20//%20Mix%20in%20string%20seed,%20then%20discard%20an%20initial%20batch%20of%2064%20values.%0A%20%20%20%20%09%09%20%20for%20(var%20k%20=%200;%20k%20%3C%20strseed.length%20+%2064;%20k++)%20%7B%0A%20%20%20%20%09%09%20%20%20%20me.x%20%5E=%20strseed.charCodeAt(k)%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20if%20(k%20==%20strseed.length)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20me.d%20=%20me.x%20%3C%3C%2010%20%5E%20me.x%20%3E%3E%3E%204;%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20me.next();%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20copy(f,%20t)%20%7B%0A%20%20%20%20%09%09%20%20t.x%20=%20f.x;%0A%20%20%20%20%09%09%20%20t.y%20=%20f.y;%0A%20%20%20%20%09%09%20%20t.z%20=%20f.z;%0A%20%20%20%20%09%09%20%20t.w%20=%20f.w;%0A%20%20%20%20%09%09%20%20t.v%20=%20f.v;%0A%20%20%20%20%09%09%20%20t.d%20=%20f.d;%0A%20%20%20%20%09%09%20%20return%20t;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20impl(seed,%20opts)%20%7B%0A%20%20%20%20%09%09%20%20var%20xg%20=%20new%20XorGen(seed),%0A%20%20%20%20%09%09%20%20%20%20%20%20state%20=%20opts%20&&%20opts.state,%0A%20%20%20%20%09%09%20%20%20%20%20%20prng%20=%20function()%20%7B%20return%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000;%20%7D;%0A%20%20%20%20%09%09%20%20prng.double%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20do%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20var%20top%20=%20xg.next()%20%3E%3E%3E%2011,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20bot%20=%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20result%20=%20(top%20+%20bot)%20/%20(1%20%3C%3C%2021);%0A%20%20%20%20%09%09%20%20%20%20%7D%20while%20(result%20===%200);%0A%20%20%20%20%09%09%20%20%20%20return%20result;%0A%20%20%20%20%09%09%20%20%7D;%0A%20%20%20%20%09%09%20%20prng.int32%20=%20xg.next;%0A%20%20%20%20%09%09%20%20prng.quick%20=%20prng;%0A%20%20%20%20%09%09%20%20if%20(state)%20%7B%0A%20%20%20%20%09%09%20%20%20%20if%20(typeof(state)%20==%20'object')%20copy(state,%20xg);%0A%20%20%20%20%09%09%20%20%20%20prng.state%20=%20function()%20%7B%20return%20copy(xg,%20%7B%7D);%20%7D;%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20return%20prng;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09if%20(module%20&&%20module.exports)%20%7B%0A%20%20%20%20%09%09%20%20module.exports%20=%20impl;%0A%20%20%20%20%09%09%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20this.xorwow%20=%20impl;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09%7D)(%0A%20%20%20%20%09%09%20%20xorwow,%0A%20%20%20%20%09%09%20%20module);%20%0A%20%20%20%20%09%7D%20(xorwow$1));%0A%20%20%20%20%09return%20xorwow$1.exports;%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20xorshift7$1%20=%20%7Bexports:%20%7B%7D%7D;%0A%0A%20%20%20%20var%20xorshift7%20=%20xorshift7$1.exports;%0A%0A%20%20%20%20var%20hasRequiredXorshift7;%0A%0A%20%20%20%20function%20requireXorshift7%20()%20%7B%0A%20%20%20%20%09if%20(hasRequiredXorshift7)%20return%20xorshift7$1.exports;%0A%20%20%20%20%09hasRequiredXorshift7%20=%201;%0A%20%20%20%20%09(function%20(module)%20%7B%0A%20%20%20%20%09%09//%20A%20Javascript%20implementaion%20of%20the%20%22xorshift7%22%20algorithm%20by%0A%20%20%20%20%09%09//%20Fran%C3%A7ois%20Panneton%20and%20Pierre%20L'ecuyer:%0A%20%20%20%20%09%09//%20%22On%20the%20Xorgshift%20Random%20Number%20Generators%22%0A%20%20%20%20%09%09//%20http://saluc.engr.uconn.edu/refs/crypto/rng/panneton05onthexorshift.pdf%0A%0A%20%20%20%20%09%09(function(global,%20module,%20define)%20%7B%0A%0A%20%20%20%20%09%09function%20XorGen(seed)%20%7B%0A%20%20%20%20%09%09%20%20var%20me%20=%20this;%0A%0A%20%20%20%20%09%09%20%20//%20Set%20up%20generator%20function.%0A%20%20%20%20%09%09%20%20me.next%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20//%20Update%20xor%20generator.%0A%20%20%20%20%09%09%20%20%20%20var%20X%20=%20me.x,%20i%20=%20me.i,%20t,%20v;%0A%20%20%20%20%09%09%20%20%20%20t%20=%20X%5Bi%5D;%20t%20%5E=%20(t%20%3E%3E%3E%207);%20v%20=%20t%20%5E%20(t%20%3C%3C%2024);%0A%20%20%20%20%09%09%20%20%20%20t%20=%20X%5B(i%20+%201)%20&%207%5D;%20v%20%5E=%20t%20%5E%20(t%20%3E%3E%3E%2010);%0A%20%20%20%20%09%09%20%20%20%20t%20=%20X%5B(i%20+%203)%20&%207%5D;%20v%20%5E=%20t%20%5E%20(t%20%3E%3E%3E%203);%0A%20%20%20%20%09%09%20%20%20%20t%20=%20X%5B(i%20+%204)%20&%207%5D;%20v%20%5E=%20t%20%5E%20(t%20%3C%3C%207);%0A%20%20%20%20%09%09%20%20%20%20t%20=%20X%5B(i%20+%207)%20&%207%5D;%20t%20=%20t%20%5E%20(t%20%3C%3C%2013);%20v%20%5E=%20t%20%5E%20(t%20%3C%3C%209);%0A%20%20%20%20%09%09%20%20%20%20X%5Bi%5D%20=%20v;%0A%20%20%20%20%09%09%20%20%20%20me.i%20=%20(i%20+%201)%20&%207;%0A%20%20%20%20%09%09%20%20%20%20return%20v;%0A%20%20%20%20%09%09%20%20%7D;%0A%0A%20%20%20%20%09%09%20%20function%20init(me,%20seed)%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20j,%20X%20=%20%5B%5D;%0A%0A%20%20%20%20%09%09%20%20%20%20if%20(seed%20===%20(seed%20%7C%200))%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20//%20Seed%20state%20array%20using%20a%2032-bit%20integer.%0A%20%20%20%20%09%09%20%20%20%20%20%20X%5B0%5D%20=%20seed;%0A%20%20%20%20%09%09%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20//%20Seed%20state%20using%20a%20string.%0A%20%20%20%20%09%09%20%20%20%20%20%20seed%20=%20''%20+%20seed;%0A%20%20%20%20%09%09%20%20%20%20%20%20for%20(j%20=%200;%20j%20%3C%20seed.length;%20++j)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20X%5Bj%20&%207%5D%20=%20(X%5Bj%20&%207%5D%20%3C%3C%2015)%20%5E%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20%20%20(seed.charCodeAt(j)%20+%20X%5B(j%20+%201)%20&%207%5D%20%3C%3C%2013);%0A%20%20%20%20%09%09%20%20%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20//%20Enforce%20an%20array%20length%20of%208,%20not%20all%20zeroes.%0A%20%20%20%20%09%09%20%20%20%20while%20(X.length%20%3C%208)%20X.push(0);%0A%20%20%20%20%09%09%20%20%20%20for%20(j%20=%200;%20j%20%3C%208%20&&%20X%5Bj%5D%20===%200;%20++j);%0A%20%20%20%20%09%09%20%20%20%20if%20(j%20==%208)%20X%5B7%5D%20=%20-1;%20else%20X%5Bj%5D;%0A%0A%20%20%20%20%09%09%20%20%20%20me.x%20=%20X;%0A%20%20%20%20%09%09%20%20%20%20me.i%20=%200;%0A%0A%20%20%20%20%09%09%20%20%20%20//%20Discard%20an%20initial%20256%20values.%0A%20%20%20%20%09%09%20%20%20%20for%20(j%20=%20256;%20j%20%3E%200;%20--j)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20me.next();%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%7D%0A%0A%20%20%20%20%09%09%20%20init(me,%20seed);%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20copy(f,%20t)%20%7B%0A%20%20%20%20%09%09%20%20t.x%20=%20f.x.slice();%0A%20%20%20%20%09%09%20%20t.i%20=%20f.i;%0A%20%20%20%20%09%09%20%20return%20t;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20impl(seed,%20opts)%20%7B%0A%20%20%20%20%09%09%20%20if%20(seed%20==%20null)%20seed%20=%20+(new%20Date);%0A%20%20%20%20%09%09%20%20var%20xg%20=%20new%20XorGen(seed),%0A%20%20%20%20%09%09%20%20%20%20%20%20state%20=%20opts%20&&%20opts.state,%0A%20%20%20%20%09%09%20%20%20%20%20%20prng%20=%20function()%20%7B%20return%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000;%20%7D;%0A%20%20%20%20%09%09%20%20prng.double%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20do%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20var%20top%20=%20xg.next()%20%3E%3E%3E%2011,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20bot%20=%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20result%20=%20(top%20+%20bot)%20/%20(1%20%3C%3C%2021);%0A%20%20%20%20%09%09%20%20%20%20%7D%20while%20(result%20===%200);%0A%20%20%20%20%09%09%20%20%20%20return%20result;%0A%20%20%20%20%09%09%20%20%7D;%0A%20%20%20%20%09%09%20%20prng.int32%20=%20xg.next;%0A%20%20%20%20%09%09%20%20prng.quick%20=%20prng;%0A%20%20%20%20%09%09%20%20if%20(state)%20%7B%0A%20%20%20%20%09%09%20%20%20%20if%20(state.x)%20copy(state,%20xg);%0A%20%20%20%20%09%09%20%20%20%20prng.state%20=%20function()%20%7B%20return%20copy(xg,%20%7B%7D);%20%7D;%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20return%20prng;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09if%20(module%20&&%20module.exports)%20%7B%0A%20%20%20%20%09%09%20%20module.exports%20=%20impl;%0A%20%20%20%20%09%09%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20this.xorshift7%20=%20impl;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09%7D)(%0A%20%20%20%20%09%09%20%20xorshift7,%0A%20%20%20%20%09%09%20%20module);%20%0A%20%20%20%20%09%7D%20(xorshift7$1));%0A%20%20%20%20%09return%20xorshift7$1.exports;%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20xor4096$1%20=%20%7Bexports:%20%7B%7D%7D;%0A%0A%20%20%20%20var%20xor4096%20=%20xor4096$1.exports;%0A%0A%20%20%20%20var%20hasRequiredXor4096;%0A%0A%20%20%20%20function%20requireXor4096%20()%20%7B%0A%20%20%20%20%09if%20(hasRequiredXor4096)%20return%20xor4096$1.exports;%0A%20%20%20%20%09hasRequiredXor4096%20=%201;%0A%20%20%20%20%09(function%20(module)%20%7B%0A%20%20%20%20%09%09//%20A%20Javascript%20implementaion%20of%20Richard%20Brent's%20Xorgens%20xor4096%20algorithm.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20This%20fast%20non-cryptographic%20random%20number%20generator%20is%20designed%20for%0A%20%20%20%20%09%09//%20use%20in%20Monte-Carlo%20algorithms.%20It%20combines%20a%20long-period%20xorshift%0A%20%20%20%20%09%09//%20generator%20with%20a%20Weyl%20generator,%20and%20it%20passes%20all%20common%20batteries%0A%20%20%20%20%09%09//%20of%20stasticial%20tests%20for%20randomness%20while%20consuming%20only%20a%20few%20nanoseconds%0A%20%20%20%20%09%09//%20for%20each%20prng%20generated.%20%20For%20background%20on%20the%20generator,%20see%20Brent's%0A%20%20%20%20%09%09//%20paper:%20%22Some%20long-period%20random%20number%20generators%20using%20shifts%20and%20xors.%22%0A%20%20%20%20%09%09//%20http://arxiv.org/pdf/1004.3115v1.pdf%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20Usage:%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20var%20xor4096%20=%20require('xor4096');%0A%20%20%20%20%09%09//%20random%20=%20xor4096(1);%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Seed%20with%20int32%20or%20string.%0A%20%20%20%20%09%09//%20assert.equal(random(),%200.1520436450538547);%20//%20(0,%201)%20range,%2053%20bits.%0A%20%20%20%20%09%09//%20assert.equal(random.int32(),%201806534897);%20%20%20//%20signed%20int32,%2032%20bits.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20For%20nonzero%20numeric%20keys,%20this%20impelementation%20provides%20a%20sequence%0A%20%20%20%20%09%09//%20identical%20to%20that%20by%20Brent's%20xorgens%203%20implementaion%20in%20C.%20%20This%0A%20%20%20%20%09%09//%20implementation%20also%20provides%20for%20initalizing%20the%20generator%20with%0A%20%20%20%20%09%09//%20string%20seeds,%20or%20for%20saving%20and%20restoring%20the%20state%20of%20the%20generator.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20On%20Chrome,%20this%20prng%20benchmarks%20about%202.1%20times%20slower%20than%0A%20%20%20%20%09%09//%20Javascript's%20built-in%20Math.random().%0A%0A%20%20%20%20%09%09(function(global,%20module,%20define)%20%7B%0A%0A%20%20%20%20%09%09function%20XorGen(seed)%20%7B%0A%20%20%20%20%09%09%20%20var%20me%20=%20this;%0A%0A%20%20%20%20%09%09%20%20//%20Set%20up%20generator%20function.%0A%20%20%20%20%09%09%20%20me.next%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20w%20=%20me.w,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20X%20=%20me.X,%20i%20=%20me.i,%20t,%20v;%0A%20%20%20%20%09%09%20%20%20%20//%20Update%20Weyl%20generator.%0A%20%20%20%20%09%09%20%20%20%20me.w%20=%20w%20=%20(w%20+%200x61c88647)%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20//%20Update%20xor%20generator.%0A%20%20%20%20%09%09%20%20%20%20v%20=%20X%5B(i%20+%2034)%20&%20127%5D;%0A%20%20%20%20%09%09%20%20%20%20t%20=%20X%5Bi%20=%20((i%20+%201)%20&%20127)%5D;%0A%20%20%20%20%09%09%20%20%20%20v%20%5E=%20v%20%3C%3C%2013;%0A%20%20%20%20%09%09%20%20%20%20t%20%5E=%20t%20%3C%3C%2017;%0A%20%20%20%20%09%09%20%20%20%20v%20%5E=%20v%20%3E%3E%3E%2015;%0A%20%20%20%20%09%09%20%20%20%20t%20%5E=%20t%20%3E%3E%3E%2012;%0A%20%20%20%20%09%09%20%20%20%20//%20Update%20Xor%20generator%20array%20state.%0A%20%20%20%20%09%09%20%20%20%20v%20=%20X%5Bi%5D%20=%20v%20%5E%20t;%0A%20%20%20%20%09%09%20%20%20%20me.i%20=%20i;%0A%20%20%20%20%09%09%20%20%20%20//%20Result%20is%20the%20combination.%0A%20%20%20%20%09%09%20%20%20%20return%20(v%20+%20(w%20%5E%20(w%20%3E%3E%3E%2016)))%20%7C%200;%0A%20%20%20%20%09%09%20%20%7D;%0A%0A%20%20%20%20%09%09%20%20function%20init(me,%20seed)%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20t,%20v,%20i,%20j,%20w,%20X%20=%20%5B%5D,%20limit%20=%20128;%0A%20%20%20%20%09%09%20%20%20%20if%20(seed%20===%20(seed%20%7C%200))%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20//%20Numeric%20seeds%20initialize%20v,%20which%20is%20used%20to%20generates%20X.%0A%20%20%20%20%09%09%20%20%20%20%20%20v%20=%20seed;%0A%20%20%20%20%09%09%20%20%20%20%20%20seed%20=%20null;%0A%20%20%20%20%09%09%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20//%20String%20seeds%20are%20mixed%20into%20v%20and%20X%20one%20character%20at%20a%20time.%0A%20%20%20%20%09%09%20%20%20%20%20%20seed%20=%20seed%20+%20'%5C0';%0A%20%20%20%20%09%09%20%20%20%20%20%20v%20=%200;%0A%20%20%20%20%09%09%20%20%20%20%20%20limit%20=%20Math.max(limit,%20seed.length);%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20//%20Initialize%20circular%20array%20and%20weyl%20value.%0A%20%20%20%20%09%09%20%20%20%20for%20(i%20=%200,%20j%20=%20-32;%20j%20%3C%20limit;%20++j)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20//%20Put%20the%20unicode%20characters%20into%20the%20array,%20and%20shuffle%20them.%0A%20%20%20%20%09%09%20%20%20%20%20%20if%20(seed)%20v%20%5E=%20seed.charCodeAt((j%20+%2032)%20%25%20seed.length);%0A%20%20%20%20%09%09%20%20%20%20%20%20//%20After%2032%20shuffles,%20take%20v%20as%20the%20starting%20w%20value.%0A%20%20%20%20%09%09%20%20%20%20%20%20if%20(j%20===%200)%20w%20=%20v;%0A%20%20%20%20%09%09%20%20%20%20%20%20v%20%5E=%20v%20%3C%3C%2010;%0A%20%20%20%20%09%09%20%20%20%20%20%20v%20%5E=%20v%20%3E%3E%3E%2015;%0A%20%20%20%20%09%09%20%20%20%20%20%20v%20%5E=%20v%20%3C%3C%204;%0A%20%20%20%20%09%09%20%20%20%20%20%20v%20%5E=%20v%20%3E%3E%3E%2013;%0A%20%20%20%20%09%09%20%20%20%20%20%20if%20(j%20%3E=%200)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20w%20=%20(w%20+%200x61c88647)%20%7C%200;%20%20%20%20%20//%20Weyl.%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20t%20=%20(X%5Bj%20&%20127%5D%20%5E=%20(v%20+%20w));%20%20//%20Combine%20xor%20and%20weyl%20to%20init%20array.%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20i%20=%20(0%20==%20t)%20?%20i%20+%201%20:%200;%20%20%20%20%20//%20Count%20zeroes.%0A%20%20%20%20%09%09%20%20%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20//%20We%20have%20detected%20all%20zeroes;%20make%20the%20key%20nonzero.%0A%20%20%20%20%09%09%20%20%20%20if%20(i%20%3E=%20128)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20X%5B(seed%20&&%20seed.length%20%7C%7C%200)%20&%20127%5D%20=%20-1;%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20//%20Run%20the%20generator%20512%20times%20to%20further%20mix%20the%20state%20before%20using%20it.%0A%20%20%20%20%09%09%20%20%20%20//%20Factoring%20this%20as%20a%20function%20slows%20the%20main%20generator,%20so%20it%20is%20just%0A%20%20%20%20%09%09%20%20%20%20//%20unrolled%20here.%20%20The%20weyl%20generator%20is%20not%20advanced%20while%20warming%20up.%0A%20%20%20%20%09%09%20%20%20%20i%20=%20127;%0A%20%20%20%20%09%09%20%20%20%20for%20(j%20=%204%20*%20128;%20j%20%3E%200;%20--j)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20v%20=%20X%5B(i%20+%2034)%20&%20127%5D;%0A%20%20%20%20%09%09%20%20%20%20%20%20t%20=%20X%5Bi%20=%20((i%20+%201)%20&%20127)%5D;%0A%20%20%20%20%09%09%20%20%20%20%20%20v%20%5E=%20v%20%3C%3C%2013;%0A%20%20%20%20%09%09%20%20%20%20%20%20t%20%5E=%20t%20%3C%3C%2017;%0A%20%20%20%20%09%09%20%20%20%20%20%20v%20%5E=%20v%20%3E%3E%3E%2015;%0A%20%20%20%20%09%09%20%20%20%20%20%20t%20%5E=%20t%20%3E%3E%3E%2012;%0A%20%20%20%20%09%09%20%20%20%20%20%20X%5Bi%5D%20=%20v%20%5E%20t;%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20//%20Storing%20state%20as%20object%20members%20is%20faster%20than%20using%20closure%20variables.%0A%20%20%20%20%09%09%20%20%20%20me.w%20=%20w;%0A%20%20%20%20%09%09%20%20%20%20me.X%20=%20X;%0A%20%20%20%20%09%09%20%20%20%20me.i%20=%20i;%0A%20%20%20%20%09%09%20%20%7D%0A%0A%20%20%20%20%09%09%20%20init(me,%20seed);%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20copy(f,%20t)%20%7B%0A%20%20%20%20%09%09%20%20t.i%20=%20f.i;%0A%20%20%20%20%09%09%20%20t.w%20=%20f.w;%0A%20%20%20%20%09%09%20%20t.X%20=%20f.X.slice();%0A%20%20%20%20%09%09%20%20return%20t;%0A%20%20%20%20%09%09%7D%0A%20%20%20%20%09%09function%20impl(seed,%20opts)%20%7B%0A%20%20%20%20%09%09%20%20if%20(seed%20==%20null)%20seed%20=%20+(new%20Date);%0A%20%20%20%20%09%09%20%20var%20xg%20=%20new%20XorGen(seed),%0A%20%20%20%20%09%09%20%20%20%20%20%20state%20=%20opts%20&&%20opts.state,%0A%20%20%20%20%09%09%20%20%20%20%20%20prng%20=%20function()%20%7B%20return%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000;%20%7D;%0A%20%20%20%20%09%09%20%20prng.double%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20do%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20var%20top%20=%20xg.next()%20%3E%3E%3E%2011,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20bot%20=%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20result%20=%20(top%20+%20bot)%20/%20(1%20%3C%3C%2021);%0A%20%20%20%20%09%09%20%20%20%20%7D%20while%20(result%20===%200);%0A%20%20%20%20%09%09%20%20%20%20return%20result;%0A%20%20%20%20%09%09%20%20%7D;%0A%20%20%20%20%09%09%20%20prng.int32%20=%20xg.next;%0A%20%20%20%20%09%09%20%20prng.quick%20=%20prng;%0A%20%20%20%20%09%09%20%20if%20(state)%20%7B%0A%20%20%20%20%09%09%20%20%20%20if%20(state.X)%20copy(state,%20xg);%0A%20%20%20%20%09%09%20%20%20%20prng.state%20=%20function()%20%7B%20return%20copy(xg,%20%7B%7D);%20%7D;%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20return%20prng;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09if%20(module%20&&%20module.exports)%20%7B%0A%20%20%20%20%09%09%20%20module.exports%20=%20impl;%0A%20%20%20%20%09%09%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20this.xor4096%20=%20impl;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09%7D)(%0A%20%20%20%20%09%09%20%20xor4096,%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20window%20object%20or%20global%0A%20%20%20%20%09%09%20%20module);%20%0A%20%20%20%20%09%7D%20(xor4096$1));%0A%20%20%20%20%09return%20xor4096$1.exports;%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20tychei$1%20=%20%7Bexports:%20%7B%7D%7D;%0A%0A%20%20%20%20var%20tychei%20=%20tychei$1.exports;%0A%0A%20%20%20%20var%20hasRequiredTychei;%0A%0A%20%20%20%20function%20requireTychei%20()%20%7B%0A%20%20%20%20%09if%20(hasRequiredTychei)%20return%20tychei$1.exports;%0A%20%20%20%20%09hasRequiredTychei%20=%201;%0A%20%20%20%20%09(function%20(module)%20%7B%0A%20%20%20%20%09%09//%20A%20Javascript%20implementaion%20of%20the%20%22Tyche-i%22%20prng%20algorithm%20by%0A%20%20%20%20%09%09//%20Samuel%20Neves%20and%20Filipe%20Araujo.%0A%20%20%20%20%09%09//%20See%20https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf%0A%0A%20%20%20%20%09%09(function(global,%20module,%20define)%20%7B%0A%0A%20%20%20%20%09%09function%20XorGen(seed)%20%7B%0A%20%20%20%20%09%09%20%20var%20me%20=%20this,%20strseed%20=%20'';%0A%0A%20%20%20%20%09%09%20%20//%20Set%20up%20generator%20function.%0A%20%20%20%20%09%09%20%20me.next%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20b%20=%20me.b,%20c%20=%20me.c,%20d%20=%20me.d,%20a%20=%20me.a;%0A%20%20%20%20%09%09%20%20%20%20b%20=%20(b%20%3C%3C%2025)%20%5E%20(b%20%3E%3E%3E%207)%20%5E%20c;%0A%20%20%20%20%09%09%20%20%20%20c%20=%20(c%20-%20d)%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20d%20=%20(d%20%3C%3C%2024)%20%5E%20(d%20%3E%3E%3E%208)%20%5E%20a;%0A%20%20%20%20%09%09%20%20%20%20a%20=%20(a%20-%20b)%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20me.b%20=%20b%20=%20(b%20%3C%3C%2020)%20%5E%20(b%20%3E%3E%3E%2012)%20%5E%20c;%0A%20%20%20%20%09%09%20%20%20%20me.c%20=%20c%20=%20(c%20-%20d)%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20me.d%20=%20(d%20%3C%3C%2016)%20%5E%20(c%20%3E%3E%3E%2016)%20%5E%20a;%0A%20%20%20%20%09%09%20%20%20%20return%20me.a%20=%20(a%20-%20b)%20%7C%200;%0A%20%20%20%20%09%09%20%20%7D;%0A%0A%20%20%20%20%09%09%20%20/*%20The%20following%20is%20non-inverted%20tyche,%20which%20has%20better%20internal%0A%20%20%20%20%09%09%20%20%20*%20bit%20diffusion,%20but%20which%20is%20about%2025%25%20slower%20than%20tyche-i%20in%20JS.%0A%20%20%20%20%09%09%20%20me.next%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20a%20=%20me.a,%20b%20=%20me.b,%20c%20=%20me.c,%20d%20=%20me.d;%0A%20%20%20%20%09%09%20%20%20%20a%20=%20(me.a%20+%20me.b%20%7C%200)%20%3E%3E%3E%200;%0A%20%20%20%20%09%09%20%20%20%20d%20=%20me.d%20%5E%20a;%20d%20=%20d%20%3C%3C%2016%20%5E%20d%20%3E%3E%3E%2016;%0A%20%20%20%20%09%09%20%20%20%20c%20=%20me.c%20+%20d%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20b%20=%20me.b%20%5E%20c;%20b%20=%20b%20%3C%3C%2012%20%5E%20d%20%3E%3E%3E%2020;%0A%20%20%20%20%09%09%20%20%20%20me.a%20=%20a%20=%20a%20+%20b%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20d%20=%20d%20%5E%20a;%20me.d%20=%20d%20=%20d%20%3C%3C%208%20%5E%20d%20%3E%3E%3E%2024;%0A%20%20%20%20%09%09%20%20%20%20me.c%20=%20c%20=%20c%20+%20d%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20b%20=%20b%20%5E%20c;%0A%20%20%20%20%09%09%20%20%20%20return%20me.b%20=%20(b%20%3C%3C%207%20%5E%20b%20%3E%3E%3E%2025);%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20*/%0A%0A%20%20%20%20%09%09%20%20me.a%20=%200;%0A%20%20%20%20%09%09%20%20me.b%20=%200;%0A%20%20%20%20%09%09%20%20me.c%20=%202654435769%20%7C%200;%0A%20%20%20%20%09%09%20%20me.d%20=%201367130551;%0A%0A%20%20%20%20%09%09%20%20if%20(seed%20===%20Math.floor(seed))%20%7B%0A%20%20%20%20%09%09%20%20%20%20//%20Integer%20seed.%0A%20%20%20%20%09%09%20%20%20%20me.a%20=%20(seed%20/%200x100000000)%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20me.b%20=%20seed%20%7C%200;%0A%20%20%20%20%09%09%20%20%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20%20%20//%20String%20seed.%0A%20%20%20%20%09%09%20%20%20%20strseed%20+=%20seed;%0A%20%20%20%20%09%09%20%20%7D%0A%0A%20%20%20%20%09%09%20%20//%20Mix%20in%20string%20seed,%20then%20discard%20an%20initial%20batch%20of%2064%20values.%0A%20%20%20%20%09%09%20%20for%20(var%20k%20=%200;%20k%20%3C%20strseed.length%20+%2020;%20k++)%20%7B%0A%20%20%20%20%09%09%20%20%20%20me.b%20%5E=%20strseed.charCodeAt(k)%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20me.next();%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20copy(f,%20t)%20%7B%0A%20%20%20%20%09%09%20%20t.a%20=%20f.a;%0A%20%20%20%20%09%09%20%20t.b%20=%20f.b;%0A%20%20%20%20%09%09%20%20t.c%20=%20f.c;%0A%20%20%20%20%09%09%20%20t.d%20=%20f.d;%0A%20%20%20%20%09%09%20%20return%20t;%0A%20%20%20%20%09%09%7D%0A%20%20%20%20%09%09function%20impl(seed,%20opts)%20%7B%0A%20%20%20%20%09%09%20%20var%20xg%20=%20new%20XorGen(seed),%0A%20%20%20%20%09%09%20%20%20%20%20%20state%20=%20opts%20&&%20opts.state,%0A%20%20%20%20%09%09%20%20%20%20%20%20prng%20=%20function()%20%7B%20return%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000;%20%7D;%0A%20%20%20%20%09%09%20%20prng.double%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20do%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20var%20top%20=%20xg.next()%20%3E%3E%3E%2011,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20bot%20=%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20result%20=%20(top%20+%20bot)%20/%20(1%20%3C%3C%2021);%0A%20%20%20%20%09%09%20%20%20%20%7D%20while%20(result%20===%200);%0A%20%20%20%20%09%09%20%20%20%20return%20result;%0A%20%20%20%20%09%09%20%20%7D;%0A%20%20%20%20%09%09%20%20prng.int32%20=%20xg.next;%0A%20%20%20%20%09%09%20%20prng.quick%20=%20prng;%0A%20%20%20%20%09%09%20%20if%20(state)%20%7B%0A%20%20%20%20%09%09%20%20%20%20if%20(typeof(state)%20==%20'object')%20copy(state,%20xg);%0A%20%20%20%20%09%09%20%20%20%20prng.state%20=%20function()%20%7B%20return%20copy(xg,%20%7B%7D);%20%7D;%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20return%20prng;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09if%20(module%20&&%20module.exports)%20%7B%0A%20%20%20%20%09%09%20%20module.exports%20=%20impl;%0A%20%20%20%20%09%09%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20this.tychei%20=%20impl;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09%7D)(%0A%20%20%20%20%09%09%20%20tychei,%0A%20%20%20%20%09%09%20%20module);%20%0A%20%20%20%20%09%7D%20(tychei$1));%0A%20%20%20%20%09return%20tychei$1.exports;%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20seedrandom$2%20=%20%7Bexports:%20%7B%7D%7D;%0A%0A%20%20%20%20/*%0A%20%20%20%20Copyright%202019%20David%20Bau.%0A%0A%20%20%20%20Permission%20is%20hereby%20granted,%20free%20of%20charge,%20to%20any%20person%20obtaining%0A%20%20%20%20a%20copy%20of%20this%20software%20and%20associated%20documentation%20files%20(the%0A%20%20%20%20%22Software%22),%20to%20deal%20in%20the%20Software%20without%20restriction,%20including%0A%20%20%20%20without%20limitation%20the%20rights%20to%20use,%20copy,%20modify,%20merge,%20publish,%0A%20%20%20%20distribute,%20sublicense,%20and/or%20sell%20copies%20of%20the%20Software,%20and%20to%0A%20%20%20%20permit%20persons%20to%20whom%20the%20Software%20is%20furnished%20to%20do%20so,%20subject%20to%0A%20%20%20%20the%20following%20conditions:%0A%0A%20%20%20%20The%20above%20copyright%20notice%20and%20this%20permission%20notice%20shall%20be%0A%20%20%20%20included%20in%20all%20copies%20or%20substantial%20portions%20of%20the%20Software.%0A%0A%20%20%20%20THE%20SOFTWARE%20IS%20PROVIDED%20%22AS%20IS%22,%20WITHOUT%20WARRANTY%20OF%20ANY%20KIND,%0A%20%20%20%20EXPRESS%20OR%20IMPLIED,%20INCLUDING%20BUT%20NOT%20LIMITED%20TO%20THE%20WARRANTIES%20OF%0A%20%20%20%20MERCHANTABILITY,%20FITNESS%20FOR%20A%20PARTICULAR%20PURPOSE%20AND%20NONINFRINGEMENT.%0A%20%20%20%20IN%20NO%20EVENT%20SHALL%20THE%20AUTHORS%20OR%20COPYRIGHT%20HOLDERS%20BE%20LIABLE%20FOR%20ANY%0A%20%20%20%20CLAIM,%20DAMAGES%20OR%20OTHER%20LIABILITY,%20WHETHER%20IN%20AN%20ACTION%20OF%20CONTRACT,%0A%20%20%20%20TORT%20OR%20OTHERWISE,%20ARISING%20FROM,%20OUT%20OF%20OR%20IN%20CONNECTION%20WITH%20THE%0A%20%20%20%20SOFTWARE%20OR%20THE%20USE%20OR%20OTHER%20DEALINGS%20IN%20THE%20SOFTWARE.%0A%0A%20%20%20%20*/%0A%20%20%20%20var%20seedrandom$1%20=%20seedrandom$2.exports;%0A%0A%20%20%20%20var%20hasRequiredSeedrandom$1;%0A%0A%20%20%20%20function%20requireSeedrandom$1%20()%20%7B%0A%20%20%20%20%09if%20(hasRequiredSeedrandom$1)%20return%20seedrandom$2.exports;%0A%20%20%20%20%09hasRequiredSeedrandom$1%20=%201;%0A%20%20%20%20%09(function%20(module)%20%7B%0A%20%20%20%20%09%09(function%20(global,%20pool,%20math)%20%7B%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20The%20following%20constants%20are%20related%20to%20IEEE%20754%20limits.%0A%20%20%20%20%09%09//%0A%0A%20%20%20%20%09%09var%20width%20=%20256,%20%20%20%20%20%20%20%20//%20each%20RC4%20output%20is%200%20%3C=%20x%20%3C%20256%0A%20%20%20%20%09%09%20%20%20%20chunks%20=%206,%20%20%20%20%20%20%20%20%20//%20at%20least%20six%20RC4%20outputs%20for%20each%20double%0A%20%20%20%20%09%09%20%20%20%20digits%20=%2052,%20%20%20%20%20%20%20%20//%20there%20are%2052%20significant%20digits%20in%20a%20double%0A%20%20%20%20%09%09%20%20%20%20rngname%20=%20'random',%20//%20rngname:%20name%20for%20Math.random%20and%20Math.seedrandom%0A%20%20%20%20%09%09%20%20%20%20startdenom%20=%20math.pow(width,%20chunks),%0A%20%20%20%20%09%09%20%20%20%20significance%20=%20math.pow(2,%20digits),%0A%20%20%20%20%09%09%20%20%20%20overflow%20=%20significance%20*%202,%0A%20%20%20%20%09%09%20%20%20%20mask%20=%20width%20-%201,%0A%20%20%20%20%09%09%20%20%20%20nodecrypto;%20%20%20%20%20%20%20%20%20//%20node.js%20crypto%20module,%20initialized%20at%20the%20bottom.%0A%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20seedrandom()%0A%20%20%20%20%09%09//%20This%20is%20the%20seedrandom%20function%20described%20above.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09function%20seedrandom(seed,%20options,%20callback)%20%7B%0A%20%20%20%20%09%09%20%20var%20key%20=%20%5B%5D;%0A%20%20%20%20%09%09%20%20options%20=%20(options%20==%20true)%20?%20%7B%20entropy:%20true%20%7D%20:%20(options%20%7C%7C%20%7B%7D);%0A%0A%20%20%20%20%09%09%20%20//%20Flatten%20the%20seed%20string%20or%20build%20one%20from%20local%20entropy%20if%20needed.%0A%20%20%20%20%09%09%20%20var%20shortseed%20=%20mixkey(flatten(%0A%20%20%20%20%09%09%20%20%20%20options.entropy%20?%20%5Bseed,%20tostring(pool)%5D%20:%0A%20%20%20%20%09%09%20%20%20%20(seed%20==%20null)%20?%20autoseed()%20:%20seed,%203),%20key);%0A%0A%20%20%20%20%09%09%20%20//%20Use%20the%20seed%20to%20initialize%20an%20ARC4%20generator.%0A%20%20%20%20%09%09%20%20var%20arc4%20=%20new%20ARC4(key);%0A%0A%20%20%20%20%09%09%20%20//%20This%20function%20returns%20a%20random%20double%20in%20%5B0,%201)%20that%20contains%0A%20%20%20%20%09%09%20%20//%20randomness%20in%20every%20bit%20of%20the%20mantissa%20of%20the%20IEEE%20754%20value.%0A%20%20%20%20%09%09%20%20var%20prng%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20n%20=%20arc4.g(chunks),%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Start%20with%20a%20numerator%20n%20%3C%202%20%5E%2048%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20d%20=%20startdenom,%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20and%20denominator%20d%20=%202%20%5E%2048.%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20x%20=%200;%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20and%20no%20'extra%20last%20byte'.%0A%20%20%20%20%09%09%20%20%20%20while%20(n%20%3C%20significance)%20%7B%20%20%20%20%20%20%20%20%20%20//%20Fill%20up%20all%20significant%20digits%20by%0A%20%20%20%20%09%09%20%20%20%20%20%20n%20=%20(n%20+%20x)%20*%20width;%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20shifting%20numerator%20and%0A%20%20%20%20%09%09%20%20%20%20%20%20d%20*=%20width;%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20denominator%20and%20generating%20a%0A%20%20%20%20%09%09%20%20%20%20%20%20x%20=%20arc4.g(1);%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20new%20least-significant-byte.%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20while%20(n%20%3E=%20overflow)%20%7B%20%20%20%20%20%20%20%20%20%20%20%20%20//%20To%20avoid%20rounding%20up,%20before%20adding%0A%20%20%20%20%09%09%20%20%20%20%20%20n%20/=%202;%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20last%20byte,%20shift%20everything%0A%20%20%20%20%09%09%20%20%20%20%20%20d%20/=%202;%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20right%20using%20integer%20math%20until%0A%20%20%20%20%09%09%20%20%20%20%20%20x%20%3E%3E%3E=%201;%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20we%20have%20exactly%20the%20desired%20bits.%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20return%20(n%20+%20x)%20/%20d;%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Form%20the%20number%20within%20%5B0,%201).%0A%20%20%20%20%09%09%20%20%7D;%0A%0A%20%20%20%20%09%09%20%20prng.int32%20=%20function()%20%7B%20return%20arc4.g(4)%20%7C%200;%20%7D;%0A%20%20%20%20%09%09%20%20prng.quick%20=%20function()%20%7B%20return%20arc4.g(4)%20/%200x100000000;%20%7D;%0A%20%20%20%20%09%09%20%20prng.double%20=%20prng;%0A%0A%20%20%20%20%09%09%20%20//%20Mix%20the%20randomness%20into%20accumulated%20entropy.%0A%20%20%20%20%09%09%20%20mixkey(tostring(arc4.S),%20pool);%0A%0A%20%20%20%20%09%09%20%20//%20Calling%20convention:%20what%20to%20return%20as%20a%20function%20of%20prng,%20seed,%20is_math.%0A%20%20%20%20%09%09%20%20return%20(options.pass%20%7C%7C%20callback%20%7C%7C%0A%20%20%20%20%09%09%20%20%20%20%20%20function(prng,%20seed,%20is_math_call,%20state)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20if%20(state)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20//%20Load%20the%20arc4%20state%20from%20the%20given%20state%20if%20it%20has%20an%20S%20array.%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20if%20(state.S)%20%7B%20copy(state,%20arc4);%20%7D%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20//%20Only%20provide%20the%20.state%20method%20if%20requested%20via%20options.state.%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20prng.state%20=%20function()%20%7B%20return%20copy(arc4,%20%7B%7D);%20%7D;%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20//%20If%20called%20as%20a%20method%20of%20Math%20(Math.seedrandom()),%20mutate%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20//%20Math.random%20because%20that%20is%20how%20seedrandom.js%20has%20worked%20since%20v1.0.%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20if%20(is_math_call)%20%7B%20math%5Brngname%5D%20=%20prng;%20return%20seed;%20%7D%0A%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20//%20Otherwise,%20it%20is%20a%20newer%20calling%20convention,%20so%20return%20the%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20//%20prng%20directly.%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20else%20return%20prng;%0A%20%20%20%20%09%09%20%20%20%20%20%20%7D)(%0A%20%20%20%20%09%09%20%20prng,%0A%20%20%20%20%09%09%20%20shortseed,%0A%20%20%20%20%09%09%20%20'global'%20in%20options%20?%20options.global%20:%20(this%20==%20math),%0A%20%20%20%20%09%09%20%20options.state);%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20ARC4%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20An%20ARC4%20implementation.%20%20The%20constructor%20takes%20a%20key%20in%20the%20form%20of%0A%20%20%20%20%09%09//%20an%20array%20of%20at%20most%20(width)%20integers%20that%20should%20be%200%20%3C=%20x%20%3C%20(width).%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20The%20g(count)%20method%20returns%20a%20pseudorandom%20integer%20that%20concatenates%0A%20%20%20%20%09%09//%20the%20next%20(count)%20outputs%20from%20ARC4.%20%20Its%20return%20value%20is%20a%20number%20x%0A%20%20%20%20%09%09//%20that%20is%20in%20the%20range%200%20%3C=%20x%20%3C%20(width%20%5E%20count).%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09function%20ARC4(key)%20%7B%0A%20%20%20%20%09%09%20%20var%20t,%20keylen%20=%20key.length,%0A%20%20%20%20%09%09%20%20%20%20%20%20me%20=%20this,%20i%20=%200,%20j%20=%20me.i%20=%20me.j%20=%200,%20s%20=%20me.S%20=%20%5B%5D;%0A%0A%20%20%20%20%09%09%20%20//%20The%20empty%20key%20%5B%5D%20is%20treated%20as%20%5B0%5D.%0A%20%20%20%20%09%09%20%20if%20(!keylen)%20%7B%20key%20=%20%5Bkeylen++%5D;%20%7D%0A%0A%20%20%20%20%09%09%20%20//%20Set%20up%20S%20using%20the%20standard%20key%20scheduling%20algorithm.%0A%20%20%20%20%09%09%20%20while%20(i%20%3C%20width)%20%7B%0A%20%20%20%20%09%09%20%20%20%20s%5Bi%5D%20=%20i++;%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20for%20(i%20=%200;%20i%20%3C%20width;%20i++)%20%7B%0A%20%20%20%20%09%09%20%20%20%20s%5Bi%5D%20=%20s%5Bj%20=%20mask%20&%20(j%20+%20key%5Bi%20%25%20keylen%5D%20+%20(t%20=%20s%5Bi%5D))%5D;%0A%20%20%20%20%09%09%20%20%20%20s%5Bj%5D%20=%20t;%0A%20%20%20%20%09%09%20%20%7D%0A%0A%20%20%20%20%09%09%20%20//%20The%20%22g%22%20method%20returns%20the%20next%20(count)%20outputs%20as%20one%20number.%0A%20%20%20%20%09%09%20%20(me.g%20=%20function(count)%20%7B%0A%20%20%20%20%09%09%20%20%20%20//%20Using%20instance%20members%20instead%20of%20closure%20state%20nearly%20doubles%20speed.%0A%20%20%20%20%09%09%20%20%20%20var%20t,%20r%20=%200,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20i%20=%20me.i,%20j%20=%20me.j,%20s%20=%20me.S;%0A%20%20%20%20%09%09%20%20%20%20while%20(count--)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20t%20=%20s%5Bi%20=%20mask%20&%20(i%20+%201)%5D;%0A%20%20%20%20%09%09%20%20%20%20%20%20r%20=%20r%20*%20width%20+%20s%5Bmask%20&%20((s%5Bi%5D%20=%20s%5Bj%20=%20mask%20&%20(j%20+%20t)%5D)%20+%20(s%5Bj%5D%20=%20t))%5D;%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20me.i%20=%20i;%20me.j%20=%20j;%0A%20%20%20%20%09%09%20%20%20%20return%20r;%0A%20%20%20%20%09%09%20%20%20%20//%20For%20robust%20unpredictability,%20the%20function%20call%20below%20automatically%0A%20%20%20%20%09%09%20%20%20%20//%20discards%20an%20initial%20batch%20of%20values.%20%20This%20is%20called%20RC4-drop%5B256%5D.%0A%20%20%20%20%09%09%20%20%20%20//%20See%20http://google.com/search?q=rsa+fluhrer+response&btnI%0A%20%20%20%20%09%09%20%20%7D)(width);%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20copy()%0A%20%20%20%20%09%09//%20Copies%20internal%20state%20of%20ARC4%20to%20or%20from%20a%20plain%20object.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09function%20copy(f,%20t)%20%7B%0A%20%20%20%20%09%09%20%20t.i%20=%20f.i;%0A%20%20%20%20%09%09%20%20t.j%20=%20f.j;%0A%20%20%20%20%09%09%20%20t.S%20=%20f.S.slice();%0A%20%20%20%20%09%09%20%20return%20t;%0A%20%20%20%20%09%09%7D%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20flatten()%0A%20%20%20%20%09%09//%20Converts%20an%20object%20tree%20to%20nested%20arrays%20of%20strings.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09function%20flatten(obj,%20depth)%20%7B%0A%20%20%20%20%09%09%20%20var%20result%20=%20%5B%5D,%20typ%20=%20(typeof%20obj),%20prop;%0A%20%20%20%20%09%09%20%20if%20(depth%20&&%20typ%20==%20'object')%20%7B%0A%20%20%20%20%09%09%20%20%20%20for%20(prop%20in%20obj)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20try%20%7B%20result.push(flatten(obj%5Bprop%5D,%20depth%20-%201));%20%7D%20catch%20(e)%20%7B%7D%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20return%20(result.length%20?%20result%20:%20typ%20==%20'string'%20?%20obj%20:%20obj%20+%20'%5C0');%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20mixkey()%0A%20%20%20%20%09%09//%20Mixes%20a%20string%20seed%20into%20a%20key%20that%20is%20an%20array%20of%20integers,%20and%0A%20%20%20%20%09%09//%20returns%20a%20shortened%20string%20seed%20that%20is%20equivalent%20to%20the%20result%20key.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09function%20mixkey(seed,%20key)%20%7B%0A%20%20%20%20%09%09%20%20var%20stringseed%20=%20seed%20+%20'',%20smear,%20j%20=%200;%0A%20%20%20%20%09%09%20%20while%20(j%20%3C%20stringseed.length)%20%7B%0A%20%20%20%20%09%09%20%20%20%20key%5Bmask%20&%20j%5D%20=%0A%20%20%20%20%09%09%20%20%20%20%20%20mask%20&%20((smear%20%5E=%20key%5Bmask%20&%20j%5D%20*%2019)%20+%20stringseed.charCodeAt(j++));%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20return%20tostring(key);%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20autoseed()%0A%20%20%20%20%09%09//%20Returns%20an%20object%20for%20autoseeding,%20using%20window.crypto%20and%20Node%20crypto%0A%20%20%20%20%09%09//%20module%20if%20available.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09function%20autoseed()%20%7B%0A%20%20%20%20%09%09%20%20try%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20out;%0A%20%20%20%20%09%09%20%20%20%20if%20(nodecrypto%20&&%20(out%20=%20nodecrypto.randomBytes))%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20//%20The%20use%20of%20'out'%20to%20remember%20randomBytes%20makes%20tight%20minified%20code.%0A%20%20%20%20%09%09%20%20%20%20%20%20out%20=%20out(width);%0A%20%20%20%20%09%09%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20out%20=%20new%20Uint8Array(width);%0A%20%20%20%20%09%09%20%20%20%20%20%20(global.crypto%20%7C%7C%20global.msCrypto).getRandomValues(out);%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20return%20tostring(out);%0A%20%20%20%20%09%09%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20browser%20=%20global.navigator,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20plugins%20=%20browser%20&&%20browser.plugins;%0A%20%20%20%20%09%09%20%20%20%20return%20%5B+new%20Date,%20global,%20plugins,%20global.screen,%20tostring(pool)%5D;%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20tostring()%0A%20%20%20%20%09%09//%20Converts%20an%20array%20of%20charcodes%20to%20a%20string%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09function%20tostring(a)%20%7B%0A%20%20%20%20%09%09%20%20return%20String.fromCharCode.apply(0,%20a);%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20When%20seedrandom.js%20is%20loaded,%20we%20immediately%20mix%20a%20few%20bits%0A%20%20%20%20%09%09//%20from%20the%20built-in%20RNG%20into%20the%20entropy%20pool.%20%20Because%20we%20do%0A%20%20%20%20%09%09//%20not%20want%20to%20interfere%20with%20deterministic%20PRNG%20state%20later,%0A%20%20%20%20%09%09//%20seedrandom%20will%20not%20call%20math.random%20on%20its%20own%20again%20after%0A%20%20%20%20%09%09//%20initialization.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09mixkey(math.random(),%20pool);%0A%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20Nodejs%20and%20AMD%20support:%20export%20the%20implementation%20as%20a%20module%20using%0A%20%20%20%20%09%09//%20either%20convention.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09if%20(module.exports)%20%7B%0A%20%20%20%20%09%09%20%20module.exports%20=%20seedrandom;%0A%20%20%20%20%09%09%20%20//%20When%20in%20node.js,%20try%20using%20crypto%20package%20for%20autoseeding.%0A%20%20%20%20%09%09%20%20try%20%7B%0A%20%20%20%20%09%09%20%20%20%20nodecrypto%20=%20require('crypto');%0A%20%20%20%20%09%09%20%20%7D%20catch%20(ex)%20%7B%7D%0A%20%20%20%20%09%09%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20//%20When%20included%20as%20a%20plain%20script,%20set%20up%20Math.seedrandom%20global.%0A%20%20%20%20%09%09%20%20math%5B'seed'%20+%20rngname%5D%20=%20seedrandom;%0A%20%20%20%20%09%09%7D%0A%0A%0A%20%20%20%20%09%09//%20End%20anonymous%20scope,%20and%20pass%20initial%20values.%0A%20%20%20%20%09%09%7D)(%0A%20%20%20%20%09%09%20%20//%20global:%20%60self%60%20in%20browsers%20(including%20strict%20mode%20and%20web%20workers),%0A%20%20%20%20%09%09%20%20//%20otherwise%20%60this%60%20in%20Node%20and%20other%20environments%0A%20%20%20%20%09%09%20%20(typeof%20self%20!==%20'undefined')%20?%20self%20:%20seedrandom$1,%0A%20%20%20%20%09%09%20%20%5B%5D,%20%20%20%20%20//%20pool:%20entropy%20pool%20starts%20empty%0A%20%20%20%20%09%09%20%20Math%20%20%20%20//%20math:%20package%20containing%20random,%20pow,%20and%20seedrandom%0A%20%20%20%20%09%09);%20%0A%20%20%20%20%09%7D%20(seedrandom$2));%0A%20%20%20%20%09return%20seedrandom$2.exports;%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20seedrandom;%0A%20%20%20%20var%20hasRequiredSeedrandom;%0A%0A%20%20%20%20function%20requireSeedrandom%20()%20%7B%0A%20%20%20%20%09if%20(hasRequiredSeedrandom)%20return%20seedrandom;%0A%20%20%20%20%09hasRequiredSeedrandom%20=%201;%0A%20%20%20%20%09//%20A%20library%20of%20seedable%20RNGs%20implemented%20in%20Javascript.%0A%20%20%20%20%09//%0A%20%20%20%20%09//%20Usage:%0A%20%20%20%20%09//%0A%20%20%20%20%09//%20var%20seedrandom%20=%20require('seedrandom');%0A%20%20%20%20%09//%20var%20random%20=%20seedrandom(1);%20//%20or%20any%20seed.%0A%20%20%20%20%09//%20var%20x%20=%20random();%20%20%20%20%20%20%20//%200%20%3C=%20x%20%3C%201.%20%20Every%20bit%20is%20random.%0A%20%20%20%20%09//%20var%20x%20=%20random.quick();%20//%200%20%3C=%20x%20%3C%201.%20%2032%20bits%20of%20randomness.%0A%0A%20%20%20%20%09//%20alea,%20a%2053-bit%20multiply-with-carry%20generator%20by%20Johannes%20Baag%C3%B8e.%0A%20%20%20%20%09//%20Period:%20~2%5E116%0A%20%20%20%20%09//%20Reported%20to%20pass%20all%20BigCrush%20tests.%0A%20%20%20%20%09var%20alea%20=%20requireAlea();%0A%0A%20%20%20%20%09//%20xor128,%20a%20pure%20xor-shift%20generator%20by%20George%20Marsaglia.%0A%20%20%20%20%09//%20Period:%202%5E128-1.%0A%20%20%20%20%09//%20Reported%20to%20fail:%20MatrixRank%20and%20LinearComp.%0A%20%20%20%20%09var%20xor128%20=%20requireXor128();%0A%0A%20%20%20%20%09//%20xorwow,%20George%20Marsaglia's%20160-bit%20xor-shift%20combined%20plus%20weyl.%0A%20%20%20%20%09//%20Period:%202%5E192-2%5E32%0A%20%20%20%20%09//%20Reported%20to%20fail:%20CollisionOver,%20SimpPoker,%20and%20LinearComp.%0A%20%20%20%20%09var%20xorwow%20=%20requireXorwow();%0A%0A%20%20%20%20%09//%20xorshift7,%20by%20Fran%C3%A7ois%20Panneton%20and%20Pierre%20L'ecuyer,%20takes%0A%20%20%20%20%09//%20a%20different%20approach:%20it%20adds%20robustness%20by%20allowing%20more%20shifts%0A%20%20%20%20%09//%20than%20Marsaglia's%20original%20three.%20%20It%20is%20a%207-shift%20generator%0A%20%20%20%20%09//%20with%20256%20bits,%20that%20passes%20BigCrush%20with%20no%20systmatic%20failures.%0A%20%20%20%20%09//%20Period%202%5E256-1.%0A%20%20%20%20%09//%20No%20systematic%20BigCrush%20failures%20reported.%0A%20%20%20%20%09var%20xorshift7%20=%20requireXorshift7();%0A%0A%20%20%20%20%09//%20xor4096,%20by%20Richard%20Brent,%20is%20a%204096-bit%20xor-shift%20with%20a%0A%20%20%20%20%09//%20very%20long%20period%20that%20also%20adds%20a%20Weyl%20generator.%20It%20also%20passes%0A%20%20%20%20%09//%20BigCrush%20with%20no%20systematic%20failures.%20%20Its%20long%20period%20may%0A%20%20%20%20%09//%20be%20useful%20if%20you%20have%20many%20generators%20and%20need%20to%20avoid%0A%20%20%20%20%09//%20collisions.%0A%20%20%20%20%09//%20Period:%202%5E4128-2%5E32.%0A%20%20%20%20%09//%20No%20systematic%20BigCrush%20failures%20reported.%0A%20%20%20%20%09var%20xor4096%20=%20requireXor4096();%0A%0A%20%20%20%20%09//%20Tyche-i,%20by%20Samuel%20Neves%20and%20Filipe%20Araujo,%20is%20a%20bit-shifting%20random%0A%20%20%20%20%09//%20number%20generator%20derived%20from%20ChaCha,%20a%20modern%20stream%20cipher.%0A%20%20%20%20%09//%20https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf%0A%20%20%20%20%09//%20Period:%20~2%5E127%0A%20%20%20%20%09//%20No%20systematic%20BigCrush%20failures%20reported.%0A%20%20%20%20%09var%20tychei%20=%20requireTychei();%0A%0A%20%20%20%20%09//%20The%20original%20ARC4-based%20prng%20included%20in%20this%20library.%0A%20%20%20%20%09//%20Period:%20~2%5E1600%0A%20%20%20%20%09var%20sr%20=%20requireSeedrandom$1();%0A%0A%20%20%20%20%09sr.alea%20=%20alea;%0A%20%20%20%20%09sr.xor128%20=%20xor128;%0A%20%20%20%20%09sr.xorwow%20=%20xorwow;%0A%20%20%20%20%09sr.xorshift7%20=%20xorshift7;%0A%20%20%20%20%09sr.xor4096%20=%20xor4096;%0A%20%20%20%20%09sr.tychei%20=%20tychei;%0A%0A%20%20%20%20%09seedrandom%20=%20sr;%0A%20%20%20%20%09return%20seedrandom;%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20seedrandomExports%20=%20requireSeedrandom();%0A%20%20%20%20var%20Seedrandom%20=%20/*@__PURE__*/getDefaultExportFromCjs(seedrandomExports);%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7BHTMLCanvasElement%7D%20canvas%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20domainKey%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20sessionKey%0A%20%20%20%20%20*%20@param%20%7Bany%7D%20getImageDataProxy%0A%20%20%20%20%20*%20@param%20%7BCanvasRenderingContext2D%20%7C%20WebGL2RenderingContext%20%7C%20WebGLRenderingContext%7D%20ctx?%0A%20%20%20%20%20*/%0A%20%20%20%20function%20computeOffScreenCanvas(canvas,%20domainKey,%20sessionKey,%20getImageDataProxy,%20ctx)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!ctx)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Type%20'null'%20is%20not%20assignable%20to%20type%20'CanvasRenderingContext2D%20%7C%20WebGL2RenderingContext%20%7C%20WebGLRenderingContext'.%0A%20%20%20%20%20%20%20%20%20%20%20%20ctx%20=%20canvas.getContext('2d');%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Make%20a%20off-screen%20canvas%20and%20put%20the%20data%20there%0A%20%20%20%20%20%20%20%20const%20offScreenCanvas%20=%20document.createElement('canvas');%0A%20%20%20%20%20%20%20%20offScreenCanvas.width%20=%20canvas.width;%0A%20%20%20%20%20%20%20%20offScreenCanvas.height%20=%20canvas.height;%0A%20%20%20%20%20%20%20%20const%20offScreenCtx%20=%20offScreenCanvas.getContext('2d');%0A%0A%20%20%20%20%20%20%20%20let%20rasterizedCtx%20=%20ctx;%0A%20%20%20%20%20%20%20%20//%20If%20we're%20not%20a%202d%20canvas%20we%20need%20to%20rasterise%20first%20into%202d%0A%20%20%20%20%20%20%20%20const%20rasterizeToCanvas%20=%20!(ctx%20instanceof%20CanvasRenderingContext2D);%0A%20%20%20%20%20%20%20%20if%20(rasterizeToCanvas)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Type%20'CanvasRenderingContext2D%20%7C%20null'%20is%20not%20assignable%20to%20type%20'CanvasRenderingContext2D%20%7C%20WebGL2RenderingContext%20%7C%20WebGLRenderingContext'.%0A%20%20%20%20%20%20%20%20%20%20%20%20rasterizedCtx%20=%20offScreenCtx;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20'offScreenCtx'%20is%20possibly%20'null'.%0A%20%20%20%20%20%20%20%20%20%20%20%20offScreenCtx.drawImage(canvas,%200,%200);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20We%20*always*%20compute%20the%20random%20pixels%20on%20the%20complete%20pixel%20set,%20then%20pass%20back%20the%20subset%20later%0A%20%20%20%20%20%20%20%20let%20imageData%20=%20getImageDataProxy._native.apply(rasterizedCtx,%20%5B0,%200,%20canvas.width,%20canvas.height%5D);%0A%20%20%20%20%20%20%20%20imageData%20=%20modifyPixelData(imageData,%20sessionKey,%20domainKey,%20canvas.width);%0A%0A%20%20%20%20%20%20%20%20if%20(rasterizeToCanvas)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Type%20'null'%20is%20not%20assignable%20to%20type%20'CanvasRenderingContext2D'.%0A%20%20%20%20%20%20%20%20%20%20%20%20clearCanvas(offScreenCtx);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20'offScreenCtx'%20is%20possibly%20'null'.%0A%20%20%20%20%20%20%20%20offScreenCtx.putImageData(imageData,%200,%200);%0A%0A%20%20%20%20%20%20%20%20return%20%7B%20offScreenCanvas,%20offScreenCtx%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Clears%20the%20pixels%20from%20the%20canvas%20context%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@param%20%7BCanvasRenderingContext2D%7D%20canvasContext%0A%20%20%20%20%20*/%0A%20%20%20%20function%20clearCanvas(canvasContext)%20%7B%0A%20%20%20%20%20%20%20%20//%20Save%20state%20and%20clean%20the%20pixels%20from%20the%20canvas%0A%20%20%20%20%20%20%20%20canvasContext.save();%0A%20%20%20%20%20%20%20%20canvasContext.globalCompositeOperation%20=%20'destination-out';%0A%20%20%20%20%20%20%20%20canvasContext.fillStyle%20=%20'rgb(255,255,255)';%0A%20%20%20%20%20%20%20%20canvasContext.fillRect(0,%200,%20canvasContext.canvas.width,%20canvasContext.canvas.height);%0A%20%20%20%20%20%20%20%20canvasContext.restore();%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7Bimport(%22@canvas/image-data%22)%7D%20imageData%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20sessionKey%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20domainKey%0A%20%20%20%20%20*%20@param%20%7Bnumber%7D%20width%0A%20%20%20%20%20*/%0A%20%20%20%20function%20modifyPixelData(imageData,%20domainKey,%20sessionKey,%20width)%20%7B%0A%20%20%20%20%20%20%20%20const%20d%20=%20imageData.data;%0A%20%20%20%20%20%20%20%20const%20length%20=%20d.length%20/%204;%0A%20%20%20%20%20%20%20%20let%20checkSum%20=%200;%0A%20%20%20%20%20%20%20%20const%20mappingArray%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20for%20(let%20i%20=%200;%20i%20%3C%20length;%20i%20+=%204)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!shouldIgnorePixel(d,%20i)%20&&%20!adjacentSame(d,%20i,%20width))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mappingArray.push(i);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20checkSum%20+=%20d%5Bi%5D%20+%20d%5Bi%20+%201%5D%20+%20d%5Bi%20+%202%5D%20+%20d%5Bi%20+%203%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20windowHash%20=%20getDataKeySync(sessionKey,%20domainKey,%20checkSum);%0A%20%20%20%20%20%20%20%20const%20rng%20=%20new%20Seedrandom(windowHash);%0A%20%20%20%20%20%20%20%20for%20(let%20i%20=%200;%20i%20%3C%20mappingArray.length;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20rand%20=%20rng();%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20byte%20=%20Math.floor(rand%20*%2010);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20channel%20=%20byte%20%25%203;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20pixelCanvasIndex%20=%20mappingArray%5Bi%5D%20+%20channel;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20d%5BpixelCanvasIndex%5D%20=%20d%5BpixelCanvasIndex%5D%20%5E%20(byte%20&%200x1);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20imageData;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Ignore%20pixels%20that%20have%20neighbours%20that%20are%20the%20same%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@param%20%7BUint8ClampedArray%7D%20imageData%0A%20%20%20%20%20*%20@param%20%7Bnumber%7D%20index%0A%20%20%20%20%20*%20@param%20%7Bnumber%7D%20width%0A%20%20%20%20%20*/%0A%20%20%20%20function%20adjacentSame(imageData,%20index,%20width)%20%7B%0A%20%20%20%20%20%20%20%20const%20widthPixel%20=%20width%20*%204;%0A%20%20%20%20%20%20%20%20const%20x%20=%20index%20%25%20widthPixel;%0A%20%20%20%20%20%20%20%20const%20maxLength%20=%20imageData.length;%0A%0A%20%20%20%20%20%20%20%20//%20Pixels%20not%20on%20the%20right%20border%20of%20the%20canvas%0A%20%20%20%20%20%20%20%20if%20(x%20%3C%20widthPixel)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20right%20=%20index%20+%204;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!pixelsSame(imageData,%20index,%20right))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20diagonalRightUp%20=%20right%20-%20widthPixel;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(diagonalRightUp%20%3E%200%20&&%20!pixelsSame(imageData,%20index,%20diagonalRightUp))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20diagonalRightDown%20=%20right%20+%20widthPixel;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(diagonalRightDown%20%3C%20maxLength%20&&%20!pixelsSame(imageData,%20index,%20diagonalRightDown))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Pixels%20not%20on%20the%20left%20border%20of%20the%20canvas%0A%20%20%20%20%20%20%20%20if%20(x%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20left%20=%20index%20-%204;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!pixelsSame(imageData,%20index,%20left))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20diagonalLeftUp%20=%20left%20-%20widthPixel;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(diagonalLeftUp%20%3E%200%20&&%20!pixelsSame(imageData,%20index,%20diagonalLeftUp))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20diagonalLeftDown%20=%20left%20+%20widthPixel;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(diagonalLeftDown%20%3C%20maxLength%20&&%20!pixelsSame(imageData,%20index,%20diagonalLeftDown))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20up%20=%20index%20-%20widthPixel;%0A%20%20%20%20%20%20%20%20if%20(up%20%3E%200%20&&%20!pixelsSame(imageData,%20index,%20up))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20down%20=%20index%20+%20widthPixel;%0A%20%20%20%20%20%20%20%20if%20(down%20%3C%20maxLength%20&&%20!pixelsSame(imageData,%20index,%20down))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Check%20that%20a%20pixel%20at%20index%20and%20index2%20match%20all%20channels%0A%20%20%20%20%20*%20@param%20%7BUint8ClampedArray%7D%20imageData%0A%20%20%20%20%20*%20@param%20%7Bnumber%7D%20index%0A%20%20%20%20%20*%20@param%20%7Bnumber%7D%20index2%0A%20%20%20%20%20*/%0A%20%20%20%20function%20pixelsSame(imageData,%20index,%20index2)%20%7B%0A%20%20%20%20%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20imageData%5Bindex%5D%20===%20imageData%5Bindex2%5D%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20imageData%5Bindex%20+%201%5D%20===%20imageData%5Bindex2%20+%201%5D%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20imageData%5Bindex%20+%202%5D%20===%20imageData%5Bindex2%20+%202%5D%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20imageData%5Bindex%20+%203%5D%20===%20imageData%5Bindex2%20+%203%5D%0A%20%20%20%20%20%20%20%20);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Returns%20true%20if%20pixel%20should%20be%20ignored%0A%20%20%20%20%20*%20@param%20%7BUint8ClampedArray%7D%20imageData%0A%20%20%20%20%20*%20@param%20%7Bnumber%7D%20index%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20shouldIgnorePixel(imageData,%20index)%20%7B%0A%20%20%20%20%20%20%20%20//%20Transparent%20pixels%0A%20%20%20%20%20%20%20%20if%20(imageData%5Bindex%20+%203%5D%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20FingerprintingCanvas%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20sessionKey,%20site%20%7D%20=%20args;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20domainKey%20=%20site.domain;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20supportsWebGl%20=%20this.getFeatureSettingEnabled('webGl');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20unsafeCanvases%20=%20new%20WeakSet();%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20canvasContexts%20=%20new%20WeakMap();%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20canvasCache%20=%20new%20WeakMap();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Clear%20cache%20as%20canvas%20has%20changed%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BOffscreenCanvas%20%7C%20HTMLCanvasElement%7D%20canvas%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20clearCache(canvas)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20canvasCache.delete(canvas);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BOffscreenCanvas%20%7C%20HTMLCanvasElement%7D%20canvas%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20treatAsUnsafe(canvas)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unsafeCanvases.add(canvas);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clearCache(canvas);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20proxy%20=%20new%20DDGProxy(this,%20HTMLCanvasElement.prototype,%20'getContext',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20context%20=%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20canvasContexts.set(thisArg,%20context);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20%7B%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20context;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20proxy.overload();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Known%20data%20methods%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20safeMethods%20=%20%5B'putImageData',%20'drawImage'%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20methodName%20of%20safeMethods)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20safeMethodProxy%20=%20new%20DDGProxy(this,%20CanvasRenderingContext2D.prototype,%20methodName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Don't%20apply%20escape%20hatch%20for%20canvases%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(methodName%20===%20'drawImage'%20&&%20args%5B0%5D%20&&%20args%5B0%5D%20instanceof%20HTMLCanvasElement)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20treatAsUnsafe(args%5B0%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clearCache(thisArg.canvas);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20safeMethodProxy.overload();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20unsafeMethods%20=%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'strokeRect',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'bezierCurveTo',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'quadraticCurveTo',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'arcTo',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'ellipse',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'rect',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'fill',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'stroke',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'lineTo',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'beginPath',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'closePath',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'arc',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'fillText',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'fillRect',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'strokeText',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'createConicGradient',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'createLinearGradient',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'createRadialGradient',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'createPattern',%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20methodName%20of%20unsafeMethods)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Some%20methods%20are%20browser%20specific%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(methodName%20in%20CanvasRenderingContext2D.prototype)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20unsafeProxy%20=%20new%20DDGProxy(this,%20CanvasRenderingContext2D.prototype,%20methodName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20treatAsUnsafe(thisArg.canvas);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unsafeProxy.overload();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(supportsWebGl)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20unsafeGlMethods%20=%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'commit',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'compileShader',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'shaderSource',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'attachShader',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'createProgram',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'linkProgram',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'drawElements',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'drawArrays',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20glContexts%20=%20%5BWebGLRenderingContext%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('WebGL2RenderingContext'%20in%20globalThis)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20glContexts.push(WebGL2RenderingContext);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20context%20of%20glContexts)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20methodName%20of%20unsafeGlMethods)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Some%20methods%20are%20browser%20specific%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(methodName%20in%20context.prototype)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20unsafeProxy%20=%20new%20DDGProxy(this,%20context.prototype,%20methodName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20treatAsUnsafe(thisArg.canvas);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unsafeProxy.overload();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Using%20proxies%20here%20to%20swallow%20calls%20to%20toString%20etc%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20getImageDataProxy%20=%20new%20DDGProxy(this,%20CanvasRenderingContext2D.prototype,%20'getImageData',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!unsafeCanvases.has(thisArg.canvas))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Anything%20we%20do%20here%20should%20be%20caught%20and%20ignored%20silently%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20offScreenCtx%20%7D%20=%20getCachedOffScreenCanvasOrCompute(thisArg.canvas,%20domainKey,%20sessionKey);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Call%20the%20original%20method%20on%20the%20modified%20off-screen%20canvas%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20offScreenCtx,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20%7B%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20getImageDataProxy.overload();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Get%20cached%20offscreen%20if%20one%20exists,%20otherwise%20compute%20one%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLCanvasElement%7D%20canvas%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20domainKey%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20sessionKey%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20getCachedOffScreenCanvasOrCompute(canvas,%20domainKey,%20sessionKey)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20result;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(canvasCache.has(canvas))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result%20=%20canvasCache.get(canvas);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20ctx%20=%20canvasContexts.get(canvas);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result%20=%20computeOffScreenCanvas(canvas,%20domainKey,%20sessionKey,%20getImageDataProxy,%20ctx);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20canvasCache.set(canvas,%20result);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20result;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20canvasMethods%20=%20%5B'toDataURL',%20'toBlob'%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20methodName%20of%20canvasMethods)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20proxy%20=%20new%20DDGProxy(this,%20HTMLCanvasElement.prototype,%20methodName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Short%20circuit%20for%20low%20risk%20canvas%20calls%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!unsafeCanvases.has(thisArg))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20offScreenCanvas%20%7D%20=%20getCachedOffScreenCanvasOrCompute(thisArg,%20domainKey,%20sessionKey);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Call%20the%20original%20method%20on%20the%20modified%20off-screen%20canvas%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20offScreenCanvas,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Something%20we%20did%20caused%20an%20exception,%20fall%20back%20to%20the%20native%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20proxy.overload();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20GoogleRejected%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('browsingTopics'%20in%20Document.prototype)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20Document.prototype.browsingTopics;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('joinAdInterestGroup'%20in%20Navigator.prototype)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20Navigator.prototype.joinAdInterestGroup;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('leaveAdInterestGroup'%20in%20Navigator.prototype)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20Navigator.prototype.leaveAdInterestGroup;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('updateAdInterestGroups'%20in%20Navigator.prototype)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20Navigator.prototype.updateAdInterestGroups;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('runAdAuction'%20in%20Navigator.prototype)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20Navigator.prototype.runAdAuction;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('adAuctionComponents'%20in%20Navigator.prototype)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20Navigator.prototype.adAuctionComponents;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Throw%20away%20this%20exception,%20it's%20likely%20a%20confict%20with%20another%20extension%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20Set%20Global%20Privacy%20Control%20property%20on%20DOM%0A%20%20%20%20class%20GlobalPrivacyControl%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20GPC%20on,%20set%20DOM%20property%20prototype%20to%20true%20if%20not%20already%20true%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(args.globalPrivacyControlValue)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(navigator.globalPrivacyControl)%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.defineProperty(Navigator.prototype,%20'globalPrivacyControl',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20GPC%20off%20&%20unsupported%20by%20browser,%20set%20DOM%20property%20prototype%20to%20false%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20this%20may%20be%20overwritten%20by%20the%20user%20agent%20or%20other%20extensions%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20navigator.globalPrivacyControl%20!==%20'undefined')%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.defineProperty(Navigator.prototype,%20'globalPrivacyControl',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Ignore%20exceptions%20that%20could%20be%20caused%20by%20conflicting%20with%20other%20extensions%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20FingerprintingHardware%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Navigator.prototype,%20'keyboard',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS2554:%20Expected%202%20arguments,%20but%20got%201.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this.getFeatureAttr('keyboard');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Navigator.prototype,%20'hardwareConcurrency',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this.getFeatureAttr('hardwareConcurrency',%202);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Navigator.prototype,%20'deviceMemory',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this.getFeatureAttr('deviceMemory',%208);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20Referrer%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20the%20referer%20is%20a%20different%20host%20to%20the%20current%20one,%20trim%20it.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(document.referrer%20&&%20new%20URL(document.URL).hostname%20!==%20new%20URL(document.referrer).hostname)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20trim%20referrer%20to%20origin.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20trimmedReferer%20=%20new%20URL(document.referrer).origin%20+%20'/';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(Document.prototype,%20'referrer',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20trimmedReferer,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20FingerprintingScreenSize%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20origPropertyValues%20=%20%7B%7D;%0A%0A%20%20%20%20%20%20%20%20init()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20this.origPropertyValues.availTop%20=%20globalThis.screen.availTop;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Screen.prototype,%20'availTop',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20this.getFeatureAttr('availTop',%200),%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20this.origPropertyValues.availLeft%20=%20globalThis.screen.availLeft;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Screen.prototype,%20'availLeft',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20this.getFeatureAttr('availLeft',%200),%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.origPropertyValues.availWidth%20=%20globalThis.screen.availWidth;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20forcedAvailWidthValue%20=%20globalThis.screen.width;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Screen.prototype,%20'availWidth',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20forcedAvailWidthValue,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.origPropertyValues.availHeight%20=%20globalThis.screen.availHeight;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20forcedAvailHeightValue%20=%20globalThis.screen.height;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Screen.prototype,%20'availHeight',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20forcedAvailHeightValue,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.origPropertyValues.colorDepth%20=%20globalThis.screen.colorDepth;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Screen.prototype,%20'colorDepth',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20this.getFeatureAttr('colorDepth',%2024),%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.origPropertyValues.pixelDepth%20=%20globalThis.screen.pixelDepth;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Screen.prototype,%20'pixelDepth',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20this.getFeatureAttr('pixelDepth',%2024),%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20globalThis.window.addEventListener('resize',%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowDimensions();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowDimensions();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20normalize%20window%20dimensions,%20if%20more%20than%20one%20monitor%20is%20in%20play.%0A%20%20%20%20%20%20%20%20%20*%20%20X/Y%20values%20are%20set%20in%20the%20browser%20based%20on%20distance%20to%20the%20main%20monitor%20top%20or%20left,%20which%0A%20%20%20%20%20%20%20%20%20*%20can%20mean%20second%20or%20more%20monitors%20have%20very%20large%20or%20negative%20values.%20This%20function%20maps%20a%20given%0A%20%20%20%20%20%20%20%20%20*%20given%20coordinate%20value%20to%20the%20proper%20place%20on%20the%20main%20screen.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20normalizeWindowDimension(value,%20targetDimension)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(value%20%3E%20targetDimension)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20value%20%25%20targetDimension;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(value%20%3C%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20targetDimension%20+%20value;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20value;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20setWindowPropertyValue(property,%20value)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Here%20we%20don't%20update%20the%20prototype%20getter%20because%20the%20values%20are%20updated%20dynamically%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.defineProperty(globalThis,%20property,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20value,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20set:%20()%20=%3E%20%7B%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Fix%20window%20dimensions.%20The%20extension%20runs%20in%20a%20different%20JS%20context%20than%20the%0A%20%20%20%20%20%20%20%20%20*%20page,%20so%20we%20can%20inject%20the%20correct%20screen%20values%20as%20the%20window%20is%20resized,%0A%20%20%20%20%20%20%20%20%20*%20ensuring%20that%20no%20information%20is%20leaked%20as%20the%20dimensions%20change,%20but%20also%20that%20the%0A%20%20%20%20%20%20%20%20%20*%20values%20change%20correctly%20for%20valid%20use%20cases.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20setWindowDimensions()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20window%20=%20globalThis;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20top%20=%20globalThis.top;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20normalizedY%20=%20this.normalizeWindowDimension(window.screenY,%20window.screen.height);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20normalizedX%20=%20this.normalizeWindowDimension(window.screenX,%20window.screen.width);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(normalizedY%20%3C=%20this.origPropertyValues.availTop)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('screenY',%200);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('screenTop',%200);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('screenY',%20normalizedY);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('screenTop',%20normalizedY);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20%20error%20TS18047:%20'top'%20is%20possibly%20'null'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(top.window.outerHeight%20%3E=%20this.origPropertyValues.availHeight%20-%201)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20%20error%20TS18047:%20'top'%20is%20possibly%20'null'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('outerHeight',%20top.window.screen.height);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20%20error%20TS18047:%20'top'%20is%20possibly%20'null'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('outerHeight',%20top.window.outerHeight);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20top%20not%20accessible%20to%20certain%20iFrames,%20so%20ignore.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(normalizedX%20%3C=%20this.origPropertyValues.availLeft)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('screenX',%200);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('screenLeft',%200);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('screenX',%20normalizedX);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('screenLeft',%20normalizedX);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20%20error%20TS18047:%20'top'%20is%20possibly%20'null'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(top.window.outerWidth%20%3E=%20this.origPropertyValues.availWidth%20-%201)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20%20error%20TS18047:%20'top'%20is%20possibly%20'null'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('outerWidth',%20top.window.screen.width);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20%20error%20TS18047:%20'top'%20is%20possibly%20'null'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('outerWidth',%20top.window.outerWidth);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20top%20not%20accessible%20to%20certain%20iFrames,%20so%20ignore.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20in%20a%20cross%20domain%20iFrame,%20top.window%20is%20not%20accessible.%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20FingerprintingTemporaryStorage%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20navigator%20=%20globalThis.navigator;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20Navigator%20=%20globalThis.Navigator;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Temporary%20storage%20can%20be%20used%20to%20determine%20hard%20disk%20usage%20and%20size.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20This%20will%20limit%20the%20max%20storage%20to%204GB%20without%20completely%20disabling%20the%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20feature.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(navigator.webkitTemporaryStorage)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20org%20=%20navigator.webkitTemporaryStorage.queryUsageAndQuota;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20tStorage%20=%20navigator.webkitTemporaryStorage;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tStorage.queryUsageAndQuota%20=%20function%20queryUsageAndQuota(callback,%20err)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20modifiedCallback%20=%20function%20(usedBytes,%20grantedBytes)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20maxBytesGranted%20=%204%20*%201024%20*%201024%20*%201024;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20spoofedGrantedBytes%20=%20Math.min(grantedBytes,%20maxBytesGranted);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20callback(usedBytes,%20spoofedGrantedBytes);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20org.call(navigator.webkitTemporaryStorage,%20modifiedCallback,%20err);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.defineProperty(Navigator.prototype,%20'webkitTemporaryStorage',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20tStorage,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7Bunknown%7D%20input%0A%20%20%20%20%20*%20@return%20%7Binput%20is%20Object%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isObject(input)%20%7B%0A%20%20%20%20%20%20%20%20return%20toString.call(input)%20===%20'%5Bobject%20Object%5D';%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7Bunknown%7D%20input%0A%20%20%20%20%20*%20@return%20%7Binput%20is%20string%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isString(input)%20%7B%0A%20%20%20%20%20%20%20%20return%20typeof%20input%20===%20'string';%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@import%20%7B%20Messaging%20%7D%20from%20%22@duckduckgo/messaging%22;%0A%20%20%20%20%20*%20@typedef%20%7BPick%3CMessaging,%20'notify'%20%7C%20'request'%20%7C%20'subscribe'%3E%7D%20MessagingInterface%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Sending%20this%20event%0A%20%20%20%20%20*/%0A%20%20%20%20class%20InstallProxy%20%7B%0A%20%20%20%20%20%20%20%20static%20NAME%20=%20'INSTALL_BRIDGE';%0A%20%20%20%20%20%20%20%20get%20name()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20InstallProxy.NAME;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.id%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.id%20=%20params.id;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bunknown%7D%20params%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20create(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isObject(params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.featureName))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.id))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20InstallProxy(%7B%20featureName:%20params.featureName,%20id:%20params.id%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20DidInstall%20%7B%0A%20%20%20%20%20%20%20%20static%20NAME%20=%20'DID_INSTALL';%0A%20%20%20%20%20%20%20%20get%20name()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20DidInstall.NAME;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.id%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.id%20=%20params.id;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bunknown%7D%20params%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20create(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isObject(params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.id))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20DidInstall(%7B%20id:%20params.id%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20ProxyRequest%20%7B%0A%20%20%20%20%20%20%20%20static%20NAME%20=%20'PROXY_REQUEST';%0A%20%20%20%20%20%20%20%20get%20name()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20ProxyRequest.NAME;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.method%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.id%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bparams.params%5D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.method%20=%20params.method;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.params%20=%20params.params;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.id%20=%20params.id;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bunknown%7D%20params%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20create(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isObject(params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.featureName))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.method))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.id))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(params.params%20&&%20!isObject(params.params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20ProxyRequest(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName:%20params.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20method:%20params.method,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params:%20params.params,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id:%20params.id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20ProxyResponse%20%7B%0A%20%20%20%20%20%20%20%20static%20NAME%20=%20'PROXY_RESPONSE';%0A%20%20%20%20%20%20%20%20get%20name()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20ProxyResponse.NAME;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.method%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.id%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bparams.result%5D%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport(%22@duckduckgo/messaging%22).MessageError%7D%20%5Bparams.error%5D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.method%20=%20params.method;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.result%20=%20params.result;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.error%20=%20params.error;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.id%20=%20params.id;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bunknown%7D%20params%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20create(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isObject(params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.featureName))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.method))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.id))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(params.result%20&&%20!isObject(params.result))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(params.error%20&&%20!isObject(params.error))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20ProxyResponse(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName:%20params.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20method:%20params.method,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result:%20params.result,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20error:%20params.error,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id:%20params.id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*/%0A%20%20%20%20class%20ProxyNotification%20%7B%0A%20%20%20%20%20%20%20%20static%20NAME%20=%20'PROXY_NOTIFICATION';%0A%20%20%20%20%20%20%20%20get%20name()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20ProxyNotification.NAME;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.method%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bparams.params%5D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.method%20=%20params.method;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.params%20=%20params.params;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bunknown%7D%20params%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20create(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isObject(params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.featureName))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.method))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(params.params%20&&%20!isObject(params.params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20ProxyNotification(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName:%20params.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20method:%20params.method,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params:%20params.params,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20SubscriptionRequest%20%7B%0A%20%20%20%20%20%20%20%20static%20NAME%20=%20'SUBSCRIPTION_REQUEST';%0A%20%20%20%20%20%20%20%20get%20name()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20SubscriptionRequest.NAME;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.subscriptionName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.id%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.subscriptionName%20=%20params.subscriptionName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.id%20=%20params.id;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bunknown%7D%20params%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20create(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isObject(params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.featureName))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.subscriptionName))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.id))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20SubscriptionRequest(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName:%20params.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20subscriptionName:%20params.subscriptionName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id:%20params.id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20SubscriptionResponse%20%7B%0A%20%20%20%20%20%20%20%20static%20NAME%20=%20'SUBSCRIPTION_RESPONSE';%0A%20%20%20%20%20%20%20%20get%20name()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20SubscriptionResponse.NAME;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.subscriptionName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.id%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bparams.params%5D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.subscriptionName%20=%20params.subscriptionName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.id%20=%20params.id;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.params%20=%20params.params;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bunknown%7D%20params%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20create(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isObject(params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.featureName))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.subscriptionName))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.id))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(params.params%20&&%20!isObject(params.params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20SubscriptionResponse(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName:%20params.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20subscriptionName:%20params.subscriptionName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params:%20params.params,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id:%20params.id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20SubscriptionUnsubscribe%20%7B%0A%20%20%20%20%20%20%20%20static%20NAME%20=%20'SUBSCRIPTION_UNSUBSCRIBE';%0A%20%20%20%20%20%20%20%20get%20name()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20SubscriptionUnsubscribe.NAME;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.id%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.id%20=%20params.id;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bunknown%7D%20params%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20create(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isObject(params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.id))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20SubscriptionUnsubscribe(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id:%20params.id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@import%20%7B%20MessagingInterface%20%7D%20from%20%22./schema.js%22%0A%20%20%20%20%20*%20@typedef%20%7BPick%3Cimport(%22../../captured-globals.js%22),%0A%20%20%20%20%20*%20%20%20%20%22dispatchEvent%22%20%7C%20%22addEventListener%22%20%7C%20%22removeEventListener%22%20%7C%20%22CustomEvent%22%20%7C%20%22String%22%20%7C%20%22Error%22%20%7C%20%22randomUUID%22%3E%0A%20%20%20%20%20*%20%7D%20Captured%0A%20%20%20%20%20*/%0A%20%20%20%20/**%20@type%20%7BCaptured%7D%20*/%0A%20%20%20%20const%20captured%20=%20capturedGlobals;%0A%0A%20%20%20%20const%20ERROR_MSG%20=%20'Did%20not%20install%20Message%20Bridge';%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Try%20to%20create%20a%20message%20bridge.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20Note:%20This%20will%20throw%20an%20exception%20if%20the%20bridge%20cannot%20be%20established.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20featureName%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5Btoken%5D%0A%20%20%20%20%20*%20@return%20%7BMessagingInterface%7D%0A%20%20%20%20%20*%20@throws%20%7BError%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20createPageWorldBridge(featureName,%20token)%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20This%20feature%20never%20operates%20without%20a%20featureName%20or%20token%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20if%20(typeof%20featureName%20!==%20'string'%20%7C%7C%20!token)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20captured.Error(ERROR_MSG);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20This%20feature%20never%20operates%20in%20a%20frame%20or%20insecure%20context%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20if%20(isBeingFramed()%20%7C%7C%20!isSecureContext)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20captured.Error(ERROR_MSG);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20eventName%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7B%60$%7Bstring%7D-$%7Bstring%7D%60%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20const%20appendToken%20=%20(eventName)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%60$%7BeventName%7D-$%7Btoken%7D%60;%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Create%20the%20sender%20to%20centralize%20the%20sending%20logic%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B%7Bname:%20string%7D%20&%20Record%3Cstring,%20any%3E%7D%20incoming%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20const%20send%20=%20(incoming)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20when%20the%20token%20is%20absent,%20just%20silently%20fail%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!token)%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20event%20=%20new%20captured.CustomEvent(appendToken(incoming.name),%20%7B%20detail:%20incoming%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20captured.dispatchEvent(event);%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Events%20are%20synchronous%20(even%20across%20contexts),%20so%20we%20can%20figure%20out%0A%20%20%20%20%20%20%20%20%20*%20the%20result%20of%20installing%20the%20proxy%20before%20we%20return%20and%20give%20a%0A%20%20%20%20%20%20%20%20%20*%20better%20experience%20for%20consumers%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20let%20installed%20=%20false;%0A%20%20%20%20%20%20%20%20const%20id%20=%20random();%0A%20%20%20%20%20%20%20%20const%20evt%20=%20new%20InstallProxy(%7B%20featureName,%20id%20%7D);%0A%20%20%20%20%20%20%20%20const%20evtName%20=%20appendToken(DidInstall.NAME%20+%20'-'%20+%20id);%0A%20%20%20%20%20%20%20%20const%20didInstall%20=%20(/**%20@type%20%7BCustomEvent%3Cunknown%3E%7D%20*/%20e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20result%20=%20DidInstall.create(e.detail);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(result%20&&%20result.id%20===%20id)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20installed%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20captured.removeEventListener(evtName,%20didInstall);%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20captured.addEventListener(evtName,%20didInstall);%0A%20%20%20%20%20%20%20%20send(evt);%0A%0A%20%20%20%20%20%20%20%20if%20(!installed)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20leaving%20this%20as%20a%20generic%20message%20for%20now%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20captured.Error(ERROR_MSG);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20createMessagingInterface(featureName,%20send,%20appendToken);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20We%20are%20executing%20exclusively%20in%20secure%20contexts,%20so%20this%20should%20never%20fail%0A%20%20%20%20%20*/%0A%20%20%20%20function%20random()%20%7B%0A%20%20%20%20%20%20%20%20if%20(typeof%20captured.randomUUID%20!==%20'function')%20throw%20new%20Error('unreachable');%0A%20%20%20%20%20%20%20%20return%20captured.randomUUID();%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20featureName%0A%20%20%20%20%20*%20@param%20%7B(evt:%20%7Bname:%20string%7D%20&%20Record%3Cstring,%20any%3E)%20=%3E%20void%7D%20send%0A%20%20%20%20%20*%20@param%20%7B(s:%20string)%20=%3E%20string%7D%20appendToken%0A%20%20%20%20%20*%20@returns%20%7BMessagingInterface%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20createMessagingInterface(featureName,%20send,%20appendToken)%20%7B%0A%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20method%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20params%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20notify(method,%20params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20send(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new%20ProxyNotification(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20method,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20method%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20params%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPromise%3Cany%3E%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20request(method,%20params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20id%20=%20random();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20send(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new%20ProxyRequest(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20method,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20Promise((resolve,%20reject)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20responseName%20=%20appendToken(ProxyResponse.NAME%20+%20'-'%20+%20id);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20handler%20=%20(/**%20@type%20%7BCustomEvent%3Cunknown%3E%7D%20*/%20e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20response%20=%20ProxyResponse.create(e.detail);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(response%20&&%20response.id%20===%20id)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('error'%20in%20response%20&&%20response.error)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20reject(new%20Error(response.error.message));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20('result'%20in%20response)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resolve(response.result);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20captured.removeEventListener(responseName,%20handler);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20captured.addEventListener(responseName,%20handler);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20name%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7B(d:%20any)%20=%3E%20void%7D%20callback%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@returns%20%7B()%20=%3E%20void%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20subscribe(name,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20id%20=%20random();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20send(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new%20SubscriptionRequest(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20subscriptionName:%20name,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20handler%20=%20(/**%20@type%20%7BCustomEvent%3Cunknown%3E%7D%20*/%20e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20subscriptionEvent%20=%20SubscriptionResponse.create(e.detail);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(subscriptionEvent)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20id:%20eventId,%20params%20%7D%20=%20subscriptionEvent;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(eventId%20===%20id)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20callback(params);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20type%20=%20appendToken(SubscriptionResponse.NAME%20+%20'-'%20+%20id);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20captured.addEventListener(type,%20handler);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20captured.removeEventListener(type,%20handler);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20evt%20=%20new%20SubscriptionUnsubscribe(%7B%20id%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20send(evt);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20NavigatorInterface%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20load(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error:%20Accessing%20private%20method%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.matchDomainFeatureSetting('privilegedDomains').length)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.injectNavigatorInterface(args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20init(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.injectNavigatorInterface(args);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20injectNavigatorInterface(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(navigator.duckduckgo)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!args.platform%20%7C%7C%20!args.platform.name)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.defineProperty(Navigator.prototype,%20'duckduckgo',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20platform:%20args.platform.name,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20isDuckDuckGo()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGPromise.resolve(true);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@import%20%7B%20MessagingInterface%20%7D%20from%20%22./message-bridge/schema.js%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20featureName%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7BMessagingInterface%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@throws%20%7BError%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20createMessageBridge(featureName)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20createPageWorldBridge(featureName,%20args.messageSecret);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20writable:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20todo:%20Just%20ignore%20this%20exception?%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20let%20adLabelStrings%20=%20%5B%5D;%0A%20%20%20%20const%20parser%20=%20new%20DOMParser();%0A%20%20%20%20let%20hiddenElements%20=%20new%20WeakMap();%0A%20%20%20%20let%20modifiedElements%20=%20new%20WeakMap();%0A%20%20%20%20let%20appliedRules%20=%20new%20Set();%0A%20%20%20%20let%20shouldInjectStyleTag%20=%20false;%0A%20%20%20%20let%20mediaAndFormSelectors%20=%20'video,canvas,embed,object,audio,map,form,input,textarea,select,option,button';%0A%20%20%20%20let%20hideTimeouts%20=%20%5B0,%20100,%20300,%20500,%201000,%202000,%203000%5D;%0A%20%20%20%20let%20unhideTimeouts%20=%20%5B1250,%202250,%203000%5D;%0A%0A%20%20%20%20/**%20@type%20%7BElementHiding%7D%20*/%0A%20%20%20%20let%20featureInstance;%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Hide%20DOM%20element%20if%20rule%20conditions%20met%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20element%0A%20%20%20%20%20*%20@param%20%7BObject%7D%20rule%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20%5BpreviousElement%5D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20collapseDomNode(element,%20rule,%20previousElement)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!element)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20const%20type%20=%20rule.type;%0A%20%20%20%20%20%20%20%20const%20alreadyHidden%20=%20hiddenElements.has(element);%0A%20%20%20%20%20%20%20%20const%20alreadyModified%20=%20modifiedElements.has(element)%20&&%20modifiedElements.get(element)%20===%20rule.type;%0A%20%20%20%20%20%20%20%20//%20return%20if%20the%20element%20has%20already%20been%20hidden,%20or%20modified%20by%20the%20same%20rule%20type%0A%20%20%20%20%20%20%20%20if%20(alreadyHidden%20%7C%7C%20alreadyModified)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20switch%20(type)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20'hide':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hideNode(element);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20'hide-empty':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(isDomNodeEmpty(element))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hideNode(element);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20appliedRules.add(rule);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20'closest-empty':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20hide%20the%20outermost%20empty%20node%20so%20that%20we%20may%20unhide%20if%20ad%20loads%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(isDomNodeEmpty(element))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20collapseDomNode(element.parentNode,%20rule,%20element);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(previousElement)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hideNode(previousElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20appliedRules.add(rule);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20'modify-attr':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20modifyAttribute(element,%20rule.values);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20'modify-style':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20modifyStyle(element,%20rule.values);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Unhide%20previously%20hidden%20DOM%20element%20if%20content%20loaded%20into%20it%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20element%0A%20%20%20%20%20*%20@param%20%7BObject%7D%20rule%0A%20%20%20%20%20*/%0A%20%20%20%20function%20expandNonEmptyDomNode(element,%20rule)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!element)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20const%20type%20=%20rule.type;%0A%0A%20%20%20%20%20%20%20%20const%20alreadyHidden%20=%20hiddenElements.has(element);%0A%0A%20%20%20%20%20%20%20%20switch%20(type)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20'hide':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20only%20care%20about%20rule%20types%20that%20specifically%20apply%20to%20empty%20elements%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20'hide-empty':%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20'closest-empty':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(alreadyHidden%20&&%20!isDomNodeEmpty(element))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unhideNode(element);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(type%20===%20'closest-empty')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20iterate%20upwards%20from%20matching%20DOM%20elements%20until%20we%20arrive%20at%20previously%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20hidden%20element.%20Unhide%20element%20if%20it%20contains%20visible%20content.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20expandNonEmptyDomNode(element.parentNode,%20rule);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Hide%20DOM%20element%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20element%0A%20%20%20%20%20*/%0A%20%20%20%20function%20hideNode(element)%20%7B%0A%20%20%20%20%20%20%20%20//%20maintain%20a%20reference%20to%20each%20hidden%20element%20along%20with%20the%20properties%0A%20%20%20%20%20%20%20%20//%20that%20are%20being%20overwritten%0A%20%20%20%20%20%20%20%20const%20cachedDisplayProperties%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20display:%20element.style.display,%0A%20%20%20%20%20%20%20%20%20%20%20%20'min-height':%20element.style.minHeight,%0A%20%20%20%20%20%20%20%20%20%20%20%20height:%20element.style.height,%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20hiddenElements.set(element,%20cachedDisplayProperties);%0A%0A%20%20%20%20%20%20%20%20//%20apply%20styles%20to%20hide%20element%0A%20%20%20%20%20%20%20%20element.style.setProperty('display',%20'none',%20'important');%0A%20%20%20%20%20%20%20%20element.style.setProperty('min-height',%20'0px',%20'important');%0A%20%20%20%20%20%20%20%20element.style.setProperty('height',%20'0px',%20'important');%0A%20%20%20%20%20%20%20%20element.hidden%20=%20true;%0A%20%20%20%20%20%20%20%20//%20add%20debug%20flag%20to%20site%20breakage%20reports%0A%20%20%20%20%20%20%20%20featureInstance.addDebugFlag();%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Show%20previously%20hidden%20DOM%20element%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20element%0A%20%20%20%20%20*/%0A%20%20%20%20function%20unhideNode(element)%20%7B%0A%20%20%20%20%20%20%20%20const%20cachedDisplayProperties%20=%20hiddenElements.get(element);%0A%20%20%20%20%20%20%20%20if%20(!cachedDisplayProperties)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20for%20(const%20prop%20in%20cachedDisplayProperties)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20element.style.setProperty(prop,%20cachedDisplayProperties%5Bprop%5D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20hiddenElements.delete(element);%0A%20%20%20%20%20%20%20%20element.hidden%20=%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Check%20if%20DOM%20element%20contains%20visible%20content%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20node%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isDomNodeEmpty(node)%20%7B%0A%20%20%20%20%20%20%20%20//%20no%20sense%20wasting%20cycles%20checking%20if%20the%20page's%20body%20element%20is%20empty%0A%20%20%20%20%20%20%20%20if%20(node.tagName%20===%20'BODY')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20//%20use%20a%20DOMParser%20to%20remove%20all%20metadata%20elements%20before%20checking%20if%0A%20%20%20%20%20%20%20%20//%20the%20node%20is%20empty.%0A%20%20%20%20%20%20%20%20const%20parsedNode%20=%20parser.parseFromString(node.outerHTML,%20'text/html').documentElement;%0A%20%20%20%20%20%20%20%20parsedNode.querySelectorAll('base,link,meta,script,style,template,title,desc').forEach((el)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20el.remove();%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20const%20visibleText%20=%20parsedNode.innerText.trim().toLocaleLowerCase().replace(/:$/,%20'');%0A%20%20%20%20%20%20%20%20const%20mediaAndFormContent%20=%20parsedNode.querySelector(mediaAndFormSelectors);%0A%20%20%20%20%20%20%20%20const%20frameElements%20=%20%5B...parsedNode.querySelectorAll('iframe')%5D;%0A%20%20%20%20%20%20%20%20//%20query%20original%20node%20instead%20of%20parsedNode%20for%20img%20elements%20since%20heuristic%20relies%0A%20%20%20%20%20%20%20%20//%20on%20size%20of%20image%20elements%0A%20%20%20%20%20%20%20%20const%20imageElements%20=%20%5B...node.querySelectorAll('img,svg')%5D;%0A%20%20%20%20%20%20%20%20//%20about:blank%20iframes%20don't%20count%20as%20content,%20return%20true%20if:%0A%20%20%20%20%20%20%20%20//%20-%20node%20doesn't%20contain%20any%20iframes%0A%20%20%20%20%20%20%20%20//%20-%20node%20contains%20iframes,%20all%20of%20which%20are%20hidden%20or%20have%20src='about:blank'%0A%20%20%20%20%20%20%20%20const%20noFramesWithContent%20=%20frameElements.every((frame)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20frame.hidden%20%7C%7C%20frame.src%20===%20'about:blank';%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20//%20ad%20containers%20often%20contain%20tracking%20pixels%20and%20other%20small%20images%20(eg%20adchoices%20logo).%0A%20%20%20%20%20%20%20%20//%20these%20should%20be%20treated%20as%20empty%20and%20hidden,%20but%20real%20images%20should%20not.%0A%20%20%20%20%20%20%20%20const%20visibleImages%20=%20imageElements.some((image)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20image.getBoundingClientRect().width%20%3E%2020%20%7C%7C%20image.getBoundingClientRect().height%20%3E%2020;%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20if%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20(visibleText%20===%20''%20%7C%7C%20adLabelStrings.includes(visibleText))%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20mediaAndFormContent%20===%20null%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20noFramesWithContent%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20!visibleImages%0A%20%20%20%20%20%20%20%20)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Modify%20specified%20attribute(s)%20on%20element%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20element%0A%20%20%20%20%20*%20@param%20%7BObject%5B%5D%7D%20values%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20values%5B%5D.property%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20values%5B%5D.value%0A%20%20%20%20%20*/%0A%20%20%20%20function%20modifyAttribute(element,%20values)%20%7B%0A%20%20%20%20%20%20%20%20values.forEach((item)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20element.setAttribute(item.property,%20item.value);%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20modifiedElements.set(element,%20'modify-attr');%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Modify%20specified%20style(s)%20on%20element%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20element%0A%20%20%20%20%20*%20@param%20%7BObject%5B%5D%7D%20values%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20values%5B%5D.property%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20values%5B%5D.value%0A%20%20%20%20%20*/%0A%20%20%20%20function%20modifyStyle(element,%20values)%20%7B%0A%20%20%20%20%20%20%20%20values.forEach((item)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20element.style.setProperty(item.property,%20item.value,%20'important');%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20modifiedElements.set(element,%20'modify-style');%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Separate%20strict%20hide%20rules%20to%20inject%20as%20style%20tag%20if%20enabled%0A%20%20%20%20%20*%20@param%20%7BObject%5B%5D%7D%20rules%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20rules%5B%5D.selector%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20rules%5B%5D.type%0A%20%20%20%20%20*/%0A%20%20%20%20function%20extractTimeoutRules(rules)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!shouldInjectStyleTag)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20rules;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20strictHideRules%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20const%20timeoutRules%20=%20%5B%5D;%0A%0A%20%20%20%20%20%20%20%20rules.forEach((rule)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(rule.type%20===%20'hide')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20strictHideRules.push(rule);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20timeoutRules.push(rule);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20injectStyleTag(strictHideRules);%0A%20%20%20%20%20%20%20%20return%20timeoutRules;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20styletag%20for%20strict%20hide%20rules%20and%20append%20it%20to%20the%20document%0A%20%20%20%20%20*%20@param%20%7BObject%5B%5D%7D%20rules%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20rules%5B%5D.selector%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20rules%5B%5D.type%0A%20%20%20%20%20*/%0A%20%20%20%20function%20injectStyleTag(rules)%20%7B%0A%20%20%20%20%20%20%20%20//%20wrap%20selector%20list%20in%20:is(...)%20to%20make%20it%20a%20forgiving%20selector%20list.%20this%20enables%0A%20%20%20%20%20%20%20%20//%20us%20to%20use%20selectors%20not%20supported%20in%20all%20browsers,%20eg%20:has%20in%20Firefox%0A%20%20%20%20%20%20%20%20let%20selector%20=%20'';%0A%0A%20%20%20%20%20%20%20%20rules.forEach((rule,%20i)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(i%20!==%20rules.length%20-%201)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selector%20=%20selector.concat(rule.selector,%20',');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selector%20=%20selector.concat(rule.selector);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20const%20styleTagProperties%20=%20'display:none!important;min-height:0!important;height:0!important;';%0A%20%20%20%20%20%20%20%20const%20styleTagContents%20=%20%60$%7BforgivingSelector(selector)%7D%20%7B$%7BstyleTagProperties%7D%7D%60;%0A%0A%20%20%20%20%20%20%20%20injectGlobalStyles(styleTagContents);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Apply%20list%20of%20active%20element%20hiding%20rules%20to%20page%0A%20%20%20%20%20*%20@param%20%7BObject%5B%5D%7D%20rules%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20rules%5B%5D.selector%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20rules%5B%5D.type%0A%20%20%20%20%20*/%0A%20%20%20%20function%20hideAdNodes(rules)%20%7B%0A%20%20%20%20%20%20%20%20const%20document%20=%20globalThis.document;%0A%0A%20%20%20%20%20%20%20%20rules.forEach((rule)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20selector%20=%20forgivingSelector(rule.selector);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20matchingElementArray%20=%20%5B...document.querySelectorAll(selector)%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20matchingElementArray.forEach((element)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20collapseDomNode(element,%20rule);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Iterate%20over%20previously%20hidden%20elements,%20unhiding%20if%20content%20has%20loaded%20into%20them%0A%20%20%20%20%20*/%0A%20%20%20%20function%20unhideLoadedAds()%20%7B%0A%20%20%20%20%20%20%20%20const%20document%20=%20globalThis.document;%0A%0A%20%20%20%20%20%20%20%20appliedRules.forEach((rule)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20selector%20=%20forgivingSelector(rule.selector);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20matchingElementArray%20=%20%5B...document.querySelectorAll(selector)%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20matchingElementArray.forEach((element)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20expandNonEmptyDomNode(element,%20rule);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Wrap%20selector(s)%20in%20:is(..)%20to%20make%20them%20forgiving%0A%20%20%20%20%20*/%0A%20%20%20%20function%20forgivingSelector(selector)%20%7B%0A%20%20%20%20%20%20%20%20return%20%60:is($%7Bselector%7D)%60;%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20ElementHiding%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/no-this-alias%0A%20%20%20%20%20%20%20%20%20%20%20%20featureInstance%20=%20this;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(isBeingFramed())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20activeRules;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20globalRules%20=%20this.getFeatureSetting('rules');%0A%20%20%20%20%20%20%20%20%20%20%20%20adLabelStrings%20=%20this.getFeatureSetting('adLabelStrings');%0A%20%20%20%20%20%20%20%20%20%20%20%20shouldInjectStyleTag%20=%20this.getFeatureSetting('useStrictHideStyleTag');%0A%20%20%20%20%20%20%20%20%20%20%20%20hideTimeouts%20=%20this.getFeatureSetting('hideTimeouts')%20%7C%7C%20hideTimeouts;%0A%20%20%20%20%20%20%20%20%20%20%20%20unhideTimeouts%20=%20this.getFeatureSetting('unhideTimeouts')%20%7C%7C%20unhideTimeouts;%0A%20%20%20%20%20%20%20%20%20%20%20%20mediaAndFormSelectors%20=%20this.getFeatureSetting('mediaAndFormSelectors')%20%7C%7C%20mediaAndFormSelectors;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20determine%20whether%20strict%20hide%20rules%20should%20be%20injected%20as%20a%20style%20tag%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(shouldInjectStyleTag)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error:%20Accessing%20private%20method%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20shouldInjectStyleTag%20=%20this.matchDomainFeatureSetting('styleTagExceptions').length%20===%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20collect%20all%20matching%20rules%20for%20domain%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error:%20Accessing%20private%20method%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20activeDomainRules%20=%20this.matchDomainFeatureSetting('domains').flatMap((item)%20=%3E%20item.rules);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20overrideRules%20=%20activeDomainRules.filter((rule)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20rule.type%20===%20'override';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20disableDefault%20=%20activeDomainRules.some((rule)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20rule.type%20===%20'disable-default';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20if%20rule%20with%20type%20'disable-default'%20is%20present,%20ignore%20all%20global%20rules%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(disableDefault)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20activeRules%20=%20activeDomainRules.filter((rule)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20rule.type%20!==%20'disable-default';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20activeRules%20=%20activeDomainRules.concat(globalRules);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20remove%20overrides%20and%20rules%20that%20match%20overrides%20from%20array%20of%20rules%20to%20be%20applied%20to%20page%0A%20%20%20%20%20%20%20%20%20%20%20%20overrideRules.forEach((override)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20activeRules%20=%20activeRules.filter((rule)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20rule.selector%20!==%20override.selector;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20applyRules%20=%20this.applyRules.bind(this);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20now%20have%20the%20final%20list%20of%20rules%20to%20apply,%20so%20we%20apply%20them%20when%20document%20is%20loaded%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(document.readyState%20===%20'loading')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20window.addEventListener('DOMContentLoaded',%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20applyRules(activeRules);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20applyRules(activeRules);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20single%20page%20applications%20don't%20have%20a%20DOMContentLoaded%20event%20on%20navigations,%20so%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20we%20use%20proxy/reflect%20on%20history.pushState%20to%20call%20applyRules%20on%20page%20navigations%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20historyMethodProxy%20=%20new%20DDGProxy(this,%20History.prototype,%20'pushState',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20applyRules(activeRules);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20historyMethodProxy.overload();%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20listen%20for%20popstate%20events%20in%20order%20to%20run%20on%20back/forward%20navigations%0A%20%20%20%20%20%20%20%20%20%20%20%20window.addEventListener('popstate',%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20applyRules(activeRules);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Apply%20relevant%20hiding%20rules%20to%20page%20at%20set%20intervals%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BObject%5B%5D%7D%20rules%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20rules%5B%5D.selector%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20rules%5B%5D.type%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20applyRules(rules)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20timeoutRules%20=%20extractTimeoutRules(rules);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20clearCacheTimer%20=%20unhideTimeouts.concat(hideTimeouts).reduce((a,%20b)%20=%3E%20Math.max(a,%20b),%200)%20+%20100;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20several%20passes%20are%20made%20to%20hide%20&%20unhide%20elements.%20this%20is%20necessary%20because%20we're%20not%20using%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20a%20mutation%20observer%20but%20we%20want%20to%20hide/unhide%20elements%20as%20soon%20as%20possible,%20and%20ads%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20frequently%20take%20from%20several%20hundred%20milliseconds%20to%20several%20seconds%20to%20load%0A%20%20%20%20%20%20%20%20%20%20%20%20hideTimeouts.forEach((timeout)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20setTimeout(()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hideAdNodes(timeoutRules);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%20timeout);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20check%20previously%20hidden%20ad%20elements%20for%20contents,%20unhide%20if%20content%20has%20loaded%20after%20hiding.%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20we%20do%20this%20in%20order%20to%20display%20non-tracking%20ads%20that%20aren't%20blocked%20at%20the%20request%20level%0A%20%20%20%20%20%20%20%20%20%20%20%20unhideTimeouts.forEach((timeout)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20setTimeout(()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unhideLoadedAds();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%20timeout);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20clear%20appliedRules%20and%20hiddenElements%20caches%20once%20all%20checks%20have%20run%0A%20%20%20%20%20%20%20%20%20%20%20%20setTimeout(()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20appliedRules%20=%20new%20Set();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hiddenElements%20=%20new%20WeakMap();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20modifiedElements%20=%20new%20WeakMap();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%20clearCacheTimer);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20ExceptionHandler%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Report%20to%20the%20debugger%20panel%20if%20an%20uncaught%20exception%20occurs%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20handleUncaughtException%20=%20(e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20postDebugMessage(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'jsException',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20documentUrl:%20document.location.href,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20message:%20e.message,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20filename:%20e.filename,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lineno:%20e.lineno,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20colno:%20e.colno,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20stack:%20e.error?.stack,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.addDebugFlag();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20globalThis.addEventListener('error',%20handleUncaughtException);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20This%20feature%20allows%20remote%20configuration%20of%20APIs%20that%20exist%20within%20the%20DOM.%0A%20%20%20%20%20*%20We%20support%20removal%20of%20APIs%20and%20returning%20different%20values%20from%20getters.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@module%20API%20manipulation%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@internal%0A%20%20%20%20%20*/%0A%20%20%20%20class%20ApiManipulation%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20apiChanges%20=%20this.getFeatureSetting('apiChanges');%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(apiChanges)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20scope%20in%20apiChanges)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20change%20=%20apiChanges%5Bscope%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this.checkIsValidAPIChange(change))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.applyApiChange(scope,%20change);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Checks%20if%20the%20config%20API%20change%20is%20valid.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bany%7D%20change%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bchange%20is%20APIChange%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20checkIsValidAPIChange(change)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20change%20!==%20'object')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(change.type%20===%20'remove')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(change.type%20===%20'descriptor')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(change.enumerable%20&&%20typeof%20change.enumerable%20!==%20'boolean')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(change.configurable%20&&%20typeof%20change.configurable%20!==%20'boolean')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20typeof%20change.getterValue%20!==%20'undefined';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20TODO%20move%20this%20to%20schema%20definition%20imported%20from%20the%20privacy-config%0A%20%20%20%20%20%20%20%20//%20Additionally%20remove%20checkIsValidAPIChange%20when%20this%20change%20happens.%0A%20%20%20%20%20%20%20%20//%20See:%20https://app.asana.com/0/1201614831475344/1208715421518231/f%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@typedef%20%7BObject%7D%20APIChange%0A%20%20%20%20%20%20%20%20%20*%20@property%20%7B%22remove%22%7C%22descriptor%22%7D%20type%0A%20%20%20%20%20%20%20%20%20*%20@property%20%7Bimport('../utils.js').ConfigSetting%7D%20%5BgetterValue%5D%20-%20The%20value%20returned%20from%20a%20getter.%0A%20%20%20%20%20%20%20%20%20*%20@property%20%7Bboolean%7D%20%5Benumerable%5D%20-%20Whether%20the%20property%20is%20enumerable.%0A%20%20%20%20%20%20%20%20%20*%20@property%20%7Bboolean%7D%20%5Bconfigurable%5D%20-%20Whether%20the%20property%20is%20configurable.%0A%20%20%20%20%20%20%20%20%20*/%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Applies%20a%20change%20to%20DOM%20APIs.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20scope%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BAPIChange%7D%20change%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bvoid%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20applyApiChange(scope,%20change)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20response%20=%20this.getGlobalObject(scope);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!response)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%5Bobj,%20key%5D%20=%20response;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(change.type%20===%20'remove')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.removeApiMethod(obj,%20key);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(change.type%20===%20'descriptor')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.wrapApiDescriptor(obj,%20key,%20change);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Removes%20a%20method%20from%20an%20API.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20api%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20key%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20removeApiMethod(api,%20key)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(hasOwnProperty.call(api,%20key))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20api%5Bkey%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Wraps%20a%20property%20with%20descriptor.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20api%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20key%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BAPIChange%7D%20change%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20wrapApiDescriptor(api,%20key,%20change)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20getterValue%20=%20change.getterValue;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(getterValue)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20descriptor%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20processAttr(getterValue,%20undefined),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('enumerable'%20in%20change)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20descriptor.enumerable%20=%20change.enumerable;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('configurable'%20in%20change)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20descriptor.configurable%20=%20change.configurable;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(api,%20key,%20descriptor);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Looks%20up%20a%20global%20object%20from%20a%20scope,%20e.g.%20'Navigator.prototype'.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20scope%20the%20scope%20of%20the%20object%20to%20get%20to.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7B%5Bobject,%20string%5D%7Cnull%7D%20the%20object%20at%20the%20scope.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20getGlobalObject(scope)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20parts%20=%20scope.split('.');%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20get%20the%20last%20part%20of%20the%20scope%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20lastPart%20=%20parts.pop();%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!lastPart)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20obj%20=%20window;%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20part%20of%20parts)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20obj%20=%20obj%5Bpart%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!obj)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%5Bobj,%20lastPart%5D;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20const%20logoImg%20=%0A%20%20%20%20%20%20%20%20'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAABUCAYAAAAcaxDBAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAABNTSURBVHgBzV0LcFPXmf6PJFt+gkEY8wrYMSEbgst7m02ywZnOZiEJCQlJC+QB25lNs7OzlEJ2ptmZLGayfUy3EEhmW5rM7gCZBtjJgzxmSTvTRSST9IF5pCE0TUosmmBjHIKNZFmWLN2e78hHPvfqXuleSdfONyNLV7q6uve7//uc85vRlwAda25oTFK8lZGn0UPaLI2okUhrTH/KGnU7M+olTevlL0KaeM3e01LaKa/PE2p64dgpGmMwGgN0rGqtS1Ve2cB/fhk/gVbSqI5KAU4wvxlBTdNe9VJ5sOnAb0I0yhg1QiWJTGN3E0gcHQRTpO0dTXJdJ7RjzZJWflHrGaNVdiTRN2kalTfOIU9VLfnqp5ruM9TTxR+dlIqGKX7uI7IDLrl7PFS2zW1iXSMURGqkbaUc0uiprqWqxa1UOXcxVcxdxAmcRoUApMZDH9HAmeMU+8NxQbYV3Ca25ITCwaRY4immcYk0AUgcv3wtJ3CxeLgBEBw++jpF249akusWsSUltGPNoq0aY5vMVLviusU04b5HbJMoVLo/ItRaBUyBp7rGtjTHuNSGj75BkbdeN/2ckdbWdODENioRSkIopFLThl4hpi0wflZzy0pO5D9aEiDsIFfXQagtf4CAXCqronzWHHFc3CQ/f53rZuGYl198zorYEKOyW0shrUUT2rFu8bc1jdqMUplLIkFi9NhRCvOLA4mp/jCVAjAn+N2qJa1UvXSZkGYjQOylfTu4OQjqPxAhl7atef+JnVQEiiK0Y+2ipzSNq7gCXFT9o1vFRRkB6evnFxJ5642SkWgF4fD4OUxYba4dEW4GLr/0bJY2FGsCCiIUMaVWEX6FDB4cF1D/T1uzJANE4uTxPBaoWbbSlNgcZiDIYsl7mg6d6iWHcEyolb0MPLyFxq1Yq9sXqg31ihx9nb4MsCK298VnxQ3XQaNTjJXd49SuOiJUkEmJIyRy7TSgWg2bf5xlK/sO76defpJuq7ZTgMy61Y9Q7bI7de/Dlndvf8xoAhw7K9uECjX3R46okomTm/rEbt0dh1TixIzqDeI9lSPZD/ZDWDT0uT2PXmqYSSvI7HryUT2pkNTB5K121d82oZ+sWQzJbJXbZmRa3GWBces2UuXX7qOKigryeDy6z0A+wqbosaDIdEYLZtdgSiq3qVcfOH6rnWPaIlQE7MTacp1ImHvuL/Ztz63iE+qpZtN2qp8z13IX6Siix4OjYi7gQCdy+6+aADNSecKys3l/+3fyHc+bb4d0nMl+KLfNyIS9vPTfPyAtEbc8jvjevz5F45r/inIBpqF6aSvV/M1twiTYLX4UCpwzYlIRw17TMnIOS5aJ8E5eE5e8Gza2TO17+nTXb3IdLyehaSeUOsBfVsj3pv77z6hsWmNmH5AJycwFQeb3nqfBqvHU399P4XBYPMfjcWK8DOXz+bK+I4mFCo2GGRh479dZpFbMbhGkSvBzvWHTvFkHd53+zNKe5lR5bjc7SPHoE7h3rOPZjwTU/POftlE+4ORS5ZVEly+OvDm1UTw0bldRsmtoaCC/32/6/SvQgDw3rVSY9GibTv2zfps7qasPHl9o9X1LCYXd5HxnKkbIyQPrt2Q+h325uOOxnGqeOQfsE+vXvxnhN7krROzd/6PUlJkU9nOJrK4mrzf7lPxcaiCt0IxE57msgkkpAQdZNf9G8tYFMr8Ns5PoDKV3YDRl47zp7OnTnUGz75tK6HC82SG3jXbTwhM6Q0U1sZvvFERVz77e1PtbwSptLBVwndN/+PNMxocb+OnGu0acJM/7mVa20Cw+Nb2CFCW2qtsIhFUndPml5wq/mAmTiT2yjep2HKKZ/7CF6r+ylKqqqmyTCdRwlcQNRmXfDeDaEP5JgFjUJzLghSDUfM2+m3UVkE4uthvkNvJz1aZAOgpNJbWv3U/jnnyeZi5bQRMmTHBEohFprfmZa6RC9eFwJcCDmg2igI5RCeP3sq7IKJ2BhzdnXosY0Zjz2gHUm0vltAe/TYFAoCgiVUByQGqhQyf5gBxftddwyiqGh3j056RuGKUTjqhoVR8mc8bf/r2wk6VGmtTdIpIoNWRxRwISCk4UtBqlVEeoUTpRaZcAkYWoOtQ8MG+xaaxZKuCmj1u+ltwArlmtS6icABjRVbczhNqRTqfQFvGM57avU21t6aXnvTOd9PKb79O+l9rpnfYOGn/7WlekFFDNnBxykcDweMeqBZnRigyhmAqjHsSY2xbkiLh0Tpw4MbMZiQ5yAo7T1h2/oG89/iL9aHeQLvQ4jynfaQ8JEqsry6lhUi2dPXeJdr/4vmtSCgnVSalqS+HxK30b5GZGD73E1mvyTcNdKEg6m3hsOeWqjKqDuMf+43VOQA09vHoJNTcGqKbKL0h2ipuWNIqHEaloC115c78rRRUM3UhO8Cyyv+HfYZqG2TBiLEpIaDqQHynNVfHCwMhJhrMHtOzguqUi85GAet52y7W0/Ym7aP7caYJMQD6XAnBQmDjhBhAuqh7foA2tUu0FoVnqrngyjE4WdMeb5upy83uXt3DJdGdigwpjJb5UAJn9nAuJSsMIhVR7QejwBC4BqLsaLPcXIp0Az7vLy8szm1Pq3XEYRoh5US45J3UwT6q9BFf7VjynCfWMqDvGtVUUVDrjhWRx8BIF8FaQTk46OGxD7TEBwg1gQoaq9jrzwkjYSU/H/UsXqJMUVGcEz1aIumt1k/OSibDnP3cfoZ/se7cgTw/8ZN+vRdjUzb+/ekUL/fJouhjtFqFylouETu05h/BFnqQv1ah+ya+czKBL1XKQsIV7/F+89VFGygrx9t09V8RzJBrnEnpEhFOAf9a15BZUTjBjUEWSkq0ebj914+uq/SxmYkIqlbL87J3joczrmqp0Ovpue4icAtGCBGJRue1WwQRQJdRYQ2CkNfpI0+bLqqhRVYod4gWpZqof6R8pSr/85u/F880mcWU+IJ6Fs4NkNs8KZKIIT1UNuQWjTwGpsr6B9QE+D6M6GdAbp9Cod8MJWO9FzL+0JHT1innC/kmAlBsLIBRAbIuHCjte3sMVo2o2FyLuP+N8ZCbyAdmCsTgEIZTv8ZHhRp8mVlukRdQ4Pl0wBqLiCYNwZkWRe5d/RQT0cEwNnMx7V7RQKWE26068P0xi7fXc/l2l/8wuoQC4kVzpfwsqz1gdDYuoOqc9FY1QwcD4USxKiUTCchczySoVZGjjG8clqIGTN4M7qsnZJErEPiVHwPA2pSPDrHUAPquFBEXnw5zUoaEhKhpJfh69PEMZ5BoT78q/L394+H6z/oVLj42sNsWDi543yRFyDBI2ulek5KOEA5OnU8EY4Pb7Uz58Gy4s0rBLZtdBrsJ9VDK4R+jlnsIl9NIbRKE2chNQc0hmKckE3CP0Qkh4eTgmNafPi3ina2RCIsOnecHnT87tpl1wQrVQ1npKoqILDKzjA+HrBgYGnBHamb/2CmLiF7Pf940f/jyW3gfSl+DJ1BB/xP6cfi4FrKIIjNfrJBQr1Ea+VGRwzFUenn5w0OFxon/M+XHPYWchjhvAsh4JlTMuQb08rmchua16r5IMzXZ1UCwWc/adpHW4BiLHmkxAF6/rskkW8nC1PCc3jVMHiya185xwTI6cU611ETrp8N64AWN6rg+htD5O6IiEGrMjY23UMTrOiCfYUdsIWFfcx/PTKZ9MYwqjkKnpOefyFCc0FVJ3UEkttmoDxyR+NJ5/hl4GkNDASsuPpz/Mk5QVY0esWi82ajQv3Z3yeSkV1JRZjQNnTvBxmfRd8BdbqEUKygP8ft9sMQXHNq7azE+EO6eoeXGm5vr0A148zn3f4MW0V0+ZlFSRfiLILxufjgJkwA+v7zRDAlROsopHzBPyNR04Ffpk7eJemYKiBioHuuT4TFFpKFf7IT6+ZFV5MoWXhyXXvcBvxrPcsVnPpfINk4SCh2MUsOQN4ZIqoQNqKY+HTGjRIa5QS1FQvq8OGZdkfIYH+ACmgDvGtEeIWl7LaQIKQR/n4dIRcgzjWixdAV4jMSSaFhkPy4yPwmupO9beUtzFsDPHxLMjO6qinJufxq1pYhvbKOUp7AbDHIBI5O5fHEkH/06hrl+F/VT9Da/WH8KzCOw9/qE9WsybmUCKzgjyblRhVe/zRag97GhvD7ejPmd21AhO7BAfVTn/X9sxeCMKw3BM/vqRDEkFCEOWBBuLrMoss3ICaCtWOEuEs6YmpYL4Kwht2nOqt2PN4qCcPYKJ+hOGFyfgQDW33CneKxgfHKOhm253ZkdNgAmw8sYiF3crHzcDpFNNOdEtYgQsCF+EV5mrSzH2aua1Qe2rTZZqO0IxdlSBKOyOEdRpjMYmCYxSe+XrDKFQe9FkahjqFL5i+4MUbUfHGMapnWFl7VIaaXUHMoRC7bmnykip8S4Yp0M7grSjRUqom8PDuZBr4jGPvvZIdQd0Bo0XSvao2+o0RpPp0M4AO+o0rzfAqo+TEVE/o8MLy+hHd1fQQHlxXUDyTzxO6ro/6AhtOtAe5D8flNvG6dCB9ZsLr5MO5/XFSGmlDbMTvN5H2+73c0J99FmAie1CASKdSCdg4nKZjnHVlsLLFar6Mq93XM5TYMxUVFyqZfTMCj+9/NUynVT+9pq864MtYVyfpS5gSCOZ1Zsk69d2ne4MbWqZhuk5YtkwCqh+brvkglks1Ut378ozAmnEUEJMwk1yUurq9AOtF/o76YVP/ofe7v5/ev/ySUqk+LCJ10/Vvuzi9Nnuk/Re8iy9P8tLA34PNfSlhBTubS2n7rps+QC5X/04RZVxjZwg3R5pRHgw4bbvtT2Z7bR0ntxr/J7F0sQFjRrznpT5PSTjqmde0y3VO//dBxxPhtBu30DE49GpU6dSZWVl5v21h2+niC87cbi69hq6a+b91DJxIb392a/of//8PEWTepMBovq9Gnm81vHtA28nOKn2bbedpZiMkk1GdQdMzwI7ahrbJbdBYM9PR6QbxDZs+bFzezpsR41qf2HA/MZ8Ev6Ydn7wfXrglytp95mdWWQCkMBYbIA0zVoCv6ix75hwTcZ+AMb1Wbzuuc2MTPF9skDzgfY2fhsyDU5RNFGX6qFoEnhoMzmBtKNqwRnqXiwY81Aibj1LxQmhgYe2GMh81rgCJiS4sUDOPJBpyXvUYB+NBlSvj0YoaC9kG4hHOamQUDndcUr1NF7tym/ftBzTI7EkPJkjHBuwOeiKa6lR5uijAILliRlgFTIlc/YeyUmoUP2UpvNkxiYt6NXkiNTO9BCWGj5VeXOPjKLrg1bE53ZiUWPfKeOKZCCXqkvkrVQ0HzyxU2Oks6dGA40TwfJnOzaV/SGdhqpqP6V6ak4bCAlM8LTVah9I+1AiwR/mUjoxYn3sdGu5tiwys5q4cDKb97fn7Ytnq/TTvP/4JjXgN/tBqP/0H/w8/0hpV0iM10ej0cxbC+qXWpIhfo+rM8iMRvqFrcQjPhinAX6MSDhMc88O0sLzTLy+0ttHUS79g7FBcUyQXTFobi7kEvGaPB1xUE3KZTdV2I56Ny1peJWSnuX85RRspxeEHRXdY6Rkym4yObvZIB6dM5+0unqxOrmsrIy+iH1O73QeobLyMt2uIDHGJXmiN0Dfv/lp6rzyKSUScQqU1dOc2rnU0j+RVh3ppjs/9tEN5710z4c+uraH0cRwWmL7tDhFEjF6sJ1R3aBe7TGii4Y0+RthsVNscGjFrg8v2MpIHLZq4/EpeXWt2nBCaNVmLFzkamOh3XgH0R3rafz48aLoHEmE6Y5DN9G4upFKMSQQZK6evY6+Oe+fqaYs25zgpp3/7jpyAtx0ZHvGPn1wtt07HjMW0kNwQvnspgpHedmu0xd6N83jkso8raRIavhXL4lbo+baINhKWhk88l//HSWTSUEqsqKTF39H3dEu7q2TQpUDvkn0vZt20arZ3xCfm558XcBR1obsZ8rjT5v26et55t/0DWkgmSy5wgmZ4tqoAHRsWFBHMe8rmqHdpZO2ktoTe7jeVdGMGTPEZLKPL39IG498U5zQfXMepK9f+5CpVBoByep68ls597FqDisTluy1rCzIYkOj0+5Sxdk1S9qYoU2EVfdDQG3Dlly2WqSh6D2CBwDVt0OiEecfX5c1Rg7VxtBNtaFXiARI7Nm9LWusjJvtXc0Hj2+iAlF0y+Cz31i0iXnYVuPUcozBoF+JmdcXDu2zEEXG1YsYEk2wioHsbgYSy2fO4TdzZXpw0WTaoWVzWNEy2F5olAslamqd7awkrMxAKSGXDMp/KGCGdAOa58wbKQh7yVXcob00Q0kIlTAzARIgtparoFu9662Qs10xpJIXgezGmHZQUkKBYWlt4y/Xm30OSUWDA0ygcLPnEqbJXDls3d2BW5pDpCW/Uwqp1B2XXEI+YgHZigNeGJOwCiUY6hw7c0KQCGeTe1IGwzDPNgz3kAtwjVAJO8SqQFkQzgVk+yZZ/HOVz7sEacbpMJYQveq4RBLb6xaRIz81SgCxSfK0esmzXqN09wP3waWRpV6lgdSeQmLKgn6RxgAZcpnnbkFuCf9BFR8KD3K/f3Q0SdSfwpcAHevQVSLVmNLYAg+j+SBYLOrlNQ0TskP4k15swUIp0s5hFvZY/YcvI/4CeAZjCToTSnsAAAAASUVORK5CYII=';%0A%20%20%20%20const%20loadingImages%20=%20%7B%0A%20%20%20%20%20%20%20%20darkMode:%0A%20%20%20%20%20%20%20%20%20%20%20%20'data:image/svg+xml;utf8,%253Csvg%2520width%253D%252220%2522%2520height%253D%252220%2522%2520viewBox%253D%25220%25200%252020%252020%2522%2520fill%253D%2522none%2522%2520xmlns%253D%2522http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg%2522%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Cstyle%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2540keyframes%2520rotate%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520from%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520transform%253A%2520rotate%25280deg%2529%253B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%257D%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520to%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520transform%253A%2520rotate%2528359deg%2529%253B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%257D%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%257D%250A%2520%2520%2520%2520%2520%2520%2520%2520%253C%252Fstyle%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Cg%2520style%253D%2522transform-origin%253A%252050%2525%252050%2525%253B%2520animation%253A%2520rotate%25201s%2520infinite%2520reverse%2520linear%253B%2522%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%252218.0968%2522%2520y%253D%252216.0861%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%2528136.161%252018.0968%252016.0861%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.1%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25228.49878%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.4%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%252219.9976%2522%2520y%253D%25228.37451%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%252890%252019.9976%25208.37451%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.2%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%252216.1727%2522%2520y%253D%25221.9917%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%252846.1607%252016.1727%25201.9917%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.3%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25228.91309%2522%2520y%253D%25226.88501%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%2528136.161%25208.91309%25206.88501%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.6%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25226.79602%2522%2520y%253D%252210.996%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%252846.1607%25206.79602%252010.996%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.7%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25227%2522%2520y%253D%25228.62549%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%252890%25207%25208.62549%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.8%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25228.49878%2522%2520y%253D%252213%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.9%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%253C%252Fg%253E%250A%2520%2520%2520%2520%253C%252Fsvg%253E',%0A%20%20%20%20%20%20%20%20lightMode:%0A%20%20%20%20%20%20%20%20%20%20%20%20'data:image/svg+xml;utf8,%253Csvg%2520width%253D%252220%2522%2520height%253D%252220%2522%2520viewBox%253D%25220%25200%252020%252020%2522%2520fill%253D%2522none%2522%2520xmlns%253D%2522http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg%2522%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Cstyle%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2540keyframes%2520rotate%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520from%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520transform%253A%2520rotate%25280deg%2529%253B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%257D%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520to%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520transform%253A%2520rotate%2528359deg%2529%253B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%257D%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%257D%250A%2520%2520%2520%2520%2520%2520%2520%2520%253C%252Fstyle%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Cg%2520style%253D%2522transform-origin%253A%252050%2525%252050%2525%253B%2520animation%253A%2520rotate%25201s%2520infinite%2520reverse%2520linear%253B%2522%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%252218.0968%2522%2520y%253D%252216.0861%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%2528136.161%252018.0968%252016.0861%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.1%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25228.49878%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.4%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%252219.9976%2522%2520y%253D%25228.37451%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%252890%252019.9976%25208.37451%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.2%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%252216.1727%2522%2520y%253D%25221.9917%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%252846.1607%252016.1727%25201.9917%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.3%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25228.91309%2522%2520y%253D%25226.88501%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%2528136.161%25208.91309%25206.88501%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.6%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25226.79602%2522%2520y%253D%252210.996%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%252846.1607%25206.79602%252010.996%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.7%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25227%2522%2520y%253D%25228.62549%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%252890%25207%25208.62549%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.8%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25228.49878%2522%2520y%253D%252213%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.9%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%253C%252Fg%253E%250A%2520%2520%2520%2520%253C%252Fsvg%253E',%20//%20'data:application/octet-stream;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KCTxzdHlsZT4KCQlAa2V5ZnJhbWVzIHJvdGF0ZSB7CgkJCWZyb20gewoJCQkJdHJhbnNmb3JtOiByb3RhdGUoMGRlZyk7CgkJCX0KCQkJdG8gewoJCQkJdHJhbnNmb3JtOiByb3RhdGUoMzU5ZGVnKTsKCQkJfQoJCX0KCTwvc3R5bGU+Cgk8ZyBzdHlsZT0idHJhbnNmb3JtLW9yaWdpbjogNTAlIDUwJTsgYW5pbWF0aW9uOiByb3RhdGUgMXMgaW5maW5pdGUgcmV2ZXJzZSBsaW5lYXI7Ij4KCQk8cmVjdCB4PSIxOC4wOTY4IiB5PSIxNi4wODYxIiB3aWR0aD0iMyIgaGVpZ2h0PSI3IiByeD0iMS41IiB0cmFuc2Zvcm09InJvdGF0ZSgxMzYuMTYxIDE4LjA5NjggMTYuMDg2MSkiIGZpbGw9IiNmZmZmZmYiIGZpbGwtb3BhY2l0eT0iMC4xIi8+CQoJCTxyZWN0IHg9IjguNDk4NzgiIHdpZHRoPSIzIiBoZWlnaHQ9IjciIHJ4PSIxLjUiIGZpbGw9IiNmZmZmZmYiIGZpbGwtb3BhY2l0eT0iMC40Ii8+CgkJPHJlY3QgeD0iMTkuOTk3NiIgeT0iOC4zNzQ1MSIgd2lkdGg9IjMiIGhlaWdodD0iNyIgcng9IjEuNSIgdHJhbnNmb3JtPSJyb3RhdGUoOTAgMTkuOTk3NiA4LjM3NDUxKSIgZmlsbD0iI2ZmZmZmZiIgZmlsbC1vcGFjaXR5PSIwLjIiLz4KCQk8cmVjdCB4PSIxNi4xNzI3IiB5PSIxLjk5MTciIHdpZHRoPSIzIiBoZWlnaHQ9IjciIHJ4PSIxLjUiIHRyYW5zZm9ybT0icm90YXRlKDQ2LjE2MDcgMTYuMTcyNyAxLjk5MTcpIiBmaWxsPSIjZmZmZmZmIiBmaWxsLW9wYWNpdHk9IjAuMyIvPgoJCTxyZWN0IHg9IjguOTEzMDkiIHk9IjYuODg1MDEiIHdpZHRoPSIzIiBoZWlnaHQ9IjciIHJ4PSIxLjUiIHRyYW5zZm9ybT0icm90YXRlKDEzNi4xNjEgOC45MTMwOSA2Ljg4NTAxKSIgZmlsbD0iI2ZmZmZmZiIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KCQk8cmVjdCB4PSI2Ljc5NjAyIiB5PSIxMC45OTYiIHdpZHRoPSIzIiBoZWlnaHQ9IjciIHJ4PSIxLjUiIHRyYW5zZm9ybT0icm90YXRlKDQ2LjE2MDcgNi43OTYwMiAxMC45OTYpIiBmaWxsPSIjZmZmZmZmIiBmaWxsLW9wYWNpdHk9IjAuNyIvPgoJCTxyZWN0IHg9IjciIHk9IjguNjI1NDkiIHdpZHRoPSIzIiBoZWlnaHQ9IjciIHJ4PSIxLjUiIHRyYW5zZm9ybT0icm90YXRlKDkwIDcgOC42MjU0OSkiIGZpbGw9IiNmZmZmZmYiIGZpbGwtb3BhY2l0eT0iMC44Ii8+CQkKCQk8cmVjdCB4PSI4LjQ5ODc4IiB5PSIxMyIgd2lkdGg9IjMiIGhlaWdodD0iNyIgcng9IjEuNSIgZmlsbD0iI2ZmZmZmZiIgZmlsbC1vcGFjaXR5PSIwLjkiLz4KCTwvZz4KPC9zdmc+Cg=='%0A%20%20%20%20%7D;%0A%20%20%20%20const%20closeIcon%20=%0A%20%20%20%20%20%20%20%20'data:image/svg+xml;utf8,%253Csvg%2520width%253D%252212%2522%2520height%253D%252212%2522%2520viewBox%253D%25220%25200%252012%252012%2522%2520fill%253D%2522none%2522%2520xmlns%253D%2522http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg%2522%253E%250A%253Cpath%2520fill-rule%253D%2522evenodd%2522%2520clip-rule%253D%2522evenodd%2522%2520d%253D%2522M5.99998%25204.58578L10.2426%25200.34314C10.6331%2520-0.0473839%252011.2663%2520-0.0473839%252011.6568%25200.34314C12.0474%25200.733665%252012.0474%25201.36683%252011.6568%25201.75735L7.41419%25205.99999L11.6568%252010.2426C12.0474%252010.6332%252012.0474%252011.2663%252011.6568%252011.6568C11.2663%252012.0474%252010.6331%252012.0474%252010.2426%252011.6568L5.99998%25207.41421L1.75734%252011.6568C1.36681%252012.0474%25200.733649%252012.0474%25200.343125%252011.6568C-0.0473991%252011.2663%2520-0.0473991%252010.6332%25200.343125%252010.2426L4.58577%25205.99999L0.343125%25201.75735C-0.0473991%25201.36683%2520-0.0473991%25200.733665%25200.343125%25200.34314C0.733649%2520-0.0473839%25201.36681%2520-0.0473839%25201.75734%25200.34314L5.99998%25204.58578Z%2522%2520fill%253D%2522%2523222222%2522%252F%253E%250A%253C%252Fsvg%253E';%0A%0A%20%20%20%20const%20blockedFBLogo%20=%0A%20%20%20%20%20%20%20%20'data:image/svg+xml;utf8,%253Csvg%2520width%253D%252280%2522%2520height%253D%252280%2522%2520viewBox%253D%25220%25200%252080%252080%2522%2520fill%253D%2522none%2522%2520xmlns%253D%2522http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg%2522%253E%250A%253Ccircle%2520cx%253D%252240%2522%2520cy%253D%252240%2522%2520r%253D%252240%2522%2520fill%253D%2522white%2522%252F%253E%250A%253Cg%2520clip-path%253D%2522url%2528%2523clip0%2529%2522%253E%250A%253Cpath%2520d%253D%2522M73.8457%252039.974C73.8457%252021.284%252058.7158%25206.15405%252040.0258%25206.15405C21.3358%25206.15405%25206.15344%252021.284%25206.15344%252039.974C6.15344%252056.884%252018.5611%252070.8622%252034.7381%252073.4275V49.764H26.0999V39.974H34.7381V32.5399C34.7381%252024.0587%252039.764%252019.347%252047.5122%252019.347C51.2293%252019.347%252055.0511%252020.0799%252055.0511%252020.0799V28.3517H50.8105C46.6222%252028.3517%252045.2611%252030.9693%252045.2611%252033.6393V39.974H54.6846L53.1664%252049.764H45.2611V73.4275C61.4381%252070.9146%252073.8457%252056.884%252073.8457%252039.974Z%2522%2520fill%253D%2522%25231877F2%2522%252F%253E%250A%253C%252Fg%253E%250A%253Crect%2520x%253D%25223.01295%2522%2520y%253D%252211.7158%2522%2520width%253D%252212.3077%2522%2520height%253D%252292.3077%2522%2520rx%253D%25226.15385%2522%2520transform%253D%2522rotate%2528-45%25203.01295%252011.7158%2529%2522%2520fill%253D%2522%2523666666%2522%2520stroke%253D%2522white%2522%2520stroke-width%253D%25226.15385%2522%252F%253E%250A%253Cdefs%253E%250A%253CclipPath%2520id%253D%2522clip0%2522%253E%250A%253Crect%2520width%253D%252267.6923%2522%2520height%253D%252267.6923%2522%2520fill%253D%2522white%2522%2520transform%253D%2522translate%25286.15344%25206.15405%2529%2522%252F%253E%250A%253C%252FclipPath%253E%250A%253C%252Fdefs%253E%250A%253C%252Fsvg%253E';%0A%20%20%20%20const%20facebookLogo%20=%0A%20%20%20%20%20%20%20%20'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMSAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTguODUgMTkuOUM0LjEgMTkuMDUgMC41IDE0Ljk1IDAuNSAxMEMwLjUgNC41IDUgMCAxMC41IDBDMTYgMCAyMC41IDQuNSAyMC41IDEwQzIwLjUgMTQuOTUgMTYuOSAxOS4wNSAxMi4xNSAxOS45TDExLjYgMTkuNDVIOS40TDguODUgMTkuOVoiIGZpbGw9IiMxODc3RjIiLz4KPHBhdGggZD0iTTE0LjQgMTIuOEwxNC44NSAxMEgxMi4yVjguMDVDMTIuMiA3LjI1IDEyLjUgNi42NSAxMy43IDYuNjVIMTVWNC4xQzE0LjMgNCAxMy41IDMuOSAxMi44IDMuOUMxMC41IDMuOSA4LjkgNS4zIDguOSA3LjhWMTBINi40VjEyLjhIOC45VjE5Ljg1QzkuNDUgMTkuOTUgMTAgMjAgMTAuNTUgMjBDMTEuMSAyMCAxMS42NSAxOS45NSAxMi4yIDE5Ljg1VjEyLjhIMTQuNFoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo=';%0A%0A%20%20%20%20const%20blockedYTVideo%20=%0A%20%20%20%20%20%20%20%20'data:image/svg+xml;utf8,%253Csvg%2520width%253D%252275%2522%2520height%253D%252275%2522%2520viewBox%253D%25220%25200%252075%252075%2522%2520fill%253D%2522none%2522%2520xmlns%253D%2522http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg%2522%253E%250A%2520%2520%253Crect%2520x%253D%25226.75%2522%2520y%253D%252215.75%2522%2520width%253D%252256.25%2522%2520height%253D%252239%2522%2520rx%253D%252213.5%2522%2520fill%253D%2522%2523DE5833%2522%252F%253E%250A%2520%2520%253Cmask%2520id%253D%2522path-2-outside-1_885_11045%2522%2520maskUnits%253D%2522userSpaceOnUse%2522%2520x%253D%252223.75%2522%2520y%253D%252222.5%2522%2520width%253D%252224%2522%2520height%253D%252226%2522%2520fill%253D%2522black%2522%253E%250A%2520%2520%253Crect%2520fill%253D%2522white%2522%2520x%253D%252223.75%2522%2520y%253D%252222.5%2522%2520width%253D%252224%2522%2520height%253D%252226%2522%252F%253E%250A%2520%2520%253Cpath%2520d%253D%2522M41.9425%252037.5279C43.6677%252036.492%252043.6677%252033.9914%252041.9425%252032.9555L31.0394%252026.4088C29.262%252025.3416%252027%252026.6218%252027%252028.695L27%252041.7884C27%252043.8615%252029.262%252045.1418%252031.0394%252044.0746L41.9425%252037.5279Z%2522%252F%253E%250A%2520%2520%253C%252Fmask%253E%250A%2520%2520%253Cpath%2520d%253D%2522M41.9425%252037.5279C43.6677%252036.492%252043.6677%252033.9914%252041.9425%252032.9555L31.0394%252026.4088C29.262%252025.3416%252027%252026.6218%252027%252028.695L27%252041.7884C27%252043.8615%252029.262%252045.1418%252031.0394%252044.0746L41.9425%252037.5279Z%2522%2520fill%253D%2522white%2522%252F%253E%250A%2520%2520%253Cpath%2520d%253D%2522M30.0296%252044.6809L31.5739%252047.2529L30.0296%252044.6809ZM30.0296%252025.8024L31.5739%252023.2304L30.0296%252025.8024ZM42.8944%252036.9563L44.4387%252039.5283L42.8944%252036.9563ZM41.35%252036.099L28.4852%252028.3744L31.5739%252023.2304L44.4387%252030.955L41.35%252036.099ZM30%252027.5171L30%252042.9663L24%252042.9663L24%252027.5171L30%252027.5171ZM28.4852%252042.1089L41.35%252034.3843L44.4387%252039.5283L31.5739%252047.2529L28.4852%252042.1089ZM30%252042.9663C30%252042.1888%252029.1517%252041.7087%252028.4852%252042.1089L31.5739%252047.2529C28.2413%252049.2539%252024%252046.8535%252024%252042.9663L30%252042.9663ZM28.4852%252028.3744C29.1517%252028.7746%252030%252028.2945%252030%252027.5171L24%252027.5171C24%252023.6299%252028.2413%252021.2294%252031.5739%252023.2304L28.4852%252028.3744ZM44.4387%252030.955C47.6735%252032.8974%252047.6735%252037.586%252044.4387%252039.5283L41.35%252034.3843C40.7031%252034.7728%252040.7031%252035.7105%252041.35%252036.099L44.4387%252030.955Z%2522%2520fill%253D%2522%2523BC4726%2522%2520mask%253D%2522url(%2523path-2-outside-1_885_11045)%2522%252F%253E%250A%2520%2520%253Ccircle%2520cx%253D%252257.75%2522%2520cy%253D%252252.5%2522%2520r%253D%252213.5%2522%2520fill%253D%2522%2523E0E0E0%2522%252F%253E%250A%2520%2520%253Crect%2520x%253D%252248.75%2522%2520y%253D%252250.25%2522%2520width%253D%252218%2522%2520height%253D%25224.5%2522%2520rx%253D%25221.5%2522%2520fill%253D%2522%2523666666%2522%252F%253E%250A%2520%2520%253Cpath%2520fill-rule%253D%2522evenodd%2522%2520clip-rule%253D%2522evenodd%2522%2520d%253D%2522M57.9853%252015.8781C58.2046%252016.1015%252058.5052%252016.2262%252058.8181%252016.2238C59.1311%252016.2262%252059.4316%252016.1015%252059.6509%252015.8781L62.9821%252012.5469C63.2974%252012.2532%252063.4272%252011.8107%252063.3206%252011.3931C63.2139%252010.9756%252062.8879%252010.6495%252062.4703%252010.5429C62.0528%252010.4363%252061.6103%252010.5661%252061.3165%252010.8813L57.9853%252014.2125C57.7627%252014.4325%252057.6374%252014.7324%252057.6374%252015.0453C57.6374%252015.3583%252057.7627%252015.6582%252057.9853%252015.8781ZM61.3598%252018.8363C61.388%252019.4872%252061.9385%252019.9919%252062.5893%252019.9637L62.6915%252019.9559L66.7769%252019.6023C67.4278%252019.5459%252067.9097%252018.9726%252067.8533%252018.3217C67.7968%252017.6708%252067.2235%252017.1889%252066.5726%252017.2453L62.4872%252017.6067C61.8363%252017.6349%252061.3316%252018.1854%252061.3598%252018.8363Z%2522%2520fill%253D%2522%2523AAAAAA%2522%2520fill-opacity%253D%25220.6%2522%252F%253E%250A%2520%2520%253Cpath%2520fill-rule%253D%2522evenodd%2522%2520clip-rule%253D%2522evenodd%2522%2520d%253D%2522M10.6535%252015.8781C10.4342%252016.1015%252010.1336%252016.2262%25209.82067%252016.2238C9.5077%252016.2262%25209.20717%252016.1015%25208.98787%252015.8781L5.65667%252012.5469C5.34138%252012.2532%25205.2116%252011.8107%25205.31823%252011.3931C5.42487%252010.9756%25205.75092%252010.6495%25206.16847%252010.5429C6.58602%252010.4363%25207.02848%252010.5661%25207.32227%252010.8813L10.6535%252014.2125C10.8761%252014.4325%252011.0014%252014.7324%252011.0014%252015.0453C11.0014%252015.3583%252010.8761%252015.6582%252010.6535%252015.8781ZM7.2791%252018.8362C7.25089%252019.4871%25206.7004%252019.9919%25206.04954%252019.9637L5.9474%252019.9558L1.86197%252019.6023C1.44093%252019.5658%25201.07135%252019.3074%25200.892432%252018.9246C0.713515%252018.5417%25200.752449%252018.0924%25200.994567%252017.7461C1.23669%252017.3997%25201.6452%252017.2088%25202.06624%252017.2453L6.15167%252017.6067C6.80254%252017.6349%25207.3073%252018.1854%25207.2791%252018.8362Z%2522%2520fill%253D%2522%2523AAAAAA%2522%2520fill-opacity%253D%25220.6%2522%252F%253E%250A%253C%252Fsvg%253E%250A';%0A%20%20%20%20const%20videoPlayDark%20=%0A%20%20%20%20%20%20%20%20'data:image/svg+xml;utf8,%253Csvg%2520width%253D%252222%2522%2520height%253D%252226%2522%2520viewBox%253D%25220%25200%252022%252026%2522%2520fill%253D%2522none%2522%2520xmlns%253D%2522http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg%2522%253E%250A%2520%2520%253Cpath%2520d%253D%2522M21%252011.2679C22.3333%252012.0377%252022.3333%252013.9622%252021%252014.732L3%252025.1244C1.66667%252025.8942%25202.59376e-06%252024.9319%25202.66105e-06%252023.3923L3.56958e-06%25202.60769C3.63688e-06%25201.06809%25201.66667%25200.105844%25203%25200.875644L21%252011.2679Z%2522%2520fill%253D%2522%2523222222%2522%252F%253E%250A%253C%252Fsvg%253E%250A';%0A%20%20%20%20const%20videoPlayLight%20=%0A%20%20%20%20%20%20%20%20'data:image/svg+xml;utf8,%253Csvg%2520width%253D%252222%2522%2520height%253D%252226%2522%2520viewBox%253D%25220%25200%252022%252026%2522%2520fill%253D%2522none%2522%2520xmlns%253D%2522http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg%2522%253E%250A%2520%2520%253Cpath%2520d%253D%2522M21%252011.2679C22.3333%252012.0377%252022.3333%252013.9622%252021%252014.732L3%252025.1244C1.66667%252025.8942%25202.59376e-06%252024.9319%25202.66105e-06%252023.3923L3.56958e-06%25202.60769C3.63688e-06%25201.06809%25201.66667%25200.105844%25203%25200.875644L21%252011.2679Z%2522%2520fill%253D%2522%2523FFFFFF%2522%252F%253E%250A%253C%252Fsvg%253E';%0A%0A%20%20%20%20var%20localesJSON%20=%20%60%7B%22bg%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22%D0%9F%D1%80%D0%B8%20%D0%B2%D0%BB%D0%B8%D0%B7%D0%B0%D0%BD%D0%B5%20%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D1%88%D0%B0%D0%B2%D0%B0%D1%82%D0%B5%20%D0%BD%D0%B0%20Facebook%20%D0%B4%D0%B0%20%D0%92%D0%B8%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%22,%22informationalModalMessageBody%22:%22%D0%A1%D0%BB%D0%B5%D0%B4%20%D0%BA%D0%B0%D1%82%D0%BE%20%D0%B2%D0%BB%D0%B5%D0%B7%D0%B5%D1%82%D0%B5,%20DuckDuckGo%20%D0%BD%D0%B5%20%D0%BC%D0%BE%D0%B6%D0%B5%20%D0%B4%D0%B0%20%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%D1%82%D0%BE%20%D0%BE%D1%82%20Facebook%20%D0%B2%20%D1%81%D1%8A%D0%B4%D1%8A%D1%80%D0%B6%D0%B0%D0%BD%D0%B8%D0%B5%D1%82%D0%BE%20%D0%BD%D0%B0%20%D1%82%D0%BE%D0%B7%D0%B8%20%D1%81%D0%B0%D0%B9%D1%82.%22,%22informationalModalConfirmButtonText%22:%22%D0%92%D1%85%D0%BE%D0%B4%22,%22informationalModalRejectButtonText%22:%22%D0%9D%D0%B0%D0%B7%D0%B0%D0%B4%22,%22loginButtonText%22:%22%D0%92%D1%85%D0%BE%D0%B4%20%D0%B2%D1%8A%D0%B2%20Facebook%22,%22loginBodyText%22:%22Facebook%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%20%D0%92%D0%B0%D1%88%D0%B0%D1%82%D0%B0%20%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D1%81%D1%82%20%D0%B2%20%D1%81%D1%8A%D0%BE%D1%82%D0%B2%D0%B5%D1%82%D0%BD%D0%B8%D1%8F%20%D1%81%D0%B0%D0%B9%D1%82,%20%D0%BA%D0%BE%D0%B3%D0%B0%D1%82%D0%BE%20%D0%B3%D0%BE%20%D0%B8%D0%B7%D0%BF%D0%BE%D0%BB%D0%B7%D0%B2%D0%B0%D1%82%D0%B5%20%D0%B7%D0%B0%20%D0%B2%D1%85%D0%BE%D0%B4.%22,%22buttonTextUnblockContent%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D1%81%D1%8A%D0%B4%D1%8A%D1%80%D0%B6%D0%B0%D0%BD%D0%B8%D0%B5%20%D0%BE%D1%82%20Facebook%22,%22buttonTextUnblockComment%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%BA%D0%BE%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%20%D0%B2%D1%8A%D0%B2%20Facebook%22,%22buttonTextUnblockComments%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%BA%D0%BE%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%20%D0%B2%D1%8A%D0%B2%20Facebook%22,%22buttonTextUnblockPost%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F%20%D0%BE%D1%82%20Facebook%22,%22buttonTextUnblockVideo%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%20%D0%BE%D1%82%20Facebook%22,%22buttonTextUnblockLogin%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%B2%D1%85%D0%BE%D0%B4%20%D1%81%20Facebook%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%20%D1%82%D0%BE%D0%B2%D0%B0%20%D1%81%D1%8A%D0%B4%D1%8A%D1%80%D0%B6%D0%B0%D0%BD%D0%B8%D0%B5,%20%D0%B7%D0%B0%20%D0%B4%D0%B0%20%D0%BF%D1%80%D0%B5%D0%B4%D0%BE%D1%82%D0%B2%D1%80%D0%B0%D1%82%D0%B8%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%20%D0%BE%D1%82%20Facebook%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%20%D1%82%D0%BE%D0%B7%D0%B8%20%D0%BA%D0%BE%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80,%20%D0%B7%D0%B0%20%D0%B4%D0%B0%20%D0%BF%D1%80%D0%B5%D0%B4%D0%BE%D1%82%D0%B2%D1%80%D0%B0%D1%82%D0%B8%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%20%D0%BE%D1%82%20Facebook%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%20%D1%82%D0%B5%D0%B7%D0%B8%20%D0%BA%D0%BE%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8,%20%D0%B7%D0%B0%20%D0%B4%D0%B0%20%D0%BF%D1%80%D0%B5%D0%B4%D0%BE%D1%82%D0%B2%D1%80%D0%B0%D1%82%D0%B8%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%20%D0%BE%D1%82%20Facebook%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%20%D1%82%D0%B0%D0%B7%D0%B8%20%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F,%20%D0%B7%D0%B0%20%D0%B4%D0%B0%20%D0%BF%D1%80%D0%B5%D0%B4%D0%BE%D1%82%D0%B2%D1%80%D0%B0%D1%82%D0%B8%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%20%D0%BE%D1%82%20Facebook%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%20%D1%82%D0%BE%D0%B2%D0%B0%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE,%20%D0%B7%D0%B0%20%D0%B4%D0%B0%20%D0%BF%D1%80%D0%B5%D0%B4%D0%BE%D1%82%D0%B2%D1%80%D0%B0%D1%82%D0%B8%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%20%D0%BE%D1%82%20Facebook%22,%22infoTextUnblockContent%22:%22%D0%91%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D1%85%D0%BC%D0%B5%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%D1%82%D0%BE%20%D0%BE%D1%82%20Facebook%20%D0%BF%D1%80%D0%B8%20%D0%B7%D0%B0%D1%80%D0%B5%D0%B6%D0%B4%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0%D1%82%D0%B0.%20%D0%90%D0%BA%D0%BE%20%D1%80%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D1%82%D0%B5%20%D1%82%D0%BE%D0%B2%D0%B0%20%D1%81%D1%8A%D0%B4%D1%8A%D1%80%D0%B6%D0%B0%D0%BD%D0%B8%D0%B5,%20Facebook%20%D1%89%D0%B5%20%D1%81%D0%BB%D0%B5%D0%B4%D0%B8%20%D0%92%D0%B0%D1%88%D0%B0%D1%82%D0%B0%20%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D1%81%D1%82.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22%D0%9D%D0%B0%D1%83%D1%87%D0%B5%D1%82%D0%B5%20%D0%BF%D0%BE%D0%B2%D0%B5%D1%87%D0%B5%22,%22readAbout%22:%22%D0%9F%D1%80%D0%BE%D1%87%D0%B5%D1%82%D0%B5%D1%82%D0%B5%20%D0%B7%D0%B0%20%D1%82%D0%B0%D0%B7%D0%B8%20%D0%B7%D0%B0%D1%89%D0%B8%D1%82%D0%B0%20%D0%BD%D0%B0%20%D0%BF%D0%BE%D0%B2%D0%B5%D1%80%D0%B8%D1%82%D0%B5%D0%BB%D0%BD%D0%BE%D1%81%D1%82%D1%82%D0%B0%22,%22shareFeedback%22:%22%D0%A1%D0%BF%D0%BE%D0%B4%D0%B5%D0%BB%D1%8F%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%BE%D1%82%D0%B7%D0%B8%D0%B2%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22%D0%90%D0%BA%D1%82%D0%B8%D0%B2%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%B2%D1%81%D0%B8%D1%87%D0%BA%D0%B8%20%D0%BF%D1%80%D0%B5%D0%B3%D0%BB%D0%B5%D0%B4%D0%B8%20%D0%B2%20YouTube?%22,%22informationalModalMessageBody%22:%22%D0%9F%D0%BE%D0%BA%D0%B0%D0%B7%D0%B2%D0%B0%D0%BD%D0%B5%D1%82%D0%BE%20%D0%BD%D0%B0%20%D0%BF%D1%80%D0%B5%D0%B3%D0%BB%D0%B5%D0%B4%20%D0%BF%D0%BE%D0%B7%D0%B2%D0%BE%D0%BB%D1%8F%D0%B2%D0%B0%20%D0%BD%D0%B0%20Google%20(%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%B8%D0%BA%20%D0%BD%D0%B0%20YouTube)%20%D0%B4%D0%B0%20%D0%B2%D0%B8%D0%B4%D0%B8%20%D1%87%D0%B0%D1%81%D1%82%20%D0%BE%D1%82%20%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%86%D0%B8%D1%8F%D1%82%D0%B0%20%D0%B7%D0%B0%20%D0%92%D0%B0%D1%88%D0%B5%D1%82%D0%BE%20%D1%83%D1%81%D1%82%D1%80%D0%BE%D0%B9%D1%81%D1%82%D0%B2%D0%BE,%20%D0%BD%D0%BE%20%D0%B2%D1%81%D0%B5%20%D0%BF%D0%B0%D0%BA%20%D0%BE%D1%81%D0%B8%D0%B3%D1%83%D1%80%D1%8F%D0%B2%D0%B0%20%D0%BF%D0%BE%D0%B2%D0%B5%D1%87%D0%B5%20%D0%BF%D0%BE%D0%B2%D0%B5%D1%80%D0%B8%D1%82%D0%B5%D0%BB%D0%BD%D0%BE%D1%81%D1%82%20%D0%BE%D1%82%D0%BA%D0%BE%D0%BB%D0%BA%D0%BE%D1%82%D0%BE%20%D0%BF%D1%80%D0%B8%20%D0%B2%D1%8A%D0%B7%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%B5%D0%B6%D0%B4%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%D0%BA%D0%BB%D0%B8%D0%BF%D0%B0.%22,%22informationalModalConfirmButtonText%22:%22%D0%90%D0%BA%D1%82%D0%B8%D0%B2%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%B2%D1%81%D0%B8%D1%87%D0%BA%D0%B8%20%D0%BF%D1%80%D0%B5%D0%B3%D0%BB%D0%B5%D0%B4%D0%B8%22,%22informationalModalRejectButtonText%22:%22%D0%9D%D0%B5,%20%D0%B1%D0%BB%D0%B0%D0%B3%D0%BE%D0%B4%D0%B0%D1%80%D1%8F%22,%22buttonTextUnblockVideo%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%20%D0%BE%D1%82%20YouTube%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%20%D1%82%D0%BE%D0%B7%D0%B8%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%D0%BA%D0%BB%D0%B8%D0%BF%20%D0%B2%20YouTube,%20%D0%B7%D0%B0%20%D0%B4%D0%B0%20%D0%BF%D1%80%D0%B5%D0%B4%D0%BE%D1%82%D0%B2%D1%80%D0%B0%D1%82%D0%B8%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%20%D0%BE%D1%82%20Google%22,%22infoTextUnblockVideo%22:%22%D0%91%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D1%85%D0%BC%D0%B5%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%D1%82%D0%BE%20%D0%BE%D1%82%20Google%20(%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%B8%D0%BA%20%D0%BD%D0%B0%20YouTube)%20%D0%BF%D1%80%D0%B8%20%D0%B7%D0%B0%D1%80%D0%B5%D0%B6%D0%B4%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0%D1%82%D0%B0.%20%D0%90%D0%BA%D0%BE%20%D1%80%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D1%82%D0%B5%20%D1%82%D0%BE%D0%B7%D0%B8%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%D0%BA%D0%BB%D0%B8%D0%BF,%20Google%20%D1%89%D0%B5%20%D1%81%D0%BB%D0%B5%D0%B4%D0%B8%20%D0%92%D0%B0%D1%88%D0%B0%D1%82%D0%B0%20%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D1%81%D1%82.%22,%22infoPreviewToggleText%22:%22%D0%9F%D1%80%D0%B5%D0%B3%D0%BB%D0%B5%D0%B4%D0%B8%D1%82%D0%B5%20%D1%81%D0%B0%20%D0%B4%D0%B5%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%B8%D1%80%D0%B0%D0%BD%D0%B8%20%D0%B7%D0%B0%20%D0%BE%D1%81%D0%B8%D0%B3%D1%83%D1%80%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%B4%D0%BE%D0%BF%D1%8A%D0%BB%D0%BD%D0%B8%D1%82%D0%B5%D0%BB%D0%BD%D0%B0%20%D0%BF%D0%BE%D0%B2%D0%B5%D1%80%D0%B8%D1%82%D0%B5%D0%BB%D0%BD%D0%BE%D1%81%D1%82%22,%22infoPreviewToggleEnabledText%22:%22%D0%9F%D1%80%D0%B5%D0%B3%D0%BB%D0%B5%D0%B4%D0%B8%D1%82%D0%B5%20%D1%81%D0%B0%20%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%B8%D1%80%D0%B0%D0%BD%D0%B8%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22%D0%92%D0%B8%D0%B7%D1%83%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8%D1%82%D0%B5%20%D0%BE%D1%82%20YouTube%20%D1%81%D0%B0%20%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%B8%D1%80%D0%B0%D0%BD%D0%B8%20%D0%B2%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3E%D0%9D%D0%B0%D1%83%D1%87%D0%B5%D1%82%D0%B5%20%D0%BF%D0%BE%D0%B2%D0%B5%D1%87%D0%B5%3C/a%3E%20%D0%B7%D0%B0%20%D0%B2%D0%B3%D1%80%D0%B0%D0%B4%D0%B5%D0%BD%D0%B0%D1%82%D0%B0%20%D0%B7%D0%B0%D1%89%D0%B8%D1%82%D0%B0%20%D0%BE%D1%82%20%D1%81%D0%BE%D1%86%D0%B8%D0%B0%D0%BB%D0%BD%D0%B8%20%D0%BC%D0%B5%D0%B4%D0%B8%D0%B8%20%D0%BD%D0%B0%20DuckDuckGo%22%7D%7D,%22cs%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Kdy%C5%BE%20se%20p%C5%99ihl%C3%A1s%C3%AD%C5%A1%20p%C5%99es%20Facebook,%20bude%20t%C4%9B%20moct%20sledovat%22,%22informationalModalMessageBody%22:%22Po%20p%C5%99ihl%C3%A1%C5%A1en%C3%AD%20u%C5%BE%20DuckDuckGo%20nem%C5%AF%C5%BEe%20br%C3%A1nit%20Facebooku,%20aby%20t%C4%9B%20na%20t%C3%A9hle%20str%C3%A1nce%20sledoval.%22,%22informationalModalConfirmButtonText%22:%22P%C5%99ihl%C3%A1sit%20se%22,%22informationalModalRejectButtonText%22:%22Zp%C4%9Bt%22,%22loginButtonText%22:%22P%C5%99ihl%C3%A1sit%20se%20pomoc%C3%AD%20Facebooku%22,%22loginBodyText%22:%22Facebook%20sleduje%20tvou%20aktivitu%20na%20webu,%20kdy%C5%BE%20se%20p%C5%99ihl%C3%A1s%C3%AD%C5%A1%20jeho%20prost%C5%99ednictv%C3%ADm.%22,%22buttonTextUnblockContent%22:%22Odblokovat%20obsah%20na%20Facebooku%22,%22buttonTextUnblockComment%22:%22Odblokovat%20koment%C3%A1%C5%99%20na%20Facebooku%22,%22buttonTextUnblockComments%22:%22Odblokovat%20koment%C3%A1%C5%99e%20na%20Facebooku%22,%22buttonTextUnblockPost%22:%22Odblokovat%20p%C5%99%C3%ADsp%C4%9Bvek%20na%20Facebooku%22,%22buttonTextUnblockVideo%22:%22Odblokovat%20video%20na%20Facebooku%22,%22buttonTextUnblockLogin%22:%22Odblokovat%20p%C5%99ihl%C3%A1%C5%A1en%C3%AD%20k%C2%A0Facebooku%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20zablokoval%20tenhle%20obsah,%20aby%20Facebooku%20zabr%C3%A1nil%20t%C4%9B%20sledovat%22,%22infoTitleUnblockComment%22:%22Slu%C5%BEba%20DuckDuckGo%20zablokovala%20tento%20koment%C3%A1%C5%99,%20aby%20Facebooku%20zabr%C3%A1nila%20ve%20tv%C3%A9m%20sledov%C3%A1n%C3%AD%22,%22infoTitleUnblockComments%22:%22Slu%C5%BEba%20DuckDuckGo%20zablokovala%20tyto%20koment%C3%A1%C5%99e,%20aby%20Facebooku%20zabr%C3%A1nila%20ve%20tv%C3%A9m%20sledov%C3%A1n%C3%AD%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20zablokoval%20tenhle%20p%C5%99%C3%ADsp%C4%9Bvek,%20aby%20Facebooku%20zabr%C3%A1nil%20t%C4%9B%20sledovat%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20zablokoval%20tohle%20video,%20aby%20Facebooku%20zabr%C3%A1nil%20t%C4%9B%20sledovat%22,%22infoTextUnblockContent%22:%22P%C5%99i%20na%C4%8D%C3%ADt%C3%A1n%C3%AD%20str%C3%A1nky%20jsme%20Facebooku%20zabr%C3%A1nili,%20aby%20t%C4%9B%20sledoval.%20Kdy%C5%BE%20tenhle%20obsah%20odblokuje%C5%A1,%20Facebook%20bude%20m%C3%ADt%20p%C5%99%C3%ADstup%20ke%20tv%C3%A9%20aktivit%C4%9B.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22V%C3%ADce%20informac%C3%AD%22,%22readAbout%22:%22P%C5%99e%C4%8Dti%20si%20o%C2%A0t%C3%A9hle%20ochran%C4%9B%20soukrom%C3%AD%22,%22shareFeedback%22:%22Pod%C4%9Blte%20se%20o%20zp%C4%9Btnou%20vazbu%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Zapnout%20v%C5%A1echny%20n%C3%A1hledy%20YouTube?%22,%22informationalModalMessageBody%22:%22Zobrazov%C3%A1n%C3%AD%20n%C3%A1hled%C5%AF%20umo%C5%BEn%C3%AD%20spole%C4%8Dnosti%20Google%20(kter%C3%A1%20vlastn%C3%AD%20YouTube)%20zobrazit%20n%C4%9Bkter%C3%A9%20informace%20o%C2%A0tv%C3%A9m%20za%C5%99%C3%ADzen%C3%AD,%20ale%20po%C5%99%C3%A1d%20jde%20o%C2%A0diskr%C3%A9tn%C4%9Bj%C5%A1%C3%AD%20volbu,%20ne%C5%BE%20je%20p%C5%99ehr%C3%A1v%C3%A1n%C3%AD%20videa.%22,%22informationalModalConfirmButtonText%22:%22Zapnout%20v%C5%A1echny%20n%C3%A1hledy%22,%22informationalModalRejectButtonText%22:%22Ne,%20d%C4%9Bkuji%22,%22buttonTextUnblockVideo%22:%22Odblokovat%20video%20na%20YouTube%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20zablokoval%20tohle%20video%20z%C2%A0YouTube,%20aby%20Googlu%20zabr%C3%A1nil%20t%C4%9B%20sledovat%22,%22infoTextUnblockVideo%22:%22Zabr%C3%A1nili%20jsme%20spole%C4%8Dnosti%20Google%20(kter%C3%A1%20vlastn%C3%AD%20YouTube),%20aby%20t%C4%9B%20p%C5%99i%20na%C4%8D%C3%ADt%C3%A1n%C3%AD%20str%C3%A1nky%20sledovala.%20Pokud%20toto%20video%20odblokuje%C5%A1,%20Google%20z%C3%ADsk%C3%A1%20p%C5%99%C3%ADstup%20ke%20tv%C3%A9%20aktivit%C4%9B.%22,%22infoPreviewToggleText%22:%22N%C3%A1hledy%20jsou%20pro%20v%C4%9Bt%C5%A1%C3%AD%20soukrom%C3%AD%20vypnut%C3%A9%22,%22infoPreviewToggleEnabledText%22:%22N%C3%A1hledy%20jsou%20zapnut%C3%A9%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22N%C3%A1hledy%20YouTube%20jsou%20v%C2%A0DuckDuckGo%20povolen%C3%A9.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EDal%C5%A1%C3%AD%20informace%3C/a%3E%20o%C2%A0ochran%C4%9B%20DuckDuckGo%20p%C5%99ed%20sledov%C3%A1n%C3%ADm%20prost%C5%99ednictv%C3%ADm%20vlo%C5%BEen%C3%A9ho%20obsahu%20ze%20soci%C3%A1ln%C3%ADch%20m%C3%A9di%C3%AD%22%7D%7D,%22da%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22N%C3%A5r%20du%20logger%20ind%20med%20Facebook,%20kan%20de%20spore%20dig%22,%22informationalModalMessageBody%22:%22N%C3%A5r%20du%20er%20logget%20ind,%20kan%20DuckDuckGo%20ikke%20blokere%20for,%20at%20indhold%20fra%20Facebook%20sporer%20dig%20p%C3%A5%20dette%20websted.%22,%22informationalModalConfirmButtonText%22:%22Log%20p%C3%A5%22,%22informationalModalRejectButtonText%22:%22G%C3%A5%20tilbage%22,%22loginButtonText%22:%22Log%20ind%20med%20Facebook%22,%22loginBodyText%22:%22Facebook%20sporer%20din%20aktivitet%20p%C3%A5%20et%20websted,%20n%C3%A5r%20du%20bruger%20dem%20til%20at%20logge%20ind.%22,%22buttonTextUnblockContent%22:%22Bloker%20ikke%20Facebook-indhold%22,%22buttonTextUnblockComment%22:%22Bloker%20ikke%20Facebook-kommentar%22,%22buttonTextUnblockComments%22:%22Bloker%20ikke%20Facebook-kommentarer%22,%22buttonTextUnblockPost%22:%22Bloker%20ikke%20Facebook-opslag%22,%22buttonTextUnblockVideo%22:%22Bloker%20ikke%20Facebook-video%22,%22buttonTextUnblockLogin%22:%22Bloker%20ikke%20Facebook-login%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20har%20blokeret%20dette%20indhold%20for%20at%20forhindre%20Facebook%20i%20at%20spore%20dig%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20har%20blokeret%20denne%20kommentar%20for%20at%20forhindre%20Facebook%20i%20at%20spore%20dig%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20har%20blokeret%20disse%20kommentarer%20for%20at%20forhindre%20Facebook%20i%20at%20spore%20dig%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20blokerede%20dette%20indl%C3%A6g%20for%20at%20forhindre%20Facebook%20i%20at%20spore%20dig%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20har%20blokeret%20denne%20video%20for%20at%20forhindre%20Facebook%20i%20at%20spore%20dig%22,%22infoTextUnblockContent%22:%22Vi%20blokerede%20for,%20at%20Facebook%20sporede%20dig,%20da%20siden%20blev%20indl%C3%A6st.%20Hvis%20du%20oph%C3%A6ver%20blokeringen%20af%20dette%20indhold,%20vil%20Facebook%20kende%20din%20aktivitet.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Mere%20info%22,%22readAbout%22:%22L%C3%A6s%20om%20denne%20beskyttelse%20af%20privatlivet%22,%22shareFeedback%22:%22Del%20feedback%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Vil%20du%20aktivere%20alle%20YouTube-forh%C3%A5ndsvisninger?%22,%22informationalModalMessageBody%22:%22Med%20forh%C3%A5ndsvisninger%20kan%20Google%20(som%20ejer%20YouTube)%20se%20nogle%20af%20enhedens%20oplysninger,%20men%20det%20er%20stadig%20mere%20privat%20end%20at%20afspille%20videoen.%22,%22informationalModalConfirmButtonText%22:%22Aktiv%C3%A9r%20alle%20forh%C3%A5ndsvisninger%22,%22informationalModalRejectButtonText%22:%22Nej%20tak.%22,%22buttonTextUnblockVideo%22:%22Bloker%20ikke%20YouTube-video%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20har%20blokeret%20denne%20YouTube-video%20for%20at%20forhindre%20Google%20i%20at%20spore%20dig%22,%22infoTextUnblockVideo%22:%22Vi%20blokerede%20Google%20(som%20ejer%20YouTube)%20fra%20at%20spore%20dig,%20da%20siden%20blev%20indl%C3%A6st.%20Hvis%20du%20fjerner%20blokeringen%20af%20denne%20video,%20vil%20Google%20f%C3%A5%20kendskab%20til%20din%20aktivitet.%22,%22infoPreviewToggleText%22:%22Forh%C3%A5ndsvisninger%20er%20deaktiveret%20for%20at%20give%20yderligere%20privatliv%22,%22infoPreviewToggleEnabledText%22:%22Forh%C3%A5ndsvisninger%20er%20deaktiveret%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube-forh%C3%A5ndsvisninger%20er%20aktiveret%20i%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EF%C3%A5%20mere%20at%20vide%20p%C3%A5%3C/a%3E%20om%20DuckDuckGos%20indbyggede%20beskyttelse%20p%C3%A5%20sociale%20medier%22%7D%7D,%22de%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Wenn%20du%20dich%20bei%20Facebook%20anmeldest,%20kann%20Facebook%20dich%20tracken%22,%22informationalModalMessageBody%22:%22Sobald%20du%20angemeldet%20bist,%20kann%20DuckDuckGo%20nicht%20mehr%20verhindern,%20dass%20Facebook-Inhalte%20dich%20auf%20dieser%20Website%20tracken.%22,%22informationalModalConfirmButtonText%22:%22Anmelden%22,%22informationalModalRejectButtonText%22:%22Zur%C3%BCck%22,%22loginButtonText%22:%22Mit%20Facebook%20anmelden%22,%22loginBodyText%22:%22Facebook%20trackt%20deine%20Aktivit%C3%A4t%20auf%20einer%20Website,%20wenn%20du%20dich%20%C3%BCber%20Facebook%20dort%20anmeldest.%22,%22buttonTextUnblockContent%22:%22Facebook-Inhalt%20entsperren%22,%22buttonTextUnblockComment%22:%22Facebook-Kommentar%20entsperren%22,%22buttonTextUnblockComments%22:%22Facebook-Kommentare%20entsperren%22,%22buttonTextUnblockPost%22:%22Facebook-Beitrag%20entsperren%22,%22buttonTextUnblockVideo%22:%22Facebook-Video%20entsperren%22,%22buttonTextUnblockLogin%22:%22Facebook-Anmeldung%20entsperren%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20hat%20diesen%20Inhalt%20blockiert,%20um%20zu%20verhindern,%20dass%20Facebook%20dich%20trackt%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20hat%20diesen%20Kommentar%20blockiert,%20um%20zu%20verhindern,%20dass%20Facebook%20dich%20trackt%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20hat%20diese%20Kommentare%20blockiert,%20um%20zu%20verhindern,%20dass%20Facebook%20dich%20trackt%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20hat%20diesen%20Beitrag%20blockiert,%20um%20zu%20verhindern,%20dass%20Facebook%20dich%20trackt%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20hat%20dieses%20Video%20blockiert,%20um%20zu%20verhindern,%20dass%20Facebook%20dich%20trackt%22,%22infoTextUnblockContent%22:%22Wir%20haben%20Facebook%20daran%20gehindert,%20dich%20zu%20tracken,%20als%20die%20Seite%20geladen%20wurde.%20Wenn%20du%20die%20Blockierung%20f%C3%BCr%20diesen%20Inhalt%20aufhebst,%20kennt%20Facebook%20deine%20Aktivit%C3%A4ten.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Mehr%20erfahren%22,%22readAbout%22:%22Weitere%20Informationen%20%C3%BCber%20diesen%20Datenschutz%22,%22shareFeedback%22:%22Feedback%20teilen%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Alle%20YouTube-Vorschauen%20aktivieren?%22,%22informationalModalMessageBody%22:%22Durch%20das%20Anzeigen%20von%20Vorschauen%20kann%20Google%20(dem%20YouTube%20geh%C3%B6rt)%20einige%20Informationen%20zu%20deinem%20Ger%C3%A4t%20sehen.%20Dies%20ist%20aber%20immer%20noch%20privater%20als%20das%20Abspielen%20des%20Videos.%22,%22informationalModalConfirmButtonText%22:%22Alle%20Vorschauen%20aktivieren%22,%22informationalModalRejectButtonText%22:%22Nein,%20danke%22,%22buttonTextUnblockVideo%22:%22YouTube-Video%20entsperren%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20hat%20dieses%20YouTube-Video%20blockiert,%20um%20zu%20verhindern,%20dass%20Google%20dich%20trackt.%22,%22infoTextUnblockVideo%22:%22Wir%20haben%20Google%20(dem%20YouTube%20geh%C3%B6rt)%20daran%20gehindert,%20dich%20beim%20Laden%20der%20Seite%20zu%20tracken.%20Wenn%20du%20die%20Blockierung%20f%C3%BCr%20dieses%20Video%20aufhebst,%20kennt%20Google%20deine%20Aktivit%C3%A4ten.%22,%22infoPreviewToggleText%22:%22Vorschau%20f%C3%BCr%20mehr%20Privatsph%C3%A4re%20deaktiviert%22,%22infoPreviewToggleEnabledText%22:%22Vorschau%20aktiviert%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube-Vorschauen%20sind%20in%20DuckDuckGo%20aktiviert.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EErfahre%20mehr%3C/a%3E%20%C3%BCber%20den%20DuckDuckGo-Schutz%20vor%20eingebetteten%20Social%20Media-Inhalten%22%7D%7D,%22el%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22%CE%97%20%CF%83%CF%8D%CE%BD%CE%B4%CE%B5%CF%83%CE%B7%20%CE%BC%CE%AD%CF%83%CF%89%20Facebook%20%CF%84%CE%BF%CF%85%CF%82%20%CE%B5%CF%80%CE%B9%CF%84%CF%81%CE%AD%CF%80%CE%B5%CE%B9%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%BF%CF%8D%CE%BD%22,%22informationalModalMessageBody%22:%22%CE%9C%CF%8C%CE%BB%CE%B9%CF%82%20%CF%83%CF%85%CE%BD%CE%B4%CE%B5%CE%B8%CE%B5%CE%AF%CF%84%CE%B5,%20%CF%84%CE%BF%20DuckDuckGo%20%CE%B4%CE%B5%CE%BD%20%CE%BC%CF%80%CE%BF%CF%81%CE%B5%CE%AF%20%CE%BD%CE%B1%20%CE%B5%CE%BC%CF%80%CE%BF%CE%B4%CE%AF%CF%83%CE%B5%CE%B9%20%CF%84%CE%BF%20%CF%80%CE%B5%CF%81%CE%B9%CE%B5%CF%87%CF%8C%CE%BC%CE%B5%CE%BD%CE%BF%20%CF%84%CE%BF%CF%85%20Facebook%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%BF%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%20%CF%83%CE%B5%20%CE%B1%CF%85%CF%84%CF%8C%CE%BD%20%CF%84%CE%BF%CE%BD%20%CE%B9%CF%83%CF%84%CF%8C%CF%84%CE%BF%CF%80%CE%BF.%22,%22informationalModalConfirmButtonText%22:%22%CE%A3%CF%8D%CE%BD%CE%B4%CE%B5%CF%83%CE%B7%22,%22informationalModalRejectButtonText%22:%22%CE%95%CF%80%CE%B9%CF%83%CF%84%CF%81%CE%BF%CF%86%CE%AE%22,%22loginButtonText%22:%22%CE%A3%CF%8D%CE%BD%CE%B4%CE%B5%CF%83%CE%B7%20%CE%BC%CE%AD%CF%83%CF%89%20Facebook%22,%22loginBodyText%22:%22%CE%A4%CE%BF%20Facebook%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%20%CF%84%CE%B7%20%CE%B4%CF%81%CE%B1%CF%83%CF%84%CE%B7%CF%81%CE%B9%CF%8C%CF%84%CE%B7%CF%84%CE%AC%20%CF%83%CE%B1%CF%82%20%CF%83%CE%B5%20%CE%AD%CE%BD%CE%B1%CE%BD%20%CE%B9%CF%83%CF%84%CF%8C%CF%84%CE%BF%CF%80%CE%BF%20%CF%8C%CF%84%CE%B1%CE%BD%20%CF%84%CE%BF%CE%BD%20%CF%87%CF%81%CE%B7%CF%83%CE%B9%CE%BC%CE%BF%CF%80%CE%BF%CE%B9%CE%B5%CE%AF%CF%84%CE%B5%20%CE%B3%CE%B9%CE%B1%20%CE%BD%CE%B1%20%CF%83%CF%85%CE%BD%CE%B4%CE%B5%CE%B8%CE%B5%CE%AF%CF%84%CE%B5.%22,%22buttonTextUnblockContent%22:%22%CE%86%CF%81%CF%83%CE%B7%20%CE%B1%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%BC%CE%BF%CF%8D%20%CF%80%CE%B5%CF%81%CE%B9%CE%B5%CF%87%CE%BF%CE%BC%CE%AD%CE%BD%CE%BF%CF%85%20%CF%83%CF%84%CE%BF%20Facebook%22,%22buttonTextUnblockComment%22:%22%CE%86%CF%81%CF%83%CE%B7%20%CE%B1%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%BC%CE%BF%CF%8D%20%CF%83%CF%87%CF%8C%CE%BB%CE%B9%CE%BF%CF%85%20%CF%83%CF%84%CE%BF%20Facebook%22,%22buttonTextUnblockComments%22:%22%CE%86%CF%81%CF%83%CE%B7%20%CE%B1%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%BC%CE%BF%CF%8D%20%CF%83%CF%87%CE%BF%CE%BB%CE%AF%CF%89%CE%BD%20%CF%83%CF%84%CE%BF%20Facebook%22,%22buttonTextUnblockPost%22:%22%CE%86%CF%81%CF%83%CE%B7%20%CE%B1%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%BC%CE%BF%CF%8D%20%CE%B1%CE%BD%CE%AC%CF%81%CF%84%CE%B7%CF%83%CE%B7%CF%82%20%CF%83%CF%84%CE%BF%20Facebook%22,%22buttonTextUnblockVideo%22:%22%CE%86%CF%81%CF%83%CE%B7%20%CE%B1%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%BC%CE%BF%CF%8D%20%CE%B2%CE%AF%CE%BD%CF%84%CE%B5%CE%BF%20%CF%83%CF%84%CE%BF%20Facebook%22,%22buttonTextUnblockLogin%22:%22%CE%86%CF%81%CF%83%CE%B7%20%CE%B1%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%BC%CE%BF%CF%8D%20%CF%83%CF%8D%CE%BD%CE%B4%CE%B5%CF%83%CE%B7%CF%82%20%CF%83%CF%84%CE%BF%20Facebook%22,%22infoTitleUnblockContent%22:%22%CE%A4%CE%BF%20DuckDuckGo%20%CE%B1%CF%80%CE%AD%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%B5%20%CF%84%CE%BF%20%CF%80%CE%B5%CF%81%CE%B9%CE%B5%CF%87%CF%8C%CE%BC%CE%B5%CE%BD%CE%BF%20%CE%B1%CF%85%CF%84%CF%8C%20%CE%B3%CE%B9%CE%B1%20%CE%BD%CE%B1%20%CE%B5%CE%BC%CF%80%CE%BF%CE%B4%CE%AF%CF%83%CE%B5%CE%B9%20%CF%84%CE%BF%20Facebook%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%BF%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%22,%22infoTitleUnblockComment%22:%22%CE%A4%CE%BF%20DuckDuckGo%20%CE%B1%CF%80%CE%AD%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%B5%20%CF%84%CE%BF%20%CF%83%CF%87%CF%8C%CE%BB%CE%B9%CE%BF%20%CE%B1%CF%85%CF%84%CF%8C%20%CE%B3%CE%B9%CE%B1%20%CE%BD%CE%B1%20%CE%B5%CE%BC%CF%80%CE%BF%CE%B4%CE%AF%CF%83%CE%B5%CE%B9%20%CF%84%CE%BF%20Facebook%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%BF%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%22,%22infoTitleUnblockComments%22:%22%CE%A4%CE%BF%20DuckDuckGo%20%CE%B1%CF%80%CE%AD%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%B5%20%CF%84%CE%B1%20%CF%83%CF%87%CF%8C%CE%BB%CE%B9%CE%B1%20%CE%B1%CF%85%CF%84%CE%AC%20%CE%B3%CE%B9%CE%B1%20%CE%BD%CE%B1%20%CE%B5%CE%BC%CF%80%CE%BF%CE%B4%CE%AF%CF%83%CE%B5%CE%B9%20%CF%84%CE%BF%20Facebook%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%BF%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%22,%22infoTitleUnblockPost%22:%22%CE%A4%CE%BF%20DuckDuckGo%20%CE%B1%CF%80%CE%AD%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%B5%20%CF%84%CE%B7%CE%BD%20%CE%B1%CE%BD%CE%AC%CF%81%CF%84%CE%B7%CF%83%CE%B7%20%CE%B1%CF%85%CF%84%CE%AE%20%CE%B3%CE%B9%CE%B1%20%CE%BD%CE%B1%20%CE%B5%CE%BC%CF%80%CE%BF%CE%B4%CE%AF%CF%83%CE%B5%CE%B9%20%CF%84%CE%BF%20Facebook%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%BF%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%22,%22infoTitleUnblockVideo%22:%22%CE%A4%CE%BF%20DuckDuckGo%20%CE%B1%CF%80%CE%AD%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%B5%20%CF%84%CE%BF%20%CE%B2%CE%AF%CE%BD%CF%84%CE%B5%CE%BF%20%CE%B1%CF%85%CF%84%CF%8C%20%CE%B3%CE%B9%CE%B1%20%CE%BD%CE%B1%20%CE%B5%CE%BC%CF%80%CE%BF%CE%B4%CE%AF%CF%83%CE%B5%CE%B9%20%CF%84%CE%BF%20Facebook%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%BF%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%22,%22infoTextUnblockContent%22:%22%CE%91%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%AF%CF%83%CE%B1%CE%BC%CE%B5%20%CF%84%CE%BF%20Facebook%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%BF%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%20%CF%8C%CF%84%CE%B1%CE%BD%20%CF%86%CE%BF%CF%81%CF%84%CF%8E%CE%B8%CE%B7%CE%BA%CE%B5%20%CE%B7%20%CF%83%CE%B5%CE%BB%CE%AF%CE%B4%CE%B1.%20%CE%95%CE%AC%CE%BD%20%CE%BA%CE%AC%CE%BD%CE%B5%CF%84%CE%B5%20%CE%AC%CF%81%CF%83%CE%B7%20%CE%B1%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%BC%CE%BF%CF%8D%20%CE%B3%CE%B9'%20%CE%B1%CF%85%CF%84%CF%8C%20%CF%84%CE%BF%20%CF%80%CE%B5%CF%81%CE%B9%CE%B5%CF%87%CF%8C%CE%BC%CE%B5%CE%BD%CE%BF,%20%CF%84%CE%BF%20Facebook%20%CE%B8%CE%B1%20%CE%B3%CE%BD%CF%89%CF%81%CE%AF%CE%B6%CE%B5%CE%B9%20%CF%84%CE%B7%20%CE%B4%CF%81%CE%B1%CF%83%CF%84%CE%B7%CF%81%CE%B9%CF%8C%CF%84%CE%B7%CF%84%CE%AC%20%CF%83%CE%B1%CF%82.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22%CE%9C%CE%AC%CE%B8%CE%B5%CF%84%CE%B5%20%CF%80%CE%B5%CF%81%CE%B9%CF%83%CF%83%CF%8C%CF%84%CE%B5%CF%81%CE%B1%22,%22readAbout%22:%22%CE%94%CE%B9%CE%B1%CE%B2%CE%AC%CF%83%CF%84%CE%B5%20%CF%83%CF%87%CE%B5%CF%84%CE%B9%CE%BA%CE%AC%20%CE%BC%CE%B5%20%CF%84%CE%B7%CE%BD%20%CF%80%CE%B1%CF%81%CE%BF%CF%8D%CF%83%CE%B1%20%CF%80%CF%81%CE%BF%CF%83%CF%84%CE%B1%CF%83%CE%AF%CE%B1%CF%82%20%CF%80%CF%81%CE%BF%CF%83%CF%89%CF%80%CE%B9%CE%BA%CF%8E%CE%BD%20%CE%B4%CE%B5%CE%B4%CE%BF%CE%BC%CE%AD%CE%BD%CF%89%CE%BD%22,%22shareFeedback%22:%22%CE%9A%CE%BF%CE%B9%CE%BD%CE%BF%CF%80%CE%BF%CE%AF%CE%B7%CF%83%CE%B7%20%CF%83%CF%87%CE%BF%CE%BB%CE%AF%CE%BF%CF%85%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22%CE%95%CE%BD%CE%B5%CF%81%CE%B3%CE%BF%CF%80%CE%BF%CE%AF%CE%B7%CF%83%CE%B7%20%CF%8C%CE%BB%CF%89%CE%BD%20%CF%84%CF%89%CE%BD%20%CF%80%CF%81%CE%BF%CE%B5%CF%80%CE%B9%CF%83%CE%BA%CE%BF%CF%80%CE%AE%CF%83%CE%B5%CF%89%CE%BD%20%CF%84%CE%BF%CF%85%20YouTube;%22,%22informationalModalMessageBody%22:%22%CE%97%20%CF%80%CF%81%CE%BF%CE%B2%CE%BF%CE%BB%CE%AE%20%CF%84%CF%89%CE%BD%20%CF%80%CF%81%CE%BF%CE%B5%CF%80%CE%B9%CF%83%CE%BA%CE%BF%CF%80%CE%AE%CF%83%CE%B5%CF%89%CE%BD%20%CE%B8%CE%B1%20%CE%B5%CF%80%CE%B9%CF%84%CF%81%CE%AD%CF%88%CE%B5%CE%B9%20%CF%83%CF%84%CE%B7%CE%BD%20Google%20(%CF%83%CF%84%CE%B7%CE%BD%20%CE%BF%CF%80%CE%BF%CE%AF%CE%B1%20%CE%B1%CE%BD%CE%AE%CE%BA%CE%B5%CE%B9%20%CF%84%CE%BF%20YouTube)%20%CE%BD%CE%B1%20%CE%B2%CE%BB%CE%AD%CF%80%CE%B5%CE%B9%20%CE%BF%CF%81%CE%B9%CF%83%CE%BC%CE%AD%CE%BD%CE%B5%CF%82%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%B9%CF%82%20%CF%80%CE%BB%CE%B7%CF%81%CE%BF%CF%86%CE%BF%CF%81%CE%AF%CE%B5%CF%82%20%CF%84%CE%B7%CF%82%20%CF%83%CF%85%CF%83%CE%BA%CE%B5%CF%85%CE%AE%CF%82%20%CF%83%CE%B1%CF%82,%20%CF%89%CF%83%CF%84%CF%8C%CF%83%CE%BF%20%CE%B5%CE%BE%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%20%CE%BD%CE%B1%20%CE%B5%CE%AF%CE%BD%CE%B1%CE%B9%20%CF%80%CE%B9%CE%BF%20%CE%B9%CE%B4%CE%B9%CF%89%CF%84%CE%B9%CE%BA%CE%AE%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%B7%CE%BD%20%CE%B1%CE%BD%CE%B1%CF%80%CE%B1%CF%81%CE%B1%CE%B3%CF%89%CE%B3%CE%AE%20%CF%84%CE%BF%CF%85%20%CE%B2%CE%AF%CE%BD%CF%84%CE%B5%CE%BF.%22,%22informationalModalConfirmButtonText%22:%22%CE%95%CE%BD%CE%B5%CF%81%CE%B3%CE%BF%CF%80%CE%BF%CE%AF%CE%B7%CF%83%CE%B7%20%CF%8C%CE%BB%CF%89%CE%BD%20%CF%84%CF%89%CE%BD%20%CF%80%CF%81%CE%BF%CE%B5%CF%80%CE%B9%CF%83%CE%BA%CE%BF%CF%80%CE%AE%CF%83%CE%B5%CF%89%CE%BD%22,%22informationalModalRejectButtonText%22:%22%CE%8C%CF%87%CE%B9,%20%CE%B5%CF%85%CF%87%CE%B1%CF%81%CE%B9%CF%83%CF%84%CF%8E%22,%22buttonTextUnblockVideo%22:%22%CE%86%CF%81%CF%83%CE%B7%20%CE%B1%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%BC%CE%BF%CF%8D%20%CE%B2%CE%AF%CE%BD%CF%84%CE%B5%CE%BF%20YouTube%22,%22infoTitleUnblockVideo%22:%22%CE%A4%CE%BF%20DuckDuckGo%20%CE%B1%CF%80%CE%AD%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%B5%20%CF%84%CE%BF%20%CE%B2%CE%AF%CE%BD%CF%84%CE%B5%CE%BF%20%CE%B1%CF%85%CF%84%CF%8C%20%CF%83%CF%84%CE%BF%20YouTube%20%CE%B3%CE%B9%CE%B1%20%CE%BD%CE%B1%20%CE%B5%CE%BC%CF%80%CE%BF%CE%B4%CE%AF%CF%83%CE%B5%CE%B9%20%CF%84%CE%B7%CE%BD%20Google%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%BF%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%22,%22infoTextUnblockVideo%22:%22%CE%91%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%AF%CF%83%CE%B1%CE%BC%CE%B5%20%CF%84%CE%B7%CE%BD%20Google%20(%CF%83%CF%84%CE%B7%CE%BD%20%CE%BF%CF%80%CE%BF%CE%AF%CE%B1%20%CE%B1%CE%BD%CE%AE%CE%BA%CE%B5%CE%B9%20%CF%84%CE%BF%20YouTube)%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%BF%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%20%CF%8C%CF%84%CE%B1%CE%BD%20%CF%86%CE%BF%CF%81%CF%84%CF%8E%CE%B8%CE%B7%CE%BA%CE%B5%20%CE%B7%20%CF%83%CE%B5%CE%BB%CE%AF%CE%B4%CE%B1.%20%CE%95%CE%AC%CE%BD%20%CE%BA%CE%AC%CE%BD%CE%B5%CF%84%CE%B5%20%CE%AC%CF%81%CF%83%CE%B7%20%CE%B1%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%BC%CE%BF%CF%8D%20%CE%B3%CE%B9'%20%CE%B1%CF%85%CF%84%CF%8C%20%CF%84%CE%BF%20%CE%B2%CE%AF%CE%BD%CF%84%CE%B5%CE%BF,%20%CE%B7%20Google%20%CE%B8%CE%B1%20%CE%B3%CE%BD%CF%89%CF%81%CE%AF%CE%B6%CE%B5%CE%B9%20%CF%84%CE%B7%20%CE%B4%CF%81%CE%B1%CF%83%CF%84%CE%B7%CF%81%CE%B9%CF%8C%CF%84%CE%B7%CF%84%CE%AC%20%CF%83%CE%B1%CF%82.%22,%22infoPreviewToggleText%22:%22%CE%9F%CE%B9%20%CF%80%CF%81%CE%BF%CE%B5%CF%80%CE%B9%CF%83%CE%BA%CE%BF%CF%80%CE%AE%CF%83%CE%B5%CE%B9%CF%82%20%CE%B1%CF%80%CE%B5%CE%BD%CE%B5%CF%81%CE%B3%CE%BF%CF%80%CE%BF%CE%B9%CE%AE%CE%B8%CE%B7%CE%BA%CE%B1%CE%BD%20%CE%B3%CE%B9%CE%B1%20%CF%80%CF%81%CF%8C%CF%83%CE%B8%CE%B5%CF%84%CE%B7%20%CF%80%CF%81%CE%BF%CF%83%CF%84%CE%B1%CF%83%CE%AF%CE%B1%20%CF%84%CF%89%CE%BD%20%CF%80%CF%81%CE%BF%CF%83%CF%89%CF%80%CE%B9%CE%BA%CF%8E%CE%BD%20%CE%B4%CE%B5%CE%B4%CE%BF%CE%BC%CE%AD%CE%BD%CF%89%CE%BD%22,%22infoPreviewToggleEnabledText%22:%22%CE%9F%CE%B9%20%CF%80%CF%81%CE%BF%CE%B5%CF%80%CE%B9%CF%83%CE%BA%CE%BF%CF%80%CE%AE%CF%83%CE%B5%CE%B9%CF%82%20%CE%B5%CE%BD%CE%B5%CF%81%CE%B3%CE%BF%CF%80%CE%BF%CE%B9%CE%AE%CE%B8%CE%B7%CE%BA%CE%B1%CE%BD%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22%CE%9F%CE%B9%20%CF%80%CF%81%CE%BF%CE%B5%CF%80%CE%B9%CF%83%CE%BA%CE%BF%CF%80%CE%AE%CF%83%CE%B5%CE%B9%CF%82%20YouTube%20%CE%B5%CE%BD%CE%B5%CF%81%CE%B3%CE%BF%CF%80%CE%BF%CE%B9%CE%AE%CE%B8%CE%B7%CE%BA%CE%B1%CE%BD%20%CF%83%CF%84%CE%BF%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3E%CE%9C%CE%AC%CE%B8%CE%B5%CF%84%CE%B5%20%CF%80%CE%B5%CF%81%CE%B9%CF%83%CF%83%CF%8C%CF%84%CE%B5%CF%81%CE%B1%3C/a%3E%20%CE%B3%CE%B9%CE%B1%20%CF%84%CE%B7%CE%BD%20%CE%B5%CE%BD%CF%83%CF%89%CE%BC%CE%B1%CF%84%CF%89%CE%BC%CE%AD%CE%BD%CE%B7%20%CF%80%CF%81%CE%BF%CF%83%CF%84%CE%B1%CF%83%CE%AF%CE%B1%20%CE%BA%CE%BF%CE%B9%CE%BD%CF%89%CE%BD%CE%B9%CE%BA%CF%8E%CE%BD%20%CE%BC%CE%AD%CF%83%CF%89%CE%BD%20DuckDuckGo%22%7D%7D,%22en%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Logging%20in%20with%20Facebook%20lets%20them%20track%20you%22,%22informationalModalMessageBody%22:%22Once%20you're%20logged%20in,%20DuckDuckGo%20can't%20block%20Facebook%20content%20from%20tracking%20you%20on%20this%20site.%22,%22informationalModalConfirmButtonText%22:%22Log%20In%22,%22informationalModalRejectButtonText%22:%22Go%20back%22,%22loginButtonText%22:%22Log%20in%20with%20Facebook%22,%22loginBodyText%22:%22Facebook%20tracks%20your%20activity%20on%20a%20site%20when%20you%20use%20them%20to%20login.%22,%22buttonTextUnblockContent%22:%22Unblock%20Facebook%20Content%22,%22buttonTextUnblockComment%22:%22Unblock%20Facebook%20Comment%22,%22buttonTextUnblockComments%22:%22Unblock%20Facebook%20Comments%22,%22buttonTextUnblockPost%22:%22Unblock%20Facebook%20Post%22,%22buttonTextUnblockVideo%22:%22Unblock%20Facebook%20Video%22,%22buttonTextUnblockLogin%22:%22Unblock%20Facebook%20Login%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20blocked%20this%20content%20to%20prevent%20Facebook%20from%20tracking%20you%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20blocked%20this%20comment%20to%20prevent%20Facebook%20from%20tracking%20you%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20blocked%20these%20comments%20to%20prevent%20Facebook%20from%20tracking%20you%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20blocked%20this%20post%20to%20prevent%20Facebook%20from%20tracking%20you%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blocked%20this%20video%20to%20prevent%20Facebook%20from%20tracking%20you%22,%22infoTextUnblockContent%22:%22We%20blocked%20Facebook%20from%20tracking%20you%20when%20the%20page%20loaded.%20If%20you%20unblock%20this%20content,%20Facebook%20will%20know%20your%20activity.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Learn%20More%22,%22readAbout%22:%22Read%20about%20this%20privacy%20protection%22,%22shareFeedback%22:%22Share%20Feedback%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Enable%20all%20YouTube%20previews?%22,%22informationalModalMessageBody%22:%22Showing%20previews%20will%20allow%20Google%20(which%20owns%20YouTube)%20to%20see%20some%20of%20your%20device%E2%80%99s%20information,%20but%20is%20still%20more%20private%20than%20playing%20the%20video.%22,%22informationalModalConfirmButtonText%22:%22Enable%20All%20Previews%22,%22informationalModalRejectButtonText%22:%22No%20Thanks%22,%22buttonTextUnblockVideo%22:%22Unblock%20YouTube%20Video%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blocked%20this%20YouTube%20video%20to%20prevent%20Google%20from%20tracking%20you%22,%22infoTextUnblockVideo%22:%22We%20blocked%20Google%20(which%20owns%20YouTube)%20from%20tracking%20you%20when%20the%20page%20loaded.%20If%20you%20unblock%20this%20video,%20Google%20will%20know%20your%20activity.%22,%22infoPreviewToggleText%22:%22Previews%20disabled%20for%20additional%20privacy%22,%22infoPreviewToggleEnabledText%22:%22Previews%20enabled%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube%20previews%20enabled%20in%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3ELearn%20more%3C/a%3E%20about%20DuckDuckGo%20Embedded%20Social%20Media%20Protection%22%7D%7D,%22es%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Al%20iniciar%20sesi%C3%B3n%20en%20Facebook,%20les%20permites%20que%20te%20rastreen%22,%22informationalModalMessageBody%22:%22Una%20vez%20que%20hayas%20iniciado%20sesi%C3%B3n,%20DuckDuckGo%20no%20puede%20bloquear%20el%20contenido%20de%20Facebook%20para%20que%20no%20te%20rastree%20en%20este%20sitio.%22,%22informationalModalConfirmButtonText%22:%22Iniciar%20sesi%C3%B3n%22,%22informationalModalRejectButtonText%22:%22Volver%20atr%C3%A1s%22,%22loginButtonText%22:%22Iniciar%20sesi%C3%B3n%20con%20Facebook%22,%22loginBodyText%22:%22Facebook%20rastrea%20tu%20actividad%20en%20un%20sitio%20web%20cuando%20lo%20usas%20para%20iniciar%20sesi%C3%B3n.%22,%22buttonTextUnblockContent%22:%22Desbloquear%20contenido%20de%20Facebook%22,%22buttonTextUnblockComment%22:%22Desbloquear%20comentario%20de%20Facebook%22,%22buttonTextUnblockComments%22:%22Desbloquear%20comentarios%20de%20Facebook%22,%22buttonTextUnblockPost%22:%22Desbloquear%20publicaci%C3%B3n%20de%20Facebook%22,%22buttonTextUnblockVideo%22:%22Desbloquear%20v%C3%ADdeo%20de%20Facebook%22,%22buttonTextUnblockLogin%22:%22Desbloquear%20inicio%20de%20sesi%C3%B3n%20de%20Facebook%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20ha%20bloqueado%20este%20contenido%20para%20evitar%20que%20Facebook%20te%20rastree%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20ha%20bloqueado%20este%20comentario%20para%20evitar%20que%20Facebook%20te%20rastree%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20ha%20bloqueado%20estos%20comentarios%20para%20evitar%20que%20Facebook%20te%20rastree%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20ha%20bloqueado%20esta%20publicaci%C3%B3n%20para%20evitar%20que%20Facebook%20te%20rastree%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20ha%20bloqueado%20este%20v%C3%ADdeo%20para%20evitar%20que%20Facebook%20te%20rastree%22,%22infoTextUnblockContent%22:%22Hemos%20bloqueado%20el%20rastreo%20de%20Facebook%20cuando%20se%20ha%20cargado%20la%20p%C3%A1gina.%20Si%20desbloqueas%20este%20contenido,%20Facebook%20tendr%C3%A1%20conocimiento%20de%20tu%20actividad.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22M%C3%A1s%20informaci%C3%B3n%22,%22readAbout%22:%22Lee%20acerca%20de%20esta%20protecci%C3%B3n%20de%20privacidad%22,%22shareFeedback%22:%22Compartir%20opiniones%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22%C2%BFHabilitar%20todas%20las%20vistas%20previas%20de%20YouTube?%22,%22informationalModalMessageBody%22:%22Mostrar%20vistas%20previas%20permitir%C3%A1%20a%20Google%20(que%20es%20el%20propietario%20de%20YouTube)%20ver%20parte%20de%20la%20informaci%C3%B3n%20de%20tu%20dispositivo,%20pero%20sigue%20siendo%20m%C3%A1s%20privado%20que%20reproducir%20el%20v%C3%ADdeo.%22,%22informationalModalConfirmButtonText%22:%22Habilitar%20todas%20las%20vistas%20previas%22,%22informationalModalRejectButtonText%22:%22No,%20gracias%22,%22buttonTextUnblockVideo%22:%22Desbloquear%20v%C3%ADdeo%20de%20YouTube%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20ha%20bloqueado%20este%20v%C3%ADdeo%20de%20YouTube%20para%20evitar%20que%20Google%20te%20rastree%22,%22infoTextUnblockVideo%22:%22Hemos%20bloqueado%20el%20rastreo%20de%20Google%20(que%20es%20el%20propietario%20de%20YouTube)%20al%20cargarse%20la%20p%C3%A1gina.%20Si%20desbloqueas%20este%20v%C3%ADdeo,%20Goggle%20tendr%C3%A1%20conocimiento%20de%20tu%20actividad.%22,%22infoPreviewToggleText%22:%22Vistas%20previas%20desactivadas%20para%20mayor%20privacidad%22,%22infoPreviewToggleEnabledText%22:%22Vistas%20previas%20activadas%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22Vistas%20previas%20de%20YouTube%20habilitadas%20en%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EM%C3%A1s%20informaci%C3%B3n%3C/a%3E%20sobre%20la%20protecci%C3%B3n%20integrada%20de%20redes%20sociales%20DuckDuckGo%22%7D%7D,%22et%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Kui%20logid%20Facebookiga%20sisse,%20saab%20Facebook%20sind%20j%C3%A4lgida%22,%22informationalModalMessageBody%22:%22Kui%20oled%20sisse%20logitud,%20ei%20saa%20DuckDuckGo%20blokeerida%20Facebooki%20sisu%20sind%20j%C3%A4lgimast.%22,%22informationalModalConfirmButtonText%22:%22Logi%20sisse%22,%22informationalModalRejectButtonText%22:%22Mine%20tagasi%22,%22loginButtonText%22:%22Logi%20sisse%20Facebookiga%22,%22loginBodyText%22:%22Kui%20logid%20sisse%20Facebookiga,%20saab%20Facebook%20sinu%20tegevust%20saidil%20j%C3%A4lgida.%22,%22buttonTextUnblockContent%22:%22Deblokeeri%20Facebooki%20sisu%22,%22buttonTextUnblockComment%22:%22Deblokeeri%20Facebooki%20kommentaar%22,%22buttonTextUnblockComments%22:%22Deblokeeri%20Facebooki%20kommentaarid%22,%22buttonTextUnblockPost%22:%22Deblokeeri%20Facebooki%20postitus%22,%22buttonTextUnblockVideo%22:%22Deblokeeri%20Facebooki%20video%22,%22buttonTextUnblockLogin%22:%22Deblokeeri%20Facebooki%20sisselogimine%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20blokeeris%20selle%20sisu,%20et%20Facebook%20ei%20saaks%20sind%20j%C3%A4lgida%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20blokeeris%20selle%20kommentaari,%20et%20Facebook%20ei%20saaks%20sind%20j%C3%A4lgida%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20blokeeris%20need%20kommentaarid,%20et%20Facebook%20ei%20saaks%20sind%20j%C3%A4lgida%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20blokeeris%20selle%20postituse,%20et%20Facebook%20ei%20saaks%20sind%20j%C3%A4lgida%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blokeeris%20selle%20video,%20et%20Facebook%20ei%20saaks%20sind%20j%C3%A4lgida%22,%22infoTextUnblockContent%22:%22Blokeerisime%20lehe%20laadimise%20ajal%20Facebooki%20jaoks%20sinu%20j%C3%A4lgimise.%20Kui%20sa%20selle%20sisu%20deblokeerid,%20saab%20Facebook%20sinu%20tegevust%20j%C3%A4lgida.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Loe%20edasi%22,%22readAbout%22:%22Loe%20selle%20privaatsuskaitse%20kohta%22,%22shareFeedback%22:%22Jaga%20tagasisidet%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Kas%20lubada%20k%C3%B5ik%20YouTube%E2%80%99i%20eelvaated?%22,%22informationalModalMessageBody%22:%22Eelvaate%20n%C3%A4itamine%20v%C3%B5imaldab%20Google%E2%80%99il%20(kellele%20YouTube%20kuulub)%20n%C3%A4ha%20osa%20sinu%20seadme%20teabest,%20kuid%20see%20on%20siiski%20privaatsem%20kui%20video%20esitamine.%22,%22informationalModalConfirmButtonText%22:%22Luba%20k%C3%B5ik%20eelvaated%22,%22informationalModalRejectButtonText%22:%22Ei%20ait%C3%A4h%22,%22buttonTextUnblockVideo%22:%22Deblokeeri%20YouTube%E2%80%99i%20video%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blokeeris%20selle%20YouTube%E2%80%99i%20video,%20et%20takistada%20Google%E2%80%99it%20sind%20j%C3%A4lgimast%22,%22infoTextUnblockVideo%22:%22Me%20blokeerisime%20lehe%20laadimise%20ajal%20Google%E2%80%99i%20(kellele%20YouTube%20kuulub)%20j%C3%A4lgimise.%20Kui%20sa%20selle%20video%20deblokeerid,%20saab%20Google%20sinu%20tegevusest%20teada.%22,%22infoPreviewToggleText%22:%22Eelvaated%20on%20t%C3%A4iendava%20privaatsuse%20tagamiseks%20keelatud%22,%22infoPreviewToggleEnabledText%22:%22Eelvaated%20on%20lubatud%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube%E2%80%99i%20eelvaated%20on%20DuckDuckGos%20lubatud.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3ELisateave%3C/a%3E%20DuckDuckGo%20sisseehitatud%20sotsiaalmeediakaitse%20kohta%22%7D%7D,%22fi%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Kun%20kirjaudut%20sis%C3%A4%C3%A4n%20Facebook-tunnuksilla,%20Facebook%20voi%20seurata%20sinua%22,%22informationalModalMessageBody%22:%22Kun%20olet%20kirjautunut%20sis%C3%A4%C3%A4n,%20DuckDuckGo%20ei%20voi%20est%C3%A4%C3%A4%20Facebook-sis%C3%A4lt%C3%B6%C3%A4%20seuraamasta%20sinua%20t%C3%A4ll%C3%A4%20sivustolla.%22,%22informationalModalConfirmButtonText%22:%22Kirjaudu%20sis%C3%A4%C3%A4n%22,%22informationalModalRejectButtonText%22:%22Edellinen%22,%22loginButtonText%22:%22Kirjaudu%20sis%C3%A4%C3%A4n%20Facebook-tunnuksilla%22,%22loginBodyText%22:%22Facebook%20seuraa%20toimintaasi%20sivustolla,%20kun%20kirjaudut%20sis%C3%A4%C3%A4n%20sen%20kautta.%22,%22buttonTextUnblockContent%22:%22Poista%20Facebook-sis%C3%A4ll%C3%B6n%20esto%22,%22buttonTextUnblockComment%22:%22Poista%20Facebook-kommentin%20esto%22,%22buttonTextUnblockComments%22:%22Poista%20Facebook-kommenttien%20esto%22,%22buttonTextUnblockPost%22:%22Poista%20Facebook-julkaisun%20esto%22,%22buttonTextUnblockVideo%22:%22Poista%20Facebook-videon%20esto%22,%22buttonTextUnblockLogin%22:%22Poista%20Facebook-kirjautumisen%20esto%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20esti%20t%C3%A4m%C3%A4n%20sis%C3%A4ll%C3%B6n%20est%C3%A4%C3%A4kseen%20Facebookia%20seuraamasta%20sinua%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20esti%20t%C3%A4m%C3%A4n%20kommentin%20est%C3%A4%C3%A4kseen%20Facebookia%20seuraamasta%20sinua%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20esti%20n%C3%A4m%C3%A4%20kommentit%20est%C3%A4%C3%A4kseen%20Facebookia%20seuraamasta%20sinua%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20esti%20t%C3%A4m%C3%A4n%20julkaisun%20est%C3%A4%C3%A4kseen%20Facebookia%20seuraamasta%20sinua%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20esti%20t%C3%A4m%C3%A4n%20videon%20est%C3%A4%C3%A4kseen%20Facebookia%20seuraamasta%20sinua%22,%22infoTextUnblockContent%22:%22Estimme%20Facebookia%20seuraamasta%20sinua,%20kun%20sivua%20ladattiin.%20Jos%20poistat%20t%C3%A4m%C3%A4n%20sis%C3%A4ll%C3%B6n%20eston,%20Facebook%20saa%20tiet%C3%A4%C3%A4%20toimintasi.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Lue%20lis%C3%A4%C3%A4%22,%22readAbout%22:%22Lue%20t%C3%A4st%C3%A4%20yksityisyydensuojasta%22,%22shareFeedback%22:%22Jaa%20palaute%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Otetaanko%20k%C3%A4ytt%C3%B6%C3%B6n%20kaikki%20YouTube-esikatselut?%22,%22informationalModalMessageBody%22:%22Kun%20sallit%20esikatselun,%20Google%20(joka%20omistaa%20YouTuben)%20voi%20n%C3%A4hd%C3%A4%20joitakin%20laitteesi%20tietoja,%20mutta%20se%20on%20silti%20yksityisemp%C3%A4%C3%A4%20kuin%20videon%20toistaminen.%22,%22informationalModalConfirmButtonText%22:%22Ota%20k%C3%A4ytt%C3%B6%C3%B6n%20kaikki%20esikatselut%22,%22informationalModalRejectButtonText%22:%22Ei%20kiitos%22,%22buttonTextUnblockVideo%22:%22Poista%20YouTube-videon%20esto%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20esti%20t%C3%A4m%C3%A4n%20YouTube-videon,%20jotta%20Google%20ei%20voi%20seurata%20sinua%22,%22infoTextUnblockVideo%22:%22Estimme%20Googlea%20(joka%20omistaa%20YouTuben)%20seuraamasta%20sinua,%20kun%20sivua%20ladattiin.%20Jos%20poistat%20t%C3%A4m%C3%A4n%20videon%20eston,%20Google%20tiet%C3%A4%C3%A4%20toimintasi.%22,%22infoPreviewToggleText%22:%22Esikatselut%20on%20poistettu%20k%C3%A4yt%C3%B6st%C3%A4%20yksityisyyden%20lis%C3%A4%C3%A4miseksi%22,%22infoPreviewToggleEnabledText%22:%22Esikatselut%20k%C3%A4yt%C3%B6ss%C3%A4%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube-esikatselut%20k%C3%A4yt%C3%B6ss%C3%A4%20DuckDuckGossa.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3ELue%20lis%C3%A4%C3%A4%3C/a%3E%20DuckDuckGon%20upotetusta%20sosiaalisen%20median%20suojauksesta%22%7D%7D,%22fr%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22L'identification%20via%20Facebook%20leur%20permet%20de%20vous%20pister%22,%22informationalModalMessageBody%22:%22Une%20fois%20que%20vous%20%C3%AAtes%20connect%C3%A9(e),%20DuckDuckGo%20ne%20peut%20pas%20emp%C3%AAcher%20le%20contenu%20Facebook%20de%20vous%20pister%20sur%20ce%20site.%22,%22informationalModalConfirmButtonText%22:%22Connexion%22,%22informationalModalRejectButtonText%22:%22Revenir%20en%20arri%C3%A8re%22,%22loginButtonText%22:%22S'identifier%20avec%20Facebook%22,%22loginBodyText%22:%22Facebook%20piste%20votre%20activit%C3%A9%20sur%20un%20site%20lorsque%20vous%20l'utilisez%20pour%20vous%20identifier.%22,%22buttonTextUnblockContent%22:%22D%C3%A9bloquer%20le%20contenu%20Facebook%22,%22buttonTextUnblockComment%22:%22D%C3%A9bloquer%20le%20commentaire%20Facebook%22,%22buttonTextUnblockComments%22:%22D%C3%A9bloquer%20les%20commentaires%20Facebook%22,%22buttonTextUnblockPost%22:%22D%C3%A9bloquer%20la%20publication%20Facebook%22,%22buttonTextUnblockVideo%22:%22D%C3%A9bloquer%20la%20vid%C3%A9o%20Facebook%22,%22buttonTextUnblockLogin%22:%22D%C3%A9bloquer%20la%20connexion%20Facebook%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20a%20bloqu%C3%A9%20ce%20contenu%20pour%20emp%C3%AAcher%20Facebook%20de%20vous%20suivre%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20a%20bloqu%C3%A9%20ce%20commentaire%20pour%20emp%C3%AAcher%20Facebook%20de%20vous%20suivre%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20a%20bloqu%C3%A9%20ces%20commentaires%20pour%20emp%C3%AAcher%20Facebook%20de%20vous%20suivre%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20a%20bloqu%C3%A9%20cette%20publication%20pour%20emp%C3%AAcher%20Facebook%20de%20vous%20pister%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20a%20bloqu%C3%A9%20cette%20vid%C3%A9o%20pour%20emp%C3%AAcher%20Facebook%20de%20vous%20pister%22,%22infoTextUnblockContent%22:%22Nous%20avons%20emp%C3%AAch%C3%A9%20Facebook%20de%20vous%20pister%20lors%20du%20chargement%20de%20la%20page.%20Si%20vous%20d%C3%A9bloquez%20ce%20contenu,%20Facebook%20conna%C3%AEtra%20votre%20activit%C3%A9.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22En%20savoir%20plus%22,%22readAbout%22:%22En%20savoir%20plus%20sur%20cette%20protection%20de%20la%20confidentialit%C3%A9%22,%22shareFeedback%22:%22Partagez%20vos%20commentaires%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Activer%20tous%20les%20aper%C3%A7us%20YouTube%C2%A0?%22,%22informationalModalMessageBody%22:%22L'affichage%20des%20aper%C3%A7us%20permettra%20%C3%A0%20Google%20(propri%C3%A9taire%20de%20YouTube)%20de%20voir%20certaines%20informations%20de%20votre%20appareil,%20mais%20cela%20reste%20davantage%20confidentiel%20qu'en%20lisant%20la%20vid%C3%A9o.%22,%22informationalModalConfirmButtonText%22:%22Activer%20tous%20les%20aper%C3%A7us%22,%22informationalModalRejectButtonText%22:%22Non%20merci%22,%22buttonTextUnblockVideo%22:%22D%C3%A9bloquer%20la%20vid%C3%A9o%20YouTube%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20a%20bloqu%C3%A9%20cette%20vid%C3%A9o%20YouTube%20pour%20emp%C3%AAcher%20Google%20de%20vous%20pister%22,%22infoTextUnblockVideo%22:%22Nous%20avons%20emp%C3%AAch%C3%A9%20Google%20(propri%C3%A9taire%20de%20YouTube)%20de%20vous%20pister%20lors%20du%20chargement%20de%20la%20page.%20Si%20vous%20d%C3%A9bloquez%20cette%20vid%C3%A9o,%20Google%20conna%C3%AEtra%20votre%20activit%C3%A9.%22,%22infoPreviewToggleText%22:%22Aper%C3%A7us%20d%C3%A9sactiv%C3%A9s%20pour%20plus%20de%20confidentialit%C3%A9%22,%22infoPreviewToggleEnabledText%22:%22Aper%C3%A7us%20activ%C3%A9s%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22Les%20aper%C3%A7us%20YouTube%20sont%20activ%C3%A9s%20dans%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EEn%20savoir%20plus%3C/a%3E%20sur%20la%20protection%20int%C3%A9gr%C3%A9e%20DuckDuckGo%20des%20r%C3%A9seaux%20sociaux%22%7D%7D,%22hr%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Prijava%20putem%20Facebooka%20omogu%C4%87uje%20im%20da%20te%20prate%22,%22informationalModalMessageBody%22:%22Nakon%20%C5%A1to%20se%20prijavi%C5%A1,%20DuckDuckGo%20ne%20mo%C5%BEe%20blokirati%20Facebookov%20sadr%C5%BEaj%20da%20te%20prati%20na%20Facebooku.%22,%22informationalModalConfirmButtonText%22:%22Prijavljivanje%22,%22informationalModalRejectButtonText%22:%22Vrati%20se%22,%22loginButtonText%22:%22Prijavi%20se%20putem%20Facebooka%22,%22loginBodyText%22:%22Facebook%20prati%20tvoju%20aktivnost%20na%20toj%20web%20lokaciji%20kad%20je%20koristi%C5%A1%20za%20prijavu.%22,%22buttonTextUnblockContent%22:%22Deblokiraj%20sadr%C5%BEaj%20na%20Facebooku%22,%22buttonTextUnblockComment%22:%22Deblokiraj%20komentar%20na%20Facebooku%22,%22buttonTextUnblockComments%22:%22Deblokiraj%20komentare%20na%20Facebooku%22,%22buttonTextUnblockPost%22:%22Deblokiraj%20objavu%20na%20Facebooku%22,%22buttonTextUnblockVideo%22:%22Deblokiraj%20videozapis%20na%20Facebooku%22,%22buttonTextUnblockLogin%22:%22Deblokiraj%20prijavu%20na%20Facebook%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20je%20blokirao%20ovaj%20sadr%C5%BEaj%20kako%20bi%20sprije%C4%8Dio%20Facebook%20da%20te%20prati%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20je%20blokirao%20ovaj%20komentar%20kako%20bi%20sprije%C4%8Dio%20Facebook%20da%20te%20prati%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20je%20blokirao%20ove%20komentare%20kako%20bi%20sprije%C4%8Dio%20Facebook%20da%20te%20prati%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20je%20blokirao%20ovu%20objavu%20kako%20bi%20sprije%C4%8Dio%20Facebook%20da%20te%20prati%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20je%20blokirao%20ovaj%20video%20kako%20bi%20sprije%C4%8Dio%20Facebook%20da%20te%20prati%22,%22infoTextUnblockContent%22:%22Blokirali%20smo%20Facebook%20da%20te%20prati%20kad%20se%20stranica%20u%C4%8Dita.%20Ako%20deblokira%C5%A1%20ovaj%20sadr%C5%BEaj,%20Facebook%20%C4%87e%20znati%20tvoju%20aktivnost.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Saznajte%20vi%C5%A1e%22,%22readAbout%22:%22Pro%C4%8Ditaj%20vi%C5%A1e%20o%20ovoj%20za%C5%A1titi%20privatnosti%22,%22shareFeedback%22:%22Podijeli%20povratne%20informacije%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Omogu%C4%87iti%20sve%20YouTube%20pretpreglede?%22,%22informationalModalMessageBody%22:%22Prikazivanje%20pretpregleda%20omogu%C4%87it%20%C4%87e%20Googleu%20(u%20%C4%8Dijem%20je%20vlasni%C5%A1tvu%20YouTube)%20da%20vidi%20neke%20podatke%20o%20tvom%20ure%C4%91aju,%20ali%20je%20i%20dalje%20privatnija%20opcija%20od%20reprodukcije%20videozapisa.%22,%22informationalModalConfirmButtonText%22:%22Omogu%C4%87i%20sve%20pretpreglede%22,%22informationalModalRejectButtonText%22:%22Ne,%20hvala%22,%22buttonTextUnblockVideo%22:%22Deblokiraj%20YouTube%20videozapis%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20je%20blokirao%20ovaj%20YouTube%20videozapis%20kako%20bi%20sprije%C4%8Dio%20Google%20da%20te%20prati%22,%22infoTextUnblockVideo%22:%22Blokirali%20smo%20Google%20(u%20%C4%8Dijem%20je%20vlasni%C5%A1tvu%20YouTube)%20da%20te%20prati%20kad%20se%20stranica%20u%C4%8Dita.%20Ako%20deblokira%C5%A1%20ovaj%20videozapis,%20Google%20%C4%87e%20znati%20tvoju%20aktivnost.%22,%22infoPreviewToggleText%22:%22Pretpregledi%20su%20onemogu%C4%87eni%20radi%20dodatne%20privatnosti%22,%22infoPreviewToggleEnabledText%22:%22Pretpregledi%20su%20omogu%C4%87eni%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube%20pretpregledi%20omogu%C4%87eni%20su%20u%20DuckDuckGou.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3ESaznaj%20vi%C5%A1e%3C/a%3E%20o%20uklju%C4%8Denoj%20DuckDuckGo%20za%C5%A1titi%20od%20dru%C5%A1tvenih%20medija%22%7D%7D,%22hu%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22A%20Facebookkal%20val%C3%B3%20bejelentkez%C3%A9skor%20a%20Facebook%20nyomon%20k%C3%B6vethet%22,%22informationalModalMessageBody%22:%22Miut%C3%A1n%20bejelentkezel,%20a%20DuckDuckGo%20nem%20fogja%20tudni%20blokkolni%20a%20Facebook-tartalmat,%20amely%20nyomon%20k%C3%B6vet%20ezen%20az%20oldalon.%22,%22informationalModalConfirmButtonText%22:%22Bejelentkez%C3%A9s%22,%22informationalModalRejectButtonText%22:%22Visszal%C3%A9p%C3%A9s%22,%22loginButtonText%22:%22Bejelentkez%C3%A9s%20Facebookkal%22,%22loginBodyText%22:%22Ha%20a%20Facebookkal%20jelentkezel%20be,%20nyomon%20k%C3%B6vetik%20a%20webhelyen%20v%C3%A9gzett%20tev%C3%A9kenys%C3%A9gedet.%22,%22buttonTextUnblockContent%22:%22Facebook-tartalom%20felold%C3%A1sa%22,%22buttonTextUnblockComment%22:%22Facebook-hozz%C3%A1sz%C3%B3l%C3%A1s%20felold%C3%A1sa%22,%22buttonTextUnblockComments%22:%22Facebook-hozz%C3%A1sz%C3%B3l%C3%A1sok%20felold%C3%A1sa%22,%22buttonTextUnblockPost%22:%22Facebook-bejegyz%C3%A9s%20felold%C3%A1sa%22,%22buttonTextUnblockVideo%22:%22Facebook-vide%C3%B3%20felold%C3%A1sa%22,%22buttonTextUnblockLogin%22:%22Facebook-bejelentkez%C3%A9s%20felold%C3%A1sa%22,%22infoTitleUnblockContent%22:%22A%20DuckDuckGo%20blokkolta%20ezt%20a%20tartalmat,%20hogy%20megakad%C3%A1lyozza%20a%20Facebookot%20a%20nyomon%20k%C3%B6vet%C3%A9sedben%22,%22infoTitleUnblockComment%22:%22A%20DuckDuckGo%20blokkolta%20ezt%20a%20hozz%C3%A1sz%C3%B3l%C3%A1st,%20hogy%20megakad%C3%A1lyozza%20a%20Facebookot%20a%20nyomon%20k%C3%B6vet%C3%A9sedben%22,%22infoTitleUnblockComments%22:%22A%20DuckDuckGo%20blokkolta%20ezeket%20a%20hozz%C3%A1sz%C3%B3l%C3%A1sokat,%20hogy%20megakad%C3%A1lyozza%20a%20Facebookot%20a%20nyomon%20k%C3%B6vet%C3%A9sedben%22,%22infoTitleUnblockPost%22:%22A%20DuckDuckGo%20blokkolta%20ezt%20a%20bejegyz%C3%A9st,%20hogy%20megakad%C3%A1lyozza%20a%20Facebookot%20a%20nyomon%20k%C3%B6vet%C3%A9sedben%22,%22infoTitleUnblockVideo%22:%22A%20DuckDuckGo%20blokkolta%20ezt%20a%20vide%C3%B3t,%20hogy%20megakad%C3%A1lyozza%20a%20Facebookot%20a%20nyomon%20k%C3%B6vet%C3%A9sedben%22,%22infoTextUnblockContent%22:%22Az%20oldal%20bet%C3%B6lt%C3%A9sekor%20blokkoltuk%20a%20Facebookot%20a%20nyomon%20k%C3%B6vet%C3%A9sedben.%20Ha%20feloldod%20ezt%20a%20tartalmat,%20a%20Facebook%20tudni%20fogja,%20hogy%20milyen%20tev%C3%A9kenys%C3%A9get%20v%C3%A9gzel.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Tov%C3%A1bbi%20r%C3%A9szletek%22,%22readAbout%22:%22Tudj%20meg%20t%C3%B6bbet%20err%C5%91l%20az%20adatv%C3%A9delemr%C5%91l%22,%22shareFeedback%22:%22Visszajelz%C3%A9s%20megoszt%C3%A1sa%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Enged%C3%A9lyezed%20minden%20YouTube-vide%C3%B3%20el%C5%91n%C3%A9zet%C3%A9t?%22,%22informationalModalMessageBody%22:%22Az%20el%C5%91n%C3%A9zetek%20megjelen%C3%ADt%C3%A9s%C3%A9vel%20a%20Google%20(a%20YouTube%20tulajdonosa)%20l%C3%A1thatja%20a%20k%C3%A9sz%C3%BCl%C3%A9k%20n%C3%A9h%C3%A1ny%20adat%C3%A1t,%20de%20ez%20adatv%C3%A9delmi%20szempontb%C3%B3l%20m%C3%A9g%20mindig%20el%C5%91ny%C3%B6sebb,%20mint%20a%20vide%C3%B3%20lej%C3%A1tsz%C3%A1sa.%22,%22informationalModalConfirmButtonText%22:%22Minden%20el%C5%91n%C3%A9zet%20enged%C3%A9lyez%C3%A9se%22,%22informationalModalRejectButtonText%22:%22Nem,%20k%C3%B6sz%C3%B6n%C3%B6m%22,%22buttonTextUnblockVideo%22:%22YouTube-vide%C3%B3%20felold%C3%A1sa%22,%22infoTitleUnblockVideo%22:%22A%20DuckDuckGo%20blokkolta%20a%20YouTube-vide%C3%B3t,%20hogy%20a%20Google%20ne%20k%C3%B6vethessen%20nyomon%22,%22infoTextUnblockVideo%22:%22Blokkoltuk,%20hogy%20a%20Google%20(a%20YouTube%20tulajdonosa)%20nyomon%20k%C3%B6vethessen%20az%20oldal%20bet%C3%B6lt%C3%A9sekor.%20Ha%20feloldod%20a%20vide%C3%B3%20blokkol%C3%A1s%C3%A1t,%20a%20Google%20tudni%20fogja,%20hogy%20milyen%20tev%C3%A9kenys%C3%A9get%20v%C3%A9gzel.%22,%22infoPreviewToggleText%22:%22Az%20el%C5%91n%C3%A9zetek%20a%20fokozott%20adatv%C3%A9delem%20%C3%A9rdek%C3%A9ben%20letiltva%22,%22infoPreviewToggleEnabledText%22:%22Az%20el%C5%91n%C3%A9zetek%20enged%C3%A9lyezve%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube-el%C5%91n%C3%A9zetek%20enged%C3%A9lyezve%20a%20DuckDuckGo-ban.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3ETov%C3%A1bbi%20tudnival%C3%B3k%3C/a%3E%20a%20DuckDuckGo%20be%C3%A1gyazott%20k%C3%B6z%C3%B6ss%C3%A9gi%20m%C3%A9dia%20elleni%20v%C3%A9delm%C3%A9r%C5%91l%22%7D%7D,%22it%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22L'accesso%20con%20Facebook%20consente%20di%20tracciarti%22,%22informationalModalMessageBody%22:%22Dopo%20aver%20effettuato%20l'accesso,%20DuckDuckGo%20non%20pu%C3%B2%20bloccare%20il%20tracciamento%20dei%20contenuti%20di%20Facebook%20su%20questo%20sito.%22,%22informationalModalConfirmButtonText%22:%22Accedi%22,%22informationalModalRejectButtonText%22:%22Torna%20indietro%22,%22loginButtonText%22:%22Accedi%20con%20Facebook%22,%22loginBodyText%22:%22Facebook%20tiene%20traccia%20della%20tua%20attivit%C3%A0%20su%20un%20sito%20quando%20lo%20usi%20per%20accedere.%22,%22buttonTextUnblockContent%22:%22Sblocca%20i%20contenuti%20di%20Facebook%22,%22buttonTextUnblockComment%22:%22Sblocca%20il%20commento%20di%20Facebook%22,%22buttonTextUnblockComments%22:%22Sblocca%20i%20commenti%20di%20Facebook%22,%22buttonTextUnblockPost%22:%22Sblocca%20post%20di%20Facebook%22,%22buttonTextUnblockVideo%22:%22Sblocca%20video%20di%20Facebook%22,%22buttonTextUnblockLogin%22:%22Sblocca%20l'accesso%20a%20Facebook%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20ha%20bloccato%20questo%20contenuto%20per%20impedire%20a%20Facebook%20di%20tracciarti%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20ha%20bloccato%20questo%20commento%20per%20impedire%20a%20Facebook%20di%20tracciarti%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20ha%20bloccato%20questi%20commenti%20per%20impedire%20a%20Facebook%20di%20tracciarti%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20ha%20bloccato%20questo%20post%20per%20impedire%20a%20Facebook%20di%20tracciarti%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20ha%20bloccato%20questo%20video%20per%20impedire%20a%20Facebook%20di%20tracciarti%22,%22infoTextUnblockContent%22:%22Abbiamo%20impedito%20a%20Facebook%20di%20tracciarti%20al%20caricamento%20della%20pagina.%20Se%20sblocchi%20questo%20contenuto,%20Facebook%20conoscer%C3%A0%20la%20tua%20attivit%C3%A0.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Ulteriori%20informazioni%22,%22readAbout%22:%22Leggi%20di%20pi%C3%B9%20su%20questa%20protezione%20della%20privacy%22,%22shareFeedback%22:%22Condividi%20feedback%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Abilitare%20tutte%20le%20anteprime%20di%20YouTube?%22,%22informationalModalMessageBody%22:%22La%20visualizzazione%20delle%20anteprime%20consentir%C3%A0%20a%20Google%20(che%20possiede%20YouTube)%20di%20vedere%20alcune%20delle%20informazioni%20del%20tuo%20dispositivo,%20ma%20%C3%A8%20comunque%20pi%C3%B9%20privato%20rispetto%20alla%20riproduzione%20del%20video.%22,%22informationalModalConfirmButtonText%22:%22Abilita%20tutte%20le%20anteprime%22,%22informationalModalRejectButtonText%22:%22No,%20grazie%22,%22buttonTextUnblockVideo%22:%22Sblocca%20video%20YouTube%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20ha%20bloccato%20questo%20video%20di%20YouTube%20per%20impedire%20a%20Google%20di%20tracciarti%22,%22infoTextUnblockVideo%22:%22Abbiamo%20impedito%20a%20Google%20(che%20possiede%20YouTube)%20di%20tracciarti%20quando%20la%20pagina%20%C3%A8%20stata%20caricata.%20Se%20sblocchi%20questo%20video,%20Google%20conoscer%C3%A0%20la%20tua%20attivit%C3%A0.%22,%22infoPreviewToggleText%22:%22Anteprime%20disabilitate%20per%20una%20maggiore%20privacy%22,%22infoPreviewToggleEnabledText%22:%22Anteprime%20abilitate%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22Anteprime%20YouTube%20abilitate%20in%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EScopri%20di%20pi%C3%B9%3C/a%3E%20sulla%20protezione%20dai%20social%20media%20integrata%20di%20DuckDuckGo%22%7D%7D,%22lt%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Prisijung%C4%99%20prie%20%E2%80%9EFacebook%E2%80%9C%20galite%20b%C5%ABti%20sekami%22,%22informationalModalMessageBody%22:%22Kai%20esate%20prisijung%C4%99,%20%E2%80%9EDuckDuckGo%E2%80%9C%20negali%20u%C5%BEblokuoti%20%E2%80%9EFacebook%E2%80%9C%20turinio,%20tod%C4%97l%20esate%20sekami%20%C5%A1ioje%20svetain%C4%97je.%22,%22informationalModalConfirmButtonText%22:%22Prisijungti%22,%22informationalModalRejectButtonText%22:%22Gr%C4%AF%C5%BEti%20atgal%22,%22loginButtonText%22:%22Prisijunkite%20su%20%E2%80%9EFacebook%E2%80%9C%22,%22loginBodyText%22:%22%E2%80%9EFacebook%E2%80%9C%20seka%20j%C5%ABs%C5%B3%20veikl%C4%85%20svetain%C4%97je,%20kai%20prisijungiate%20su%20%C5%A1ia%20svetaine.%22,%22buttonTextUnblockContent%22:%22Atblokuoti%20%E2%80%9EFacebook%E2%80%9C%20turin%C4%AF%22,%22buttonTextUnblockComment%22:%22Atblokuoti%20%E2%80%9EFacebook%E2%80%9C%20komentar%C4%85%22,%22buttonTextUnblockComments%22:%22Atblokuoti%20%E2%80%9EFacebook%E2%80%9C%20komentarus%22,%22buttonTextUnblockPost%22:%22Atblokuoti%20%E2%80%9EFacebook%E2%80%9C%20%C4%AFra%C5%A1%C4%85%22,%22buttonTextUnblockVideo%22:%22Atblokuoti%20%E2%80%9EFacebook%E2%80%9C%20vaizdo%20%C4%AFra%C5%A1%C4%85%22,%22buttonTextUnblockLogin%22:%22Atblokuoti%20%E2%80%9EFacebook%E2%80%9C%20prisijungim%C4%85%22,%22infoTitleUnblockContent%22:%22%E2%80%9EDuckDuckGo%E2%80%9C%20u%C5%BEblokavo%20%C5%A1%C4%AF%20turin%C4%AF,%20kad%20%E2%80%9EFacebook%E2%80%9C%20negal%C4%97t%C5%B3%20j%C5%ABs%C5%B3%20sekti%22,%22infoTitleUnblockComment%22:%22%E2%80%9EDuckDuckGo%E2%80%9C%20u%C5%BEblokavo%20%C5%A1%C4%AF%20komentar%C4%85,%20kad%20%E2%80%9EFacebook%E2%80%9C%20negal%C4%97t%C5%B3%20j%C5%ABs%C5%B3%20sekti%22,%22infoTitleUnblockComments%22:%22%E2%80%9EDuckDuckGo%E2%80%9C%20u%C5%BEblokavo%20%C5%A1iuos%20komentarus,%20kad%20%E2%80%9EFacebook%E2%80%9C%20negal%C4%97t%C5%B3%20j%C5%ABs%C5%B3%20sekti%22,%22infoTitleUnblockPost%22:%22%E2%80%9EDuckDuckGo%E2%80%9C%20u%C5%BEblokavo%20%C5%A1%C4%AF%20%C4%AFra%C5%A1%C4%85,%20kad%20%E2%80%9EFacebook%E2%80%9C%20negal%C4%97t%C5%B3%20j%C5%ABs%C5%B3%20sekti%22,%22infoTitleUnblockVideo%22:%22%E2%80%9EDuckDuckGo%E2%80%9C%20u%C5%BEblokavo%20%C5%A1%C4%AF%20vaizdo%20%C4%AFra%C5%A1%C4%85,%20kad%20%E2%80%9EFacebook%E2%80%9C%20negal%C4%97t%C5%B3%20j%C5%ABs%C5%B3%20sekti%22,%22infoTextUnblockContent%22:%22U%C5%BEblokavome%20%E2%80%9EFacebook%E2%80%9C,%20kad%20negal%C4%97t%C5%B3%20j%C5%ABs%C5%B3%20sekti,%20kai%20puslapis%20buvo%20%C4%AFkeltas.%20Jei%20atblokuosite%20%C5%A1%C4%AF%20turin%C4%AF,%20%E2%80%9EFacebook%E2%80%9C%20%C5%BEinos%20apie%20j%C5%ABs%C5%B3%20veikl%C4%85.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Su%C5%BEinoti%20daugiau%22,%22readAbout%22:%22Skaitykite%20apie%20%C5%A1i%C4%85%20privatumo%20apsaug%C4%85%22,%22shareFeedback%22:%22Bendrinti%20atsiliepim%C4%85%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22%C4%AEjungti%20visas%20%E2%80%9EYouTube%E2%80%9C%20per%C5%BEi%C5%ABras?%22,%22informationalModalMessageBody%22:%22Per%C5%BEi%C5%ABr%C5%B3%20rodymas%20leis%20%E2%80%9EGoogle%E2%80%9C%20(kuriai%20priklauso%20%E2%80%9EYouTube%E2%80%9C)%20matyti%20tam%20tikr%C4%85%20j%C5%ABs%C5%B3%20%C4%AFrenginio%20informacij%C4%85,%20ta%C4%8Diau%20ji%20vis%20tiek%20bus%20privatesn%C4%97%20nei%20leid%C5%BEiant%20vaizdo%20%C4%AFra%C5%A1%C4%85.%22,%22informationalModalConfirmButtonText%22:%22%C4%AEjungti%20visas%20per%C5%BEi%C5%ABras%22,%22informationalModalRejectButtonText%22:%22Ne,%20d%C4%97koju%22,%22buttonTextUnblockVideo%22:%22Atblokuoti%20%E2%80%9EYouTube%E2%80%9C%20vaizdo%20%C4%AFra%C5%A1%C4%85%22,%22infoTitleUnblockVideo%22:%22%E2%80%9EDuckDuckGo%E2%80%9C%20u%C5%BEblokavo%20%C5%A1%C4%AF%20%E2%80%9EYouTube%E2%80%9C%20vaizdo%20%C4%AFra%C5%A1%C4%85,%20kad%20%E2%80%9EGoogle%E2%80%9C%20negal%C4%97t%C5%B3%20j%C5%ABs%C5%B3%20sekti%22,%22infoTextUnblockVideo%22:%22U%C5%BEblokavome%20%E2%80%9EGoogle%E2%80%9C%20(kuriai%20priklauso%20%E2%80%9EYouTube%E2%80%9C)%20galimyb%C4%99%20sekti%20jus,%20kai%20puslapis%20buvo%20%C4%AFkeltas.%20Jei%20atblokuosite%20%C5%A1%C4%AF%20vaizdo%20%C4%AFra%C5%A1%C4%85,%20%E2%80%9EGoogle%E2%80%9C%20su%C5%BEinos%20apie%20j%C5%ABs%C5%B3%20veikl%C4%85.%22,%22infoPreviewToggleText%22:%22Per%C5%BEi%C5%ABros%20i%C5%A1jungtos%20d%C4%97l%20papildomo%20privatumo%22,%22infoPreviewToggleEnabledText%22:%22Per%C5%BEi%C5%ABros%20%C4%AFjungtos%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22%E2%80%9EYouTube%E2%80%9C%20per%C5%BEi%C5%ABros%20%C4%AFjungtos%20%E2%80%9EDuckDuckGo%E2%80%9C.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3ESu%C5%BEinokite%20daugiau%3C/a%3E%20apie%20%E2%80%9EDuckDuckGo%E2%80%9C%20%C4%AFd%C4%97t%C4%85j%C4%85%20socialin%C4%97s%20%C5%BEiniasklaidos%20apsaug%C4%85%22%7D%7D,%22lv%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Ja%20pieteiksies%20ar%20Facebook,%20vi%C5%86i%20var%C4%93s%20tevi%20izsekot%22,%22informationalModalMessageBody%22:%22Kad%20tu%20piesakies,%20DuckDuckGo%20nevar%20nov%C4%93rst,%20ka%20Facebook%20saturs%20tevi%20izseko%20%C5%A1aj%C4%81%20vietn%C4%93.%22,%22informationalModalConfirmButtonText%22:%22Pieteikties%22,%22informationalModalRejectButtonText%22:%22Atgriezties%22,%22loginButtonText%22:%22Pieteikties%20ar%20Facebook%22,%22loginBodyText%22:%22Facebook%20izseko%20tavas%20aktivit%C4%81tes%20vietn%C4%93,%20kad%20esi%20pieteicies%20ar%20Facebook.%22,%22buttonTextUnblockContent%22:%22Atblo%C4%B7%C4%93t%20Facebook%20saturu%22,%22buttonTextUnblockComment%22:%22Atblo%C4%B7%C4%93t%20Facebook%20koment%C4%81ru%22,%22buttonTextUnblockComments%22:%22Atblo%C4%B7%C4%93t%20Facebook%20koment%C4%81rus%22,%22buttonTextUnblockPost%22:%22Atblo%C4%B7%C4%93t%20Facebook%20zi%C5%86u%22,%22buttonTextUnblockVideo%22:%22Atblo%C4%B7%C4%93t%20Facebook%20video%22,%22buttonTextUnblockLogin%22:%22Atblo%C4%B7%C4%93t%20Facebook%20pieteik%C5%A1anos%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20blo%C4%B7%C4%93ja%20%C5%A1o%20saturu,%20lai%20ne%C4%BCautu%20Facebook%20tevi%20izsekot%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20blo%C4%B7%C4%93ja%20%C5%A1o%20koment%C4%81ru,%20lai%20ne%C4%BCautu%20Facebook%20tevi%20izsekot%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20blo%C4%B7%C4%93ja%20%C5%A1os%20koment%C4%81rus,%20lai%20ne%C4%BCautu%20Facebook%20tevi%20izsekot%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20blo%C4%B7%C4%93ja%20%C5%A1o%20zi%C5%86u,%20lai%20ne%C4%BCautu%20Facebook%20tevi%20izsekot%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blo%C4%B7%C4%93ja%20%C5%A1o%20videoklipu,%20lai%20ne%C4%BCautu%20Facebook%20tevi%20izsekot%22,%22infoTextUnblockContent%22:%22M%C4%93s%20blo%C4%B7%C4%93j%C4%81m%20Facebook%20iesp%C4%93ju%20tevi%20izsekot,%20iel%C4%81d%C4%93jot%20lapu.%20Ja%20atblo%C4%B7%C4%93si%20%C5%A1o%20saturu,%20Facebook%20redz%C4%93s,%20ko%20tu%20dari.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Uzzin%C4%81t%20vair%C4%81k%22,%22readAbout%22:%22Lasi%20par%20%C5%A1o%20priv%C4%81tuma%20aizsardz%C4%ABbu%22,%22shareFeedback%22:%22Kop%C4%ABgot%20atsauksmi%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Vai%20iesp%C4%93jot%20visus%20YouTube%20priek%C5%A1skat%C4%ABjumus?%22,%22informationalModalMessageBody%22:%22Priek%C5%A1skat%C4%ABjumu%20r%C4%81d%C4%AB%C5%A1ana%20%C4%BCaus%20Google%20(kam%20pieder%20YouTube)%20redz%C4%93t%20da%C4%BCu%20tavas%20ier%C4%ABces%20inform%C4%81cijas,%20ta%C4%8Du%20tas%20t%C4%81pat%20ir%20priv%C4%81t%C4%81k%20par%20videoklipa%20atska%C5%86o%C5%A1anu.%22,%22informationalModalConfirmButtonText%22:%22Iesp%C4%93jot%20visus%20priek%C5%A1skat%C4%ABjumus%22,%22informationalModalRejectButtonText%22:%22N%C4%93,%20paldies%22,%22buttonTextUnblockVideo%22:%22Atblo%C4%B7%C4%93t%20YouTube%20videoklipu%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blo%C4%B7%C4%93ja%20%C5%A1o%20YouTube%20videoklipu,%20lai%20ne%C4%BCautu%20Google%20tevi%20izsekot%22,%22infoTextUnblockVideo%22:%22M%C4%93s%20ne%C4%BC%C4%81v%C4%81m%20Google%20(kam%20pieder%20YouTube)%20tevi%20izsekot,%20kad%20lapa%20tika%20iel%C4%81d%C4%93ta.%20Ja%20atblo%C4%B7%C4%93si%20%C5%A1o%20videoklipu,%20Google%20zin%C4%81s,%20ko%20tu%20dari.%22,%22infoPreviewToggleText%22:%22Priek%C5%A1skat%C4%ABjumi%20ir%20atsp%C4%93joti,%20lai%20nodro%C5%A1in%C4%81tu%20papildu%20konfidencialit%C4%81ti%22,%22infoPreviewToggleEnabledText%22:%22Priek%C5%A1skat%C4%ABjumi%20ir%20iesp%C4%93joti%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22DuckDuckGo%20iesp%C4%93joti%20YouTube%20priek%C5%A1skat%C4%ABjumi.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EUzzini%20vair%C4%81k%3C/a%3E%20par%20DuckDuckGo%20iegulto%20soci%C4%81lo%20mediju%20aizsardz%C4%ABbu%22%7D%7D,%22nb%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22N%C3%A5r%20du%20logger%20p%C3%A5%20med%20Facebook,%20kan%20de%20spore%20deg%22,%22informationalModalMessageBody%22:%22N%C3%A5r%20du%20er%20logget%20p%C3%A5,%20kan%20ikke%20DuckDuckGo%20hindre%20Facebook-innhold%20i%20%C3%A5%20spore%20deg%20p%C3%A5%20dette%20nettstedet.%22,%22informationalModalConfirmButtonText%22:%22Logg%20inn%22,%22informationalModalRejectButtonText%22:%22G%C3%A5%20tilbake%22,%22loginButtonText%22:%22Logg%20p%C3%A5%20med%20Facebook%22,%22loginBodyText%22:%22N%C3%A5r%20du%20logger%20p%C3%A5%20med%20Facebook,%20sporer%20de%20aktiviteten%20din%20p%C3%A5%20nettstedet.%22,%22buttonTextUnblockContent%22:%22Fjern%20blokkering%20av%20Facebook-innhold%22,%22buttonTextUnblockComment%22:%22Fjern%20blokkering%20av%20Facebook-kommentar%22,%22buttonTextUnblockComments%22:%22Fjern%20blokkering%20av%20Facebook-kommentarer%22,%22buttonTextUnblockPost%22:%22Fjern%20blokkering%20av%20Facebook-innlegg%22,%22buttonTextUnblockVideo%22:%22Fjern%20blokkering%20av%20Facebook-video%22,%22buttonTextUnblockLogin%22:%22Fjern%20blokkering%20av%20Facebook-p%C3%A5logging%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20blokkerte%20dette%20innholdet%20for%20%C3%A5%20hindre%20Facebook%20i%20%C3%A5%20spore%20deg%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20blokkerte%20denne%20kommentaren%20for%20%C3%A5%20hindre%20Facebook%20i%20%C3%A5%20spore%20deg%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20blokkerte%20disse%20kommentarene%20for%20%C3%A5%20hindre%20Facebook%20i%20%C3%A5%20spore%20deg%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20blokkerte%20dette%20innlegget%20for%20%C3%A5%20hindre%20Facebook%20i%20%C3%A5%20spore%20deg%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blokkerte%20denne%20videoen%20for%20%C3%A5%20hindre%20Facebook%20i%20%C3%A5%20spore%20deg%22,%22infoTextUnblockContent%22:%22Vi%20hindret%20Facebook%20i%20%C3%A5%20spore%20deg%20da%20siden%20ble%20lastet.%20Hvis%20du%20opphever%20blokkeringen%20av%20dette%20innholdet,%20f%C3%A5r%20Facebook%20vite%20om%20aktiviteten%20din.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Finn%20ut%20mer%22,%22readAbout%22:%22Les%20om%20denne%20personvernfunksjonen%22,%22shareFeedback%22:%22Del%20tilbakemelding%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Vil%20du%20aktivere%20alle%20YouTube-forh%C3%A5ndsvisninger?%22,%22informationalModalMessageBody%22:%22Forh%C3%A5ndsvisninger%20gj%C3%B8r%20det%20mulig%20for%20Google%20(som%20eier%20YouTube)%20%C3%A5%20se%20enkelte%20opplysninger%20om%20enheten%20din,%20men%20det%20er%20likevel%20mer%20privat%20enn%20%C3%A5%20spille%20av%20videoen.%22,%22informationalModalConfirmButtonText%22:%22Aktiver%20alle%20forh%C3%A5ndsvisninger%22,%22informationalModalRejectButtonText%22:%22Nei%20takk%22,%22buttonTextUnblockVideo%22:%22Fjern%20blokkering%20av%20YouTube-video%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blokkerte%20denne%20YouTube-videoen%20for%20%C3%A5%20hindre%20Google%20i%20%C3%A5%20spore%20deg%22,%22infoTextUnblockVideo%22:%22Vi%20blokkerte%20Google%20(som%20eier%20YouTube)%20mot%20%C3%A5%20spore%20deg%20da%20siden%20ble%20lastet.%20Hvis%20du%20opphever%20blokkeringen%20av%20denne%20videoen,%20f%C3%A5r%20Google%20vite%20om%20aktiviteten%20din.%22,%22infoPreviewToggleText%22:%22Forh%C3%A5ndsvisninger%20er%20deaktivert%20for%20%C3%A5%20gi%20deg%20ekstra%20personvern%22,%22infoPreviewToggleEnabledText%22:%22Forh%C3%A5ndsvisninger%20er%20aktivert%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube-forh%C3%A5ndsvisninger%20er%20aktivert%20i%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EFinn%20ut%20mer%3C/a%3E%20om%20DuckDuckGos%20innebygde%20beskyttelse%20for%20sosiale%20medier%22%7D%7D,%22nl%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Als%20je%20inlogt%20met%20Facebook,%20kunnen%20zij%20je%20volgen%22,%22informationalModalMessageBody%22:%22Als%20je%20eenmaal%20bent%20ingelogd,%20kan%20DuckDuckGo%20niet%20voorkomen%20dat%20Facebook%20je%20op%20deze%20site%20volgt.%22,%22informationalModalConfirmButtonText%22:%22Inloggen%22,%22informationalModalRejectButtonText%22:%22Terug%22,%22loginButtonText%22:%22Inloggen%20met%20Facebook%22,%22loginBodyText%22:%22Facebook%20volgt%20je%20activiteit%20op%20een%20site%20als%20je%20Facebook%20gebruikt%20om%20in%20te%20loggen.%22,%22buttonTextUnblockContent%22:%22Facebook-inhoud%20deblokkeren%22,%22buttonTextUnblockComment%22:%22Facebook-opmerkingen%20deblokkeren%22,%22buttonTextUnblockComments%22:%22Facebook-opmerkingen%20deblokkeren%22,%22buttonTextUnblockPost%22:%22Facebook-bericht%20deblokkeren%22,%22buttonTextUnblockVideo%22:%22Facebook-video%20deblokkeren%22,%22buttonTextUnblockLogin%22:%22Facebook-aanmelding%20deblokkeren%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20heeft%20deze%20inhoud%20geblokkeerd%20om%20te%20voorkomen%20dat%20Facebook%20je%20kan%20volgen%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20heeft%20deze%20opmerking%20geblokkeerd%20om%20te%20voorkomen%20dat%20Facebook%20je%20kan%20volgen%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20heeft%20deze%20opmerkingen%20geblokkeerd%20om%20te%20voorkomen%20dat%20Facebook%20je%20kan%20volgen%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20heeft%20dit%20bericht%20geblokkeerd%20om%20te%20voorkomen%20dat%20Facebook%20je%20kan%20volgen%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20heeft%20deze%20video%20geblokkeerd%20om%20te%20voorkomen%20dat%20Facebook%20je%20kan%20volgen%22,%22infoTextUnblockContent%22:%22We%20hebben%20voorkomen%20dat%20Facebook%20je%20volgde%20toen%20de%20pagina%20werd%20geladen.%20Als%20je%20deze%20inhoud%20deblokkeert,%20kan%20Facebook%20je%20activiteit%20zien.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Meer%20informatie%22,%22readAbout%22:%22Lees%20meer%20over%20deze%20privacybescherming%22,%22shareFeedback%22:%22Feedback%20delen%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Alle%20YouTube-voorbeelden%20inschakelen?%22,%22informationalModalMessageBody%22:%22Bij%20het%20tonen%20van%20voorbeelden%20kan%20Google%20(eigenaar%20van%20YouTube)%20een%20deel%20van%20de%20informatie%20over%20je%20apparaat%20zien,%20maar%20blijft%20je%20privacy%20beter%20beschermd%20dan%20als%20je%20de%20video%20zou%20afspelen.%22,%22informationalModalConfirmButtonText%22:%22Alle%20voorbeelden%20inschakelen%22,%22informationalModalRejectButtonText%22:%22Nee,%20bedankt%22,%22buttonTextUnblockVideo%22:%22YouTube-video%20deblokkeren%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20heeft%20deze%20YouTube-video%20geblokkeerd%20om%20te%20voorkomen%20dat%20Google%20je%20kan%20volgen%22,%22infoTextUnblockVideo%22:%22We%20hebben%20voorkomen%20dat%20Google%20(eigenaar%20van%20YouTube)%20je%20volgde%20toen%20de%20pagina%20werd%20geladen.%20Als%20je%20deze%20video%20deblokkeert,%20kan%20Google%20je%20activiteit%20zien.%22,%22infoPreviewToggleText%22:%22Voorbeelden%20uitgeschakeld%20voor%20extra%20privacy%22,%22infoPreviewToggleEnabledText%22:%22Voorbeelden%20ingeschakeld%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube-voorbeelden%20ingeschakeld%20in%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EMeer%20informatie%3C/a%3E%20over%20DuckDuckGo's%20bescherming%20tegen%20ingesloten%20social%20media%22%7D%7D,%22pl%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Je%C5%9Bli%20zalogujesz%20si%C4%99%20za%20po%C5%9Brednictwem%20Facebooka,%20b%C4%99dzie%20on%20m%C3%B3g%C5%82%20%C5%9Bledzi%C4%87%20Twoj%C4%85%20aktywno%C5%9B%C4%87%22,%22informationalModalMessageBody%22:%22Po%20zalogowaniu%20si%C4%99%20DuckDuckGo%20nie%20mo%C5%BCe%20zablokowa%C4%87%20mo%C5%BCliwo%C5%9Bci%20%C5%9Bledzenia%20Ci%C4%99%20przez%20Facebooka%20na%20tej%20stronie.%22,%22informationalModalConfirmButtonText%22:%22Zaloguj%20si%C4%99%22,%22informationalModalRejectButtonText%22:%22Wr%C3%B3%C4%87%22,%22loginButtonText%22:%22Zaloguj%20si%C4%99%20za%20po%C5%9Brednictwem%20Facebooka%22,%22loginBodyText%22:%22Facebook%20%C5%9Bledzi%20Twoj%C4%85%20aktywno%C5%9B%C4%87%20na%20stronie,%20gdy%20logujesz%20si%C4%99%20za%20jego%20po%C5%9Brednictwem.%22,%22buttonTextUnblockContent%22:%22Odblokuj%20tre%C5%9B%C4%87%20na%20Facebooku%22,%22buttonTextUnblockComment%22:%22Odblokuj%20komentarz%20na%20Facebooku%22,%22buttonTextUnblockComments%22:%22Odblokuj%20komentarze%20na%20Facebooku%22,%22buttonTextUnblockPost%22:%22Odblokuj%20post%20na%20Facebooku%22,%22buttonTextUnblockVideo%22:%22Odblokuj%20wideo%20na%20Facebooku%22,%22buttonTextUnblockLogin%22:%22Odblokuj%20logowanie%20na%20Facebooku%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20zablokowa%C5%82%20t%C4%99%20tre%C5%9B%C4%87,%20aby%20Facebook%20nie%20m%C3%B3g%C5%82%20Ci%C4%99%20%C5%9Bledzi%C4%87%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20zablokowa%C5%82%20ten%20komentarz,%20aby%20Facebook%20nie%20m%C3%B3g%C5%82%20Ci%C4%99%20%C5%9Bledzi%C4%87%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20zablokowa%C5%82%20te%20komentarze,%20aby%20Facebook%20nie%20m%C3%B3g%C5%82%20Ci%C4%99%20%C5%9Bledzi%C4%87%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20zablokowa%C5%82%20ten%20post,%20aby%20Facebook%20nie%20m%C3%B3g%C5%82%20Ci%C4%99%20%C5%9Bledzi%C4%87%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20zablokowa%C5%82%20t%C4%99%20tre%C5%9B%C4%87%20wideo,%20aby%20Facebook%20nie%20m%C3%B3g%C5%82%20Ci%C4%99%20%C5%9Bledzi%C4%87.%22,%22infoTextUnblockContent%22:%22Zablokowali%C5%9Bmy%20Facebookowi%20mo%C5%BCliwo%C5%9B%C4%87%20%C5%9Bledzenia%20Ci%C4%99%20podczas%20%C5%82adowania%20strony.%20Je%C5%9Bli%20odblokujesz%20t%C4%99%20tre%C5%9B%C4%87,%20Facebook%20uzyska%20informacje%20o%20Twojej%20aktywno%C5%9Bci.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Dowiedz%20si%C4%99%20wi%C4%99cej%22,%22readAbout%22:%22Dowiedz%20si%C4%99%20wi%C4%99cej%20o%20tej%20ochronie%20prywatno%C5%9Bci%22,%22shareFeedback%22:%22Podziel%20si%C4%99%20opini%C4%85%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22W%C5%82%C4%85czy%C4%87%20wszystkie%20podgl%C4%85dy%20w%20YouTube?%22,%22informationalModalMessageBody%22:%22Wy%C5%9Bwietlanie%20podgl%C4%85du%20pozwala%20Google%20(kt%C3%B3ry%20jest%20w%C5%82a%C5%9Bcicielem%20YouTube)%20zobaczy%C4%87%20niekt%C3%B3re%20informacje%20o%20Twoim%20urz%C4%85dzeniu,%20ale%20nadal%20jest%20to%20bardziej%20prywatne%20ni%C5%BC%20odtwarzanie%20filmu.%22,%22informationalModalConfirmButtonText%22:%22W%C5%82%C4%85cz%20wszystkie%20podgl%C4%85dy%22,%22informationalModalRejectButtonText%22:%22Nie,%20dzi%C4%99kuj%C4%99%22,%22buttonTextUnblockVideo%22:%22Odblokuj%20wideo%20w%20YouTube%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20zablokowa%C5%82%20ten%20film%20w%20YouTube,%20aby%20uniemo%C5%BCliwi%C4%87%20Google%20%C5%9Bledzenie%20Twojej%20aktywno%C5%9Bci%22,%22infoTextUnblockVideo%22:%22Zablokowali%C5%9Bmy%20mo%C5%BCliwo%C5%9B%C4%87%20%C5%9Bledzenia%20Ci%C4%99%20przez%20Google%20(w%C5%82a%C5%9Bciciela%20YouTube)%20podczas%20%C5%82adowania%20strony.%20Je%C5%9Bli%20odblokujesz%20ten%20film,%20Google%20zobaczy%20Twoj%C4%85%20aktywno%C5%9B%C4%87.%22,%22infoPreviewToggleText%22:%22Podgl%C4%85dy%20zosta%C5%82y%20wy%C5%82%C4%85czone,%20aby%20zapewni%C4%87%20wi%C4%99ksz%C4%85%20ptywatno%C5%9B%C4%87%22,%22infoPreviewToggleEnabledText%22:%22Podgl%C4%85dy%20w%C5%82%C4%85czone%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22Podgl%C4%85dy%20YouTube%20w%C5%82%C4%85czone%20w%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EDowiedz%20si%C4%99%20wi%C4%99cej%3C/a%3E%20o%20zabezpieczeniu%20osadzonych%20tre%C5%9Bci%20spo%C5%82eczno%C5%9Bciowych%20DuckDuckGo%22%7D%7D,%22pt%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Iniciar%20sess%C3%A3o%20no%20Facebook%20permite%20que%20este%20te%20rastreie%22,%22informationalModalMessageBody%22:%22Depois%20de%20iniciares%20sess%C3%A3o,%20o%20DuckDuckGo%20n%C3%A3o%20poder%C3%A1%20bloquear%20o%20rastreio%20por%20parte%20do%20conte%C3%BAdo%20do%20Facebook%20neste%20site.%22,%22informationalModalConfirmButtonText%22:%22Iniciar%20sess%C3%A3o%22,%22informationalModalRejectButtonText%22:%22Retroceder%22,%22loginButtonText%22:%22Iniciar%20sess%C3%A3o%20com%20o%20Facebook%22,%22loginBodyText%22:%22O%20Facebook%20rastreia%20a%20tua%20atividade%20num%20site%20quando%20o%20usas%20para%20iniciares%20sess%C3%A3o.%22,%22buttonTextUnblockContent%22:%22Desbloquear%20Conte%C3%BAdo%20do%20Facebook%22,%22buttonTextUnblockComment%22:%22Desbloquear%20Coment%C3%A1rio%20do%20Facebook%22,%22buttonTextUnblockComments%22:%22Desbloquear%20Coment%C3%A1rios%20do%20Facebook%22,%22buttonTextUnblockPost%22:%22Desbloquear%20Publica%C3%A7%C3%A3o%20no%20Facebook%22,%22buttonTextUnblockVideo%22:%22Desbloquear%20V%C3%ADdeo%20do%20Facebook%22,%22buttonTextUnblockLogin%22:%22Desbloquear%20In%C3%ADcio%20de%20Sess%C3%A3o%20no%20Facebook%22,%22infoTitleUnblockContent%22:%22O%20DuckDuckGo%20bloqueou%20este%20conte%C3%BAdo%20para%20evitar%20que%20o%20Facebook%20te%20rastreie%22,%22infoTitleUnblockComment%22:%22O%20DuckDuckGo%20bloqueou%20este%20coment%C3%A1rio%20para%20evitar%20que%20o%20Facebook%20te%20rastreie%22,%22infoTitleUnblockComments%22:%22O%20DuckDuckGo%20bloqueou%20estes%20coment%C3%A1rios%20para%20evitar%20que%20o%20Facebook%20te%20rastreie%22,%22infoTitleUnblockPost%22:%22O%20DuckDuckGo%20bloqueou%20esta%20publica%C3%A7%C3%A3o%20para%20evitar%20que%20o%20Facebook%20te%20rastreie%22,%22infoTitleUnblockVideo%22:%22O%20DuckDuckGo%20bloqueou%20este%20v%C3%ADdeo%20para%20evitar%20que%20o%20Facebook%20te%20rastreie%22,%22infoTextUnblockContent%22:%22Bloque%C3%A1mos%20o%20rastreio%20por%20parte%20do%20Facebook%20quando%20a%20p%C3%A1gina%20foi%20carregada.%20Se%20desbloqueares%20este%20conte%C3%BAdo,%20o%20Facebook%20fica%20a%20saber%20a%20tua%20atividade.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Saiba%20mais%22,%22readAbout%22:%22Ler%20mais%20sobre%20esta%20prote%C3%A7%C3%A3o%20de%20privacidade%22,%22shareFeedback%22:%22Partilhar%20coment%C3%A1rios%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Ativar%20todas%20as%20pr%C3%A9-visualiza%C3%A7%C3%B5es%20do%20YouTube?%22,%22informationalModalMessageBody%22:%22Mostrar%20visualiza%C3%A7%C3%B5es%20permite%20%C3%A0%20Google%20(que%20det%C3%A9m%20o%20YouTube)%20ver%20algumas%20das%20informa%C3%A7%C3%B5es%20do%20teu%20dispositivo,%20mas%20ainda%20%C3%A9%20mais%20privado%20do%20que%20reproduzir%20o%20v%C3%ADdeo.%22,%22informationalModalConfirmButtonText%22:%22Ativar%20todas%20as%20pr%C3%A9-visualiza%C3%A7%C3%B5es%22,%22informationalModalRejectButtonText%22:%22N%C3%A3o,%20obrigado%22,%22buttonTextUnblockVideo%22:%22Desbloquear%20V%C3%ADdeo%20do%20YouTube%22,%22infoTitleUnblockVideo%22:%22O%20DuckDuckGo%20bloqueou%20este%20v%C3%ADdeo%20do%20YouTube%20para%20impedir%20que%20a%20Google%20te%20rastreie%22,%22infoTextUnblockVideo%22:%22Bloque%C3%A1mos%20o%20rastreio%20por%20parte%20da%20Google%20(que%20det%C3%A9m%20o%20YouTube)%20quando%20a%20p%C3%A1gina%20foi%20carregada.%20Se%20desbloqueares%20este%20v%C3%ADdeo,%20a%20Google%20fica%20a%20saber%20a%20tua%20atividade.%22,%22infoPreviewToggleText%22:%22Pr%C3%A9-visualiza%C3%A7%C3%B5es%20desativadas%20para%20privacidade%20adicional%22,%22infoPreviewToggleEnabledText%22:%22Pr%C3%A9-visualiza%C3%A7%C3%B5es%20ativadas%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22Pr%C3%A9-visualiza%C3%A7%C3%B5es%20do%20YouTube%20ativadas%20no%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3ESaiba%20mais%3C/a%3E%20sobre%20a%20Prote%C3%A7%C3%A3o%20contra%20conte%C3%BAdos%20de%20redes%20sociais%20incorporados%20do%20DuckDuckGo%22%7D%7D,%22ro%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Conectarea%20cu%20Facebook%20%C3%AEi%20permite%20s%C4%83%20te%20urm%C4%83reasc%C4%83%22,%22informationalModalMessageBody%22:%22Odat%C4%83%20ce%20te-ai%20conectat,%20DuckDuckGo%20nu%20poate%20%C3%AEmpiedica%20con%C8%9Binutul%20Facebook%20s%C4%83%20te%20urm%C4%83reasc%C4%83%20pe%20acest%20site.%22,%22informationalModalConfirmButtonText%22:%22Autentificare%22,%22informationalModalRejectButtonText%22:%22%C3%8Enapoi%22,%22loginButtonText%22:%22Conecteaz%C4%83-te%20cu%20Facebook%22,%22loginBodyText%22:%22Facebook%20urm%C4%83re%C8%99te%20activitatea%20ta%20pe%20un%20site%20atunci%20c%C3%A2nd%20%C3%AEl%20utilizezi%20pentru%20a%20te%20conecta.%22,%22buttonTextUnblockContent%22:%22Deblocheaz%C4%83%20con%C8%9Binutul%20Facebook%22,%22buttonTextUnblockComment%22:%22Deblocheaz%C4%83%20comentariul%20de%20pe%20Facebook%22,%22buttonTextUnblockComments%22:%22Deblocheaz%C4%83%20comentariile%20de%20pe%20Facebook%22,%22buttonTextUnblockPost%22:%22Deblocheaz%C4%83%20postarea%20de%20pe%20Facebook%22,%22buttonTextUnblockVideo%22:%22Deblocheaz%C4%83%20videoclipul%20de%20pe%20Facebook%22,%22buttonTextUnblockLogin%22:%22Deblocheaz%C4%83%20conectarea%20cu%20Facebook%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20a%20blocat%20acest%20con%C8%9Binut%20pentru%20a%20%C3%AEmpiedica%20Facebook%20s%C4%83%20te%20urm%C4%83reasc%C4%83%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20a%20blocat%20acest%20comentariu%20pentru%20a%20%C3%AEmpiedica%20Facebook%20s%C4%83%20te%20urm%C4%83reasc%C4%83%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20a%20blocat%20aceste%20comentarii%20pentru%20a%20%C3%AEmpiedica%20Facebook%20s%C4%83%20te%20urm%C4%83reasc%C4%83%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20a%20blocat%20aceast%C4%83%20postare%20pentru%20a%20%C3%AEmpiedica%20Facebook%20s%C4%83%20te%20urm%C4%83reasc%C4%83%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20a%20blocat%20acest%20videoclip%20pentru%20a%20%C3%AEmpiedica%20Facebook%20s%C4%83%20te%20urm%C4%83reasc%C4%83%22,%22infoTextUnblockContent%22:%22Am%20%C3%AEmpiedicat%20Facebook%20s%C4%83%20te%20urm%C4%83reasc%C4%83%20atunci%20c%C3%A2nd%20pagina%20a%20fost%20%C3%AEnc%C4%83rcat%C4%83.%20Dac%C4%83%20deblochezi%20acest%20con%C8%9Binut,%20Facebook%20%C3%AE%C8%9Bi%20va%20cunoa%C8%99te%20activitatea.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Afl%C4%83%20mai%20multe%22,%22readAbout%22:%22Cite%C8%99te%20despre%20aceast%C4%83%20protec%C8%9Bie%20a%20confiden%C8%9Bialit%C4%83%C8%9Bii%22,%22shareFeedback%22:%22Partajeaz%C4%83%20feedback%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Activezi%20toate%20previzualiz%C4%83rile%20YouTube?%22,%22informationalModalMessageBody%22:%22Afi%C8%99area%20previzualiz%C4%83rilor%20va%20permite%20ca%20Google%20(care%20de%C8%9Bine%20YouTube)%20s%C4%83%20vad%C4%83%20unele%20dintre%20informa%C8%9Biile%20despre%20dispozitivul%20t%C4%83u,%20dar%20este%20totu%C8%99i%20mai%20privat%C4%83%20dec%C3%A2t%20redarea%20videoclipului.%22,%22informationalModalConfirmButtonText%22:%22Activeaz%C4%83%20toate%20previzualiz%C4%83rile%22,%22informationalModalRejectButtonText%22:%22Nu,%20mul%C8%9Bumesc%22,%22buttonTextUnblockVideo%22:%22Deblocheaz%C4%83%20videoclipul%20de%20pe%20YouTube%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20a%20blocat%20acest%20videoclip%20de%20pe%20YouTube%20pentru%20a%20%C3%AEmpiedica%20Google%20s%C4%83%20te%20urm%C4%83reasc%C4%83%22,%22infoTextUnblockVideo%22:%22Am%20%C3%AEmpiedicat%20Google%20(care%20de%C8%9Bine%20YouTube)%20s%C4%83%20te%20urm%C4%83reasc%C4%83%20atunci%20c%C3%A2nd%20s-a%20%C3%AEnc%C4%83rcat%20pagina.%20Dac%C4%83%20deblochezi%20acest%20videoclip,%20Google%20va%20cunoa%C8%99te%20activitatea%20ta.%22,%22infoPreviewToggleText%22:%22Previzualiz%C4%83rile%20au%20fost%20dezactivate%20pentru%20o%20confiden%C8%9Bialitate%20suplimentar%C4%83%22,%22infoPreviewToggleEnabledText%22:%22Previzualiz%C4%83ri%20activate%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22Previzualiz%C4%83rile%20YouTube%20sunt%20activate%20%C3%AEn%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EAfl%C4%83%20mai%20multe%3C/a%3E%20despre%20Protec%C8%9Bia%20integrat%C4%83%20DuckDuckGo%20pentru%20re%C8%9Belele%20sociale%22%7D%7D,%22ru%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22%D0%92%D1%85%D0%BE%D0%B4%20%D1%87%D0%B5%D1%80%D0%B5%D0%B7%20Facebook%20%D0%BF%D0%BE%D0%B7%D0%B2%D0%BE%D0%BB%D1%8F%D0%B5%D1%82%20%D1%8D%D1%82%D0%BE%D0%B9%20%D1%81%D0%BE%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9%20%D1%81%D0%B5%D1%82%D0%B8%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D1%82%D1%8C%20%D0%B2%D0%B0%D1%81%22,%22informationalModalMessageBody%22:%22%D0%9F%D0%BE%D1%81%D0%BB%D0%B5%20%D0%B2%D1%85%D0%BE%D0%B4%D0%B0%20DuckDuckGo%20%D0%BD%D0%B5%20%D1%81%D0%BC%D0%BE%D0%B6%D0%B5%D1%82%20%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%20%D0%B2%D0%B0%D1%88%D0%B8%D1%85%20%D0%B4%D0%B5%D0%B9%D1%81%D1%82%D0%B2%D0%B8%D0%B9%20%D1%81%20%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%BD%D1%82%D0%BE%D0%BC%20%D0%BD%D0%B0%20Facebook.%22,%22informationalModalConfirmButtonText%22:%22%D0%92%D0%BE%D0%B9%D1%82%D0%B8%22,%22informationalModalRejectButtonText%22:%22%D0%92%D0%B5%D1%80%D0%BD%D1%83%D1%82%D1%8C%D1%81%D1%8F%22,%22loginButtonText%22:%22%D0%92%D0%BE%D0%B9%D1%82%D0%B8%20%D1%87%D0%B5%D1%80%D0%B5%D0%B7%20Facebook%22,%22loginBodyText%22:%22%D0%9F%D1%80%D0%B8%20%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B8%20%D1%83%D1%87%D1%91%D1%82%D0%BD%D0%BE%D0%B9%20%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D0%B8%20Facebook%20%D0%B4%D0%BB%D1%8F%20%D0%B2%D1%85%D0%BE%D0%B4%D0%B0%20%D0%BD%D0%B0%20%D1%81%D0%B0%D0%B9%D1%82%D1%8B%20%D1%8D%D1%82%D0%B0%20%D1%81%D0%BE%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F%20%D1%81%D0%B5%D1%82%D1%8C%20%D1%81%D0%BC%D0%BE%D0%B6%D0%B5%D1%82%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BD%D0%B0%20%D0%BD%D0%B8%D1%85%20%D0%B2%D0%B0%D1%88%D0%B8%20%D0%B4%D0%B5%D0%B9%D1%81%D1%82%D0%B2%D0%B8%D1%8F.%22,%22buttonTextUnblockContent%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%BD%D1%82%20%D0%B8%D0%B7%20Facebook%22,%22buttonTextUnblockComment%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BA%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B9%20%D0%B8%D0%B7%20Facebook%22,%22buttonTextUnblockComments%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BA%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8%20%D0%B8%D0%B7%20Facebook%22,%22buttonTextUnblockPost%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8E%20%D0%B8%D0%B7%20Facebook%22,%22buttonTextUnblockVideo%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%20%D0%B8%D0%B7%20Facebook%22,%22buttonTextUnblockLogin%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BE%D0%BA%D0%BD%D0%BE%20%D0%B2%D1%85%D0%BE%D0%B4%D0%B0%20%D0%B2%20Facebook%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20%D0%B7%D0%B0%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BB%20%D1%8D%D1%82%D0%BE%D1%82%20%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%BD%D1%82,%20%D1%87%D1%82%D0%BE%D0%B1%D1%8B%20%D0%B2%D0%B0%D1%81%20%D0%BD%D0%B5%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D0%BB%20Facebook%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20%D0%B7%D0%B0%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BB%20%D1%8D%D1%82%D0%BE%D1%82%20%D0%BA%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B9,%20%D1%87%D1%82%D0%BE%D0%B1%D1%8B%20%D0%B2%D0%B0%D1%81%20%D0%BD%D0%B5%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D0%BB%20Facebook%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20%D0%B7%D0%B0%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BB%20%D1%8D%D1%82%D0%B8%20%D0%BA%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8,%20%D1%87%D1%82%D0%BE%D0%B1%D1%8B%20%D0%B2%D0%B0%D1%81%20%D0%BD%D0%B5%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D0%BB%20Facebook%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20%D0%B7%D0%B0%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BB%20%D1%8D%D1%82%D1%83%20%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8E,%20%D1%87%D1%82%D0%BE%D0%B1%D1%8B%20%D0%B2%D0%B0%D1%81%20%D0%BD%D0%B5%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D0%BB%20Facebook%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20%D0%B7%D0%B0%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BB%20%D1%8D%D1%82%D0%BE%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE,%20%D1%87%D1%82%D0%BE%D0%B1%D1%8B%20%D0%B2%D0%B0%D1%81%20%D0%BD%D0%B5%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D0%BB%20Facebook%22,%22infoTextUnblockContent%22:%22%D0%92%D0%BE%20%D0%B2%D1%80%D0%B5%D0%BC%D1%8F%20%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8%20%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D1%8B%20%D0%BC%D1%8B%20%D0%BF%D0%BE%D0%BC%D0%B5%D1%88%D0%B0%D0%BB%D0%B8%20Facebook%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B4%D0%B8%D1%82%D1%8C%20%D0%B2%D0%B0%D1%88%D0%B8%20%D0%B4%D0%B5%D0%B9%D1%81%D1%82%D0%B2%D0%B8%D1%8F.%20%D0%95%D1%81%D0%BB%D0%B8%20%D1%80%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D1%8D%D1%82%D0%BE%D1%82%20%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%BD%D1%82,%20Facebook%20%D1%81%D0%BC%D0%BE%D0%B6%D0%B5%D1%82%20%D1%84%D0%B8%D0%BA%D1%81%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%B2%D0%B0%D1%88%D1%83%20%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D1%81%D1%82%D1%8C.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22%D0%A3%D0%B7%D0%BD%D0%B0%D1%82%D1%8C%20%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%22,%22readAbout%22:%22%D0%9F%D0%BE%D0%B4%D1%80%D0%BE%D0%B1%D0%BD%D0%B5%D0%B5%20%D0%BE%D0%B1%20%D1%8D%D1%82%D0%BE%D0%BC%20%D0%B2%D0%B8%D0%B4%D0%B5%20%D0%B7%D0%B0%D1%89%D0%B8%D1%82%D1%8B%20%D0%BA%D0%BE%D0%BD%D1%84%D0%B8%D0%B4%D0%B5%D0%BD%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8%22,%22shareFeedback%22:%22%D0%9E%D1%81%D1%82%D0%B0%D0%B2%D1%8C%D1%82%D0%B5%20%D0%BD%D0%B0%D0%BC%20%D0%BE%D1%82%D0%B7%D1%8B%D0%B2%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22%D0%92%D0%BA%D0%BB%D1%8E%D1%87%D0%B8%D1%82%D1%8C%20%D0%BF%D1%80%D0%B5%D0%B4%D0%BF%D1%80%D0%BE%D1%81%D0%BC%D0%BE%D1%82%D1%80%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%20%D0%B8%D0%B7%20YouTube?%22,%22informationalModalMessageBody%22:%22%D0%92%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%BF%D1%80%D0%B5%D0%B4%D0%B2%D0%B0%D1%80%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%20%D0%BF%D1%80%D0%BE%D1%81%D0%BC%D0%BE%D1%82%D1%80%D0%B0%20%D0%BF%D0%BE%D0%B7%D0%B2%D0%BE%D0%BB%D0%B8%D1%82%20Google%20(%D0%B2%D0%BB%D0%B0%D0%B4%D0%B5%D0%BB%D1%8C%D1%86%D1%83%20YouTube)%20%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C%20%D0%BD%D0%B5%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D1%8B%D0%B5%20%D1%81%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D1%8F%20%D0%BE%20%D0%B2%D0%B0%D1%88%D0%B5%D0%BC%20%D1%83%D1%81%D1%82%D1%80%D0%BE%D0%B9%D1%81%D1%82%D0%B2%D0%B5,%20%D0%BE%D0%B4%D0%BD%D0%B0%D0%BA%D0%BE%20%D1%8D%D1%82%D0%BE%20%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5%20%D0%B1%D0%B5%D0%B7%D0%BE%D0%BF%D0%B0%D1%81%D0%BD%D1%8B%D0%B9%20%D0%B2%D0%B0%D1%80%D0%B8%D0%B0%D0%BD%D1%82,%20%D1%87%D0%B5%D0%BC%20%D0%B2%D0%BE%D1%81%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%20%D1%86%D0%B5%D0%BB%D0%B8%D0%BA%D0%BE%D0%BC.%22,%22informationalModalConfirmButtonText%22:%22%D0%92%D0%BA%D0%BB%D1%8E%D1%87%D0%B8%D1%82%D1%8C%20%D0%BF%D1%80%D0%B5%D0%B4%D0%BF%D1%80%D0%BE%D1%81%D0%BC%D0%BE%D1%82%D1%80%22,%22informationalModalRejectButtonText%22:%22%D0%9D%D0%B5%D1%82,%20%D1%81%D0%BF%D0%B0%D1%81%D0%B8%D0%B1%D0%BE%22,%22buttonTextUnblockVideo%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%20%D0%B8%D0%B7%20YouTube%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20%D0%B7%D0%B0%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BB%20%D1%8D%D1%82%D0%BE%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%20%D0%B8%D0%B7%20YouTube,%20%D1%87%D1%82%D0%BE%D0%B1%D1%8B%20%D0%B2%D0%B0%D1%81%20%D0%BD%D0%B5%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D0%BB%20Google%22,%22infoTextUnblockVideo%22:%22%D0%92%D0%BE%20%D0%B2%D1%80%D0%B5%D0%BC%D1%8F%20%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8%20%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D1%8B%20%D0%BC%D1%8B%20%D0%BF%D0%BE%D0%BC%D0%B5%D1%88%D0%B0%D0%BB%D0%B8%20Google%20(%D0%B2%D0%BB%D0%B0%D0%B4%D0%B5%D0%BB%D1%8C%D1%86%D1%83%20YouTube)%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B4%D0%B8%D1%82%D1%8C%20%D0%B2%D0%B0%D1%88%D0%B8%20%D0%B4%D0%B5%D0%B9%D1%81%D1%82%D0%B2%D0%B8%D1%8F.%20%D0%95%D1%81%D0%BB%D0%B8%20%D1%80%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE,%20Google%20%D1%81%D0%BC%D0%BE%D0%B6%D0%B5%D1%82%20%D1%84%D0%B8%D0%BA%D1%81%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%B2%D0%B0%D1%88%D1%83%20%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D1%81%D1%82%D1%8C.%22,%22infoPreviewToggleText%22:%22%D0%9F%D1%80%D0%B5%D0%B4%D0%B2%D0%B0%D1%80%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9%20%D0%BF%D1%80%D0%BE%D1%81%D0%BC%D0%BE%D1%82%D1%80%20%D0%BE%D1%82%D0%BA%D0%BB%D1%8E%D1%87%D1%91%D0%BD%20%D0%B4%D0%BB%D1%8F%20%D0%B4%D0%BE%D0%BF%D0%BE%D0%BB%D0%BD%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9%20%D0%B7%D0%B0%D1%89%D0%B8%D1%82%D1%8B%20%D0%BA%D0%BE%D0%BD%D1%84%D0%B8%D0%B4%D0%B5%D0%BD%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8%22,%22infoPreviewToggleEnabledText%22:%22%D0%9F%D1%80%D0%B5%D0%B4%D0%B2%D0%B0%D1%80%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9%20%D0%BF%D1%80%D0%BE%D1%81%D0%BC%D0%BE%D1%82%D1%80%20%D0%B2%D0%BA%D0%BB%D1%8E%D1%87%D1%91%D0%BD%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22%D0%92%20DuckDuckGo%20%D0%B2%D0%BA%D0%BB%D1%8E%D1%87%D1%91%D0%BD%20%D0%BF%D1%80%D0%B5%D0%B4%D0%BF%D1%80%D0%BE%D1%81%D0%BC%D0%BE%D1%82%D1%80%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%20%D0%B8%D0%B7%20YouTube.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3E%D0%9F%D0%BE%D0%B4%D1%80%D0%BE%D0%B1%D0%BD%D0%B5%D0%B5%3C/a%3E%20%D0%BE%20%D0%B7%D0%B0%D1%89%D0%B8%D1%82%D0%B5%20DuckDuckGo%20%D0%BE%D1%82%20%D0%B2%D0%BD%D0%B5%D0%B4%D1%80%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE%20%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%BD%D1%82%D0%B0%20%D1%81%D0%BE%D1%86%D1%81%D0%B5%D1%82%D0%B5%D0%B9%22%7D%7D,%22sk%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Prihl%C3%A1senie%20cez%20Facebook%20mu%20umo%C5%BEn%C3%AD%20sledova%C5%A5%20v%C3%A1s%22,%22informationalModalMessageBody%22:%22DuckDuckGo%20po%20prihl%C3%A1sen%C3%AD%20nem%C3%B4%C5%BEe%20na%20tejto%20lokalite%20zablokova%C5%A5%20sledovanie%20va%C5%A1ej%20osoby%20obsahom%20Facebooku.%22,%22informationalModalConfirmButtonText%22:%22Prihl%C3%A1si%C5%A5%20sa%22,%22informationalModalRejectButtonText%22:%22Prejs%C5%A5%20sp%C3%A4%C5%A5%22,%22loginButtonText%22:%22Prihl%C3%A1ste%20sa%20pomocou%20slu%C5%BEby%20Facebook%22,%22loginBodyText%22:%22Ke%C4%8F%20pou%C5%BEijete%20prihlasovanie%20cez%20Facebook,%20Facebook%20bude%20na%20lokalite%20sledova%C5%A5%20va%C5%A1u%20aktivitu.%22,%22buttonTextUnblockContent%22:%22Odblokova%C5%A5%20obsah%20Facebooku%22,%22buttonTextUnblockComment%22:%22Odblokova%C5%A5%20koment%C3%A1r%20na%20Facebooku%22,%22buttonTextUnblockComments%22:%22Odblokova%C5%A5%20koment%C3%A1re%20na%20Facebooku%22,%22buttonTextUnblockPost%22:%22Odblokova%C5%A5%20pr%C3%ADspevok%20na%20Facebooku%22,%22buttonTextUnblockVideo%22:%22Odblokovanie%20videa%20na%20Facebooku%22,%22buttonTextUnblockLogin%22:%22Odblokova%C5%A5%20prihl%C3%A1senie%20na%20Facebook%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20zablokoval%20tento%20obsah,%20aby%20v%C3%A1s%20Facebook%20nesledoval%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20zablokoval%20tento%20koment%C3%A1r,%20aby%20zabr%C3%A1nil%20sledovaniu%20zo%20strany%20Facebooku%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20zablokoval%20tieto%20koment%C3%A1re,%20aby%20v%C3%A1s%20Facebook%20nesledoval%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20zablokoval%20tento%20pr%C3%ADspevok,%20aby%20v%C3%A1s%20Facebook%20nesledoval%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20zablokoval%20toto%20video,%20aby%20v%C3%A1s%20Facebook%20nesledoval%22,%22infoTextUnblockContent%22:%22Pri%20na%C4%8D%C3%ADtan%C3%AD%20str%C3%A1nky%20sme%20zablokovali%20Facebook,%20aby%20v%C3%A1s%20nesledoval.%20Ak%20tento%20obsah%20odblokujete,%20Facebook%20bude%20vedie%C5%A5%20o%20va%C5%A1ej%20aktivite.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Zistite%20viac%22,%22readAbout%22:%22Pre%C4%8D%C3%ADtajte%20si%20o%20tejto%20ochrane%20s%C3%BAkromia%22,%22shareFeedback%22:%22Zdie%C4%BEa%C5%A5%20sp%C3%A4tn%C3%BA%20v%C3%A4zbu%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Chcete%20povoli%C5%A5%20v%C5%A1etky%20uk%C3%A1%C5%BEky%20zo%20slu%C5%BEby%20YouTube?%22,%22informationalModalMessageBody%22:%22Zobrazenie%20uk%C3%A1%C5%BEok%20umo%C5%BEn%C3%AD%20spolo%C4%8Dnosti%20Google%20(ktor%C3%A1%20vlastn%C3%AD%20YouTube)%20vidie%C5%A5%20niektor%C3%A9%20inform%C3%A1cie%20o%20va%C5%A1om%20zariaden%C3%AD,%20ale%20st%C3%A1le%20je%20to%20s%C3%BAkromnej%C5%A1ie%20ako%20prehr%C3%A1vanie%20videa.%22,%22informationalModalConfirmButtonText%22:%22Povoli%C5%A5%20v%C5%A1etky%20uk%C3%A1%C5%BEky%22,%22informationalModalRejectButtonText%22:%22Nie,%20%C4%8Fakujem%22,%22buttonTextUnblockVideo%22:%22Odblokova%C5%A5%20YouTube%20video%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20toto%20video%20v%20slu%C5%BEbe%20YouTube%20zablokoval%20s%20cie%C4%BEom%20pred%C3%ADs%C5%A5%20tomu,%20aby%20v%C3%A1s%20spolo%C4%8Dnos%C5%A5%20Google%20mohla%20sledova%C5%A5%22,%22infoTextUnblockVideo%22:%22Zablokovali%20sme%20pre%20spolo%C4%8Dnos%C5%A5%20Google%20(ktor%C3%A1%20vlastn%C3%AD%20YouTube),%20aby%20v%C3%A1s%20nemohla%20sledova%C5%A5,%20ke%C4%8F%20sa%20str%C3%A1nka%20na%C4%8D%C3%ADta.%20Ak%20toto%20video%20odblokujete,%20Google%20bude%20pozna%C5%A5%20va%C5%A1u%20aktivitu.%22,%22infoPreviewToggleText%22:%22Uk%C3%A1%C5%BEky%20s%C3%BA%20zak%C3%A1zan%C3%A9%20s%20cie%C4%BEom%20zv%C3%BD%C5%A1i%C5%A5%20ochranu%20s%C3%BAkromia%22,%22infoPreviewToggleEnabledText%22:%22Uk%C3%A1%C5%BEky%20s%C3%BA%20povolen%C3%A9%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22Uk%C3%A1%C5%BEky%20YouTube%20s%C3%BA%20v%20DuckDuckGo%20povolen%C3%A9.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EZ%C3%ADskajte%20viac%20inform%C3%A1ci%C3%AD%3C/a%3E%20o%20DuckDuckGo,%20vlo%C5%BEenej%20ochrane%20soci%C3%A1lnych%20m%C3%A9di%C3%AD%22%7D%7D,%22sl%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22%C4%8Ce%20se%20prijavite%20s%20Facebookom,%20vam%20Facebook%20lahko%20sledi%22,%22informationalModalMessageBody%22:%22Ko%20ste%20enkrat%20prijavljeni,%20DuckDuckGo%20ne%20more%20blokirati%20Facebookove%20vsebine,%20da%20bi%20vam%20sledila%20na%20tem%20spletnem%20mestu.%22,%22informationalModalConfirmButtonText%22:%22Prijava%22,%22informationalModalRejectButtonText%22:%22Pojdi%20nazaj%22,%22loginButtonText%22:%22Prijavite%20se%20s%20Facebookom%22,%22loginBodyText%22:%22%C4%8Ce%20se%20prijavite%20s%20Facebookom,%20bo%20nato%20spremljal%20va%C5%A1a%20dejanja%20na%20spletnem%20mestu.%22,%22buttonTextUnblockContent%22:%22Odblokiraj%20vsebino%20na%20Facebooku%22,%22buttonTextUnblockComment%22:%22Odblokiraj%20komentar%20na%20Facebooku%22,%22buttonTextUnblockComments%22:%22Odblokiraj%20komentarje%20na%20Facebooku%22,%22buttonTextUnblockPost%22:%22Odblokiraj%20objavo%20na%20Facebooku%22,%22buttonTextUnblockVideo%22:%22Odblokiraj%20videoposnetek%20na%20Facebooku%22,%22buttonTextUnblockLogin%22:%22Odblokiraj%20prijavo%20na%20Facebooku%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20je%20blokiral%20to%20vsebino,%20da%20bi%20Facebooku%20prepre%C4%8Dil%20sledenje%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20je%20blokiral%20ta%20komentar,%20da%20bi%20Facebooku%20prepre%C4%8Dil%20sledenje%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20je%20blokiral%20te%20komentarje,%20da%20bi%20Facebooku%20prepre%C4%8Dil%20sledenje%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20je%20blokiral%20to%20objavo,%20da%20bi%20Facebooku%20prepre%C4%8Dil%20sledenje%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20je%20blokiral%20ta%20videoposnetek,%20da%20bi%20Facebooku%20prepre%C4%8Dil%20sledenje%22,%22infoTextUnblockContent%22:%22Ko%20se%20je%20stran%20nalo%C5%BEila,%20smo%20Facebooku%20prepre%C4%8Dili,%20da%20bi%20vam%20sledil.%20%C4%8Ce%20to%20vsebino%20odblokirate,%20bo%20Facebook%20izvedel%20za%20va%C5%A1a%20dejanja.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Ve%C4%8D%22,%22readAbout%22:%22Preberite%20ve%C4%8D%20o%20tej%20za%C5%A1%C4%8Diti%20zasebnosti%22,%22shareFeedback%22:%22Deli%20povratne%20informacije%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22%C5%BDelite%20omogo%C4%8Diti%20vse%20YouTubove%20predoglede?%22,%22informationalModalMessageBody%22:%22Prikaz%20predogledov%20omogo%C4%8Da%20Googlu%20(ki%20je%20lastnik%20YouTuba)%20vpogled%20v%20nekatere%20podatke%20o%20napravi,%20vendar%20je%20%C5%A1e%20vedno%20bolj%20zasebno%20kot%20predvajanje%20videoposnetka.%22,%22informationalModalConfirmButtonText%22:%22Omogo%C4%8Di%20vse%20predoglede%22,%22informationalModalRejectButtonText%22:%22Ne,%20hvala%22,%22buttonTextUnblockVideo%22:%22Odblokiraj%20videoposnetek%20na%20YouTubu%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20je%20blokiral%20ta%20videoposnetek%20v%20YouTubu,%20da%20bi%20Googlu%20prepre%C4%8Dil%20sledenje%22,%22infoTextUnblockVideo%22:%22Googlu%20(ki%20je%20lastnik%20YouTuba)%20smo%20prepre%C4%8Dili,%20da%20bi%20vam%20sledil,%20ko%20se%20je%20stran%20nalo%C5%BEila.%20%C4%8Ce%20odblokirate%20ta%20videoposnetek,%20bo%20Google%20izvedel%20za%20va%C5%A1o%20dejavnost.%22,%22infoPreviewToggleText%22:%22Predogledi%20so%20zaradi%20dodatne%20zasebnosti%20onemogo%C4%8Deni%22,%22infoPreviewToggleEnabledText%22:%22Predogledi%20so%20omogo%C4%8Deni%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTubovi%20predogledi%20so%20omogo%C4%8Deni%20v%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EVe%C4%8D%3C/a%3E%20o%20vgrajeni%20za%C5%A1%C4%8Diti%20dru%C5%BEbenih%20medijev%20DuckDuckGo%22%7D%7D,%22sv%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Om%20du%20loggar%20in%20med%20Facebook%20kan%20de%20sp%C3%A5ra%20dig%22,%22informationalModalMessageBody%22:%22N%C3%A4r%20du%20v%C3%A4l%20%C3%A4r%20inloggad%20kan%20DuckDuckGo%20inte%20hindra%20Facebooks%20inneh%C3%A5ll%20fr%C3%A5n%20att%20sp%C3%A5ra%20dig%20p%C3%A5%20den%20h%C3%A4r%20webbplatsen.%22,%22informationalModalConfirmButtonText%22:%22Logga%20in%22,%22informationalModalRejectButtonText%22:%22G%C3%A5%20tillbaka%22,%22loginButtonText%22:%22Logga%20in%20med%20Facebook%22,%22loginBodyText%22:%22Facebook%20sp%C3%A5rar%20din%20aktivitet%20p%C3%A5%20en%20webbplats%20om%20du%20anv%C3%A4nder%20det%20f%C3%B6r%20att%20logga%20in.%22,%22buttonTextUnblockContent%22:%22Avblockera%20Facebook-inneh%C3%A5ll%22,%22buttonTextUnblockComment%22:%22Avblockera%20Facebook-kommentar%22,%22buttonTextUnblockComments%22:%22Avblockera%20Facebook-kommentarer%22,%22buttonTextUnblockPost%22:%22Avblockera%20Facebook-inl%C3%A4gg%22,%22buttonTextUnblockVideo%22:%22Avblockera%20Facebook-video%22,%22buttonTextUnblockLogin%22:%22Avblockera%20Facebook-inloggning%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20blockerade%20det%20h%C3%A4r%20inneh%C3%A5llet%20f%C3%B6r%20att%20f%C3%B6rhindra%20att%20Facebook%20sp%C3%A5rar%20dig%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20blockerade%20den%20h%C3%A4r%20kommentaren%20f%C3%B6r%20att%20f%C3%B6rhindra%20att%20Facebook%20sp%C3%A5rar%20dig%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20blockerade%20de%20h%C3%A4r%20kommentarerna%20f%C3%B6r%20att%20f%C3%B6rhindra%20att%20Facebook%20sp%C3%A5rar%20dig%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20blockerade%20det%20h%C3%A4r%20inl%C3%A4gget%20f%C3%B6r%20att%20f%C3%B6rhindra%20att%20Facebook%20sp%C3%A5rar%20dig%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blockerade%20den%20h%C3%A4r%20videon%20f%C3%B6r%20att%20f%C3%B6rhindra%20att%20Facebook%20sp%C3%A5rar%20dig%22,%22infoTextUnblockContent%22:%22Vi%20hindrade%20Facebook%20fr%C3%A5n%20att%20sp%C3%A5ra%20dig%20n%C3%A4r%20sidan%20l%C3%A4stes%20in.%20Om%20du%20avblockerar%20det%20h%C3%A4r%20inneh%C3%A5llet%20kommer%20Facebook%20att%20k%C3%A4nna%20till%20din%20aktivitet.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22L%C3%A4s%20mer%22,%22readAbout%22:%22L%C3%A4s%20mer%20om%20detta%20integritetsskydd%22,%22shareFeedback%22:%22Ber%C3%A4tta%20vad%20du%20tycker%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Aktivera%20alla%20f%C3%B6rhandsvisningar%20f%C3%B6r%20YouTube?%22,%22informationalModalMessageBody%22:%22Genom%20att%20visa%20f%C3%B6rhandsvisningar%20kan%20Google%20(som%20%C3%A4ger%20YouTube)%20se%20en%20del%20av%20enhetens%20information,%20men%20det%20%C3%A4r%20%C3%A4nd%C3%A5%20mer%20privat%20%C3%A4n%20att%20spela%20upp%20videon.%22,%22informationalModalConfirmButtonText%22:%22Aktivera%20alla%20f%C3%B6rhandsvisningar%22,%22informationalModalRejectButtonText%22:%22Nej%20tack%22,%22buttonTextUnblockVideo%22:%22Avblockera%20YouTube-video%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blockerade%20den%20h%C3%A4r%20YouTube-videon%20f%C3%B6r%20att%20f%C3%B6rhindra%20att%20Google%20sp%C3%A5rar%20dig%22,%22infoTextUnblockVideo%22:%22Vi%20hindrade%20Google%20(som%20%C3%A4ger%20YouTube)%20fr%C3%A5n%20att%20sp%C3%A5ra%20dig%20n%C3%A4r%20sidan%20laddades.%20Om%20du%20tar%20bort%20blockeringen%20av%20videon%20kommer%20Google%20att%20k%C3%A4nna%20till%20din%20aktivitet.%22,%22infoPreviewToggleText%22:%22F%C3%B6rhandsvisningar%20har%20inaktiverats%20f%C3%B6r%20ytterligare%20integritet%22,%22infoPreviewToggleEnabledText%22:%22F%C3%B6rhandsvisningar%20aktiverade%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube-f%C3%B6rhandsvisningar%20aktiverade%20i%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EL%C3%A4s%20mer%3C/a%3E%20om%20DuckDuckGos%20skydd%20mot%20inb%C3%A4ddade%20sociala%20medier%22%7D%7D,%22tr%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Facebook%20ile%20giri%C5%9F%20yapmak,%20sizi%20takip%20etmelerini%20sa%C4%9Flar%22,%22informationalModalMessageBody%22:%22Giri%C5%9F%20yapt%C4%B1ktan%20sonra,%20DuckDuckGo%20Facebook%20i%C3%A7eri%C4%9Finin%20sizi%20bu%20sitede%20izlemesini%20engelleyemez.%22,%22informationalModalConfirmButtonText%22:%22Oturum%20A%C3%A7%22,%22informationalModalRejectButtonText%22:%22Geri%20d%C3%B6n%22,%22loginButtonText%22:%22Facebook%20ile%20giri%C5%9F%20yap%C4%B1n%22,%22loginBodyText%22:%22Facebook,%20giri%C5%9F%20yapmak%20i%C3%A7in%20kulland%C4%B1%C4%9F%C4%B1n%C4%B1zda%20bir%20sitedeki%20etkinli%C4%9Finizi%20izler.%22,%22buttonTextUnblockContent%22:%22Facebook%20%C4%B0%C3%A7eri%C4%9Finin%20Engelini%20Kald%C4%B1r%22,%22buttonTextUnblockComment%22:%22Facebook%20Yorumunun%20Engelini%20Kald%C4%B1r%22,%22buttonTextUnblockComments%22:%22Facebook%20Yorumlar%C4%B1n%C4%B1n%20Engelini%20Kald%C4%B1r%22,%22buttonTextUnblockPost%22:%22Facebook%20G%C3%B6nderisinin%20Engelini%20Kald%C4%B1r%22,%22buttonTextUnblockVideo%22:%22Facebook%20Videosunun%20Engelini%20Kald%C4%B1r%22,%22buttonTextUnblockLogin%22:%22Facebook%20Giri%C5%9Finin%20Engelini%20Kald%C4%B1r%22,%22infoTitleUnblockContent%22:%22DuckDuckGo,%20Facebook'un%20sizi%20izlemesini%20%C3%B6nlemek%20i%C3%A7in%20bu%20i%C3%A7eri%C4%9Fi%20engelledi%22,%22infoTitleUnblockComment%22:%22DuckDuckGo,%20Facebook'un%20sizi%20izlemesini%20%C3%B6nlemek%20i%C3%A7in%20bu%20yorumu%20engelledi%22,%22infoTitleUnblockComments%22:%22DuckDuckGo,%20Facebook'un%20sizi%20izlemesini%20%C3%B6nlemek%20i%C3%A7in%20bu%20yorumlar%C4%B1%20engelledi%22,%22infoTitleUnblockPost%22:%22DuckDuckGo,%20Facebook'un%20sizi%20izlemesini%20%C3%B6nlemek%20i%C3%A7in%20bu%20g%C3%B6nderiyi%20engelledi%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo,%20Facebook'un%20sizi%20izlemesini%20%C3%B6nlemek%20i%C3%A7in%20bu%20videoyu%20engelledi%22,%22infoTextUnblockContent%22:%22Sayfa%20y%C3%BCklendi%C4%9Finde%20Facebook'un%20sizi%20izlemesini%20engelledik.%20Bu%20i%C3%A7eri%C4%9Fin%20engelini%20kald%C4%B1r%C4%B1rsan%C4%B1z%20Facebook%20etkinli%C4%9Finizi%20%C3%B6%C4%9Frenecektir.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Daha%20Fazla%20Bilgi%22,%22readAbout%22:%22Bu%20gizlilik%20korumas%C4%B1%20hakk%C4%B1nda%20bilgi%20edinin%22,%22shareFeedback%22:%22Geri%20Bildirim%20Payla%C5%9F%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22T%C3%BCm%20YouTube%20%C3%B6nizlemeleri%20etkinle%C5%9Ftirilsin%20mi?%22,%22informationalModalMessageBody%22:%22%C3%96nizlemelerin%20g%C3%B6sterilmesi%20Google'%C4%B1n%20(YouTube'un%20sahibi)%20cihaz%C4%B1n%C4%B1z%C4%B1n%20baz%C4%B1%20bilgilerini%20g%C3%B6rmesine%20izin%20verir,%20ancak%20yine%20de%20videoyu%20oynatmaktan%20daha%20%C3%B6zeldir.%22,%22informationalModalConfirmButtonText%22:%22T%C3%BCm%20%C3%96nizlemeleri%20Etkinle%C5%9Ftir%22,%22informationalModalRejectButtonText%22:%22Hay%C4%B1r%20Te%C5%9Fekk%C3%BCrler%22,%22buttonTextUnblockVideo%22:%22YouTube%20Videosunun%20Engelini%20Kald%C4%B1r%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo,%20Google'%C4%B1n%20sizi%20izlemesini%20%C3%B6nlemek%20i%C3%A7in%20bu%20YouTube%20videosunu%20engelledi%22,%22infoTextUnblockVideo%22:%22Sayfa%20y%C3%BCklendi%C4%9Finde%20Google'%C4%B1n%20(YouTube'un%20sahibi)%20sizi%20izlemesini%20engelledik.%20Bu%20videonun%20engelini%20kald%C4%B1r%C4%B1rsan%C4%B1z,%20Google%20etkinli%C4%9Finizi%20%C3%B6%C4%9Frenecektir.%22,%22infoPreviewToggleText%22:%22Ek%20gizlilik%20i%C3%A7in%20%C3%B6nizlemeler%20devre%20d%C4%B1%C5%9F%C4%B1%20b%C4%B1rak%C4%B1ld%C4%B1%22,%22infoPreviewToggleEnabledText%22:%22%C3%96nizlemeler%20etkinle%C5%9Ftirildi%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22DuckDuckGo'da%20YouTube%20%C3%B6nizlemeleri%20etkinle%C5%9Ftirildi.%22,%22infoPreviewInfoText%22:%22DuckDuckGo%20Yerle%C5%9Fik%20Sosyal%20Medya%20Korumas%C4%B1%20hakk%C4%B1nda%20%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3Edaha%20fazla%20bilgi%20edinin%3C/a%3E%22%7D%7D%7D%60;%0A%0A%20%20%20%20/*********************************************************%0A%20%20%20%20%20*%20%20Style%20Definitions%0A%20%20%20%20%20*********************************************************/%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Get%20CSS%20style%20defintions%20for%20CTL,%20using%20the%20provided%20AssetConfig%20for%20any%20non-embedded%20assets%0A%20%20%20%20%20*%20(e.g.%20fonts.)%0A%20%20%20%20%20*%20@param%20%7Bimport('../../content-feature.js').AssetConfig%7D%20%5Bassets%5D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20getStyles(assets)%20%7B%0A%20%20%20%20%20%20%20%20let%20fontStyle%20=%20'';%0A%20%20%20%20%20%20%20%20let%20regularFontFamily%20=%0A%20%20%20%20%20%20%20%20%20%20%20%20%22system,%20-apple-system,%20system-ui,%20BlinkMacSystemFont,%20'Segoe%20UI',%20Roboto,%20Helvetica,%20Arial,%20sans-serif,%20'Apple%20Color%20Emoji',%20'Segoe%20UI%20Emoji',%20'Segoe%20UI%20Symbol'%22;%0A%20%20%20%20%20%20%20%20let%20boldFontFamily%20=%20regularFontFamily;%0A%20%20%20%20%20%20%20%20if%20(assets?.regularFontUrl%20&&%20assets?.boldFontUrl)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20fontStyle%20=%20%60%0A%20%20%20%20%20%20%20%20@font-face%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-family:%20DuckDuckGoPrivacyEssentials;%0A%20%20%20%20%20%20%20%20%20%20%20%20src:%20url($%7Bassets.regularFontUrl%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20@font-face%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-family:%20DuckDuckGoPrivacyEssentialsBold;%0A%20%20%20%20%20%20%20%20%20%20%20%20font-weight:%20bold;%0A%20%20%20%20%20%20%20%20%20%20%20%20src:%20url($%7Bassets.boldFontUrl%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20regularFontFamily%20=%20'DuckDuckGoPrivacyEssentials';%0A%20%20%20%20%20%20%20%20%20%20%20%20boldFontFamily%20=%20'DuckDuckGoPrivacyEssentialsBold';%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20fontStyle,%0A%20%20%20%20%20%20%20%20%20%20%20%20darkMode:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20background:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20#111111;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20textFont:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20rgba(255,%20255,%20255,%200.9);%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonFont:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20#111111;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20linkFont:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20#7295F6;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackground:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20#5784FF;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackgroundHover:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20#557FF3;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackgroundPress:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20#3969EF;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20toggleButtonText:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20#EEEEEE;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20toggleButtonBgState:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20active:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20background:%20#5784FF;%0A%20%20%20%20%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inactive:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20background-color:%20#666666;%0A%20%20%20%20%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20lightMode:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20background:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20#FFFFFF;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20textFont:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20#222222;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonFont:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20#FFFFFF;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20linkFont:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20#3969EF;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackground:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20#3969EF;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackgroundHover:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20#2B55CA;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackgroundPress:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20#1E42A4;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20toggleButtonText:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20#666666;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20toggleButtonBgState:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20active:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20background:%20#3969EF;%0A%20%20%20%20%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inactive:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20background-color:%20#666666;%0A%20%20%20%20%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20loginMode:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackground:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20#666666;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonFont:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20#FFFFFF;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20cancelMode:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackground:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20rgba(34,%2034,%2034,%200.1);%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonFont:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20#222222;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackgroundHover:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20rgba(0,%200,%200,%200.12);%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackgroundPress:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20rgba(0,%200,%200,%200.18);%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20button:%20%60%0A%20%20%20%20%20%20%20%20border-radius:%208px;%0A%0A%20%20%20%20%20%20%20%20padding:%2011px%2022px;%0A%20%20%20%20%20%20%20%20font-weight:%20bold;%0A%20%20%20%20%20%20%20%20margin:%200px%20auto;%0A%20%20%20%20%20%20%20%20border-color:%20#3969EF;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%0A%20%20%20%20%20%20%20%20font-family:%20$%7BboldFontFamily%7D;%0A%20%20%20%20%20%20%20%20font-size:%2014px;%0A%0A%20%20%20%20%20%20%20%20position:%20relative;%0A%20%20%20%20%20%20%20%20cursor:%20pointer;%0A%20%20%20%20%20%20%20%20box-shadow:%20none;%0A%20%20%20%20%20%20%20%20z-index:%202147483646;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20circle:%20%60%0A%20%20%20%20%20%20%20%20border-radius:%2050%25;%0A%20%20%20%20%20%20%20%20width:%2018px;%0A%20%20%20%20%20%20%20%20height:%2018px;%0A%20%20%20%20%20%20%20%20background:%20#E0E0E0;%0A%20%20%20%20%20%20%20%20border:%201px%20solid%20#E0E0E0;%0A%20%20%20%20%20%20%20%20position:%20absolute;%0A%20%20%20%20%20%20%20%20top:%20-8px;%0A%20%20%20%20%20%20%20%20right:%20-8px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20loginIcon:%20%60%0A%20%20%20%20%20%20%20%20position:%20absolute;%0A%20%20%20%20%20%20%20%20top:%20-13px;%0A%20%20%20%20%20%20%20%20right:%20-10px;%0A%20%20%20%20%20%20%20%20height:%2028px;%0A%20%20%20%20%20%20%20%20width:%2028px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20rectangle:%20%60%0A%20%20%20%20%20%20%20%20width:%2012px;%0A%20%20%20%20%20%20%20%20height:%203px;%0A%20%20%20%20%20%20%20%20background:%20#666666;%0A%20%20%20%20%20%20%20%20position:%20relative;%0A%20%20%20%20%20%20%20%20top:%2042.5%25;%0A%20%20%20%20%20%20%20%20margin:%20auto;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20textBubble:%20%60%0A%20%20%20%20%20%20%20%20background:%20#FFFFFF;%0A%20%20%20%20%20%20%20%20border:%201px%20solid%20rgba(0,%200,%200,%200.1);%0A%20%20%20%20%20%20%20%20border-radius:%2016px;%0A%20%20%20%20%20%20%20%20box-shadow:%200px%202px%206px%20rgba(0,%200,%200,%200.12),%200px%208px%2016px%20rgba(0,%200,%200,%200.08);%0A%20%20%20%20%20%20%20%20width:%20360px;%0A%20%20%20%20%20%20%20%20margin-top:%2010px;%0A%20%20%20%20%20%20%20%20z-index:%202147483647;%0A%20%20%20%20%20%20%20%20position:%20absolute;%0A%20%20%20%20%20%20%20%20line-height:%20normal;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20textBubbleWidth:%20360,%20//%20Should%20match%20the%20width%20rule%20in%20textBubble%0A%20%20%20%20%20%20%20%20%20%20%20%20textBubbleLeftShift:%20100,%20//%20Should%20match%20the%20CSS%20left:%20rule%20in%20textBubble%0A%20%20%20%20%20%20%20%20%20%20%20%20textArrow:%20%60%0A%20%20%20%20%20%20%20%20display:%20inline-block;%0A%20%20%20%20%20%20%20%20background:%20#FFFFFF;%0A%20%20%20%20%20%20%20%20border:%20solid%20rgba(0,%200,%200,%200.1);%0A%20%20%20%20%20%20%20%20border-width:%200%201px%201px%200;%0A%20%20%20%20%20%20%20%20padding:%205px;%0A%20%20%20%20%20%20%20%20transform:%20rotate(-135deg);%0A%20%20%20%20%20%20%20%20-webkit-transform:%20rotate(-135deg);%0A%20%20%20%20%20%20%20%20position:%20relative;%0A%20%20%20%20%20%20%20%20top:%20-9px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20arrowDefaultLocationPercent:%2050,%0A%20%20%20%20%20%20%20%20%20%20%20%20hoverTextTitle:%20%60%0A%20%20%20%20%20%20%20%20padding:%200px%2012px%2012px;%0A%20%20%20%20%20%20%20%20margin-top:%20-5px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20hoverTextBody:%20%60%0A%20%20%20%20%20%20%20%20font-family:%20$%7BregularFontFamily%7D;%0A%20%20%20%20%20%20%20%20font-size:%2014px;%0A%20%20%20%20%20%20%20%20line-height:%2021px;%0A%20%20%20%20%20%20%20%20margin:%20auto;%0A%20%20%20%20%20%20%20%20padding:%2017px;%0A%20%20%20%20%20%20%20%20text-align:%20left;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20hoverContainer:%20%60%0A%20%20%20%20%20%20%20%20padding-bottom:%2010px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20buttonTextContainer:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20flex-direction:%20row;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%20%20%20%20margin:%200;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20headerRow:%20%60%0A%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20block:%20%60%0A%20%20%20%20%20%20%20%20box-sizing:%20border-box;%0A%20%20%20%20%20%20%20%20border:%201px%20solid%20rgba(0,0,0,0.1);%0A%20%20%20%20%20%20%20%20border-radius:%2012px;%0A%20%20%20%20%20%20%20%20max-width:%20600px;%0A%20%20%20%20%20%20%20%20min-height:%20300px;%0A%20%20%20%20%20%20%20%20margin:%20auto;%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20flex-direction:%20column;%0A%0A%20%20%20%20%20%20%20%20font-family:%20$%7BregularFontFamily%7D;%0A%20%20%20%20%20%20%20%20line-height:%201;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubeDialogBlock:%20%60%0A%20%20%20%20%20%20%20%20height:%20calc(100%25%20-%2030px);%0A%20%20%20%20%20%20%20%20max-width:%20initial;%0A%20%20%20%20%20%20%20%20min-height:%20initial;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20imgRow:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20flex-direction:%20column;%0A%20%20%20%20%20%20%20%20margin:%2020px%200px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20content:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20flex-direction:%20column;%0A%20%20%20%20%20%20%20%20padding:%2016px%200;%0A%20%20%20%20%20%20%20%20flex:%201%201%201px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20feedbackLink:%20%60%0A%20%20%20%20%20%20%20%20font-family:%20$%7BregularFontFamily%7D;%0A%20%20%20%20%20%20%20%20font-style:%20normal;%0A%20%20%20%20%20%20%20%20font-weight:%20400;%0A%20%20%20%20%20%20%20%20font-size:%2012px;%0A%20%20%20%20%20%20%20%20line-height:%2012px;%0A%20%20%20%20%20%20%20%20color:%20#ABABAB;%0A%20%20%20%20%20%20%20%20text-decoration:%20none;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20feedbackRow:%20%60%0A%20%20%20%20%20%20%20%20height:%2030px;%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20justify-content:%20flex-end;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20titleBox:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20padding:%2012px;%0A%20%20%20%20%20%20%20%20max-height:%2044px;%0A%20%20%20%20%20%20%20%20border-bottom:%201px%20solid;%0A%20%20%20%20%20%20%20%20border-color:%20rgba(196,%20196,%20196,%200.3);%0A%20%20%20%20%20%20%20%20margin:%200;%0A%20%20%20%20%20%20%20%20margin-bottom:%204px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20title:%20%60%0A%20%20%20%20%20%20%20%20font-family:%20$%7BregularFontFamily%7D;%0A%20%20%20%20%20%20%20%20line-height:%201.4;%0A%20%20%20%20%20%20%20%20font-size:%2014px;%0A%20%20%20%20%20%20%20%20margin:%20auto%2010px;%0A%20%20%20%20%20%20%20%20flex-basis:%20100%25;%0A%20%20%20%20%20%20%20%20height:%201.4em;%0A%20%20%20%20%20%20%20%20flex-wrap:%20wrap;%0A%20%20%20%20%20%20%20%20overflow:%20hidden;%0A%20%20%20%20%20%20%20%20text-align:%20left;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20buttonRow:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20height:%20100%25%0A%20%20%20%20%20%20%20%20flex-direction:%20row;%0A%20%20%20%20%20%20%20%20margin:%2020px%20auto%200px;%0A%20%20%20%20%20%20%20%20height:%20100%25;%0A%20%20%20%20%20%20%20%20align-items:%20flex-start;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20modalContentTitle:%20%60%0A%20%20%20%20%20%20%20%20font-family:%20$%7BboldFontFamily%7D;%0A%20%20%20%20%20%20%20%20font-size:%2017px;%0A%20%20%20%20%20%20%20%20font-weight:%20bold;%0A%20%20%20%20%20%20%20%20line-height:%2021px;%0A%20%20%20%20%20%20%20%20margin:%2010px%20auto;%0A%20%20%20%20%20%20%20%20text-align:%20center;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%20%20%20%20padding:%200px%2032px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20modalContentText:%20%60%0A%20%20%20%20%20%20%20%20font-family:%20$%7BregularFontFamily%7D;%0A%20%20%20%20%20%20%20%20font-size:%2014px;%0A%20%20%20%20%20%20%20%20line-height:%2021px;%0A%20%20%20%20%20%20%20%20margin:%200px%20auto%2014px;%0A%20%20%20%20%20%20%20%20text-align:%20center;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20modalButtonRow:%20%60%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%20%20%20%20margin:%20auto;%0A%20%20%20%20%20%20%20%20width:%20100%25;%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20flex-direction:%20column;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20modalButton:%20%60%0A%20%20%20%20%20%20%20%20width:%20100%25;%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20justify-content:%20center;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20modalIcon:%20%60%0A%20%20%20%20%20%20%20%20display:%20block;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20contentTitle:%20%60%0A%20%20%20%20%20%20%20%20font-family:%20$%7BboldFontFamily%7D;%0A%20%20%20%20%20%20%20%20font-size:%2017px;%0A%20%20%20%20%20%20%20%20font-weight:%20bold;%0A%20%20%20%20%20%20%20%20margin:%2020px%20auto%2010px;%0A%20%20%20%20%20%20%20%20padding:%200px%2030px;%0A%20%20%20%20%20%20%20%20text-align:%20center;%0A%20%20%20%20%20%20%20%20margin-top:%20auto;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20contentText:%20%60%0A%20%20%20%20%20%20%20%20font-family:%20$%7BregularFontFamily%7D;%0A%20%20%20%20%20%20%20%20font-size:%2014px;%0A%20%20%20%20%20%20%20%20line-height:%2021px;%0A%20%20%20%20%20%20%20%20padding:%200px%2040px;%0A%20%20%20%20%20%20%20%20text-align:%20center;%0A%20%20%20%20%20%20%20%20margin:%200%20auto%20auto;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20icon:%20%60%0A%20%20%20%20%20%20%20%20height:%2080px;%0A%20%20%20%20%20%20%20%20width:%2080px;%0A%20%20%20%20%20%20%20%20margin:%20auto;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20closeIcon:%20%60%0A%20%20%20%20%20%20%20%20height:%2012px;%0A%20%20%20%20%20%20%20%20width:%2012px;%0A%20%20%20%20%20%20%20%20margin:%20auto;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20closeButton:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20justify-content:%20center;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%20%20%20%20min-width:%2020px;%0A%20%20%20%20%20%20%20%20height:%2021px;%0A%20%20%20%20%20%20%20%20border:%200;%0A%20%20%20%20%20%20%20%20background:%20transparent;%0A%20%20%20%20%20%20%20%20cursor:%20pointer;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20logo:%20%60%0A%20%20%20%20%20%20%20%20flex-basis:%200%25;%0A%20%20%20%20%20%20%20%20min-width:%2020px;%0A%20%20%20%20%20%20%20%20height:%2021px;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%20%20%20%20margin:%200;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20logoImg:%20%60%0A%20%20%20%20%20%20%20%20height:%2021px;%0A%20%20%20%20%20%20%20%20width:%2021px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20loadingImg:%20%60%0A%20%20%20%20%20%20%20%20display:%20block;%0A%20%20%20%20%20%20%20%20margin:%200px%208px%200px%200px;%0A%20%20%20%20%20%20%20%20height:%2014px;%0A%20%20%20%20%20%20%20%20width:%2014px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20modal:%20%60%0A%20%20%20%20%20%20%20%20width:%20340px;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%20%20%20%20margin:%20auto;%0A%20%20%20%20%20%20%20%20background-color:%20#FFFFFF;%0A%20%20%20%20%20%20%20%20position:%20absolute;%0A%20%20%20%20%20%20%20%20top:%2050%25;%0A%20%20%20%20%20%20%20%20left:%2050%25;%0A%20%20%20%20%20%20%20%20transform:%20translate(-50%25,%20-50%25);%0A%20%20%20%20%20%20%20%20display:%20block;%0A%20%20%20%20%20%20%20%20box-shadow:%200px%201px%203px%20rgba(0,%200,%200,%200.08),%200px%202px%204px%20rgba(0,%200,%200,%200.1);%0A%20%20%20%20%20%20%20%20border-radius:%2012px;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20modalContent:%20%60%0A%20%20%20%20%20%20%20%20padding:%2024px;%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20flex-direction:%20column;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%20%20%20%20margin:%200;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20overlay:%20%60%0A%20%20%20%20%20%20%20%20height:%20100%25;%0A%20%20%20%20%20%20%20%20width:%20100%25;%0A%20%20%20%20%20%20%20%20background-color:%20#666666;%0A%20%20%20%20%20%20%20%20opacity:%20.5;%0A%20%20%20%20%20%20%20%20display:%20block;%0A%20%20%20%20%20%20%20%20position:%20fixed;%0A%20%20%20%20%20%20%20%20top:%200;%0A%20%20%20%20%20%20%20%20right:%200;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%20%20%20%20margin:%200;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20modalContainer:%20%60%0A%20%20%20%20%20%20%20%20height:%20100vh;%0A%20%20%20%20%20%20%20%20width:%20100vw;%0A%20%20%20%20%20%20%20%20box-sizing:%20border-box;%0A%20%20%20%20%20%20%20%20z-index:%202147483647;%0A%20%20%20%20%20%20%20%20display:%20block;%0A%20%20%20%20%20%20%20%20position:%20fixed;%0A%20%20%20%20%20%20%20%20border:%200;%0A%20%20%20%20%20%20%20%20margin:%200;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20headerLinkContainer:%20%60%0A%20%20%20%20%20%20%20%20flex-basis:%20100%25;%0A%20%20%20%20%20%20%20%20display:%20grid;%0A%20%20%20%20%20%20%20%20justify-content:%20flex-end;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20headerLink:%20%60%0A%20%20%20%20%20%20%20%20line-height:%201.4;%0A%20%20%20%20%20%20%20%20font-size:%2014px;%0A%20%20%20%20%20%20%20%20font-weight:%20bold;%0A%20%20%20%20%20%20%20%20font-family:%20$%7BboldFontFamily%7D;%0A%20%20%20%20%20%20%20%20text-decoration:%20none;%0A%20%20%20%20%20%20%20%20cursor:%20pointer;%0A%20%20%20%20%20%20%20%20min-width:%20100px;%0A%20%20%20%20%20%20%20%20text-align:%20end;%0A%20%20%20%20%20%20%20%20float:%20right;%0A%20%20%20%20%20%20%20%20display:%20none;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20generalLink:%20%60%0A%20%20%20%20%20%20%20%20line-height:%201.4;%0A%20%20%20%20%20%20%20%20font-size:%2014px;%0A%20%20%20%20%20%20%20%20font-weight:%20bold;%0A%20%20%20%20%20%20%20%20font-family:%20$%7BboldFontFamily%7D;%0A%20%20%20%20%20%20%20%20cursor:%20pointer;%0A%20%20%20%20%20%20%20%20text-decoration:%20none;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20wrapperDiv:%20%60%0A%20%20%20%20%20%20%20%20display:%20inline-block;%0A%20%20%20%20%20%20%20%20border:%200;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%20%20%20%20margin:%200;%0A%20%20%20%20%20%20%20%20max-width:%20600px;%0A%20%20%20%20%20%20%20%20min-height:%20300px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20toggleButtonWrapper:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%20%20%20%20cursor:%20pointer;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20toggleButton:%20%60%0A%20%20%20%20%20%20%20%20cursor:%20pointer;%0A%20%20%20%20%20%20%20%20position:%20relative;%0A%20%20%20%20%20%20%20%20width:%2030px;%0A%20%20%20%20%20%20%20%20height:%2016px;%0A%20%20%20%20%20%20%20%20margin-top:%20-3px;%0A%20%20%20%20%20%20%20%20margin:%200;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%20%20%20%20background-color:%20transparent;%0A%20%20%20%20%20%20%20%20text-align:%20left;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20toggleButtonBg:%20%60%0A%20%20%20%20%20%20%20%20right:%200;%0A%20%20%20%20%20%20%20%20width:%2030px;%0A%20%20%20%20%20%20%20%20height:%2016px;%0A%20%20%20%20%20%20%20%20overflow:%20visible;%0A%20%20%20%20%20%20%20%20border-radius:%2010px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20toggleButtonText:%20%60%0A%20%20%20%20%20%20%20%20display:%20inline-block;%0A%20%20%20%20%20%20%20%20margin:%200%200%200%207px;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20toggleButtonKnob:%20%60%0A%20%20%20%20%20%20%20%20position:%20absolute;%0A%20%20%20%20%20%20%20%20display:%20inline-block;%0A%20%20%20%20%20%20%20%20width:%2014px;%0A%20%20%20%20%20%20%20%20height:%2014px;%0A%20%20%20%20%20%20%20%20border-radius:%2010px;%0A%20%20%20%20%20%20%20%20background-color:%20#ffffff;%0A%20%20%20%20%20%20%20%20margin-top:%201px;%0A%20%20%20%20%20%20%20%20top:%20calc(50%25%20-%2014px/2%20-%201px);%0A%20%20%20%20%20%20%20%20box-shadow:%200px%200px%201px%20rgba(0,%200,%200,%200.05),%200px%201px%201px%20rgba(0,%200,%200,%200.1);%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20toggleButtonKnobState:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20active:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20right:%201px;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inactive:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20left:%201px;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20placeholderWrapperDiv:%20%60%0A%20%20%20%20%20%20%20%20position:%20relative;%0A%20%20%20%20%20%20%20%20overflow:%20hidden;%0A%20%20%20%20%20%20%20%20border-radius:%2012px;%0A%20%20%20%20%20%20%20%20box-sizing:%20border-box;%0A%20%20%20%20%20%20%20%20max-width:%20initial;%0A%20%20%20%20%20%20%20%20min-width:%20380px;%0A%20%20%20%20%20%20%20%20min-height:%20300px;%0A%20%20%20%20%20%20%20%20margin:%20auto;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubeWrapperDiv:%20%60%0A%20%20%20%20%20%20%20%20position:%20relative;%0A%20%20%20%20%20%20%20%20overflow:%20hidden;%0A%20%20%20%20%20%20%20%20max-width:%20initial;%0A%20%20%20%20%20%20%20%20min-width:%20380px;%0A%20%20%20%20%20%20%20%20min-height:%20300px;%0A%20%20%20%20%20%20%20%20height:%20100%25;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubeDialogDiv:%20%60%0A%20%20%20%20%20%20%20%20position:%20relative;%0A%20%20%20%20%20%20%20%20overflow:%20hidden;%0A%20%20%20%20%20%20%20%20border-radius:%2012px;%0A%20%20%20%20%20%20%20%20max-width:%20initial;%0A%20%20%20%20%20%20%20%20min-height:%20initial;%0A%20%20%20%20%20%20%20%20height:%20calc(100%25%20-%2030px);%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubeDialogBottomRow:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20flex-direction:%20column;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%20%20%20%20justify-content:%20flex-end;%0A%20%20%20%20%20%20%20%20margin-top:%20auto;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubePlaceholder:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20flex-direction:%20column;%0A%20%20%20%20%20%20%20%20justify-content:%20flex-start;%0A%20%20%20%20%20%20%20%20position:%20relative;%0A%20%20%20%20%20%20%20%20width:%20100%25;%0A%20%20%20%20%20%20%20%20height:%20100%25;%0A%20%20%20%20%20%20%20%20background:%20rgba(45,%2045,%2045,%200.8);%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubePreviewWrapperImg:%20%60%0A%20%20%20%20%20%20%20%20position:%20absolute;%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20justify-content:%20center;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%20%20%20%20width:%20100%25;%0A%20%20%20%20%20%20%20%20height:%20100%25;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubePreviewImg:%20%60%0A%20%20%20%20%20%20%20%20min-width:%20100%25;%0A%20%20%20%20%20%20%20%20min-height:%20100%25;%0A%20%20%20%20%20%20%20%20height:%20auto;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubeTopSection:%20%60%0A%20%20%20%20%20%20%20%20font-family:%20$%7BboldFontFamily%7D;%0A%20%20%20%20%20%20%20%20flex:%201;%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20justify-content:%20space-between;%0A%20%20%20%20%20%20%20%20position:%20relative;%0A%20%20%20%20%20%20%20%20padding:%2018px%2012px%200;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubeTitle:%20%60%0A%20%20%20%20%20%20%20%20font-size:%2014px;%0A%20%20%20%20%20%20%20%20font-weight:%20bold;%0A%20%20%20%20%20%20%20%20line-height:%2014px;%0A%20%20%20%20%20%20%20%20color:%20#FFFFFF;%0A%20%20%20%20%20%20%20%20margin:%200;%0A%20%20%20%20%20%20%20%20width:%20100%25;%0A%20%20%20%20%20%20%20%20white-space:%20nowrap;%0A%20%20%20%20%20%20%20%20overflow:%20hidden;%0A%20%20%20%20%20%20%20%20text-overflow:%20ellipsis;%0A%20%20%20%20%20%20%20%20box-sizing:%20border-box;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubePlayButtonRow:%20%60%0A%20%20%20%20%20%20%20%20flex:%202;%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%20%20%20%20justify-content:%20center;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubePlayButton:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20justify-content:%20center;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%20%20%20%20height:%2048px;%0A%20%20%20%20%20%20%20%20width:%2080px;%0A%20%20%20%20%20%20%20%20padding:%200px%2024px;%0A%20%20%20%20%20%20%20%20border-radius:%208px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubePreviewToggleRow:%20%60%0A%20%20%20%20%20%20%20%20flex:%201;%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20flex-direction:%20column;%0A%20%20%20%20%20%20%20%20justify-content:%20flex-end;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%20%20%20%20padding:%200%2012px%2018px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubePreviewToggleText:%20%60%0A%20%20%20%20%20%20%20%20color:%20#EEEEEE;%0A%20%20%20%20%20%20%20%20font-weight:%20400;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubePreviewInfoText:%20%60%0A%20%20%20%20%20%20%20%20color:%20#ABABAB;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20locale%20UI%20locale%0A%20%20%20%20%20*/%0A%20%20%20%20function%20getConfig(locale)%20%7B%0A%20%20%20%20%20%20%20%20const%20allLocales%20=%20JSON.parse(localesJSON);%0A%20%20%20%20%20%20%20%20const%20localeStrings%20=%20allLocales%5Blocale%5D%20%7C%7C%20allLocales.en;%0A%0A%20%20%20%20%20%20%20%20const%20fbStrings%20=%20localeStrings%5B'facebook.json'%5D;%0A%20%20%20%20%20%20%20%20const%20ytStrings%20=%20localeStrings%5B'youtube.json'%5D;%0A%20%20%20%20%20%20%20%20const%20sharedStrings%20=%20localeStrings%5B'shared.json'%5D;%0A%0A%20%20%20%20%20%20%20%20const%20config%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20'Facebook,%20Inc.':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20informationalModal:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20icon:%20blockedFBLogo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20messageTitle:%20fbStrings.informationalModalMessageTitle,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20messageBody:%20fbStrings.informationalModalMessageBody,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20confirmButtonText:%20fbStrings.informationalModalConfirmButtonText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20rejectButtonText:%20fbStrings.informationalModalRejectButtonText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20elementData:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Like%20Button':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-like'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'blank',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Button%20iFrames':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/plugins/like.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/v2.0/plugins/like.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/plugins/share_button.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/v2.0/plugins/share_button.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'blank',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Save%20Button':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-save'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'blank',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Share%20Button':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-share-button'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'blank',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Page%20iFrames':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/plugins/page.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/v2.0/plugins/page.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'originalElement',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Page%20Div':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-page'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'iFrame',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20targetURL:%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'https://www.facebook.com/plugins/page.php?href=data-href&tabs=data-tabs&width=data-width&height=data-height',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20urlDataAttributesToPreserve:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-href':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20required:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-tabs':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'timeline',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-height':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'500',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-width':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'500',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20styleDataAttributes:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20'data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unit:%20'px',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20height:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20'data-height',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unit:%20'px',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Comment%20iFrames':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/plugins/comment_embed.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/v2.0/plugins/comment_embed.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockComment,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockComment,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'originalElement',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Comments':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-comments',%20'fb%5C%5C:comments'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockComments,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockComments,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'allowFull',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20targetURL:%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'https://www.facebook.com/v9.0/plugins/comments.php?href=data-href&numposts=data-numposts&sdk=joey&version=v9.0&width=data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20urlDataAttributesToPreserve:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-href':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20required:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-numposts':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%2010,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-width':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'500',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Embedded%20Comment%20Div':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-comment-embed'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockComment,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockComment,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'iFrame',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20targetURL:%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'https://www.facebook.com/v9.0/plugins/comment_embed.php?href=data-href&sdk=joey&width=data-width&include_parent=data-include-parent',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20urlDataAttributesToPreserve:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-href':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20required:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-width':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'500',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-include-parent':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'false',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20styleDataAttributes:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20'data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unit:%20'px',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Post%20iFrames':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/plugins/post.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/v2.0/plugins/post.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockPost,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockPost,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'originalElement',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Posts%20Div':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-post'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockPost,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockPost,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'allowFull',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20targetURL:%20'https://www.facebook.com/v9.0/plugins/post.php?href=data-href&sdk=joey&show_text=true&width=data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20urlDataAttributesToPreserve:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-href':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20required:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-width':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'500',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20styleDataAttributes:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20'data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unit:%20'px',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20height:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20'data-height',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unit:%20'px',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fallbackAttribute:%20'data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Video%20iFrames':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/plugins/video.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/v2.0/plugins/video.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockVideo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockVideo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'originalElement',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Video':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-video'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockVideo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockVideo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'iFrame',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20targetURL:%20'https://www.facebook.com/plugins/video.php?href=data-href&show_text=true&width=data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20urlDataAttributesToPreserve:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-href':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20required:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-width':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'500',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20styleDataAttributes:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20'data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unit:%20'px',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20height:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20'data-height',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unit:%20'px',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fallbackAttribute:%20'data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Group%20iFrames':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/plugins/group.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/v2.0/plugins/group.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'originalElement',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Group':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-group'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'iFrame',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20targetURL:%20'https://www.facebook.com/plugins/group.php?href=data-href&width=data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20urlDataAttributesToPreserve:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-href':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20required:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-width':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'500',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20styleDataAttributes:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20'data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unit:%20'px',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Login%20Button':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-login-button'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'loginButton',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20icon:%20blockedFBLogo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.loginButtonText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonTextUnblockLogin:%20fbStrings.buttonTextUnblockLogin,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20popupBodyText:%20fbStrings.loginBodyText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'allowFull',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20targetURL:%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'https://www.facebook.com/v9.0/plugins/login_button.php?app_id=app_id_replace&auto_logout_link=false&button_type=continue_with&sdk=joey&size=large&use_continue_as=false&width=',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20urlDataAttributesToPreserve:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-href':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20required:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-width':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'500',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20app_id_replace:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'null',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20Youtube:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20informationalModal:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20icon:%20blockedYTVideo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20messageTitle:%20ytStrings.informationalModalMessageTitle,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20messageBody:%20ytStrings.informationalModalMessageBody,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20confirmButtonText:%20ytStrings.informationalModalConfirmButtonText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20rejectButtonText:%20ytStrings.informationalModalRejectButtonText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20elementData:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'YouTube%20embedded%20video':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//youtube.com/embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//youtube-nocookie.com/embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.youtube.com/embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.youtube-nocookie.com/embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bdata-src*='//youtube.com/embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bdata-src*='//youtube-nocookie.com/embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bdata-src*='//www.youtube.com/embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bdata-src*='//www.youtube-nocookie.com/embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'youtube-video',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20ytStrings.buttonTextUnblockVideo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20ytStrings.infoTitleUnblockVideo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20ytStrings.infoTextUnblockVideo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20previewToggleText:%20ytStrings.infoPreviewToggleText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20placeholder:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20previewToggleEnabledText:%20ytStrings.infoPreviewToggleEnabledText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20previewInfoText:%20ytStrings.infoPreviewInfoText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20previewToggleEnabledDuckDuckGoText:%20ytStrings.infoPreviewToggleEnabledText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20videoPlayIcon:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lightMode:%20videoPlayLight,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20darkMode:%20videoPlayDark,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'youtube-video',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'YouTube%20embedded%20subscription%20button':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//youtube.com/subscribe_embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//youtube-nocookie.com/subscribe_embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.youtube.com/subscribe_embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.youtube-nocookie.com/subscribe_embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bdata-src*='//youtube.com/subscribe_embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bdata-src*='//youtube-nocookie.com/subscribe_embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bdata-src*='//www.youtube.com/subscribe_embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bdata-src*='//www.youtube-nocookie.com/subscribe_embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'blank',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20return%20%7B%20config,%20sharedStrings%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20The%20following%20code%20is%20originally%20from%20https://github.com/mozilla-extensions/secure-proxy/blob/db4d1b0e2bfe0abae416bf04241916f9e4768fd2/src/commons/template.js%0A%20%20%20%20%20*/%0A%20%20%20%20class%20Template%20%7B%0A%20%20%20%20%20%20%20%20constructor(strings,%20values)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.values%20=%20values;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.strings%20=%20strings;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Escapes%20any%20occurrences%20of%20&,%20%22,%20%3C,%20%3E%20or%20/%20with%20XML%20entities.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20str%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20The%20string%20to%20escape.%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7Bstring%7D%20The%20escaped%20string.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20escapeXML(str)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20replacements%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'&':%20'&',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'%22':%20'"',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22'%22:%20''',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'%3C':%20'<',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'%3E':%20'>',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'/':%20'/',%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20String(str).replace(/%5B&%22'%3C%3E/%5D/g,%20(m)%20=%3E%20replacements%5Bm%5D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20potentiallyEscape(value)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20value%20===%20'object')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(value%20instanceof%20Array)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20value.map((val)%20=%3E%20this.potentiallyEscape(val)).join('');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20we%20are%20an%20escaped%20template%20let%20join%20call%20toString%20on%20it%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(value%20instanceof%20Template)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20value;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('Unknown%20object%20to%20escape');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.escapeXML(value);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20toString()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20result%20=%20%5B%5D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20%5Bi,%20string%5D%20of%20this.strings.entries())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result.push(string);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(i%20%3C%20this.values.length)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result.push(this.potentiallyEscape(this.values%5Bi%5D));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20result.join('');%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20html(strings,%20...values)%20%7B%0A%20%20%20%20%20%20%20%20return%20new%20Template(strings,%20values);%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20cssVars%20=%20%22:host%20%7B%5Cn%20%20%20%20/*%20Color%20palette%20*/%5Cn%20%20%20%20--ddg-shade-06:%20rgba(0,%200,%200,%200.06);%5Cn%20%20%20%20--ddg-shade-12:%20rgba(0,%200,%200,%200.12);%5Cn%20%20%20%20--ddg-shade-18:%20rgba(0,%200,%200,%200.18);%5Cn%20%20%20%20--ddg-shade-36:%20rgba(0,%200,%200,%200.36);%5Cn%20%20%20%20--ddg-shade-84:%20rgba(0,%200,%200,%200.84);%5Cn%20%20%20%20--ddg-tint-12:%20rgba(255,%20255,%20255,%200.12);%5Cn%20%20%20%20--ddg-tint-18:%20rgba(255,%20255,%20255,%200.18);%5Cn%20%20%20%20--ddg-tint-24:%20rgba(255,%20255,%20255,%200.24);%5Cn%20%20%20%20--ddg-tint-84:%20rgba(255,%20255,%20255,%200.84);%5Cn%20%20%20%20/*%20Tokens%20*/%5Cn%20%20%20%20--ddg-color-primary:%20#3969ef;%5Cn%20%20%20%20--ddg-color-bg-01:%20#ffffff;%5Cn%20%20%20%20--ddg-color-bg-02:%20#ababab;%5Cn%20%20%20%20--ddg-color-border:%20var(--ddg-shade-12);%5Cn%20%20%20%20--ddg-color-txt:%20var(--ddg-shade-84);%5Cn%20%20%20%20--ddg-color-txt-link-02:%20#ababab;%5Cn%7D%5Cn@media%20(prefers-color-scheme:%20dark)%20%7B%5Cn%20%20%20%20:host%20%7B%5Cn%20%20%20%20%20%20%20%20--ddg-color-primary:%20#7295f6;%5Cn%20%20%20%20%20%20%20%20--ddg-color-bg-01:%20#222222;%5Cn%20%20%20%20%20%20%20%20--ddg-color-bg-02:%20#444444;%5Cn%20%20%20%20%20%20%20%20--ddg-color-border:%20var(--ddg-tint-12);%5Cn%20%20%20%20%20%20%20%20--ddg-color-txt:%20var(--ddg-tint-84);%5Cn%20%20%20%20%7D%5Cn%7D%5Cn%5Cn/*%20SHARED%20STYLES%20*/%5Cn/*%20Text%20Link%20*/%5Cn.ddg-text-link%20%7B%5Cn%20%20%20%20line-height:%201.4;%5Cn%20%20%20%20font-size:%2014px;%5Cn%20%20%20%20font-weight:%20700;%5Cn%20%20%20%20cursor:%20pointer;%5Cn%20%20%20%20text-decoration:%20none;%5Cn%20%20%20%20color:%20var(--ddg-color-primary);%5Cn%7D%5Cn%5Cn/*%20Button%20*/%5Cn.DuckDuckGoButton%20%7B%5Cn%20%20%20%20border-radius:%208px;%5Cn%20%20%20%20padding:%208px%2016px;%5Cn%20%20%20%20border-color:%20var(--ddg-color-primary);%5Cn%20%20%20%20border:%20none;%5Cn%20%20%20%20min-height:%2036px;%5Cn%5Cn%20%20%20%20position:%20relative;%5Cn%20%20%20%20cursor:%20pointer;%5Cn%20%20%20%20box-shadow:%20none;%5Cn%20%20%20%20z-index:%202147483646;%5Cn%7D%5Cn.DuckDuckGoButton%20%3E%20div%20%7B%5Cn%20%20%20%20display:%20flex;%5Cn%20%20%20%20flex-direction:%20row;%5Cn%20%20%20%20align-items:%20center;%5Cn%20%20%20%20border:%20none;%5Cn%20%20%20%20padding:%200;%5Cn%20%20%20%20margin:%200;%5Cn%7D%5Cn.DuckDuckGoButton,%5Cn.DuckDuckGoButton%20%3E%20div%20%7B%5Cn%20%20%20%20font-size:%2014px;%5Cn%20%20%20%20font-family:%20DuckDuckGoPrivacyEssentialsBold;%5Cn%20%20%20%20font-weight:%20600;%5Cn%7D%5Cn.DuckDuckGoButton.tertiary%20%7B%5Cn%20%20%20%20color:%20var(--ddg-color-txt);%5Cn%20%20%20%20background-color:%20transparent;%5Cn%20%20%20%20display:%20flex;%5Cn%20%20%20%20justify-content:%20center;%5Cn%20%20%20%20align-items:%20center;%5Cn%20%20%20%20border:%201px%20solid%20var(--ddg-color-border);%5Cn%20%20%20%20border-radius:%208px;%5Cn%7D%5Cn.DuckDuckGoButton.tertiary:hover%20%7B%5Cn%20%20%20%20background:%20var(--ddg-shade-06);%5Cn%20%20%20%20border-color:%20var(--ddg-shade-18);%5Cn%7D%5Cn@media%20(prefers-color-scheme:%20dark)%20%7B%5Cn%20%20%20%20.DuckDuckGoButton.tertiary:hover%20%7B%5Cn%20%20%20%20%20%20%20%20background:%20var(--ddg-tint-18);%5Cn%20%20%20%20%20%20%20%20border-color:%20var(--ddg-tint-24);%5Cn%20%20%20%20%7D%5Cn%7D%5Cn.DuckDuckGoButton.tertiary:active%20%7B%5Cn%20%20%20%20background:%20var(--ddg-shade-12);%5Cn%20%20%20%20border-color:%20var(--ddg-shade-36);%5Cn%7D%5Cn@media%20(prefers-color-scheme:%20dark)%20%7B%5Cn%20%20%20%20.DuckDuckGoButton.tertiary:active%20%7B%5Cn%20%20%20%20%20%20%20%20background:%20var(--ddg-tint-24);%5Cn%20%20%20%20%20%20%20%20border-color:%20var(--ddg-tint-24);%5Cn%20%20%20%20%7D%5Cn%7D%5Cn%22;%0A%0A%20%20%20%20var%20css$1%20=%20%22:host,%5Cn*%20%7B%5Cn%20%20%20%20font-family:%20DuckDuckGoPrivacyEssentials,%20system,%20-apple-system,%20system-ui,%20BlinkMacSystemFont,%20'Segoe%20UI',%20Roboto,%5Cn%20%20%20%20%20%20%20%20Helvetica,%20Arial,%20sans-serif,%20'Apple%20Color%20Emoji',%20'Segoe%20UI%20Emoji',%20'Segoe%20UI%20Symbol';%5Cn%20%20%20%20box-sizing:%20border-box;%5Cn%20%20%20%20font-weight:%20normal;%5Cn%20%20%20%20font-style:%20normal;%5Cn%20%20%20%20margin:%200;%5Cn%20%20%20%20padding:%200;%5Cn%20%20%20%20text-align:%20left;%5Cn%7D%5Cn%5Cn:host,%5Cn.DuckDuckGoSocialContainer%20%7B%5Cn%20%20%20%20display:%20inline-block;%5Cn%20%20%20%20border:%200;%5Cn%20%20%20%20padding:%200;%5Cn%20%20%20%20margin:%20auto;%5Cn%20%20%20%20inset:%20initial;%5Cn%20%20%20%20max-width:%20600px;%5Cn%20%20%20%20min-height:%20180px;%5Cn%7D%5Cn%5Cn/*%20SHARED%20STYLES%20*/%5Cn/*%20Toggle%20Button%20*/%5Cn.ddg-toggle-button-container%20%7B%5Cn%20%20%20%20display:%20flex;%5Cn%20%20%20%20align-items:%20center;%5Cn%20%20%20%20cursor:%20pointer;%5Cn%7D%5Cn.ddg-toggle-button%20%7B%5Cn%20%20%20%20cursor:%20pointer;%5Cn%20%20%20%20position:%20relative;%5Cn%20%20%20%20margin-top:%20-3px;%5Cn%20%20%20%20margin:%200;%5Cn%20%20%20%20padding:%200;%5Cn%20%20%20%20border:%20none;%5Cn%20%20%20%20background-color:%20transparent;%5Cn%20%20%20%20text-align:%20left;%5Cn%7D%5Cn.ddg-toggle-button,%5Cn.ddg-toggle-button.md,%5Cn.ddg-toggle-button-bg,%5Cn.ddg-toggle-button.md%20.ddg-toggle-button-bg%20%7B%5Cn%20%20%20%20width:%2032px;%5Cn%20%20%20%20height:%2016px;%5Cn%20%20%20%20border-radius:%2020px;%5Cn%7D%5Cn.ddg-toggle-button.lg,%5Cn.ddg-toggle-button.lg%20.ddg-toggle-button-bg%20%7B%5Cn%20%20%20%20width:%2056px;%5Cn%20%20%20%20height:%2034px;%5Cn%20%20%20%20border-radius:%2050px;%5Cn%7D%5Cn.ddg-toggle-button-bg%20%7B%5Cn%20%20%20%20right:%200;%5Cn%20%20%20%20overflow:%20visible;%5Cn%7D%5Cn.ddg-toggle-button.active%20.ddg-toggle-button-bg%20%7B%5Cn%20%20%20%20background:%20var(--ddg-color-primary);%5Cn%7D%5Cn.ddg-toggle-button.inactive%20.ddg-toggle-button-bg%20%7B%5Cn%20%20%20%20background:%20var(--ddg-color-bg-02);%5Cn%7D%5Cn.ddg-toggle-button-knob%20%7B%5Cn%20%20%20%20--ddg-toggle-knob-margin:%202px;%5Cn%20%20%20%20position:%20absolute;%5Cn%20%20%20%20display:%20inline-block;%5Cn%20%20%20%20border-radius:%2050%25;%5Cn%20%20%20%20background-color:%20#ffffff;%5Cn%20%20%20%20margin-top:%20var(--ddg-toggle-knob-margin);%5Cn%7D%5Cn.ddg-toggle-button-knob,%5Cn.ddg-toggle-button.md%20.ddg-toggle-button-knob%20%7B%5Cn%20%20%20%20width:%2012px;%5Cn%20%20%20%20height:%2012px;%5Cn%20%20%20%20top:%20calc(50%25%20-%2016px%20/%202);%5Cn%7D%5Cn.ddg-toggle-button.lg%20.ddg-toggle-button-knob%20%7B%5Cn%20%20%20%20--ddg-toggle-knob-margin:%204px;%5Cn%20%20%20%20width:%2026px;%5Cn%20%20%20%20height:%2026px;%5Cn%20%20%20%20top:%20calc(50%25%20-%2034px%20/%202);%5Cn%7D%5Cn.ddg-toggle-button.active%20.ddg-toggle-button-knob%20%7B%5Cn%20%20%20%20right:%20var(--ddg-toggle-knob-margin);%5Cn%7D%5Cn.ddg-toggle-button.inactive%20.ddg-toggle-button-knob%20%7B%5Cn%20%20%20%20left:%20var(--ddg-toggle-knob-margin);%5Cn%7D%5Cn.ddg-toggle-button-label%20%7B%5Cn%20%20%20%20font-size:%2014px;%5Cn%20%20%20%20line-height:%2020px;%5Cn%20%20%20%20color:%20var(--ddg-color-txt);%5Cn%20%20%20%20margin-left:%2012px;%5Cn%7D%5Cn%5Cn/*%20Styles%20for%20DDGCtlPlaceholderBlocked%20*/%5Cn.DuckDuckGoButton.ddg-ctl-unblock-btn%20%7B%5Cn%20%20%20%20width:%20100%25;%5Cn%20%20%20%20margin:%200%20auto;%5Cn%7D%5Cn.DuckDuckGoSocialContainer:is(.size-md,%20.size-lg)%20.DuckDuckGoButton.ddg-ctl-unblock-btn%20%7B%5Cn%20%20%20%20width:%20auto;%5Cn%7D%5Cn%5Cn.ddg-ctl-placeholder-card%20%7B%5Cn%20%20%20%20height:%20100%25;%5Cn%20%20%20%20overflow:%20auto;%5Cn%20%20%20%20padding:%2016px;%5Cn%20%20%20%20color:%20var(--ddg-color-txt);%5Cn%20%20%20%20background:%20var(--ddg-color-bg-01);%5Cn%20%20%20%20border:%201px%20solid%20var(--ddg-color-border);%5Cn%20%20%20%20border-radius:%2012px;%5Cn%20%20%20%20margin:%20auto;%5Cn%20%20%20%20display:%20grid;%5Cn%20%20%20%20justify-content:%20center;%5Cn%20%20%20%20align-items:%20center;%5Cn%20%20%20%20line-height:%201;%5Cn%7D%5Cn.ddg-ctl-placeholder-card.slim-card%20%7B%5Cn%20%20%20%20padding:%2012px;%5Cn%7D%5Cn.DuckDuckGoSocialContainer.size-xs%20.ddg-ctl-placeholder-card-body%20%7B%5Cn%20%20%20%20margin:%20auto;%5Cn%7D%5Cn.DuckDuckGoSocialContainer:is(.size-md,%20.size-lg)%20.ddg-ctl-placeholder-card.with-feedback-link%20%7B%5Cn%20%20%20%20height:%20calc(100%25%20-%2030px);%5Cn%20%20%20%20max-width:%20initial;%5Cn%20%20%20%20min-height:%20initial;%5Cn%7D%5Cn%5Cn.ddg-ctl-placeholder-card-header%20%7B%5Cn%20%20%20%20width:%20100%25;%5Cn%20%20%20%20display:%20flex;%5Cn%20%20%20%20align-items:%20center;%5Cn%20%20%20%20margin:%20auto;%5Cn%20%20%20%20margin-bottom:%208px;%5Cn%20%20%20%20text-align:%20left;%5Cn%7D%5Cn.DuckDuckGoSocialContainer:is(.size-md,%20.size-lg)%20.ddg-ctl-placeholder-card-header%20%7B%5Cn%20%20%20%20flex-direction:%20column;%5Cn%20%20%20%20align-items:%20center;%5Cn%20%20%20%20justify-content:%20center;%5Cn%20%20%20%20margin-bottom:%2012px;%5Cn%20%20%20%20width:%2080%25;%5Cn%20%20%20%20text-align:%20center;%5Cn%7D%5Cn%5Cn.DuckDuckGoSocialContainer:is(.size-md,%20.size-lg)%20.ddg-ctl-placeholder-card-header%20.ddg-ctl-placeholder-card-title,%5Cn.DuckDuckGoSocialContainer:is(.size-md,%20.size-lg)%20.ddg-ctl-placeholder-card-header%20.ddg-text-link%20%7B%5Cn%20%20%20%20text-align:%20center;%5Cn%7D%5Cn%5Cn/*%20Show%20Learn%20More%20link%20in%20the%20header%20on%20mobile%20and%5Cn%20*%20tablet%20size%20screens%20and%20hide%20it%20on%20desktop%20size%20*/%5Cn.DuckDuckGoSocialContainer.size-lg%20.ddg-ctl-placeholder-card-header%20.ddg-learn-more%20%7B%5Cn%20%20%20%20display:%20none;%5Cn%7D%5Cn%5Cn.ddg-ctl-placeholder-card-title,%5Cn.ddg-ctl-placeholder-card-title%20.ddg-text-link%20%7B%5Cn%20%20%20%20font-family:%20DuckDuckGoPrivacyEssentialsBold;%5Cn%20%20%20%20font-weight:%20700;%5Cn%20%20%20%20font-size:%2016px;%5Cn%20%20%20%20line-height:%2024px;%5Cn%7D%5Cn%5Cn.ddg-ctl-placeholder-card-header-dax%20%7B%5Cn%20%20%20%20align-self:%20flex-start;%5Cn%20%20%20%20width:%2048px;%5Cn%20%20%20%20height:%2048px;%5Cn%20%20%20%20margin:%200%208px%200%200;%5Cn%7D%5Cn.DuckDuckGoSocialContainer:is(.size-md,%20.size-lg)%20.ddg-ctl-placeholder-card-header-dax%20%7B%5Cn%20%20%20%20align-self:%20inherit;%5Cn%20%20%20%20margin:%200%200%2012px%200;%5Cn%7D%5Cn%5Cn.DuckDuckGoSocialContainer.size-lg%20.ddg-ctl-placeholder-card-header-dax%20%7B%5Cn%20%20%20%20width:%2056px;%5Cn%20%20%20%20height:%2056px;%5Cn%7D%5Cn%5Cn.ddg-ctl-placeholder-card-body-text%20%7B%5Cn%20%20%20%20font-size:%2016px;%5Cn%20%20%20%20line-height:%2024px;%5Cn%20%20%20%20text-align:%20center;%5Cn%20%20%20%20margin:%200%20auto%2012px;%5Cn%5Cn%20%20%20%20display:%20none;%5Cn%7D%5Cn.DuckDuckGoSocialContainer.size-lg%20.ddg-ctl-placeholder-card-body-text%20%7B%5Cn%20%20%20%20width:%2080%25;%5Cn%20%20%20%20display:%20block;%5Cn%7D%5Cn%5Cn.ddg-ctl-placeholder-card-footer%20%7B%5Cn%20%20%20%20width:%20100%25;%5Cn%20%20%20%20margin-top:%2012px;%5Cn%20%20%20%20display:%20flex;%5Cn%20%20%20%20align-items:%20center;%5Cn%20%20%20%20justify-content:%20flex-start;%5Cn%20%20%20%20align-self:%20end;%5Cn%7D%5Cn%5Cn/*%20Only%20display%20the%20unblock%20button%20on%20really%20small%20placeholders%20*/%5Cn.DuckDuckGoSocialContainer.size-xs%20.ddg-ctl-placeholder-card-header,%5Cn.DuckDuckGoSocialContainer.size-xs%20.ddg-ctl-placeholder-card-body-text,%5Cn.DuckDuckGoSocialContainer.size-xs%20.ddg-ctl-placeholder-card-footer%20%7B%5Cn%20%20%20%20display:%20none;%5Cn%7D%5Cn%5Cn.ddg-ctl-feedback-row%20%7B%5Cn%20%20%20%20display:%20none;%5Cn%7D%5Cn.DuckDuckGoSocialContainer:is(.size-md,%20.size-lg)%20.ddg-ctl-feedback-row%20%7B%5Cn%20%20%20%20height:%2030px;%5Cn%20%20%20%20justify-content:%20flex-end;%5Cn%20%20%20%20align-items:%20center;%5Cn%20%20%20%20display:%20flex;%5Cn%7D%5Cn%5Cn.ddg-ctl-feedback-link%20%7B%5Cn%20%20%20%20font-style:%20normal;%5Cn%20%20%20%20font-weight:%20400;%5Cn%20%20%20%20font-size:%2012px;%5Cn%20%20%20%20line-height:%2012px;%5Cn%20%20%20%20color:%20var(--ddg-color-txt-link-02);%5Cn%20%20%20%20text-decoration:%20none;%5Cn%20%20%20%20display:%20inline;%5Cn%20%20%20%20background-color:%20transparent;%5Cn%20%20%20%20border:%200;%5Cn%20%20%20%20padding:%200;%5Cn%20%20%20%20cursor:%20pointer;%5Cn%7D%5Cn%22;%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Size%20keys%20for%20a%20placeholder%0A%20%20%20%20%20*%20@typedef%20%7B%20'size-xs'%20%7C%20'size-sm'%20%7C%20'size-md'%20%7C%20'size-lg'%7C%20null%20%7D%20placeholderSize%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20WithToggleParams%20-%20Toggle%20params%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20isActive%20-%20Toggle%20state%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20dataKey%20-%20data-key%20attribute%20for%20toggle%20button%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20label%20-%20Text%20to%20be%20presented%20with%20toggle%0A%20%20%20%20%20*%20@property%20%7B'md'%20%7C%20'lg'%7D%20%5Bsize=md%5D%20-%20Toggle%20size%20variant,%20'md'%20by%20default%0A%20%20%20%20%20*%20@property%20%7B()%20=%3E%20void%7D%20onClick%20-%20Toggle%20on%20click%20callback%0A%20%20%20%20%20*/%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20WithFeedbackParams%20-%20Feedback%20link%20params%0A%20%20%20%20%20*%20@property%20%7Bstring=%7D%20label%20-%20%22Share%20Feedback%22%20link%20text%0A%20%20%20%20%20*%20@property%20%7B()%20=%3E%20void%7D%20onClick%20-%20Feedback%20element%20on%20click%20callback%0A%20%20%20%20%20*/%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20LearnMoreParams%20-%20%22Learn%20More%22%20link%20params%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20readAbout%20-%20%22Learn%20More%22%20aria-label%20text%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20learnMore%20-%20%22Learn%20More%22%20link%20text%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20The%20custom%20HTML%20element%20(Web%20Component)%20template%20with%20the%20placeholder%20for%20blocked%0A%20%20%20%20%20*%20embedded%20content.%20The%20constructor%20gets%20a%20list%20of%20parameters%20with%20the%0A%20%20%20%20%20*%20content%20and%20event%20handlers%20for%20this%20template.%0A%20%20%20%20%20*%20This%20is%20currently%20only%20used%20in%20our%20Mobile%20Apps,%20but%20can%20be%20expanded%20in%20the%20future.%0A%20%20%20%20%20*/%0A%20%20%20%20class%20DDGCtlPlaceholderBlockedElement%20extends%20HTMLElement%20%7B%0A%20%20%20%20%20%20%20%20static%20CUSTOM_TAG_NAME%20=%20'ddg-ctl-placeholder-blocked';%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Min%20height%20that%20the%20placeholder%20needs%20to%20have%20in%20order%20to%0A%20%20%20%20%20%20%20%20%20*%20have%20enough%20room%20to%20display%20content.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20MIN_CONTENT_HEIGHT%20=%20110;%0A%20%20%20%20%20%20%20%20static%20MAX_CONTENT_WIDTH_SMALL%20=%20480;%0A%20%20%20%20%20%20%20%20static%20MAX_CONTENT_WIDTH_MEDIUM%20=%20650;%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Set%20observed%20attributes%20that%20will%20trigger%20attributeChangedCallback()%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20get%20observedAttributes()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%5B'style'%5D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Placeholder%20element%20for%20blocked%20content%0A%20%20%20%20%20%20%20%20%20*%20@type%20%7BHTMLDivElement%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20placeholderBlocked;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Size%20variant%20of%20the%20latest%20calculated%20size%20of%20the%20placeholder.%0A%20%20%20%20%20%20%20%20%20*%20This%20is%20used%20to%20add%20the%20appropriate%20CSS%20class%20to%20the%20placeholder%20container%0A%20%20%20%20%20%20%20%20%20*%20and%20adapt%20the%20layout%20for%20each%20size.%0A%20%20%20%20%20%20%20%20%20*%20@type%20%7BplaceholderSize%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20size%20=%20null;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%20-%20Params%20for%20building%20a%20custom%20element%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20with%20a%20placeholder%20for%20blocked%20content%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean%7D%20params.devMode%20-%20Used%20to%20create%20the%20Shadow%20DOM%20on%20'open'(true)%20or%20'closed'(false)%20mode%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.title%20-%20Card%20title%20text%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.body%20-%20Card%20body%20text%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.unblockBtnText%20-%20Unblock%20button%20text%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean=%7D%20params.useSlimCard%20-%20Flag%20for%20using%20less%20padding%20on%20card%20(ie%20YT%20CTL%20on%20mobile)%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20params.originalElement%20-%20The%20original%20element%20this%20placeholder%20is%20replacing.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BLearnMoreParams%7D%20params.learnMore%20-%20Localized%20strings%20for%20%22Learn%20More%22%20link.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BWithToggleParams=%7D%20params.withToggle%20-%20Toggle%20config%20to%20be%20displayed%20in%20the%20bottom%20of%20the%20placeholder%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BWithFeedbackParams=%7D%20params.withFeedback%20-%20Shows%20feedback%20link%20on%20tablet%20and%20desktop%20sizes,%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(originalElement:%20HTMLIFrameElement%20%7C%20HTMLElement,%20replacementElement:%20HTMLElement)%20=%3E%20(e:%20any)%20=%3E%20void%7D%20params.onButtonClick%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20super();%0A%20%20%20%20%20%20%20%20%20%20%20%20this.params%20=%20params;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Create%20the%20shadow%20root,%20closed%20to%20prevent%20any%20outside%20observers%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7BShadowRoot%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20shadow%20=%20this.attachShadow(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mode:%20this.params.devMode%20?%20'open'%20:%20'closed',%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Add%20our%20styles%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7BHTMLStyleElement%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20style%20=%20document.createElement('style');%0A%20%20%20%20%20%20%20%20%20%20%20%20style.innerText%20=%20cssVars%20+%20css$1;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Creates%20the%20placeholder%20for%20blocked%20content%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7BHTMLDivElement%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.placeholderBlocked%20=%20this.createPlaceholder();%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Creates%20the%20Share%20Feedback%20element%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7BHTMLDivElement%20%7C%20null%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20feedbackLink%20=%20this.params.withFeedback%20?%20this.createShareFeedbackLink()%20:%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Setup%20the%20click%20handlers%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.setupEventListeners(this.placeholderBlocked,%20feedbackLink);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Append%20both%20to%20the%20shadow%20root%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/no-unused-expressions%0A%20%20%20%20%20%20%20%20%20%20%20%20feedbackLink%20&&%20this.placeholderBlocked.appendChild(feedbackLink);%0A%20%20%20%20%20%20%20%20%20%20%20%20shadow.appendChild(this.placeholderBlocked);%0A%20%20%20%20%20%20%20%20%20%20%20%20shadow.appendChild(style);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Creates%20a%20placeholder%20for%20content%20blocked%20by%20Click%20to%20Load.%0A%20%20%20%20%20%20%20%20%20*%20Note:%20We're%20using%20arrow%20functions%20()%20=%3E%20%7B%7D%20in%20this%20class%20due%20to%20a%20bug%0A%20%20%20%20%20%20%20%20%20*%20found%20in%20Firefox%20where%20it%20is%20getting%20the%20wrong%20%22this%22%20context%20on%20calls%20in%20the%20constructor.%0A%20%20%20%20%20%20%20%20%20*%20This%20is%20a%20temporary%20workaround.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BHTMLDivElement%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20createPlaceholder%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20title,%20body,%20unblockBtnText,%20useSlimCard,%20withToggle,%20withFeedback%20%7D%20=%20this.params;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20container%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20%20%20%20%20container.classList.add('DuckDuckGoSocialContainer');%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cardClassNames%20=%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'slim-card',%20!!useSlimCard%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'with-feedback-link',%20!!withFeedback%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.map((%5BclassName,%20active%5D)%20=%3E%20(active%20?%20className%20:%20''))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.join('%20');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Only%20add%20a%20card%20footer%20if%20we%20have%20the%20toggle%20button%20to%20display%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cardFooterSection%20=%20withToggle%20?%20html%60%3Cdiv%20class=%22ddg-ctl-placeholder-card-footer%22%3E$%7Bthis.createToggleButton()%7D%3C/div%3E%20%60%20:%20'';%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20learnMoreLink%20=%20this.createLearnMoreLink();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20container.innerHTML%20=%20html%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-ctl-placeholder-card%20$%7BcardClassNames%7D%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-ctl-placeholder-card-header%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cimg%20class=%22ddg-ctl-placeholder-card-header-dax%22%20src=$%7BlogoImg%7D%20alt=%22DuckDuckGo%20Dax%22%20/%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-ctl-placeholder-card-title%22%3E$%7Btitle%7D.%20$%7BlearnMoreLink%7D%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-ctl-placeholder-card-body%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-ctl-placeholder-card-body-text%22%3E$%7Bbody%7D%20$%7BlearnMoreLink%7D%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20class=%22DuckDuckGoButton%20tertiary%20ddg-ctl-unblock-btn%22%20type=%22button%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%3E$%7BunblockBtnText%7D%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20$%7BcardFooterSection%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%60.toString();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20container;%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Creates%20a%20template%20string%20for%20Learn%20More%20link.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20createLearnMoreLink%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20learnMore%20%7D%20=%20this.params;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20html%60%3Ca%0A%20%20%20%20%20%20%20%20%20%20%20%20class=%22ddg-text-link%20ddg-learn-more%22%0A%20%20%20%20%20%20%20%20%20%20%20%20aria-label=%22$%7BlearnMore.readAbout%7D%22%0A%20%20%20%20%20%20%20%20%20%20%20%20href=%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%22%0A%20%20%20%20%20%20%20%20%20%20%20%20target=%22_blank%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%3E$%7BlearnMore.learnMore%7D%3C/a%0A%20%20%20%20%20%20%20%20%3E%60;%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Creates%20a%20Feedback%20Link%20container%20row%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BHTMLDivElement%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20createShareFeedbackLink%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20withFeedback%20%7D%20=%20this.params;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20container%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20%20%20%20%20container.classList.add('ddg-ctl-feedback-row');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20container.innerHTML%20=%20html%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20class=%22ddg-ctl-feedback-link%22%20type=%22button%22%3E$%7BwithFeedback?.label%20%7C%7C%20'Share%20Feedback'%7D%3C/button%3E%0A%20%20%20%20%20%20%20%20%60.toString();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20container;%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Creates%20a%20template%20string%20for%20a%20toggle%20button%20with%20text.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20createToggleButton%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20withToggle%20%7D%20=%20this.params;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!withToggle)%20return;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20isActive,%20dataKey,%20label,%20size:%20toggleSize%20=%20'md'%20%7D%20=%20withToggle;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20toggleButton%20=%20html%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-toggle-button-container%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20class=%22ddg-toggle-button%20$%7BisActive%20?%20'active'%20:%20'inactive'%7D%20$%7BtoggleSize%7D%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type=%22button%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20aria-pressed=$%7B!!isActive%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20data-key=$%7BdataKey%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-toggle-button-bg%22%3E%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-toggle-button-knob%22%3E%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-toggle-button-label%22%3E$%7Blabel%7D%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20toggleButton;%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20containerElement%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement?%7D%20feedbackLink%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20setupEventListeners%20=%20(containerElement,%20feedbackLink)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20withToggle,%20withFeedback,%20originalElement,%20onButtonClick%20%7D%20=%20this.params;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20containerElement.querySelector('button.ddg-ctl-unblock-btn')?.addEventListener('click',%20onButtonClick(originalElement,%20this));%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(withToggle)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20containerElement.querySelector('.ddg-toggle-button-container')?.addEventListener('click',%20withToggle.onClick);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(withFeedback%20&&%20feedbackLink)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20feedbackLink.querySelector('.ddg-ctl-feedback-link')?.addEventListener('click',%20withFeedback.onClick);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Use%20JS%20to%20calculate%20the%20width%20and%20height%20of%20the%20root%20element%20placeholder.%20We%20could%20use%20a%20CSS%20Container%20Query,%20but%20full%0A%20%20%20%20%20%20%20%20%20*%20support%20to%20it%20was%20only%20added%20recently,%20so%20we're%20not%20using%20it%20for%20now.%0A%20%20%20%20%20%20%20%20%20*%20https://caniuse.com/css-container-queries%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20updatePlaceholderSize%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7BplaceholderSize%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20newSize%20=%20null;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20height,%20width%20%7D%20=%20this.getBoundingClientRect();%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(height%20&&%20height%20%3C%20DDGCtlPlaceholderBlockedElement.MIN_CONTENT_HEIGHT)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20newSize%20=%20'size-xs';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(width)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(width%20%3C%20DDGCtlPlaceholderBlockedElement.MAX_CONTENT_WIDTH_SMALL)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20newSize%20=%20'size-sm';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(width%20%3C%20DDGCtlPlaceholderBlockedElement.MAX_CONTENT_WIDTH_MEDIUM)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20newSize%20=%20'size-md';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20newSize%20=%20'size-lg';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(newSize%20&&%20newSize%20!==%20this.size)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.size)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.placeholderBlocked.classList.remove(this.size);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.placeholderBlocked.classList.add(newSize);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.size%20=%20newSize;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Web%20Component%20lifecycle%20function.%0A%20%20%20%20%20%20%20%20%20*%20When%20element%20is%20first%20added%20to%20the%20DOM,%20trigger%20this%20callback%20and%0A%20%20%20%20%20%20%20%20%20*%20update%20the%20element%20CSS%20size%20class.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20connectedCallback()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.updatePlaceholderSize();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Web%20Component%20lifecycle%20function.%0A%20%20%20%20%20%20%20%20%20*%20When%20the%20root%20element%20gets%20the%20'style'%20attribute%20updated,%20reflect%20that%20in%20the%20container%0A%20%20%20%20%20%20%20%20%20*%20element%20inside%20the%20shadow%20root.%20This%20way,%20we%20can%20copy%20the%20size%20and%20other%20styles%20from%20the%20root%0A%20%20%20%20%20%20%20%20%20*%20element%20and%20have%20the%20inner%20context%20be%20able%20to%20use%20the%20same%20sizes%20to%20adapt%20the%20template%20layout.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20attr%20Observed%20attribute%20key%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B*%7D%20_%20Attribute%20old%20value,%20ignored%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B*%7D%20newValue%20Attribute%20new%20value%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20attributeChangedCallback(attr,%20_,%20newValue)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(attr%20===%20'style')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.placeholderBlocked%5Battr%5D.cssText%20=%20newValue;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.updatePlaceholderSize();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20css%20=%20%22:host,%5Cn*%20%7B%5Cn%20%20%20%20font-family:%20DuckDuckGoPrivacyEssentials,%20system,%20-apple-system,%20system-ui,%20BlinkMacSystemFont,%20'Segoe%20UI',%20Roboto,%5Cn%20%20%20%20%20%20%20%20Helvetica,%20Arial,%20sans-serif,%20'Apple%20Color%20Emoji',%20'Segoe%20UI%20Emoji',%20'Segoe%20UI%20Symbol';%5Cn%20%20%20%20box-sizing:%20border-box;%5Cn%20%20%20%20font-weight:%20normal;%5Cn%20%20%20%20font-style:%20normal;%5Cn%20%20%20%20margin:%200;%5Cn%20%20%20%20padding:%200;%5Cn%20%20%20%20text-align:%20left;%5Cn%7D%5Cn%5Cn/*%20SHARED%20STYLES%20*/%5Cn/*%20Popover%20*/%5Cn.ddg-popover%20%7B%5Cn%20%20%20%20background:%20#ffffff;%5Cn%20%20%20%20border:%201px%20solid%20rgba(0,%200,%200,%200.1);%5Cn%20%20%20%20border-radius:%2016px;%5Cn%20%20%20%20box-shadow:%200px%202px%206px%20rgba(0,%200,%200,%200.12),%200px%208px%2016px%20rgba(0,%200,%200,%200.08);%5Cn%20%20%20%20width:%20360px;%5Cn%20%20%20%20margin-top:%2010px;%5Cn%20%20%20%20z-index:%202147483647;%5Cn%20%20%20%20position:%20absolute;%5Cn%20%20%20%20line-height:%20normal;%5Cn%7D%5Cn.ddg-popover-arrow%20%7B%5Cn%20%20%20%20display:%20inline-block;%5Cn%20%20%20%20background:%20#ffffff;%5Cn%20%20%20%20border:%20solid%20rgba(0,%200,%200,%200.1);%5Cn%20%20%20%20border-width:%200%201px%201px%200;%5Cn%20%20%20%20padding:%205px;%5Cn%20%20%20%20transform:%20rotate(-135deg);%5Cn%20%20%20%20-webkit-transform:%20rotate(-135deg);%5Cn%20%20%20%20position:%20relative;%5Cn%20%20%20%20top:%20-9px;%5Cn%7D%5Cn.ddg-popover%20.ddg-title-header%20%7B%5Cn%20%20%20%20padding:%200px%2012px%2012px;%5Cn%20%20%20%20margin-top:%20-5px;%5Cn%7D%5Cn.ddg-popover-body%20%7B%5Cn%20%20%20%20font-size:%2014px;%5Cn%20%20%20%20line-height:%2021px;%5Cn%20%20%20%20margin:%20auto;%5Cn%20%20%20%20padding:%2017px;%5Cn%20%20%20%20text-align:%20left;%5Cn%7D%5Cn%5Cn/*%20DDG%20common%20header%20*/%5Cn.ddg-title-header%20%7B%5Cn%20%20%20%20display:%20flex;%5Cn%20%20%20%20padding:%2012px;%5Cn%20%20%20%20max-height:%2044px;%5Cn%20%20%20%20border-bottom:%201px%20solid;%5Cn%20%20%20%20border-color:%20rgba(196,%20196,%20196,%200.3);%5Cn%20%20%20%20margin:%200;%5Cn%20%20%20%20margin-bottom:%204px;%5Cn%7D%5Cn.ddg-title-header%20.ddg-title-text%20%7B%5Cn%20%20%20%20line-height:%201.4;%5Cn%20%20%20%20font-size:%2014px;%5Cn%20%20%20%20margin:%20auto%2010px;%5Cn%20%20%20%20flex-basis:%20100%25;%5Cn%20%20%20%20height:%201.4em;%5Cn%20%20%20%20flex-wrap:%20wrap;%5Cn%20%20%20%20overflow:%20hidden;%5Cn%20%20%20%20text-align:%20left;%5Cn%20%20%20%20border:%20none;%5Cn%20%20%20%20padding:%200;%5Cn%7D%5Cn.ddg-title-header%20.ddg-logo%20%7B%5Cn%20%20%20%20flex-basis:%200%25;%5Cn%20%20%20%20min-width:%2020px;%5Cn%20%20%20%20height:%2021px;%5Cn%20%20%20%20border:%20none;%5Cn%20%20%20%20padding:%200;%5Cn%20%20%20%20margin:%200;%5Cn%7D%5Cn.ddg-title-header%20.ddg-logo%20.ddg-logo-img%20%7B%5Cn%20%20%20%20height:%2021px;%5Cn%20%20%20%20width:%2021px;%5Cn%7D%5Cn%5Cn/*%20CTL%20Login%20Button%20styles%20*/%5Cn#DuckDuckGoPrivacyEssentialsHoverable%20%7B%5Cn%20%20%20%20padding-bottom:%2010px;%5Cn%7D%5Cn%5Cn#DuckDuckGoPrivacyEssentialsHoverableText%20%7B%5Cn%20%20%20%20display:%20none;%5Cn%7D%5Cn#DuckDuckGoPrivacyEssentialsHoverable:hover%20#DuckDuckGoPrivacyEssentialsHoverableText%20%7B%5Cn%20%20%20%20display:%20block;%5Cn%7D%5Cn%5Cn.DuckDuckGoButton.tertiary.ddg-ctl-fb-login-btn%20%7B%5Cn%20%20%20%20background-color:%20var(--ddg-color-bg-01);%5Cn%7D%5Cn@media%20(prefers-color-scheme:%20dark)%20%7B%5Cn%20%20%20%20.DuckDuckGoButton.tertiary.ddg-ctl-fb-login-btn%20%7B%5Cn%20%20%20%20%20%20%20%20background:%20#111111;%5Cn%20%20%20%20%7D%5Cn%7D%5Cn.DuckDuckGoButton.tertiary:hover%20%7B%5Cn%20%20%20%20background:%20rgb(238,%20238,%20238);%5Cn%20%20%20%20border-color:%20var(--ddg-shade-18);%5Cn%7D%5Cn@media%20(prefers-color-scheme:%20dark)%20%7B%5Cn%20%20%20%20.DuckDuckGoButton.tertiary:hover%20%7B%5Cn%20%20%20%20%20%20%20%20background:%20rgb(39,%2039,%2039);%5Cn%20%20%20%20%20%20%20%20border-color:%20var(--ddg-tint-24);%5Cn%20%20%20%20%7D%5Cn%7D%5Cn.DuckDuckGoButton.tertiary:active%20%7B%5Cn%20%20%20%20background:%20rgb(220,%20220,%20220);%5Cn%20%20%20%20border-color:%20var(--ddg-shade-36);%5Cn%7D%5Cn@media%20(prefers-color-scheme:%20dark)%20%7B%5Cn%20%20%20%20.DuckDuckGoButton.tertiary:active%20%7B%5Cn%20%20%20%20%20%20%20%20background:%20rgb(65,%2065,%2065);%5Cn%20%20%20%20%20%20%20%20border-color:%20var(--ddg-tint-24);%5Cn%20%20%20%20%7D%5Cn%7D%5Cn%5Cn.ddg-ctl-button-login-icon%20%7B%5Cn%20%20%20%20margin-right:%208px;%5Cn%20%20%20%20height:%2020px;%5Cn%20%20%20%20width:%2020px;%5Cn%7D%5Cn%5Cn.ddg-fb-login-container%20%7B%5Cn%20%20%20%20position:%20relative;%5Cn%20%20%20%20margin:%20auto;%5Cn%20%20%20%20width:%20auto;%5Cn%7D%5Cn%22;%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20LearnMoreParams%20-%20%22Learn%20More%22%20link%20params%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20readAbout%20-%20%22Learn%20More%22%20aria-label%20text%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20learnMore%20-%20%22Learn%20More%22%20link%20text%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Template%20for%20creating%20a%20%3Cdiv/%3E%20element%20placeholder%20for%20blocked%20login%20embedded%20buttons.%0A%20%20%20%20%20*%20The%20constructor%20gets%20a%20list%20of%20parameters%20with%20the%0A%20%20%20%20%20*%20content%20and%20event%20handlers%20for%20this%20template.%0A%20%20%20%20%20*%20This%20is%20currently%20only%20used%20in%20our%20Mobile%20Apps,%20but%20can%20be%20expanded%20in%20the%20future.%0A%20%20%20%20%20*/%0A%20%20%20%20class%20DDGCtlLoginButton%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Placeholder%20container%20element%20for%20blocked%20login%20button%0A%20%20%20%20%20%20%20%20%20*%20@type%20%7BHTMLDivElement%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20#element;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%20-%20Params%20for%20building%20a%20custom%20element%20with%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%20placeholder%20for%20a%20blocked%20login%20button%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean%7D%20params.devMode%20-%20Used%20to%20create%20the%20Shadow%20DOM%20on%20'open'(true)%20or%20'closed'(false)%20mode%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.label%20-%20Button%20text%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.logoIcon%20-%20Logo%20image%20to%20be%20displayed%20in%20the%20Login%20Button%20to%20the%20left%20of%20the%20label%20text%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.hoverText%20-%20Text%20for%20popover%20on%20button%20hover%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean=%7D%20params.useSlimCard%20-%20Flag%20for%20using%20less%20padding%20on%20card%20(ie%20YT%20CTL%20on%20mobile)%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20params.originalElement%20-%20The%20original%20element%20this%20placeholder%20is%20replacing.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BLearnMoreParams%7D%20params.learnMore%20-%20Localized%20strings%20for%20%22Learn%20More%22%20link.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(originalElement:%20HTMLIFrameElement%20%7C%20HTMLElement,%20replacementElement:%20HTMLElement)%20=%3E%20(e:%20any)%20=%3E%20void%7D%20params.onClick%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.params%20=%20params;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Create%20the%20placeholder%20element%20to%20be%20inject%20in%20the%20page%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7BHTMLDivElement%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.element%20=%20document.createElement('div');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Create%20the%20shadow%20root,%20closed%20to%20prevent%20any%20outside%20observers%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7BShadowRoot%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20shadow%20=%20this.element.attachShadow(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mode:%20this.params.devMode%20?%20'open'%20:%20'closed',%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Add%20our%20styles%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7BHTMLStyleElement%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20style%20=%20document.createElement('style');%0A%20%20%20%20%20%20%20%20%20%20%20%20style.innerText%20=%20cssVars%20+%20css;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Create%20the%20Facebook%20login%20button%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7BHTMLDivElement%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20loginButton%20=%20this._createLoginButton();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Setup%20the%20click%20handlers%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this._setupEventListeners(loginButton);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Append%20both%20to%20the%20shadow%20root%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20shadow.appendChild(loginButton);%0A%20%20%20%20%20%20%20%20%20%20%20%20shadow.appendChild(style);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BHTMLDivElement%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20get%20element()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.#element;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLDivElement%7D%20el%20-%20New%20placeholder%20element%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20set%20element(el)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.#element%20=%20el;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Creates%20a%20placeholder%20Facebook%20login%20button.%20When%20clicked,%20a%20warning%20dialog%0A%20%20%20%20%20%20%20%20%20*%20is%20displayed%20to%20the%20user.%20The%20login%20flow%20only%20continues%20if%20the%20user%20clicks%20to%0A%20%20%20%20%20%20%20%20%20*%20proceed.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BHTMLDivElement%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_createLoginButton()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20label,%20hoverText,%20logoIcon,%20learnMore%20%7D%20=%20this.params;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20popoverStyle,%20arrowStyle%20%7D%20=%20this._calculatePopoverPosition();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20container%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Add%20our%20own%20styles%20and%20inherit%20any%20local%20class%20styles%20on%20the%20button%0A%20%20%20%20%20%20%20%20%20%20%20%20container.classList.add('ddg-fb-login-container');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20container.innerHTML%20=%20html%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22DuckDuckGoPrivacyEssentialsHoverable%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Login%20Button%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20class=%22DuckDuckGoButton%20tertiary%20ddg-ctl-fb-login-btn%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cimg%20class=%22ddg-ctl-button-login-icon%22%20height=%2220px%22%20width=%2220px%22%20src=%22$%7BlogoIcon%7D%22%20/%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%3E$%7Blabel%7D%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/button%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Popover%20-%20hover%20box%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22DuckDuckGoPrivacyEssentialsHoverableText%22%20class=%22ddg-popover%22%20style=%22$%7BpopoverStyle%7D%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-popover-arrow%22%20style=%22$%7BarrowStyle%7D%22%3E%3C/div%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-title-header%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-logo%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cimg%20class=%22ddg-logo-img%22%20src=%22$%7BlogoImg%7D%22%20height=%2221px%22%20/%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22DuckDuckGoPrivacyEssentialsCTLElementTitle%22%20class=%22ddg-title-text%22%3EDuckDuckGo%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-popover-body%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20$%7BhoverText%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ca%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20class=%22ddg-text-link%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20aria-label=%22$%7BlearnMore.readAbout%7D%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20href=%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20target=%22_blank%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id=%22learnMoreLink%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20$%7BlearnMore.learnMore%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/a%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%60.toString();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20container;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20The%20left%20side%20of%20the%20popover%20may%20go%20offscreen%20if%20the%0A%20%20%20%20%20%20%20%20%20*%20login%20button%20is%20all%20the%20way%20on%20the%20left%20side%20of%20the%20page.%20This%0A%20%20%20%20%20%20%20%20%20*%20If%20that%20is%20the%20case,%20dynamically%20shift%20the%20box%20right%20so%20it%20shows%0A%20%20%20%20%20%20%20%20%20*%20properly.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7B%7B%0A%20%20%20%20%20%20%20%20%20*%20%20popoverStyle:%20string,%20//%20CSS%20styles%20to%20be%20applied%20in%20the%20Popover%20container%0A%20%20%20%20%20%20%20%20%20*%20%20arrowStyle:%20string,%20%20%20//%20CSS%20styles%20to%20be%20applied%20in%20the%20Popover%20arrow%0A%20%20%20%20%20%20%20%20%20*%20%7D%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_calculatePopoverPosition()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20originalElement%20%7D%20=%20this.params;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20rect%20=%20originalElement.getBoundingClientRect();%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20textBubbleWidth%20=%20360;%20//%20Should%20match%20the%20width%20rule%20in%20.ddg-popover%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20textBubbleLeftShift%20=%20100;%20//%20Should%20match%20the%20CSS%20left:%20rule%20in%20.ddg-popover%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20arrowDefaultLocationPercent%20=%2050;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20popoverStyle;%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20arrowStyle;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(rect.left%20%3C%20textBubbleLeftShift)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20leftShift%20=%20-rect.left%20+%2010;%20//%2010px%20away%20from%20edge%20of%20the%20screen%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20popoverStyle%20=%20%60left:%20$%7BleftShift%7Dpx;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20change%20=%20(1%20-%20rect.left%20/%20textBubbleLeftShift)%20*%20(100%20-%20arrowDefaultLocationPercent);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20arrowStyle%20=%20%60left:%20$%7BMath.max(10,%20arrowDefaultLocationPercent%20-%20change)%7D%25;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(rect.left%20+%20textBubbleWidth%20-%20textBubbleLeftShift%20%3E%20window.innerWidth)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20rightShift%20=%20rect.left%20+%20textBubbleWidth%20-%20textBubbleLeftShift;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20diff%20=%20Math.min(rightShift%20-%20window.innerWidth,%20textBubbleLeftShift);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20rightMargin%20=%2020;%20//%20Add%20some%20margin%20to%20the%20page,%20so%20scrollbar%20doesn't%20overlap.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20popoverStyle%20=%20%60left:%20-$%7BtextBubbleLeftShift%20+%20diff%20+%20rightMargin%7Dpx;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20change%20=%20(diff%20/%20textBubbleLeftShift)%20*%20(100%20-%20arrowDefaultLocationPercent);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20arrowStyle%20=%20%60left:%20$%7BMath.max(10,%20arrowDefaultLocationPercent%20+%20change)%7D%25;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20popoverStyle%20=%20%60left:%20-$%7BtextBubbleLeftShift%7Dpx;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20arrowStyle%20=%20%60left:%20$%7BarrowDefaultLocationPercent%7D%25;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%20popoverStyle,%20arrowStyle%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20loginButton%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_setupEventListeners(loginButton)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20originalElement,%20onClick%20%7D%20=%20this.params;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20loginButton.querySelector('.ddg-ctl-fb-login-btn')?.addEventListener('click',%20onClick(originalElement,%20this.element));%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Register%20custom%20elements%20in%20this%20wrapper%20function%20to%20be%20called%20only%20when%20we%20need%20to%0A%20%20%20%20%20*%20and%20also%20to%20allow%20remote-config%20later%20if%20needed.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20registerCustomElements()%20%7B%0A%20%20%20%20%20%20%20%20if%20(!customElements.get(DDGCtlPlaceholderBlockedElement.CUSTOM_TAG_NAME))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20customElements.define(DDGCtlPlaceholderBlockedElement.CUSTOM_TAG_NAME,%20DDGCtlPlaceholderBlockedElement);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7B'darkMode'%20%7C%20'lightMode'%20%7C%20'loginMode'%20%7C%20'cancelMode'%7D%20displayMode%0A%20%20%20%20%20*%20%20%20Key%20for%20theme%20value%20to%20determine%20the%20styling%20of%20buttons/placeholders.%0A%20%20%20%20%20*%20%20%20Matches%20%60styles%5Bmode%5D%60%20keys:%0A%20%20%20%20%20*%20%20%20%20%20-%20%60'lightMode'%60:%20Primary%20colors%20styling%20for%20light%20theme%0A%20%20%20%20%20*%20%20%20%20%20-%20%60'darkMode'%60:%20Primary%20colors%20styling%20for%20dark%20theme%0A%20%20%20%20%20*%20%20%20%20%20-%20%60'cancelMode'%60:%20Secondary%20colors%20styling%20for%20all%20themes%0A%20%20%20%20%20*/%0A%0A%20%20%20%20let%20devMode%20=%20false;%0A%20%20%20%20let%20isYoutubePreviewsEnabled%20=%20false;%0A%20%20%20%20let%20appID;%0A%0A%20%20%20%20const%20titleID%20=%20'DuckDuckGoPrivacyEssentialsCTLElementTitle';%0A%0A%20%20%20%20//%20Configuration%20for%20how%20the%20placeholder%20elements%20should%20look%20and%20behave.%0A%20%20%20%20//%20@see%20%7BgetConfig%7D%0A%20%20%20%20let%20config%20=%20null;%0A%20%20%20%20let%20sharedStrings%20=%20null;%0A%20%20%20%20let%20styles%20=%20null;%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20List%20of%20platforms%20where%20we%20can%20skip%20showing%20a%20Web%20Modal%20from%20C-S-S.%0A%20%20%20%20%20*%20It%20is%20generally%20expected%20that%20the%20platform%20will%20show%20a%20native%20modal%20instead.%0A%20%20%20%20%20*%20@type%20%7Bimport('../utils').Platform%5B%22name%22%5D%5B%5D%7D%20*/%0A%20%20%20%20const%20platformsWithNativeModalSupport%20=%20%5B'android',%20'ios'%5D;%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Platforms%20supporting%20the%20new%20layout%20using%20Web%20Components.%0A%20%20%20%20%20*%20@type%20%7Bimport('../utils').Platform%5B%22name%22%5D%5B%5D%7D%20*/%0A%20%20%20%20const%20platformsWithWebComponentsEnabled%20=%20%5B'android',%20'ios'%5D;%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Based%20on%20the%20current%20Platform%20where%20the%20Widget%20is%20running,%20it%20will%0A%20%20%20%20%20*%20return%20if%20it%20is%20one%20of%20our%20mobile%20apps%20or%20not.%20This%20should%20be%20used%20to%0A%20%20%20%20%20*%20define%20which%20layout%20to%20use%20between%20Mobile%20and%20Desktop%20Platforms%20variations.%0A%20%20%20%20%20*%20@type%20%7Bimport('../utils').Platform%5B%22name%22%5D%5B%5D%7D%20*/%0A%20%20%20%20const%20mobilePlatforms%20=%20%5B'android',%20'ios'%5D;%0A%0A%20%20%20%20//%20TODO:%20Remove%20these%20redundant%20data%20structures%20and%20refactor%20the%20related%20code.%0A%20%20%20%20//%20%20%20%20%20%20%20There%20should%20be%20no%20need%20to%20have%20the%20entity%20configuration%20stored%20in%20two%0A%20%20%20%20//%20%20%20%20%20%20%20places.%0A%20%20%20%20const%20entities%20=%20%5B%5D;%0A%20%20%20%20const%20entityData%20=%20%7B%7D;%0A%0A%20%20%20%20//%20Used%20to%20avoid%20displaying%20placeholders%20for%20the%20same%20tracking%20element%20twice.%0A%20%20%20%20const%20knownTrackingElements%20=%20new%20WeakSet();%0A%0A%20%20%20%20//%20Promise%20that%20is%20resolved%20when%20the%20Click%20to%20Load%20feature%20init()%20function%20has%0A%20%20%20%20//%20finished%20its%20work,%20enough%20that%20it's%20now%20safe%20to%20replace%20elements%20with%0A%20%20%20%20//%20placeholders.%0A%20%20%20%20let%20readyToDisplayPlaceholdersResolver;%0A%20%20%20%20const%20readyToDisplayPlaceholders%20=%20new%20Promise((resolve)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20readyToDisplayPlaceholdersResolver%20=%20resolve;%0A%20%20%20%20%7D);%0A%0A%20%20%20%20//%20Promise%20that%20is%20resolved%20when%20the%20page%20has%20finished%20loading%20(and%0A%20%20%20%20//%20readyToDisplayPlaceholders%20has%20resolved).%20Wait%20for%20this%20before%20sending%0A%20%20%20%20//%20essential%20messages%20to%20surrogate%20scripts.%0A%20%20%20%20let%20afterPageLoadResolver;%0A%20%20%20%20const%20afterPageLoad%20=%20new%20Promise((resolve)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20afterPageLoadResolver%20=%20resolve;%0A%20%20%20%20%7D);%0A%0A%20%20%20%20//%20Messaging%20layer%20for%20Click%20to%20Load.%20The%20messaging%20instance%20is%20initialized%20in%0A%20%20%20%20//%20ClickToLoad.init()%20and%20updated%20here%20to%20be%20used%20outside%20ClickToLoad%20class%0A%20%20%20%20//%20we%20need%20a%20module%20scoped%20reference.%0A%20%20%20%20/**%20@type%20%7Bimport(%22@duckduckgo/messaging%22).Messaging%7D%20*/%0A%20%20%20%20let%20_messagingModuleScope;%0A%20%20%20%20/**%20@type%20function%20*/%0A%20%20%20%20let%20_addDebugFlag;%0A%20%20%20%20const%20ctl%20=%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7Bimport(%22@duckduckgo/messaging%22).Messaging%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20get%20messaging()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!_messagingModuleScope)%20throw%20new%20Error('Messaging%20not%20initialized');%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20_messagingModuleScope;%0A%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20addDebugFlag()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!_addDebugFlag)%20throw%20new%20Error('addDebugFlag%20not%20initialized');%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20_addDebugFlag();%0A%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%7D;%0A%0A%20%20%20%20/*********************************************************%0A%20%20%20%20%20*%20%20Widget%20Replacement%20logic%0A%20%20%20%20%20*********************************************************/%0A%20%20%20%20class%20DuckWidget%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BObject%7D%20widgetData%0A%20%20%20%20%20%20%20%20%20*%20%20%20The%20configuration%20for%20this%20%22widget%22%20as%20determined%20in%20ctl-config.js.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20originalElement%0A%20%20%20%20%20%20%20%20%20*%20%20%20The%20original%20tracking%20element%20to%20replace%20with%20a%20placeholder.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20entity%0A%20%20%20%20%20%20%20%20%20*%20%20%20The%20entity%20behind%20the%20tracking%20element%20(e.g.%20%22Facebook,%20Inc.%22).%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../utils').Platform%7D%20platform%0A%20%20%20%20%20%20%20%20%20*%20%20%20The%20platform%20where%20Click%20to%20Load%20and%20the%20Duck%20Widget%20is%20running%20on%20(ie%20Extension,%20Android%20App,%20etc)%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(widgetData,%20originalElement,%20entity,%20platform)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.clickAction%20=%20%7B%20...widgetData.clickAction%20%7D;%20//%20shallow%20copy%0A%20%20%20%20%20%20%20%20%20%20%20%20this.replaceSettings%20=%20widgetData.replaceSettings;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.originalElement%20=%20originalElement;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.placeholderElement%20=%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.dataElements%20=%20%7B%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.gatherDataElements();%0A%20%20%20%20%20%20%20%20%20%20%20%20this.entity%20=%20entity;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.widgetID%20=%20Math.random();%0A%20%20%20%20%20%20%20%20%20%20%20%20this.autoplay%20=%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Boolean%20if%20widget%20is%20unblocked%20and%20content%20should%20not%20be%20blocked%0A%20%20%20%20%20%20%20%20%20%20%20%20this.isUnblocked%20=%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.platform%20=%20platform;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Dispatch%20an%20event%20on%20the%20target%20element,%20including%20the%20widget's%20ID%20and%0A%20%20%20%20%20%20%20%20%20*%20other%20details.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BEventTarget%7D%20eventTarget%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20eventName%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20dispatchEvent(eventTarget,%20eventName)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20eventTarget.dispatchEvent(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20createCustomEvent(eventName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20detail:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20entity:%20this.entity,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20this.replaceSettings,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20widgetID:%20this.widgetID,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D),%0A%20%20%20%20%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Take%20note%20of%20some%20of%20the%20tracking%20element's%20attributes%20(as%20determined%20by%0A%20%20%20%20%20%20%20%20%20*%20clickAction.urlDataAttributesToPreserve)%20and%20store%20those%20in%0A%20%20%20%20%20%20%20%20%20*%20this.dataElement.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20gatherDataElements()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this.clickAction.urlDataAttributesToPreserve)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20%5BattrName,%20attrSettings%5D%20of%20Object.entries(this.clickAction.urlDataAttributesToPreserve))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20value%20=%20this.originalElement.getAttribute(attrName);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!value)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(attrSettings.required)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Missing%20a%20required%20attribute%20means%20we%20won't%20be%20able%20to%20replace%20it%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20with%20a%20light%20version,%20replace%20with%20full%20version.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.clickAction.type%20=%20'allowFull';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20the%20attribute%20is%20%22width%22,%20try%20first%20to%20measure%20the%20parent's%20width%20and%20use%20that%20as%20a%20default%20value.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(attrName%20===%20'data-width')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20windowWidth%20=%20window.innerWidth;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20parentElement%20%7D%20=%20this.originalElement;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20parentStyles%20=%20parentElement%20?%20window.getComputedStyle(parentElement)%20:%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20parentInnerWidth%20=%20null;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20We%20want%20to%20calculate%20the%20inner%20width%20of%20the%20parent%20element%20as%20the%20iframe,%20when%20added%20back,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20should%20not%20be%20bigger%20than%20the%20space%20available%20in%20the%20parent%20element.%20There%20is%20no%20straightforward%20way%20of%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20doing%20this.%20We%20need%20to%20get%20the%20parent's%20.clientWidth%20and%20remove%20the%20paddings%20size%20from%20it.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(parentElement%20&&%20parentStyles%20&&%20parentStyles.display%20!==%20'inline')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20parentInnerWidth%20=%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20parentElement.clientWidth%20-%20parseFloat(parentStyles.paddingLeft)%20-%20parseFloat(parentStyles.paddingRight);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(parentInnerWidth%20&&%20parentInnerWidth%20%3C%20windowWidth)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value%20=%20parentInnerWidth.toString();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Our%20default%20value%20for%20width%20is%20often%20greater%20than%20the%20window%20size%20of%20smaller%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20screens%20(ie%20mobile).%20Then%20use%20whatever%20is%20the%20smallest%20value.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value%20=%20Math.min(attrSettings.default,%20windowWidth).toString();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value%20=%20attrSettings.default;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.dataElements%5BattrName%5D%20=%20value;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Return%20the%20URL%20of%20the%20Facebook%20content,%20for%20use%20when%20a%20Facebook%20Click%20to%0A%20%20%20%20%20%20%20%20%20*%20Load%20placeholder%20has%20been%20clicked%20by%20the%20user.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bstring%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20getTargetURL()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Copying%20over%20data%20fields%20should%20be%20done%20lazily,%20since%20some%20required%20data%20may%20not%20be%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20captured%20until%20after%20page%20scripts%20run.%0A%20%20%20%20%20%20%20%20%20%20%20%20this.copySocialDataFields();%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.clickAction.targetURL;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Determines%20which%20display%20mode%20the%20placeholder%20element%20should%20render%20in.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BdisplayMode%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20getMode()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Login%20buttons%20are%20always%20the%20login%20style%20types%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.replaceSettings.type%20===%20'loginButton')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20'loginMode';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(window?.matchMedia('(prefers-color-scheme:%20dark)')?.matches)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20'darkMode';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20'lightMode';%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Take%20note%20of%20some%20of%20the%20tracking%20element's%20style%20attributes%20(as%0A%20%20%20%20%20%20%20%20%20*%20determined%20by%20clickAction.styleDataAttributes)%20as%20a%20CSS%20string.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bstring%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20getStyle()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20styleString%20=%20'border:%20none;';%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.clickAction.styleDataAttributes)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Copy%20elements%20from%20the%20original%20div%20into%20style%20attributes%20as%20directed%20by%20config%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20%5Battr,%20valAttr%5D%20of%20Object.entries(this.clickAction.styleDataAttributes))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20valueFound%20=%20this.dataElements%5BvalAttr.name%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!valueFound)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20valueFound%20=%20this.dataElements%5BvalAttr.fallbackAttribute%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20partialStyleString%20=%20'';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(valueFound)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20partialStyleString%20+=%20%60$%7Battr%7D:%20$%7BvalueFound%7D%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!partialStyleString.includes(valAttr.unit))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20partialStyleString%20+=%20valAttr.unit;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20partialStyleString%20+=%20';';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20styleString%20+=%20partialStyleString;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20styleString;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Store%20some%20attributes%20from%20the%20original%20tracking%20element,%20used%20for%20both%0A%20%20%20%20%20%20%20%20%20*%20placeholder%20element%20styling,%20and%20when%20restoring%20the%20original%20tracking%0A%20%20%20%20%20%20%20%20%20*%20element.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20copySocialDataFields()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this.clickAction.urlDataAttributesToPreserve)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20App%20ID%20may%20be%20set%20by%20client%20scripts,%20and%20is%20required%20for%20some%20elements.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.dataElements.app_id_replace%20&&%20appID%20!=%20null)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.clickAction.targetURL%20=%20this.clickAction.targetURL.replace('app_id_replace',%20appID);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20key%20of%20Object.keys(this.dataElements))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20attrValue%20=%20this.dataElements%5Bkey%5D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!attrValue)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20The%20URL%20for%20Facebook%20videos%20are%20specified%20as%20the%20data-href%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20attribute%20on%20a%20div,%20that%20is%20then%20used%20to%20create%20the%20iframe.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Some%20websites%20omit%20the%20protocol%20part%20of%20the%20URL%20when%20doing%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20that,%20which%20then%20prevents%20the%20iframe%20from%20loading%20correctly.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(key%20===%20'data-href'%20&&%20attrValue.startsWith('//'))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20attrValue%20=%20window.location.protocol%20+%20attrValue;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.clickAction.targetURL%20=%20this.clickAction.targetURL.replace(key,%20encodeURIComponent(attrValue));%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Creates%20an%20iFrame%20for%20this%20facebook%20content.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BHTMLIFrameElement%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20createFBIFrame()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20frame%20=%20document.createElement('iframe');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20frame.setAttribute('src',%20this.getTargetURL());%0A%20%20%20%20%20%20%20%20%20%20%20%20frame.setAttribute('style',%20this.getStyle());%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20frame;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Tweaks%20an%20embedded%20YouTube%20video%20element%20ready%20for%20when%20it's%0A%20%20%20%20%20%20%20%20%20*%20reloaded.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLIFrameElement%7D%20videoElement%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BEventListener?%7D%20onError%0A%20%20%20%20%20%20%20%20%20*%20%20%20Function%20to%20be%20called%20if%20the%20video%20fails%20to%20load.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20adjustYouTubeVideoElement(videoElement)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20onError%20=%20null;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!videoElement.src)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20onError;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20url%20=%20new%20URL(videoElement.src);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20hostname:%20originalHostname%20%7D%20=%20url;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Upgrade%20video%20to%20YouTube's%20%22privacy%20enhanced%22%20mode,%20but%20fall%20back%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20to%20standard%20mode%20if%20the%20video%20fails%20to%20load.%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Note:%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20%201.%20Changing%20the%20iframe's%20host%20like%20this%20won't%20cause%20a%20CSP%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20%20%20violation%20on%20Chrome,%20see%20https://crbug.com/1271196.%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20%202.%20The%20onError%20event%20doesn't%20fire%20for%20blocked%20iframes%20on%20Chrome.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(originalHostname%20!==%20'www.youtube-nocookie.com')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20url.hostname%20=%20'www.youtube-nocookie.com';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20onError%20=%20(event)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20url.hostname%20=%20originalHostname;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20videoElement.src%20=%20url.href;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20event.stopImmediatePropagation();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Configure%20auto-play%20correctly%20depending%20on%20if%20the%20video's%20preview%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20loaded,%20otherwise%20it%20doesn't%20allow%20autoplay.%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20allowString%20=%20videoElement.getAttribute('allow')%20%7C%7C%20'';%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20allowed%20=%20new%20Set(allowString.split(';').map((s)%20=%3E%20s.trim()));%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.autoplay)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20allowed.add('autoplay');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20url.searchParams.set('autoplay',%20'1');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20allowed.delete('autoplay');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20url.searchParams.delete('autoplay');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20allowString%20=%20Array.from(allowed).join(';%20');%0A%20%20%20%20%20%20%20%20%20%20%20%20videoElement.setAttribute('allow',%20allowString);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20videoElement.src%20=%20url.href;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20onError;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Fades%20the%20given%20element%20in/out.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20element%0A%20%20%20%20%20%20%20%20%20*%20%20%20The%20element%20to%20fade%20in%20or%20out.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bnumber%7D%20interval%0A%20%20%20%20%20%20%20%20%20*%20%20%20Frequency%20of%20opacity%20updates%20(ms).%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean%7D%20fadeIn%0A%20%20%20%20%20%20%20%20%20*%20%20%20True%20if%20the%20element%20should%20fade%20in%20instead%20of%20out.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPromise%3Cvoid%3E%7D%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20Promise%20that%20resolves%20when%20the%20fade%20in/out%20is%20complete.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20fadeElement(element,%20interval,%20fadeIn)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20Promise((resolve)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20opacity%20=%20fadeIn%20?%200%20:%201;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20originStyle%20=%20element.style.cssText;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20fadeOut%20=%20setInterval(function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20opacity%20+=%20fadeIn%20?%200.03%20:%20-0.03;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20element.style.cssText%20=%20originStyle%20+%20%60opacity:%20$%7Bopacity%7D;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(opacity%20%3C=%200%20%7C%7C%20opacity%20%3E=%201)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clearInterval(fadeOut);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resolve();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%20interval);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Fades%20the%20given%20element%20out.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20element%0A%20%20%20%20%20%20%20%20%20*%20%20%20The%20element%20to%20fade%20out.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPromise%3Cvoid%3E%7D%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20Promise%20that%20resolves%20when%20the%20fade%20out%20is%20complete.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20fadeOutElement(element)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.fadeElement(element,%2010,%20false);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Fades%20the%20given%20element%20in.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20element%0A%20%20%20%20%20%20%20%20%20*%20%20%20The%20element%20to%20fade%20in.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPromise%3Cvoid%3E%7D%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20Promise%20that%20resolves%20when%20the%20fade%20in%20is%20complete.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20fadeInElement(element)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.fadeElement(element,%2010,%20true);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20The%20function%20that's%20called%20when%20the%20user%20clicks%20to%20load%20some%20content.%0A%20%20%20%20%20%20%20%20%20*%20Unblocks%20the%20content,%20puts%20it%20back%20in%20the%20page,%20and%20removes%20the%0A%20%20%20%20%20%20%20%20%20*%20placeholder.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLIFrameElement%7D%20originalElement%0A%20%20%20%20%20%20%20%20%20*%20%20%20The%20original%20tracking%20element.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20replacementElement%0A%20%20%20%20%20%20%20%20%20*%20%20%20The%20placeholder%20element.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20clickFunction(originalElement,%20replacementElement)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20clicked%20=%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20handleClick%20=%20(e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Ensure%20that%20the%20click%20is%20created%20by%20a%20user%20event%20&%20prevent%20double%20clicks%20from%20adding%20more%20animations%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(e.isTrusted%20&&%20!clicked)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20e.stopPropagation();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.isUnblocked%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clicked%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20isLogin%20=%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Logins%20triggered%20by%20user%20click%20means%20they%20were%20not%20triggered%20by%20the%20surrogate%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20isSurrogateLogin%20=%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20clickElement%20=%20e.srcElement;%20//%20Object.assign(%7B%7D,%20e)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.replaceSettings.type%20===%20'loginButton')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20isLogin%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20action%20=%20this.entity%20===%20'Youtube'%20?%20'block-ctl-yt'%20:%20'block-ctl-fb';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20promise/prefer-await-to-then%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unblockClickToLoadContent(%7B%20entity:%20this.entity,%20action,%20isLogin,%20isSurrogateLogin%20%7D).then((response)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20user%20rejected%20confirmation%20modal%20and%20content%20was%20not%20unblocked,%20inform%20surrogate%20and%20stop.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(response%20&&%20response.type%20===%20'ddg-ctp-user-cancel')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20abortSurrogateConfirmation(this.entity);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20parent%20=%20replacementElement.parentNode;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20The%20placeholder%20was%20removed%20from%20the%20DOM%20while%20we%20loaded%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20the%20original%20content,%20give%20up.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!parent)%20return;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20we%20allow%20everything%20when%20this%20element%20is%20clicked,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20notify%20surrogate%20to%20enable%20SDK%20and%20replace%20original%20element.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.clickAction.type%20===%20'allowFull')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20parent.replaceChild(originalElement,%20replacementElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.dispatchEvent(window,%20'ddg-ctp-load-sdk');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Create%20a%20container%20for%20the%20new%20FB%20element%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20fbContainer%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbContainer.style.cssText%20=%20styles.wrapperDiv;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20fadeIn%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fadeIn.style.cssText%20=%20'display:%20none;%20opacity:%200;';%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Loading%20animation%20(FB%20can%20take%20some%20time%20to%20load)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20loadingImg%20=%20document.createElement('img');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loadingImg.setAttribute('src',%20loadingImages%5Bthis.getMode()%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loadingImg.setAttribute('height',%20'14px');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loadingImg.style.cssText%20=%20styles.loadingImg;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Always%20add%20the%20animation%20to%20the%20button,%20regardless%20of%20click%20source%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(clickElement.nodeName%20===%20'BUTTON')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickElement.firstElementChild.insertBefore(loadingImg,%20clickElement.firstElementChild.firstChild);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20try%20to%20find%20the%20button%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20el%20=%20clickElement;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20button%20=%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20while%20(button%20===%20null%20&&%20el%20!==%20null)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20button%20=%20el.querySelector('button');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20el%20=%20el.parentElement;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(button)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20button.firstElementChild.insertBefore(loadingImg,%20button.firstElementChild.firstChild);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbContainer.appendChild(fadeIn);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20fbElement;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20onError%20=%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20switch%20(this.clickAction.type)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20case%20'iFrame':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbElement%20=%20this.createFBIFrame();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20case%20'youtube-video':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20onError%20=%20this.adjustYouTubeVideoElement(originalElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbElement%20=%20originalElement;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbElement%20=%20originalElement;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Modify%20the%20overlay%20to%20include%20a%20Facebook%20iFrame,%20which%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20starts%20invisible.%20Once%20loaded,%20fade%20out%20and%20remove%20the%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20overlay%20then%20fade%20in%20the%20Facebook%20content.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20parent.replaceChild(fbContainer,%20replacementElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbContainer.appendChild(replacementElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fadeIn.appendChild(fbElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbElement.addEventListener(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'load',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20async%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20await%20this.fadeOutElement(replacementElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbContainer.replaceWith(fbElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.dispatchEvent(fbElement,%20'ddg-ctp-placeholder-clicked');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20await%20this.fadeInElement(fadeIn);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Focus%20on%20new%20element%20for%20screen%20readers.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbElement.focus();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20once:%20true%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Note:%20This%20event%20only%20fires%20on%20Firefox,%20on%20Chrome%20the%20frame's%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20load%20event%20will%20always%20fire.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(onError)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbElement.addEventListener('error',%20onError,%20%7B%20once:%20true%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20this%20is%20a%20login%20button,%20show%20modal%20if%20needed%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.replaceSettings.type%20===%20'loginButton'%20&&%20entityData%5Bthis.entity%5D.shouldShowLoginModal)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20(e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Even%20if%20the%20user%20cancels%20the%20login%20attempt,%20consider%20Facebook%20Click%20to%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Load%20to%20have%20been%20active%20on%20the%20page%20if%20the%20user%20reports%20the%20page%20as%20broken.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.entity%20===%20'Facebook,%20Inc.')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20notifyFacebookLogin();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20handleUnblockConfirmation(this.platform.name,%20this.entity,%20handleClick,%20e);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20handleClick;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Based%20on%20the%20current%20Platform%20where%20the%20Widget%20is%20running,%20it%20will%0A%20%20%20%20%20%20%20%20%20*%20return%20if%20the%20new%20layout%20using%20Web%20Components%20is%20supported%20or%20not.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20shouldUseCustomElement()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20platformsWithWebComponentsEnabled.includes(this.platform.name);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Based%20on%20the%20current%20Platform%20where%20the%20Widget%20is%20running,%20it%20will%0A%20%20%20%20%20%20%20%20%20*%20return%20if%20it%20is%20one%20of%20our%20mobile%20apps%20or%20not.%20This%20should%20be%20used%20to%0A%20%20%20%20%20%20%20%20%20*%20define%20which%20layout%20to%20use%20between%20Mobile%20and%20Desktop%20Platforms%20variations.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20isMobilePlatform()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20mobilePlatforms.includes(this.platform.name);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Replace%20the%20given%20tracking%20element%20with%20the%20given%20placeholder.%0A%20%20%20%20%20*%20Notes:%0A%20%20%20%20%20*%20%201.%20This%20function%20also%20dispatches%20events%20targeting%20the%20original%20and%0A%20%20%20%20%20*%20%20%20%20%20placeholder%20elements.%20That%20way,%20the%20surrogate%20scripts%20can%20use%20the%20event%0A%20%20%20%20%20*%20%20%20%20%20targets%20to%20keep%20track%20of%20which%20placeholder%20corresponds%20to%20which%20tracking%0A%20%20%20%20%20*%20%20%20%20%20element.%0A%20%20%20%20%20*%20%202.%20To%20achieve%20that,%20the%20original%20and%20placeholder%20elements%20must%20be%20in%20the%20DOM%0A%20%20%20%20%20*%20%20%20%20%20at%20the%20time%20the%20events%20are%20dispatched.%20Otherwise,%20the%20events%20will%20not%0A%20%20%20%20%20*%20%20%20%20%20bubble%20up%20and%20the%20surrogate%20script%20will%20miss%20them.%0A%20%20%20%20%20*%20%203.%20Placeholder%20must%20be%20shown%20immediately%20(to%20avoid%20a%20flicker%20for%20the%20user),%0A%20%20%20%20%20*%20%20%20%20%20but%20the%20events%20must%20only%20be%20sent%20once%20the%20document%20(and%20therefore%0A%20%20%20%20%20*%20%20%20%20%20surrogate%20scripts)%20have%20loaded.%0A%20%20%20%20%20*%20%204.%20Therefore,%20we%20hide%20the%20element%20until%20the%20page%20has%20loaded,%20then%20dispatch%0A%20%20%20%20%20*%20%20%20%20%20the%20events%20after%20page%20load,%20and%20then%20remove%20the%20element%20from%20the%20DOM.%0A%20%20%20%20%20*%20%205.%20The%20%22ddg-ctp-ready%22%20event%20needs%20to%20be%20dispatched%20_after_%20the%20element%0A%20%20%20%20%20*%20%20%20%20%20replacement%20events%20have%20fired.%20That%20is%20why%20a%20setTimeout%20is%20required%0A%20%20%20%20%20*%20%20%20%20%20before%20dispatching%20%22ddg-ctp-ready%22.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%20Also%20note,%20this%20all%20assumes%20that%20the%20surrogate%20script%20that%20needs%20these%0A%20%20%20%20%20*%20%20events%20will%20not%20be%20loaded%20asynchronously%20after%20the%20page%20has%20finished%0A%20%20%20%20%20*%20%20loading.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@param%20%7BDuckWidget%7D%20widget%0A%20%20%20%20%20*%20%20%20The%20DuckWidget%20associated%20with%20the%20tracking%20element.%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20trackingElement%0A%20%20%20%20%20*%20%20%20The%20tracking%20element%20on%20the%20page%20to%20replace.%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20placeholderElement%0A%20%20%20%20%20*%20%20%20The%20placeholder%20element%20that%20should%20be%20shown%20instead.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20replaceTrackingElement(widget,%20trackingElement,%20placeholderElement)%20%7B%0A%20%20%20%20%20%20%20%20//%20In%20some%20situations%20(e.g.%20YouTube%20Click%20to%20Load%20previews%20are%0A%20%20%20%20%20%20%20%20//%20enabled/disabled),%20a%20second%20placeholder%20will%20be%20shown%20for%20a%20tracking%0A%20%20%20%20%20%20%20%20//%20element.%0A%20%20%20%20%20%20%20%20const%20elementToReplace%20=%20widget.placeholderElement%20%7C%7C%20trackingElement;%0A%0A%20%20%20%20%20%20%20%20//%20Note%20the%20placeholder%20element,%20so%20that%20it%20can%20also%20be%20replaced%20later%20if%0A%20%20%20%20%20%20%20%20//%20necessary.%0A%20%20%20%20%20%20%20%20widget.placeholderElement%20=%20placeholderElement;%0A%0A%20%20%20%20%20%20%20%20//%20First%20hide%20the%20element,%20since%20we%20need%20to%20keep%20it%20in%20the%20DOM%20until%20the%0A%20%20%20%20%20%20%20%20//%20events%20have%20been%20dispatched.%0A%20%20%20%20%20%20%20%20const%20originalDisplay%20=%20%5BelementToReplace.style.getPropertyValue('display'),%20elementToReplace.style.getPropertyPriority('display')%5D;%0A%20%20%20%20%20%20%20%20elementToReplace.style.setProperty('display',%20'none',%20'important');%0A%0A%20%20%20%20%20%20%20%20//%20Add%20the%20placeholder%20element%20to%20the%20page.%0A%20%20%20%20%20%20%20%20elementToReplace.parentElement.insertBefore(placeholderElement,%20elementToReplace);%0A%0A%20%20%20%20%20%20%20%20//%20While%20the%20placeholder%20is%20shown%20(and%20original%20element%20hidden)%0A%20%20%20%20%20%20%20%20//%20synchronously,%20the%20events%20are%20dispatched%20(and%20original%20element%20removed%0A%20%20%20%20%20%20%20%20//%20from%20the%20DOM)%20asynchronously%20after%20the%20page%20has%20finished%20loading.%0A%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20promise/prefer-await-to-then%0A%20%20%20%20%20%20%20%20afterPageLoad.then(()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20With%20page%20load%20complete,%20and%20both%20elements%20in%20the%20DOM,%20the%20events%20can%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20be%20dispatched.%0A%20%20%20%20%20%20%20%20%20%20%20%20widget.dispatchEvent(trackingElement,%20'ddg-ctp-tracking-element');%0A%20%20%20%20%20%20%20%20%20%20%20%20widget.dispatchEvent(placeholderElement,%20'ddg-ctp-placeholder-element');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Once%20the%20events%20are%20sent,%20the%20tracking%20element%20(or%20previous%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20placeholder)%20can%20finally%20be%20removed%20from%20the%20DOM.%0A%20%20%20%20%20%20%20%20%20%20%20%20elementToReplace.remove();%0A%20%20%20%20%20%20%20%20%20%20%20%20elementToReplace.style.setProperty('display',%20...originalDisplay);%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Creates%20a%20placeholder%20element%20for%20the%20given%20tracking%20element%20and%20replaces%0A%20%20%20%20%20*%20it%20on%20the%20page.%0A%20%20%20%20%20*%20@param%20%7BDuckWidget%7D%20widget%0A%20%20%20%20%20*%20%20%20The%20CTL%20'widget'%20associated%20with%20the%20tracking%20element.%0A%20%20%20%20%20*%20@param%20%7BHTMLIFrameElement%7D%20trackingElement%0A%20%20%20%20%20*%20%20%20The%20tracking%20element%20on%20the%20page%20that%20should%20be%20replaced%20with%20a%20placeholder.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20createPlaceholderElementAndReplace(widget,%20trackingElement)%20%7B%0A%20%20%20%20%20%20%20%20if%20(widget.replaceSettings.type%20===%20'blank')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20replaceTrackingElement(widget,%20trackingElement,%20document.createElement('div'));%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if%20(widget.replaceSettings.type%20===%20'loginButton')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20icon%20=%20widget.replaceSettings.icon;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Create%20a%20button%20to%20replace%20old%20element%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(widget.shouldUseCustomElement())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20facebookLoginButton%20=%20new%20DDGCtlLoginButton(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20devMode,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20label:%20widget.replaceSettings.buttonTextUnblockLogin,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hoverText:%20widget.replaceSettings.popupBodyText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20logoIcon:%20facebookLogo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20originalElement:%20trackingElement,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20learnMore:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Localized%20strings%20for%20%22Learn%20More%22%20link.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20readAbout:%20sharedStrings.readAbout,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20learnMore:%20sharedStrings.learnMore,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20onClick:%20widget.clickFunction.bind(widget),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D).element;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20facebookLoginButton.classList.add('fb-login-button',%20'FacebookLogin__button');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20facebookLoginButton.appendChild(makeFontFaceStyleElement());%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceTrackingElement(widget,%20trackingElement,%20facebookLoginButton);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20button,%20container%20%7D%20=%20makeLoginButton(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20widget.replaceSettings.buttonText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20widget.getMode(),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20widget.replaceSettings.popupBodyText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20icon,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20trackingElement,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20button.addEventListener('click',%20widget.clickFunction(trackingElement,%20container));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceTrackingElement(widget,%20trackingElement,%20container);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Facebook%0A%20%20%20%20%20%20%20%20if%20(widget.replaceSettings.type%20===%20'dialog')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20ctl.addDebugFlag();%0A%20%20%20%20%20%20%20%20%20%20%20%20ctl.messaging.notify('updateFacebookCTLBreakageFlags',%20%7B%20ctlFacebookPlaceholderShown:%20true%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(widget.shouldUseCustomElement())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Creates%20a%20custom%20HTML%20element%20with%20the%20placeholder%20element%20for%20blocked%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20embedded%20content.%20The%20constructor%20gets%20a%20list%20of%20parameters%20with%20the%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20content%20and%20event%20handlers%20for%20this%20HTML%20element.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20mobileBlockedPlaceholder%20=%20new%20DDGCtlPlaceholderBlockedElement(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20devMode,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20title:%20widget.replaceSettings.infoTitle,%20//%20Card%20title%20text%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20body:%20widget.replaceSettings.infoText,%20//%20Card%20body%20text%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unblockBtnText:%20widget.replaceSettings.buttonText,%20//%20Unblock%20button%20text%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20useSlimCard:%20false,%20//%20Flag%20for%20using%20less%20padding%20on%20card%20(ie%20YT%20CTL%20on%20mobile)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20originalElement:%20trackingElement,%20//%20The%20original%20element%20this%20placeholder%20is%20replacing.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20learnMore:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Localized%20strings%20for%20%22Learn%20More%22%20link.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20readAbout:%20sharedStrings.readAbout,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20learnMore:%20sharedStrings.learnMore,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20onButtonClick:%20widget.clickFunction.bind(widget),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mobileBlockedPlaceholder.appendChild(makeFontFaceStyleElement());%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceTrackingElement(widget,%20trackingElement,%20mobileBlockedPlaceholder);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20showExtraUnblockIfShortPlaceholder(null,%20mobileBlockedPlaceholder);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20icon%20=%20widget.replaceSettings.icon;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20button%20=%20makeButton(widget.replaceSettings.buttonText,%20widget.getMode());%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20textButton%20=%20makeTextButton(widget.replaceSettings.buttonText,%20widget.getMode());%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20contentBlock,%20shadowRoot%20%7D%20=%20createContentBlock(widget,%20button,%20textButton,%20icon);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20button.addEventListener('click',%20widget.clickFunction(trackingElement,%20contentBlock));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20textButton.addEventListener('click',%20widget.clickFunction(trackingElement,%20contentBlock));%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceTrackingElement(widget,%20trackingElement,%20contentBlock);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20showExtraUnblockIfShortPlaceholder(shadowRoot,%20contentBlock);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20YouTube%0A%20%20%20%20%20%20%20%20if%20(widget.replaceSettings.type%20===%20'youtube-video')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20ctl.addDebugFlag();%0A%20%20%20%20%20%20%20%20%20%20%20%20ctl.messaging.notify('updateYouTubeCTLAddedFlag',%20%7B%20youTubeCTLAddedFlag:%20true%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20replaceYouTubeCTL(trackingElement,%20widget);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Subscribe%20to%20changes%20to%20youtubePreviewsEnabled%20setting%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20and%20update%20the%20CTL%20state%0A%20%20%20%20%20%20%20%20%20%20%20%20ctl.messaging.subscribe('setYoutubePreviewsEnabled',%20(%7B%20value%20%7D)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20isYoutubePreviewsEnabled%20=%20value;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceYouTubeCTL(trackingElement,%20widget);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7BHTMLIFrameElement%7D%20trackingElement%0A%20%20%20%20%20*%20%20%20The%20original%20tracking%20element%20(YouTube%20video%20iframe)%0A%20%20%20%20%20*%20@param%20%7BDuckWidget%7D%20widget%0A%20%20%20%20%20*%20%20%20The%20CTL%20'widget'%20associated%20with%20the%20tracking%20element.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20replaceYouTubeCTL(trackingElement,%20widget)%20%7B%0A%20%20%20%20%20%20%20%20//%20Skip%20replacing%20tracking%20element%20if%20it%20has%20already%20been%20unblocked%0A%20%20%20%20%20%20%20%20if%20(widget.isUnblocked)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if%20(isYoutubePreviewsEnabled%20===%20true)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Show%20YouTube%20Preview%20for%20embedded%20video%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20oldPlaceholder%20=%20widget.placeholderElement;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20youTubePreview,%20shadowRoot%20%7D%20=%20createYouTubePreview(trackingElement,%20widget);%0A%20%20%20%20%20%20%20%20%20%20%20%20resizeElementToMatch(oldPlaceholder%20%7C%7C%20trackingElement,%20youTubePreview);%0A%20%20%20%20%20%20%20%20%20%20%20%20replaceTrackingElement(widget,%20trackingElement,%20youTubePreview);%0A%20%20%20%20%20%20%20%20%20%20%20%20showExtraUnblockIfShortPlaceholder(shadowRoot,%20youTubePreview);%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Block%20YouTube%20embedded%20video%20and%20display%20blocking%20dialog%0A%20%20%20%20%20%20%20%20%20%20%20%20widget.autoplay%20=%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20oldPlaceholder%20=%20widget.placeholderElement;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(widget.shouldUseCustomElement())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Creates%20a%20custom%20HTML%20element%20with%20the%20placeholder%20element%20for%20blocked%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20embedded%20content.%20The%20constructor%20gets%20a%20list%20of%20parameters%20with%20the%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20content%20and%20event%20handlers%20for%20this%20HTML%20element.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20mobileBlockedPlaceholderElement%20=%20new%20DDGCtlPlaceholderBlockedElement(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20devMode,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20title:%20widget.replaceSettings.infoTitle,%20//%20Card%20title%20text%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20body:%20widget.replaceSettings.infoText,%20//%20Card%20body%20text%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unblockBtnText:%20widget.replaceSettings.buttonText,%20//%20Unblock%20button%20text%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20useSlimCard:%20true,%20//%20Flag%20for%20using%20less%20padding%20on%20card%20(ie%20YT%20CTL%20on%20mobile)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20originalElement:%20trackingElement,%20//%20The%20original%20element%20this%20placeholder%20is%20replacing.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20learnMore:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Localized%20strings%20for%20%22Learn%20More%22%20link.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20readAbout:%20sharedStrings.readAbout,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20learnMore:%20sharedStrings.learnMore,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20withToggle:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Toggle%20config%20to%20be%20displayed%20in%20the%20bottom%20of%20the%20placeholder%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20isActive:%20false,%20//%20Toggle%20state%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20dataKey:%20'yt-preview-toggle',%20//%20data-key%20attribute%20for%20button%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20label:%20widget.replaceSettings.previewToggleText,%20//%20Text%20to%20be%20presented%20with%20toggle%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20size:%20widget.isMobilePlatform()%20?%20'lg'%20:%20'md',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20onClick:%20()%20=%3E%20ctl.messaging.notify('setYoutubePreviewsEnabled',%20%7B%20youtubePreviewsEnabled:%20true%20%7D),%20//%20Toggle%20click%20callback%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20withFeedback:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20label:%20sharedStrings.shareFeedback,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20onClick:%20()%20=%3E%20openShareFeedbackPage(),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20onButtonClick:%20widget.clickFunction.bind(widget),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mobileBlockedPlaceholderElement.appendChild(makeFontFaceStyleElement());%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mobileBlockedPlaceholderElement.id%20=%20trackingElement.id;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resizeElementToMatch(oldPlaceholder%20%7C%7C%20trackingElement,%20mobileBlockedPlaceholderElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceTrackingElement(widget,%20trackingElement,%20mobileBlockedPlaceholderElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20showExtraUnblockIfShortPlaceholder(null,%20mobileBlockedPlaceholderElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20blockingDialog,%20shadowRoot%20%7D%20=%20createYouTubeBlockingDialog(trackingElement,%20widget);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resizeElementToMatch(oldPlaceholder%20%7C%7C%20trackingElement,%20blockingDialog);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceTrackingElement(widget,%20trackingElement,%20blockingDialog);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20showExtraUnblockIfShortPlaceholder(shadowRoot,%20blockingDialog);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hideInfoTextIfNarrowPlaceholder(shadowRoot,%20blockingDialog,%20460);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Show%20the%20extra%20unblock%20link%20in%20the%20header%20if%20the%20placeholder%20or%0A%20%20%20%20%20*%20its%20parent%20is%20too%20short%20for%20the%20normal%20unblock%20button%20to%20be%20visible.%0A%20%20%20%20%20*%20Note:%20This%20does%20not%20take%20into%20account%20the%20placeholder's%20vertical%0A%20%20%20%20%20*%20%20%20%20%20%20%20position%20in%20the%20parent%20element.%0A%20%20%20%20%20*%20@param%20%7BShadowRoot?%7D%20shadowRoot%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20placeholder%20Placeholder%20for%20tracking%20element%0A%20%20%20%20%20*/%0A%20%20%20%20function%20showExtraUnblockIfShortPlaceholder(shadowRoot,%20placeholder)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!placeholder.parentElement)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20const%20parentStyles%20=%20window.getComputedStyle(placeholder.parentElement);%0A%20%20%20%20%20%20%20%20//%20Inline%20elements,%20like%20span%20or%20p,%20don't%20have%20a%20height%20value%20that%20we%20can%20use%20because%20they're%0A%20%20%20%20%20%20%20%20//%20not%20a%20%22block%22%20like%20element%20with%20defined%20sizes.%20Because%20we%20skip%20this%20check%20on%20%22inline%22%0A%20%20%20%20%20%20%20%20//%20parents,%20it%20might%20be%20necessary%20to%20traverse%20up%20the%20DOM%20tree%20until%20we%20find%20the%20nearest%20non%0A%20%20%20%20%20%20%20%20//%20%22inline%22%20parent%20to%20get%20a%20reliable%20height%20for%20this%20check.%0A%20%20%20%20%20%20%20%20if%20(parentStyles.display%20===%20'inline')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20const%20%7B%20height:%20placeholderHeight%20%7D%20=%20placeholder.getBoundingClientRect();%0A%20%20%20%20%20%20%20%20const%20%7B%20height:%20parentHeight%20%7D%20=%20placeholder.parentElement.getBoundingClientRect();%0A%0A%20%20%20%20%20%20%20%20if%20((placeholderHeight%20%3E%200%20&&%20placeholderHeight%20%3C=%20200)%20%7C%7C%20(parentHeight%20%3E%200%20&&%20parentHeight%20%3C=%20230))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(shadowRoot)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7BHTMLElement?%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20titleRowTextButton%20=%20shadowRoot.querySelector(%60#$%7BtitleID%20+%20'TextButton'%7D%60);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(titleRowTextButton)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20titleRowTextButton.style.display%20=%20'block';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Avoid%20the%20placeholder%20being%20taller%20than%20the%20containing%20element%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20and%20overflowing.%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7BHTMLElement?%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20blockedDiv%20=%20shadowRoot?.querySelector('.DuckDuckGoSocialContainer')%20%7C%7C%20placeholder;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(blockedDiv)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20blockedDiv.style.minHeight%20=%20'initial';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20blockedDiv.style.maxHeight%20=%20parentHeight%20+%20'px';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20blockedDiv.style.overflow%20=%20'hidden';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Hide%20the%20info%20text%20(and%20move%20the%20%22Learn%20More%22%20link)%20if%20the%20placeholder%20is%20too%0A%20%20%20%20%20*%20narrow.%0A%20%20%20%20%20*%20@param%20%7BShadowRoot%7D%20shadowRoot%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20placeholder%20Placeholder%20for%20tracking%20element%0A%20%20%20%20%20*%20@param%20%7Bnumber%7D%20narrowWidth%0A%20%20%20%20%20*%20%20%20%20Maximum%20placeholder%20width%20(in%20pixels)%20for%20the%20placeholder%20to%20be%20considered%0A%20%20%20%20%20*%20%20%20%20narrow.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20hideInfoTextIfNarrowPlaceholder(shadowRoot,%20placeholder,%20narrowWidth)%20%7B%0A%20%20%20%20%20%20%20%20const%20%7B%20width:%20placeholderWidth%20%7D%20=%20placeholder.getBoundingClientRect();%0A%20%20%20%20%20%20%20%20if%20(placeholderWidth%20%3E%200%20&&%20placeholderWidth%20%3C=%20narrowWidth)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20buttonContainer%20=%20shadowRoot.querySelector('.DuckDuckGoButton.primary')?.parentElement;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20contentTitle%20=%20shadowRoot.getElementById('contentTitle');%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20infoText%20=%20shadowRoot.getElementById('infoText');%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7BHTMLElement?%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20learnMoreLink%20=%20shadowRoot.getElementById('learnMoreLink');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20These%20elements%20will%20exist,%20but%20this%20check%20keeps%20TypeScript%20happy.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!buttonContainer%20%7C%7C%20!contentTitle%20%7C%7C%20!infoText%20%7C%7C%20!learnMoreLink)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Remove%20the%20information%20text.%0A%20%20%20%20%20%20%20%20%20%20%20%20infoText.remove();%0A%20%20%20%20%20%20%20%20%20%20%20%20learnMoreLink.remove();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Append%20the%20%22Learn%20More%22%20link%20to%20the%20title.%0A%20%20%20%20%20%20%20%20%20%20%20%20contentTitle.innerText%20+=%20'.%20';%0A%20%20%20%20%20%20%20%20%20%20%20%20learnMoreLink.style.removeProperty('font-size');%0A%20%20%20%20%20%20%20%20%20%20%20%20contentTitle.appendChild(learnMoreLink);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Improve%20margin/padding,%20to%20ensure%20as%20much%20is%20displayed%20as%20possible.%0A%20%20%20%20%20%20%20%20%20%20%20%20buttonContainer.style.removeProperty('margin');%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/*********************************************************%0A%20%20%20%20%20*%20%20Messaging%20to%20surrogates%20&%20extension%0A%20%20%20%20%20*********************************************************/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20unblockClickToLoadContentRequest%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20entity%0A%20%20%20%20%20*%20%20%20The%20entity%20to%20unblock%20requests%20for%20(e.g.%20%22Facebook,%20Inc.%22).%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20%5BisLogin=false%5D%0A%20%20%20%20%20*%20%20%20True%20if%20we%20should%20%22allow%20social%20login%22,%20defaults%20to%20false.%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20%5BisSurrogateLogin=false%5D%0A%20%20%20%20%20*%20%20%20True%20if%20logins%20triggered%20by%20the%20surrogate%20(custom%20login),%20False%20if%20login%20trigger%0A%20%20%20%20%20*%20%20%20by%20user%20clicking%20in%20our%20Login%20button%20placeholder.%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20action%0A%20%20%20%20%20*%20%20%20The%20Click%20to%20Load%20blocklist%20rule%20action%20(e.g.%20%22block-ctl-fb%22)%20that%20should%0A%20%20%20%20%20*%20%20%20be%20allowed.%20Important%20since%20in%20the%20future%20there%20might%20be%20multiple%20types%20of%0A%20%20%20%20%20*%20%20%20embedded%20content%20from%20the%20same%20entity%20that%20the%20user%20can%20allow%0A%20%20%20%20%20*%20%20%20independently.%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Send%20a%20message%20to%20the%20background%20to%20unblock%20requests%20for%20the%20given%20entity%20for%0A%20%20%20%20%20*%20the%20page.%0A%20%20%20%20%20*%20@param%20%7BunblockClickToLoadContentRequest%7D%20message%0A%20%20%20%20%20*%20@see%20%7B@link%20ddg-ctp-unblockClickToLoadContent-complete%7D%20for%20the%20response%20handler.%0A%20%20%20%20%20*%20@returns%20%7BPromise%3Cany%3E%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20unblockClickToLoadContent(message)%20%7B%0A%20%20%20%20%20%20%20%20return%20ctl.messaging.request('unblockClickToLoadContent',%20message);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Handle%20showing%20a%20web%20modal%20to%20request%20the%20user%20for%20a%20confirmation%20or,%20in%20some%20platforms,%0A%20%20%20%20%20*%20proceed%20with%20the%20%22acceptFunction%22%20call%20and%20let%20the%20platform%20handle%20with%20each%20request%0A%20%20%20%20%20*%20accordingly.%0A%20%20%20%20%20*%20@param%20%7Bimport('../utils').Platform%5B%22name%22%5D%7D%20platformName%0A%20%20%20%20%20*%20%20%20The%20current%20platform%20name%20where%20Click%20to%20Load%20is%20running%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20entity%0A%20%20%20%20%20*%20%20%20The%20entity%20to%20unblock%20requests%20for%20(e.g.%20%22Facebook,%20Inc.%22)%20if%20the%20user%0A%20%20%20%20%20*%20%20%20clicks%20to%20proceed.%0A%20%20%20%20%20*%20@param%20%7Bfunction%7D%20acceptFunction%0A%20%20%20%20%20*%20%20%20The%20function%20to%20call%20if%20the%20user%20has%20clicked%20to%20proceed.%0A%20%20%20%20%20*%20@param%20%7B...any%7D%20acceptFunctionParams%0A%20%20%20%20%20*%20%20%20The%20parameters%20passed%20to%20acceptFunction%20when%20it%20is%20called.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20handleUnblockConfirmation(platformName,%20entity,%20acceptFunction,%20...acceptFunctionParams)%20%7B%0A%20%20%20%20%20%20%20%20//%20In%20our%20mobile%20platforms,%20we%20want%20to%20show%20a%20native%20UI%20to%20request%20user%20unblock%0A%20%20%20%20%20%20%20%20//%20confirmation.%20In%20these%20cases%20we%20send%20directly%20the%20unblock%20request%20to%20the%20platform%0A%20%20%20%20%20%20%20%20//%20and%20the%20platform%20chooses%20how%20to%20best%20handle%20it.%0A%20%20%20%20%20%20%20%20if%20(platformsWithNativeModalSupport.includes(platformName))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20acceptFunction(...acceptFunctionParams);%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20By%20default,%20for%20other%20platforms%20(ie%20Extension),%20we%20show%20a%20web%20modal%20with%20a%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20confirmation%20request%20to%20the%20user%20before%20we%20proceed%20to%20unblock%20the%20content.%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20makeModal(entity,%20acceptFunction,%20...acceptFunctionParams);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Set%20the%20ctlFacebookLogin%20breakage%20flag%20for%20the%20page,%20to%20indicate%20that%20the%0A%20%20%20%20%20*%20Facebook%20Click%20to%20Load%20login%20flow%20had%20started%20if%20the%20user%20should%20then%20report%0A%20%20%20%20%20*%20the%20website%20as%20broken.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20notifyFacebookLogin()%20%7B%0A%20%20%20%20%20%20%20%20ctl.addDebugFlag();%0A%20%20%20%20%20%20%20%20ctl.messaging.notify('updateFacebookCTLBreakageFlags',%20%7B%20ctlFacebookLogin:%20true%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Unblock%20the%20entity,%20close%20the%20login%20dialog%20and%20continue%20the%20Facebook%20login%0A%20%20%20%20%20*%20flow.%20Called%20after%20the%20user%20clicks%20to%20proceed%20after%20the%20warning%20dialog%20is%0A%20%20%20%20%20*%20shown.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20entity%0A%20%20%20%20%20*/%0A%20%20%20%20async%20function%20runLogin(entity)%20%7B%0A%20%20%20%20%20%20%20%20if%20(entity%20===%20'Facebook,%20Inc.')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20notifyFacebookLogin();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20action%20=%20entity%20===%20'Youtube'%20?%20'block-ctl-yt'%20:%20'block-ctl-fb';%0A%20%20%20%20%20%20%20%20const%20response%20=%20await%20unblockClickToLoadContent(%7B%20entity,%20action,%20isLogin:%20true,%20isSurrogateLogin:%20true%20%7D);%0A%20%20%20%20%20%20%20%20//%20If%20user%20rejected%20confirmation%20modal%20and%20content%20was%20not%20unblocked,%20inform%20surrogate%20and%20stop.%0A%20%20%20%20%20%20%20%20if%20(response%20&&%20response.type%20===%20'ddg-ctp-user-cancel')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20abortSurrogateConfirmation(this.entity);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20//%20Communicate%20with%20surrogate%20to%20run%20login%0A%20%20%20%20%20%20%20%20originalWindowDispatchEvent(%0A%20%20%20%20%20%20%20%20%20%20%20%20createCustomEvent('ddg-ctp-run-login',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20detail:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20entity,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D),%0A%20%20%20%20%20%20%20%20);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Communicate%20with%20the%20surrogate%20to%20abort%20(ie%20Abort%20login%20when%20user%20rejects%20confirmation%20dialog)%0A%20%20%20%20%20*%20Called%20after%20the%20user%20cancel%20from%20a%20warning%20dialog.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20entity%0A%20%20%20%20%20*/%0A%20%20%20%20function%20abortSurrogateConfirmation(entity)%20%7B%0A%20%20%20%20%20%20%20%20originalWindowDispatchEvent(%0A%20%20%20%20%20%20%20%20%20%20%20%20createCustomEvent('ddg-ctp-cancel-modal',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20detail:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20entity,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D),%0A%20%20%20%20%20%20%20%20);%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20openShareFeedbackPage()%20%7B%0A%20%20%20%20%20%20%20%20ctl.messaging.notify('openShareFeedbackPage');%0A%20%20%20%20%7D%0A%0A%20%20%20%20/*********************************************************%0A%20%20%20%20%20*%20%20Widget%20building%20blocks%0A%20%20%20%20%20*********************************************************/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Creates%20a%20%22Learn%20more%22%20link%20element.%0A%20%20%20%20%20*%20@param%20%7BdisplayMode%7D%20%5Bmode='lightMode'%5D%0A%20%20%20%20%20*%20@returns%20%7BHTMLAnchorElement%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20getLearnMoreLink(mode%20=%20'lightMode')%20%7B%0A%20%20%20%20%20%20%20%20const%20linkElement%20=%20document.createElement('a');%0A%20%20%20%20%20%20%20%20linkElement.style.cssText%20=%20styles.generalLink%20+%20styles%5Bmode%5D.linkFont;%0A%20%20%20%20%20%20%20%20linkElement.ariaLabel%20=%20sharedStrings.readAbout;%0A%20%20%20%20%20%20%20%20linkElement.href%20=%20'https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/';%0A%20%20%20%20%20%20%20%20linkElement.target%20=%20'_blank';%0A%20%20%20%20%20%20%20%20linkElement.textContent%20=%20sharedStrings.learnMore;%0A%20%20%20%20%20%20%20%20linkElement.id%20=%20'learnMoreLink';%0A%20%20%20%20%20%20%20%20return%20linkElement;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Resizes%20and%20positions%20the%20target%20element%20to%20match%20the%20source%20element.%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20sourceElement%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20targetElement%0A%20%20%20%20%20*/%0A%20%20%20%20function%20resizeElementToMatch(sourceElement,%20targetElement)%20%7B%0A%20%20%20%20%20%20%20%20const%20computedStyle%20=%20window.getComputedStyle(sourceElement);%0A%20%20%20%20%20%20%20%20const%20stylesToCopy%20=%20%5B'position',%20'top',%20'bottom',%20'left',%20'right',%20'transform',%20'margin'%5D;%0A%0A%20%20%20%20%20%20%20%20//%20It's%20apparently%20preferable%20to%20use%20the%20source%20element's%20size%20relative%20to%0A%20%20%20%20%20%20%20%20//%20the%20current%20viewport,%20when%20resizing%20the%20target%20element.%20However,%20the%0A%20%20%20%20%20%20%20%20//%20declarativeNetRequest%20API%20%22collapses%22%20(hides)%20blocked%20elements.%20When%0A%20%20%20%20%20%20%20%20//%20that%20happens,%20getBoundingClientRect%20will%20return%20all%20zeros.%0A%20%20%20%20%20%20%20%20//%20TODO:%20Remove%20this%20entirely,%20and%20always%20use%20the%20computed%20height/width%20of%0A%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20the%20source%20element%20instead?%0A%20%20%20%20%20%20%20%20const%20%7B%20height,%20width%20%7D%20=%20sourceElement.getBoundingClientRect();%0A%20%20%20%20%20%20%20%20if%20(height%20%3E%200%20&&%20width%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20targetElement.style.height%20=%20height%20+%20'px';%0A%20%20%20%20%20%20%20%20%20%20%20%20targetElement.style.width%20=%20width%20+%20'px';%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20stylesToCopy.push('height',%20'width');%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20for%20(const%20key%20of%20stylesToCopy)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20targetElement.style%5Bkey%5D%20=%20computedStyle%5Bkey%5D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20If%20the%20parent%20element%20is%20very%20small%20(and%20its%20dimensions%20can%20be%20trusted)%20set%20a%20max%20height/width%0A%20%20%20%20%20%20%20%20//%20to%20avoid%20the%20placeholder%20overflowing.%0A%20%20%20%20%20%20%20%20if%20(computedStyle.display%20!==%20'inline')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(targetElement.style.maxHeight%20%3C%20computedStyle.height)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20targetElement.style.maxHeight%20=%20'initial';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(targetElement.style.maxWidth%20%3C%20computedStyle.width)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20targetElement.style.maxWidth%20=%20'initial';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20a%20%60%3Cstyle/%3E%60%20element%20with%20DDG%20font-face%20styles/CSS%0A%20%20%20%20%20*%20to%20be%20attached%20to%20DDG%20wrapper%20elements%0A%20%20%20%20%20*%20@returns%20HTMLStyleElement%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeFontFaceStyleElement()%20%7B%0A%20%20%20%20%20%20%20%20//%20Put%20our%20custom%20font-faces%20inside%20the%20wrapper%20element,%20since%0A%20%20%20%20%20%20%20%20//%20@font-face%20does%20not%20work%20inside%20a%20shadowRoot.%0A%20%20%20%20%20%20%20%20//%20See%20https://github.com/mdn/interactive-examples/issues/887.%0A%20%20%20%20%20%20%20%20const%20fontFaceStyleElement%20=%20document.createElement('style');%0A%20%20%20%20%20%20%20%20fontFaceStyleElement.textContent%20=%20styles.fontStyle;%0A%20%20%20%20%20%20%20%20return%20fontFaceStyleElement;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20a%20%60%3Cstyle/%3E%60%20element%20with%20base%20styles%20for%20DDG%20social%20container%20and%0A%20%20%20%20%20*%20button%20to%20be%20attached%20to%20DDG%20wrapper%20elements/shadowRoot,%20also%20returns%20a%20wrapper%0A%20%20%20%20%20*%20class%20name%20for%20Social%20Container%20link%20styles%0A%20%20%20%20%20*%20@param%20%7BdisplayMode%7D%20%5Bmode='lightMode'%5D%0A%20%20%20%20%20*%20@returns%20%7B%7BwrapperClass:%20string,%20styleElement:%20HTMLStyleElement;%20%7D%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeBaseStyleElement(mode%20=%20'lightMode')%20%7B%0A%20%20%20%20%20%20%20%20//%20Style%20element%20includes%20our%20font%20&%20overwrites%20page%20styles%0A%20%20%20%20%20%20%20%20const%20styleElement%20=%20document.createElement('style');%0A%20%20%20%20%20%20%20%20const%20wrapperClass%20=%20'DuckDuckGoSocialContainer';%0A%20%20%20%20%20%20%20%20styleElement.textContent%20=%20%60%0A%20%20%20%20%20%20%20%20.$%7BwrapperClass%7D%20a%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles%5Bmode%5D.linkFont%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20font-weight:%20bold;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.$%7BwrapperClass%7D%20a:hover%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles%5Bmode%5D.linkFont%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20font-weight:%20bold;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles.button%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton%20%3E%20div%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles.buttonTextContainer%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton.primary%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles%5Bmode%5D.buttonBackground%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton.primary%20%3E%20div%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles%5Bmode%5D.buttonFont%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton.primary:hover%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles%5Bmode%5D.buttonBackgroundHover%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton.primary:active%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles%5Bmode%5D.buttonBackgroundPress%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton.secondary%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles.cancelMode.buttonBackground%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton.secondary%20%3E%20div%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles.cancelMode.buttonFont%7D%0A%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton.secondary:hover%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles.cancelMode.buttonBackgroundHover%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton.secondary:active%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles.cancelMode.buttonBackgroundPress%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%60;%0A%20%20%20%20%20%20%20%20return%20%7B%20wrapperClass,%20styleElement%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Creates%20an%20anchor%20element%20with%20no%20destination.%20It%20is%20expected%20that%20a%20click%0A%20%20%20%20%20*%20handler%20is%20added%20to%20the%20element%20later.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20linkText%0A%20%20%20%20%20*%20@param%20%7BdisplayMode%7D%20mode%0A%20%20%20%20%20*%20@returns%20%7BHTMLAnchorElement%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeTextButton(linkText,%20mode%20=%20'lightMode')%20%7B%0A%20%20%20%20%20%20%20%20const%20linkElement%20=%20document.createElement('a');%0A%20%20%20%20%20%20%20%20linkElement.style.cssText%20=%20styles.headerLink%20+%20styles%5Bmode%5D.linkFont;%0A%20%20%20%20%20%20%20%20linkElement.textContent%20=%20linkText;%0A%20%20%20%20%20%20%20%20return%20linkElement;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20a%20button%20element.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20buttonText%0A%20%20%20%20%20*%20%20%20Text%20to%20be%20displayed%20inside%20the%20button.%0A%20%20%20%20%20*%20@param%20%7BdisplayMode%7D%20%5Bmode='lightMode'%5D%0A%20%20%20%20%20*%20%20%20The%20button%20is%20usually%20styled%20as%20the%20primary%20call%20to%20action,%20but%20if%0A%20%20%20%20%20*%20%20%20'cancelMode'%20is%20specified%20the%20button%20is%20styled%20as%20a%20secondary%20call%20to%0A%20%20%20%20%20*%20%20%20action.%0A%20%20%20%20%20*%20@returns%20%7BHTMLButtonElement%7D%20Button%20element%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeButton(buttonText,%20mode%20=%20'lightMode')%20%7B%0A%20%20%20%20%20%20%20%20const%20button%20=%20document.createElement('button');%0A%20%20%20%20%20%20%20%20button.classList.add('DuckDuckGoButton');%0A%20%20%20%20%20%20%20%20button.classList.add(mode%20===%20'cancelMode'%20?%20'secondary'%20:%20'primary');%0A%20%20%20%20%20%20%20%20if%20(buttonText)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20textContainer%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20%20%20%20%20textContainer.textContent%20=%20buttonText;%0A%20%20%20%20%20%20%20%20%20%20%20%20button.appendChild(textContainer);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20button;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20a%20toggle%20button.%0A%20%20%20%20%20*%20@param%20%7BdisplayMode%7D%20mode%0A%20%20%20%20%20*%20@param%20%7Bboolean%7D%20%5BisActive=false%5D%0A%20%20%20%20%20*%20%20%20True%20if%20the%20button%20should%20be%20toggled%20by%20default.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BclassNames=''%5D%0A%20%20%20%20%20*%20%20%20Class%20names%20to%20assign%20to%20the%20button%20(space%20delimited).%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BdataKey=''%5D%0A%20%20%20%20%20*%20%20%20Value%20to%20assign%20to%20the%20button's%20'data-key'%20attribute.%0A%20%20%20%20%20*%20@returns%20%7BHTMLButtonElement%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeToggleButton(mode,%20isActive%20=%20false,%20classNames%20=%20'',%20dataKey%20=%20'')%20%7B%0A%20%20%20%20%20%20%20%20const%20toggleButton%20=%20document.createElement('button');%0A%20%20%20%20%20%20%20%20toggleButton.className%20=%20classNames;%0A%20%20%20%20%20%20%20%20toggleButton.style.cssText%20=%20styles.toggleButton;%0A%20%20%20%20%20%20%20%20toggleButton.type%20=%20'button';%0A%20%20%20%20%20%20%20%20toggleButton.setAttribute('aria-pressed',%20isActive%20?%20'true'%20:%20'false');%0A%20%20%20%20%20%20%20%20toggleButton.setAttribute('data-key',%20dataKey);%0A%0A%20%20%20%20%20%20%20%20const%20activeKey%20=%20isActive%20?%20'active'%20:%20'inactive';%0A%0A%20%20%20%20%20%20%20%20const%20toggleBg%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20toggleBg.style.cssText%20=%20styles.toggleButtonBg%20+%20styles%5Bmode%5D.toggleButtonBgState%5BactiveKey%5D;%0A%0A%20%20%20%20%20%20%20%20const%20toggleKnob%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20toggleKnob.style.cssText%20=%20styles.toggleButtonKnob%20+%20styles.toggleButtonKnobState%5BactiveKey%5D;%0A%0A%20%20%20%20%20%20%20%20toggleButton.appendChild(toggleBg);%0A%20%20%20%20%20%20%20%20toggleButton.appendChild(toggleKnob);%0A%0A%20%20%20%20%20%20%20%20return%20toggleButton;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20a%20toggle%20button%20that's%20wrapped%20in%20a%20div%20with%20some%20text.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20text%0A%20%20%20%20%20*%20%20%20Text%20to%20display%20by%20the%20button.%0A%20%20%20%20%20*%20@param%20%7BdisplayMode%7D%20mode%0A%20%20%20%20%20*%20@param%20%7Bboolean%7D%20%5BisActive=false%5D%0A%20%20%20%20%20*%20%20%20True%20if%20the%20button%20should%20be%20toggled%20by%20default.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BtoggleClassNames=''%5D%0A%20%20%20%20%20*%20%20%20Class%20names%20to%20assign%20to%20the%20toggle%20button.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BtextCssStyles=''%5D%0A%20%20%20%20%20*%20%20%20Styles%20to%20apply%20to%20the%20wrapping%20div%20(on%20top%20of%20ones%20determined%20by%20the%0A%20%20%20%20%20*%20%20%20display%20mode.)%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BdataKey=''%5D%0A%20%20%20%20%20*%20%20%20Value%20to%20assign%20to%20the%20button's%20'data-key'%20attribute.%0A%20%20%20%20%20*%20@returns%20%7BHTMLDivElement%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeToggleButtonWithText(text,%20mode,%20isActive%20=%20false,%20toggleClassNames%20=%20'',%20textCssStyles%20=%20'',%20dataKey%20=%20'')%20%7B%0A%20%20%20%20%20%20%20%20const%20wrapper%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20wrapper.style.cssText%20=%20styles.toggleButtonWrapper;%0A%0A%20%20%20%20%20%20%20%20const%20toggleButton%20=%20makeToggleButton(mode,%20isActive,%20toggleClassNames,%20dataKey);%0A%0A%20%20%20%20%20%20%20%20const%20textDiv%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20textDiv.style.cssText%20=%20styles.contentText%20+%20styles.toggleButtonText%20+%20styles%5Bmode%5D.toggleButtonText%20+%20textCssStyles;%0A%20%20%20%20%20%20%20%20textDiv.textContent%20=%20text;%0A%0A%20%20%20%20%20%20%20%20wrapper.appendChild(toggleButton);%0A%20%20%20%20%20%20%20%20wrapper.appendChild(textDiv);%0A%20%20%20%20%20%20%20%20return%20wrapper;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20the%20default%20block%20symbol,%20for%20when%20the%20image%20isn't%20available.%0A%20%20%20%20%20*%20@returns%20%7BHTMLDivElement%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeDefaultBlockIcon()%20%7B%0A%20%20%20%20%20%20%20%20const%20blockedIcon%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20const%20dash%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20blockedIcon.appendChild(dash);%0A%20%20%20%20%20%20%20%20blockedIcon.style.cssText%20=%20styles.circle;%0A%20%20%20%20%20%20%20%20dash.style.cssText%20=%20styles.rectangle;%0A%20%20%20%20%20%20%20%20return%20blockedIcon;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Creates%20a%20share%20feedback%20link%20element.%0A%20%20%20%20%20*%20@returns%20%7BHTMLAnchorElement%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeShareFeedbackLink()%20%7B%0A%20%20%20%20%20%20%20%20const%20feedbackLink%20=%20document.createElement('a');%0A%20%20%20%20%20%20%20%20feedbackLink.style.cssText%20=%20styles.feedbackLink;%0A%20%20%20%20%20%20%20%20feedbackLink.target%20=%20'_blank';%0A%20%20%20%20%20%20%20%20feedbackLink.href%20=%20'#';%0A%20%20%20%20%20%20%20%20feedbackLink.text%20=%20sharedStrings.shareFeedback;%0A%20%20%20%20%20%20%20%20//%20Open%20Feedback%20Form%20page%20through%20background%20event%20to%20avoid%20browser%20blocking%20extension%20link%0A%20%20%20%20%20%20%20%20feedbackLink.addEventListener('click',%20function%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20e.preventDefault();%0A%20%20%20%20%20%20%20%20%20%20%20%20openShareFeedbackPage();%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20return%20feedbackLink;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Creates%20a%20share%20feedback%20link%20element,%20wrapped%20in%20a%20styled%20div.%0A%20%20%20%20%20*%20@returns%20%7BHTMLDivElement%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeShareFeedbackRow()%20%7B%0A%20%20%20%20%20%20%20%20const%20feedbackRow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20feedbackRow.style.cssText%20=%20styles.feedbackRow;%0A%0A%20%20%20%20%20%20%20%20const%20feedbackLink%20=%20makeShareFeedbackLink();%0A%20%20%20%20%20%20%20%20feedbackRow.appendChild(feedbackLink);%0A%0A%20%20%20%20%20%20%20%20return%20feedbackRow;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Creates%20a%20placeholder%20Facebook%20login%20button.%20When%20clicked,%20a%20warning%20dialog%0A%20%20%20%20%20*%20is%20displayed%20to%20the%20user.%20The%20login%20flow%20only%20continues%20if%20the%20user%20clicks%20to%0A%20%20%20%20%20*%20proceed.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20buttonText%0A%20%20%20%20%20*%20@param%20%7BdisplayMode%7D%20mode%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20hoverTextBody%0A%20%20%20%20%20*%20%20%20The%20hover%20text%20to%20display%20for%20the%20button.%0A%20%20%20%20%20*%20@param%20%7Bstring?%7D%20icon%0A%20%20%20%20%20*%20%20%20The%20source%20of%20the%20icon%20to%20display%20in%20the%20button,%20if%20null%20the%20default%20block%0A%20%20%20%20%20*%20%20%20icon%20is%20used%20instead.%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20originalElement%0A%20%20%20%20%20*%20%20%20The%20original%20Facebook%20login%20button%20that%20this%20placeholder%20is%20replacing.%0A%20%20%20%20%20*%20%20%20Note:%20This%20function%20does%20not%20actually%20replace%20the%20button,%20the%20caller%20is%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20expected%20to%20do%20that.%0A%20%20%20%20%20*%20@returns%20%7B%7B%20container:%20HTMLDivElement,%20button:%20HTMLButtonElement%20%7D%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeLoginButton(buttonText,%20mode,%20hoverTextBody,%20icon,%20originalElement)%20%7B%0A%20%20%20%20%20%20%20%20const%20container%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20container.style.cssText%20=%20'position:%20relative;';%0A%20%20%20%20%20%20%20%20container.appendChild(makeFontFaceStyleElement());%0A%0A%20%20%20%20%20%20%20%20const%20shadowRoot%20=%20container.attachShadow(%7B%20mode:%20devMode%20?%20'open'%20:%20'closed'%20%7D);%0A%20%20%20%20%20%20%20%20//%20inherit%20any%20class%20styles%20on%20the%20button%0A%20%20%20%20%20%20%20%20container.className%20=%20'fb-login-button%20FacebookLogin__button';%0A%20%20%20%20%20%20%20%20const%20%7B%20styleElement%20%7D%20=%20makeBaseStyleElement(mode);%0A%20%20%20%20%20%20%20%20styleElement.textContent%20+=%20%60%0A%20%20%20%20%20%20%20%20#DuckDuckGoPrivacyEssentialsHoverableText%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20display:%20none;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20#DuckDuckGoPrivacyEssentialsHoverable:hover%20#DuckDuckGoPrivacyEssentialsHoverableText%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20display:%20block;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%60;%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(styleElement);%0A%0A%20%20%20%20%20%20%20%20const%20hoverContainer%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20hoverContainer.id%20=%20'DuckDuckGoPrivacyEssentialsHoverable';%0A%20%20%20%20%20%20%20%20hoverContainer.style.cssText%20=%20styles.hoverContainer;%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(hoverContainer);%0A%0A%20%20%20%20%20%20%20%20//%20Make%20the%20button%0A%20%20%20%20%20%20%20%20const%20button%20=%20makeButton(buttonText,%20mode);%0A%20%20%20%20%20%20%20%20//%20Add%20blocked%20icon%0A%20%20%20%20%20%20%20%20if%20(!icon)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20button.appendChild(makeDefaultBlockIcon());%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20imgElement%20=%20document.createElement('img');%0A%20%20%20%20%20%20%20%20%20%20%20%20imgElement.style.cssText%20=%20styles.loginIcon;%0A%20%20%20%20%20%20%20%20%20%20%20%20imgElement.setAttribute('src',%20icon);%0A%20%20%20%20%20%20%20%20%20%20%20%20imgElement.setAttribute('height',%20'28px');%0A%20%20%20%20%20%20%20%20%20%20%20%20button.appendChild(imgElement);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20hoverContainer.appendChild(button);%0A%0A%20%20%20%20%20%20%20%20//%20hover%20action%0A%20%20%20%20%20%20%20%20const%20hoverBox%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20hoverBox.id%20=%20'DuckDuckGoPrivacyEssentialsHoverableText';%0A%20%20%20%20%20%20%20%20hoverBox.style.cssText%20=%20styles.textBubble;%0A%20%20%20%20%20%20%20%20const%20arrow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20arrow.style.cssText%20=%20styles.textArrow;%0A%20%20%20%20%20%20%20%20hoverBox.appendChild(arrow);%0A%20%20%20%20%20%20%20%20const%20branding%20=%20createTitleRow('DuckDuckGo');%0A%20%20%20%20%20%20%20%20branding.style.cssText%20+=%20styles.hoverTextTitle;%0A%20%20%20%20%20%20%20%20hoverBox.appendChild(branding);%0A%20%20%20%20%20%20%20%20const%20hoverText%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20hoverText.style.cssText%20=%20styles.hoverTextBody;%0A%20%20%20%20%20%20%20%20hoverText.textContent%20=%20hoverTextBody%20+%20'%20';%0A%20%20%20%20%20%20%20%20hoverText.appendChild(getLearnMoreLink(mode));%0A%20%20%20%20%20%20%20%20hoverBox.appendChild(hoverText);%0A%0A%20%20%20%20%20%20%20%20hoverContainer.appendChild(hoverBox);%0A%20%20%20%20%20%20%20%20const%20rect%20=%20originalElement.getBoundingClientRect();%0A%0A%20%20%20%20%20%20%20%20//%20The%20left%20side%20of%20the%20hover%20popup%20may%20go%20offscreen%20if%20the%0A%20%20%20%20%20%20%20%20//%20login%20button%20is%20all%20the%20way%20on%20the%20left%20side%20of%20the%20page.%20This%0A%20%20%20%20%20%20%20%20//%20If%20that%20is%20the%20case,%20dynamically%20shift%20the%20box%20right%20so%20it%20shows%0A%20%20%20%20%20%20%20%20//%20properly.%0A%20%20%20%20%20%20%20%20if%20(rect.left%20%3C%20styles.textBubbleLeftShift)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20leftShift%20=%20-rect.left%20+%2010;%20//%2010px%20away%20from%20edge%20of%20the%20screen%0A%20%20%20%20%20%20%20%20%20%20%20%20hoverBox.style.cssText%20+=%20%60left:%20$%7BleftShift%7Dpx;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20change%20=%20(1%20-%20rect.left%20/%20styles.textBubbleLeftShift)%20*%20(100%20-%20styles.arrowDefaultLocationPercent);%0A%20%20%20%20%20%20%20%20%20%20%20%20arrow.style.cssText%20+=%20%60left:%20$%7BMath.max(10,%20styles.arrowDefaultLocationPercent%20-%20change)%7D%25;%60;%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(rect.left%20+%20styles.textBubbleWidth%20-%20styles.textBubbleLeftShift%20%3E%20window.innerWidth)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20rightShift%20=%20rect.left%20+%20styles.textBubbleWidth%20-%20styles.textBubbleLeftShift;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20diff%20=%20Math.min(rightShift%20-%20window.innerWidth,%20styles.textBubbleLeftShift);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20rightMargin%20=%2020;%20//%20Add%20some%20margin%20to%20the%20page,%20so%20scrollbar%20doesn't%20overlap.%0A%20%20%20%20%20%20%20%20%20%20%20%20hoverBox.style.cssText%20+=%20%60left:%20-$%7Bstyles.textBubbleLeftShift%20+%20diff%20+%20rightMargin%7Dpx;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20change%20=%20(diff%20/%20styles.textBubbleLeftShift)%20*%20(100%20-%20styles.arrowDefaultLocationPercent);%0A%20%20%20%20%20%20%20%20%20%20%20%20arrow.style.cssText%20+=%20%60left:%20$%7BMath.max(10,%20styles.arrowDefaultLocationPercent%20+%20change)%7D%25;%60;%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20hoverBox.style.cssText%20+=%20%60left:%20-$%7Bstyles.textBubbleLeftShift%7Dpx;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20arrow.style.cssText%20+=%20%60left:%20$%7Bstyles.arrowDefaultLocationPercent%7D%25;%60;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20button,%0A%20%20%20%20%20%20%20%20%20%20%20%20container,%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Creates%20a%20privacy%20warning%20dialog%20for%20the%20user,%20so%20that%20the%20user%20can%20choose%20to%0A%20%20%20%20%20*%20proceed/abort.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20entity%0A%20%20%20%20%20*%20%20%20The%20entity%20to%20unblock%20requests%20for%20(e.g.%20%22Facebook,%20Inc.%22)%20if%20the%20user%0A%20%20%20%20%20*%20%20%20clicks%20to%20proceed.%0A%20%20%20%20%20*%20@param%20%7Bfunction%7D%20acceptFunction%0A%20%20%20%20%20*%20%20%20The%20function%20to%20call%20if%20the%20user%20has%20clicked%20to%20proceed.%0A%20%20%20%20%20*%20@param%20%7B...any%7D%20acceptFunctionParams%0A%20%20%20%20%20*%20%20%20The%20parameters%20passed%20to%20acceptFunction%20when%20it%20is%20called.%0A%20%20%20%20%20*%20%20%20TODO:%20Have%20the%20caller%20bind%20these%20arguments%20to%20the%20function%20instead.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeModal(entity,%20acceptFunction,%20...acceptFunctionParams)%20%7B%0A%20%20%20%20%20%20%20%20const%20icon%20=%20entityData%5Bentity%5D.modalIcon;%0A%0A%20%20%20%20%20%20%20%20const%20modalContainer%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20modalContainer.setAttribute('data-key',%20'modal');%0A%20%20%20%20%20%20%20%20modalContainer.style.cssText%20=%20styles.modalContainer;%0A%0A%20%20%20%20%20%20%20%20modalContainer.appendChild(makeFontFaceStyleElement());%0A%0A%20%20%20%20%20%20%20%20const%20closeModal%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20document.body.removeChild(modalContainer);%0A%20%20%20%20%20%20%20%20%20%20%20%20abortSurrogateConfirmation(entity);%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20//%20Protect%20the%20contents%20of%20our%20modal%20inside%20a%20shadowRoot,%20to%20avoid%0A%20%20%20%20%20%20%20%20//%20it%20being%20styled%20by%20the%20website's%20stylesheets.%0A%20%20%20%20%20%20%20%20const%20shadowRoot%20=%20modalContainer.attachShadow(%7B%20mode:%20devMode%20?%20'open'%20:%20'closed'%20%7D);%0A%20%20%20%20%20%20%20%20const%20%7B%20styleElement%20%7D%20=%20makeBaseStyleElement('lightMode');%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(styleElement);%0A%0A%20%20%20%20%20%20%20%20const%20pageOverlay%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20pageOverlay.style.cssText%20=%20styles.overlay;%0A%0A%20%20%20%20%20%20%20%20const%20modal%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20modal.style.cssText%20=%20styles.modal;%0A%0A%20%20%20%20%20%20%20%20//%20Title%0A%20%20%20%20%20%20%20%20const%20modalTitle%20=%20createTitleRow('DuckDuckGo',%20null,%20closeModal);%0A%20%20%20%20%20%20%20%20modal.appendChild(modalTitle);%0A%0A%20%20%20%20%20%20%20%20const%20iconElement%20=%20document.createElement('img');%0A%20%20%20%20%20%20%20%20iconElement.style.cssText%20=%20styles.icon%20+%20styles.modalIcon;%0A%20%20%20%20%20%20%20%20iconElement.setAttribute('src',%20icon);%0A%20%20%20%20%20%20%20%20iconElement.setAttribute('height',%20'70px');%0A%0A%20%20%20%20%20%20%20%20const%20title%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20title.style.cssText%20=%20styles.modalContentTitle;%0A%20%20%20%20%20%20%20%20title.textContent%20=%20entityData%5Bentity%5D.modalTitle;%0A%0A%20%20%20%20%20%20%20%20//%20Content%0A%20%20%20%20%20%20%20%20const%20modalContent%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20modalContent.style.cssText%20=%20styles.modalContent;%0A%0A%20%20%20%20%20%20%20%20const%20message%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20message.style.cssText%20=%20styles.modalContentText;%0A%20%20%20%20%20%20%20%20message.textContent%20=%20entityData%5Bentity%5D.modalText%20+%20'%20';%0A%20%20%20%20%20%20%20%20message.appendChild(getLearnMoreLink());%0A%0A%20%20%20%20%20%20%20%20modalContent.appendChild(iconElement);%0A%20%20%20%20%20%20%20%20modalContent.appendChild(title);%0A%20%20%20%20%20%20%20%20modalContent.appendChild(message);%0A%0A%20%20%20%20%20%20%20%20//%20Buttons%0A%20%20%20%20%20%20%20%20const%20buttonRow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20buttonRow.style.cssText%20=%20styles.modalButtonRow;%0A%20%20%20%20%20%20%20%20const%20allowButton%20=%20makeButton(entityData%5Bentity%5D.modalAcceptText,%20'lightMode');%0A%20%20%20%20%20%20%20%20allowButton.style.cssText%20+=%20styles.modalButton%20+%20'margin-bottom:%208px;';%0A%20%20%20%20%20%20%20%20allowButton.setAttribute('data-key',%20'allow');%0A%20%20%20%20%20%20%20%20allowButton.addEventListener('click',%20function%20doLogin()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20acceptFunction(...acceptFunctionParams);%0A%20%20%20%20%20%20%20%20%20%20%20%20document.body.removeChild(modalContainer);%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20const%20rejectButton%20=%20makeButton(entityData%5Bentity%5D.modalRejectText,%20'cancelMode');%0A%20%20%20%20%20%20%20%20rejectButton.setAttribute('data-key',%20'reject');%0A%20%20%20%20%20%20%20%20rejectButton.style.cssText%20+=%20styles.modalButton;%0A%20%20%20%20%20%20%20%20rejectButton.addEventListener('click',%20closeModal);%0A%0A%20%20%20%20%20%20%20%20buttonRow.appendChild(allowButton);%0A%20%20%20%20%20%20%20%20buttonRow.appendChild(rejectButton);%0A%20%20%20%20%20%20%20%20modalContent.appendChild(buttonRow);%0A%0A%20%20%20%20%20%20%20%20modal.appendChild(modalContent);%0A%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(pageOverlay);%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(modal);%0A%0A%20%20%20%20%20%20%20%20document.body.insertBefore(modalContainer,%20document.body.childNodes%5B0%5D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20the%20%22title%20row%22%20div%20that%20contains%20a%20placeholder's%20heading.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20message%0A%20%20%20%20%20*%20%20%20The%20title%20text%20to%20display.%0A%20%20%20%20%20*%20@param%20%7BHTMLAnchorElement?%7D%20%5BtextButton%5D%0A%20%20%20%20%20*%20%20%20The%20link%20to%20display%20with%20the%20title,%20if%20any.%0A%20%20%20%20%20*%20@param%20%7BEventListener%7D%20%5BcloseBtnFn%5D%0A%20%20%20%20%20*%20%20%20If%20provided,%20a%20close%20button%20is%20added%20that%20calls%20this%20function%20when%20clicked.%0A%20%20%20%20%20*%20@returns%20%7BHTMLDivElement%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20createTitleRow(message,%20textButton,%20closeBtnFn)%20%7B%0A%20%20%20%20%20%20%20%20//%20Create%20row%20container%0A%20%20%20%20%20%20%20%20const%20row%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20row.style.cssText%20=%20styles.titleBox;%0A%0A%20%20%20%20%20%20%20%20//%20Logo%0A%20%20%20%20%20%20%20%20const%20logoContainer%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20logoContainer.style.cssText%20=%20styles.logo;%0A%20%20%20%20%20%20%20%20const%20logoElement%20=%20document.createElement('img');%0A%20%20%20%20%20%20%20%20logoElement.setAttribute('src',%20logoImg);%0A%20%20%20%20%20%20%20%20logoElement.setAttribute('height',%20'21px');%0A%20%20%20%20%20%20%20%20logoElement.style.cssText%20=%20styles.logoImg;%0A%20%20%20%20%20%20%20%20logoContainer.appendChild(logoElement);%0A%20%20%20%20%20%20%20%20row.appendChild(logoContainer);%0A%0A%20%20%20%20%20%20%20%20//%20Content%20box%20title%0A%20%20%20%20%20%20%20%20const%20msgElement%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20msgElement.id%20=%20titleID;%20//%20Ensure%20we%20can%20find%20this%20to%20potentially%20hide%20it%20later.%0A%20%20%20%20%20%20%20%20msgElement.textContent%20=%20message;%0A%20%20%20%20%20%20%20%20msgElement.style.cssText%20=%20styles.title;%0A%20%20%20%20%20%20%20%20row.appendChild(msgElement);%0A%0A%20%20%20%20%20%20%20%20//%20Close%20Button%0A%20%20%20%20%20%20%20%20if%20(typeof%20closeBtnFn%20===%20'function')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20closeButton%20=%20document.createElement('button');%0A%20%20%20%20%20%20%20%20%20%20%20%20closeButton.style.cssText%20=%20styles.closeButton;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20closeIconImg%20=%20document.createElement('img');%0A%20%20%20%20%20%20%20%20%20%20%20%20closeIconImg.setAttribute('src',%20closeIcon);%0A%20%20%20%20%20%20%20%20%20%20%20%20closeIconImg.setAttribute('height',%20'12px');%0A%20%20%20%20%20%20%20%20%20%20%20%20closeIconImg.style.cssText%20=%20styles.closeIcon;%0A%20%20%20%20%20%20%20%20%20%20%20%20closeButton.appendChild(closeIconImg);%0A%20%20%20%20%20%20%20%20%20%20%20%20closeButton.addEventListener('click',%20closeBtnFn);%0A%20%20%20%20%20%20%20%20%20%20%20%20row.appendChild(closeButton);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Text%20button%20for%20very%20small%20boxes%0A%20%20%20%20%20%20%20%20if%20(textButton)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20textButton.id%20=%20titleID%20+%20'TextButton';%0A%20%20%20%20%20%20%20%20%20%20%20%20row.appendChild(textButton);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20row;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20a%20placeholder%20element%20(wrapped%20in%20a%20div%20and%20shadowRoot),%20to%20replace%20a%0A%20%20%20%20%20*%20tracking%20element%20with.%0A%20%20%20%20%20*%20@param%20%7BDuckWidget%7D%20widget%0A%20%20%20%20%20*%20%20%20Widget%20corresponding%20to%20the%20tracking%20element.%0A%20%20%20%20%20*%20@param%20%7BHTMLButtonElement%7D%20button%0A%20%20%20%20%20*%20%20%20Primary%20button%20that%20loads%20the%20original%20tracking%20element%20(and%20removed%20this%0A%20%20%20%20%20*%20%20%20placeholder)%20when%20clicked.%0A%20%20%20%20%20*%20@param%20%7BHTMLAnchorElement?%7D%20textButton%0A%20%20%20%20%20*%20%20%20Link%20to%20display%20next%20to%20the%20title,%20if%20any.%0A%20%20%20%20%20*%20@param%20%7Bstring?%7D%20img%0A%20%20%20%20%20*%20%20%20Source%20of%20image%20to%20display%20in%20the%20placeholder%20(if%20any).%0A%20%20%20%20%20*%20@param%20%7BHTMLDivElement%7D%20%5BbottomRow%5D%0A%20%20%20%20%20*%20%20%20Bottom%20row%20to%20append%20to%20the%20placeholder,%20if%20any.%0A%20%20%20%20%20*%20@returns%20%7B%7B%20contentBlock:%20HTMLDivElement,%20shadowRoot:%20ShadowRoot%20%7D%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20createContentBlock(widget,%20button,%20textButton,%20img,%20bottomRow)%20%7B%0A%20%20%20%20%20%20%20%20const%20contentBlock%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20contentBlock.style.cssText%20=%20styles.wrapperDiv;%0A%0A%20%20%20%20%20%20%20%20contentBlock.appendChild(makeFontFaceStyleElement());%0A%0A%20%20%20%20%20%20%20%20//%20Put%20everything%20else%20inside%20the%20shadowRoot%20of%20the%20wrapper%20element%20to%0A%20%20%20%20%20%20%20%20//%20reduce%20the%20chances%20of%20the%20website's%20stylesheets%20messing%20up%20the%0A%20%20%20%20%20%20%20%20//%20placeholder's%20appearance.%0A%20%20%20%20%20%20%20%20const%20shadowRootMode%20=%20devMode%20?%20'open'%20:%20'closed';%0A%20%20%20%20%20%20%20%20const%20shadowRoot%20=%20contentBlock.attachShadow(%7B%20mode:%20shadowRootMode%20%7D);%0A%0A%20%20%20%20%20%20%20%20//%20Style%20element%20includes%20our%20font%20&%20overwrites%20page%20styles%0A%20%20%20%20%20%20%20%20const%20%7B%20wrapperClass,%20styleElement%20%7D%20=%20makeBaseStyleElement(widget.getMode());%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(styleElement);%0A%0A%20%20%20%20%20%20%20%20//%20Create%20overall%20grid%20structure%0A%20%20%20%20%20%20%20%20const%20element%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20element.style.cssText%20=%20styles.block%20+%20styles%5Bwidget.getMode()%5D.background%20+%20styles%5Bwidget.getMode()%5D.textFont;%0A%20%20%20%20%20%20%20%20if%20(widget.replaceSettings.type%20===%20'youtube-video')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20element.style.cssText%20+=%20styles.youTubeDialogBlock;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20element.className%20=%20wrapperClass;%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(element);%0A%0A%20%20%20%20%20%20%20%20//%20grid%20of%20three%20rows%0A%20%20%20%20%20%20%20%20const%20titleRow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20titleRow.style.cssText%20=%20styles.headerRow;%0A%20%20%20%20%20%20%20%20element.appendChild(titleRow);%0A%20%20%20%20%20%20%20%20titleRow.appendChild(createTitleRow('DuckDuckGo',%20textButton));%0A%0A%20%20%20%20%20%20%20%20const%20contentRow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20contentRow.style.cssText%20=%20styles.content;%0A%0A%20%20%20%20%20%20%20%20if%20(img)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20imageRow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20%20%20%20%20imageRow.style.cssText%20=%20styles.imgRow;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20imgElement%20=%20document.createElement('img');%0A%20%20%20%20%20%20%20%20%20%20%20%20imgElement.style.cssText%20=%20styles.icon;%0A%20%20%20%20%20%20%20%20%20%20%20%20imgElement.setAttribute('src',%20img);%0A%20%20%20%20%20%20%20%20%20%20%20%20imgElement.setAttribute('height',%20'70px');%0A%20%20%20%20%20%20%20%20%20%20%20%20imageRow.appendChild(imgElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20element.appendChild(imageRow);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20contentTitle%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20contentTitle.style.cssText%20=%20styles.contentTitle;%0A%20%20%20%20%20%20%20%20contentTitle.textContent%20=%20widget.replaceSettings.infoTitle;%0A%20%20%20%20%20%20%20%20contentTitle.id%20=%20'contentTitle';%0A%20%20%20%20%20%20%20%20contentRow.appendChild(contentTitle);%0A%20%20%20%20%20%20%20%20const%20contentText%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20contentText.style.cssText%20=%20styles.contentText;%0A%20%20%20%20%20%20%20%20const%20contentTextSpan%20=%20document.createElement('span');%0A%20%20%20%20%20%20%20%20contentTextSpan.id%20=%20'infoText';%0A%20%20%20%20%20%20%20%20contentTextSpan.textContent%20=%20widget.replaceSettings.infoText%20+%20'%20';%0A%20%20%20%20%20%20%20%20contentText.appendChild(contentTextSpan);%0A%20%20%20%20%20%20%20%20contentText.appendChild(getLearnMoreLink());%0A%20%20%20%20%20%20%20%20contentRow.appendChild(contentText);%0A%20%20%20%20%20%20%20%20element.appendChild(contentRow);%0A%0A%20%20%20%20%20%20%20%20const%20buttonRow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20buttonRow.style.cssText%20=%20styles.buttonRow;%0A%20%20%20%20%20%20%20%20buttonRow.appendChild(button);%0A%20%20%20%20%20%20%20%20contentText.appendChild(buttonRow);%0A%0A%20%20%20%20%20%20%20%20if%20(bottomRow)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20contentRow.appendChild(bottomRow);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%20Share%20Feedback%20Link%20*/%0A%20%20%20%20%20%20%20%20if%20(widget.replaceSettings.type%20===%20'youtube-video')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20feedbackRow%20=%20makeShareFeedbackRow();%0A%20%20%20%20%20%20%20%20%20%20%20%20shadowRoot.appendChild(feedbackRow);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20%7B%20contentBlock,%20shadowRoot%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20the%20content%20block%20to%20replace%20embedded%20YouTube%20videos/iframes%20with.%0A%20%20%20%20%20*%20@param%20%7BHTMLIFrameElement%7D%20trackingElement%0A%20%20%20%20%20*%20@param%20%7BDuckWidget%7D%20widget%0A%20%20%20%20%20*%20@returns%20%7B%7B%20blockingDialog:%20HTMLElement,%20shadowRoot:%20ShadowRoot%20%7D%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20createYouTubeBlockingDialog(trackingElement,%20widget)%20%7B%0A%20%20%20%20%20%20%20%20const%20button%20=%20makeButton(widget.replaceSettings.buttonText,%20widget.getMode());%0A%20%20%20%20%20%20%20%20const%20textButton%20=%20makeTextButton(widget.replaceSettings.buttonText,%20widget.getMode());%0A%0A%20%20%20%20%20%20%20%20const%20bottomRow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20bottomRow.style.cssText%20=%20styles.youTubeDialogBottomRow;%0A%20%20%20%20%20%20%20%20const%20previewToggle%20=%20makeToggleButtonWithText(%0A%20%20%20%20%20%20%20%20%20%20%20%20widget.replaceSettings.previewToggleText,%0A%20%20%20%20%20%20%20%20%20%20%20%20widget.getMode(),%0A%20%20%20%20%20%20%20%20%20%20%20%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20'yt-preview-toggle',%0A%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20previewToggle.addEventListener('click',%20()%20=%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20makeModal(widget.entity,%20()%20=%3E%20ctl.messaging.notify('setYoutubePreviewsEnabled',%20%7B%20youtubePreviewsEnabled:%20true%20%7D),%20widget.entity),%0A%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20bottomRow.appendChild(previewToggle);%0A%0A%20%20%20%20%20%20%20%20const%20%7B%20contentBlock,%20shadowRoot%20%7D%20=%20createContentBlock(widget,%20button,%20textButton,%20null,%20bottomRow);%0A%20%20%20%20%20%20%20%20contentBlock.id%20=%20trackingElement.id;%0A%20%20%20%20%20%20%20%20contentBlock.style.cssText%20+=%20styles.wrapperDiv%20+%20styles.youTubeWrapperDiv;%0A%0A%20%20%20%20%20%20%20%20button.addEventListener('click',%20widget.clickFunction(trackingElement,%20contentBlock));%0A%20%20%20%20%20%20%20%20textButton.addEventListener('click',%20widget.clickFunction(trackingElement,%20contentBlock));%0A%0A%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20blockingDialog:%20contentBlock,%0A%20%20%20%20%20%20%20%20%20%20%20%20shadowRoot,%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Creates%20the%20placeholder%20element%20to%20replace%20a%20YouTube%20video%20iframe%20element%0A%20%20%20%20%20*%20with%20a%20preview%20image.%20Mutates%20widget%20Object%20to%20set%20the%20autoplay%20property%0A%20%20%20%20%20*%20as%20the%20preview%20details%20load.%0A%20%20%20%20%20*%20@param%20%7BHTMLIFrameElement%7D%20originalElement%0A%20%20%20%20%20*%20%20%20The%20YouTube%20video%20iframe%20element.%0A%20%20%20%20%20*%20@param%20%7BDuckWidget%7D%20widget%0A%20%20%20%20%20*%20%20%20The%20widget%20Object.%20We%20mutate%20this%20to%20set%20the%20autoplay%20property.%0A%20%20%20%20%20*%20@returns%20%7B%7B%20youTubePreview:%20HTMLElement,%20shadowRoot:%20ShadowRoot%20%7D%7D%0A%20%20%20%20%20*%20%20%20Object%20containing%20the%20YouTube%20Preview%20element%20and%20its%20shadowRoot.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20createYouTubePreview(originalElement,%20widget)%20%7B%0A%20%20%20%20%20%20%20%20const%20youTubePreview%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20youTubePreview.id%20=%20originalElement.id;%0A%20%20%20%20%20%20%20%20youTubePreview.style.cssText%20=%20styles.wrapperDiv%20+%20styles.placeholderWrapperDiv;%0A%0A%20%20%20%20%20%20%20%20youTubePreview.appendChild(makeFontFaceStyleElement());%0A%0A%20%20%20%20%20%20%20%20//%20Protect%20the%20contents%20of%20our%20placeholder%20inside%20a%20shadowRoot,%20to%20avoid%0A%20%20%20%20%20%20%20%20//%20it%20being%20styled%20by%20the%20website's%20stylesheets.%0A%20%20%20%20%20%20%20%20const%20shadowRoot%20=%20youTubePreview.attachShadow(%7B%20mode:%20devMode%20?%20'open'%20:%20'closed'%20%7D);%0A%20%20%20%20%20%20%20%20const%20%7B%20wrapperClass,%20styleElement%20%7D%20=%20makeBaseStyleElement(widget.getMode());%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(styleElement);%0A%0A%20%20%20%20%20%20%20%20const%20youTubePreviewDiv%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20youTubePreviewDiv.style.cssText%20=%20styles.youTubeDialogDiv;%0A%20%20%20%20%20%20%20%20youTubePreviewDiv.classList.add(wrapperClass);%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(youTubePreviewDiv);%0A%0A%20%20%20%20%20%20%20%20/**%20Preview%20Image%20*/%0A%20%20%20%20%20%20%20%20const%20previewImageWrapper%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20previewImageWrapper.style.cssText%20=%20styles.youTubePreviewWrapperImg;%0A%20%20%20%20%20%20%20%20youTubePreviewDiv.appendChild(previewImageWrapper);%0A%20%20%20%20%20%20%20%20//%20We%20use%20an%20image%20element%20for%20the%20preview%20image%20so%20that%20we%20can%20ensure%0A%20%20%20%20%20%20%20%20//%20the%20referrer%20isn't%20passed.%0A%20%20%20%20%20%20%20%20const%20previewImageElement%20=%20document.createElement('img');%0A%20%20%20%20%20%20%20%20previewImageElement.setAttribute('referrerPolicy',%20'no-referrer');%0A%20%20%20%20%20%20%20%20previewImageElement.style.cssText%20=%20styles.youTubePreviewImg;%0A%20%20%20%20%20%20%20%20previewImageWrapper.appendChild(previewImageElement);%0A%0A%20%20%20%20%20%20%20%20const%20innerDiv%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20innerDiv.style.cssText%20=%20styles.youTubePlaceholder;%0A%0A%20%20%20%20%20%20%20%20/**%20Top%20section%20*/%0A%20%20%20%20%20%20%20%20const%20topSection%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20topSection.style.cssText%20=%20styles.youTubeTopSection;%0A%20%20%20%20%20%20%20%20innerDiv.appendChild(topSection);%0A%0A%20%20%20%20%20%20%20%20/**%20Video%20Title%20*/%0A%20%20%20%20%20%20%20%20const%20titleElement%20=%20document.createElement('p');%0A%20%20%20%20%20%20%20%20titleElement.style.cssText%20=%20styles.youTubeTitle;%0A%20%20%20%20%20%20%20%20topSection.appendChild(titleElement);%0A%0A%20%20%20%20%20%20%20%20/**%20Text%20Button%20on%20top%20section%20*/%0A%20%20%20%20%20%20%20%20//%20Use%20darkMode%20styles%20because%20the%20preview%20background%20is%20dark%20and%20causes%20poor%20contrast%0A%20%20%20%20%20%20%20%20//%20with%20lightMode%20button,%20making%20it%20hard%20to%20read.%0A%20%20%20%20%20%20%20%20const%20textButton%20=%20makeTextButton(widget.replaceSettings.buttonText,%20'darkMode');%0A%20%20%20%20%20%20%20%20textButton.id%20=%20titleID%20+%20'TextButton';%0A%0A%20%20%20%20%20%20%20%20textButton.addEventListener('click',%20widget.clickFunction(originalElement,%20youTubePreview));%0A%20%20%20%20%20%20%20%20topSection.appendChild(textButton);%0A%0A%20%20%20%20%20%20%20%20/**%20Play%20Button%20*/%0A%20%20%20%20%20%20%20%20const%20playButtonRow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20playButtonRow.style.cssText%20=%20styles.youTubePlayButtonRow;%0A%0A%20%20%20%20%20%20%20%20const%20playButton%20=%20makeButton('',%20widget.getMode());%0A%20%20%20%20%20%20%20%20playButton.style.cssText%20+=%20styles.youTubePlayButton;%0A%0A%20%20%20%20%20%20%20%20const%20videoPlayImg%20=%20document.createElement('img');%0A%20%20%20%20%20%20%20%20const%20videoPlayIcon%20=%20widget.replaceSettings.placeholder.videoPlayIcon%5Bwidget.getMode()%5D;%0A%20%20%20%20%20%20%20%20videoPlayImg.setAttribute('src',%20videoPlayIcon);%0A%20%20%20%20%20%20%20%20playButton.appendChild(videoPlayImg);%0A%0A%20%20%20%20%20%20%20%20playButton.addEventListener('click',%20widget.clickFunction(originalElement,%20youTubePreview));%0A%20%20%20%20%20%20%20%20playButtonRow.appendChild(playButton);%0A%20%20%20%20%20%20%20%20innerDiv.appendChild(playButtonRow);%0A%0A%20%20%20%20%20%20%20%20/**%20Preview%20Toggle%20*/%0A%20%20%20%20%20%20%20%20const%20previewToggleRow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20previewToggleRow.style.cssText%20=%20styles.youTubePreviewToggleRow;%0A%0A%20%20%20%20%20%20%20%20//%20TODO:%20Use%20%60widget.replaceSettings.placeholder.previewToggleEnabledDuckDuckGoText%60%20for%20toggle%0A%20%20%20%20%20%20%20%20//%20copy%20when%20implementing%20mobile%20YT%20CTL%20Preview%0A%20%20%20%20%20%20%20%20const%20previewToggle%20=%20makeToggleButtonWithText(%0A%20%20%20%20%20%20%20%20%20%20%20%20widget.replaceSettings.placeholder.previewToggleEnabledText,%0A%20%20%20%20%20%20%20%20%20%20%20%20widget.getMode(),%0A%20%20%20%20%20%20%20%20%20%20%20%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20styles.youTubePreviewToggleText,%0A%20%20%20%20%20%20%20%20%20%20%20%20'yt-preview-toggle',%0A%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20previewToggle.addEventListener('click',%20()%20=%3E%20ctl.messaging.notify('setYoutubePreviewsEnabled',%20%7B%20youtubePreviewsEnabled:%20false%20%7D));%0A%0A%20%20%20%20%20%20%20%20/**%20Preview%20Info%20Text%20*/%0A%20%20%20%20%20%20%20%20const%20previewText%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20previewText.style.cssText%20=%20styles.contentText%20+%20styles.toggleButtonText%20+%20styles.youTubePreviewInfoText;%0A%20%20%20%20%20%20%20%20//%20Since%20this%20string%20contains%20an%20anchor%20element,%20setting%20innerText%20won't%0A%20%20%20%20%20%20%20%20//%20work.%0A%20%20%20%20%20%20%20%20//%20Warning:%20This%20is%20not%20ideal!%20The%20translated%20(and%20original)%20strings%20must%20be%0A%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20%20%20%20checked%20very%20carefully!%20Any%20HTML%20they%20contain%20will%20be%20inserted.%0A%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20%20%20%20Ideally,%20the%20translation%20system%20would%20allow%20only%20certain%20element%0A%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20%20%20%20types%20to%20be%20included,%20and%20would%20avoid%20the%20URLs%20for%20links%20being%0A%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20%20%20%20included%20in%20the%20translations.%0A%20%20%20%20%20%20%20%20previewText.insertAdjacentHTML('beforeend',%20widget.replaceSettings.placeholder.previewInfoText);%0A%20%20%20%20%20%20%20%20const%20previewTextLink%20=%20previewText.querySelector('a');%0A%20%20%20%20%20%20%20%20if%20(previewTextLink)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20newPreviewTextLink%20=%20getLearnMoreLink(widget.getMode());%0A%20%20%20%20%20%20%20%20%20%20%20%20newPreviewTextLink.innerText%20=%20previewTextLink.innerText;%0A%20%20%20%20%20%20%20%20%20%20%20%20previewTextLink.replaceWith(newPreviewTextLink);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20previewToggleRow.appendChild(previewToggle);%0A%20%20%20%20%20%20%20%20previewToggleRow.appendChild(previewText);%0A%20%20%20%20%20%20%20%20innerDiv.appendChild(previewToggleRow);%0A%0A%20%20%20%20%20%20%20%20youTubePreviewDiv.appendChild(innerDiv);%0A%0A%20%20%20%20%20%20%20%20//%20We%20use%20.then()%20instead%20of%20await%20here%20to%20show%20the%20placeholder%20right%20away%0A%20%20%20%20%20%20%20%20//%20while%20the%20YouTube%20endpoint%20takes%20it%20time%20to%20respond.%0A%20%20%20%20%20%20%20%20const%20videoURL%20=%20originalElement.src%20%7C%7C%20originalElement.getAttribute('data-src');%0A%20%20%20%20%20%20%20%20ctl.messaging%0A%20%20%20%20%20%20%20%20%20%20%20%20.request('getYouTubeVideoDetails',%20%7B%20videoURL%20%7D)%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20promise/prefer-await-to-then%0A%20%20%20%20%20%20%20%20%20%20%20%20.then((%7B%20videoURL:%20videoURLResp,%20status,%20title,%20previewImage%20%7D)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!status%20%7C%7C%20videoURLResp%20!==%20videoURL)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(status%20===%20'success')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20titleElement.innerText%20=%20title;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20titleElement.title%20=%20title;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(previewImage)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20previewImageElement.setAttribute('src',%20previewImage);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20widget.autoplay%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20/**%20Share%20Feedback%20Link%20*/%0A%20%20%20%20%20%20%20%20const%20feedbackRow%20=%20makeShareFeedbackRow();%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(feedbackRow);%0A%0A%20%20%20%20%20%20%20%20return%20%7B%20youTubePreview,%20shadowRoot%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7Bimport('@duckduckgo/messaging').MessagingContext%7D%20MessagingContext%0A%20%20%20%20%20*/%0A%0A%20%20%20%20class%20ClickToLoad%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20/**%20@type%20%7BMessagingContext%7D%20*/%0A%20%20%20%20%20%20%20%20#messagingContext;%0A%0A%20%20%20%20%20%20%20%20async%20init(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Bail%20if%20no%20messaging%20backend%20-%20this%20is%20a%20debugging%20feature%20to%20ensure%20we%20don't%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20accidentally%20enabled%20this%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this.messaging)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('Cannot%20operate%20click%20to%20load%20without%20a%20messaging%20backend');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20_messagingModuleScope%20=%20this.messaging;%0A%20%20%20%20%20%20%20%20%20%20%20%20_addDebugFlag%20=%20this.addDebugFlag.bind(this);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20websiteOwner%20=%20args?.site?.parentEntity;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20settings%20=%20args?.featureSettings?.clickToLoad%20%7C%7C%20%7B%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20locale%20=%20args?.locale%20%7C%7C%20'en';%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20localizedConfig%20=%20getConfig(locale);%0A%20%20%20%20%20%20%20%20%20%20%20%20config%20=%20localizedConfig.config;%0A%20%20%20%20%20%20%20%20%20%20%20%20sharedStrings%20=%20localizedConfig.sharedStrings;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20update%20styles%20if%20asset%20config%20was%20sent%0A%20%20%20%20%20%20%20%20%20%20%20%20styles%20=%20getStyles(this.assetConfig);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Register%20Custom%20Elements%20only%20when%20Click%20to%20Load%20is%20initialized,%20to%20ensure%20it%20is%20only%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20called%20when%20config%20is%20ready%20and%20any%20previous%20context%20have%20been%20appropriately%20invalidated%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20prior%20when%20applicable%20(ie%20Firefox%20when%20hot%20reloading%20the%20Extension)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20registerCustomElements();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20entity%20of%20Object.keys(config))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Strip%20config%20entities%20that%20are%20first-party,%20or%20aren't%20enabled%20in%20the%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20extension's%20clickToLoad%20settings.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20((websiteOwner%20&&%20entity%20===%20websiteOwner)%20%7C%7C%20!settings%5Bentity%5D%20%7C%7C%20settings%5Bentity%5D.state%20!==%20'enabled')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20config%5Bentity%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Populate%20the%20entities%20and%20entityData%20data%20structures.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20TODO:%20Remove%20them%20and%20this%20logic,%20they%20seem%20unnecessary.%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20entities.push(entity);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20shouldShowLoginModal%20=%20!!config%5Bentity%5D.informationalModal;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20currentEntityData%20=%20%7B%20shouldShowLoginModal%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(shouldShowLoginModal)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20informationalModal%20%7D%20=%20config%5Bentity%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20currentEntityData.modalIcon%20=%20informationalModal.icon;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20currentEntityData.modalTitle%20=%20informationalModal.messageTitle;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20currentEntityData.modalText%20=%20informationalModal.messageBody;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20currentEntityData.modalAcceptText%20=%20informationalModal.confirmButtonText;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20currentEntityData.modalRejectText%20=%20informationalModal.rejectButtonText;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20entityData%5Bentity%5D%20=%20currentEntityData;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Listen%20for%20window%20events%20from%20%22surrogate%22%20scripts.%0A%20%20%20%20%20%20%20%20%20%20%20%20window.addEventListener('ddg-ctp',%20(/**%20@type%20%7BCustomEvent%7D%20*/%20event)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!('detail'%20in%20event))%20return;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20entity%20=%20event.detail?.entity;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!entities.includes(entity))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Unknown%20entity,%20reject%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(event.detail?.appID)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20appID%20=%20JSON.stringify(event.detail.appID).replace(/%22/g,%20'');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Handle%20login%20call%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(event.detail?.action%20===%20'login')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Even%20if%20the%20user%20cancels%20the%20login%20attempt,%20consider%20Facebook%20Click%20to%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Load%20to%20have%20been%20active%20on%20the%20page%20if%20the%20user%20reports%20the%20page%20as%20broken.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(entity%20===%20'Facebook,%20Inc.')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20notifyFacebookLogin();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(entityData%5Bentity%5D.shouldShowLoginModal)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20handleUnblockConfirmation(this.platform.name,%20entity,%20runLogin,%20entity);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20runLogin(entity);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Listen%20to%20message%20from%20Platform%20letting%20CTL%20know%20that%20we're%20ready%20to%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20replace%20elements%20in%20the%20page%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messaging.subscribe(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'displayClickToLoadPlaceholders',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20TODO:%20Pass%20%60message.options.ruleAction%60%20through,%20that%20way%20only%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20content%20corresponding%20to%20the%20entity%20for%20that%20ruleAction%20need%20to%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20be%20replaced%20with%20a%20placeholder.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20()%20=%3E%20this.replaceClickToLoadElements(),%0A%20%20%20%20%20%20%20%20%20%20%20%20);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Request%20the%20current%20state%20of%20Click%20to%20Load%20from%20the%20platform.%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Note:%20When%20the%20response%20is%20received,%20the%20response%20handler%20resolves%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20the%20readyToDisplayPlaceholders%20Promise.%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20clickToLoadState%20=%20await%20this.messaging.request('getClickToLoadState');%0A%20%20%20%20%20%20%20%20%20%20%20%20this.onClickToLoadState(clickToLoadState);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Then%20wait%20for%20the%20page%20to%20finish%20loading,%20and%20resolve%20the%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20afterPageLoad%20Promise.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(document.readyState%20===%20'complete')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20afterPageLoadResolver();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20window.addEventListener('load',%20afterPageLoadResolver,%20%7B%20once:%20true%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20await%20afterPageLoad;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20On%20some%20websites,%20the%20%22ddg-ctp-ready%22%20event%20is%20occasionally%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20dispatched%20too%20early,%20before%20the%20listener%20is%20ready%20to%20receive%20it.%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20To%20counter%20that,%20catch%20%22ddg-ctp-surrogate-load%22%20events%20dispatched%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20_after_%20page,%20so%20the%20%22ddg-ctp-ready%22%20event%20can%20be%20dispatched%20again.%0A%20%20%20%20%20%20%20%20%20%20%20%20window.addEventListener('ddg-ctp-surrogate-load',%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20originalWindowDispatchEvent(createCustomEvent('ddg-ctp-ready'));%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Then%20wait%20for%20any%20in-progress%20element%20replacements,%20before%20letting%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20the%20surrogate%20scripts%20know%20to%20start.%0A%20%20%20%20%20%20%20%20%20%20%20%20window.setTimeout(()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20originalWindowDispatchEvent(createCustomEvent('ddg-ctp-ready'));%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%200);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20This%20is%20only%20called%20by%20the%20current%20integration%20between%20Android%20and%20Extension%20and%20is%20now%0A%20%20%20%20%20%20%20%20%20*%20used%20to%20connect%20only%20these%20Platforms%20responses%20with%20the%20temporary%20implementation%20of%0A%20%20%20%20%20%20%20%20%20*%20SendMessageMessagingTransport%20that%20wraps%20this%20communication.%0A%20%20%20%20%20%20%20%20%20*%20This%20can%20be%20removed%20once%20they%20have%20their%20own%20Messaging%20integration.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20update(message)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20TODO:%20Once%20all%20Click%20to%20Load%20messages%20include%20the%20feature%20property,%20drop%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20messages%20that%20don't%20include%20the%20feature%20property%20too.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(message?.feature%20&&%20message?.feature%20!==%20'clickToLoad')%20return;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20messageType%20=%20message?.messageType;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!messageType)%20return;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this._clickToLoadMessagingTransport)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('_clickToLoadMessagingTransport%20not%20ready.%20Cannot%20operate%20click%20to%20load%20without%20a%20messaging%20backend');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Send%20to%20Messaging%20layer%20the%20response%20or%20subscription%20message%20received%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20from%20the%20Platform.%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this._clickToLoadMessagingTransport.onResponse(message);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Update%20Click%20to%20Load%20internal%20state%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BObject%7D%20state%20Click%20to%20Load%20state%20response%20from%20the%20Platform%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean%7D%20state.devMode%20Developer%20or%20Production%20environment%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean%7D%20state.youtubePreviewsEnabled%20YouTube%20Click%20to%20Load%20-%20YT%20Previews%20enabled%20flag%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20onClickToLoadState(state)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20devMode%20=%20state.devMode;%0A%20%20%20%20%20%20%20%20%20%20%20%20isYoutubePreviewsEnabled%20=%20state.youtubePreviewsEnabled;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Mark%20the%20feature%20as%20ready,%20to%20allow%20placeholder%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20replacements%20to%20start.%0A%20%20%20%20%20%20%20%20%20%20%20%20readyToDisplayPlaceholdersResolver();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Replace%20the%20blocked%20CTL%20elements%20on%20the%20page%20with%20placeholders.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20%5BtargetElement%5D%0A%20%20%20%20%20%20%20%20%20*%20%20%20If%20specified,%20only%20this%20element%20will%20be%20replaced%20(assuming%20it%20matches%0A%20%20%20%20%20%20%20%20%20*%20%20%20one%20of%20the%20expected%20CSS%20selectors).%20If%20omitted,%20all%20matching%20elements%0A%20%20%20%20%20%20%20%20%20*%20%20%20in%20the%20document%20will%20be%20replaced%20instead.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20async%20replaceClickToLoadElements(targetElement)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20await%20readyToDisplayPlaceholders;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20entity%20of%20Object.keys(config))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20widgetData%20of%20Object.values(config%5Bentity%5D.elementData))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20selector%20=%20widgetData.selectors.join();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20trackingElements%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(targetElement)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(targetElement.matches(selector))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20trackingElements.push(targetElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20trackingElements%20=%20Array.from(document.querySelectorAll(selector));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20await%20Promise.all(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20trackingElements.map((trackingElement)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(knownTrackingElements.has(trackingElement))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20Promise.resolve();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20knownTrackingElements.add(trackingElement);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20widget%20=%20new%20DuckWidget(widgetData,%20trackingElement,%20entity,%20this.platform);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20createPlaceholderElementAndReplace(widget,%20trackingElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BMessagingContext%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20get%20messagingContext()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.#messagingContext)%20return%20this.#messagingContext;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.#messagingContext%20=%20this._createMessagingContext();%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.#messagingContext;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Messaging%20layer%20between%20Click%20to%20Load%20and%20the%20Platform%0A%20%20%20%20%20%20%20%20get%20messaging()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this._messaging)%20return%20this._messaging;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.platform.name%20===%20'android'%20%7C%7C%20this.platform.name%20===%20'extension')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._clickToLoadMessagingTransport%20=%20new%20SendMessageMessagingTransport();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20config%20=%20new%20TestTransportConfig(this._clickToLoadMessagingTransport);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._messaging%20=%20new%20Messaging(this.messagingContext,%20config);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this._messaging;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(this.platform.name%20===%20'ios'%20%7C%7C%20this.platform.name%20===%20'macos')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20config%20=%20new%20WebkitMessagingConfig(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20secret:%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hasModernWebkitAPI:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20webkitMessageHandlerNames:%20%5B'contentScopeScriptsIsolated'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._messaging%20=%20new%20Messaging(this.messagingContext,%20config);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this._messaging;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('Messaging%20not%20supported%20yet%20on%20platform:%20'%20+%20this.name);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20platformFeatures%20=%20%7B%0A%20%20%20%20%20%20%20%20ddg_feature_cookie:%20CookieFeature,%0A%20%20%20%20%20%20%20%20ddg_feature_fingerprintingAudio:%20FingerprintingAudio,%0A%20%20%20%20%20%20%20%20ddg_feature_fingerprintingBattery:%20FingerprintingBattery,%0A%20%20%20%20%20%20%20%20ddg_feature_fingerprintingCanvas:%20FingerprintingCanvas,%0A%20%20%20%20%20%20%20%20ddg_feature_googleRejected:%20GoogleRejected,%0A%20%20%20%20%20%20%20%20ddg_feature_gpc:%20GlobalPrivacyControl,%0A%20%20%20%20%20%20%20%20ddg_feature_fingerprintingHardware:%20FingerprintingHardware,%0A%20%20%20%20%20%20%20%20ddg_feature_referrer:%20Referrer,%0A%20%20%20%20%20%20%20%20ddg_feature_fingerprintingScreenSize:%20FingerprintingScreenSize,%0A%20%20%20%20%20%20%20%20ddg_feature_fingerprintingTemporaryStorage:%20FingerprintingTemporaryStorage,%0A%20%20%20%20%20%20%20%20ddg_feature_navigatorInterface:%20NavigatorInterface,%0A%20%20%20%20%20%20%20%20ddg_feature_elementHiding:%20ElementHiding,%0A%20%20%20%20%20%20%20%20ddg_feature_exceptionHandler:%20ExceptionHandler,%0A%20%20%20%20%20%20%20%20ddg_feature_apiManipulation:%20ApiManipulation,%0A%20%20%20%20%20%20%20%20ddg_feature_clickToLoad:%20ClickToLoad%0A%20%20%20%20%7D;%0A%0A%20%20%20%20let%20initArgs%20=%20null;%0A%20%20%20%20const%20updates%20=%20%5B%5D;%0A%20%20%20%20const%20features%20=%20%5B%5D;%0A%20%20%20%20const%20alwaysInitFeatures%20=%20new%20Set(%5B'cookie'%5D);%0A%20%20%20%20const%20performanceMonitor%20=%20new%20PerformanceMonitor();%0A%0A%20%20%20%20//%20It's%20important%20to%20avoid%20enabling%20the%20features%20for%20non-HTML%20documents%20(such%20as%0A%20%20%20%20//%20XML%20documents%20that%20aren't%20XHTML).%20Note%20that%20it's%20necessary%20to%20check%20the%0A%20%20%20%20//%20document%20type%20in%20advance,%20to%20minimise%20the%20risk%20of%20a%20website%20breaking%20the%0A%20%20%20%20//%20checks%20by%20altering%20document.__proto__.%20In%20the%20future,%20it%20might%20be%20worth%0A%20%20%20%20//%20running%20the%20checks%20even%20earlier%20(and%20in%20the%20%22isolated%20world%22%20for%20the%20Chrome%0A%20%20%20%20//%20extension),%20to%20further%20reduce%20that%20risk.%0A%20%20%20%20const%20isHTMLDocument%20=%0A%20%20%20%20%20%20%20%20document%20instanceof%20HTMLDocument%20%7C%7C%20(document%20instanceof%20XMLDocument%20&&%20document.createElement('div')%20instanceof%20HTMLDivElement);%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7Bobject%7D%20LoadArgs%0A%20%20%20%20%20*%20@property%20%7Bimport('./content-feature').Site%7D%20site%0A%20%20%20%20%20*%20@property%20%7Bimport('./utils.js').Platform%7D%20platform%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20documentOriginIsTracker%0A%20%20%20%20%20*%20@property%20%7Bimport('./utils.js').RemoteConfig%7D%20bundledConfig%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20%5BinjectName%5D%0A%20%20%20%20%20*%20@property%20%7Bobject%7D%20trackerLookup%20-%20provided%20currently%20only%20by%20the%20extension%0A%20%20%20%20%20*%20@property%20%7Bimport('@duckduckgo/messaging').MessagingConfig%7D%20%5BmessagingConfig%5D%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7BLoadArgs%7D%20args%0A%20%20%20%20%20*/%0A%20%20%20%20function%20load(args)%20%7B%0A%20%20%20%20%20%20%20%20const%20mark%20=%20performanceMonitor.mark('load');%0A%20%20%20%20%20%20%20%20if%20(!isHTMLDocument)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20featureNames%20=%20platformSupport%5B%22chrome%22%5D%20;%0A%0A%20%20%20%20%20%20%20%20for%20(const%20featureName%20of%20featureNames)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20ContentFeature%20=%20platformFeatures%5B'ddg_feature_'%20+%20featureName%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20featureInstance%20=%20new%20ContentFeature(featureName);%0A%20%20%20%20%20%20%20%20%20%20%20%20featureInstance.callLoad(args);%0A%20%20%20%20%20%20%20%20%20%20%20%20features.push(%7B%20featureName,%20featureInstance%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20mark.end();%0A%20%20%20%20%7D%0A%0A%20%20%20%20async%20function%20init(args)%20%7B%0A%20%20%20%20%20%20%20%20const%20mark%20=%20performanceMonitor.mark('init');%0A%20%20%20%20%20%20%20%20initArgs%20=%20args;%0A%20%20%20%20%20%20%20%20if%20(!isHTMLDocument)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20registerMessageSecret(args.messageSecret);%0A%20%20%20%20%20%20%20%20initStringExemptionLists(args);%0A%20%20%20%20%20%20%20%20const%20resolvedFeatures%20=%20await%20Promise.all(features);%0A%20%20%20%20%20%20%20%20resolvedFeatures.forEach((%7B%20featureInstance,%20featureName%20%7D)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isFeatureBroken(args,%20featureName)%20%7C%7C%20alwaysInitExtensionFeatures(args,%20featureName))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureInstance.callInit(args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20//%20Fire%20off%20updates%20that%20came%20in%20faster%20than%20the%20init%0A%20%20%20%20%20%20%20%20while%20(updates.length)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20update%20=%20updates.pop();%0A%20%20%20%20%20%20%20%20%20%20%20%20await%20updateFeaturesInner(update);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20mark.end();%0A%20%20%20%20%20%20%20%20if%20(args.debug)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20performanceMonitor.measureAll();%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20update(args)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!isHTMLDocument)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(initArgs%20===%20null)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20updates.push(args);%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20updateFeaturesInner(args);%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20alwaysInitExtensionFeatures(args,%20featureName)%20%7B%0A%20%20%20%20%20%20%20%20return%20args.platform.name%20===%20'extension'%20&&%20alwaysInitFeatures.has(featureName);%0A%20%20%20%20%7D%0A%0A%20%20%20%20async%20function%20updateFeaturesInner(args)%20%7B%0A%20%20%20%20%20%20%20%20const%20resolvedFeatures%20=%20await%20Promise.all(features);%0A%20%20%20%20%20%20%20%20resolvedFeatures.forEach((%7B%20featureInstance,%20featureName%20%7D)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isFeatureBroken(initArgs,%20featureName)%20&&%20featureInstance.update)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureInstance.update(args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20exports.init%20=%20init;%0A%20%20%20%20exports.load%20=%20load;%0A%20%20%20%20exports.update%20=%20update;%0A%0A%20%20%20%20return%20exports;%0A%0A%7D)(%7B%7D);%0A")} + ${decodeURI("/*!%20%C2%A9%20DuckDuckGo%20ContentScopeScripts%20protections%20https://github.com/duckduckgo/content-scope-scripts/%20*/%0Avar%20contentScopeFeatures%20=%20(function%20(exports)%20%7B%0A%20%20%20%20'use%20strict';%0A%0A%20%20%20%20/*%20eslint-disable%20no-redeclare%20*/%0A%20%20%20%20const%20Set$1%20=%20globalThis.Set;%0A%20%20%20%20const%20Reflect$1%20=%20globalThis.Reflect;%0A%20%20%20%20const%20customElementsGet%20=%20globalThis.customElements?.get.bind(globalThis.customElements);%0A%20%20%20%20const%20customElementsDefine%20=%20globalThis.customElements?.define.bind(globalThis.customElements);%0A%20%20%20%20const%20getOwnPropertyDescriptor%20=%20Object.getOwnPropertyDescriptor;%0A%20%20%20%20const%20getOwnPropertyDescriptors%20=%20Object.getOwnPropertyDescriptors;%0A%20%20%20%20const%20toString%20=%20Object.prototype.toString;%0A%20%20%20%20const%20objectKeys%20=%20Object.keys;%0A%20%20%20%20const%20objectEntries%20=%20Object.entries;%0A%20%20%20%20const%20objectDefineProperty%20=%20Object.defineProperty;%0A%20%20%20%20const%20URL$1%20=%20globalThis.URL;%0A%20%20%20%20const%20Proxy$1%20=%20globalThis.Proxy;%0A%20%20%20%20const%20functionToString%20=%20Function.prototype.toString;%0A%20%20%20%20const%20TypeError$1%20=%20globalThis.TypeError;%0A%20%20%20%20const%20Symbol%20=%20globalThis.Symbol;%0A%20%20%20%20const%20hasOwnProperty%20=%20Object.prototype.hasOwnProperty;%0A%20%20%20%20const%20dispatchEvent%20=%20globalThis.dispatchEvent?.bind(globalThis);%0A%20%20%20%20const%20addEventListener%20=%20globalThis.addEventListener?.bind(globalThis);%0A%20%20%20%20const%20removeEventListener%20=%20globalThis.removeEventListener?.bind(globalThis);%0A%20%20%20%20const%20CustomEvent$1%20=%20globalThis.CustomEvent;%0A%20%20%20%20const%20Promise$1%20=%20globalThis.Promise;%0A%20%20%20%20const%20String$1%20=%20globalThis.String;%0A%20%20%20%20const%20Map$1%20=%20globalThis.Map;%0A%20%20%20%20const%20Error$2%20=%20globalThis.Error;%0A%20%20%20%20const%20randomUUID%20=%20globalThis.crypto?.randomUUID?.bind(globalThis.crypto);%0A%0A%20%20%20%20var%20capturedGlobals%20=%20/*#__PURE__*/Object.freeze(%7B%0A%20%20%20%20%20%20%20%20__proto__:%20null,%0A%20%20%20%20%20%20%20%20CustomEvent:%20CustomEvent$1,%0A%20%20%20%20%20%20%20%20Error:%20Error$2,%0A%20%20%20%20%20%20%20%20Map:%20Map$1,%0A%20%20%20%20%20%20%20%20Promise:%20Promise$1,%0A%20%20%20%20%20%20%20%20Proxy:%20Proxy$1,%0A%20%20%20%20%20%20%20%20Reflect:%20Reflect$1,%0A%20%20%20%20%20%20%20%20Set:%20Set$1,%0A%20%20%20%20%20%20%20%20String:%20String$1,%0A%20%20%20%20%20%20%20%20Symbol:%20Symbol,%0A%20%20%20%20%20%20%20%20TypeError:%20TypeError$1,%0A%20%20%20%20%20%20%20%20URL:%20URL$1,%0A%20%20%20%20%20%20%20%20addEventListener:%20addEventListener,%0A%20%20%20%20%20%20%20%20customElementsDefine:%20customElementsDefine,%0A%20%20%20%20%20%20%20%20customElementsGet:%20customElementsGet,%0A%20%20%20%20%20%20%20%20dispatchEvent:%20dispatchEvent,%0A%20%20%20%20%20%20%20%20functionToString:%20functionToString,%0A%20%20%20%20%20%20%20%20getOwnPropertyDescriptor:%20getOwnPropertyDescriptor,%0A%20%20%20%20%20%20%20%20getOwnPropertyDescriptors:%20getOwnPropertyDescriptors,%0A%20%20%20%20%20%20%20%20hasOwnProperty:%20hasOwnProperty,%0A%20%20%20%20%20%20%20%20objectDefineProperty:%20objectDefineProperty,%0A%20%20%20%20%20%20%20%20objectEntries:%20objectEntries,%0A%20%20%20%20%20%20%20%20objectKeys:%20objectKeys,%0A%20%20%20%20%20%20%20%20randomUUID:%20randomUUID,%0A%20%20%20%20%20%20%20%20removeEventListener:%20removeEventListener,%0A%20%20%20%20%20%20%20%20toString:%20toString%0A%20%20%20%20%7D);%0A%0A%20%20%20%20/*%20eslint-disable%20no-redeclare,%20no-global-assign%20*/%0A%20%20%20%20/*%20global%20cloneInto,%20exportFunction,%20false%20*/%0A%0A%20%20%20%20//%20Only%20use%20globalThis%20for%20testing%20this%20breaks%20window.wrappedJSObject%20code%20in%20Firefox%0A%0A%20%20%20%20let%20globalObj%20=%20typeof%20window%20===%20'undefined'%20?%20globalThis%20:%20window;%0A%20%20%20%20let%20Error$1%20=%20globalObj.Error;%0A%20%20%20%20let%20messageSecret;%0A%0A%20%20%20%20//%20save%20a%20reference%20to%20original%20CustomEvent%20amd%20dispatchEvent%20so%20they%20can't%20be%20overriden%20to%20forge%20messages%0A%20%20%20%20const%20OriginalCustomEvent%20=%20typeof%20CustomEvent%20===%20'undefined'%20?%20null%20:%20CustomEvent;%0A%20%20%20%20const%20originalWindowDispatchEvent%20=%20typeof%20window%20===%20'undefined'%20?%20null%20:%20window.dispatchEvent.bind(window);%0A%20%20%20%20function%20registerMessageSecret(secret)%20%7B%0A%20%20%20%20%20%20%20%20messageSecret%20=%20secret;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@returns%20%7BHTMLElement%7D%20the%20element%20to%20inject%20the%20script%20into%0A%20%20%20%20%20*/%0A%20%20%20%20function%20getInjectionElement()%20%7B%0A%20%20%20%20%20%20%20%20return%20document.head%20%7C%7C%20document.documentElement;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Creates%20a%20script%20element%20with%20the%20given%20code%20to%20avoid%20Firefox%20CSP%20restrictions.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20css%0A%20%20%20%20%20*%20@returns%20%7BHTMLLinkElement%20%7C%20HTMLStyleElement%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20createStyleElement(css)%20%7B%0A%20%20%20%20%20%20%20%20let%20style;%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20style%20=%20document.createElement('style');%0A%20%20%20%20%20%20%20%20%20%20%20%20style.innerText%20=%20css;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20style;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Injects%20a%20script%20into%20the%20page,%20avoiding%20CSP%20restrictions%20if%20possible.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20injectGlobalStyles(css)%20%7B%0A%20%20%20%20%20%20%20%20const%20style%20=%20createStyleElement(css);%0A%20%20%20%20%20%20%20%20getInjectionElement().appendChild(style);%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20linear%20feedback%20shift%20register%20to%20find%20a%20random%20approximation%0A%20%20%20%20function%20nextRandom(v)%20%7B%0A%20%20%20%20%20%20%20%20return%20Math.abs((v%20%3E%3E%201)%20%7C%20(((v%20%3C%3C%2062)%20%5E%20(v%20%3C%3C%2061))%20&%20(~(~0%20%3C%3C%2063)%20%3C%3C%2062)));%0A%20%20%20%20%7D%0A%0A%20%20%20%20const%20exemptionLists%20=%20%7B%7D;%0A%20%20%20%20function%20shouldExemptUrl(type,%20url)%20%7B%0A%20%20%20%20%20%20%20%20for%20(const%20regex%20of%20exemptionLists%5Btype%5D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(regex.test(url))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20let%20debug%20=%20false;%0A%0A%20%20%20%20function%20initStringExemptionLists(args)%20%7B%0A%20%20%20%20%20%20%20%20const%20%7B%20stringExemptionLists%20%7D%20=%20args;%0A%20%20%20%20%20%20%20%20debug%20=%20args.debug;%0A%20%20%20%20%20%20%20%20for%20(const%20type%20in%20stringExemptionLists)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20exemptionLists%5Btype%5D%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20stringExemption%20of%20stringExemptionLists%5Btype%5D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20exemptionLists%5Btype%5D.push(new%20RegExp(stringExemption));%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Best%20guess%20effort%20if%20the%20document%20is%20being%20framed%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%20if%20we%20infer%20the%20document%20is%20framed%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isBeingFramed()%20%7B%0A%20%20%20%20%20%20%20%20if%20(globalThis.location%20&&%20'ancestorOrigins'%20in%20globalThis.location)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20globalThis.location.ancestorOrigins.length%20%3E%200;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20globalThis.top%20!==%20globalThis.window;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Best%20guess%20effort%20if%20the%20document%20is%20third%20party%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%20if%20we%20infer%20the%20document%20is%20third%20party%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isThirdPartyFrame()%20%7B%0A%20%20%20%20%20%20%20%20if%20(!isBeingFramed())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20const%20tabHostname%20=%20getTabHostname();%0A%20%20%20%20%20%20%20%20//%20If%20we%20can't%20get%20the%20tab%20hostname,%20assume%20it's%20third%20party%0A%20%20%20%20%20%20%20%20if%20(!tabHostname)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20!matchHostname(globalThis.location.hostname,%20tabHostname);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Best%20guess%20effort%20of%20the%20tabs%20hostname;%20where%20possible%20always%20prefer%20the%20args.site.domain%0A%20%20%20%20%20*%20@returns%20%7Bstring%7Cnull%7D%20inferred%20tab%20hostname%0A%20%20%20%20%20*/%0A%20%20%20%20function%20getTabHostname()%20%7B%0A%20%20%20%20%20%20%20%20let%20framingOrigin%20=%20null;%0A%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20globalThis.top%20is%20possibly%20'null'%20here%0A%20%20%20%20%20%20%20%20%20%20%20%20framingOrigin%20=%20globalThis.top.location.href;%0A%20%20%20%20%20%20%20%20%7D%20catch%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20framingOrigin%20=%20globalThis.document.referrer;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Not%20supported%20in%20Firefox%0A%20%20%20%20%20%20%20%20if%20('ancestorOrigins'%20in%20globalThis.location%20&&%20globalThis.location.ancestorOrigins.length)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20ancestorOrigins%20is%20reverse%20order,%20with%20the%20last%20item%20being%20the%20top%20frame%0A%20%20%20%20%20%20%20%20%20%20%20%20framingOrigin%20=%20globalThis.location.ancestorOrigins.item(globalThis.location.ancestorOrigins.length%20-%201);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20framingOrigin%20is%20possibly%20'null'%20here%0A%20%20%20%20%20%20%20%20%20%20%20%20framingOrigin%20=%20new%20URL(framingOrigin).hostname;%0A%20%20%20%20%20%20%20%20%7D%20catch%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20framingOrigin%20=%20null;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20framingOrigin;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Returns%20true%20if%20hostname%20is%20a%20subset%20of%20exceptionDomain%20or%20an%20exact%20match.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20hostname%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20exceptionDomain%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20matchHostname(hostname,%20exceptionDomain)%20%7B%0A%20%20%20%20%20%20%20%20return%20hostname%20===%20exceptionDomain%20%7C%7C%20hostname.endsWith(%60.$%7BexceptionDomain%7D%60);%0A%20%20%20%20%7D%0A%0A%20%20%20%20const%20lineTest%20=%20/(%5C()?(https?:%5B%5E)%5D+):%5B0-9%5D+:%5B0-9%5D+(%5C))?/;%0A%20%20%20%20function%20getStackTraceUrls(stack)%20%7B%0A%20%20%20%20%20%20%20%20const%20urls%20=%20new%20Set$1();%0A%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20errorLines%20=%20stack.split('%5Cn');%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Should%20cater%20for%20Chrome%20and%20Firefox%20stacks,%20we%20only%20care%20about%20https?%20resources.%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20line%20of%20errorLines)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20res%20=%20line.match(lineTest);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(res)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20urls.add(new%20URL(res%5B2%5D,%20location.href));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Fall%20through%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20urls;%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20getStackTraceOrigins(stack)%20%7B%0A%20%20%20%20%20%20%20%20const%20urls%20=%20getStackTraceUrls(stack);%0A%20%20%20%20%20%20%20%20const%20origins%20=%20new%20Set$1();%0A%20%20%20%20%20%20%20%20for%20(const%20url%20of%20urls)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20origins.add(url.hostname);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20origins;%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20Checks%20the%20stack%20trace%20if%20there%20are%20known%20libraries%20that%20are%20broken.%0A%20%20%20%20function%20shouldExemptMethod(type)%20%7B%0A%20%20%20%20%20%20%20%20//%20Short%20circuit%20stack%20tracing%20if%20we%20don't%20have%20checks%0A%20%20%20%20%20%20%20%20if%20(!(type%20in%20exemptionLists)%20%7C%7C%20exemptionLists%5Btype%5D.length%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20const%20stack%20=%20getStack();%0A%20%20%20%20%20%20%20%20const%20errorFiles%20=%20getStackTraceUrls(stack);%0A%20%20%20%20%20%20%20%20for%20(const%20path%20of%20errorFiles)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(shouldExemptUrl(type,%20path.href))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20Iterate%20through%20the%20key,%20passing%20an%20item%20index%20and%20a%20byte%20to%20be%20modified%0A%20%20%20%20function%20iterateDataKey(key,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20let%20item%20=%20key.charCodeAt(0);%0A%20%20%20%20%20%20%20%20for%20(const%20i%20in%20key)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20byte%20=%20key.charCodeAt(i);%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(let%20j%20=%208;%20j%20%3E=%200;%20j--)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20res%20=%20callback(item,%20byte);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Exit%20early%20if%20callback%20returns%20null%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(res%20===%20null)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20find%20next%20item%20to%20perturb%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20item%20=%20nextRandom(item);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Right%20shift%20as%20we%20use%20the%20least%20significant%20bit%20of%20it%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20byte%20=%20byte%20%3E%3E%201;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20isFeatureBroken(args,%20feature)%20%7B%0A%20%20%20%20%20%20%20%20return%20isPlatformSpecificFeature(feature)%0A%20%20%20%20%20%20%20%20%20%20%20%20?%20!args.site.enabledFeatures.includes(feature)%0A%20%20%20%20%20%20%20%20%20%20%20%20:%20args.site.isBroken%20%7C%7C%20args.site.allowlisted%20%7C%7C%20!args.site.enabledFeatures.includes(feature);%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20camelcase(dashCaseText)%20%7B%0A%20%20%20%20%20%20%20%20return%20dashCaseText.replace(/-(.)/g,%20(match,%20letter)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20letter.toUpperCase();%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20We%20use%20this%20method%20to%20detect%20M1%20macs%20and%20set%20appropriate%20API%20values%20to%20prevent%20sites%20from%20detecting%20fingerprinting%20protections%0A%20%20%20%20function%20isAppleSilicon()%20%7B%0A%20%20%20%20%20%20%20%20const%20canvas%20=%20document.createElement('canvas');%0A%20%20%20%20%20%20%20%20const%20gl%20=%20canvas.getContext('webgl');%0A%0A%20%20%20%20%20%20%20%20//%20Best%20guess%20if%20the%20device%20is%20an%20Apple%20Silicon%0A%20%20%20%20%20%20%20%20//%20https://stackoverflow.com/a/65412357%0A%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Object%20is%20possibly%20'null'%0A%20%20%20%20%20%20%20%20return%20gl.getSupportedExtensions().indexOf('WEBGL_compressed_texture_etc')%20!==%20-1;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Take%20configSeting%20which%20should%20be%20an%20array%20of%20possible%20values.%0A%20%20%20%20%20*%20If%20a%20value%20contains%20a%20criteria%20that%20is%20a%20match%20for%20this%20environment%20then%20return%20that%20value.%0A%20%20%20%20%20*%20Otherwise%20return%20the%20first%20value%20that%20doesn't%20have%20a%20criteria.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@param%20%7BConfigSetting%5B%5D%7D%20configSetting%20-%20Config%20setting%20which%20should%20contain%20a%20list%20of%20possible%20values%0A%20%20%20%20%20*%20@returns%20%7B*%7Cundefined%7D%20-%20The%20value%20from%20the%20list%20that%20best%20matches%20the%20criteria%20in%20the%20config%0A%20%20%20%20%20*/%0A%20%20%20%20function%20processAttrByCriteria(configSetting)%20%7B%0A%20%20%20%20%20%20%20%20let%20bestOption;%0A%20%20%20%20%20%20%20%20for%20(const%20item%20of%20configSetting)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(item.criteria)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(item.criteria.arch%20===%20'AppleSilicon'%20&&%20isAppleSilicon())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20bestOption%20=%20item;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20bestOption%20=%20item;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20bestOption;%0A%20%20%20%20%7D%0A%0A%20%20%20%20const%20functionMap%20=%20%7B%0A%20%20%20%20%20%20%20%20/**%20Useful%20for%20debugging%20APIs%20in%20the%20wild,%20shouldn't%20be%20used%20*/%0A%20%20%20%20%20%20%20%20debug:%20(...args)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20console.log('debugger',%20...args);%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20no-debugger%0A%20%20%20%20%20%20%20%20%20%20%20%20debugger;%0A%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20noop:%20()%20=%3E%20%7B%7D,%0A%20%20%20%20%7D;%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7Bobject%7D%20ConfigSetting%0A%20%20%20%20%20*%20@property%20%7B'undefined'%20%7C%20'number'%20%7C%20'string'%20%7C%20'function'%20%7C%20'boolean'%20%7C%20'null'%20%7C%20'array'%20%7C%20'object'%7D%20type%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20%5BfunctionName%5D%0A%20%20%20%20%20*%20@property%20%7Bboolean%20%7C%20string%20%7C%20number%7D%20value%0A%20%20%20%20%20*%20@property%20%7Bobject%7D%20%5Bcriteria%5D%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20criteria.arch%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Processes%20a%20structured%20config%20setting%20and%20returns%20the%20value%20according%20to%20its%20type%0A%20%20%20%20%20*%20@param%20%7BConfigSetting%7D%20configSetting%0A%20%20%20%20%20*%20@param%20%7B*%7D%20%5BdefaultValue%5D%0A%20%20%20%20%20*%20@returns%0A%20%20%20%20%20*/%0A%20%20%20%20function%20processAttr(configSetting,%20defaultValue)%20%7B%0A%20%20%20%20%20%20%20%20if%20(configSetting%20===%20undefined)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20defaultValue;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20configSettingType%20=%20typeof%20configSetting;%0A%20%20%20%20%20%20%20%20switch%20(configSettingType)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20'object':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(Array.isArray(configSetting))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configSetting%20=%20processAttrByCriteria(configSetting);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(configSetting%20===%20undefined)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20defaultValue;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!configSetting.type)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20defaultValue;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(configSetting.type%20===%20'function')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(configSetting.functionName%20&&%20functionMap%5BconfigSetting.functionName%5D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20functionMap%5BconfigSetting.functionName%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(configSetting.type%20===%20'undefined')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20undefined;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20All%20JSON%20expressable%20types%20are%20handled%20here%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20configSetting.value;%0A%20%20%20%20%20%20%20%20%20%20%20%20default:%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20defaultValue;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20getStack()%20%7B%0A%20%20%20%20%20%20%20%20return%20new%20Error$1().stack;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7B*%5B%5D%7D%20argsArray%0A%20%20%20%20%20*%20@returns%20%7Bstring%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20debugSerialize(argsArray)%20%7B%0A%20%20%20%20%20%20%20%20const%20maxSerializedSize%20=%201000;%0A%20%20%20%20%20%20%20%20const%20serializedArgs%20=%20argsArray.map((arg)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20serializableOut%20=%20JSON.stringify(arg);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(serializableOut.length%20%3E%20maxSerializedSize)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%60%3Ctruncated,%20length:%20$%7BserializableOut.length%7D,%20value:%20$%7BserializableOut.substring(0,%20maxSerializedSize)%7D...%3E%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20serializableOut;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Sometimes%20this%20happens%20when%20we%20can't%20serialize%20an%20object%20to%20string%20but%20we%20still%20wish%20to%20log%20it%20and%20make%20other%20args%20readable%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20'%3Cunserializable%3E';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20return%20JSON.stringify(serializedArgs);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@template%20%7Bobject%7D%20P%0A%20%20%20%20%20*%20@typedef%20%7Bobject%7D%20ProxyObject%3CP%3E%0A%20%20%20%20%20*%20@property%20%7B(target?:%20object,%20thisArg?:%20P,%20args?:%20object)%20=%3E%20void%7D%20apply%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@template%20%5BP=object%5D%0A%20%20%20%20%20*/%0A%20%20%20%20class%20DDGProxy%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('./content-feature').default%7D%20feature%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BP%7D%20objectScope%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20property%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BProxyObject%3CP%3E%7D%20proxyObject%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(feature,%20objectScope,%20property,%20proxyObject)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.objectScope%20=%20objectScope;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.property%20=%20property;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.feature%20=%20feature;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20feature.name;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.camelFeatureName%20=%20camelcase(this.featureName);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20outputHandler%20=%20(...args)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.feature.addDebugFlag();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20isExempt%20=%20shouldExemptMethod(this.camelFeatureName);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Keep%20this%20here%20as%20getStack()%20is%20expensive%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(debug)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20postDebugMessage(this.camelFeatureName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20isProxy:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20action:%20isExempt%20?%20'ignore'%20:%20'restrict',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20kind:%20this.property,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20documentUrl:%20document.location.href,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20stack:%20getStack(),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20args:%20debugSerialize(args%5B2%5D),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20The%20normal%20return%20value%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(isExempt)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(...args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20proxyObject.apply(...args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20getMethod%20=%20(target,%20prop,%20receiver)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.feature.addDebugFlag();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(prop%20===%20'toString')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20method%20=%20Reflect.get(target,%20prop,%20receiver).bind(target);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Object.defineProperty(method,%20'toString',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value:%20String.toString.bind(String.toString),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20method;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.get(target,%20prop,%20receiver);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._native%20=%20objectScope%5Bproperty%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20handler%20=%20%7B%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20handler.apply%20=%20outputHandler;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20handler.get%20=%20getMethod;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.internal%20=%20new%20globalObj.Proxy(objectScope%5Bproperty%5D,%20handler);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Actually%20apply%20the%20proxy%20to%20the%20native%20property%0A%20%20%20%20%20%20%20%20overload()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.objectScope%5Bthis.property%5D%20=%20this.internal;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20overloadDescriptor()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20TODO:%20this%20is%20not%20always%20correct!%20Use%20wrap*%20or%20shim*%20methods%20instead%0A%20%20%20%20%20%20%20%20%20%20%20%20this.feature.defineProperty(this.objectScope,%20this.property,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value:%20this.internal,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20writable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20const%20maxCounter%20=%20new%20Map();%0A%20%20%20%20function%20numberOfTimesDebugged(feature)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!maxCounter.has(feature))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20maxCounter.set(feature,%201);%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20maxCounter.set(feature,%20maxCounter.get(feature)%20+%201);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20maxCounter.get(feature);%0A%20%20%20%20%7D%0A%0A%20%20%20%20const%20DEBUG_MAX_TIMES%20=%205000;%0A%0A%20%20%20%20function%20postDebugMessage(feature,%20message,%20allowNonDebug%20=%20false)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!debug%20&&%20!allowNonDebug)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(numberOfTimesDebugged(feature)%20%3E%20DEBUG_MAX_TIMES)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(message.stack)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20scriptOrigins%20=%20%5B...getStackTraceOrigins(message.stack)%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20message.scriptOrigins%20=%20scriptOrigins;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20globalObj.postMessage(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20action:%20feature,%0A%20%20%20%20%20%20%20%20%20%20%20%20message,%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20let%20DDGReflect;%0A%20%20%20%20let%20DDGPromise;%0A%0A%20%20%20%20//%20Exports%20for%20usage%20where%20we%20have%20to%20cross%20the%20xray%20boundary:%20https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Sharing_objects_with_page_scripts%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20DDGPromise%20=%20globalObj.Promise;%0A%20%20%20%20%20%20%20%20DDGReflect%20=%20globalObj.Reflect;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7Bstring%20%7C%20null%7D%20topLevelHostname%0A%20%20%20%20%20*%20@param%20%7Bobject%5B%5D%7D%20featureList%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isUnprotectedDomain(topLevelHostname,%20featureList)%20%7B%0A%20%20%20%20%20%20%20%20let%20unprotectedDomain%20=%20false;%0A%20%20%20%20%20%20%20%20if%20(!topLevelHostname)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20const%20domainParts%20=%20topLevelHostname.split('.');%0A%0A%20%20%20%20%20%20%20%20//%20walk%20up%20the%20domain%20to%20see%20if%20it's%20unprotected%0A%20%20%20%20%20%20%20%20while%20(domainParts.length%20%3E%201%20&&%20!unprotectedDomain)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20partialDomain%20=%20domainParts.join('.');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20unprotectedDomain%20=%20featureList.filter((domain)%20=%3E%20domain.domain%20===%20partialDomain).length%20%3E%200;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20domainParts.shift();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20unprotectedDomain;%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20parseVersionString(versionString)%20%7B%0A%20%20%20%20%20%20%20%20return%20versionString.split('.').map(Number);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20minVersionString%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20applicationVersionString%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20satisfiesMinVersion(minVersionString,%20applicationVersionString)%20%7B%0A%20%20%20%20%20%20%20%20const%20minVersions%20=%20parseVersionString(minVersionString);%0A%20%20%20%20%20%20%20%20const%20currentVersions%20=%20parseVersionString(applicationVersionString);%0A%20%20%20%20%20%20%20%20const%20maxLength%20=%20Math.max(minVersions.length,%20currentVersions.length);%0A%20%20%20%20%20%20%20%20for%20(let%20i%20=%200;%20i%20%3C%20maxLength;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20minNumberPart%20=%20minVersions%5Bi%5D%20%7C%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20currentVersionPart%20=%20currentVersions%5Bi%5D%20%7C%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(currentVersionPart%20%3E%20minNumberPart)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(currentVersionPart%20%3C%20minNumberPart)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7Bstring%20%7C%20number%20%7C%20undefined%7D%20minSupportedVersion%0A%20%20%20%20%20*%20@param%20%7Bstring%20%7C%20number%20%7C%20undefined%7D%20currentVersion%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isSupportedVersion(minSupportedVersion,%20currentVersion)%20%7B%0A%20%20%20%20%20%20%20%20if%20(typeof%20currentVersion%20===%20'string'%20&&%20typeof%20minSupportedVersion%20===%20'string')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(satisfiesMinVersion(minSupportedVersion,%20currentVersion))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(typeof%20currentVersion%20===%20'number'%20&&%20typeof%20minSupportedVersion%20===%20'number')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(minSupportedVersion%20%3C=%20currentVersion)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Retutns%20a%20list%20of%20enabled%20features%0A%20%20%20%20%20*%20@param%20%7BRemoteConfig%7D%20data%0A%20%20%20%20%20*%20@param%20%7Bstring%20%7C%20null%7D%20topLevelHostname%0A%20%20%20%20%20*%20@param%20%7BPlatform%5B'version'%5D%7D%20platformVersion%0A%20%20%20%20%20*%20@param%20%7Bstring%5B%5D%7D%20platformSpecificFeatures%0A%20%20%20%20%20*%20@returns%20%7Bstring%5B%5D%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20computeEnabledFeatures(data,%20topLevelHostname,%20platformVersion,%20platformSpecificFeatures%20=%20%5B%5D)%20%7B%0A%20%20%20%20%20%20%20%20const%20remoteFeatureNames%20=%20Object.keys(data.features);%0A%20%20%20%20%20%20%20%20const%20platformSpecificFeaturesNotInRemoteConfig%20=%20platformSpecificFeatures.filter(%0A%20%20%20%20%20%20%20%20%20%20%20%20(featureName)%20=%3E%20!remoteFeatureNames.includes(featureName),%0A%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20const%20enabledFeatures%20=%20remoteFeatureNames%0A%20%20%20%20%20%20%20%20%20%20%20%20.filter((featureName)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20feature%20=%20data.features%5BfeatureName%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Check%20that%20the%20platform%20supports%20minSupportedVersion%20checks%20and%20that%20the%20feature%20has%20a%20minSupportedVersion%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(feature.minSupportedVersion%20&&%20platformVersion)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isSupportedVersion(feature.minSupportedVersion,%20platformVersion))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20feature.state%20===%20'enabled'%20&&%20!isUnprotectedDomain(topLevelHostname,%20feature.exceptions);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20%20%20%20%20%20%20.concat(platformSpecificFeaturesNotInRemoteConfig);%20//%20only%20disable%20platform%20specific%20features%20if%20it's%20explicitly%20disabled%20in%20remote%20config%0A%20%20%20%20%20%20%20%20return%20enabledFeatures;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Returns%20the%20relevant%20feature%20settings%20for%20the%20enabled%20features%0A%20%20%20%20%20*%20@param%20%7BRemoteConfig%7D%20data%0A%20%20%20%20%20*%20@param%20%7Bstring%5B%5D%7D%20enabledFeatures%0A%20%20%20%20%20*%20@returns%20%7BRecord%3Cstring,%20unknown%3E%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20parseFeatureSettings(data,%20enabledFeatures)%20%7B%0A%20%20%20%20%20%20%20%20/**%20@type%20%7BRecord%3Cstring,%20unknown%3E%7D%20*/%0A%20%20%20%20%20%20%20%20const%20featureSettings%20=%20%7B%7D;%0A%20%20%20%20%20%20%20%20const%20remoteFeatureNames%20=%20Object.keys(data.features);%0A%20%20%20%20%20%20%20%20remoteFeatureNames.forEach((featureName)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!enabledFeatures.includes(featureName))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20featureSettings%5BfeatureName%5D%20=%20data.features%5BfeatureName%5D.settings;%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20return%20featureSettings;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@import%20%7BFeatureName%7D%20from%20%22./features%22;%0A%20%20%20%20%20*%20@type%20%7BFeatureName%5B%5D%7D%0A%20%20%20%20%20*/%0A%20%20%20%20const%20platformSpecificFeatures%20=%20%5B'windowsPermissionUsage',%20'messageBridge'%5D;%0A%0A%20%20%20%20function%20isPlatformSpecificFeature(featureName)%20%7B%0A%20%20%20%20%20%20%20%20return%20platformSpecificFeatures.includes(featureName);%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20createCustomEvent(eventName,%20eventDetail)%20%7B%0A%0A%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20possibly%20null%0A%20%20%20%20%20%20%20%20return%20new%20OriginalCustomEvent(eventName,%20eventDetail);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%20@deprecated%20*/%0A%20%20%20%20function%20legacySendMessage(messageType,%20options)%20%7B%0A%20%20%20%20%20%20%20%20//%20FF%20&%20Chrome%0A%20%20%20%20%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20originalWindowDispatchEvent%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20originalWindowDispatchEvent(createCustomEvent('sendMessageProxy'%20+%20messageSecret,%20%7B%20detail:%20%7B%20messageType,%20options%20%7D%20%7D))%0A%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20//%20TBD%20other%20platforms%0A%20%20%20%20%7D%0A%0A%20%20%20%20const%20baseFeatures%20=%20/**%20@type%20%7Bconst%7D%20*/%20(%5B%0A%20%20%20%20%20%20%20%20'fingerprintingAudio',%0A%20%20%20%20%20%20%20%20'fingerprintingBattery',%0A%20%20%20%20%20%20%20%20'fingerprintingCanvas',%0A%20%20%20%20%20%20%20%20'googleRejected',%0A%20%20%20%20%20%20%20%20'gpc',%0A%20%20%20%20%20%20%20%20'fingerprintingHardware',%0A%20%20%20%20%20%20%20%20'referrer',%0A%20%20%20%20%20%20%20%20'fingerprintingScreenSize',%0A%20%20%20%20%20%20%20%20'fingerprintingTemporaryStorage',%0A%20%20%20%20%20%20%20%20'navigatorInterface',%0A%20%20%20%20%20%20%20%20'elementHiding',%0A%20%20%20%20%20%20%20%20'exceptionHandler',%0A%20%20%20%20%20%20%20%20'apiManipulation',%0A%20%20%20%20%5D);%0A%0A%20%20%20%20const%20otherFeatures%20=%20/**%20@type%20%7Bconst%7D%20*/%20(%5B%0A%20%20%20%20%20%20%20%20'clickToLoad',%0A%20%20%20%20%20%20%20%20'cookie',%0A%20%20%20%20%20%20%20%20'messageBridge',%0A%20%20%20%20%20%20%20%20'duckPlayer',%0A%20%20%20%20%20%20%20%20'harmfulApis',%0A%20%20%20%20%20%20%20%20'webCompat',%0A%20%20%20%20%20%20%20%20'windowsPermissionUsage',%0A%20%20%20%20%20%20%20%20'brokerProtection',%0A%20%20%20%20%20%20%20%20'performanceMetrics',%0A%20%20%20%20%20%20%20%20'breakageReporting',%0A%20%20%20%20%20%20%20%20'autofillPasswordImport',%0A%20%20%20%20%5D);%0A%0A%20%20%20%20/**%20@typedef%20%7BbaseFeatures%5Bnumber%5D%7CotherFeatures%5Bnumber%5D%7D%20FeatureName%20*/%0A%20%20%20%20/**%20@type%20%7BRecord%3Cstring,%20FeatureName%5B%5D%3E%7D%20*/%0A%20%20%20%20const%20platformSupport%20=%20%7B%0A%20%20%20%20%20%20%20%20apple:%20%5B'webCompat',%20...baseFeatures%5D,%0A%20%20%20%20%20%20%20%20'apple-isolated':%20%5B'duckPlayer',%20'brokerProtection',%20'performanceMetrics',%20'clickToLoad',%20'messageBridge'%5D,%0A%20%20%20%20%20%20%20%20android:%20%5B...baseFeatures,%20'webCompat',%20'clickToLoad',%20'breakageReporting',%20'duckPlayer'%5D,%0A%20%20%20%20%20%20%20%20'android-autofill-password-import':%20%5B'autofillPasswordImport'%5D,%0A%20%20%20%20%20%20%20%20windows:%20%5B'cookie',%20...baseFeatures,%20'windowsPermissionUsage',%20'duckPlayer',%20'brokerProtection',%20'breakageReporting'%5D,%0A%20%20%20%20%20%20%20%20firefox:%20%5B'cookie',%20...baseFeatures,%20'clickToLoad'%5D,%0A%20%20%20%20%20%20%20%20chrome:%20%5B'cookie',%20...baseFeatures,%20'clickToLoad'%5D,%0A%20%20%20%20%20%20%20%20'chrome-mv3':%20%5B'cookie',%20...baseFeatures,%20'clickToLoad'%5D,%0A%20%20%20%20%20%20%20%20integration:%20%5B...baseFeatures,%20...otherFeatures%5D,%0A%20%20%20%20%7D;%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Performance%20monitor,%20holds%20reference%20to%20PerformanceMark%20instances.%0A%20%20%20%20%20*/%0A%20%20%20%20class%20PerformanceMonitor%20%7B%0A%20%20%20%20%20%20%20%20constructor()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.marks%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Create%20performance%20marker%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20name%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPerformanceMark%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20mark(name)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20mark%20=%20new%20PerformanceMark(name);%0A%20%20%20%20%20%20%20%20%20%20%20%20this.marks.push(mark);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20mark;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Measure%20all%20performance%20markers%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20measureAll()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.marks.forEach((mark)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mark.measure();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Tiny%20wrapper%20around%20performance.mark%20and%20performance.measure%0A%20%20%20%20%20*/%0A%20%20%20%20//%20eslint-disable-next-line%20no-redeclare%0A%20%20%20%20class%20PerformanceMark%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20name%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(name)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.name%20=%20name;%0A%20%20%20%20%20%20%20%20%20%20%20%20performance.mark(this.name%20+%20'Start');%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20end()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20performance.mark(this.name%20+%20'End');%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20measure()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20performance.measure(this.name,%20this.name%20+%20'Start',%20this.name%20+%20'End');%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20Cookie%20%7B%0A%20%20%20%20%20%20%20%20constructor(cookieString)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.parts%20=%20cookieString.split(';');%0A%20%20%20%20%20%20%20%20%20%20%20%20this.parse();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20parse()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20EXTRACT_ATTRIBUTES%20=%20new%20Set(%5B'max-age',%20'expires',%20'domain'%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20this.attrIdx%20=%20%7B%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.parts.forEach((part,%20index)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20kv%20=%20part.split('=',%201);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20attribute%20=%20kv%5B0%5D.trim();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20value%20=%20part.slice(kv%5B0%5D.length%20+%201);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(index%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.name%20=%20attribute;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.value%20=%20value;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(EXTRACT_ATTRIBUTES.has(attribute.toLowerCase()))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this%5Battribute.toLowerCase()%5D%20=%20value;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Object%20is%20possibly%20'undefined'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.attrIdx%5Battribute.toLowerCase()%5D%20=%20index;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20getExpiry()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20expires%20is%20not%20defined%20in%20the%20type%20definition%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this.maxAge%20&&%20!this.expires)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20NaN;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20expiry%20=%20this.maxAge%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20?%20parseInt(this.maxAge)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20:%20//%20@ts-expect-error%20expires%20is%20not%20defined%20in%20the%20type%20definition%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(new%20Date(this.expires)%20-%20new%20Date())%20/%201000;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20expiry;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20get%20maxAge()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this%5B'max-age'%5D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20set%20maxAge(value)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Object%20is%20possibly%20'undefined'.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.attrIdx%5B'max-age'%5D%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Object%20is%20possibly%20'undefined'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.parts.splice(this.attrIdx%5B'max-age'%5D,%201,%20%60max-age=$%7Bvalue%7D%60);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.parts.push(%60max-age=$%7Bvalue%7D%60);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20this.parse();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20toString()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.parts.join(';');%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20isJSONArray(value)%20%7B%0A%20%20%20%20%20%20return%20Array.isArray(value);%0A%20%20%20%20%7D%0A%20%20%20%20function%20isJSONObject(value)%20%7B%0A%20%20%20%20%20%20return%20value%20!==%20null%20&&%20typeof%20value%20===%20'object'%20&&%20(value.constructor%20===%20undefined%20%7C%7C%0A%20%20%20%20%20%20//%20for%20example%20Object.create(null)%0A%20%20%20%20%20%20value.constructor.name%20===%20'Object')%20//%20do%20not%20match%20on%20classes%20or%20Array%0A%20%20%20%20%20%20;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Test%20deep%20equality%20of%20two%20JSON%20values,%20objects,%20or%20arrays%0A%20%20%20%20%20*/%0A%20%20%20%20//%20TODO:%20write%20unit%20tests%0A%20%20%20%20function%20isEqual(a,%20b)%20%7B%0A%20%20%20%20%20%20//%20FIXME:%20this%20function%20will%20return%20false%20for%20two%20objects%20with%20the%20same%20keys%0A%20%20%20%20%20%20//%20%20but%20different%20order%20of%20keys%0A%20%20%20%20%20%20return%20JSON.stringify(a)%20===%20JSON.stringify(b);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Get%20all%20but%20the%20last%20items%20from%20an%20array%0A%20%20%20%20%20*/%0A%20%20%20%20//%20TODO:%20write%20unit%20tests%0A%20%20%20%20function%20initial(array)%20%7B%0A%20%20%20%20%20%20return%20array.slice(0,%20array.length%20-%201);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Get%20the%20last%20item%20from%20an%20array%0A%20%20%20%20%20*/%0A%20%20%20%20//%20TODO:%20write%20unit%20tests%0A%20%20%20%20function%20last(array)%20%7B%0A%20%20%20%20%20%20return%20array%5Barray.length%20-%201%5D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Test%20whether%20a%20value%20is%20an%20Object%20or%20an%20Array%20(and%20not%20a%20primitive%20JSON%20value)%0A%20%20%20%20%20*/%0A%20%20%20%20//%20TODO:%20write%20unit%20tests%0A%20%20%20%20function%20isObjectOrArray(value)%20%7B%0A%20%20%20%20%20%20return%20typeof%20value%20===%20'object'%20&&%20value%20!==%20null;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Immutability%20helpers%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20inspiration:%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20https://www.npmjs.com/package/seamless-immutable%0A%20%20%20%20%20*%20https://www.npmjs.com/package/ih%0A%20%20%20%20%20*%20https://www.npmjs.com/package/mutatis%0A%20%20%20%20%20*%20https://github.com/mariocasciaro/object-path-immutable%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Shallow%20clone%20of%20an%20Object,%20Array,%20or%20value%0A%20%20%20%20%20*%20Symbols%20are%20cloned%20too.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20shallowClone(value)%20%7B%0A%20%20%20%20%20%20if%20(isJSONArray(value))%20%7B%0A%20%20%20%20%20%20%20%20//%20copy%20array%20items%0A%20%20%20%20%20%20%20%20const%20copy%20=%20value.slice();%0A%0A%20%20%20%20%20%20%20%20//%20copy%20all%20symbols%0A%20%20%20%20%20%20%20%20Object.getOwnPropertySymbols(value).forEach(symbol%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20%20%20%20%20copy%5Bsymbol%5D%20=%20value%5Bsymbol%5D;%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20return%20copy;%0A%20%20%20%20%20%20%7D%20else%20if%20(isJSONObject(value))%20%7B%0A%20%20%20%20%20%20%20%20//%20copy%20object%20properties%0A%20%20%20%20%20%20%20%20const%20copy%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20...value%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20//%20copy%20all%20symbols%0A%20%20%20%20%20%20%20%20Object.getOwnPropertySymbols(value).forEach(symbol%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20%20%20%20%20copy%5Bsymbol%5D%20=%20value%5Bsymbol%5D;%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20return%20copy;%0A%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20return%20value;%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Update%20a%20value%20in%20an%20object%20in%20an%20immutable%20way.%0A%20%20%20%20%20*%20If%20the%20value%20is%20unchanged,%20the%20original%20object%20will%20be%20returned%0A%20%20%20%20%20*/%0A%20%20%20%20function%20applyProp(object,%20key,%20value)%20%7B%0A%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20if%20(object%5Bkey%5D%20===%20value)%20%7B%0A%20%20%20%20%20%20%20%20//%20return%20original%20object%20unchanged%20when%20the%20new%20value%20is%20identical%20to%20the%20old%20one%0A%20%20%20%20%20%20%20%20return%20object;%0A%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20const%20updatedObject%20=%20shallowClone(object);%0A%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20%20%20updatedObject%5Bkey%5D%20=%20value;%0A%20%20%20%20%20%20%20%20return%20updatedObject;%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20helper%20function%20to%20get%20a%20nested%20property%20in%20an%20object%20or%20array%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@return%20Returns%20the%20field%20when%20found,%20or%20undefined%20when%20the%20path%20doesn't%20exist%0A%20%20%20%20%20*/%0A%20%20%20%20function%20getIn(object,%20path)%20%7B%0A%20%20%20%20%20%20let%20value%20=%20object;%0A%20%20%20%20%20%20let%20i%20=%200;%0A%20%20%20%20%20%20while%20(i%20%3C%20path.length)%20%7B%0A%20%20%20%20%20%20%20%20if%20(isJSONObject(value))%20%7B%0A%20%20%20%20%20%20%20%20%20%20value%20=%20value%5Bpath%5Bi%5D%5D;%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(isJSONArray(value))%20%7B%0A%20%20%20%20%20%20%20%20%20%20value%20=%20value%5BparseInt(path%5Bi%5D)%5D;%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20value%20=%20undefined;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20i++;%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20return%20value;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20helper%20function%20to%20replace%20a%20nested%20property%20in%20an%20object%20with%20a%20new%20value%0A%20%20%20%20%20*%20without%20mutating%20the%20object%20itself.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@param%20object%0A%20%20%20%20%20*%20@param%20path%0A%20%20%20%20%20*%20@param%20value%0A%20%20%20%20%20*%20@param%20%5BcreatePath=false%5D%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20If%20true,%20%60path%60%20will%20be%20created%20when%20(partly)%20missing%20in%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20the%20object.%20For%20correctly%20creating%20nested%20Arrays%20or%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Objects,%20the%20function%20relies%20on%20%60path%60%20containing%20number%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20in%20case%20of%20array%20indexes.%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20If%20false%20(default),%20an%20error%20will%20be%20thrown%20when%20the%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20path%20doesn't%20exist.%0A%20%20%20%20%20*%20@return%20Returns%20a%20new,%20updated%20object%20or%20array%0A%20%20%20%20%20*/%0A%20%20%20%20function%20setIn(object,%20path,%20value)%20%7B%0A%20%20%20%20%20%20let%20createPath%20=%20arguments.length%20%3E%203%20&&%20arguments%5B3%5D%20!==%20undefined%20?%20arguments%5B3%5D%20:%20false;%0A%20%20%20%20%20%20if%20(path.length%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20return%20value;%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20const%20key%20=%20path%5B0%5D;%0A%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20const%20updatedValue%20=%20setIn(object%20?%20object%5Bkey%5D%20:%20undefined,%20path.slice(1),%20value,%20createPath);%0A%20%20%20%20%20%20if%20(isJSONObject(object)%20%7C%7C%20isJSONArray(object))%20%7B%0A%20%20%20%20%20%20%20%20return%20applyProp(object,%20key,%20updatedValue);%0A%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20if%20(createPath)%20%7B%0A%20%20%20%20%20%20%20%20%20%20const%20newObject%20=%20IS_INTEGER_REGEX.test(key)%20?%20%5B%5D%20:%20%7B%7D;%0A%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20%20%20%20%20newObject%5Bkey%5D%20=%20updatedValue;%0A%20%20%20%20%20%20%20%20%20%20return%20newObject;%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('Path%20does%20not%20exist');%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20const%20IS_INTEGER_REGEX%20=%20/%5E%5Cd+$/;%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20helper%20function%20to%20replace%20a%20nested%20property%20in%20an%20object%20with%20a%20new%20value%0A%20%20%20%20%20*%20without%20mutating%20the%20object%20itself.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@return%20%20Returns%20a%20new,%20updated%20object%20or%20array%0A%20%20%20%20%20*/%0A%20%20%20%20function%20updateIn(object,%20path,%20transform)%20%7B%0A%20%20%20%20%20%20if%20(path.length%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20return%20transform(object);%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20if%20(!isObjectOrArray(object))%20%7B%0A%20%20%20%20%20%20%20%20throw%20new%20Error('Path%20doesn%5C't%20exist');%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20const%20key%20=%20path%5B0%5D;%0A%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20const%20updatedValue%20=%20updateIn(object%5Bkey%5D,%20path.slice(1),%20transform);%0A%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20return%20applyProp(object,%20key,%20updatedValue);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20helper%20function%20to%20delete%20a%20nested%20property%20in%20an%20object%0A%20%20%20%20%20*%20without%20mutating%20the%20object%20itself.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@return%20Returns%20a%20new,%20updated%20object%20or%20array%0A%20%20%20%20%20*/%0A%20%20%20%20function%20deleteIn(object,%20path)%20%7B%0A%20%20%20%20%20%20if%20(path.length%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20return%20object;%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20if%20(!isObjectOrArray(object))%20%7B%0A%20%20%20%20%20%20%20%20throw%20new%20Error('Path%20does%20not%20exist');%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20if%20(path.length%20===%201)%20%7B%0A%20%20%20%20%20%20%20%20const%20key%20=%20path%5B0%5D;%0A%20%20%20%20%20%20%20%20if%20(!(key%20in%20object))%20%7B%0A%20%20%20%20%20%20%20%20%20%20//%20key%20doesn't%20exist.%20return%20object%20unchanged%0A%20%20%20%20%20%20%20%20%20%20return%20object;%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20const%20updatedObject%20=%20shallowClone(object);%0A%20%20%20%20%20%20%20%20%20%20if%20(isJSONArray(updatedObject))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20updatedObject.splice(parseInt(key),%201);%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20if%20(isJSONObject(updatedObject))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20delete%20updatedObject%5Bkey%5D;%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20return%20updatedObject;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20const%20key%20=%20path%5B0%5D;%0A%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20const%20updatedValue%20=%20deleteIn(object%5Bkey%5D,%20path.slice(1));%0A%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20return%20applyProp(object,%20key,%20updatedValue);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Insert%20a%20new%20item%20in%20an%20array%20at%20a%20specific%20index.%0A%20%20%20%20%20*%20Example%20usage:%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%20%20%20%20insertAt(%7Barr:%20%5B1,2,3%5D%7D,%20%5B'arr',%20'2'%5D,%20'inserted')%20%20//%20%5B1,2,'inserted',3%5D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20insertAt(document,%20path,%20value)%20%7B%0A%20%20%20%20%20%20const%20parentPath%20=%20path.slice(0,%20path.length%20-%201);%0A%20%20%20%20%20%20const%20index%20=%20path%5Bpath.length%20-%201%5D;%0A%20%20%20%20%20%20return%20updateIn(document,%20parentPath,%20items%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20if%20(!Array.isArray(items))%20%7B%0A%20%20%20%20%20%20%20%20%20%20throw%20new%20TypeError('Array%20expected%20at%20path%20'%20+%20JSON.stringify(parentPath));%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20const%20updatedItems%20=%20shallowClone(items);%0A%20%20%20%20%20%20%20%20updatedItems.splice(parseInt(index),%200,%20value);%0A%20%20%20%20%20%20%20%20return%20updatedItems;%0A%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Test%20whether%20a%20path%20exists%20in%20a%20JSON%20object%0A%20%20%20%20%20*%20@return%20Returns%20true%20if%20the%20path%20exists,%20else%20returns%20false%0A%20%20%20%20%20*/%0A%20%20%20%20function%20existsIn(document,%20path)%20%7B%0A%20%20%20%20%20%20if%20(document%20===%20undefined)%20%7B%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20if%20(path.length%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20if%20(document%20===%20null)%20%7B%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20return%20existsIn(document%5Bpath%5B0%5D%5D,%20path.slice(1));%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Parse%20a%20JSON%20Pointer%0A%20%20%20%20%20*/%0A%20%20%20%20function%20parseJSONPointer(pointer)%20%7B%0A%20%20%20%20%20%20const%20path%20=%20pointer.split('/');%0A%20%20%20%20%20%20path.shift();%20//%20remove%20the%20first%20empty%20entry%0A%0A%20%20%20%20%20%20return%20path.map(p%20=%3E%20p.replace(/~1/g,%20'/').replace(/~0/g,%20'~'));%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Compile%20a%20JSON%20Pointer%0A%20%20%20%20%20*/%0A%20%20%20%20function%20compileJSONPointer(path)%20%7B%0A%20%20%20%20%20%20return%20path.map(compileJSONPointerProp).join('');%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Compile%20a%20single%20path%20property%20from%20a%20JSONPath%0A%20%20%20%20%20*/%0A%20%20%20%20function%20compileJSONPointerProp(pathProp)%20%7B%0A%20%20%20%20%20%20return%20'/'%20+%20String(pathProp).replace(/~/g,%20'~0').replace(/%5C//g,%20'~1');%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Apply%20a%20patch%20to%20a%20JSON%20object%0A%20%20%20%20%20*%20The%20original%20JSON%20object%20will%20not%20be%20changed,%0A%20%20%20%20%20*%20instead,%20the%20patch%20is%20applied%20in%20an%20immutable%20way%0A%20%20%20%20%20*/%0A%20%20%20%20function%20immutableJSONPatch(document,%20operations,%20options)%20%7B%0A%20%20%20%20%20%20let%20updatedDocument%20=%20document;%0A%20%20%20%20%20%20for%20(let%20i%20=%200;%20i%20%3C%20operations.length;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20validateJSONPatchOperation(operations%5Bi%5D);%0A%20%20%20%20%20%20%20%20let%20operation%20=%20operations%5Bi%5D;%0A%20%20%20%20%20%20%20%20const%20path%20=%20parsePath(updatedDocument,%20operation.path);%0A%20%20%20%20%20%20%20%20if%20(operation.op%20===%20'add')%20%7B%0A%20%20%20%20%20%20%20%20%20%20updatedDocument%20=%20add(updatedDocument,%20path,%20operation.value);%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(operation.op%20===%20'remove')%20%7B%0A%20%20%20%20%20%20%20%20%20%20updatedDocument%20=%20remove(updatedDocument,%20path);%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(operation.op%20===%20'replace')%20%7B%0A%20%20%20%20%20%20%20%20%20%20updatedDocument%20=%20replace(updatedDocument,%20path,%20operation.value);%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(operation.op%20===%20'copy')%20%7B%0A%20%20%20%20%20%20%20%20%20%20updatedDocument%20=%20copy(updatedDocument,%20path,%20parseFrom(operation.from));%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(operation.op%20===%20'move')%20%7B%0A%20%20%20%20%20%20%20%20%20%20updatedDocument%20=%20move(updatedDocument,%20path,%20parseFrom(operation.from));%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(operation.op%20===%20'test')%20%7B%0A%20%20%20%20%20%20%20%20%20%20test(updatedDocument,%20path,%20operation.value);%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('Unknown%20JSONPatch%20operation%20'%20+%20JSON.stringify(operation));%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20return%20updatedDocument;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Replace%20an%20existing%20item%0A%20%20%20%20%20*/%0A%20%20%20%20function%20replace(document,%20path,%20value)%20%7B%0A%20%20%20%20%20%20return%20setIn(document,%20path,%20value);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Remove%20an%20item%20or%20property%0A%20%20%20%20%20*/%0A%20%20%20%20function%20remove(document,%20path)%20%7B%0A%20%20%20%20%20%20return%20deleteIn(document,%20path);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Add%20an%20item%20or%20property%0A%20%20%20%20%20*/%0A%20%20%20%20function%20add(document,%20path,%20value)%20%7B%0A%20%20%20%20%20%20if%20(isArrayItem(document,%20path))%20%7B%0A%20%20%20%20%20%20%20%20return%20insertAt(document,%20path,%20value);%0A%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20return%20setIn(document,%20path,%20value);%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Copy%20a%20value%0A%20%20%20%20%20*/%0A%20%20%20%20function%20copy(document,%20path,%20from)%20%7B%0A%20%20%20%20%20%20const%20value%20=%20getIn(document,%20from);%0A%20%20%20%20%20%20if%20(isArrayItem(document,%20path))%20%7B%0A%20%20%20%20%20%20%20%20return%20insertAt(document,%20path,%20value);%0A%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20const%20value%20=%20getIn(document,%20from);%0A%20%20%20%20%20%20%20%20return%20setIn(document,%20path,%20value);%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Move%20a%20value%0A%20%20%20%20%20*/%0A%20%20%20%20function%20move(document,%20path,%20from)%20%7B%0A%20%20%20%20%20%20const%20value%20=%20getIn(document,%20from);%0A%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20const%20removedJson%20=%20deleteIn(document,%20from);%0A%20%20%20%20%20%20return%20isArrayItem(removedJson,%20path)%20?%20insertAt(removedJson,%20path,%20value)%20:%20setIn(removedJson,%20path,%20value);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Test%20whether%20the%20data%20contains%20the%20provided%20value%20at%20the%20specified%20path.%0A%20%20%20%20%20*%20Throws%20an%20error%20when%20the%20test%20fails%0A%20%20%20%20%20*/%0A%20%20%20%20function%20test(document,%20path,%20value)%20%7B%0A%20%20%20%20%20%20if%20(value%20===%20undefined)%20%7B%0A%20%20%20%20%20%20%20%20throw%20new%20Error(%60Test%20failed:%20no%20value%20provided%20(path:%20%22$%7BcompileJSONPointer(path)%7D%22)%60);%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20if%20(!existsIn(document,%20path))%20%7B%0A%20%20%20%20%20%20%20%20throw%20new%20Error(%60Test%20failed:%20path%20not%20found%20(path:%20%22$%7BcompileJSONPointer(path)%7D%22)%60);%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20const%20actualValue%20=%20getIn(document,%20path);%0A%20%20%20%20%20%20if%20(!isEqual(actualValue,%20value))%20%7B%0A%20%20%20%20%20%20%20%20throw%20new%20Error(%60Test%20failed,%20value%20differs%20(path:%20%22$%7BcompileJSONPointer(path)%7D%22)%60);%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20function%20isArrayItem(document,%20path)%20%7B%0A%20%20%20%20%20%20if%20(path.length%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20const%20parent%20=%20getIn(document,%20initial(path));%0A%20%20%20%20%20%20return%20Array.isArray(parent);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Resolve%20the%20path%20index%20of%20an%20array,%20resolves%20indexes%20'-'%0A%20%20%20%20%20*%20@returns%20Returns%20the%20resolved%20path%0A%20%20%20%20%20*/%0A%20%20%20%20function%20resolvePathIndex(document,%20path)%20%7B%0A%20%20%20%20%20%20if%20(last(path)%20!==%20'-')%20%7B%0A%20%20%20%20%20%20%20%20return%20path;%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20const%20parentPath%20=%20initial(path);%0A%20%20%20%20%20%20const%20parent%20=%20getIn(document,%20parentPath);%0A%0A%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/ban-ts-comment%0A%20%20%20%20%20%20//%20@ts-ignore%0A%20%20%20%20%20%20return%20parentPath.concat(parent.length);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Validate%20a%20JSONPatch%20operation.%0A%20%20%20%20%20*%20Throws%20an%20error%20when%20there%20is%20an%20issue%0A%20%20%20%20%20*/%0A%20%20%20%20function%20validateJSONPatchOperation(operation)%20%7B%0A%20%20%20%20%20%20//%20TODO:%20write%20unit%20tests%0A%20%20%20%20%20%20const%20ops%20=%20%5B'add',%20'remove',%20'replace',%20'copy',%20'move',%20'test'%5D;%0A%20%20%20%20%20%20if%20(!ops.includes(operation.op))%20%7B%0A%20%20%20%20%20%20%20%20throw%20new%20Error('Unknown%20JSONPatch%20op%20'%20+%20JSON.stringify(operation.op));%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20if%20(typeof%20operation.path%20!==%20'string')%20%7B%0A%20%20%20%20%20%20%20%20throw%20new%20Error('Required%20property%20%22path%22%20missing%20or%20not%20a%20string%20in%20operation%20'%20+%20JSON.stringify(operation));%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20if%20(operation.op%20===%20'copy'%20%7C%7C%20operation.op%20===%20'move')%20%7B%0A%20%20%20%20%20%20%20%20if%20(typeof%20operation.from%20!==%20'string')%20%7B%0A%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('Required%20property%20%22from%22%20missing%20or%20not%20a%20string%20in%20operation%20'%20+%20JSON.stringify(operation));%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20function%20parsePath(document,%20pointer)%20%7B%0A%20%20%20%20%20%20return%20resolvePathIndex(document,%20parseJSONPointer(pointer));%0A%20%20%20%20%7D%0A%20%20%20%20function%20parseFrom(fromPointer)%20%7B%0A%20%20%20%20%20%20return%20parseJSONPointer(fromPointer);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/*%20global%20false,%20cloneInto,%20exportFunction%20*/%0A%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Like%20Object.defineProperty,%20but%20with%20support%20for%20Firefox's%20mozProxies.%0A%20%20%20%20%20*%20@param%20%7Bany%7D%20object%20-%20object%20whose%20property%20we%20are%20wrapping%20(most%20commonly%20a%20prototype,%20e.g.%20globalThis.BatteryManager.prototype)%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20propertyName%0A%20%20%20%20%20*%20@param%20%7Bimport('./wrapper-utils').StrictPropertyDescriptor%7D%20descriptor%20-%20requires%20all%20descriptor%20options%20to%20be%20defined%20because%20we%20can't%20validate%20correctness%20based%20on%20TS%20types%0A%20%20%20%20%20*/%0A%20%20%20%20function%20defineProperty(object,%20propertyName,%20descriptor)%20%7B%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20objectDefineProperty(object,%20propertyName,%20descriptor);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20return%20a%20proxy%20to%20%60newFn%60%20that%20fakes%20.toString()%20and%20.toString.toString()%20to%20resemble%20the%20%60origFn%60.%0A%20%20%20%20%20*%20WARNING:%20do%20NOT%20proxy%20toString%20multiple%20times,%20as%20it%20will%20not%20work%20as%20expected.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@param%20%7B*%7D%20newFn%0A%20%20%20%20%20*%20@param%20%7B*%7D%20origFn%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BmockValue%5D%20-%20when%20provided,%20.toString()%20will%20return%20this%20value%0A%20%20%20%20%20*/%0A%20%20%20%20function%20wrapToString(newFn,%20origFn,%20mockValue)%20%7B%0A%20%20%20%20%20%20%20%20if%20(typeof%20newFn%20!==%20'function'%20%7C%7C%20typeof%20origFn%20!==%20'function')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20newFn;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20new%20Proxy(newFn,%20%7B%20get:%20toStringGetTrap(origFn,%20mockValue)%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20generate%20a%20proxy%20handler%20trap%20that%20fakes%20.toString()%20and%20.toString.toString()%20to%20resemble%20the%20%60targetFn%60.%0A%20%20%20%20%20*%20Note%20that%20it%20should%20be%20used%20as%20the%20get()%20trap.%0A%20%20%20%20%20*%20@param%20%7B*%7D%20targetFn%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BmockValue%5D%20-%20when%20provided,%20.toString()%20will%20return%20this%20value%0A%20%20%20%20%20*%20@returns%20%7B%20(target:%20any,%20prop:%20string,%20receiver:%20any)%20=%3E%20any%20%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20toStringGetTrap(targetFn,%20mockValue)%20%7B%0A%20%20%20%20%20%20%20%20//%20We%20wrap%20two%20levels%20deep%20to%20handle%20toString.toString()%20calls%0A%20%20%20%20%20%20%20%20return%20function%20get(target,%20prop,%20receiver)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(prop%20===%20'toString')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20origToString%20=%20Reflect.get(targetFn,%20'toString',%20targetFn);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20toStringProxy%20=%20new%20Proxy(origToString,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20argumentsList)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20only%20mock%20toString()%20when%20called%20on%20the%20proxy%20itself.%20If%20the%20method%20is%20applied%20to%20some%20other%20object,%20it%20should%20behave%20as%20a%20normal%20toString()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(thisArg%20===%20receiver)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(mockValue)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20mockValue;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20Reflect.apply(target,%20targetFn,%20argumentsList);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20Reflect.apply(target,%20thisArg,%20argumentsList);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get(target,%20prop,%20receiver)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20handle%20toString.toString()%20result%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(prop%20===%20'toString')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20origToStringToString%20=%20Reflect.get(origToString,%20'toString',%20origToString);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20toStringToStringProxy%20=%20new%20Proxy(origToStringToString,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20argumentsList)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(thisArg%20===%20toStringProxy)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20Reflect.apply(target,%20origToString,%20argumentsList);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20Reflect.apply(target,%20thisArg,%20argumentsList);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20toStringToStringProxy;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20Reflect.get(target,%20prop,%20receiver);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20toStringProxy;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20Reflect.get(target,%20prop,%20receiver);%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Wrap%20a%20%60get%60/%60set%60%20or%20%60value%60%20property%20descriptor.%20Only%20for%20data%20properties.%20For%20methods,%20use%20wrapMethod().%20For%20constructors,%20use%20wrapConstructor().%0A%20%20%20%20%20*%20@param%20%7Bany%7D%20object%20-%20object%20whose%20property%20we%20are%20wrapping%20(most%20commonly%20a%20prototype,%20e.g.%20globalThis.Screen.prototype)%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20propertyName%0A%20%20%20%20%20*%20@param%20%7BPartial%3CPropertyDescriptor%3E%7D%20descriptor%0A%20%20%20%20%20*%20@param%20%7Btypeof%20Object.defineProperty%7D%20definePropertyFn%20-%20function%20to%20use%20for%20defining%20the%20property%0A%20%20%20%20%20*%20@returns%20%7BPropertyDescriptor%7Cundefined%7D%20original%20property%20descriptor,%20or%20undefined%20if%20it's%20not%20found%0A%20%20%20%20%20*/%0A%20%20%20%20function%20wrapProperty(object,%20propertyName,%20descriptor,%20definePropertyFn)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!object)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%20@type%20%7BStrictPropertyDescriptor%7D%20*/%0A%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20we%20check%20for%20undefined%20below%0A%20%20%20%20%20%20%20%20const%20origDescriptor%20=%20getOwnPropertyDescriptor(object,%20propertyName);%0A%20%20%20%20%20%20%20%20if%20(!origDescriptor)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20this%20happens%20if%20the%20property%20is%20not%20implemented%20in%20the%20browser%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20('value'%20in%20origDescriptor%20&&%20'value'%20in%20descriptor)%20%7C%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20('get'%20in%20origDescriptor%20&&%20'get'%20in%20descriptor)%20%7C%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20('set'%20in%20origDescriptor%20&&%20'set'%20in%20descriptor)%0A%20%20%20%20%20%20%20%20)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20definePropertyFn(object,%20propertyName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20...origDescriptor,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20...descriptor,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20origDescriptor;%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20if%20the%20property%20is%20defined%20with%20get/set%20it%20must%20be%20wrapped%20with%20a%20get/set.%20If%20it's%20defined%20with%20a%20%60value%60,%20it%20must%20be%20wrapped%20with%20a%20%60value%60%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error(%60Property%20descriptor%20for%20$%7BpropertyName%7D%20may%20only%20include%20the%20following%20keys:%20$%7BobjectKeys(origDescriptor)%7D%60);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Wrap%20a%20method%20descriptor.%20Only%20for%20function%20properties.%20For%20data%20properties,%20use%20wrapProperty().%20For%20constructors,%20use%20wrapConstructor().%0A%20%20%20%20%20*%20@param%20%7Bany%7D%20object%20-%20object%20whose%20property%20we%20are%20wrapping%20(most%20commonly%20a%20prototype,%20e.g.%20globalThis.Bluetooth.prototype)%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20propertyName%0A%20%20%20%20%20*%20@param%20%7B(originalFn,%20...args)%20=%3E%20any%20%7D%20wrapperFn%20-%20wrapper%20function%20receives%20the%20original%20function%20as%20the%20first%20argument%0A%20%20%20%20%20*%20@param%20%7BDefinePropertyFn%7D%20definePropertyFn%20-%20function%20to%20use%20for%20defining%20the%20property%0A%20%20%20%20%20*%20@returns%20%7BPropertyDescriptor%7Cundefined%7D%20original%20property%20descriptor,%20or%20undefined%20if%20it's%20not%20found%0A%20%20%20%20%20*/%0A%20%20%20%20function%20wrapMethod(object,%20propertyName,%20wrapperFn,%20definePropertyFn)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!object)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%20@type%20%7BStrictPropertyDescriptor%7D%20*/%0A%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20we%20check%20for%20undefined%20below%0A%20%20%20%20%20%20%20%20const%20origDescriptor%20=%20getOwnPropertyDescriptor(object,%20propertyName);%0A%20%20%20%20%20%20%20%20if%20(!origDescriptor)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20this%20happens%20if%20the%20property%20is%20not%20implemented%20in%20the%20browser%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20we%20check%20for%20undefined%20below%0A%20%20%20%20%20%20%20%20const%20origFn%20=%20origDescriptor.value;%0A%20%20%20%20%20%20%20%20if%20(!origFn%20%7C%7C%20typeof%20origFn%20!==%20'function')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20method%20properties%20are%20expected%20to%20be%20defined%20with%20a%20%60value%60%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error(%60Property%20$%7BpropertyName%7D%20does%20not%20look%20like%20a%20method%60);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20newFn%20=%20wrapToString(function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20wrapperFn.call(this,%20origFn,%20...arguments);%0A%20%20%20%20%20%20%20%20%7D,%20origFn);%0A%0A%20%20%20%20%20%20%20%20definePropertyFn(object,%20propertyName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20...origDescriptor,%0A%20%20%20%20%20%20%20%20%20%20%20%20value:%20newFn,%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20return%20origDescriptor;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@template%20%7Bkeyof%20typeof%20globalThis%7D%20StandardInterfaceName%0A%20%20%20%20%20*%20@param%20%7BStandardInterfaceName%7D%20interfaceName%20-%20the%20name%20of%20the%20interface%20to%20shim%20(must%20be%20some%20known%20standard%20API,%20e.g.%20'MediaSession')%0A%20%20%20%20%20*%20@param%20%7Btypeof%20globalThis%5BStandardInterfaceName%5D%7D%20ImplClass%20-%20the%20class%20to%20use%20as%20the%20shim%20implementation%0A%20%20%20%20%20*%20@param%20%7BDefineInterfaceOptions%7D%20options%20-%20options%20for%20defining%20the%20interface%0A%20%20%20%20%20*%20@param%20%7BDefinePropertyFn%7D%20definePropertyFn%20-%20function%20to%20use%20for%20defining%20the%20property%0A%20%20%20%20%20*/%0A%20%20%20%20function%20shimInterface(interfaceName,%20ImplClass,%20options,%20definePropertyFn)%20%7B%0A%0A%20%20%20%20%20%20%20%20/**%20@type%20%7BDefineInterfaceOptions%7D%20*/%0A%20%20%20%20%20%20%20%20const%20defaultOptions%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20allowConstructorCall:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20disallowConstructor:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20constructorErrorMessage:%20'Illegal%20constructor',%0A%20%20%20%20%20%20%20%20%20%20%20%20wrapToString:%20true,%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20const%20fullOptions%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20interfaceDescriptorOptions:%20%7B%20writable:%20true,%20enumerable:%20false,%20configurable:%20true,%20value:%20ImplClass%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20...defaultOptions,%0A%20%20%20%20%20%20%20%20%20%20%20%20...options,%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20//%20In%20some%20cases%20we%20can%20get%20away%20without%20a%20full%20proxy,%20but%20in%20many%20cases%20below%20we%20need%20it.%0A%20%20%20%20%20%20%20%20//%20For%20example,%20we%20can't%20redefine%20%60prototype%60%20property%20on%20ES6%20classes.%0A%20%20%20%20%20%20%20%20//%20Se%20we%20just%20always%20wrap%20the%20class%20to%20make%20the%20code%20more%20maintaibnable%0A%0A%20%20%20%20%20%20%20%20/**%20@type%20%7BProxyHandler%3CFunction%3E%7D%20*/%0A%20%20%20%20%20%20%20%20const%20proxyHandler%20=%20%7B%7D;%0A%0A%20%20%20%20%20%20%20%20//%20handle%20the%20case%20where%20the%20constructor%20is%20called%20without%20new%0A%20%20%20%20%20%20%20%20if%20(fullOptions.allowConstructorCall)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20make%20the%20constructor%20function%20callable%20without%20new%0A%20%20%20%20%20%20%20%20%20%20%20%20proxyHandler.apply%20=%20function%20(target,%20thisArg,%20argumentsList)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20Reflect.construct(target,%20argumentsList,%20target);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20make%20the%20constructor%20function%20throw%20when%20called%20without%20new%0A%20%20%20%20%20%20%20%20if%20(fullOptions.disallowConstructor)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20proxyHandler.construct%20=%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20TypeError(fullOptions.constructorErrorMessage);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if%20(fullOptions.wrapToString)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20mask%20toString()%20on%20class%20methods.%20%60ImplClass.prototype%60%20is%20non-configurable:%20we%20can't%20override%20or%20proxy%20it,%20so%20we%20have%20to%20wrap%20each%20method%20individually%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20%5Bprop,%20descriptor%5D%20of%20objectEntries(getOwnPropertyDescriptors(ImplClass.prototype)))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(prop%20!==%20'constructor'%20&&%20descriptor.writable%20&&%20typeof%20descriptor.value%20===%20'function')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ImplClass.prototype%5Bprop%5D%20=%20new%20Proxy(descriptor.value,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20toStringGetTrap(descriptor.value,%20%60function%20$%7Bprop%7D()%20%7B%20%5Bnative%20code%5D%20%7D%60),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20wrap%20toString%20on%20the%20constructor%20function%20itself%0A%20%20%20%20%20%20%20%20%20%20%20%20Object.assign(proxyHandler,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20toStringGetTrap(ImplClass,%20%60function%20$%7BinterfaceName%7D()%20%7B%20%5Bnative%20code%5D%20%7D%60),%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Note%20that%20instanceof%20should%20still%20work,%20since%20the%20%60.prototype%60%20object%20is%20proxied%20too:%0A%20%20%20%20%20%20%20%20//%20Interface()%20instanceof%20Interface%20===%20true%0A%20%20%20%20%20%20%20%20//%20ImplClass()%20instanceof%20Interface%20===%20true%0A%20%20%20%20%20%20%20%20const%20Interface%20=%20new%20Proxy(ImplClass,%20proxyHandler);%0A%0A%20%20%20%20%20%20%20%20//%20Make%20sure%20that%20Interface().constructor%20===%20Interface%20(not%20ImplClass)%0A%20%20%20%20%20%20%20%20if%20(ImplClass.prototype?.constructor%20===%20ImplClass)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7BStrictDataDescriptor%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20As%20long%20as%20ImplClass%20is%20a%20normal%20class,%20it%20should%20have%20the%20prototype%20property%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20descriptor%20=%20getOwnPropertyDescriptor(ImplClass.prototype,%20'constructor');%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(descriptor.writable)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ImplClass.prototype.constructor%20=%20Interface;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20mock%20the%20name%20property%0A%20%20%20%20%20%20%20%20definePropertyFn(ImplClass,%20'name',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20value:%20interfaceName,%0A%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20writable:%20false,%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20//%20interfaces%20are%20exposed%20directly%20on%20the%20global%20object,%20not%20on%20its%20prototype%0A%20%20%20%20%20%20%20%20definePropertyFn(globalThis,%20interfaceName,%20%7B%20...fullOptions.interfaceDescriptorOptions,%20value:%20Interface%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Define%20a%20missing%20standard%20property%20on%20a%20global%20(prototype)%20object.%20Only%20for%20data%20properties.%0A%20%20%20%20%20*%20For%20constructors,%20use%20shimInterface().%0A%20%20%20%20%20*%20Most%20of%20the%20time,%20you'd%20want%20to%20call%20shimInterface()%20first%20to%20shim%20the%20class%20itself%20(MediaSession),%20and%20then%20shimProperty()%20for%20the%20global%20singleton%20instance%20(Navigator.prototype.mediaSession).%0A%20%20%20%20%20*%20@template%20Base%0A%20%20%20%20%20*%20@template%20%7Bkeyof%20Base%20&%20string%7D%20K%0A%20%20%20%20%20*%20@param%20%7BBase%7D%20baseObject%20-%20object%20whose%20property%20we%20are%20shimming%20(most%20commonly%20a%20prototype%20object,%20e.g.%20Navigator.prototype)%0A%20%20%20%20%20*%20@param%20%7BK%7D%20propertyName%20-%20name%20of%20the%20property%20to%20shim%20(e.g.%20'mediaSession')%0A%20%20%20%20%20*%20@param%20%7BBase%5BK%5D%7D%20implInstance%20-%20instance%20to%20use%20as%20the%20shim%20(e.g.%20new%20MyMediaSession())%0A%20%20%20%20%20*%20@param%20%7Bboolean%7D%20readOnly%20-%20whether%20the%20property%20should%20be%20read-only%0A%20%20%20%20%20*%20@param%20%7BDefinePropertyFn%7D%20definePropertyFn%20-%20function%20to%20use%20for%20defining%20the%20property%0A%20%20%20%20%20*/%0A%20%20%20%20function%20shimProperty(baseObject,%20propertyName,%20implInstance,%20readOnly,%20definePropertyFn)%20%7B%0A%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20implInstance%20is%20a%20class%20instance%0A%20%20%20%20%20%20%20%20const%20ImplClass%20=%20implInstance.constructor;%0A%0A%20%20%20%20%20%20%20%20//%20mask%20toString()%20and%20toString.toString()%20on%20the%20instance%0A%20%20%20%20%20%20%20%20const%20proxiedInstance%20=%20new%20Proxy(implInstance,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20get:%20toStringGetTrap(implInstance,%20%60%5Bobject%20$%7BImplClass.name%7D%5D%60),%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20/**%20@type%20%7BStrictPropertyDescriptor%7D%20*/%0A%20%20%20%20%20%20%20%20let%20descriptor;%0A%0A%20%20%20%20%20%20%20%20//%20Note%20that%20we%20only%20cover%20most%20common%20cases:%20a%20getter%20for%20%22readonly%22%20properties,%20and%20a%20value%20descriptor%20for%20writable%20properties.%0A%20%20%20%20%20%20%20%20//%20But%20there%20could%20be%20other%20cases,%20e.g.%20a%20property%20with%20both%20a%20getter%20and%20a%20setter.%20These%20could%20be%20defined%20with%20a%20raw%20defineProperty()%20call.%0A%20%20%20%20%20%20%20%20//%20Important:%20make%20sure%20to%20cover%20each%20new%20shim%20with%20a%20test%20that%20verifies%20that%20all%20descriptors%20match%20the%20standard%20API.%0A%20%20%20%20%20%20%20%20if%20(readOnly)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20getter%20=%20function%20get()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20proxiedInstance;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20proxiedGetter%20=%20new%20Proxy(getter,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20toStringGetTrap(getter,%20%60function%20get%20$%7BpropertyName%7D()%20%7B%20%5Bnative%20code%5D%20%7D%60),%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20descriptor%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20proxiedGetter,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20descriptor%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20writable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value:%20proxiedInstance,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20definePropertyFn(baseObject,%20propertyName,%20descriptor);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@callback%20DefinePropertyFn%0A%20%20%20%20%20*%20@param%20%7Bobject%7D%20baseObj%0A%20%20%20%20%20*%20@param%20%7BPropertyKey%7D%20propertyName%0A%20%20%20%20%20*%20@param%20%7BStrictPropertyDescriptor%7D%20descriptor%0A%20%20%20%20%20*%20@returns%20%7Bobject%7D%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7BObject%7D%20BaseStrictPropertyDescriptor%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20configurable%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20enumerable%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7BBaseStrictPropertyDescriptor%20&%20%7B%20value:%20any;%20writable:%20boolean%20%7D%7D%20StrictDataDescriptor%0A%20%20%20%20%20*%20@typedef%20%7BBaseStrictPropertyDescriptor%20&%20%7B%20get:%20()%20=%3E%20any;%20set:%20(v:%20any)%20=%3E%20void%20%7D%7D%20StrictAccessorDescriptor%0A%20%20%20%20%20*%20@typedef%20%7BBaseStrictPropertyDescriptor%20&%20%7B%20get:%20()%20=%3E%20any%20%7D%7D%20StrictGetDescriptor%0A%20%20%20%20%20*%20@typedef%20%7BBaseStrictPropertyDescriptor%20&%20%7B%20set:%20(v:%20any)%20=%3E%20void%20%7D%7D%20StrictSetDescriptor%0A%20%20%20%20%20*%20@typedef%20%7BStrictDataDescriptor%20%7C%20StrictAccessorDescriptor%20%7C%20StrictGetDescriptor%20%7C%20StrictSetDescriptor%7D%20StrictPropertyDescriptor%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7BObject%7D%20BaseDefineInterfaceOptions%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20%5BconstructorErrorMessage%5D%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20wrapToString%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7B%7B%20allowConstructorCall:%20true;%20disallowConstructor:%20false%20%7D%7D%20DefineInterfaceOptionsWithAllowConstructorCallMixin%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7B%7B%20allowConstructorCall:%20false;%20disallowConstructor:%20true%20%7D%7D%20DefineInterfaceOptionsWithDisallowConstructorMixin%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7B%7B%20allowConstructorCall:%20false;%20disallowConstructor:%20false%20%7D%7D%20DefineInterfaceOptionsDefaultMixin%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7BBaseDefineInterfaceOptions%20&%20(DefineInterfaceOptionsWithAllowConstructorCallMixin%20%7C%20DefineInterfaceOptionsWithDisallowConstructorMixin%20%7C%20DefineInterfaceOptionsDefaultMixin)%7D%20DefineInterfaceOptions%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20A%20wrapper%20for%20messaging%20on%20Windows.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20This%20requires%203%20methods%20to%20be%20available,%20see%20%7B@link%20WindowsMessagingConfig%7D%20for%20details%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@document%20messaging/lib/examples/windows.example.js%0A%20%20%20%20%20*%0A%20%20%20%20%20*/%0A%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/no-unused-vars%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20An%20implementation%20of%20%7B@link%20MessagingTransport%7D%20for%20Windows%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20All%20messages%20go%20through%20%60window.chrome.webview%60%20APIs%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@implements%20%7BMessagingTransport%7D%0A%20%20%20%20%20*/%0A%20%20%20%20class%20WindowsMessagingTransport%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BWindowsMessagingConfig%7D%20config%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../index.js').MessagingContext%7D%20messagingContext%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(config,%20messagingContext)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messagingContext%20=%20messagingContext;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.config%20=%20config;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.globals%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20window,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20JSONparse:%20window.JSON.parse,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20JSONstringify:%20window.JSON.stringify,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Promise:%20window.Promise,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Error:%20window.Error,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20String:%20window.String,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20%5BmethodName,%20fn%5D%20of%20Object.entries(this.config.methods))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20fn%20!==%20'function')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('cannot%20create%20WindowsMessagingTransport,%20missing%20the%20method:%20'%20+%20methodName);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../index.js').NotificationMessage%7D%20msg%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20notify(msg)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20data%20=%20this.globals.JSONparse(this.globals.JSONstringify(msg.params%20%7C%7C%20%7B%7D));%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20notification%20=%20WindowsNotification.fromNotification(msg,%20data);%0A%20%20%20%20%20%20%20%20%20%20%20%20this.config.methods.postMessage(notification);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../index.js').RequestMessage%7D%20msg%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B%7Bsignal?:%20AbortSignal%7D%7D%20opts%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7BPromise%3Cany%3E%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20request(msg,%20opts%20=%20%7B%7D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20convert%20the%20message%20to%20window-specific%20naming%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20data%20=%20this.globals.JSONparse(this.globals.JSONstringify(msg.params%20%7C%7C%20%7B%7D));%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20outgoing%20=%20WindowsRequestMessage.fromRequest(msg,%20data);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20send%20the%20message%0A%20%20%20%20%20%20%20%20%20%20%20%20this.config.methods.postMessage(outgoing);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20compare%20incoming%20messages%20against%20the%20%60msg.id%60%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20comparator%20=%20(eventData)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20eventData.featureName%20===%20msg.featureName%20&&%20eventData.context%20===%20msg.context%20&&%20eventData.id%20===%20msg.id;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20data%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7Bdata%20is%20import('../index.js').MessageResponse%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20isMessageResponse(data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('result'%20in%20data)%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('error'%20in%20data)%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20now%20wait%20for%20a%20matching%20message%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20this.globals.Promise((resolve,%20reject)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._subscribe(comparator,%20opts,%20(value,%20unsubscribe)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unsubscribe();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isMessageResponse(value))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.warn('unknown%20response%20type',%20value);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20reject(new%20this.globals.Error('unknown%20response'));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(value.result)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20resolve(value.result);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20message%20=%20this.globals.String(value.error?.message%20%7C%7C%20'unknown%20error');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20reject(new%20this.globals.Error(message));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20reject(e);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../index.js').Subscription%7D%20msg%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(value:%20unknown%20%7C%20undefined)%20=%3E%20void%7D%20callback%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20subscribe(msg,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20compare%20incoming%20messages%20against%20the%20%60msg.subscriptionName%60%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20comparator%20=%20(eventData)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20eventData.featureName%20===%20msg.featureName%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20eventData.context%20===%20msg.context%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20eventData.subscriptionName%20===%20msg.subscriptionName%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20only%20forward%20the%20'params'%20from%20a%20SubscriptionEvent%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cb%20=%20(eventData)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20callback(eventData.params);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20now%20listen%20for%20matching%20incoming%20messages.%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this._subscribe(comparator,%20%7B%7D,%20cb);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@typedef%20%7Bimport('../index.js').MessageResponse%20%7C%20import('../index.js').SubscriptionEvent%7D%20Incoming%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(eventData:%20any)%20=%3E%20boolean%7D%20comparator%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B%7Bsignal?:%20AbortSignal%7D%7D%20options%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(value:%20Incoming,%20unsubscribe:%20(()=%3Evoid))%20=%3E%20void%7D%20callback%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_subscribe(comparator,%20options,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20if%20already%20aborted,%20reject%20immediately%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(options?.signal?.aborted)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20DOMException('Aborted',%20'AbortError');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7B(()=%3Evoid)%20%7C%20undefined%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20prefer-const%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20teardown;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BMessageEvent%7D%20event%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20idHandler%20=%20(event)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.messagingContext.env%20===%20'production')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(event.origin%20!==%20null%20&&%20event.origin%20!==%20undefined)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.warn('ignoring%20because%20evt.origin%20is%20not%20%60null%60%20or%20%60undefined%60');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!event.data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.warn('data%20absent%20from%20message');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(comparator(event.data))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!teardown)%20throw%20new%20Error('unreachable');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20callback(event.data,%20teardown);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20what%20to%20do%20if%20this%20promise%20is%20aborted%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20abortHandler%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20teardown?.();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20DOMException('Aborted',%20'AbortError');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20console.log('DEBUG:%20handler%20setup',%20%7B%20config,%20comparator%20%7D)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.config.methods.addEventListener('message',%20idHandler);%0A%20%20%20%20%20%20%20%20%20%20%20%20options?.signal?.addEventListener('abort',%20abortHandler);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20teardown%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20console.log('DEBUG:%20handler%20teardown',%20%7B%20config,%20comparator%20%7D)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.config.methods.removeEventListener('message',%20idHandler);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20options?.signal?.removeEventListener('abort',%20abortHandler);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20teardown?.();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20To%20construct%20this%20configuration%20object,%20you%20need%20access%20to%203%20methods%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20-%20%60postMessage%60%0A%20%20%20%20%20*%20-%20%60addEventListener%60%0A%20%20%20%20%20*%20-%20%60removeEventListener%60%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20These%20would%20normally%20be%20available%20on%20Windows%20via%20the%20following:%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20-%20%60window.chrome.webview.postMessage%60%0A%20%20%20%20%20*%20-%20%60window.chrome.webview.addEventListener%60%0A%20%20%20%20%20*%20-%20%60window.chrome.webview.removeEventListener%60%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20Depending%20on%20where%20the%20script%20is%20running,%20we%20may%20want%20to%20restrict%20access%20to%20those%20globals.%20On%20the%20native%0A%20%20%20%20%20*%20side%20those%20handlers%20%60window.chrome.webview%60%20handlers%20might%20be%20deleted%20and%20replaces%20with%20in-scope%20variables,%20such%20as:%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%5BExample%5D(./examples/windows.example.js)%0A%20%20%20%20%20*%0A%20%20%20%20%20*/%0A%20%20%20%20class%20WindowsMessagingConfig%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BWindowsInteropMethods%7D%20params.methods%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20methods%20required%20for%20communication%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.methods%20=%20params.methods;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7B'windows'%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.platform%20=%20'windows';%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20This%20data%20type%20represents%20a%20message%20sent%20to%20the%20Windows%0A%20%20%20%20%20*%20platform%20via%20%60window.chrome.webview.postMessage%60.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20**NOTE**:%20This%20is%20sent%20when%20a%20response%20is%20*not*%20expected%0A%20%20%20%20%20*/%0A%20%20%20%20class%20WindowsNotification%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.Feature%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.SubFeatureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.Name%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bparams.Data%5D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Alias%20for:%20%7B@link%20NotificationMessage.context%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.Feature%20=%20params.Feature;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Alias%20for:%20%7B@link%20NotificationMessage.featureName%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.SubFeatureName%20=%20params.SubFeatureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Alias%20for:%20%7B@link%20NotificationMessage.method%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.Name%20=%20params.Name;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Alias%20for:%20%7B@link%20NotificationMessage.params%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.Data%20=%20params.Data;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Helper%20to%20convert%20a%20%7B@link%20NotificationMessage%7D%20to%20a%20format%20that%20Windows%20can%20support%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BNotificationMessage%7D%20notification%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BWindowsNotification%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20fromNotification(notification,%20data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7BWindowsNotification%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20output%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Data:%20data,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Feature:%20notification.context,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20SubFeatureName:%20notification.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Name:%20notification.method,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20output;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20This%20data%20type%20represents%20a%20message%20sent%20to%20the%20Windows%0A%20%20%20%20%20*%20platform%20via%20%60window.chrome.webview.postMessage%60%20when%20it%0A%20%20%20%20%20*%20expects%20a%20response%0A%20%20%20%20%20*/%0A%20%20%20%20class%20WindowsRequestMessage%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.Feature%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.SubFeatureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.Name%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bparams.Data%5D%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5Bparams.Id%5D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.Feature%20=%20params.Feature;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.SubFeatureName%20=%20params.SubFeatureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.Name%20=%20params.Name;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.Data%20=%20params.Data;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.Id%20=%20params.Id;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Helper%20to%20convert%20a%20%7B@link%20RequestMessage%7D%20to%20a%20format%20that%20Windows%20can%20support%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRequestMessage%7D%20msg%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20data%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BWindowsRequestMessage%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20fromRequest(msg,%20data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7BWindowsRequestMessage%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20output%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Data:%20data,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Feature:%20msg.context,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20SubFeatureName:%20msg.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Name:%20msg.method,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Id:%20msg.id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20output;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20These%20are%20all%20the%20shared%20data%20types%20used%20throughout.%20Transports%20receive%20these%20types%20and%0A%20%20%20%20%20*%20can%20choose%20how%20to%20deliver%20the%20message%20to%20their%20respective%20native%20platforms.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20-%20Notifications%20via%20%7B@link%20NotificationMessage%7D%0A%20%20%20%20%20*%20-%20Request%20-%3E%20Response%20via%20%7B@link%20RequestMessage%7D%20and%20%7B@link%20MessageResponse%7D%0A%20%20%20%20%20*%20-%20Subscriptions%20via%20%7B@link%20Subscription%7D%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20Note:%20For%20backwards%20compatibility,%20some%20platforms%20may%20alter%20the%20data%20shape%20within%20the%20transport.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@module%20Messaging%20Schema%0A%20%20%20%20%20*%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20This%20is%20the%20format%20of%20an%20outgoing%20message.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20-%20See%20%7B@link%20MessageResponse%7D%20for%20what's%20expected%20in%20a%20response%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20**NOTE**:%0A%20%20%20%20%20*%20-%20Windows%20will%20alter%20this%20before%20it's%20sent,%20see:%20%7B@link%20Messaging.WindowsRequestMessage%7D%0A%20%20%20%20%20*/%0A%20%20%20%20class%20RequestMessage%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.context%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.method%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.id%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bparams.params%5D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20global%20context%20for%20this%20message.%20For%20example,%20something%20like%20%60contentScopeScripts%60%20or%20%60specialPages%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7Bstring%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.context%20=%20params.context;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20name%20of%20the%20sub-feature,%20such%20as%20%60duckPlayer%60%20or%20%60clickToLoad%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7Bstring%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20name%20of%20the%20handler%20to%20be%20executed%20on%20the%20native%20side%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.method%20=%20params.method;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20%60id%60%20that%20native%20sides%20can%20use%20when%20sending%20back%20a%20response%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.id%20=%20params.id;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Optional%20data%20payload%20-%20must%20be%20a%20plain%20key/value%20object%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.params%20=%20params.params;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20**NOTE**:%0A%20%20%20%20%20*%20-%20Windows%20will%20alter%20this%20before%20it's%20sent,%20see:%20%7B@link%20Messaging.WindowsNotification%7D%0A%20%20%20%20%20*/%0A%20%20%20%20class%20NotificationMessage%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.context%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.method%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bparams.params%5D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20global%20context%20for%20this%20message.%20For%20example,%20something%20like%20%60contentScopeScripts%60%20or%20%60specialPages%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.context%20=%20params.context;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20name%20of%20the%20sub-feature,%20such%20as%20%60duckPlayer%60%20or%20%60clickToLoad%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20name%20of%20the%20handler%20to%20be%20executed%20on%20the%20native%20side%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.method%20=%20params.method;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20An%20optional%20payload%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.params%20=%20params.params;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20Subscription%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.context%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.subscriptionName%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.context%20=%20params.context;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.subscriptionName%20=%20params.subscriptionName;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7BRequestMessage%7D%20request%0A%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20data%0A%20%20%20%20%20*%20@return%20%7Bdata%20is%20MessageResponse%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isResponseFor(request,%20data)%20%7B%0A%20%20%20%20%20%20%20%20if%20('result'%20in%20data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20data.featureName%20===%20request.featureName%20&&%20data.context%20===%20request.context%20&&%20data.id%20===%20request.id;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20('error'%20in%20data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20('message'%20in%20data.error)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7BSubscription%7D%20sub%0A%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20data%0A%20%20%20%20%20*%20@return%20%7Bdata%20is%20SubscriptionEvent%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isSubscriptionEventFor(sub,%20data)%20%7B%0A%20%20%20%20%20%20%20%20if%20('subscriptionName'%20in%20data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20data.featureName%20===%20sub.featureName%20&&%20data.context%20===%20sub.context%20&&%20data.subscriptionName%20===%20sub.subscriptionName;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20A%20wrapper%20for%20messaging%20on%20WebKit%20platforms.%20It%20supports%20modern%20WebKit%20messageHandlers%0A%20%20%20%20%20*%20along%20with%20encryption%20for%20older%20versions%20(like%20macOS%20Catalina)%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20Note:%20If%20you%20wish%20to%20support%20Catalina%20then%20you'll%20need%20to%20implement%20the%20native%0A%20%20%20%20%20*%20part%20of%20the%20message%20handling,%20see%20%7B@link%20WebkitMessagingTransport%7D%20for%20details.%0A%20%20%20%20%20*/%0A%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/no-unused-vars%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@example%0A%20%20%20%20%20*%20On%20macOS%2011+,%20this%20will%20just%20call%20through%20to%20%60window.webkit.messageHandlers.x.postMessage%60%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20Eg:%20for%20a%20%60foo%60%20message%20defined%20in%20Swift%20that%20accepted%20the%20payload%20%60%7B%22bar%22:%20%22baz%22%7D%60,%20the%20following%0A%20%20%20%20%20*%20would%20occur:%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%60%60%60js%0A%20%20%20%20%20*%20const%20json%20=%20await%20window.webkit.messageHandlers.foo.postMessage(%7B%20bar:%20%22baz%22%20%7D);%0A%20%20%20%20%20*%20const%20response%20=%20JSON.parse(json)%0A%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@example%0A%20%20%20%20%20*%20On%20macOS%2010%20however,%20the%20process%20is%20a%20little%20more%20involved.%20A%20method%20will%20be%20appended%20to%20%60window%60%0A%20%20%20%20%20*%20that%20allows%20the%20response%20to%20be%20delivered%20there%20instead.%20It's%20not%20exactly%20this,%20but%20you%20can%20visualize%20the%20flow%0A%20%20%20%20%20*%20as%20being%20something%20along%20the%20lines%20of:%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%60%60%60js%0A%20%20%20%20%20*%20//%20add%20the%20window%20method%0A%20%20%20%20%20*%20window%5B%22_0123456%22%5D%20=%20(response)%20=%3E%20%7B%0A%20%20%20%20%20*%20%20%20%20//%20decrypt%20%60response%60%20and%20deliver%20the%20result%20to%20the%20caller%20here%0A%20%20%20%20%20*%20%20%20%20//%20then%20remove%20the%20temporary%20method%0A%20%20%20%20%20*%20%20%20%20delete%20window%5B'_0123456'%5D%0A%20%20%20%20%20*%20%7D;%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20//%20send%20the%20data%20+%20%60messageHanding%60%20values%0A%20%20%20%20%20*%20window.webkit.messageHandlers.foo.postMessage(%7B%0A%20%20%20%20%20*%20%20%20bar:%20%22baz%22,%0A%20%20%20%20%20*%20%20%20messagingHandling:%20%7B%0A%20%20%20%20%20*%20%20%20%20%20methodName:%20%22_0123456%22,%0A%20%20%20%20%20*%20%20%20%20%20secret:%20%22super-secret%22,%0A%20%20%20%20%20*%20%20%20%20%20key:%20%5B1,%202,%2045,%202%5D,%0A%20%20%20%20%20*%20%20%20%20%20iv:%20%5B34,%204,%2043%5D,%0A%20%20%20%20%20*%20%20%20%7D%0A%20%20%20%20%20*%20%7D);%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20//%20later%20in%20swift,%20the%20following%20JavaScript%20snippet%20will%20be%20executed%0A%20%20%20%20%20*%20(()%20=%3E%20%7B%0A%20%20%20%20%20*%20%20%20window%5B'_0123456'%5D(%7B%0A%20%20%20%20%20*%20%20%20%20%20ciphertext:%20%5B12,%2013,%204%5D,%0A%20%20%20%20%20*%20%20%20%20%20tag:%20%5B3,%205,%2067,%2056%5D%0A%20%20%20%20%20*%20%20%20%7D)%0A%20%20%20%20%20*%20%7D)()%0A%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20*%20@implements%20%7BMessagingTransport%7D%0A%20%20%20%20%20*/%0A%20%20%20%20class%20WebkitMessagingTransport%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BWebkitMessagingConfig%7D%20config%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../index.js').MessagingContext%7D%20messagingContext%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(config,%20messagingContext)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messagingContext%20=%20messagingContext;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.config%20=%20config;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.globals%20=%20captureGlobals();%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this.config.hasModernWebkitAPI)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.captureWebkitHandlers(this.config.webkitMessageHandlerNames);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Sends%20message%20to%20the%20webkit%20layer%20(fire%20and%20forget)%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BString%7D%20handler%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B*%7D%20data%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20wkSend(handler,%20data%20=%20%7B%7D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!(handler%20in%20this.globals.window.webkit.messageHandlers))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20MissingHandler(%60Missing%20webkit%20handler:%20'$%7Bhandler%7D'%60,%20handler);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this.config.hasModernWebkitAPI)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20outgoing%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20...data,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20messageHandling:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20...data.messageHandling,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20secret:%20this.config.secret,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!(handler%20in%20this.globals.capturedWebkitHandlers))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20MissingHandler(%60cannot%20continue,%20method%20$%7Bhandler%7D%20not%20captured%20on%20macos%20%3C%2011%60,%20handler);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this.globals.capturedWebkitHandlers%5Bhandler%5D(outgoing);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.globals.window.webkit.messageHandlers%5Bhandler%5D.postMessage?.(data);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Sends%20message%20to%20the%20webkit%20layer%20and%20waits%20for%20the%20specified%20response%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BString%7D%20handler%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../index.js').RequestMessage%7D%20data%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPromise%3C*%3E%7D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20async%20wkSendAndWait(handler,%20data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.config.hasModernWebkitAPI)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20response%20=%20await%20this.wkSend(handler,%20data);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this.globals.JSONparse(response%20%7C%7C%20'%7B%7D');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20randMethodName%20=%20this.createRandMethodName();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20key%20=%20await%20this.createRandKey();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20iv%20=%20this.createRandIv();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20ciphertext,%20tag%20%7D%20=%20await%20new%20this.globals.Promise((/**%20@type%20%7Bany%7D%20*/%20resolve)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.generateRandomMethod(randMethodName,%20resolve);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20this%20is%20a%20carve-out%20for%20catalina%20that%20will%20be%20removed%20soon%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20data.messageHandling%20=%20new%20SecureMessagingParams(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20methodName:%20randMethodName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20secret:%20this.config.secret,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20key:%20this.globals.Arrayfrom(key),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20iv:%20this.globals.Arrayfrom(iv),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.wkSend(handler,%20data);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20cipher%20=%20new%20this.globals.Uint8Array(%5B...ciphertext,%20...tag%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20decrypted%20=%20await%20this.decrypt(cipher,%20key,%20iv);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this.globals.JSONparse(decrypted%20%7C%7C%20'%7B%7D');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20re-throw%20when%20the%20error%20is%20just%20a%20'MissingHandler'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(e%20instanceof%20MissingHandler)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20e;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.error('decryption%20failed',%20e);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.error(e);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%20error:%20e%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../index.js').NotificationMessage%7D%20msg%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20notify(msg)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wkSend(msg.context,%20msg);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../index.js').RequestMessage%7D%20msg%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20async%20request(msg)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20data%20=%20await%20this.wkSendAndWait(msg.context,%20msg);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(isResponseFor(msg,%20data))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(data.result)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20data.result%20%7C%7C%20%7B%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20forward%20the%20error%20if%20one%20was%20given%20explicity%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(data.error)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error(data.error.message);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('an%20unknown%20error%20occurred');%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Generate%20a%20random%20method%20name%20and%20adds%20it%20to%20the%20global%20scope%0A%20%20%20%20%20%20%20%20%20*%20The%20native%20layer%20will%20use%20this%20method%20to%20send%20the%20response%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%20%7C%20number%7D%20randomMethodName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BFunction%7D%20callback%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20generateRandomMethod(randomMethodName,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.globals.ObjectDefineProperty(this.globals.window,%20randomMethodName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20configurable,%20To%20allow%20for%20deletion%20later%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20writable:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7Bany%5B%5D%7D%20args%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value:%20(...args)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20callback(...args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20this.globals.window%5BrandomMethodName%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7Bstring%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20randomString()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20''%20+%20this.globals.getRandomValues(new%20this.globals.Uint32Array(1))%5B0%5D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7Bstring%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20createRandMethodName()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20'_'%20+%20this.randomString();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@type%20%7B%7Bname:%20string,%20length:%20number%7D%7D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20algoObj%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20name:%20'AES-GCM',%0A%20%20%20%20%20%20%20%20%20%20%20%20length:%20256,%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPromise%3CUint8Array%3E%7D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20async%20createRandKey()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20key%20=%20await%20this.globals.generateKey(this.algoObj,%20true,%20%5B'encrypt',%20'decrypt'%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20exportedKey%20=%20await%20this.globals.exportKey('raw',%20key);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20this.globals.Uint8Array(exportedKey);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BUint8Array%7D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20createRandIv()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.globals.getRandomValues(new%20this.globals.Uint8Array(12));%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BBufferSource%7D%20ciphertext%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BBufferSource%7D%20key%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BUint8Array%7D%20iv%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPromise%3Cstring%3E%7D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20async%20decrypt(ciphertext,%20key,%20iv)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cryptoKey%20=%20await%20this.globals.importKey('raw',%20key,%20'AES-GCM',%20false,%20%5B'decrypt'%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20algo%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20'AES-GCM',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20iv,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20decrypted%20=%20await%20this.globals.decrypt(algo,%20cryptoKey,%20ciphertext);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20dec%20=%20new%20this.globals.TextDecoder();%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20dec.decode(decrypted);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20When%20required%20(such%20as%20on%20macos%2010.x),%20capture%20the%20%60postMessage%60%20method%20on%0A%20%20%20%20%20%20%20%20%20*%20each%20webkit%20messageHandler%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%5B%5D%7D%20handlerNames%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20captureWebkitHandlers(handlerNames)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20handlers%20=%20window.webkit.messageHandlers;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!handlers)%20throw%20new%20MissingHandler('window.webkit.messageHandlers%20was%20absent',%20'all');%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20webkitMessageHandlerName%20of%20handlerNames)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20handlers%5BwebkitMessageHandlerName%5D?.postMessage%20===%20'function')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20%60bind%60%20is%20used%20here%20to%20ensure%20future%20calls%20to%20the%20captured%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20%60postMessage%60%20have%20the%20correct%20%60this%60%20context%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20original%20=%20handlers%5BwebkitMessageHandlerName%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20bound%20=%20handlers%5BwebkitMessageHandlerName%5D.postMessage?.bind(original);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.globals.capturedWebkitHandlers%5BwebkitMessageHandlerName%5D%20=%20bound;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20handlers%5BwebkitMessageHandlerName%5D.postMessage;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../index.js').Subscription%7D%20msg%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(value:%20unknown)%20=%3E%20void%7D%20callback%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20subscribe(msg,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20for%20now,%20bail%20if%20there's%20already%20a%20handler%20setup%20for%20this%20subscription%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(msg.subscriptionName%20in%20this.globals.window)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20this.globals.Error(%60A%20subscription%20with%20the%20name%20$%7Bmsg.subscriptionName%7D%20already%20exists%60);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20this.globals.ObjectDefineProperty(this.globals.window,%20msg.subscriptionName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20writable:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value:%20(data)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(data%20&&%20isSubscriptionEventFor(msg,%20data))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20callback(data.params);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.warn('Received%20a%20message%20that%20did%20not%20match%20the%20subscription',%20data);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.globals.ReflectDeleteProperty(this.globals.window,%20msg.subscriptionName);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Use%20this%20configuration%20to%20create%20an%20instance%20of%20%7B@link%20Messaging%7D%20for%20WebKit%20platforms%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20We%20support%20modern%20WebKit%20environments%20*and*%20macOS%20Catalina.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20Please%20see%20%7B@link%20WebkitMessagingTransport%7D%20for%20details%20on%20how%20messages%20are%20sent/received%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%5BExample%5D(./examples/webkit.example.js)%0A%20%20%20%20%20*/%0A%20%20%20%20class%20WebkitMessagingConfig%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean%7D%20params.hasModernWebkitAPI%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%5B%5D%7D%20params.webkitMessageHandlerNames%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.secret%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Whether%20or%20not%20the%20current%20WebKit%20Platform%20supports%20secure%20messaging%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20by%20default%20(eg:%20macOS%2011+)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.hasModernWebkitAPI%20=%20params.hasModernWebkitAPI;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20A%20list%20of%20WebKit%20message%20handler%20names%20that%20a%20user%20script%20can%20send.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20For%20example,%20if%20the%20native%20platform%20can%20receive%20messages%20through%20this:%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20%60%60%60js%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20window.webkit.messageHandlers.foo.postMessage('...')%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20then,%20this%20property%20would%20be:%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20%60%60%60js%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20webkitMessageHandlerNames:%20%5B'foo'%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.webkitMessageHandlerNames%20=%20params.webkitMessageHandlerNames;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20A%20string%20provided%20by%20native%20platforms%20to%20be%20sent%20with%20future%20outgoing%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20messages.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.secret%20=%20params.secret;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20This%20is%20the%20additional%20payload%20that%20gets%20appended%20to%20outgoing%20messages.%0A%20%20%20%20%20*%20It's%20used%20in%20the%20Swift%20side%20to%20encrypt%20the%20response%20that%20comes%20back%0A%20%20%20%20%20*/%0A%20%20%20%20class%20SecureMessagingParams%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.methodName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.secret%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bnumber%5B%5D%7D%20params.key%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bnumber%5B%5D%7D%20params.iv%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20method%20that's%20been%20appended%20to%20%60window%60%20to%20be%20called%20later%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.methodName%20=%20params.methodName;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20secret%20used%20to%20ensure%20message%20sender%20validity%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.secret%20=%20params.secret;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20CipherKey%20as%20number%5B%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.key%20=%20params.key;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20Initial%20Vector%20as%20number%5B%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.iv%20=%20params.iv;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Capture%20some%20globals%20used%20for%20messaging%20handling%20to%20prevent%20page%0A%20%20%20%20%20*%20scripts%20from%20tampering%20with%20this%0A%20%20%20%20%20*/%0A%20%20%20%20function%20captureGlobals()%20%7B%0A%20%20%20%20%20%20%20%20//%20Create%20base%20with%20null%20prototype%0A%20%20%20%20%20%20%20%20const%20globals%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20window,%0A%20%20%20%20%20%20%20%20%20%20%20%20getRandomValues:%20window.crypto.getRandomValues.bind(window.crypto),%0A%20%20%20%20%20%20%20%20%20%20%20%20TextEncoder,%0A%20%20%20%20%20%20%20%20%20%20%20%20TextDecoder,%0A%20%20%20%20%20%20%20%20%20%20%20%20Uint8Array,%0A%20%20%20%20%20%20%20%20%20%20%20%20Uint16Array,%0A%20%20%20%20%20%20%20%20%20%20%20%20Uint32Array,%0A%20%20%20%20%20%20%20%20%20%20%20%20JSONstringify:%20window.JSON.stringify,%0A%20%20%20%20%20%20%20%20%20%20%20%20JSONparse:%20window.JSON.parse,%0A%20%20%20%20%20%20%20%20%20%20%20%20Arrayfrom:%20window.Array.from,%0A%20%20%20%20%20%20%20%20%20%20%20%20Promise:%20window.Promise,%0A%20%20%20%20%20%20%20%20%20%20%20%20Error:%20window.Error,%0A%20%20%20%20%20%20%20%20%20%20%20%20ReflectDeleteProperty:%20window.Reflect.deleteProperty.bind(window.Reflect),%0A%20%20%20%20%20%20%20%20%20%20%20%20ObjectDefineProperty:%20window.Object.defineProperty,%0A%20%20%20%20%20%20%20%20%20%20%20%20addEventListener:%20window.addEventListener.bind(window),%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7BRecord%3Cstring,%20any%3E%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20capturedWebkitHandlers:%20%7B%7D,%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20if%20(isSecureContext)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20skip%20for%20HTTP%20content%20since%20window.crypto.subtle%20is%20unavailable%0A%20%20%20%20%20%20%20%20%20%20%20%20globals.generateKey%20=%20window.crypto.subtle.generateKey.bind(window.crypto.subtle);%0A%20%20%20%20%20%20%20%20%20%20%20%20globals.exportKey%20=%20window.crypto.subtle.exportKey.bind(window.crypto.subtle);%0A%20%20%20%20%20%20%20%20%20%20%20%20globals.importKey%20=%20window.crypto.subtle.importKey.bind(window.crypto.subtle);%0A%20%20%20%20%20%20%20%20%20%20%20%20globals.encrypt%20=%20window.crypto.subtle.encrypt.bind(window.crypto.subtle);%0A%20%20%20%20%20%20%20%20%20%20%20%20globals.decrypt%20=%20window.crypto.subtle.decrypt.bind(window.crypto.subtle);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20globals;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20A%20wrapper%20for%20messaging%20on%20Android.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20You%20must%20share%20a%20%7B@link%20AndroidMessagingConfig%7D%20instance%20between%20features%0A%20%20%20%20%20*%0A%20%20%20%20%20*/%0A%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/no-unused-vars%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7Bimport('../index.js').Subscription%7D%20Subscription%0A%20%20%20%20%20*%20@typedef%20%7Bimport('../index.js').MessagingContext%7D%20MessagingContext%0A%20%20%20%20%20*%20@typedef%20%7Bimport('../index.js').RequestMessage%7D%20RequestMessage%0A%20%20%20%20%20*%20@typedef%20%7Bimport('../index.js').NotificationMessage%7D%20NotificationMessage%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20An%20implementation%20of%20%7B@link%20MessagingTransport%7D%20for%20Android%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20All%20messages%20go%20through%20%60window.chrome.webview%60%20APIs%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@implements%20%7BMessagingTransport%7D%0A%20%20%20%20%20*/%0A%20%20%20%20class%20AndroidMessagingTransport%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BAndroidMessagingConfig%7D%20config%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BMessagingContext%7D%20messagingContext%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(config,%20messagingContext)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messagingContext%20=%20messagingContext;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.config%20=%20config;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BNotificationMessage%7D%20msg%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20notify(msg)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.config.sendMessageThrows?.(JSON.stringify(msg));%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.error('.notify%20failed',%20e);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRequestMessage%7D%20msg%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7BPromise%3Cany%3E%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20request(msg)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20Promise((resolve,%20reject)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20subscribe%20early%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20unsub%20=%20this.config.subscribe(msg.id,%20handler);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.config.sendMessageThrows?.(JSON.stringify(msg));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unsub();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20reject(new%20Error('request%20failed%20to%20send:%20'%20+%20e.message%20%7C%7C%20'unknown%20error'));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20function%20handler(data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(isResponseFor(msg,%20data))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20success%20case,%20forward%20.result%20only%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(data.result)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resolve(data.result%20%7C%7C%20%7B%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20unsub();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20error%20case,%20forward%20the%20error%20as%20a%20regular%20promise%20rejection%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(data.error)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20reject(new%20Error(data.error.message));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20unsub();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20getting%20here%20is%20undefined%20behavior%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unsub();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('unreachable:%20must%20have%20%60result%60%20or%20%60error%60%20key%20by%20this%20point');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BSubscription%7D%20msg%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(value:%20unknown%20%7C%20undefined)%20=%3E%20void%7D%20callback%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20subscribe(msg,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20unsub%20=%20this.config.subscribe(msg.subscriptionName,%20(data)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(isSubscriptionEventFor(msg,%20data))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20callback(data.params%20%7C%7C%20%7B%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unsub();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Android%20shared%20messaging%20configuration.%20This%20class%20should%20be%20constructed%20once%20and%20then%20shared%0A%20%20%20%20%20*%20between%20features%20(because%20of%20the%20way%20it%20modifies%20globals).%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20For%20example,%20if%20Android%20is%20injecting%20a%20JavaScript%20module%20like%20C-S-S%20which%20contains%20multiple%20'sub-features',%20then%0A%20%20%20%20%20*%20this%20class%20would%20be%20instantiated%20once%20and%20then%20shared%20between%20all%20sub-features.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20The%20following%20example%20shows%20all%20the%20fields%20that%20are%20required%20to%20be%20passed%20in:%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%60%60%60js%0A%20%20%20%20%20*%20const%20config%20=%20new%20AndroidMessagingConfig(%7B%0A%20%20%20%20%20*%20%20%20%20%20//%20a%20value%20that%20native%20has%20injected%20into%20the%20script%0A%20%20%20%20%20*%20%20%20%20%20messageSecret:%20'abc',%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%20%20%20%20//%20the%20name%20of%20the%20window%20method%20that%20android%20will%20deliver%20responses%20through%0A%20%20%20%20%20*%20%20%20%20%20messageCallback:%20'callback_123',%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%20%20%20%20//%20the%20%60@JavascriptInterface%60%20name%20from%20native%20that%20will%20be%20used%20to%20receive%20messages%0A%20%20%20%20%20*%20%20%20%20%20javascriptInterface:%20%22ARandomValue%22,%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%20%20%20%20//%20the%20global%20object%20where%20methods%20will%20be%20registered%0A%20%20%20%20%20*%20%20%20%20%20target:%20globalThis%0A%20%20%20%20%20*%20%7D);%0A%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20*%20Once%20an%20instance%20of%20%7B@link%20AndroidMessagingConfig%7D%20is%20created,%20you%20can%20then%20use%20it%20to%20construct%0A%20%20%20%20%20*%20many%20instances%20of%20%7B@link%20Messaging%7D%20(one%20per%20feature).%20See%20%60examples/android.example.js%60%20for%20an%20example.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20##%20Native%20integration%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20Assuming%20you%20have%20the%20following:%0A%20%20%20%20%20*%20%20-%20a%20%60@JavascriptInterface%60%20named%20%60%22ContentScopeScripts%22%60%0A%20%20%20%20%20*%20%20-%20a%20sub-feature%20called%20%60%22featureA%22%60%0A%20%20%20%20%20*%20%20-%20and%20a%20method%20on%20%60%22featureA%22%60%20called%20%60%22helloWorld%22%60%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20Then%20delivering%20a%20%7B@link%20NotificationMessage%7D%20to%20it,%20would%20be%20roughly%20this%20in%20JavaScript%20(remember%20%60params%60%20is%20optional%20though)%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20*%20const%20secret%20=%20%22abc%22;%0A%20%20%20%20%20*%20const%20json%20=%20JSON.stringify(%7B%0A%20%20%20%20%20*%20%20%20%20%20context:%20%22ContentScopeScripts%22,%0A%20%20%20%20%20*%20%20%20%20%20featureName:%20%22featureA%22,%0A%20%20%20%20%20*%20%20%20%20%20method:%20%22helloWorld%22,%0A%20%20%20%20%20*%20%20%20%20%20params:%20%7B%20%22foo%22:%20%22bar%22%20%7D%0A%20%20%20%20%20*%20%7D);%0A%20%20%20%20%20*%20window.ContentScopeScripts.process(json,%20secret)%0A%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20*%20When%20you%20receive%20the%20JSON%20payload%20(note%20that%20it%20will%20be%20a%20string),%20you'll%20need%20to%20deserialize/verify%20it%20according%20to%20%7B@link%20%22Messaging%20Implementation%20Guide%22%7D%0A%20%20%20%20%20*%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20##%20Responding%20to%20a%20%7B@link%20RequestMessage%7D,%20or%20pushing%20a%20%7B@link%20SubscriptionEvent%7D%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20If%20you%20receive%20a%20%7B@link%20RequestMessage%7D,%20you'll%20need%20to%20deliver%20a%20%7B@link%20MessageResponse%7D.%0A%20%20%20%20%20*%20Similarly,%20if%20you%20want%20to%20push%20new%20data,%20you%20need%20to%20deliver%20a%20%7B@link%20SubscriptionEvent%7D.%20In%20both%0A%20%20%20%20%20*%20cases%20you'll%20do%20this%20through%20a%20global%20%60window%60%20method.%20Given%20the%20snippet%20below,%20this%20is%20how%20it%20would%20relate%0A%20%20%20%20%20*%20to%20the%20%7B@link%20AndroidMessagingConfig%7D:%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20-%20%60$messageCallback%60%20matches%20%7B@link%20AndroidMessagingConfig.messageCallback%7D%0A%20%20%20%20%20*%20-%20%60$messageSecret%60%20matches%20%7B@link%20AndroidMessagingConfig.messageSecret%7D%0A%20%20%20%20%20*%20-%20%60$message%60%20is%20JSON%20string%20that%20represents%20one%20of%20%7B@link%20MessageResponse%7D%20or%20%7B@link%20SubscriptionEvent%7D%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20*%20object%20ReplyHandler%20%7B%0A%20%20%20%20%20*%20%20%20%20%20fun%20constructReply(message:%20String,%20messageCallback:%20String,%20messageSecret:%20String):%20String%20%7B%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20return%20%22%22%22%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20(function()%20%7B%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20window%5B'$messageCallback'%5D('$messageSecret',%20$message);%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%7D)();%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%22%22%22.trimIndent()%0A%20%20%20%20%20*%20%20%20%20%20%7D%0A%20%20%20%20%20*%20%7D%0A%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20*/%0A%20%20%20%20class%20AndroidMessagingConfig%20%7B%0A%20%20%20%20%20%20%20%20/**%20@type%20%7B(json:%20string,%20secret:%20string)%20=%3E%20void%7D%20*/%0A%20%20%20%20%20%20%20%20_capturedHandler;%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20params.target%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean%7D%20params.debug%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.messageSecret%20-%20a%20secret%20to%20ensure%20that%20messages%20are%20only%0A%20%20%20%20%20%20%20%20%20*%20processed%20by%20the%20correct%20handler%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.javascriptInterface%20-%20the%20name%20of%20the%20javascript%20interface%0A%20%20%20%20%20%20%20%20%20*%20registered%20on%20the%20native%20side%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.messageCallback%20-%20the%20name%20of%20the%20callback%20that%20the%20native%0A%20%20%20%20%20%20%20%20%20*%20side%20will%20use%20to%20send%20messages%20back%20to%20the%20javascript%20side%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.target%20=%20params.target;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.debug%20=%20params.debug;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.javascriptInterface%20=%20params.javascriptInterface;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messageSecret%20=%20params.messageSecret;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messageCallback%20=%20params.messageCallback;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7BMap%3Cstring,%20(msg:%20MessageResponse%20%7C%20SubscriptionEvent)%20=%3E%20void%3E%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.listeners%20=%20new%20globalThis.Map();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Capture%20the%20global%20handler%20and%20remove%20it%20from%20the%20global%20object.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this._captureGlobalHandler();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Assign%20the%20incoming%20handler%20method%20to%20the%20global%20object.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this._assignHandlerMethod();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20The%20transport%20can%20call%20this%20to%20transmit%20a%20JSON%20payload%20along%20with%20a%20secret%0A%20%20%20%20%20%20%20%20%20*%20to%20the%20native%20Android%20handler.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20Note:%20This%20can%20throw%20-%20it's%20up%20to%20the%20transport%20to%20handle%20the%20error.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@type%20%7B(json:%20string)%20=%3E%20void%7D%0A%20%20%20%20%20%20%20%20%20*%20@throws%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20sendMessageThrows(json)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this._capturedHandler(json,%20this.messageSecret);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20A%20subscription%20on%20Android%20is%20just%20a%20named%20listener.%20All%20messages%20from%0A%20%20%20%20%20%20%20%20%20*%20android%20-%3E%20are%20delivered%20through%20a%20single%20function,%20and%20this%20mapping%20is%20used%0A%20%20%20%20%20%20%20%20%20*%20to%20route%20the%20messages%20to%20the%20correct%20listener.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20Note:%20Use%20this%20to%20implement%20request-%3Eresponse%20by%20unsubscribing%20after%20the%20first%0A%20%20%20%20%20%20%20%20%20*%20response.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20id%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(msg:%20MessageResponse%20%7C%20SubscriptionEvent)%20=%3E%20void%7D%20callback%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7B()%20=%3E%20void%7D%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20subscribe(id,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.listeners.set(id,%20callback);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.listeners.delete(id);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Accept%20incoming%20messages%20and%20try%20to%20deliver%20it%20to%20a%20registered%20listener.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20This%20code%20is%20defensive%20to%20prevent%20any%20single%20handler%20from%20affecting%20another%20if%0A%20%20%20%20%20%20%20%20%20*%20it%20throws%20(producer%20interference).%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BMessageResponse%20%7C%20SubscriptionEvent%7D%20payload%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_dispatch(payload)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20do%20nothing%20if%20the%20response%20is%20empty%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20this%20prevents%20the%20next%20%60in%60%20checks%20from%20throwing%20in%20test/debug%20scenarios%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!payload)%20return%20this._log('no%20response');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20if%20the%20payload%20has%20an%20'id'%20field,%20then%20it's%20a%20message%20response%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20('id'%20in%20payload)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.listeners.has(payload.id))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._tryCatch(()%20=%3E%20this.listeners.get(payload.id)?.(payload));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._log('no%20listeners%20for%20',%20payload);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20if%20the%20payload%20has%20an%20'subscriptionName'%20field,%20then%20it's%20a%20push%20event%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20('subscriptionName'%20in%20payload)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.listeners.has(payload.subscriptionName))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._tryCatch(()%20=%3E%20this.listeners.get(payload.subscriptionName)?.(payload));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._log('no%20subscription%20listeners%20for%20',%20payload);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(...args:%20any%5B%5D)%20=%3E%20any%7D%20fn%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5Bcontext%5D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_tryCatch(fn,%20context%20=%20'none')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20fn();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.debug)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.error('AndroidMessagingConfig%20error:',%20context);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.error(e);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B...any%7D%20args%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_log(...args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.debug)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.log('AndroidMessagingConfig',%20...args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Capture%20the%20global%20handler%20and%20remove%20it%20from%20the%20global%20object.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_captureGlobalHandler()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20target,%20javascriptInterface%20%7D%20=%20this;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(Object.prototype.hasOwnProperty.call(target,%20javascriptInterface))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._capturedHandler%20=%20target%5BjavascriptInterface%5D.process.bind(target%5BjavascriptInterface%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20target%5BjavascriptInterface%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._capturedHandler%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._log('Android%20messaging%20interface%20not%20available',%20javascriptInterface);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Assign%20the%20incoming%20handler%20method%20to%20the%20global%20object.%0A%20%20%20%20%20%20%20%20%20*%20This%20is%20the%20method%20that%20Android%20will%20call%20to%20deliver%20messages.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_assignHandlerMethod()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7B(secret:%20string,%20response:%20MessageResponse%20%7C%20SubscriptionEvent)%20=%3E%20void%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20responseHandler%20=%20(providedSecret,%20response)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(providedSecret%20===%20this.messageSecret)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._dispatch(response);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20Object.defineProperty(this.target,%20this.messageCallback,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value:%20responseHandler,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20An%20abstraction%20for%20communications%20between%20JavaScript%20and%20host%20platforms.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%201)%20First%20you%20construct%20your%20platform-specific%20configuration%20(eg:%20%7B@link%20WebkitMessagingConfig%7D)%0A%20%20%20%20%20*%202)%20Then%20use%20that%20to%20get%20an%20instance%20of%20the%20Messaging%20utility%20which%20allows%0A%20%20%20%20%20*%20you%20to%20send%20and%20receive%20data%20in%20a%20unified%20way%0A%20%20%20%20%20*%203)%20Each%20platform%20implements%20%7B@link%20MessagingTransport%7D%20along%20with%20its%20own%20Configuration%0A%20%20%20%20%20*%20%20%20%20%20-%20For%20example,%20to%20learn%20what%20configuration%20is%20required%20for%20Webkit,%20see:%20%7B@link%20WebkitMessagingConfig%7D%0A%20%20%20%20%20*%20%20%20%20%20-%20Or,%20to%20learn%20about%20how%20messages%20are%20sent%20and%20received%20in%20Webkit,%20see%20%7B@link%20WebkitMessagingTransport%7D%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20##%20Links%0A%20%20%20%20%20*%20Please%20see%20the%20following%20links%20for%20examples%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20-%20Windows:%20%7B@link%20WindowsMessagingConfig%7D%0A%20%20%20%20%20*%20-%20Webkit:%20%7B@link%20WebkitMessagingConfig%7D%0A%20%20%20%20%20*%20-%20Android:%20%7B@link%20AndroidMessagingConfig%7D%0A%20%20%20%20%20*%20-%20Schema:%20%7B@link%20%22Messaging%20Schema%22%7D%0A%20%20%20%20%20*%20-%20Implementation%20Guide:%20%7B@link%20%22Messaging%20Implementation%20Guide%22%7D%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@module%20Messaging%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Common%20options/config%20that%20are%20*not*%20transport%20specific.%0A%20%20%20%20%20*/%0A%20%20%20%20class%20MessagingContext%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.context%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B%22production%22%20%7C%20%22development%22%7D%20params.env%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.context%20=%20params.context;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.env%20=%20params.env;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7BWebkitMessagingConfig%20%7C%20WindowsMessagingConfig%20%7C%20AndroidMessagingConfig%20%7C%20TestTransportConfig%7D%20MessagingConfig%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%0A%20%20%20%20%20*/%0A%20%20%20%20class%20Messaging%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BMessagingContext%7D%20messagingContext%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BMessagingConfig%7D%20config%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(messagingContext,%20config)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messagingContext%20=%20messagingContext;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.transport%20=%20getTransport(config,%20this.messagingContext);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Send%20a%20'fire-and-forget'%20message.%0A%20%20%20%20%20%20%20%20%20*%20@throws%20%7BMissingHandler%7D%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@example%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60ts%0A%20%20%20%20%20%20%20%20%20*%20const%20messaging%20=%20new%20Messaging(config)%0A%20%20%20%20%20%20%20%20%20*%20messaging.notify(%22foo%22,%20%7Bbar:%20%22baz%22%7D)%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20name%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bdata%5D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20notify(name,%20data%20=%20%7B%7D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20message%20=%20new%20NotificationMessage(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20context:%20this.messagingContext.context,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName:%20this.messagingContext.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20method:%20name,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params:%20data,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20this.transport.notify(message);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Send%20a%20request,%20and%20wait%20for%20a%20response%0A%20%20%20%20%20%20%20%20%20*%20@throws%20%7BMissingHandler%7D%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@example%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20%20%20%20%20*%20const%20messaging%20=%20new%20Messaging(config)%0A%20%20%20%20%20%20%20%20%20*%20const%20response%20=%20await%20messaging.request(%22foo%22,%20%7Bbar:%20%22baz%22%7D)%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20name%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bdata%5D%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7BPromise%3Cany%3E%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20request(name,%20data%20=%20%7B%7D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20id%20=%20globalThis?.crypto?.randomUUID?.()%20%7C%7C%20name%20+%20'.response';%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20message%20=%20new%20RequestMessage(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20context:%20this.messagingContext.context,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName:%20this.messagingContext.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20method:%20name,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params:%20data,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.transport.request(message);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20name%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(value:%20unknown)%20=%3E%20void%7D%20callback%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7B()%20=%3E%20void%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20subscribe(name,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20msg%20=%20new%20Subscription(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20context:%20this.messagingContext.context,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName:%20this.messagingContext.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20subscriptionName:%20name,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.transport.subscribe(msg,%20callback);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Use%20this%20to%20create%20testing%20transport%20on%20the%20fly.%0A%20%20%20%20%20*%20It's%20useful%20for%20debugging,%20and%20for%20enabling%20scripts%20to%20run%20in%0A%20%20%20%20%20*%20other%20environments%20-%20for%20example,%20testing%20in%20a%20browser%20without%20the%20need%0A%20%20%20%20%20*%20for%20a%20full%20integration%0A%20%20%20%20%20*/%0A%20%20%20%20class%20TestTransportConfig%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BMessagingTransport%7D%20impl%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(impl)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.impl%20=%20impl;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@implements%20%7BMessagingTransport%7D%0A%20%20%20%20%20*/%0A%20%20%20%20class%20TestTransport%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BTestTransportConfig%7D%20config%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BMessagingContext%7D%20messagingContext%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(config,%20messagingContext)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.config%20=%20config;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messagingContext%20=%20messagingContext;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20notify(msg)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.config.impl.notify(msg);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20request(msg)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.config.impl.request(msg);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20subscribe(msg,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.config.impl.subscribe(msg,%20callback);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7BWebkitMessagingConfig%20%7C%20WindowsMessagingConfig%20%7C%20AndroidMessagingConfig%20%7C%20TestTransportConfig%7D%20config%0A%20%20%20%20%20*%20@param%20%7BMessagingContext%7D%20messagingContext%0A%20%20%20%20%20*%20@returns%20%7BMessagingTransport%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20getTransport(config,%20messagingContext)%20%7B%0A%20%20%20%20%20%20%20%20if%20(config%20instanceof%20WebkitMessagingConfig)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20WebkitMessagingTransport(config,%20messagingContext);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(config%20instanceof%20WindowsMessagingConfig)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20WindowsMessagingTransport(config,%20messagingContext);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(config%20instanceof%20AndroidMessagingConfig)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20AndroidMessagingTransport(config,%20messagingContext);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(config%20instanceof%20TestTransportConfig)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20TestTransport(config,%20messagingContext);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20throw%20new%20Error('unreachable');%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Thrown%20when%20a%20handler%20cannot%20be%20found%0A%20%20%20%20%20*/%0A%20%20%20%20class%20MissingHandler%20extends%20Error%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20message%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20handlerName%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(message,%20handlerName)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20super(message);%0A%20%20%20%20%20%20%20%20%20%20%20%20this.handlerName%20=%20handlerName;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Workaround%20defining%20MessagingTransport%20locally%20because%20%22import()%22%20is%20not%20working%20in%20%60@implements%60%0A%20%20%20%20%20*%20@typedef%20%7Bimport('@duckduckgo/messaging').MessagingTransport%7D%20MessagingTransport%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@deprecated%20-%20A%20temporary%20constructor%20for%20the%20extension%20to%20make%20the%20messaging%20config%0A%20%20%20%20%20*/%0A%20%20%20%20function%20extensionConstructMessagingConfig()%20%7B%0A%20%20%20%20%20%20%20%20const%20messagingTransport%20=%20new%20SendMessageMessagingTransport();%0A%20%20%20%20%20%20%20%20return%20new%20TestTransportConfig(messagingTransport);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20A%20temporary%20implementation%20of%20%7B@link%20MessagingTransport%7D%20to%20communicate%20with%20Extensions.%0A%20%20%20%20%20*%20It%20wraps%20the%20current%20messaging%20system%20that%20calls%20%60sendMessage%60%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@implements%20%7BMessagingTransport%7D%0A%20%20%20%20%20*%20@deprecated%20-%20Use%20this%20only%20to%20communicate%20with%20Android%20and%20the%20Extension%20while%20support%20to%20%7B@link%20Messaging%7D%0A%20%20%20%20%20*%20is%20not%20ready%20and%20we%20need%20to%20use%20%60sendMessage()%60.%0A%20%20%20%20%20*/%0A%20%20%20%20class%20SendMessageMessagingTransport%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Queue%20of%20callbacks%20to%20be%20called%20with%20messages%20sent%20from%20the%20Platform.%0A%20%20%20%20%20%20%20%20%20*%20This%20is%20used%20to%20connect%20requests%20with%20responses%20and%20to%20trigger%20subscriptions%20callbacks.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_queue%20=%20new%20Set();%0A%0A%20%20%20%20%20%20%20%20constructor()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.globals%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20window:%20globalThis,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20globalThis,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20JSONparse:%20globalThis.JSON.parse,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20JSONstringify:%20globalThis.JSON.stringify,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Promise:%20globalThis.Promise,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Error:%20globalThis.Error,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20String:%20globalThis.String,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Callback%20for%20update()%20handler.%20This%20connects%20messages%20sent%20from%20the%20Platform%0A%20%20%20%20%20%20%20%20%20*%20with%20callback%20functions%20in%20the%20_queue.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bany%7D%20response%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20onResponse(response)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this._queue.forEach((subscription)%20=%3E%20subscription(response));%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('@duckduckgo/messaging').NotificationMessage%7D%20msg%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20notify(msg)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20params%20=%20msg.params;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Unwrap%20'setYoutubePreviewsEnabled'%20params%20to%20match%20expected%20payload%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20for%20sendMessage()%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(msg.method%20===%20'setYoutubePreviewsEnabled')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params%20=%20msg.params?.youtubePreviewsEnabled;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Unwrap%20'updateYouTubeCTLAddedFlag'%20params%20to%20match%20expected%20payload%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20for%20sendMessage()%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(msg.method%20===%20'updateYouTubeCTLAddedFlag')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params%20=%20msg.params?.youTubeCTLAddedFlag;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20legacySendMessage(msg.method,%20params);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('@duckduckgo/messaging').RequestMessage%7D%20req%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7BPromise%3Cany%3E%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20request(req)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20comparator%20=%20(eventData)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20eventData.responseMessageType%20===%20req.method;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20params%20=%20req.params;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Adapts%20request%20for%20'getYouTubeVideoDetails'%20by%20identifying%20the%20correct%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20response%20for%20each%20request%20and%20updating%20params%20to%20expect%20current%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20implementation%20specifications.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(req.method%20===%20'getYouTubeVideoDetails')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20comparator%20=%20(eventData)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20eventData.responseMessageType%20===%20req.method%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20eventData.response%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20eventData.response.videoURL%20===%20req.params?.videoURL%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params%20=%20req.params?.videoURL;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20legacySendMessage(req.method,%20params);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20this.globals.Promise((resolve)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._subscribe(comparator,%20(msgRes,%20unsubscribe)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unsubscribe();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20resolve(msgRes.response);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('@duckduckgo/messaging').Subscription%7D%20msg%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(value:%20unknown%20%7C%20undefined)%20=%3E%20void%7D%20callback%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20subscribe(msg,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20comparator%20=%20(eventData)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20eventData.messageType%20===%20msg.subscriptionName%20%7C%7C%20eventData.responseMessageType%20===%20msg.subscriptionName;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20only%20forward%20the%20'params'%20('response'%20in%20current%20format),%20to%20match%20expected%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20callback%20from%20a%20SubscriptionEvent%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cb%20=%20(eventData)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20callback(eventData.response);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this._subscribe(comparator,%20cb);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(eventData:%20any)%20=%3E%20boolean%7D%20comparator%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(value:%20any,%20unsubscribe:%20(()=%3Evoid))%20=%3E%20void%7D%20callback%0A%20%20%20%20%20%20%20%20%20*%20@internal%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_subscribe(comparator,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7B(()=%3Evoid)%20%7C%20undefined%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20prefer-const%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20teardown;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BMessageEvent%7D%20event%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20idHandler%20=%20(event)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!event)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.warn('no%20message%20available');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(comparator(event))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!teardown)%20throw%20new%20this.globals.Error('unreachable');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20callback(event,%20teardown);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20this._queue.add(idHandler);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20teardown%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._queue.delete(idHandler);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20teardown?.();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7Bobject%7D%20AssetConfig%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20regularFontUrl%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20boldFontUrl%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7Bobject%7D%20Site%0A%20%20%20%20%20*%20@property%20%7Bstring%20%7C%20null%7D%20domain%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20%5BisBroken%5D%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20%5Ballowlisted%5D%0A%20%20%20%20%20*%20@property%20%7Bstring%5B%5D%7D%20%5BenabledFeatures%5D%0A%20%20%20%20%20*/%0A%0A%20%20%20%20class%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20/**%20@type%20%7Bimport('./utils.js').RemoteConfig%20%7C%20undefined%7D%20*/%0A%20%20%20%20%20%20%20%20#bundledConfig;%0A%20%20%20%20%20%20%20%20/**%20@type%20%7Bobject%20%7C%20undefined%7D%20*/%0A%20%20%20%20%20%20%20%20#trackerLookup;%0A%20%20%20%20%20%20%20%20/**%20@type%20%7Bboolean%20%7C%20undefined%7D%20*/%0A%20%20%20%20%20%20%20%20#documentOriginIsTracker;%0A%20%20%20%20%20%20%20%20/**%20@type%20%7BRecord%3Cstring,%20unknown%3E%20%7C%20undefined%7D%20*/%0A%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20no-unused-private-class-members%0A%20%20%20%20%20%20%20%20#bundledfeatureSettings;%0A%20%20%20%20%20%20%20%20/**%20@type%20%7Bimport('../../messaging').Messaging%7D%20*/%0A%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20no-unused-private-class-members%0A%20%20%20%20%20%20%20%20#messaging;%0A%20%20%20%20%20%20%20%20/**%20@type%20%7Bboolean%7D%20*/%0A%20%20%20%20%20%20%20%20#isDebugFlagSet%20=%20false;%0A%0A%20%20%20%20%20%20%20%20/**%20@type%20%7B%7B%20debug?:%20boolean,%20desktopModeEnabled?:%20boolean,%20forcedZoomEnabled?:%20boolean,%20featureSettings?:%20Record%3Cstring,%20unknown%3E,%20assets?:%20AssetConfig%20%7C%20undefined,%20site:%20Site,%20messagingConfig?:%20import('@duckduckgo/messaging').MessagingConfig%20%7D%20%7C%20null%7D%20*/%0A%20%20%20%20%20%20%20%20#args;%0A%0A%20%20%20%20%20%20%20%20constructor(featureName)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.name%20=%20featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.#args%20=%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.monitor%20=%20new%20PerformanceMonitor();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20get%20isDebug()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.#args?.debug%20%7C%7C%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20get%20desktopModeEnabled()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.#args?.desktopModeEnabled%20%7C%7C%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20get%20forcedZoomEnabled()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.#args?.forcedZoomEnabled%20%7C%7C%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('./utils').Platform%7D%20platform%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20set%20platform(platform)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this._platform%20=%20platform;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20get%20platform()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Type%20'Platform%20%7C%20undefined'%20is%20not%20assignable%20to%20type%20'Platform'%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this._platform;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@type%20%7BAssetConfig%20%7C%20undefined%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20get%20assetConfig()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.#args?.assets;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20get%20documentOriginIsTracker()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20!!this.#documentOriginIsTracker;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bobject%7D%0A%20%20%20%20%20%20%20%20%20**/%0A%20%20%20%20%20%20%20%20get%20trackerLookup()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.#trackerLookup%20%7C%7C%20%7B%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bimport('./utils.js').RemoteConfig%20%7C%20undefined%7D%0A%20%20%20%20%20%20%20%20%20**/%0A%20%20%20%20%20%20%20%20get%20bundledConfig()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.#bundledConfig;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@deprecated%20as%20we%20should%20make%20this%20internal%20to%20the%20class%20and%20not%20used%20externally%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7BMessagingContext%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_createMessagingContext()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20contextName%20=%20'contentScopeScripts';%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20MessagingContext(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20context:%20contextName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20env:%20this.isDebug%20?%20'development'%20:%20'production',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName:%20this.name,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Lazily%20create%20a%20messaging%20instance%20for%20the%20given%20Platform%20+%20feature%20combo%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7Bimport('@duckduckgo/messaging').Messaging%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20get%20messaging()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this._messaging)%20return%20this._messaging;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20messagingContext%20=%20this._createMessagingContext();%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20messagingConfig%20=%20this.#args?.messagingConfig;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!messagingConfig)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.platform?.name%20!==%20'extension')%20throw%20new%20Error('Only%20extension%20messaging%20supported,%20all%20others%20should%20be%20passed%20in');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20messagingConfig%20=%20extensionConstructMessagingConfig();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20this._messaging%20=%20new%20Messaging(messagingContext,%20messagingConfig);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this._messaging;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Get%20the%20value%20of%20a%20config%20setting.%0A%20%20%20%20%20%20%20%20%20*%20If%20the%20value%20is%20not%20set,%20return%20the%20default%20value.%0A%20%20%20%20%20%20%20%20%20*%20If%20the%20value%20is%20not%20an%20object,%20return%20the%20value.%0A%20%20%20%20%20%20%20%20%20*%20If%20the%20value%20is%20an%20object,%20check%20its%20type%20property.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20attrName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bany%7D%20defaultValue%20-%20The%20default%20value%20to%20use%20if%20the%20config%20setting%20is%20not%20set%0A%20%20%20%20%20%20%20%20%20*%20@returns%20The%20value%20of%20the%20config%20setting%20or%20the%20default%20value%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20getFeatureAttr(attrName,%20defaultValue)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20configSetting%20=%20this.getFeatureSetting(attrName);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20processAttr(configSetting,%20defaultValue);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Return%20a%20specific%20setting%20from%20the%20feature%20settings%0A%20%20%20%20%20%20%20%20%20*%20If%20the%20%22settings%22%20key%20within%20the%20config%20has%20a%20%22domains%22%20key,%20it%20will%20be%20used%20to%20override%20the%20settings.%0A%20%20%20%20%20%20%20%20%20*%20This%20uses%20JSONPatch%20to%20apply%20the%20patches%20to%20settings%20before%20getting%20the%20setting%20value.%0A%20%20%20%20%20%20%20%20%20*%20For%20example.com%20getFeatureSettings('val')%20will%20return%201:%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60json%0A%20%20%20%20%20%20%20%20%20*%20%20%7B%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%22settings%22:%20%7B%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%22domains%22:%20%5B%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22domain%22:%20%22example.com%22,%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22patchSettings%22:%20%5B%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20%22op%22:%20%22replace%22,%20%22path%22:%20%22/val%22,%20%22value%22:%201%20%7D%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20*%20%20%7D%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20%20%20%20%20*%20%22domain%22%20can%20either%20be%20a%20string%20or%20an%20array%20of%20strings.%0A%0A%20%20%20%20%20%20%20%20%20*%20For%20boolean%20states%20you%20should%20consider%20using%20getFeatureSettingEnabled.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20featureKeyName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BfeatureName%5D%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bany%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20getFeatureSetting(featureKeyName,%20featureName)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20result%20=%20this._getFeatureSettings(featureName);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(featureKeyName%20===%20'domains')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('domains%20is%20a%20reserved%20feature%20setting%20key%20name');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20domainMatch%20=%20%5B...this.matchDomainFeatureSetting('domains')%5D.sort((a,%20b)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20a.domain.length%20-%20b.domain.length;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20match%20of%20domainMatch)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(match.patchSettings%20===%20undefined)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result%20=%20immutableJSONPatch(result,%20match.patchSettings);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.error('Error%20applying%20patch%20settings',%20e);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20result?.%5BfeatureKeyName%5D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Return%20the%20settings%20object%20for%20a%20feature%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BfeatureName%5D%20-%20The%20name%20of%20the%20feature%20to%20get%20the%20settings%20for;%20defaults%20to%20the%20name%20of%20the%20feature%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bany%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_getFeatureSettings(featureName)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20camelFeatureName%20=%20featureName%20%7C%7C%20camelcase(this.name);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.#args?.featureSettings?.%5BcamelFeatureName%5D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20For%20simple%20boolean%20settings,%20return%20true%20if%20the%20setting%20is%20'enabled'%0A%20%20%20%20%20%20%20%20%20*%20For%20objects,%20verify%20the%20'state'%20field%20is%20'enabled'.%0A%20%20%20%20%20%20%20%20%20*%20This%20allows%20for%20future%20forwards%20compatibility%20with%20more%20complex%20settings%20if%20required.%0A%20%20%20%20%20%20%20%20%20*%20For%20example:%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60json%0A%20%20%20%20%20%20%20%20%20*%20%7B%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%22toggle%22:%20%22enabled%22%0A%20%20%20%20%20%20%20%20%20*%20%7D%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20%20%20%20%20*%20Could%20become%20later%20(without%20breaking%20changes):%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60json%0A%20%20%20%20%20%20%20%20%20*%20%7B%0A%20%20%20%20%20%20%20%20%20*%20%20%20%22toggle%22:%20%7B%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%22state%22:%20%22enabled%22,%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%22someOtherKey%22:%201%0A%20%20%20%20%20%20%20%20%20*%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20*%20%7D%0A%20%20%20%20%20%20%20%20%20*%20%60%60%60%0A%20%20%20%20%20%20%20%20%20*%20This%20also%20supports%20domain%20overrides%20as%20per%20%60getFeatureSetting%60.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20featureKeyName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BfeatureName%5D%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20getFeatureSettingEnabled(featureKeyName,%20featureName)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20result%20=%20this.getFeatureSetting(featureKeyName,%20featureName);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20result%20===%20'object')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20result.state%20===%20'enabled';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20result%20===%20'enabled';%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Given%20a%20config%20key,%20interpret%20the%20value%20as%20a%20list%20of%20domain%20overrides,%20and%20return%20the%20elements%20that%20match%20the%20current%20page%0A%20%20%20%20%20%20%20%20%20*%20Consider%20using%20patchSettings%20instead%20as%20per%20%60getFeatureSetting%60.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20featureKeyName%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7Bany%5B%5D%7D%0A%20%20%20%20%20%20%20%20%20*%20@private%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20matchDomainFeatureSetting(featureKeyName)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20domain%20=%20this.#args?.site.domain;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!domain)%20return%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20domains%20=%20this._getFeatureSettings()?.%5BfeatureKeyName%5D%20%7C%7C%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20domains.filter((rule)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(Array.isArray(rule.domain))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20rule.domain.some((domainRule)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20matchHostname(domain,%20domainRule);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20matchHostname(domain,%20rule.domain);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20init(args)%20%7B%7D%0A%0A%20%20%20%20%20%20%20%20callInit(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20mark%20=%20this.monitor.mark(this.name%20+%20'CallInit');%0A%20%20%20%20%20%20%20%20%20%20%20%20this.#args%20=%20args;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.platform%20=%20args.platform;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.init(args);%0A%20%20%20%20%20%20%20%20%20%20%20%20mark.end();%0A%20%20%20%20%20%20%20%20%20%20%20%20this.measure();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20load(args)%20%7B%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20This%20is%20a%20wrapper%20around%20%60this.messaging.notify%60%20that%20applies%20the%0A%20%20%20%20%20%20%20%20%20*%20auto-generated%20types%20from%20the%20%60src/types%60%20folder.%20It's%20used%0A%20%20%20%20%20%20%20%20%20*%20to%20provide%20per-feature%20type%20information%20based%20on%20the%20schemas%0A%20%20%20%20%20%20%20%20%20*%20in%20%60src/messages%60%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@type%20%7Bimport(%22@duckduckgo/messaging%22).Messaging%5B'notify'%5D%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20notify(...args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%5Bname,%20params%5D%20=%20args;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messaging.notify(name,%20params);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20This%20is%20a%20wrapper%20around%20%60this.messaging.request%60%20that%20applies%20the%0A%20%20%20%20%20%20%20%20%20*%20auto-generated%20types%20from%20the%20%60src/types%60%20folder.%20It's%20used%0A%20%20%20%20%20%20%20%20%20*%20to%20provide%20per-feature%20type%20information%20based%20on%20the%20schemas%0A%20%20%20%20%20%20%20%20%20*%20in%20%60src/messages%60%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@type%20%7Bimport(%22@duckduckgo/messaging%22).Messaging%5B'request'%5D%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20request(...args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%5Bname,%20params%5D%20=%20args;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.messaging.request(name,%20params);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20This%20is%20a%20wrapper%20around%20%60this.messaging.subscribe%60%20that%20applies%20the%0A%20%20%20%20%20%20%20%20%20*%20auto-generated%20types%20from%20the%20%60src/types%60%20folder.%20It's%20used%0A%20%20%20%20%20%20%20%20%20*%20to%20provide%20per-feature%20type%20information%20based%20on%20the%20schemas%0A%20%20%20%20%20%20%20%20%20*%20in%20%60src/messages%60%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@type%20%7Bimport(%22@duckduckgo/messaging%22).Messaging%5B'subscribe'%5D%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20subscribe(...args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%5Bname,%20cb%5D%20=%20args;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.messaging.subscribe(name,%20cb);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('./content-scope-features.js').LoadArgs%7D%20args%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20callLoad(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20mark%20=%20this.monitor.mark(this.name%20+%20'CallLoad');%0A%20%20%20%20%20%20%20%20%20%20%20%20this.#args%20=%20args;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.platform%20=%20args.platform;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.#bundledConfig%20=%20args.bundledConfig;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20we%20have%20a%20bundled%20config,%20treat%20it%20as%20a%20regular%20config%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20This%20will%20be%20overriden%20by%20the%20remote%20config%20if%20it%20is%20available%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.#bundledConfig%20&&%20this.#args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20enabledFeatures%20=%20computeEnabledFeatures(args.bundledConfig,%20args.site.domain,%20this.platform.version);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.#args.featureSettings%20=%20parseFeatureSettings(args.bundledConfig,%20enabledFeatures);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20this.#trackerLookup%20=%20args.trackerLookup;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.#documentOriginIsTracker%20=%20args.documentOriginIsTracker;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.load(args);%0A%20%20%20%20%20%20%20%20%20%20%20%20mark.end();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20measure()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.#args?.debug)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.monitor.measureAll();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20update()%20%7B%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Register%20a%20flag%20that%20will%20be%20added%20to%20page%20breakage%20reports%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20addDebugFlag()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.#isDebugFlagSet)%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.#isDebugFlagSet%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messaging?.notify('addDebugFlag',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20flag:%20this.name,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Define%20a%20property%20descriptor%20with%20debug%20flags.%0A%20%20%20%20%20%20%20%20%20*%20Mainly%20used%20for%20defining%20new%20properties.%20For%20overriding%20existing%20properties,%20consider%20using%20wrapProperty(),%20wrapMethod()%20and%20wrapConstructor().%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bany%7D%20object%20-%20object%20whose%20property%20we%20are%20wrapping%20(most%20commonly%20a%20prototype,%20e.g.%20globalThis.BatteryManager.prototype)%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20propertyName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('./wrapper-utils').StrictPropertyDescriptor%7D%20descriptor%20-%20requires%20all%20descriptor%20options%20to%20be%20defined%20because%20we%20can't%20validate%20correctness%20based%20on%20TS%20types%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20defineProperty(object,%20propertyName,%20descriptor)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20make%20sure%20to%20send%20a%20debug%20flag%20when%20the%20property%20is%20used%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20NOTE:%20properties%20passing%20data%20in%20%60value%60%20would%20not%20be%20caught%20by%20this%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B'value',%20'get',%20'set'%5D.forEach((k)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20descriptorProp%20=%20descriptor%5Bk%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20descriptorProp%20===%20'function')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20addDebugFlag%20=%20this.addDebugFlag.bind(this);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20wrapper%20=%20new%20Proxy$1(descriptorProp,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20argumentsList)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20addDebugFlag();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20Reflect$1.apply(descriptorProp,%20thisArg,%20argumentsList);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20descriptor%5Bk%5D%20=%20wrapToString(wrapper,%20descriptorProp);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20defineProperty(object,%20propertyName,%20descriptor);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Wrap%20a%20%60get%60/%60set%60%20or%20%60value%60%20property%20descriptor.%20Only%20for%20data%20properties.%20For%20methods,%20use%20wrapMethod().%20For%20constructors,%20use%20wrapConstructor().%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bany%7D%20object%20-%20object%20whose%20property%20we%20are%20wrapping%20(most%20commonly%20a%20prototype,%20e.g.%20globalThis.Screen.prototype)%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20propertyName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BPartial%3CPropertyDescriptor%3E%7D%20descriptor%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPropertyDescriptor%7Cundefined%7D%20original%20property%20descriptor,%20or%20undefined%20if%20it's%20not%20found%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20wrapProperty(object,%20propertyName,%20descriptor)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20wrapProperty(object,%20propertyName,%20descriptor,%20this.defineProperty.bind(this));%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Wrap%20a%20method%20descriptor.%20Only%20for%20function%20properties.%20For%20data%20properties,%20use%20wrapProperty().%20For%20constructors,%20use%20wrapConstructor().%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bany%7D%20object%20-%20object%20whose%20property%20we%20are%20wrapping%20(most%20commonly%20a%20prototype,%20e.g.%20globalThis.Bluetooth.prototype)%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20propertyName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(originalFn,%20...args)%20=%3E%20any%20%7D%20wrapperFn%20-%20wrapper%20function%20receives%20the%20original%20function%20as%20the%20first%20argument%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPropertyDescriptor%7Cundefined%7D%20original%20property%20descriptor,%20or%20undefined%20if%20it's%20not%20found%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20wrapMethod(object,%20propertyName,%20wrapperFn)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20wrapMethod(object,%20propertyName,%20wrapperFn,%20this.defineProperty.bind(this));%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@template%20%7Bkeyof%20typeof%20globalThis%7D%20StandardInterfaceName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BStandardInterfaceName%7D%20interfaceName%20-%20the%20name%20of%20the%20interface%20to%20shim%20(must%20be%20some%20known%20standard%20API,%20e.g.%20'MediaSession')%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Btypeof%20globalThis%5BStandardInterfaceName%5D%7D%20ImplClass%20-%20the%20class%20to%20use%20as%20the%20shim%20implementation%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('./wrapper-utils').DefineInterfaceOptions%7D%20options%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20shimInterface(interfaceName,%20ImplClass,%20options)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20shimInterface(interfaceName,%20ImplClass,%20options,%20this.defineProperty.bind(this));%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Define%20a%20missing%20standard%20property%20on%20a%20global%20(prototype)%20object.%20Only%20for%20data%20properties.%0A%20%20%20%20%20%20%20%20%20*%20For%20constructors,%20use%20shimInterface().%0A%20%20%20%20%20%20%20%20%20*%20Most%20of%20the%20time,%20you'd%20want%20to%20call%20shimInterface()%20first%20to%20shim%20the%20class%20itself%20(MediaSession),%20and%20then%20shimProperty()%20for%20the%20global%20singleton%20instance%20(Navigator.prototype.mediaSession).%0A%20%20%20%20%20%20%20%20%20*%20@template%20Base%0A%20%20%20%20%20%20%20%20%20*%20@template%20%7Bkeyof%20Base%20&%20string%7D%20K%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BBase%7D%20instanceHost%20-%20object%20whose%20property%20we%20are%20shimming%20(most%20commonly%20a%20prototype%20object,%20e.g.%20Navigator.prototype)%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BK%7D%20instanceProp%20-%20name%20of%20the%20property%20to%20shim%20(e.g.%20'mediaSession')%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BBase%5BK%5D%7D%20implInstance%20-%20instance%20to%20use%20as%20the%20shim%20(e.g.%20new%20MyMediaSession())%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean%7D%20%5BreadOnly%5D%20-%20whether%20the%20property%20should%20be%20read-only%20(default:%20false)%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20shimProperty(instanceHost,%20instanceProp,%20implInstance,%20readOnly%20=%20false)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20shimProperty(instanceHost,%20instanceProp,%20implInstance,%20readOnly,%20this.defineProperty.bind(this));%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Check%20if%20the%20current%20document%20origin%20is%20on%20the%20tracker%20list,%20using%20the%20provided%20lookup%20trie.%0A%20%20%20%20%20*%20@param%20%7Bobject%7D%20trackerLookup%20Trie%20lookup%20of%20tracker%20domains%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%20True%20iff%20the%20origin%20is%20a%20tracker.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isTrackerOrigin(trackerLookup,%20originHostname%20=%20document.location.hostname)%20%7B%0A%20%20%20%20%20%20%20%20const%20parts%20=%20originHostname.split('.').reverse();%0A%20%20%20%20%20%20%20%20let%20node%20=%20trackerLookup;%0A%20%20%20%20%20%20%20%20for%20(const%20sub%20of%20parts)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(node%5Bsub%5D%20===%201)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(node%5Bsub%5D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20node%20=%20node%5Bsub%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20ExtensionCookiePolicy%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20isFrame%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20isTracker%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20shouldBlock%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20isThirdPartyFrame%0A%20%20%20%20%20*/%0A%0A%20%20%20%20function%20initialShouldBlockTrackerCookie()%20%7B%0A%20%20%20%20%20%20%20%20const%20injectName%20=%20%22chrome%22;%0A%20%20%20%20%20%20%20%20return%20injectName%20===%20'chrome';%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20Initial%20cookie%20policy%20pre%20init%0A%20%20%20%20let%20cookiePolicy%20=%20%7B%0A%20%20%20%20%20%20%20%20debug:%20false,%0A%20%20%20%20%20%20%20%20isFrame:%20isBeingFramed(),%0A%20%20%20%20%20%20%20%20isTracker:%20false,%0A%20%20%20%20%20%20%20%20shouldBlock:%20true,%0A%20%20%20%20%20%20%20%20shouldBlockTrackerCookie:%20initialShouldBlockTrackerCookie(),%0A%20%20%20%20%20%20%20%20shouldBlockNonTrackerCookie:%20false,%0A%20%20%20%20%20%20%20%20isThirdPartyFrame:%20isThirdPartyFrame(),%0A%20%20%20%20%20%20%20%20policy:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20threshold:%20604800,%20//%207%20days%0A%20%20%20%20%20%20%20%20%20%20%20%20maxAge:%20604800,%20//%207%20days%0A%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20trackerPolicy:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20threshold:%2086400,%20//%201%20day%0A%20%20%20%20%20%20%20%20%20%20%20%20maxAge:%2086400,%20//%201%20day%0A%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20allowlist:%20/**%20@type%20%7B%7B%20host:%20string%20%7D%5B%5D%7D%20*/%20(%5B%5D),%0A%20%20%20%20%7D;%0A%20%20%20%20let%20trackerLookup%20=%20%7B%7D;%0A%0A%20%20%20%20let%20loadedPolicyResolve;%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7B'ignore'%20%7C%20'block'%20%7C%20'restrict'%7D%20action%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20reason%0A%20%20%20%20%20*%20@param%20%7Bany%7D%20ctx%0A%20%20%20%20%20*/%0A%20%20%20%20function%20debugHelper(action,%20reason,%20ctx)%20%7B%0A%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/no-unused-expressions%0A%20%20%20%20%20%20%20%20cookiePolicy.debug%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20postDebugMessage('jscookie',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20action,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20reason,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20stack:%20ctx.stack,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20documentUrl:%20globalThis.document.location.href,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value:%20ctx.value,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20shouldBlockTrackingCookie()%20%7B%0A%20%20%20%20%20%20%20%20return%20cookiePolicy.shouldBlock%20&&%20cookiePolicy.shouldBlockTrackerCookie%20&&%20isTrackingCookie();%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20shouldBlockNonTrackingCookie()%20%7B%0A%20%20%20%20%20%20%20%20return%20cookiePolicy.shouldBlock%20&&%20cookiePolicy.shouldBlockNonTrackerCookie%20&&%20isNonTrackingCookie();%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7BSet%3Cstring%3E%7D%20scriptOrigins%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isFirstPartyTrackerScript(scriptOrigins)%20%7B%0A%20%20%20%20%20%20%20%20let%20matched%20=%20false;%0A%20%20%20%20%20%20%20%20for%20(const%20scriptOrigin%20of%20scriptOrigins)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(cookiePolicy.allowlist.find((allowlistOrigin)%20=%3E%20matchHostname(allowlistOrigin.host,%20scriptOrigin)))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(isTrackerOrigin(trackerLookup,%20scriptOrigin))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20matched%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20matched;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isTrackingCookie()%20%7B%0A%20%20%20%20%20%20%20%20return%20cookiePolicy.isFrame%20&&%20cookiePolicy.isTracker%20&&%20cookiePolicy.isThirdPartyFrame;%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20isNonTrackingCookie()%20%7B%0A%20%20%20%20%20%20%20%20return%20cookiePolicy.isFrame%20&&%20!cookiePolicy.isTracker%20&&%20cookiePolicy.isThirdPartyFrame;%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20CookieFeature%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20load()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.documentOriginIsTracker)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookiePolicy.isTracker%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.trackerLookup)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20trackerLookup%20=%20this.trackerLookup;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.bundledConfig?.features?.cookie)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20use%20the%20bundled%20config%20to%20get%20a%20best-effort%20at%20the%20policy,%20before%20the%20background%20sends%20the%20real%20one%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20exceptions,%20settings%20%7D%20=%20this.bundledConfig.features.cookie;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20tabHostname%20=%20getTabHostname();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20tabExempted%20=%20true;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(tabHostname%20!=%20null)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tabExempted%20=%20exceptions.some((exception)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20matchHostname(tabHostname,%20exception.domain);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20frameExempted%20=%20settings.excludedCookieDomains.some((exception)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20matchHostname(globalThis.location.hostname,%20exception.domain);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookiePolicy.shouldBlock%20=%20!frameExempted%20&&%20!tabExempted;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookiePolicy.policy%20=%20settings.firstPartyCookiePolicy;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookiePolicy.trackerPolicy%20=%20settings.firstPartyTrackerCookiePolicy;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Allows%20for%20ad%20click%20conversion%20detection%20as%20described%20by%20https://help.duckduckgo.com/duckduckgo-help-pages/privacy/web-tracking-protections/.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20This%20only%20applies%20when%20the%20resources%20that%20would%20set%20these%20cookies%20are%20unblocked.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookiePolicy.allowlist%20=%20this.getFeatureSetting('allowlist',%20'adClickAttribution')%20%7C%7C%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20The%20cookie%20policy%20is%20injected%20into%20every%20frame%20immediately%20so%20that%20no%20cookie%20will%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20be%20missed.%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20document%20=%20globalThis.document;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Object%20is%20possibly%20'undefined'.%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cookieSetter%20=%20Object.getOwnPropertyDescriptor(globalThis.Document.prototype,%20'cookie').set;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Object%20is%20possibly%20'undefined'.%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cookieGetter%20=%20Object.getOwnPropertyDescriptor(globalThis.Document.prototype,%20'cookie').get;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20loadPolicy%20=%20new%20Promise((resolve)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loadedPolicyResolve%20=%20resolve;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Create%20the%20then%20callback%20now%20-%20this%20ensures%20that%20Promise.prototype.then%20changes%20won't%20break%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20this%20call.%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20loadPolicyThen%20=%20loadPolicy.then.bind(loadPolicy);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20getCookiePolicy()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20getCookieContext%20=%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(cookiePolicy.debug)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20stack%20=%20getStack();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20getCookieContext%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20stack,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value:%20'getter',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(shouldBlockTrackingCookie()%20%7C%7C%20shouldBlockNonTrackingCookie())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debugHelper('block',%20'3p%20frame',%20getCookieContext);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20'';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(isTrackingCookie()%20%7C%7C%20isNonTrackingCookie())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debugHelper('ignore',%20'3p%20frame',%20getCookieContext);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'cookieGetter'%20is%20possibly%20'undefined'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20cookieGetter.call(this);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7Bany%7D%20argValue%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20setCookiePolicy(argValue)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20setCookieContext%20=%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!argValue?.toString%20%7C%7C%20typeof%20argValue.toString()%20!==%20'string')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20not%20a%20string,%20or%20string-like%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20value%20=%20argValue.toString();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(cookiePolicy.debug)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20stack%20=%20getStack();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20setCookieContext%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20stack,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(shouldBlockTrackingCookie()%20%7C%7C%20shouldBlockNonTrackingCookie())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debugHelper('block',%20'3p%20frame',%20setCookieContext);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(isTrackingCookie()%20%7C%7C%20isNonTrackingCookie())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debugHelper('ignore',%20'3p%20frame',%20setCookieContext);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20call%20the%20native%20document.cookie%20implementation.%20This%20will%20set%20the%20cookie%20immediately%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20if%20the%20value%20is%20valid.%20We%20will%20override%20this%20set%20later%20if%20the%20policy%20dictates%20that%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20the%20expiry%20should%20be%20changed.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'cookieSetter'%20is%20possibly%20'undefined'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookieSetter.call(this,%20argValue);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20wait%20for%20config%20before%20doing%20same-site%20tests%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loadPolicyThen(()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20shouldBlock,%20policy,%20trackerPolicy%20%7D%20=%20cookiePolicy;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20stack%20=%20getStack();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20scriptOrigins%20=%20getStackTraceOrigins(stack);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20chosenPolicy%20=%20isFirstPartyTrackerScript(scriptOrigins)%20?%20trackerPolicy%20:%20policy;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!shouldBlock)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debugHelper('ignore',%20'disabled',%20setCookieContext);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20extract%20cookie%20expiry%20from%20cookie%20string%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20cookie%20=%20new%20Cookie(value);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20apply%20cookie%20policy%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(cookie.getExpiry()%20%3E%20chosenPolicy.threshold)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20check%20if%20the%20cookie%20still%20exists%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(document.cookie.split(';').findIndex((kv)%20=%3E%20kv.trim().startsWith(cookie.parts%5B0%5D.trim()))%20!==%20-1)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookie.maxAge%20=%20chosenPolicy.maxAge;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debugHelper('restrict',%20'expiry',%20setCookieContext);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'cookieSetter'%20is%20possibly%20'undefined'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookieSetter.apply(document,%20%5Bcookie.toString()%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debugHelper('ignore',%20'dissappeared',%20setCookieContext);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debugHelper('ignore',%20'expiry',%20setCookieContext);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debugHelper('ignore',%20'error',%20setCookieContext);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20suppress%20error%20in%20cookie%20override%20to%20avoid%20breakage%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.warn('Error%20in%20cookie%20override',%20e);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Document.prototype,%20'cookie',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20set:%20setCookiePolicy,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20getCookiePolicy,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20init(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20restOfPolicy%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20debug:%20this.isDebug,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20shouldBlockTrackerCookie:%20this.getFeatureSettingEnabled('trackerCookie'),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20shouldBlockNonTrackerCookie:%20this.getFeatureSettingEnabled('nonTrackerCookie'),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20allowlist:%20this.getFeatureSetting('allowlist',%20'adClickAttribution')%20%7C%7C%20%5B%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20policy:%20this.getFeatureSetting('firstPartyCookiePolicy'),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20trackerPolicy:%20this.getFeatureSetting('firstPartyTrackerCookiePolicy'),%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20The%20extension%20provides%20some%20additional%20info%20about%20the%20cookie%20policy,%20let's%20use%20that%20over%20our%20guesses%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(args.cookie)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20extensionCookiePolicy%20=%20/**%20@type%20%7BExtensionCookiePolicy%7D%20*/%20(args.cookie);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookiePolicy%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20...extensionCookiePolicy,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20...restOfPolicy,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20copy%20non-null%20entries%20from%20restOfPolicy%20to%20cookiePolicy%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Object.keys(restOfPolicy).forEach((key)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(restOfPolicy%5Bkey%5D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cookiePolicy%5Bkey%5D%20=%20restOfPolicy%5Bkey%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20loadedPolicyResolve();%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20@ts-nocheck%0A%20%20%20%20const%20sjcl%20=%20(()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20/*jslint%20indent:%202,%20bitwise:%20false,%20nomen:%20false,%20plusplus:%20false,%20white:%20false,%20regexp:%20false%20*/%0A%20%20%20%20%20%20%20%20/*global%20document,%20window,%20escape,%20unescape,%20module,%20require,%20Uint32Array%20*/%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20The%20Stanford%20Javascript%20Crypto%20Library,%20top-level%20namespace.%0A%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20var%20sjcl%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Symmetric%20ciphers.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20cipher:%20%7B%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Hash%20functions.%20%20Right%20now%20only%20SHA256%20is%20implemented.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20hash:%20%7B%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Key%20exchange%20functions.%20%20Right%20now%20only%20SRP%20is%20implemented.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20keyexchange:%20%7B%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Cipher%20modes%20of%20operation.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20mode:%20%7B%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Miscellaneous.%20%20HMAC%20and%20PBKDF2.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20misc:%20%7B%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Bit%20array%20encoders%20and%20decoders.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@description%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20members%20of%20this%20namespace%20are%20functions%20which%20translate%20between%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20SJCL's%20bitArrays%20and%20other%20objects%20(usually%20strings).%20%20Because%20it%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20isn't%20always%20clear%20which%20direction%20is%20encoding%20and%20which%20is%20decoding,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20the%20method%20names%20are%20%22fromBits%22%20and%20%22toBits%22.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20codec:%20%7B%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Exceptions.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20exception:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Ciphertext%20is%20corrupt.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@constructor%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20corrupt:%20function%20(message)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.toString%20=%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20'CORRUPT:%20'%20+%20this.message;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.message%20=%20message;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Invalid%20parameter.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@constructor%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20invalid:%20function%20(message)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.toString%20=%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20'INVALID:%20'%20+%20this.message;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.message%20=%20message;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Bug%20or%20missing%20feature%20in%20SJCL.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@constructor%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20bug:%20function%20(message)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.toString%20=%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20'BUG:%20'%20+%20this.message;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.message%20=%20message;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Something%20isn't%20ready.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@constructor%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20notReady:%20function%20(message)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.toString%20=%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20'NOT%20READY:%20'%20+%20this.message;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.message%20=%20message;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20/**%20@fileOverview%20Arrays%20of%20bits,%20encoded%20as%20arrays%20of%20Numbers.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@author%20Emily%20Stark%0A%20%20%20%20%20%20%20%20%20*%20@author%20Mike%20Hamburg%0A%20%20%20%20%20%20%20%20%20*%20@author%20Dan%20Boneh%0A%20%20%20%20%20%20%20%20%20*/%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Arrays%20of%20bits,%20encoded%20as%20arrays%20of%20Numbers.%0A%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20*%20@description%0A%20%20%20%20%20%20%20%20%20*%20%3Cp%3E%0A%20%20%20%20%20%20%20%20%20*%20These%20objects%20are%20the%20currency%20accepted%20by%20SJCL's%20crypto%20functions.%0A%20%20%20%20%20%20%20%20%20*%20%3C/p%3E%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20%3Cp%3E%0A%20%20%20%20%20%20%20%20%20*%20Most%20of%20our%20crypto%20primitives%20operate%20on%20arrays%20of%204-byte%20words%20internally,%0A%20%20%20%20%20%20%20%20%20*%20but%20many%20of%20them%20can%20take%20arguments%20that%20are%20not%20a%20multiple%20of%204%20bytes.%0A%20%20%20%20%20%20%20%20%20*%20This%20library%20encodes%20arrays%20of%20bits%20(whose%20size%20need%20not%20be%20a%20multiple%20of%208%0A%20%20%20%20%20%20%20%20%20*%20bits)%20as%20arrays%20of%2032-bit%20words.%20%20The%20bits%20are%20packed,%20big-endian,%20into%20an%0A%20%20%20%20%20%20%20%20%20*%20array%20of%20words,%2032%20bits%20at%20a%20time.%20%20Since%20the%20words%20are%20double-precision%0A%20%20%20%20%20%20%20%20%20*%20floating%20point%20numbers,%20they%20fit%20some%20extra%20data.%20%20We%20use%20this%20(in%20a%20private,%0A%20%20%20%20%20%20%20%20%20*%20possibly-changing%20manner)%20to%20encode%20the%20number%20of%20bits%20actually%20%20present%0A%20%20%20%20%20%20%20%20%20*%20in%20the%20last%20word%20of%20the%20array.%0A%20%20%20%20%20%20%20%20%20*%20%3C/p%3E%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20%3Cp%3E%0A%20%20%20%20%20%20%20%20%20*%20Because%20bitwise%20ops%20clear%20this%20out-of-band%20data,%20these%20arrays%20can%20be%20passed%0A%20%20%20%20%20%20%20%20%20*%20to%20ciphers%20like%20AES%20which%20want%20arrays%20of%20words.%0A%20%20%20%20%20%20%20%20%20*%20%3C/p%3E%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20sjcl.bitArray%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Array%20slices%20in%20units%20of%20bits.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20a%20The%20array%20to%20slice.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20bstart%20The%20offset%20to%20the%20start%20of%20the%20slice,%20in%20bits.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20bend%20The%20offset%20to%20the%20end%20of%20the%20slice,%20in%20bits.%20%20If%20this%20is%20undefined,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20slice%20until%20the%20end%20of%20the%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7BbitArray%7D%20The%20requested%20slice.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20bitSlice:%20function%20(a,%20bstart,%20bend)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%20=%20sjcl.bitArray._shiftRight(a.slice(bstart%20/%2032),%2032%20-%20(bstart%20&%2031)).slice(1);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20bend%20===%20undefined%20?%20a%20:%20sjcl.bitArray.clamp(a,%20bend%20-%20bstart);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Extract%20a%20number%20packed%20into%20a%20bit%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20a%20The%20array%20to%20slice.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20bstart%20The%20offset%20to%20the%20start%20of%20the%20slice,%20in%20bits.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20blength%20The%20length%20of%20the%20number%20to%20extract.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7BNumber%7D%20The%20requested%20slice.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20extract:%20function%20(a,%20bstart,%20blength)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20FIXME:%20this%20Math.floor%20is%20not%20necessary%20at%20all,%20but%20for%20some%20reason%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20seems%20to%20suppress%20a%20bug%20in%20the%20Chromium%20JIT.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20x,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sh%20=%20Math.floor((-bstart%20-%20blength)%20&%2031);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(((bstart%20+%20blength%20-%201)%20%5E%20bstart)%20&%20-32)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20it%20crosses%20a%20boundary%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%20=%20(a%5B(bstart%20/%2032)%20%7C%200%5D%20%3C%3C%20(32%20-%20sh))%20%5E%20(a%5B(bstart%20/%2032%20+%201)%20%7C%200%5D%20%3E%3E%3E%20sh);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20within%20a%20single%20word%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%20=%20a%5B(bstart%20/%2032)%20%7C%200%5D%20%3E%3E%3E%20sh;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20x%20&%20((1%20%3C%3C%20blength)%20-%201);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Concatenate%20two%20bit%20arrays.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20a1%20The%20first%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20a2%20The%20second%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7BbitArray%7D%20The%20concatenation%20of%20a1%20and%20a2.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20concat:%20function%20(a1,%20a2)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(a1.length%20===%200%20%7C%7C%20a2.length%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20a1.concat(a2);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20last%20=%20a1%5Ba1.length%20-%201%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20shift%20=%20sjcl.bitArray.getPartial(last);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(shift%20===%2032)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20a1.concat(a2);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20sjcl.bitArray._shiftRight(a2,%20shift,%20last%20%7C%200,%20a1.slice(0,%20a1.length%20-%201));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Find%20the%20length%20of%20an%20array%20of%20bits.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20a%20The%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7BNumber%7D%20The%20length%20of%20a,%20in%20bits.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20bitLength:%20function%20(a)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20l%20=%20a.length,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(l%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%20=%20a%5Bl%20-%201%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20(l%20-%201)%20*%2032%20+%20sjcl.bitArray.getPartial(x);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Truncate%20an%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20a%20The%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20len%20The%20length%20to%20truncate%20to,%20in%20bits.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7BbitArray%7D%20A%20new%20array,%20truncated%20to%20len%20bits.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20clamp:%20function%20(a,%20len)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(a.length%20*%2032%20%3C%20len)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20a;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%20=%20a.slice(0,%20Math.ceil(len%20/%2032));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20l%20=%20a.length;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20len%20=%20len%20&%2031;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(l%20%3E%200%20&&%20len)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%5Bl%20-%201%5D%20=%20sjcl.bitArray.partial(len,%20a%5Bl%20-%201%5D%20&%20(0x80000000%20%3E%3E%20(len%20-%201)),%201);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20a;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Make%20a%20partial%20word%20for%20a%20bit%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20len%20The%20number%20of%20bits%20in%20the%20word.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20x%20The%20bits.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20%5B_end=0%5D%20Pass%201%20if%20x%20has%20already%20been%20shifted%20to%20the%20high%20side.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7BNumber%7D%20The%20partial%20word.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20partial:%20function%20(len,%20x,%20_end)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(len%20===%2032)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20x;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20(_end%20?%20x%20%7C%200%20:%20x%20%3C%3C%20(32%20-%20len))%20+%20len%20*%200x10000000000;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Get%20the%20number%20of%20bits%20used%20by%20a%20partial%20word.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20x%20The%20partial%20word.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7BNumber%7D%20The%20number%20of%20bits%20used%20by%20the%20partial%20word.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20getPartial:%20function%20(x)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20Math.round(x%20/%200x10000000000)%20%7C%7C%2032;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Compare%20two%20arrays%20for%20equality%20in%20a%20predictable%20amount%20of%20time.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20a%20The%20first%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20b%20The%20second%20array.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7Bboolean%7D%20true%20if%20a%20==%20b;%20false%20otherwise.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20equal:%20function%20(a,%20b)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(sjcl.bitArray.bitLength(a)%20!==%20sjcl.bitArray.bitLength(b))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20x%20=%200,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20i;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%200;%20i%20%3C%20a.length;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%20%7C=%20a%5Bi%5D%20%5E%20b%5Bi%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20x%20===%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20Shift%20an%20array%20right.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20a%20The%20array%20to%20shift.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20shift%20The%20number%20of%20bits%20to%20shift.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BNumber%7D%20%5Bcarry=0%5D%20A%20byte%20to%20carry%20in%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20%5Bout=%5B%5D%5D%20An%20array%20to%20prepend%20to%20the%20output.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@private%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20_shiftRight:%20function%20(a,%20shift,%20carry,%20out)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20i,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20last2%20=%200,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20shift2;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(out%20===%20undefined)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(;%20shift%20%3E=%2032;%20shift%20-=%2032)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out.push(carry);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20carry%20=%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(shift%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20out.concat(a);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%200;%20i%20%3C%20a.length;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out.push(carry%20%7C%20(a%5Bi%5D%20%3E%3E%3E%20shift));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20carry%20=%20a%5Bi%5D%20%3C%3C%20(32%20-%20shift);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20last2%20=%20a.length%20?%20a%5Ba.length%20-%201%5D%20:%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20shift2%20=%20sjcl.bitArray.getPartial(last2);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out.push(sjcl.bitArray.partial((shift%20+%20shift2)%20&%2031,%20shift%20+%20shift2%20%3E%2032%20?%20carry%20:%20out.pop(),%201));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20out;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20xor%20a%20block%20of%204%20words%20together.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@private%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20_xor4:%20function%20(x,%20y)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%5Bx%5B0%5D%20%5E%20y%5B0%5D,%20x%5B1%5D%20%5E%20y%5B1%5D,%20x%5B2%5D%20%5E%20y%5B2%5D,%20x%5B3%5D%20%5E%20y%5B3%5D%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20byteswap%20a%20word%20array%20inplace.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20(does%20not%20handle%20partial%20words)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7Bsjcl.bitArray%7D%20a%20word%20array%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7Bsjcl.bitArray%7D%20byteswapped%20array%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20byteswapM:%20function%20(a)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20i,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20m%20=%200xff00;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%200;%20i%20%3C%20a.length;%20++i)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v%20=%20a%5Bi%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%5Bi%5D%20=%20(v%20%3E%3E%3E%2024)%20%7C%20((v%20%3E%3E%3E%208)%20&%20m)%20%7C%20((v%20&%20m)%20%3C%3C%208)%20%7C%20(v%20%3C%3C%2024);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20a;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20/**%20@fileOverview%20Bit%20array%20codec%20implementations.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@author%20Emily%20Stark%0A%20%20%20%20%20%20%20%20%20*%20@author%20Mike%20Hamburg%0A%20%20%20%20%20%20%20%20%20*%20@author%20Dan%20Boneh%0A%20%20%20%20%20%20%20%20%20*/%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20UTF-8%20strings%0A%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20sjcl.codec.utf8String%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20Convert%20from%20a%20bitArray%20to%20a%20UTF-8%20string.%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20fromBits:%20function%20(arr)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20out%20=%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20bl%20=%20sjcl.bitArray.bitLength(arr),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20i,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%200;%20i%20%3C%20bl%20/%208;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20((i%20&%203)%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp%20=%20arr%5Bi%20/%204%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out%20+=%20String.fromCharCode(((tmp%20%3E%3E%3E%208)%20%3E%3E%3E%208)%20%3E%3E%3E%208);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp%20%3C%3C=%208;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20decodeURIComponent(escape(out));%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20Convert%20from%20a%20UTF-8%20string%20to%20a%20bitArray.%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20toBits:%20function%20(str)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20str%20=%20unescape(encodeURIComponent(str));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20out%20=%20%5B%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20i,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp%20=%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%200;%20i%20%3C%20str.length;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp%20=%20(tmp%20%3C%3C%208)%20%7C%20str.charCodeAt(i);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20((i%20&%203)%20===%203)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out.push(tmp);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp%20=%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(i%20&%203)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out.push(sjcl.bitArray.partial(8%20*%20(i%20&%203),%20tmp));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20out;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20/**%20@fileOverview%20Bit%20array%20codec%20implementations.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@author%20Emily%20Stark%0A%20%20%20%20%20%20%20%20%20*%20@author%20Mike%20Hamburg%0A%20%20%20%20%20%20%20%20%20*%20@author%20Dan%20Boneh%0A%20%20%20%20%20%20%20%20%20*/%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Hexadecimal%0A%20%20%20%20%20%20%20%20%20*%20@namespace%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20sjcl.codec.hex%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20Convert%20from%20a%20bitArray%20to%20a%20hex%20string.%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20fromBits:%20function%20(arr)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20out%20=%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20i;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%200;%20i%20%3C%20arr.length;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out%20+=%20((arr%5Bi%5D%20%7C%200)%20+%200xf00000000000).toString(16).substr(4);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20out.substr(0,%20sjcl.bitArray.bitLength(arr)%20/%204);%20//.replace(/(.%7B8%7D)/g,%20%22$1%20%22);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20Convert%20from%20a%20hex%20string%20to%20a%20bitArray.%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20toBits:%20function%20(str)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20i,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out%20=%20%5B%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20len;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20str%20=%20str.replace(/%5Cs%7C0x/g,%20'');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20len%20=%20str.length;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20str%20=%20str%20+%20'00000000';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%200;%20i%20%3C%20str.length;%20i%20+=%208)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out.push(parseInt(str.substr(i,%208),%2016)%20%5E%200);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20sjcl.bitArray.clamp(out,%20len%20*%204);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%20@fileOverview%20Javascript%20SHA-256%20implementation.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20An%20older%20version%20of%20this%20implementation%20is%20available%20in%20the%20public%0A%20%20%20%20%20%20%20%20%20*%20domain,%20but%20this%20one%20is%20(c)%20Emily%20Stark,%20Mike%20Hamburg,%20Dan%20Boneh,%0A%20%20%20%20%20%20%20%20%20*%20Stanford%20University%202008-2010%20and%20BSD-licensed%20for%20liability%0A%20%20%20%20%20%20%20%20%20*%20reasons.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20Special%20thanks%20to%20Aldo%20Cortesi%20for%20pointing%20out%20several%20bugs%20in%0A%20%20%20%20%20%20%20%20%20*%20this%20code.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@author%20Emily%20Stark%0A%20%20%20%20%20%20%20%20%20*%20@author%20Mike%20Hamburg%0A%20%20%20%20%20%20%20%20%20*%20@author%20Dan%20Boneh%0A%20%20%20%20%20%20%20%20%20*/%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Context%20for%20a%20SHA-256%20operation%20in%20progress.%0A%20%20%20%20%20%20%20%20%20*%20@constructor%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20sjcl.hash.sha256%20=%20function%20(hash)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this._key%5B0%5D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._precompute();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(hash)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._h%20=%20hash._h.slice(0);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._buffer%20=%20hash._buffer.slice(0);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._length%20=%20hash._length;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.reset();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Hash%20a%20string%20or%20an%20array%20of%20words.%0A%20%20%20%20%20%20%20%20%20*%20@static%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7CString%7D%20data%20the%20data%20to%20hash.%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7BbitArray%7D%20The%20hash%20value,%20an%20array%20of%2016%20big-endian%20words.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20sjcl.hash.sha256.hash%20=%20function%20(data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20sjcl.hash.sha256().update(data).finalize();%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20sjcl.hash.sha256.prototype%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20hash's%20block%20size,%20in%20bits.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@constant%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20blockSize:%20512,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Reset%20the%20hash%20state.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20this%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20reset:%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._h%20=%20this._init.slice(0);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._buffer%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._length%20=%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Input%20several%20words%20to%20the%20hash.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7CString%7D%20data%20the%20data%20to%20hash.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20this%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20update:%20function%20(data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20data%20===%20'string')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20data%20=%20sjcl.codec.utf8String.toBits(data);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20i,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b%20=%20(this._buffer%20=%20sjcl.bitArray.concat(this._buffer,%20data)),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ol%20=%20this._length,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20nl%20=%20(this._length%20=%20ol%20+%20sjcl.bitArray.bitLength(data));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(nl%20%3E%209007199254740991)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20sjcl.exception.invalid('Cannot%20hash%20more%20than%202%5E53%20-%201%20bits');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20Uint32Array%20!==%20'undefined')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20c%20=%20new%20Uint32Array(b);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20j%20=%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%20512%20+%20ol%20-%20((512%20+%20ol)%20&%20511);%20i%20%3C=%20nl;%20i%20+=%20512)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._block(c.subarray(16%20*%20j,%2016%20*%20(j%20+%201)));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20j%20+=%201;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b.splice(0,%2016%20*%20j);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%20512%20+%20ol%20-%20((512%20+%20ol)%20&%20511);%20i%20%3C=%20nl;%20i%20+=%20512)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._block(b.splice(0,%2016));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Complete%20hashing%20and%20output%20the%20hash%20value.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7BbitArray%7D%20The%20hash%20value,%20an%20array%20of%208%20big-endian%20words.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20finalize:%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20i,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b%20=%20this._buffer,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%20=%20this._h;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Round%20out%20and%20push%20the%20buffer%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b%20=%20sjcl.bitArray.concat(b,%20%5Bsjcl.bitArray.partial(1,%201)%5D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Round%20out%20the%20buffer%20to%20a%20multiple%20of%2016%20words,%20less%20the%202%20length%20words.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%20b.length%20+%202;%20i%20&%2015;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b.push(0);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20append%20the%20length%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b.push(Math.floor(this._length%20/%200x100000000));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b.push(this._length%20%7C%200);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20while%20(b.length)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._block(b.splice(0,%2016));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.reset();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20h;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20SHA-256%20initialization%20vector,%20to%20be%20precomputed.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@private%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20_init:%20%5B%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20/*%0A%20%20%20%20%20%20_init:%5B0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19%5D,%0A%20%20%20%20%20%20*/%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20SHA-256%20hash%20key,%20to%20be%20precomputed.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@private%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20_key:%20%5B%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20/*%0A%20%20%20%20%20%20_key:%0A%20%20%20%20%20%20%20%20%5B0x428a2f98,%200x71374491,%200xb5c0fbcf,%200xe9b5dba5,%200x3956c25b,%200x59f111f1,%200x923f82a4,%200xab1c5ed5,%0A%20%20%20%20%20%20%20%20%200xd807aa98,%200x12835b01,%200x243185be,%200x550c7dc3,%200x72be5d74,%200x80deb1fe,%200x9bdc06a7,%200xc19bf174,%0A%20%20%20%20%20%20%20%20%200xe49b69c1,%200xefbe4786,%200x0fc19dc6,%200x240ca1cc,%200x2de92c6f,%200x4a7484aa,%200x5cb0a9dc,%200x76f988da,%0A%20%20%20%20%20%20%20%20%200x983e5152,%200xa831c66d,%200xb00327c8,%200xbf597fc7,%200xc6e00bf3,%200xd5a79147,%200x06ca6351,%200x14292967,%0A%20%20%20%20%20%20%20%20%200x27b70a85,%200x2e1b2138,%200x4d2c6dfc,%200x53380d13,%200x650a7354,%200x766a0abb,%200x81c2c92e,%200x92722c85,%0A%20%20%20%20%20%20%20%20%200xa2bfe8a1,%200xa81a664b,%200xc24b8b70,%200xc76c51a3,%200xd192e819,%200xd6990624,%200xf40e3585,%200x106aa070,%0A%20%20%20%20%20%20%20%20%200x19a4c116,%200x1e376c08,%200x2748774c,%200x34b0bcb5,%200x391c0cb3,%200x4ed8aa4a,%200x5b9cca4f,%200x682e6ff3,%0A%20%20%20%20%20%20%20%20%200x748f82ee,%200x78a5636f,%200x84c87814,%200x8cc70208,%200x90befffa,%200xa4506ceb,%200xbef9a3f7,%200xc67178f2%5D,%0A%20%20%20%20%20%20*/%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Function%20to%20precompute%20_init%20and%20_key.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@private%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20_precompute:%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20i%20=%200,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20prime%20=%202,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20factor,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20isPrime;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20function%20frac(x)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20((x%20-%20Math.floor(x))%20*%200x100000000)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(;%20i%20%3C%2064;%20prime++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20isPrime%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(factor%20=%202;%20factor%20*%20factor%20%3C=%20prime;%20factor++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(prime%20%25%20factor%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20isPrime%20=%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(isPrime)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(i%20%3C%208)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._init%5Bi%5D%20=%20frac(Math.pow(prime,%201%20/%202));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._key%5Bi%5D%20=%20frac(Math.pow(prime,%201%20/%203));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20i++;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Perform%20one%20cycle%20of%20SHA-256.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BUint32Array%7CbitArray%7D%20w%20one%20block%20of%20words.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@private%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20_block:%20function%20(w)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20i,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%20=%20this._h,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20k%20=%20this._key,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h0%20=%20h%5B0%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h1%20=%20h%5B1%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h2%20=%20h%5B2%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h3%20=%20h%5B3%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h4%20=%20h%5B4%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h5%20=%20h%5B5%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h6%20=%20h%5B6%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h7%20=%20h%5B7%5D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/*%20Rationale%20for%20placement%20of%20%7C0%20:%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20If%20a%20value%20can%20overflow%20is%20original%2032%20bits%20by%20a%20factor%20of%20more%20than%20a%20few%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20million%20(2%5E23%20ish),%20there%20is%20a%20possibility%20that%20it%20might%20overflow%20the%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%2053-bit%20mantissa%20and%20lose%20precision.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20To%20avoid%20this,%20we%20clamp%20back%20to%2032%20bits%20by%20%7C'ing%20with%200%20on%20any%20value%20that%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20propagates%20around%20the%20loop,%20and%20on%20the%20hash%20state%20h%5B%5D.%20%20I%20don't%20believe%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20that%20the%20clamps%20on%20h4%20and%20on%20h0%20are%20strictly%20necessary,%20but%20it's%20close%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20(for%20h4%20anyway),%20and%20better%20safe%20than%20sorry.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20The%20clamps%20on%20h%5B%5D%20are%20necessary%20for%20the%20output%20to%20be%20correct%20even%20in%20the%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20common%20case%20and%20for%20short%20inputs.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%200;%20i%20%3C%2064;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20load%20up%20the%20input%20word%20for%20this%20round%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(i%20%3C%2016)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp%20=%20w%5Bi%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%20=%20w%5B(i%20+%201)%20&%2015%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b%20=%20w%5B(i%20+%2014)%20&%2015%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp%20=%20w%5Bi%20&%2015%5D%20=%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(((a%20%3E%3E%3E%207)%20%5E%20(a%20%3E%3E%3E%2018)%20%5E%20(a%20%3E%3E%3E%203)%20%5E%20(a%20%3C%3C%2025)%20%5E%20(a%20%3C%3C%2014))%20+%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20((b%20%3E%3E%3E%2017)%20%5E%20(b%20%3E%3E%3E%2019)%20%5E%20(b%20%3E%3E%3E%2010)%20%5E%20(b%20%3C%3C%2015)%20%5E%20(b%20%3C%3C%2013))%20+%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20w%5Bi%20&%2015%5D%20+%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20w%5B(i%20+%209)%20&%2015%5D)%20%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp%20=%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tmp%20+%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h7%20+%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20((h4%20%3E%3E%3E%206)%20%5E%20(h4%20%3E%3E%3E%2011)%20%5E%20(h4%20%3E%3E%3E%2025)%20%5E%20(h4%20%3C%3C%2026)%20%5E%20(h4%20%3C%3C%2021)%20%5E%20(h4%20%3C%3C%207))%20+%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(h6%20%5E%20(h4%20&%20(h5%20%5E%20h6)))%20+%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20k%5Bi%5D;%20//%20%7C%200;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20shift%20register%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h7%20=%20h6;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h6%20=%20h5;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h5%20=%20h4;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h4%20=%20(h3%20+%20tmp)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h3%20=%20h2;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h2%20=%20h1;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h1%20=%20h0;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h0%20=%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(tmp%20+%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20((h1%20&%20h2)%20%5E%20(h3%20&%20(h1%20%5E%20h2)))%20+%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20((h1%20%3E%3E%3E%202)%20%5E%20(h1%20%3E%3E%3E%2013)%20%5E%20(h1%20%3E%3E%3E%2022)%20%5E%20(h1%20%3C%3C%2030)%20%5E%20(h1%20%3C%3C%2019)%20%5E%20(h1%20%3C%3C%2010)))%20%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%5B0%5D%20=%20(h%5B0%5D%20+%20h0)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%5B1%5D%20=%20(h%5B1%5D%20+%20h1)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%5B2%5D%20=%20(h%5B2%5D%20+%20h2)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%5B3%5D%20=%20(h%5B3%5D%20+%20h3)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%5B4%5D%20=%20(h%5B4%5D%20+%20h4)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%5B5%5D%20=%20(h%5B5%5D%20+%20h5)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%5B6%5D%20=%20(h%5B6%5D%20+%20h6)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%5B7%5D%20=%20(h%5B7%5D%20+%20h7)%20%7C%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%20@fileOverview%20HMAC%20implementation.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@author%20Emily%20Stark%0A%20%20%20%20%20%20%20%20%20*%20@author%20Mike%20Hamburg%0A%20%20%20%20%20%20%20%20%20*%20@author%20Dan%20Boneh%0A%20%20%20%20%20%20%20%20%20*/%0A%0A%20%20%20%20%20%20%20%20/**%20HMAC%20with%20the%20specified%20hash%20function.%0A%20%20%20%20%20%20%20%20%20*%20@constructor%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7D%20key%20the%20key%20for%20HMAC.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BObject%7D%20%5BHash=sjcl.hash.sha256%5D%20The%20hash%20function%20to%20use.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20sjcl.misc.hmac%20=%20function%20(key,%20Hash)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this._hash%20=%20Hash%20=%20Hash%20%7C%7C%20sjcl.hash.sha256;%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20exKey%20=%20%5B%5B%5D,%20%5B%5D%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20i,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20bs%20=%20Hash.prototype.blockSize%20/%2032;%0A%20%20%20%20%20%20%20%20%20%20%20%20this._baseHash%20=%20%5Bnew%20Hash(),%20new%20Hash()%5D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(key.length%20%3E%20bs)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20key%20=%20Hash.hash(key);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(i%20=%200;%20i%20%3C%20bs;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20exKey%5B0%5D%5Bi%5D%20=%20key%5Bi%5D%20%5E%200x36363636;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20exKey%5B1%5D%5Bi%5D%20=%20key%5Bi%5D%20%5E%200x5c5c5c5c;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this._baseHash%5B0%5D.update(exKey%5B0%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20this._baseHash%5B1%5D.update(exKey%5B1%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20this._resultHash%20=%20new%20Hash(this._baseHash%5B0%5D);%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%20HMAC%20with%20the%20specified%20hash%20function.%20%20Also%20called%20encrypt%20since%20it's%20a%20prf.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BbitArray%7CString%7D%20data%20The%20data%20to%20mac.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20sjcl.misc.hmac.prototype.encrypt%20=%20sjcl.misc.hmac.prototype.mac%20=%20function%20(data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this._updated)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.update(data);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this.digest(data);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20sjcl.exception.invalid('encrypt%20on%20already%20updated%20hmac%20called!');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20sjcl.misc.hmac.prototype.reset%20=%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this._resultHash%20=%20new%20this._hash(this._baseHash%5B0%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20this._updated%20=%20false;%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20sjcl.misc.hmac.prototype.update%20=%20function%20(data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this._updated%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20this._resultHash.update(data);%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20sjcl.misc.hmac.prototype.digest%20=%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20w%20=%20this._resultHash.finalize(),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result%20=%20new%20this._hash(this._baseHash%5B1%5D).update(w).finalize();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.reset();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20result;%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20return%20sjcl;%0A%20%20%20%20%7D)();%0A%0A%20%20%20%20function%20getDataKeySync(sessionKey,%20domainKey,%20inputData)%20%7B%0A%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20new-cap%0A%20%20%20%20%20%20%20%20const%20hmac%20=%20new%20sjcl.misc.hmac(sjcl.codec.utf8String.toBits(sessionKey%20+%20domainKey),%20sjcl.hash.sha256);%0A%20%20%20%20%20%20%20%20return%20sjcl.codec.hex.fromBits(hmac.encrypt(inputData));%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20FingerprintingAudio%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20sessionKey,%20site%20%7D%20=%20args;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20domainKey%20=%20site.domain;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20In%20place%20modify%20array%20data%20to%20remove%20fingerprinting%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20transformArrayData(channelData,%20domainKey,%20sessionKey,%20thisArg)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20%7B%20audioKey%20%7D%20=%20getCachedResponse(thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!audioKey)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20cdSum%20=%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20k%20in%20channelData)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cdSum%20+=%20channelData%5Bk%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20the%20buffer%20is%20blank,%20skip%20adding%20data%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(cdSum%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20audioKey%20=%20getDataKeySync(sessionKey,%20domainKey,%20cdSum);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20setCache(thisArg,%20args,%20audioKey);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20iterateDataKey(audioKey,%20(item,%20byte)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20itemAudioIndex%20=%20item%20%25%20channelData.length;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20factor%20=%20byte%20*%200.0000001;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(byte%20%5E%200x1)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20factor%20=%200%20-%20factor;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20channelData%5BitemAudioIndex%5D%20=%20channelData%5BitemAudioIndex%5D%20+%20factor;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20copyFromChannelProxy%20=%20new%20DDGProxy(this,%20AudioBuffer.prototype,%20'copyFromChannel',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%5Bsource,%20channelNumber,%20startInChannel%5D%20=%20args;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20This%20is%20implemented%20in%20a%20different%20way%20to%20canvas%20purely%20because%20calling%20the%20function%20copied%20the%20original%20value,%20which%20is%20not%20ideal%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20channelNumber%20is%20longer%20than%20arrayBuffer%20number%20of%20channels%20then%20call%20the%20default%20method%20to%20throw%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20channelNumber%20%3E%20thisArg.numberOfChannels%20%7C%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20startInChannel%20is%20longer%20than%20the%20arrayBuffer%20length%20then%20call%20the%20default%20method%20to%20throw%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20startInChannel%20%3E%20thisArg.length%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20The%20normal%20return%20value%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Call%20the%20protected%20getChannelData%20we%20implement,%20slice%20from%20the%20startInChannel%20value%20and%20assign%20to%20the%20source%20array%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20thisArg%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.getChannelData(channelNumber)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.slice(startInChannel)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.forEach((val,%20index)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20source%5Bindex%5D%20=%20val;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20copyFromChannelProxy.overload();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cacheExpiry%20=%2060;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cacheData%20=%20new%20WeakMap();%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20getCachedResponse(thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20data%20=%20cacheData.get(thisArg);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20timeNow%20=%20Date.now();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(data%20&&%20data.args%20===%20JSON.stringify(args)%20&&%20data.expires%20%3E%20timeNow)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20data.expires%20=%20timeNow%20+%20cacheExpiry;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cacheData.set(thisArg,%20data);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20data;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%20audioKey:%20null%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20setCache(thisArg,%20args,%20audioKey)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cacheData.set(thisArg,%20%7B%20args:%20JSON.stringify(args),%20expires:%20Date.now()%20+%20cacheExpiry,%20audioKey%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20getChannelDataProxy%20=%20new%20DDGProxy(this,%20AudioBuffer.prototype,%20'getChannelData',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20The%20normal%20return%20value%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20channelData%20=%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Anything%20we%20do%20here%20should%20be%20caught%20and%20ignored%20silently%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20transformArrayData(channelData,%20domainKey,%20sessionKey,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20%7B%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20channelData;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20getChannelDataProxy.overload();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20audioMethods%20=%20%5B'getByteTimeDomainData',%20'getFloatTimeDomainData',%20'getByteFrequencyData',%20'getFloatFrequencyData'%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20methodName%20of%20audioMethods)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20proxy%20=%20new%20DDGProxy(this,%20AnalyserNode.prototype,%20methodName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Anything%20we%20do%20here%20should%20be%20caught%20and%20ignored%20silently%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20transformArrayData(args%5B0%5D,%20domainKey,%20sessionKey,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20%7B%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20proxy.overload();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Overwrites%20the%20Battery%20API%20if%20present%20in%20the%20browser.%0A%20%20%20%20%20*%20It%20will%20return%20the%20values%20defined%20in%20the%20getBattery%20function%20to%20the%20client,%0A%20%20%20%20%20*%20as%20well%20as%20prevent%20any%20script%20from%20listening%20to%20events.%0A%20%20%20%20%20*/%0A%20%20%20%20class%20FingerprintingBattery%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(globalThis.navigator.getBattery)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20BatteryManager%20=%20globalThis.BatteryManager;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20spoofedValues%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20charging:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20chargingTime:%200,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20dischargingTime:%20Infinity,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20level:%201,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20eventProperties%20=%20%5B'onchargingchange',%20'onchargingtimechange',%20'ondischargingtimechange',%20'onlevelchange'%5D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20%5Bprop,%20val%5D%20of%20Object.entries(spoofedValues))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.defineProperty(BatteryManager.prototype,%20prop,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20val;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20eventProp%20of%20eventProperties)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.defineProperty(BatteryManager.prototype,%20eventProp,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20set:%20(x)%20=%3E%20x,%20//%20noop%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20getDefaultExportFromCjs%20(x)%20%7B%0A%20%20%20%20%09return%20x%20&&%20x.__esModule%20&&%20Object.prototype.hasOwnProperty.call(x,%20'default')%20?%20x%5B'default'%5D%20:%20x;%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20alea$1%20=%20%7Bexports:%20%7B%7D%7D;%0A%0A%20%20%20%20var%20alea%20=%20alea$1.exports;%0A%0A%20%20%20%20var%20hasRequiredAlea;%0A%0A%20%20%20%20function%20requireAlea%20()%20%7B%0A%20%20%20%20%09if%20(hasRequiredAlea)%20return%20alea$1.exports;%0A%20%20%20%20%09hasRequiredAlea%20=%201;%0A%20%20%20%20%09(function%20(module)%20%7B%0A%20%20%20%20%09%09//%20A%20port%20of%20an%20algorithm%20by%20Johannes%20Baag%C3%B8e%20%3Cbaagoe@baagoe.com%3E,%202010%0A%20%20%20%20%09%09//%20http://baagoe.com/en/RandomMusings/javascript/%0A%20%20%20%20%09%09//%20https://github.com/nquinlan/better-random-numbers-for-javascript-mirror%0A%20%20%20%20%09%09//%20Original%20work%20is%20under%20MIT%20license%20-%0A%0A%20%20%20%20%09%09//%20Copyright%20(C)%202010%20by%20Johannes%20Baag%C3%B8e%20%3Cbaagoe@baagoe.org%3E%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20Permission%20is%20hereby%20granted,%20free%20of%20charge,%20to%20any%20person%20obtaining%20a%20copy%0A%20%20%20%20%09%09//%20of%20this%20software%20and%20associated%20documentation%20files%20(the%20%22Software%22),%20to%20deal%0A%20%20%20%20%09%09//%20in%20the%20Software%20without%20restriction,%20including%20without%20limitation%20the%20rights%0A%20%20%20%20%09%09//%20to%20use,%20copy,%20modify,%20merge,%20publish,%20distribute,%20sublicense,%20and/or%20sell%0A%20%20%20%20%09%09//%20copies%20of%20the%20Software,%20and%20to%20permit%20persons%20to%20whom%20the%20Software%20is%0A%20%20%20%20%09%09//%20furnished%20to%20do%20so,%20subject%20to%20the%20following%20conditions:%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20The%20above%20copyright%20notice%20and%20this%20permission%20notice%20shall%20be%20included%20in%0A%20%20%20%20%09%09//%20all%20copies%20or%20substantial%20portions%20of%20the%20Software.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20THE%20SOFTWARE%20IS%20PROVIDED%20%22AS%20IS%22,%20WITHOUT%20WARRANTY%20OF%20ANY%20KIND,%20EXPRESS%20OR%0A%20%20%20%20%09%09//%20IMPLIED,%20INCLUDING%20BUT%20NOT%20LIMITED%20TO%20THE%20WARRANTIES%20OF%20MERCHANTABILITY,%0A%20%20%20%20%09%09//%20FITNESS%20FOR%20A%20PARTICULAR%20PURPOSE%20AND%20NONINFRINGEMENT.%20IN%20NO%20EVENT%20SHALL%20THE%0A%20%20%20%20%09%09//%20AUTHORS%20OR%20COPYRIGHT%20HOLDERS%20BE%20LIABLE%20FOR%20ANY%20CLAIM,%20DAMAGES%20OR%20OTHER%0A%20%20%20%20%09%09//%20LIABILITY,%20WHETHER%20IN%20AN%20ACTION%20OF%20CONTRACT,%20TORT%20OR%20OTHERWISE,%20ARISING%20FROM,%0A%20%20%20%20%09%09//%20OUT%20OF%20OR%20IN%20CONNECTION%20WITH%20THE%20SOFTWARE%20OR%20THE%20USE%20OR%20OTHER%20DEALINGS%20IN%0A%20%20%20%20%09%09//%20THE%20SOFTWARE.%0A%0A%0A%0A%20%20%20%20%09%09(function(global,%20module,%20define)%20%7B%0A%0A%20%20%20%20%09%09function%20Alea(seed)%20%7B%0A%20%20%20%20%09%09%20%20var%20me%20=%20this,%20mash%20=%20Mash();%0A%0A%20%20%20%20%09%09%20%20me.next%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20t%20=%202091639%20*%20me.s0%20+%20me.c%20*%202.3283064365386963e-10;%20//%202%5E-32%0A%20%20%20%20%09%09%20%20%20%20me.s0%20=%20me.s1;%0A%20%20%20%20%09%09%20%20%20%20me.s1%20=%20me.s2;%0A%20%20%20%20%09%09%20%20%20%20return%20me.s2%20=%20t%20-%20(me.c%20=%20t%20%7C%200);%0A%20%20%20%20%09%09%20%20%7D;%0A%0A%20%20%20%20%09%09%20%20//%20Apply%20the%20seeding%20algorithm%20from%20Baagoe.%0A%20%20%20%20%09%09%20%20me.c%20=%201;%0A%20%20%20%20%09%09%20%20me.s0%20=%20mash('%20');%0A%20%20%20%20%09%09%20%20me.s1%20=%20mash('%20');%0A%20%20%20%20%09%09%20%20me.s2%20=%20mash('%20');%0A%20%20%20%20%09%09%20%20me.s0%20-=%20mash(seed);%0A%20%20%20%20%09%09%20%20if%20(me.s0%20%3C%200)%20%7B%20me.s0%20+=%201;%20%7D%0A%20%20%20%20%09%09%20%20me.s1%20-=%20mash(seed);%0A%20%20%20%20%09%09%20%20if%20(me.s1%20%3C%200)%20%7B%20me.s1%20+=%201;%20%7D%0A%20%20%20%20%09%09%20%20me.s2%20-=%20mash(seed);%0A%20%20%20%20%09%09%20%20if%20(me.s2%20%3C%200)%20%7B%20me.s2%20+=%201;%20%7D%0A%20%20%20%20%09%09%20%20mash%20=%20null;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20copy(f,%20t)%20%7B%0A%20%20%20%20%09%09%20%20t.c%20=%20f.c;%0A%20%20%20%20%09%09%20%20t.s0%20=%20f.s0;%0A%20%20%20%20%09%09%20%20t.s1%20=%20f.s1;%0A%20%20%20%20%09%09%20%20t.s2%20=%20f.s2;%0A%20%20%20%20%09%09%20%20return%20t;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20impl(seed,%20opts)%20%7B%0A%20%20%20%20%09%09%20%20var%20xg%20=%20new%20Alea(seed),%0A%20%20%20%20%09%09%20%20%20%20%20%20state%20=%20opts%20&&%20opts.state,%0A%20%20%20%20%09%09%20%20%20%20%20%20prng%20=%20xg.next;%0A%20%20%20%20%09%09%20%20prng.int32%20=%20function()%20%7B%20return%20(xg.next()%20*%200x100000000)%20%7C%200;%20%7D;%0A%20%20%20%20%09%09%20%20prng.double%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20return%20prng()%20+%20(prng()%20*%200x200000%20%7C%200)%20*%201.1102230246251565e-16;%20//%202%5E-53%0A%20%20%20%20%09%09%20%20%7D;%0A%20%20%20%20%09%09%20%20prng.quick%20=%20prng;%0A%20%20%20%20%09%09%20%20if%20(state)%20%7B%0A%20%20%20%20%09%09%20%20%20%20if%20(typeof(state)%20==%20'object')%20copy(state,%20xg);%0A%20%20%20%20%09%09%20%20%20%20prng.state%20=%20function()%20%7B%20return%20copy(xg,%20%7B%7D);%20%7D;%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20return%20prng;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20Mash()%20%7B%0A%20%20%20%20%09%09%20%20var%20n%20=%200xefc8249d;%0A%0A%20%20%20%20%09%09%20%20var%20mash%20=%20function(data)%20%7B%0A%20%20%20%20%09%09%20%20%20%20data%20=%20String(data);%0A%20%20%20%20%09%09%20%20%20%20for%20(var%20i%20=%200;%20i%20%3C%20data.length;%20i++)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20n%20+=%20data.charCodeAt(i);%0A%20%20%20%20%09%09%20%20%20%20%20%20var%20h%20=%200.02519603282416938%20*%20n;%0A%20%20%20%20%09%09%20%20%20%20%20%20n%20=%20h%20%3E%3E%3E%200;%0A%20%20%20%20%09%09%20%20%20%20%20%20h%20-=%20n;%0A%20%20%20%20%09%09%20%20%20%20%20%20h%20*=%20n;%0A%20%20%20%20%09%09%20%20%20%20%20%20n%20=%20h%20%3E%3E%3E%200;%0A%20%20%20%20%09%09%20%20%20%20%20%20h%20-=%20n;%0A%20%20%20%20%09%09%20%20%20%20%20%20n%20+=%20h%20*%200x100000000;%20//%202%5E32%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20return%20(n%20%3E%3E%3E%200)%20*%202.3283064365386963e-10;%20//%202%5E-32%0A%20%20%20%20%09%09%20%20%7D;%0A%0A%20%20%20%20%09%09%20%20return%20mash;%0A%20%20%20%20%09%09%7D%0A%0A%0A%20%20%20%20%09%09if%20(module%20&&%20module.exports)%20%7B%0A%20%20%20%20%09%09%20%20module.exports%20=%20impl;%0A%20%20%20%20%09%09%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20this.alea%20=%20impl;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09%7D)(%0A%20%20%20%20%09%09%20%20alea,%0A%20%20%20%20%09%09%20%20module);%20%0A%20%20%20%20%09%7D%20(alea$1));%0A%20%20%20%20%09return%20alea$1.exports;%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20xor128$1%20=%20%7Bexports:%20%7B%7D%7D;%0A%0A%20%20%20%20var%20xor128%20=%20xor128$1.exports;%0A%0A%20%20%20%20var%20hasRequiredXor128;%0A%0A%20%20%20%20function%20requireXor128%20()%20%7B%0A%20%20%20%20%09if%20(hasRequiredXor128)%20return%20xor128$1.exports;%0A%20%20%20%20%09hasRequiredXor128%20=%201;%0A%20%20%20%20%09(function%20(module)%20%7B%0A%20%20%20%20%09%09//%20A%20Javascript%20implementaion%20of%20the%20%22xor128%22%20prng%20algorithm%20by%0A%20%20%20%20%09%09//%20George%20Marsaglia.%20%20See%20http://www.jstatsoft.org/v08/i14/paper%0A%0A%20%20%20%20%09%09(function(global,%20module,%20define)%20%7B%0A%0A%20%20%20%20%09%09function%20XorGen(seed)%20%7B%0A%20%20%20%20%09%09%20%20var%20me%20=%20this,%20strseed%20=%20'';%0A%0A%20%20%20%20%09%09%20%20me.x%20=%200;%0A%20%20%20%20%09%09%20%20me.y%20=%200;%0A%20%20%20%20%09%09%20%20me.z%20=%200;%0A%20%20%20%20%09%09%20%20me.w%20=%200;%0A%0A%20%20%20%20%09%09%20%20//%20Set%20up%20generator%20function.%0A%20%20%20%20%09%09%20%20me.next%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20t%20=%20me.x%20%5E%20(me.x%20%3C%3C%2011);%0A%20%20%20%20%09%09%20%20%20%20me.x%20=%20me.y;%0A%20%20%20%20%09%09%20%20%20%20me.y%20=%20me.z;%0A%20%20%20%20%09%09%20%20%20%20me.z%20=%20me.w;%0A%20%20%20%20%09%09%20%20%20%20return%20me.w%20%5E=%20(me.w%20%3E%3E%3E%2019)%20%5E%20t%20%5E%20(t%20%3E%3E%3E%208);%0A%20%20%20%20%09%09%20%20%7D;%0A%0A%20%20%20%20%09%09%20%20if%20(seed%20===%20(seed%20%7C%200))%20%7B%0A%20%20%20%20%09%09%20%20%20%20//%20Integer%20seed.%0A%20%20%20%20%09%09%20%20%20%20me.x%20=%20seed;%0A%20%20%20%20%09%09%20%20%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20%20%20//%20String%20seed.%0A%20%20%20%20%09%09%20%20%20%20strseed%20+=%20seed;%0A%20%20%20%20%09%09%20%20%7D%0A%0A%20%20%20%20%09%09%20%20//%20Mix%20in%20string%20seed,%20then%20discard%20an%20initial%20batch%20of%2064%20values.%0A%20%20%20%20%09%09%20%20for%20(var%20k%20=%200;%20k%20%3C%20strseed.length%20+%2064;%20k++)%20%7B%0A%20%20%20%20%09%09%20%20%20%20me.x%20%5E=%20strseed.charCodeAt(k)%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20me.next();%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20copy(f,%20t)%20%7B%0A%20%20%20%20%09%09%20%20t.x%20=%20f.x;%0A%20%20%20%20%09%09%20%20t.y%20=%20f.y;%0A%20%20%20%20%09%09%20%20t.z%20=%20f.z;%0A%20%20%20%20%09%09%20%20t.w%20=%20f.w;%0A%20%20%20%20%09%09%20%20return%20t;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20impl(seed,%20opts)%20%7B%0A%20%20%20%20%09%09%20%20var%20xg%20=%20new%20XorGen(seed),%0A%20%20%20%20%09%09%20%20%20%20%20%20state%20=%20opts%20&&%20opts.state,%0A%20%20%20%20%09%09%20%20%20%20%20%20prng%20=%20function()%20%7B%20return%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000;%20%7D;%0A%20%20%20%20%09%09%20%20prng.double%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20do%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20var%20top%20=%20xg.next()%20%3E%3E%3E%2011,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20bot%20=%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20result%20=%20(top%20+%20bot)%20/%20(1%20%3C%3C%2021);%0A%20%20%20%20%09%09%20%20%20%20%7D%20while%20(result%20===%200);%0A%20%20%20%20%09%09%20%20%20%20return%20result;%0A%20%20%20%20%09%09%20%20%7D;%0A%20%20%20%20%09%09%20%20prng.int32%20=%20xg.next;%0A%20%20%20%20%09%09%20%20prng.quick%20=%20prng;%0A%20%20%20%20%09%09%20%20if%20(state)%20%7B%0A%20%20%20%20%09%09%20%20%20%20if%20(typeof(state)%20==%20'object')%20copy(state,%20xg);%0A%20%20%20%20%09%09%20%20%20%20prng.state%20=%20function()%20%7B%20return%20copy(xg,%20%7B%7D);%20%7D;%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20return%20prng;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09if%20(module%20&&%20module.exports)%20%7B%0A%20%20%20%20%09%09%20%20module.exports%20=%20impl;%0A%20%20%20%20%09%09%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20this.xor128%20=%20impl;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09%7D)(%0A%20%20%20%20%09%09%20%20xor128,%0A%20%20%20%20%09%09%20%20module);%20%0A%20%20%20%20%09%7D%20(xor128$1));%0A%20%20%20%20%09return%20xor128$1.exports;%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20xorwow$1%20=%20%7Bexports:%20%7B%7D%7D;%0A%0A%20%20%20%20var%20xorwow%20=%20xorwow$1.exports;%0A%0A%20%20%20%20var%20hasRequiredXorwow;%0A%0A%20%20%20%20function%20requireXorwow%20()%20%7B%0A%20%20%20%20%09if%20(hasRequiredXorwow)%20return%20xorwow$1.exports;%0A%20%20%20%20%09hasRequiredXorwow%20=%201;%0A%20%20%20%20%09(function%20(module)%20%7B%0A%20%20%20%20%09%09//%20A%20Javascript%20implementaion%20of%20the%20%22xorwow%22%20prng%20algorithm%20by%0A%20%20%20%20%09%09//%20George%20Marsaglia.%20%20See%20http://www.jstatsoft.org/v08/i14/paper%0A%0A%20%20%20%20%09%09(function(global,%20module,%20define)%20%7B%0A%0A%20%20%20%20%09%09function%20XorGen(seed)%20%7B%0A%20%20%20%20%09%09%20%20var%20me%20=%20this,%20strseed%20=%20'';%0A%0A%20%20%20%20%09%09%20%20//%20Set%20up%20generator%20function.%0A%20%20%20%20%09%09%20%20me.next%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20t%20=%20(me.x%20%5E%20(me.x%20%3E%3E%3E%202));%0A%20%20%20%20%09%09%20%20%20%20me.x%20=%20me.y;%20me.y%20=%20me.z;%20me.z%20=%20me.w;%20me.w%20=%20me.v;%0A%20%20%20%20%09%09%20%20%20%20return%20(me.d%20=%20(me.d%20+%20362437%20%7C%200))%20+%0A%20%20%20%20%09%09%20%20%20%20%20%20%20(me.v%20=%20(me.v%20%5E%20(me.v%20%3C%3C%204))%20%5E%20(t%20%5E%20(t%20%3C%3C%201)))%20%7C%200;%0A%20%20%20%20%09%09%20%20%7D;%0A%0A%20%20%20%20%09%09%20%20me.x%20=%200;%0A%20%20%20%20%09%09%20%20me.y%20=%200;%0A%20%20%20%20%09%09%20%20me.z%20=%200;%0A%20%20%20%20%09%09%20%20me.w%20=%200;%0A%20%20%20%20%09%09%20%20me.v%20=%200;%0A%0A%20%20%20%20%09%09%20%20if%20(seed%20===%20(seed%20%7C%200))%20%7B%0A%20%20%20%20%09%09%20%20%20%20//%20Integer%20seed.%0A%20%20%20%20%09%09%20%20%20%20me.x%20=%20seed;%0A%20%20%20%20%09%09%20%20%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20%20%20//%20String%20seed.%0A%20%20%20%20%09%09%20%20%20%20strseed%20+=%20seed;%0A%20%20%20%20%09%09%20%20%7D%0A%0A%20%20%20%20%09%09%20%20//%20Mix%20in%20string%20seed,%20then%20discard%20an%20initial%20batch%20of%2064%20values.%0A%20%20%20%20%09%09%20%20for%20(var%20k%20=%200;%20k%20%3C%20strseed.length%20+%2064;%20k++)%20%7B%0A%20%20%20%20%09%09%20%20%20%20me.x%20%5E=%20strseed.charCodeAt(k)%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20if%20(k%20==%20strseed.length)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20me.d%20=%20me.x%20%3C%3C%2010%20%5E%20me.x%20%3E%3E%3E%204;%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20me.next();%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20copy(f,%20t)%20%7B%0A%20%20%20%20%09%09%20%20t.x%20=%20f.x;%0A%20%20%20%20%09%09%20%20t.y%20=%20f.y;%0A%20%20%20%20%09%09%20%20t.z%20=%20f.z;%0A%20%20%20%20%09%09%20%20t.w%20=%20f.w;%0A%20%20%20%20%09%09%20%20t.v%20=%20f.v;%0A%20%20%20%20%09%09%20%20t.d%20=%20f.d;%0A%20%20%20%20%09%09%20%20return%20t;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20impl(seed,%20opts)%20%7B%0A%20%20%20%20%09%09%20%20var%20xg%20=%20new%20XorGen(seed),%0A%20%20%20%20%09%09%20%20%20%20%20%20state%20=%20opts%20&&%20opts.state,%0A%20%20%20%20%09%09%20%20%20%20%20%20prng%20=%20function()%20%7B%20return%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000;%20%7D;%0A%20%20%20%20%09%09%20%20prng.double%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20do%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20var%20top%20=%20xg.next()%20%3E%3E%3E%2011,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20bot%20=%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20result%20=%20(top%20+%20bot)%20/%20(1%20%3C%3C%2021);%0A%20%20%20%20%09%09%20%20%20%20%7D%20while%20(result%20===%200);%0A%20%20%20%20%09%09%20%20%20%20return%20result;%0A%20%20%20%20%09%09%20%20%7D;%0A%20%20%20%20%09%09%20%20prng.int32%20=%20xg.next;%0A%20%20%20%20%09%09%20%20prng.quick%20=%20prng;%0A%20%20%20%20%09%09%20%20if%20(state)%20%7B%0A%20%20%20%20%09%09%20%20%20%20if%20(typeof(state)%20==%20'object')%20copy(state,%20xg);%0A%20%20%20%20%09%09%20%20%20%20prng.state%20=%20function()%20%7B%20return%20copy(xg,%20%7B%7D);%20%7D;%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20return%20prng;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09if%20(module%20&&%20module.exports)%20%7B%0A%20%20%20%20%09%09%20%20module.exports%20=%20impl;%0A%20%20%20%20%09%09%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20this.xorwow%20=%20impl;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09%7D)(%0A%20%20%20%20%09%09%20%20xorwow,%0A%20%20%20%20%09%09%20%20module);%20%0A%20%20%20%20%09%7D%20(xorwow$1));%0A%20%20%20%20%09return%20xorwow$1.exports;%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20xorshift7$1%20=%20%7Bexports:%20%7B%7D%7D;%0A%0A%20%20%20%20var%20xorshift7%20=%20xorshift7$1.exports;%0A%0A%20%20%20%20var%20hasRequiredXorshift7;%0A%0A%20%20%20%20function%20requireXorshift7%20()%20%7B%0A%20%20%20%20%09if%20(hasRequiredXorshift7)%20return%20xorshift7$1.exports;%0A%20%20%20%20%09hasRequiredXorshift7%20=%201;%0A%20%20%20%20%09(function%20(module)%20%7B%0A%20%20%20%20%09%09//%20A%20Javascript%20implementaion%20of%20the%20%22xorshift7%22%20algorithm%20by%0A%20%20%20%20%09%09//%20Fran%C3%A7ois%20Panneton%20and%20Pierre%20L'ecuyer:%0A%20%20%20%20%09%09//%20%22On%20the%20Xorgshift%20Random%20Number%20Generators%22%0A%20%20%20%20%09%09//%20http://saluc.engr.uconn.edu/refs/crypto/rng/panneton05onthexorshift.pdf%0A%0A%20%20%20%20%09%09(function(global,%20module,%20define)%20%7B%0A%0A%20%20%20%20%09%09function%20XorGen(seed)%20%7B%0A%20%20%20%20%09%09%20%20var%20me%20=%20this;%0A%0A%20%20%20%20%09%09%20%20//%20Set%20up%20generator%20function.%0A%20%20%20%20%09%09%20%20me.next%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20//%20Update%20xor%20generator.%0A%20%20%20%20%09%09%20%20%20%20var%20X%20=%20me.x,%20i%20=%20me.i,%20t,%20v;%0A%20%20%20%20%09%09%20%20%20%20t%20=%20X%5Bi%5D;%20t%20%5E=%20(t%20%3E%3E%3E%207);%20v%20=%20t%20%5E%20(t%20%3C%3C%2024);%0A%20%20%20%20%09%09%20%20%20%20t%20=%20X%5B(i%20+%201)%20&%207%5D;%20v%20%5E=%20t%20%5E%20(t%20%3E%3E%3E%2010);%0A%20%20%20%20%09%09%20%20%20%20t%20=%20X%5B(i%20+%203)%20&%207%5D;%20v%20%5E=%20t%20%5E%20(t%20%3E%3E%3E%203);%0A%20%20%20%20%09%09%20%20%20%20t%20=%20X%5B(i%20+%204)%20&%207%5D;%20v%20%5E=%20t%20%5E%20(t%20%3C%3C%207);%0A%20%20%20%20%09%09%20%20%20%20t%20=%20X%5B(i%20+%207)%20&%207%5D;%20t%20=%20t%20%5E%20(t%20%3C%3C%2013);%20v%20%5E=%20t%20%5E%20(t%20%3C%3C%209);%0A%20%20%20%20%09%09%20%20%20%20X%5Bi%5D%20=%20v;%0A%20%20%20%20%09%09%20%20%20%20me.i%20=%20(i%20+%201)%20&%207;%0A%20%20%20%20%09%09%20%20%20%20return%20v;%0A%20%20%20%20%09%09%20%20%7D;%0A%0A%20%20%20%20%09%09%20%20function%20init(me,%20seed)%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20j,%20X%20=%20%5B%5D;%0A%0A%20%20%20%20%09%09%20%20%20%20if%20(seed%20===%20(seed%20%7C%200))%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20//%20Seed%20state%20array%20using%20a%2032-bit%20integer.%0A%20%20%20%20%09%09%20%20%20%20%20%20X%5B0%5D%20=%20seed;%0A%20%20%20%20%09%09%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20//%20Seed%20state%20using%20a%20string.%0A%20%20%20%20%09%09%20%20%20%20%20%20seed%20=%20''%20+%20seed;%0A%20%20%20%20%09%09%20%20%20%20%20%20for%20(j%20=%200;%20j%20%3C%20seed.length;%20++j)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20X%5Bj%20&%207%5D%20=%20(X%5Bj%20&%207%5D%20%3C%3C%2015)%20%5E%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20%20%20(seed.charCodeAt(j)%20+%20X%5B(j%20+%201)%20&%207%5D%20%3C%3C%2013);%0A%20%20%20%20%09%09%20%20%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20//%20Enforce%20an%20array%20length%20of%208,%20not%20all%20zeroes.%0A%20%20%20%20%09%09%20%20%20%20while%20(X.length%20%3C%208)%20X.push(0);%0A%20%20%20%20%09%09%20%20%20%20for%20(j%20=%200;%20j%20%3C%208%20&&%20X%5Bj%5D%20===%200;%20++j);%0A%20%20%20%20%09%09%20%20%20%20if%20(j%20==%208)%20X%5B7%5D%20=%20-1;%20else%20X%5Bj%5D;%0A%0A%20%20%20%20%09%09%20%20%20%20me.x%20=%20X;%0A%20%20%20%20%09%09%20%20%20%20me.i%20=%200;%0A%0A%20%20%20%20%09%09%20%20%20%20//%20Discard%20an%20initial%20256%20values.%0A%20%20%20%20%09%09%20%20%20%20for%20(j%20=%20256;%20j%20%3E%200;%20--j)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20me.next();%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%7D%0A%0A%20%20%20%20%09%09%20%20init(me,%20seed);%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20copy(f,%20t)%20%7B%0A%20%20%20%20%09%09%20%20t.x%20=%20f.x.slice();%0A%20%20%20%20%09%09%20%20t.i%20=%20f.i;%0A%20%20%20%20%09%09%20%20return%20t;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20impl(seed,%20opts)%20%7B%0A%20%20%20%20%09%09%20%20if%20(seed%20==%20null)%20seed%20=%20+(new%20Date);%0A%20%20%20%20%09%09%20%20var%20xg%20=%20new%20XorGen(seed),%0A%20%20%20%20%09%09%20%20%20%20%20%20state%20=%20opts%20&&%20opts.state,%0A%20%20%20%20%09%09%20%20%20%20%20%20prng%20=%20function()%20%7B%20return%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000;%20%7D;%0A%20%20%20%20%09%09%20%20prng.double%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20do%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20var%20top%20=%20xg.next()%20%3E%3E%3E%2011,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20bot%20=%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20result%20=%20(top%20+%20bot)%20/%20(1%20%3C%3C%2021);%0A%20%20%20%20%09%09%20%20%20%20%7D%20while%20(result%20===%200);%0A%20%20%20%20%09%09%20%20%20%20return%20result;%0A%20%20%20%20%09%09%20%20%7D;%0A%20%20%20%20%09%09%20%20prng.int32%20=%20xg.next;%0A%20%20%20%20%09%09%20%20prng.quick%20=%20prng;%0A%20%20%20%20%09%09%20%20if%20(state)%20%7B%0A%20%20%20%20%09%09%20%20%20%20if%20(state.x)%20copy(state,%20xg);%0A%20%20%20%20%09%09%20%20%20%20prng.state%20=%20function()%20%7B%20return%20copy(xg,%20%7B%7D);%20%7D;%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20return%20prng;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09if%20(module%20&&%20module.exports)%20%7B%0A%20%20%20%20%09%09%20%20module.exports%20=%20impl;%0A%20%20%20%20%09%09%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20this.xorshift7%20=%20impl;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09%7D)(%0A%20%20%20%20%09%09%20%20xorshift7,%0A%20%20%20%20%09%09%20%20module);%20%0A%20%20%20%20%09%7D%20(xorshift7$1));%0A%20%20%20%20%09return%20xorshift7$1.exports;%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20xor4096$1%20=%20%7Bexports:%20%7B%7D%7D;%0A%0A%20%20%20%20var%20xor4096%20=%20xor4096$1.exports;%0A%0A%20%20%20%20var%20hasRequiredXor4096;%0A%0A%20%20%20%20function%20requireXor4096%20()%20%7B%0A%20%20%20%20%09if%20(hasRequiredXor4096)%20return%20xor4096$1.exports;%0A%20%20%20%20%09hasRequiredXor4096%20=%201;%0A%20%20%20%20%09(function%20(module)%20%7B%0A%20%20%20%20%09%09//%20A%20Javascript%20implementaion%20of%20Richard%20Brent's%20Xorgens%20xor4096%20algorithm.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20This%20fast%20non-cryptographic%20random%20number%20generator%20is%20designed%20for%0A%20%20%20%20%09%09//%20use%20in%20Monte-Carlo%20algorithms.%20It%20combines%20a%20long-period%20xorshift%0A%20%20%20%20%09%09//%20generator%20with%20a%20Weyl%20generator,%20and%20it%20passes%20all%20common%20batteries%0A%20%20%20%20%09%09//%20of%20stasticial%20tests%20for%20randomness%20while%20consuming%20only%20a%20few%20nanoseconds%0A%20%20%20%20%09%09//%20for%20each%20prng%20generated.%20%20For%20background%20on%20the%20generator,%20see%20Brent's%0A%20%20%20%20%09%09//%20paper:%20%22Some%20long-period%20random%20number%20generators%20using%20shifts%20and%20xors.%22%0A%20%20%20%20%09%09//%20http://arxiv.org/pdf/1004.3115v1.pdf%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20Usage:%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20var%20xor4096%20=%20require('xor4096');%0A%20%20%20%20%09%09//%20random%20=%20xor4096(1);%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Seed%20with%20int32%20or%20string.%0A%20%20%20%20%09%09//%20assert.equal(random(),%200.1520436450538547);%20//%20(0,%201)%20range,%2053%20bits.%0A%20%20%20%20%09%09//%20assert.equal(random.int32(),%201806534897);%20%20%20//%20signed%20int32,%2032%20bits.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20For%20nonzero%20numeric%20keys,%20this%20impelementation%20provides%20a%20sequence%0A%20%20%20%20%09%09//%20identical%20to%20that%20by%20Brent's%20xorgens%203%20implementaion%20in%20C.%20%20This%0A%20%20%20%20%09%09//%20implementation%20also%20provides%20for%20initalizing%20the%20generator%20with%0A%20%20%20%20%09%09//%20string%20seeds,%20or%20for%20saving%20and%20restoring%20the%20state%20of%20the%20generator.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20On%20Chrome,%20this%20prng%20benchmarks%20about%202.1%20times%20slower%20than%0A%20%20%20%20%09%09//%20Javascript's%20built-in%20Math.random().%0A%0A%20%20%20%20%09%09(function(global,%20module,%20define)%20%7B%0A%0A%20%20%20%20%09%09function%20XorGen(seed)%20%7B%0A%20%20%20%20%09%09%20%20var%20me%20=%20this;%0A%0A%20%20%20%20%09%09%20%20//%20Set%20up%20generator%20function.%0A%20%20%20%20%09%09%20%20me.next%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20w%20=%20me.w,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20X%20=%20me.X,%20i%20=%20me.i,%20t,%20v;%0A%20%20%20%20%09%09%20%20%20%20//%20Update%20Weyl%20generator.%0A%20%20%20%20%09%09%20%20%20%20me.w%20=%20w%20=%20(w%20+%200x61c88647)%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20//%20Update%20xor%20generator.%0A%20%20%20%20%09%09%20%20%20%20v%20=%20X%5B(i%20+%2034)%20&%20127%5D;%0A%20%20%20%20%09%09%20%20%20%20t%20=%20X%5Bi%20=%20((i%20+%201)%20&%20127)%5D;%0A%20%20%20%20%09%09%20%20%20%20v%20%5E=%20v%20%3C%3C%2013;%0A%20%20%20%20%09%09%20%20%20%20t%20%5E=%20t%20%3C%3C%2017;%0A%20%20%20%20%09%09%20%20%20%20v%20%5E=%20v%20%3E%3E%3E%2015;%0A%20%20%20%20%09%09%20%20%20%20t%20%5E=%20t%20%3E%3E%3E%2012;%0A%20%20%20%20%09%09%20%20%20%20//%20Update%20Xor%20generator%20array%20state.%0A%20%20%20%20%09%09%20%20%20%20v%20=%20X%5Bi%5D%20=%20v%20%5E%20t;%0A%20%20%20%20%09%09%20%20%20%20me.i%20=%20i;%0A%20%20%20%20%09%09%20%20%20%20//%20Result%20is%20the%20combination.%0A%20%20%20%20%09%09%20%20%20%20return%20(v%20+%20(w%20%5E%20(w%20%3E%3E%3E%2016)))%20%7C%200;%0A%20%20%20%20%09%09%20%20%7D;%0A%0A%20%20%20%20%09%09%20%20function%20init(me,%20seed)%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20t,%20v,%20i,%20j,%20w,%20X%20=%20%5B%5D,%20limit%20=%20128;%0A%20%20%20%20%09%09%20%20%20%20if%20(seed%20===%20(seed%20%7C%200))%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20//%20Numeric%20seeds%20initialize%20v,%20which%20is%20used%20to%20generates%20X.%0A%20%20%20%20%09%09%20%20%20%20%20%20v%20=%20seed;%0A%20%20%20%20%09%09%20%20%20%20%20%20seed%20=%20null;%0A%20%20%20%20%09%09%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20//%20String%20seeds%20are%20mixed%20into%20v%20and%20X%20one%20character%20at%20a%20time.%0A%20%20%20%20%09%09%20%20%20%20%20%20seed%20=%20seed%20+%20'%5C0';%0A%20%20%20%20%09%09%20%20%20%20%20%20v%20=%200;%0A%20%20%20%20%09%09%20%20%20%20%20%20limit%20=%20Math.max(limit,%20seed.length);%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20//%20Initialize%20circular%20array%20and%20weyl%20value.%0A%20%20%20%20%09%09%20%20%20%20for%20(i%20=%200,%20j%20=%20-32;%20j%20%3C%20limit;%20++j)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20//%20Put%20the%20unicode%20characters%20into%20the%20array,%20and%20shuffle%20them.%0A%20%20%20%20%09%09%20%20%20%20%20%20if%20(seed)%20v%20%5E=%20seed.charCodeAt((j%20+%2032)%20%25%20seed.length);%0A%20%20%20%20%09%09%20%20%20%20%20%20//%20After%2032%20shuffles,%20take%20v%20as%20the%20starting%20w%20value.%0A%20%20%20%20%09%09%20%20%20%20%20%20if%20(j%20===%200)%20w%20=%20v;%0A%20%20%20%20%09%09%20%20%20%20%20%20v%20%5E=%20v%20%3C%3C%2010;%0A%20%20%20%20%09%09%20%20%20%20%20%20v%20%5E=%20v%20%3E%3E%3E%2015;%0A%20%20%20%20%09%09%20%20%20%20%20%20v%20%5E=%20v%20%3C%3C%204;%0A%20%20%20%20%09%09%20%20%20%20%20%20v%20%5E=%20v%20%3E%3E%3E%2013;%0A%20%20%20%20%09%09%20%20%20%20%20%20if%20(j%20%3E=%200)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20w%20=%20(w%20+%200x61c88647)%20%7C%200;%20%20%20%20%20//%20Weyl.%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20t%20=%20(X%5Bj%20&%20127%5D%20%5E=%20(v%20+%20w));%20%20//%20Combine%20xor%20and%20weyl%20to%20init%20array.%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20i%20=%20(0%20==%20t)%20?%20i%20+%201%20:%200;%20%20%20%20%20//%20Count%20zeroes.%0A%20%20%20%20%09%09%20%20%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20//%20We%20have%20detected%20all%20zeroes;%20make%20the%20key%20nonzero.%0A%20%20%20%20%09%09%20%20%20%20if%20(i%20%3E=%20128)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20X%5B(seed%20&&%20seed.length%20%7C%7C%200)%20&%20127%5D%20=%20-1;%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20//%20Run%20the%20generator%20512%20times%20to%20further%20mix%20the%20state%20before%20using%20it.%0A%20%20%20%20%09%09%20%20%20%20//%20Factoring%20this%20as%20a%20function%20slows%20the%20main%20generator,%20so%20it%20is%20just%0A%20%20%20%20%09%09%20%20%20%20//%20unrolled%20here.%20%20The%20weyl%20generator%20is%20not%20advanced%20while%20warming%20up.%0A%20%20%20%20%09%09%20%20%20%20i%20=%20127;%0A%20%20%20%20%09%09%20%20%20%20for%20(j%20=%204%20*%20128;%20j%20%3E%200;%20--j)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20v%20=%20X%5B(i%20+%2034)%20&%20127%5D;%0A%20%20%20%20%09%09%20%20%20%20%20%20t%20=%20X%5Bi%20=%20((i%20+%201)%20&%20127)%5D;%0A%20%20%20%20%09%09%20%20%20%20%20%20v%20%5E=%20v%20%3C%3C%2013;%0A%20%20%20%20%09%09%20%20%20%20%20%20t%20%5E=%20t%20%3C%3C%2017;%0A%20%20%20%20%09%09%20%20%20%20%20%20v%20%5E=%20v%20%3E%3E%3E%2015;%0A%20%20%20%20%09%09%20%20%20%20%20%20t%20%5E=%20t%20%3E%3E%3E%2012;%0A%20%20%20%20%09%09%20%20%20%20%20%20X%5Bi%5D%20=%20v%20%5E%20t;%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20//%20Storing%20state%20as%20object%20members%20is%20faster%20than%20using%20closure%20variables.%0A%20%20%20%20%09%09%20%20%20%20me.w%20=%20w;%0A%20%20%20%20%09%09%20%20%20%20me.X%20=%20X;%0A%20%20%20%20%09%09%20%20%20%20me.i%20=%20i;%0A%20%20%20%20%09%09%20%20%7D%0A%0A%20%20%20%20%09%09%20%20init(me,%20seed);%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20copy(f,%20t)%20%7B%0A%20%20%20%20%09%09%20%20t.i%20=%20f.i;%0A%20%20%20%20%09%09%20%20t.w%20=%20f.w;%0A%20%20%20%20%09%09%20%20t.X%20=%20f.X.slice();%0A%20%20%20%20%09%09%20%20return%20t;%0A%20%20%20%20%09%09%7D%0A%20%20%20%20%09%09function%20impl(seed,%20opts)%20%7B%0A%20%20%20%20%09%09%20%20if%20(seed%20==%20null)%20seed%20=%20+(new%20Date);%0A%20%20%20%20%09%09%20%20var%20xg%20=%20new%20XorGen(seed),%0A%20%20%20%20%09%09%20%20%20%20%20%20state%20=%20opts%20&&%20opts.state,%0A%20%20%20%20%09%09%20%20%20%20%20%20prng%20=%20function()%20%7B%20return%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000;%20%7D;%0A%20%20%20%20%09%09%20%20prng.double%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20do%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20var%20top%20=%20xg.next()%20%3E%3E%3E%2011,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20bot%20=%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20result%20=%20(top%20+%20bot)%20/%20(1%20%3C%3C%2021);%0A%20%20%20%20%09%09%20%20%20%20%7D%20while%20(result%20===%200);%0A%20%20%20%20%09%09%20%20%20%20return%20result;%0A%20%20%20%20%09%09%20%20%7D;%0A%20%20%20%20%09%09%20%20prng.int32%20=%20xg.next;%0A%20%20%20%20%09%09%20%20prng.quick%20=%20prng;%0A%20%20%20%20%09%09%20%20if%20(state)%20%7B%0A%20%20%20%20%09%09%20%20%20%20if%20(state.X)%20copy(state,%20xg);%0A%20%20%20%20%09%09%20%20%20%20prng.state%20=%20function()%20%7B%20return%20copy(xg,%20%7B%7D);%20%7D;%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20return%20prng;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09if%20(module%20&&%20module.exports)%20%7B%0A%20%20%20%20%09%09%20%20module.exports%20=%20impl;%0A%20%20%20%20%09%09%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20this.xor4096%20=%20impl;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09%7D)(%0A%20%20%20%20%09%09%20%20xor4096,%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20window%20object%20or%20global%0A%20%20%20%20%09%09%20%20module);%20%0A%20%20%20%20%09%7D%20(xor4096$1));%0A%20%20%20%20%09return%20xor4096$1.exports;%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20tychei$1%20=%20%7Bexports:%20%7B%7D%7D;%0A%0A%20%20%20%20var%20tychei%20=%20tychei$1.exports;%0A%0A%20%20%20%20var%20hasRequiredTychei;%0A%0A%20%20%20%20function%20requireTychei%20()%20%7B%0A%20%20%20%20%09if%20(hasRequiredTychei)%20return%20tychei$1.exports;%0A%20%20%20%20%09hasRequiredTychei%20=%201;%0A%20%20%20%20%09(function%20(module)%20%7B%0A%20%20%20%20%09%09//%20A%20Javascript%20implementaion%20of%20the%20%22Tyche-i%22%20prng%20algorithm%20by%0A%20%20%20%20%09%09//%20Samuel%20Neves%20and%20Filipe%20Araujo.%0A%20%20%20%20%09%09//%20See%20https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf%0A%0A%20%20%20%20%09%09(function(global,%20module,%20define)%20%7B%0A%0A%20%20%20%20%09%09function%20XorGen(seed)%20%7B%0A%20%20%20%20%09%09%20%20var%20me%20=%20this,%20strseed%20=%20'';%0A%0A%20%20%20%20%09%09%20%20//%20Set%20up%20generator%20function.%0A%20%20%20%20%09%09%20%20me.next%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20b%20=%20me.b,%20c%20=%20me.c,%20d%20=%20me.d,%20a%20=%20me.a;%0A%20%20%20%20%09%09%20%20%20%20b%20=%20(b%20%3C%3C%2025)%20%5E%20(b%20%3E%3E%3E%207)%20%5E%20c;%0A%20%20%20%20%09%09%20%20%20%20c%20=%20(c%20-%20d)%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20d%20=%20(d%20%3C%3C%2024)%20%5E%20(d%20%3E%3E%3E%208)%20%5E%20a;%0A%20%20%20%20%09%09%20%20%20%20a%20=%20(a%20-%20b)%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20me.b%20=%20b%20=%20(b%20%3C%3C%2020)%20%5E%20(b%20%3E%3E%3E%2012)%20%5E%20c;%0A%20%20%20%20%09%09%20%20%20%20me.c%20=%20c%20=%20(c%20-%20d)%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20me.d%20=%20(d%20%3C%3C%2016)%20%5E%20(c%20%3E%3E%3E%2016)%20%5E%20a;%0A%20%20%20%20%09%09%20%20%20%20return%20me.a%20=%20(a%20-%20b)%20%7C%200;%0A%20%20%20%20%09%09%20%20%7D;%0A%0A%20%20%20%20%09%09%20%20/*%20The%20following%20is%20non-inverted%20tyche,%20which%20has%20better%20internal%0A%20%20%20%20%09%09%20%20%20*%20bit%20diffusion,%20but%20which%20is%20about%2025%25%20slower%20than%20tyche-i%20in%20JS.%0A%20%20%20%20%09%09%20%20me.next%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20a%20=%20me.a,%20b%20=%20me.b,%20c%20=%20me.c,%20d%20=%20me.d;%0A%20%20%20%20%09%09%20%20%20%20a%20=%20(me.a%20+%20me.b%20%7C%200)%20%3E%3E%3E%200;%0A%20%20%20%20%09%09%20%20%20%20d%20=%20me.d%20%5E%20a;%20d%20=%20d%20%3C%3C%2016%20%5E%20d%20%3E%3E%3E%2016;%0A%20%20%20%20%09%09%20%20%20%20c%20=%20me.c%20+%20d%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20b%20=%20me.b%20%5E%20c;%20b%20=%20b%20%3C%3C%2012%20%5E%20d%20%3E%3E%3E%2020;%0A%20%20%20%20%09%09%20%20%20%20me.a%20=%20a%20=%20a%20+%20b%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20d%20=%20d%20%5E%20a;%20me.d%20=%20d%20=%20d%20%3C%3C%208%20%5E%20d%20%3E%3E%3E%2024;%0A%20%20%20%20%09%09%20%20%20%20me.c%20=%20c%20=%20c%20+%20d%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20b%20=%20b%20%5E%20c;%0A%20%20%20%20%09%09%20%20%20%20return%20me.b%20=%20(b%20%3C%3C%207%20%5E%20b%20%3E%3E%3E%2025);%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20*/%0A%0A%20%20%20%20%09%09%20%20me.a%20=%200;%0A%20%20%20%20%09%09%20%20me.b%20=%200;%0A%20%20%20%20%09%09%20%20me.c%20=%202654435769%20%7C%200;%0A%20%20%20%20%09%09%20%20me.d%20=%201367130551;%0A%0A%20%20%20%20%09%09%20%20if%20(seed%20===%20Math.floor(seed))%20%7B%0A%20%20%20%20%09%09%20%20%20%20//%20Integer%20seed.%0A%20%20%20%20%09%09%20%20%20%20me.a%20=%20(seed%20/%200x100000000)%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20me.b%20=%20seed%20%7C%200;%0A%20%20%20%20%09%09%20%20%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20%20%20//%20String%20seed.%0A%20%20%20%20%09%09%20%20%20%20strseed%20+=%20seed;%0A%20%20%20%20%09%09%20%20%7D%0A%0A%20%20%20%20%09%09%20%20//%20Mix%20in%20string%20seed,%20then%20discard%20an%20initial%20batch%20of%2064%20values.%0A%20%20%20%20%09%09%20%20for%20(var%20k%20=%200;%20k%20%3C%20strseed.length%20+%2020;%20k++)%20%7B%0A%20%20%20%20%09%09%20%20%20%20me.b%20%5E=%20strseed.charCodeAt(k)%20%7C%200;%0A%20%20%20%20%09%09%20%20%20%20me.next();%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09function%20copy(f,%20t)%20%7B%0A%20%20%20%20%09%09%20%20t.a%20=%20f.a;%0A%20%20%20%20%09%09%20%20t.b%20=%20f.b;%0A%20%20%20%20%09%09%20%20t.c%20=%20f.c;%0A%20%20%20%20%09%09%20%20t.d%20=%20f.d;%0A%20%20%20%20%09%09%20%20return%20t;%0A%20%20%20%20%09%09%7D%0A%20%20%20%20%09%09function%20impl(seed,%20opts)%20%7B%0A%20%20%20%20%09%09%20%20var%20xg%20=%20new%20XorGen(seed),%0A%20%20%20%20%09%09%20%20%20%20%20%20state%20=%20opts%20&&%20opts.state,%0A%20%20%20%20%09%09%20%20%20%20%20%20prng%20=%20function()%20%7B%20return%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000;%20%7D;%0A%20%20%20%20%09%09%20%20prng.double%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20do%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20var%20top%20=%20xg.next()%20%3E%3E%3E%2011,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20bot%20=%20(xg.next()%20%3E%3E%3E%200)%20/%200x100000000,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20result%20=%20(top%20+%20bot)%20/%20(1%20%3C%3C%2021);%0A%20%20%20%20%09%09%20%20%20%20%7D%20while%20(result%20===%200);%0A%20%20%20%20%09%09%20%20%20%20return%20result;%0A%20%20%20%20%09%09%20%20%7D;%0A%20%20%20%20%09%09%20%20prng.int32%20=%20xg.next;%0A%20%20%20%20%09%09%20%20prng.quick%20=%20prng;%0A%20%20%20%20%09%09%20%20if%20(state)%20%7B%0A%20%20%20%20%09%09%20%20%20%20if%20(typeof(state)%20==%20'object')%20copy(state,%20xg);%0A%20%20%20%20%09%09%20%20%20%20prng.state%20=%20function()%20%7B%20return%20copy(xg,%20%7B%7D);%20%7D;%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20return%20prng;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09if%20(module%20&&%20module.exports)%20%7B%0A%20%20%20%20%09%09%20%20module.exports%20=%20impl;%0A%20%20%20%20%09%09%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20this.tychei%20=%20impl;%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09%7D)(%0A%20%20%20%20%09%09%20%20tychei,%0A%20%20%20%20%09%09%20%20module);%20%0A%20%20%20%20%09%7D%20(tychei$1));%0A%20%20%20%20%09return%20tychei$1.exports;%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20seedrandom$2%20=%20%7Bexports:%20%7B%7D%7D;%0A%0A%20%20%20%20/*%0A%20%20%20%20Copyright%202019%20David%20Bau.%0A%0A%20%20%20%20Permission%20is%20hereby%20granted,%20free%20of%20charge,%20to%20any%20person%20obtaining%0A%20%20%20%20a%20copy%20of%20this%20software%20and%20associated%20documentation%20files%20(the%0A%20%20%20%20%22Software%22),%20to%20deal%20in%20the%20Software%20without%20restriction,%20including%0A%20%20%20%20without%20limitation%20the%20rights%20to%20use,%20copy,%20modify,%20merge,%20publish,%0A%20%20%20%20distribute,%20sublicense,%20and/or%20sell%20copies%20of%20the%20Software,%20and%20to%0A%20%20%20%20permit%20persons%20to%20whom%20the%20Software%20is%20furnished%20to%20do%20so,%20subject%20to%0A%20%20%20%20the%20following%20conditions:%0A%0A%20%20%20%20The%20above%20copyright%20notice%20and%20this%20permission%20notice%20shall%20be%0A%20%20%20%20included%20in%20all%20copies%20or%20substantial%20portions%20of%20the%20Software.%0A%0A%20%20%20%20THE%20SOFTWARE%20IS%20PROVIDED%20%22AS%20IS%22,%20WITHOUT%20WARRANTY%20OF%20ANY%20KIND,%0A%20%20%20%20EXPRESS%20OR%20IMPLIED,%20INCLUDING%20BUT%20NOT%20LIMITED%20TO%20THE%20WARRANTIES%20OF%0A%20%20%20%20MERCHANTABILITY,%20FITNESS%20FOR%20A%20PARTICULAR%20PURPOSE%20AND%20NONINFRINGEMENT.%0A%20%20%20%20IN%20NO%20EVENT%20SHALL%20THE%20AUTHORS%20OR%20COPYRIGHT%20HOLDERS%20BE%20LIABLE%20FOR%20ANY%0A%20%20%20%20CLAIM,%20DAMAGES%20OR%20OTHER%20LIABILITY,%20WHETHER%20IN%20AN%20ACTION%20OF%20CONTRACT,%0A%20%20%20%20TORT%20OR%20OTHERWISE,%20ARISING%20FROM,%20OUT%20OF%20OR%20IN%20CONNECTION%20WITH%20THE%0A%20%20%20%20SOFTWARE%20OR%20THE%20USE%20OR%20OTHER%20DEALINGS%20IN%20THE%20SOFTWARE.%0A%0A%20%20%20%20*/%0A%20%20%20%20var%20seedrandom$1%20=%20seedrandom$2.exports;%0A%0A%20%20%20%20var%20hasRequiredSeedrandom$1;%0A%0A%20%20%20%20function%20requireSeedrandom$1%20()%20%7B%0A%20%20%20%20%09if%20(hasRequiredSeedrandom$1)%20return%20seedrandom$2.exports;%0A%20%20%20%20%09hasRequiredSeedrandom$1%20=%201;%0A%20%20%20%20%09(function%20(module)%20%7B%0A%20%20%20%20%09%09(function%20(global,%20pool,%20math)%20%7B%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20The%20following%20constants%20are%20related%20to%20IEEE%20754%20limits.%0A%20%20%20%20%09%09//%0A%0A%20%20%20%20%09%09var%20width%20=%20256,%20%20%20%20%20%20%20%20//%20each%20RC4%20output%20is%200%20%3C=%20x%20%3C%20256%0A%20%20%20%20%09%09%20%20%20%20chunks%20=%206,%20%20%20%20%20%20%20%20%20//%20at%20least%20six%20RC4%20outputs%20for%20each%20double%0A%20%20%20%20%09%09%20%20%20%20digits%20=%2052,%20%20%20%20%20%20%20%20//%20there%20are%2052%20significant%20digits%20in%20a%20double%0A%20%20%20%20%09%09%20%20%20%20rngname%20=%20'random',%20//%20rngname:%20name%20for%20Math.random%20and%20Math.seedrandom%0A%20%20%20%20%09%09%20%20%20%20startdenom%20=%20math.pow(width,%20chunks),%0A%20%20%20%20%09%09%20%20%20%20significance%20=%20math.pow(2,%20digits),%0A%20%20%20%20%09%09%20%20%20%20overflow%20=%20significance%20*%202,%0A%20%20%20%20%09%09%20%20%20%20mask%20=%20width%20-%201,%0A%20%20%20%20%09%09%20%20%20%20nodecrypto;%20%20%20%20%20%20%20%20%20//%20node.js%20crypto%20module,%20initialized%20at%20the%20bottom.%0A%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20seedrandom()%0A%20%20%20%20%09%09//%20This%20is%20the%20seedrandom%20function%20described%20above.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09function%20seedrandom(seed,%20options,%20callback)%20%7B%0A%20%20%20%20%09%09%20%20var%20key%20=%20%5B%5D;%0A%20%20%20%20%09%09%20%20options%20=%20(options%20==%20true)%20?%20%7B%20entropy:%20true%20%7D%20:%20(options%20%7C%7C%20%7B%7D);%0A%0A%20%20%20%20%09%09%20%20//%20Flatten%20the%20seed%20string%20or%20build%20one%20from%20local%20entropy%20if%20needed.%0A%20%20%20%20%09%09%20%20var%20shortseed%20=%20mixkey(flatten(%0A%20%20%20%20%09%09%20%20%20%20options.entropy%20?%20%5Bseed,%20tostring(pool)%5D%20:%0A%20%20%20%20%09%09%20%20%20%20(seed%20==%20null)%20?%20autoseed()%20:%20seed,%203),%20key);%0A%0A%20%20%20%20%09%09%20%20//%20Use%20the%20seed%20to%20initialize%20an%20ARC4%20generator.%0A%20%20%20%20%09%09%20%20var%20arc4%20=%20new%20ARC4(key);%0A%0A%20%20%20%20%09%09%20%20//%20This%20function%20returns%20a%20random%20double%20in%20%5B0,%201)%20that%20contains%0A%20%20%20%20%09%09%20%20//%20randomness%20in%20every%20bit%20of%20the%20mantissa%20of%20the%20IEEE%20754%20value.%0A%20%20%20%20%09%09%20%20var%20prng%20=%20function()%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20n%20=%20arc4.g(chunks),%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Start%20with%20a%20numerator%20n%20%3C%202%20%5E%2048%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20d%20=%20startdenom,%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20and%20denominator%20d%20=%202%20%5E%2048.%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20x%20=%200;%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20and%20no%20'extra%20last%20byte'.%0A%20%20%20%20%09%09%20%20%20%20while%20(n%20%3C%20significance)%20%7B%20%20%20%20%20%20%20%20%20%20//%20Fill%20up%20all%20significant%20digits%20by%0A%20%20%20%20%09%09%20%20%20%20%20%20n%20=%20(n%20+%20x)%20*%20width;%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20shifting%20numerator%20and%0A%20%20%20%20%09%09%20%20%20%20%20%20d%20*=%20width;%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20denominator%20and%20generating%20a%0A%20%20%20%20%09%09%20%20%20%20%20%20x%20=%20arc4.g(1);%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20new%20least-significant-byte.%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20while%20(n%20%3E=%20overflow)%20%7B%20%20%20%20%20%20%20%20%20%20%20%20%20//%20To%20avoid%20rounding%20up,%20before%20adding%0A%20%20%20%20%09%09%20%20%20%20%20%20n%20/=%202;%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20last%20byte,%20shift%20everything%0A%20%20%20%20%09%09%20%20%20%20%20%20d%20/=%202;%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20right%20using%20integer%20math%20until%0A%20%20%20%20%09%09%20%20%20%20%20%20x%20%3E%3E%3E=%201;%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20we%20have%20exactly%20the%20desired%20bits.%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20return%20(n%20+%20x)%20/%20d;%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Form%20the%20number%20within%20%5B0,%201).%0A%20%20%20%20%09%09%20%20%7D;%0A%0A%20%20%20%20%09%09%20%20prng.int32%20=%20function()%20%7B%20return%20arc4.g(4)%20%7C%200;%20%7D;%0A%20%20%20%20%09%09%20%20prng.quick%20=%20function()%20%7B%20return%20arc4.g(4)%20/%200x100000000;%20%7D;%0A%20%20%20%20%09%09%20%20prng.double%20=%20prng;%0A%0A%20%20%20%20%09%09%20%20//%20Mix%20the%20randomness%20into%20accumulated%20entropy.%0A%20%20%20%20%09%09%20%20mixkey(tostring(arc4.S),%20pool);%0A%0A%20%20%20%20%09%09%20%20//%20Calling%20convention:%20what%20to%20return%20as%20a%20function%20of%20prng,%20seed,%20is_math.%0A%20%20%20%20%09%09%20%20return%20(options.pass%20%7C%7C%20callback%20%7C%7C%0A%20%20%20%20%09%09%20%20%20%20%20%20function(prng,%20seed,%20is_math_call,%20state)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20if%20(state)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20//%20Load%20the%20arc4%20state%20from%20the%20given%20state%20if%20it%20has%20an%20S%20array.%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20if%20(state.S)%20%7B%20copy(state,%20arc4);%20%7D%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20//%20Only%20provide%20the%20.state%20method%20if%20requested%20via%20options.state.%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20prng.state%20=%20function()%20%7B%20return%20copy(arc4,%20%7B%7D);%20%7D;%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20//%20If%20called%20as%20a%20method%20of%20Math%20(Math.seedrandom()),%20mutate%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20//%20Math.random%20because%20that%20is%20how%20seedrandom.js%20has%20worked%20since%20v1.0.%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20if%20(is_math_call)%20%7B%20math%5Brngname%5D%20=%20prng;%20return%20seed;%20%7D%0A%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20//%20Otherwise,%20it%20is%20a%20newer%20calling%20convention,%20so%20return%20the%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20//%20prng%20directly.%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20else%20return%20prng;%0A%20%20%20%20%09%09%20%20%20%20%20%20%7D)(%0A%20%20%20%20%09%09%20%20prng,%0A%20%20%20%20%09%09%20%20shortseed,%0A%20%20%20%20%09%09%20%20'global'%20in%20options%20?%20options.global%20:%20(this%20==%20math),%0A%20%20%20%20%09%09%20%20options.state);%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20ARC4%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20An%20ARC4%20implementation.%20%20The%20constructor%20takes%20a%20key%20in%20the%20form%20of%0A%20%20%20%20%09%09//%20an%20array%20of%20at%20most%20(width)%20integers%20that%20should%20be%200%20%3C=%20x%20%3C%20(width).%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20The%20g(count)%20method%20returns%20a%20pseudorandom%20integer%20that%20concatenates%0A%20%20%20%20%09%09//%20the%20next%20(count)%20outputs%20from%20ARC4.%20%20Its%20return%20value%20is%20a%20number%20x%0A%20%20%20%20%09%09//%20that%20is%20in%20the%20range%200%20%3C=%20x%20%3C%20(width%20%5E%20count).%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09function%20ARC4(key)%20%7B%0A%20%20%20%20%09%09%20%20var%20t,%20keylen%20=%20key.length,%0A%20%20%20%20%09%09%20%20%20%20%20%20me%20=%20this,%20i%20=%200,%20j%20=%20me.i%20=%20me.j%20=%200,%20s%20=%20me.S%20=%20%5B%5D;%0A%0A%20%20%20%20%09%09%20%20//%20The%20empty%20key%20%5B%5D%20is%20treated%20as%20%5B0%5D.%0A%20%20%20%20%09%09%20%20if%20(!keylen)%20%7B%20key%20=%20%5Bkeylen++%5D;%20%7D%0A%0A%20%20%20%20%09%09%20%20//%20Set%20up%20S%20using%20the%20standard%20key%20scheduling%20algorithm.%0A%20%20%20%20%09%09%20%20while%20(i%20%3C%20width)%20%7B%0A%20%20%20%20%09%09%20%20%20%20s%5Bi%5D%20=%20i++;%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20for%20(i%20=%200;%20i%20%3C%20width;%20i++)%20%7B%0A%20%20%20%20%09%09%20%20%20%20s%5Bi%5D%20=%20s%5Bj%20=%20mask%20&%20(j%20+%20key%5Bi%20%25%20keylen%5D%20+%20(t%20=%20s%5Bi%5D))%5D;%0A%20%20%20%20%09%09%20%20%20%20s%5Bj%5D%20=%20t;%0A%20%20%20%20%09%09%20%20%7D%0A%0A%20%20%20%20%09%09%20%20//%20The%20%22g%22%20method%20returns%20the%20next%20(count)%20outputs%20as%20one%20number.%0A%20%20%20%20%09%09%20%20(me.g%20=%20function(count)%20%7B%0A%20%20%20%20%09%09%20%20%20%20//%20Using%20instance%20members%20instead%20of%20closure%20state%20nearly%20doubles%20speed.%0A%20%20%20%20%09%09%20%20%20%20var%20t,%20r%20=%200,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20i%20=%20me.i,%20j%20=%20me.j,%20s%20=%20me.S;%0A%20%20%20%20%09%09%20%20%20%20while%20(count--)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20t%20=%20s%5Bi%20=%20mask%20&%20(i%20+%201)%5D;%0A%20%20%20%20%09%09%20%20%20%20%20%20r%20=%20r%20*%20width%20+%20s%5Bmask%20&%20((s%5Bi%5D%20=%20s%5Bj%20=%20mask%20&%20(j%20+%20t)%5D)%20+%20(s%5Bj%5D%20=%20t))%5D;%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20me.i%20=%20i;%20me.j%20=%20j;%0A%20%20%20%20%09%09%20%20%20%20return%20r;%0A%20%20%20%20%09%09%20%20%20%20//%20For%20robust%20unpredictability,%20the%20function%20call%20below%20automatically%0A%20%20%20%20%09%09%20%20%20%20//%20discards%20an%20initial%20batch%20of%20values.%20%20This%20is%20called%20RC4-drop%5B256%5D.%0A%20%20%20%20%09%09%20%20%20%20//%20See%20http://google.com/search?q=rsa+fluhrer+response&btnI%0A%20%20%20%20%09%09%20%20%7D)(width);%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20copy()%0A%20%20%20%20%09%09//%20Copies%20internal%20state%20of%20ARC4%20to%20or%20from%20a%20plain%20object.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09function%20copy(f,%20t)%20%7B%0A%20%20%20%20%09%09%20%20t.i%20=%20f.i;%0A%20%20%20%20%09%09%20%20t.j%20=%20f.j;%0A%20%20%20%20%09%09%20%20t.S%20=%20f.S.slice();%0A%20%20%20%20%09%09%20%20return%20t;%0A%20%20%20%20%09%09%7D%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20flatten()%0A%20%20%20%20%09%09//%20Converts%20an%20object%20tree%20to%20nested%20arrays%20of%20strings.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09function%20flatten(obj,%20depth)%20%7B%0A%20%20%20%20%09%09%20%20var%20result%20=%20%5B%5D,%20typ%20=%20(typeof%20obj),%20prop;%0A%20%20%20%20%09%09%20%20if%20(depth%20&&%20typ%20==%20'object')%20%7B%0A%20%20%20%20%09%09%20%20%20%20for%20(prop%20in%20obj)%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20try%20%7B%20result.push(flatten(obj%5Bprop%5D,%20depth%20-%201));%20%7D%20catch%20(e)%20%7B%7D%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20return%20(result.length%20?%20result%20:%20typ%20==%20'string'%20?%20obj%20:%20obj%20+%20'%5C0');%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20mixkey()%0A%20%20%20%20%09%09//%20Mixes%20a%20string%20seed%20into%20a%20key%20that%20is%20an%20array%20of%20integers,%20and%0A%20%20%20%20%09%09//%20returns%20a%20shortened%20string%20seed%20that%20is%20equivalent%20to%20the%20result%20key.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09function%20mixkey(seed,%20key)%20%7B%0A%20%20%20%20%09%09%20%20var%20stringseed%20=%20seed%20+%20'',%20smear,%20j%20=%200;%0A%20%20%20%20%09%09%20%20while%20(j%20%3C%20stringseed.length)%20%7B%0A%20%20%20%20%09%09%20%20%20%20key%5Bmask%20&%20j%5D%20=%0A%20%20%20%20%09%09%20%20%20%20%20%20mask%20&%20((smear%20%5E=%20key%5Bmask%20&%20j%5D%20*%2019)%20+%20stringseed.charCodeAt(j++));%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%20%20return%20tostring(key);%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20autoseed()%0A%20%20%20%20%09%09//%20Returns%20an%20object%20for%20autoseeding,%20using%20window.crypto%20and%20Node%20crypto%0A%20%20%20%20%09%09//%20module%20if%20available.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09function%20autoseed()%20%7B%0A%20%20%20%20%09%09%20%20try%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20out;%0A%20%20%20%20%09%09%20%20%20%20if%20(nodecrypto%20&&%20(out%20=%20nodecrypto.randomBytes))%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20//%20The%20use%20of%20'out'%20to%20remember%20randomBytes%20makes%20tight%20minified%20code.%0A%20%20%20%20%09%09%20%20%20%20%20%20out%20=%20out(width);%0A%20%20%20%20%09%09%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20%20%20%20%20out%20=%20new%20Uint8Array(width);%0A%20%20%20%20%09%09%20%20%20%20%20%20(global.crypto%20%7C%7C%20global.msCrypto).getRandomValues(out);%0A%20%20%20%20%09%09%20%20%20%20%7D%0A%20%20%20%20%09%09%20%20%20%20return%20tostring(out);%0A%20%20%20%20%09%09%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%09%09%20%20%20%20var%20browser%20=%20global.navigator,%0A%20%20%20%20%09%09%20%20%20%20%20%20%20%20plugins%20=%20browser%20&&%20browser.plugins;%0A%20%20%20%20%09%09%20%20%20%20return%20%5B+new%20Date,%20global,%20plugins,%20global.screen,%20tostring(pool)%5D;%0A%20%20%20%20%09%09%20%20%7D%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20tostring()%0A%20%20%20%20%09%09//%20Converts%20an%20array%20of%20charcodes%20to%20a%20string%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09function%20tostring(a)%20%7B%0A%20%20%20%20%09%09%20%20return%20String.fromCharCode.apply(0,%20a);%0A%20%20%20%20%09%09%7D%0A%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20When%20seedrandom.js%20is%20loaded,%20we%20immediately%20mix%20a%20few%20bits%0A%20%20%20%20%09%09//%20from%20the%20built-in%20RNG%20into%20the%20entropy%20pool.%20%20Because%20we%20do%0A%20%20%20%20%09%09//%20not%20want%20to%20interfere%20with%20deterministic%20PRNG%20state%20later,%0A%20%20%20%20%09%09//%20seedrandom%20will%20not%20call%20math.random%20on%20its%20own%20again%20after%0A%20%20%20%20%09%09//%20initialization.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09mixkey(math.random(),%20pool);%0A%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09//%20Nodejs%20and%20AMD%20support:%20export%20the%20implementation%20as%20a%20module%20using%0A%20%20%20%20%09%09//%20either%20convention.%0A%20%20%20%20%09%09//%0A%20%20%20%20%09%09if%20(module.exports)%20%7B%0A%20%20%20%20%09%09%20%20module.exports%20=%20seedrandom;%0A%20%20%20%20%09%09%20%20//%20When%20in%20node.js,%20try%20using%20crypto%20package%20for%20autoseeding.%0A%20%20%20%20%09%09%20%20try%20%7B%0A%20%20%20%20%09%09%20%20%20%20nodecrypto%20=%20require('crypto');%0A%20%20%20%20%09%09%20%20%7D%20catch%20(ex)%20%7B%7D%0A%20%20%20%20%09%09%7D%20else%20%7B%0A%20%20%20%20%09%09%20%20//%20When%20included%20as%20a%20plain%20script,%20set%20up%20Math.seedrandom%20global.%0A%20%20%20%20%09%09%20%20math%5B'seed'%20+%20rngname%5D%20=%20seedrandom;%0A%20%20%20%20%09%09%7D%0A%0A%0A%20%20%20%20%09%09//%20End%20anonymous%20scope,%20and%20pass%20initial%20values.%0A%20%20%20%20%09%09%7D)(%0A%20%20%20%20%09%09%20%20//%20global:%20%60self%60%20in%20browsers%20(including%20strict%20mode%20and%20web%20workers),%0A%20%20%20%20%09%09%20%20//%20otherwise%20%60this%60%20in%20Node%20and%20other%20environments%0A%20%20%20%20%09%09%20%20(typeof%20self%20!==%20'undefined')%20?%20self%20:%20seedrandom$1,%0A%20%20%20%20%09%09%20%20%5B%5D,%20%20%20%20%20//%20pool:%20entropy%20pool%20starts%20empty%0A%20%20%20%20%09%09%20%20Math%20%20%20%20//%20math:%20package%20containing%20random,%20pow,%20and%20seedrandom%0A%20%20%20%20%09%09);%20%0A%20%20%20%20%09%7D%20(seedrandom$2));%0A%20%20%20%20%09return%20seedrandom$2.exports;%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20seedrandom;%0A%20%20%20%20var%20hasRequiredSeedrandom;%0A%0A%20%20%20%20function%20requireSeedrandom%20()%20%7B%0A%20%20%20%20%09if%20(hasRequiredSeedrandom)%20return%20seedrandom;%0A%20%20%20%20%09hasRequiredSeedrandom%20=%201;%0A%20%20%20%20%09//%20A%20library%20of%20seedable%20RNGs%20implemented%20in%20Javascript.%0A%20%20%20%20%09//%0A%20%20%20%20%09//%20Usage:%0A%20%20%20%20%09//%0A%20%20%20%20%09//%20var%20seedrandom%20=%20require('seedrandom');%0A%20%20%20%20%09//%20var%20random%20=%20seedrandom(1);%20//%20or%20any%20seed.%0A%20%20%20%20%09//%20var%20x%20=%20random();%20%20%20%20%20%20%20//%200%20%3C=%20x%20%3C%201.%20%20Every%20bit%20is%20random.%0A%20%20%20%20%09//%20var%20x%20=%20random.quick();%20//%200%20%3C=%20x%20%3C%201.%20%2032%20bits%20of%20randomness.%0A%0A%20%20%20%20%09//%20alea,%20a%2053-bit%20multiply-with-carry%20generator%20by%20Johannes%20Baag%C3%B8e.%0A%20%20%20%20%09//%20Period:%20~2%5E116%0A%20%20%20%20%09//%20Reported%20to%20pass%20all%20BigCrush%20tests.%0A%20%20%20%20%09var%20alea%20=%20requireAlea();%0A%0A%20%20%20%20%09//%20xor128,%20a%20pure%20xor-shift%20generator%20by%20George%20Marsaglia.%0A%20%20%20%20%09//%20Period:%202%5E128-1.%0A%20%20%20%20%09//%20Reported%20to%20fail:%20MatrixRank%20and%20LinearComp.%0A%20%20%20%20%09var%20xor128%20=%20requireXor128();%0A%0A%20%20%20%20%09//%20xorwow,%20George%20Marsaglia's%20160-bit%20xor-shift%20combined%20plus%20weyl.%0A%20%20%20%20%09//%20Period:%202%5E192-2%5E32%0A%20%20%20%20%09//%20Reported%20to%20fail:%20CollisionOver,%20SimpPoker,%20and%20LinearComp.%0A%20%20%20%20%09var%20xorwow%20=%20requireXorwow();%0A%0A%20%20%20%20%09//%20xorshift7,%20by%20Fran%C3%A7ois%20Panneton%20and%20Pierre%20L'ecuyer,%20takes%0A%20%20%20%20%09//%20a%20different%20approach:%20it%20adds%20robustness%20by%20allowing%20more%20shifts%0A%20%20%20%20%09//%20than%20Marsaglia's%20original%20three.%20%20It%20is%20a%207-shift%20generator%0A%20%20%20%20%09//%20with%20256%20bits,%20that%20passes%20BigCrush%20with%20no%20systmatic%20failures.%0A%20%20%20%20%09//%20Period%202%5E256-1.%0A%20%20%20%20%09//%20No%20systematic%20BigCrush%20failures%20reported.%0A%20%20%20%20%09var%20xorshift7%20=%20requireXorshift7();%0A%0A%20%20%20%20%09//%20xor4096,%20by%20Richard%20Brent,%20is%20a%204096-bit%20xor-shift%20with%20a%0A%20%20%20%20%09//%20very%20long%20period%20that%20also%20adds%20a%20Weyl%20generator.%20It%20also%20passes%0A%20%20%20%20%09//%20BigCrush%20with%20no%20systematic%20failures.%20%20Its%20long%20period%20may%0A%20%20%20%20%09//%20be%20useful%20if%20you%20have%20many%20generators%20and%20need%20to%20avoid%0A%20%20%20%20%09//%20collisions.%0A%20%20%20%20%09//%20Period:%202%5E4128-2%5E32.%0A%20%20%20%20%09//%20No%20systematic%20BigCrush%20failures%20reported.%0A%20%20%20%20%09var%20xor4096%20=%20requireXor4096();%0A%0A%20%20%20%20%09//%20Tyche-i,%20by%20Samuel%20Neves%20and%20Filipe%20Araujo,%20is%20a%20bit-shifting%20random%0A%20%20%20%20%09//%20number%20generator%20derived%20from%20ChaCha,%20a%20modern%20stream%20cipher.%0A%20%20%20%20%09//%20https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf%0A%20%20%20%20%09//%20Period:%20~2%5E127%0A%20%20%20%20%09//%20No%20systematic%20BigCrush%20failures%20reported.%0A%20%20%20%20%09var%20tychei%20=%20requireTychei();%0A%0A%20%20%20%20%09//%20The%20original%20ARC4-based%20prng%20included%20in%20this%20library.%0A%20%20%20%20%09//%20Period:%20~2%5E1600%0A%20%20%20%20%09var%20sr%20=%20requireSeedrandom$1();%0A%0A%20%20%20%20%09sr.alea%20=%20alea;%0A%20%20%20%20%09sr.xor128%20=%20xor128;%0A%20%20%20%20%09sr.xorwow%20=%20xorwow;%0A%20%20%20%20%09sr.xorshift7%20=%20xorshift7;%0A%20%20%20%20%09sr.xor4096%20=%20xor4096;%0A%20%20%20%20%09sr.tychei%20=%20tychei;%0A%0A%20%20%20%20%09seedrandom%20=%20sr;%0A%20%20%20%20%09return%20seedrandom;%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20seedrandomExports%20=%20requireSeedrandom();%0A%20%20%20%20var%20Seedrandom%20=%20/*@__PURE__*/getDefaultExportFromCjs(seedrandomExports);%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7BHTMLCanvasElement%7D%20canvas%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20domainKey%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20sessionKey%0A%20%20%20%20%20*%20@param%20%7Bany%7D%20getImageDataProxy%0A%20%20%20%20%20*%20@param%20%7BCanvasRenderingContext2D%20%7C%20WebGL2RenderingContext%20%7C%20WebGLRenderingContext%7D%20ctx?%0A%20%20%20%20%20*/%0A%20%20%20%20function%20computeOffScreenCanvas(canvas,%20domainKey,%20sessionKey,%20getImageDataProxy,%20ctx)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!ctx)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Type%20'null'%20is%20not%20assignable%20to%20type%20'CanvasRenderingContext2D%20%7C%20WebGL2RenderingContext%20%7C%20WebGLRenderingContext'.%0A%20%20%20%20%20%20%20%20%20%20%20%20ctx%20=%20canvas.getContext('2d');%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Make%20a%20off-screen%20canvas%20and%20put%20the%20data%20there%0A%20%20%20%20%20%20%20%20const%20offScreenCanvas%20=%20document.createElement('canvas');%0A%20%20%20%20%20%20%20%20offScreenCanvas.width%20=%20canvas.width;%0A%20%20%20%20%20%20%20%20offScreenCanvas.height%20=%20canvas.height;%0A%20%20%20%20%20%20%20%20const%20offScreenCtx%20=%20offScreenCanvas.getContext('2d');%0A%0A%20%20%20%20%20%20%20%20let%20rasterizedCtx%20=%20ctx;%0A%20%20%20%20%20%20%20%20//%20If%20we're%20not%20a%202d%20canvas%20we%20need%20to%20rasterise%20first%20into%202d%0A%20%20%20%20%20%20%20%20const%20rasterizeToCanvas%20=%20!(ctx%20instanceof%20CanvasRenderingContext2D);%0A%20%20%20%20%20%20%20%20if%20(rasterizeToCanvas)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Type%20'CanvasRenderingContext2D%20%7C%20null'%20is%20not%20assignable%20to%20type%20'CanvasRenderingContext2D%20%7C%20WebGL2RenderingContext%20%7C%20WebGLRenderingContext'.%0A%20%20%20%20%20%20%20%20%20%20%20%20rasterizedCtx%20=%20offScreenCtx;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20'offScreenCtx'%20is%20possibly%20'null'.%0A%20%20%20%20%20%20%20%20%20%20%20%20offScreenCtx.drawImage(canvas,%200,%200);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20We%20*always*%20compute%20the%20random%20pixels%20on%20the%20complete%20pixel%20set,%20then%20pass%20back%20the%20subset%20later%0A%20%20%20%20%20%20%20%20let%20imageData%20=%20getImageDataProxy._native.apply(rasterizedCtx,%20%5B0,%200,%20canvas.width,%20canvas.height%5D);%0A%20%20%20%20%20%20%20%20imageData%20=%20modifyPixelData(imageData,%20sessionKey,%20domainKey,%20canvas.width);%0A%0A%20%20%20%20%20%20%20%20if%20(rasterizeToCanvas)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20Type%20'null'%20is%20not%20assignable%20to%20type%20'CanvasRenderingContext2D'.%0A%20%20%20%20%20%20%20%20%20%20%20%20clearCanvas(offScreenCtx);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20'offScreenCtx'%20is%20possibly%20'null'.%0A%20%20%20%20%20%20%20%20offScreenCtx.putImageData(imageData,%200,%200);%0A%0A%20%20%20%20%20%20%20%20return%20%7B%20offScreenCanvas,%20offScreenCtx%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Clears%20the%20pixels%20from%20the%20canvas%20context%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@param%20%7BCanvasRenderingContext2D%7D%20canvasContext%0A%20%20%20%20%20*/%0A%20%20%20%20function%20clearCanvas(canvasContext)%20%7B%0A%20%20%20%20%20%20%20%20//%20Save%20state%20and%20clean%20the%20pixels%20from%20the%20canvas%0A%20%20%20%20%20%20%20%20canvasContext.save();%0A%20%20%20%20%20%20%20%20canvasContext.globalCompositeOperation%20=%20'destination-out';%0A%20%20%20%20%20%20%20%20canvasContext.fillStyle%20=%20'rgb(255,255,255)';%0A%20%20%20%20%20%20%20%20canvasContext.fillRect(0,%200,%20canvasContext.canvas.width,%20canvasContext.canvas.height);%0A%20%20%20%20%20%20%20%20canvasContext.restore();%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7Bimport(%22@canvas/image-data%22)%7D%20imageData%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20sessionKey%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20domainKey%0A%20%20%20%20%20*%20@param%20%7Bnumber%7D%20width%0A%20%20%20%20%20*/%0A%20%20%20%20function%20modifyPixelData(imageData,%20domainKey,%20sessionKey,%20width)%20%7B%0A%20%20%20%20%20%20%20%20const%20d%20=%20imageData.data;%0A%20%20%20%20%20%20%20%20const%20length%20=%20d.length%20/%204;%0A%20%20%20%20%20%20%20%20let%20checkSum%20=%200;%0A%20%20%20%20%20%20%20%20const%20mappingArray%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20for%20(let%20i%20=%200;%20i%20%3C%20length;%20i%20+=%204)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!shouldIgnorePixel(d,%20i)%20&&%20!adjacentSame(d,%20i,%20width))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mappingArray.push(i);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20checkSum%20+=%20d%5Bi%5D%20+%20d%5Bi%20+%201%5D%20+%20d%5Bi%20+%202%5D%20+%20d%5Bi%20+%203%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20windowHash%20=%20getDataKeySync(sessionKey,%20domainKey,%20checkSum);%0A%20%20%20%20%20%20%20%20const%20rng%20=%20new%20Seedrandom(windowHash);%0A%20%20%20%20%20%20%20%20for%20(let%20i%20=%200;%20i%20%3C%20mappingArray.length;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20rand%20=%20rng();%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20byte%20=%20Math.floor(rand%20*%2010);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20channel%20=%20byte%20%25%203;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20pixelCanvasIndex%20=%20mappingArray%5Bi%5D%20+%20channel;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20d%5BpixelCanvasIndex%5D%20=%20d%5BpixelCanvasIndex%5D%20%5E%20(byte%20&%200x1);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20imageData;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Ignore%20pixels%20that%20have%20neighbours%20that%20are%20the%20same%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@param%20%7BUint8ClampedArray%7D%20imageData%0A%20%20%20%20%20*%20@param%20%7Bnumber%7D%20index%0A%20%20%20%20%20*%20@param%20%7Bnumber%7D%20width%0A%20%20%20%20%20*/%0A%20%20%20%20function%20adjacentSame(imageData,%20index,%20width)%20%7B%0A%20%20%20%20%20%20%20%20const%20widthPixel%20=%20width%20*%204;%0A%20%20%20%20%20%20%20%20const%20x%20=%20index%20%25%20widthPixel;%0A%20%20%20%20%20%20%20%20const%20maxLength%20=%20imageData.length;%0A%0A%20%20%20%20%20%20%20%20//%20Pixels%20not%20on%20the%20right%20border%20of%20the%20canvas%0A%20%20%20%20%20%20%20%20if%20(x%20%3C%20widthPixel)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20right%20=%20index%20+%204;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!pixelsSame(imageData,%20index,%20right))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20diagonalRightUp%20=%20right%20-%20widthPixel;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(diagonalRightUp%20%3E%200%20&&%20!pixelsSame(imageData,%20index,%20diagonalRightUp))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20diagonalRightDown%20=%20right%20+%20widthPixel;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(diagonalRightDown%20%3C%20maxLength%20&&%20!pixelsSame(imageData,%20index,%20diagonalRightDown))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Pixels%20not%20on%20the%20left%20border%20of%20the%20canvas%0A%20%20%20%20%20%20%20%20if%20(x%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20left%20=%20index%20-%204;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!pixelsSame(imageData,%20index,%20left))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20diagonalLeftUp%20=%20left%20-%20widthPixel;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(diagonalLeftUp%20%3E%200%20&&%20!pixelsSame(imageData,%20index,%20diagonalLeftUp))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20diagonalLeftDown%20=%20left%20+%20widthPixel;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(diagonalLeftDown%20%3C%20maxLength%20&&%20!pixelsSame(imageData,%20index,%20diagonalLeftDown))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20up%20=%20index%20-%20widthPixel;%0A%20%20%20%20%20%20%20%20if%20(up%20%3E%200%20&&%20!pixelsSame(imageData,%20index,%20up))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20down%20=%20index%20+%20widthPixel;%0A%20%20%20%20%20%20%20%20if%20(down%20%3C%20maxLength%20&&%20!pixelsSame(imageData,%20index,%20down))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Check%20that%20a%20pixel%20at%20index%20and%20index2%20match%20all%20channels%0A%20%20%20%20%20*%20@param%20%7BUint8ClampedArray%7D%20imageData%0A%20%20%20%20%20*%20@param%20%7Bnumber%7D%20index%0A%20%20%20%20%20*%20@param%20%7Bnumber%7D%20index2%0A%20%20%20%20%20*/%0A%20%20%20%20function%20pixelsSame(imageData,%20index,%20index2)%20%7B%0A%20%20%20%20%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20imageData%5Bindex%5D%20===%20imageData%5Bindex2%5D%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20imageData%5Bindex%20+%201%5D%20===%20imageData%5Bindex2%20+%201%5D%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20imageData%5Bindex%20+%202%5D%20===%20imageData%5Bindex2%20+%202%5D%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20imageData%5Bindex%20+%203%5D%20===%20imageData%5Bindex2%20+%203%5D%0A%20%20%20%20%20%20%20%20);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Returns%20true%20if%20pixel%20should%20be%20ignored%0A%20%20%20%20%20*%20@param%20%7BUint8ClampedArray%7D%20imageData%0A%20%20%20%20%20*%20@param%20%7Bnumber%7D%20index%0A%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20shouldIgnorePixel(imageData,%20index)%20%7B%0A%20%20%20%20%20%20%20%20//%20Transparent%20pixels%0A%20%20%20%20%20%20%20%20if%20(imageData%5Bindex%20+%203%5D%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20FingerprintingCanvas%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20sessionKey,%20site%20%7D%20=%20args;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20domainKey%20=%20site.domain;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20supportsWebGl%20=%20this.getFeatureSettingEnabled('webGl');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20unsafeCanvases%20=%20new%20WeakSet();%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20canvasContexts%20=%20new%20WeakMap();%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20canvasCache%20=%20new%20WeakMap();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Clear%20cache%20as%20canvas%20has%20changed%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BOffscreenCanvas%20%7C%20HTMLCanvasElement%7D%20canvas%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20clearCache(canvas)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20canvasCache.delete(canvas);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BOffscreenCanvas%20%7C%20HTMLCanvasElement%7D%20canvas%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20treatAsUnsafe(canvas)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unsafeCanvases.add(canvas);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clearCache(canvas);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20proxy%20=%20new%20DDGProxy(this,%20HTMLCanvasElement.prototype,%20'getContext',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20context%20=%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20canvasContexts.set(thisArg,%20context);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20%7B%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20context;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20proxy.overload();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Known%20data%20methods%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20safeMethods%20=%20%5B'putImageData',%20'drawImage'%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20methodName%20of%20safeMethods)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20safeMethodProxy%20=%20new%20DDGProxy(this,%20CanvasRenderingContext2D.prototype,%20methodName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Don't%20apply%20escape%20hatch%20for%20canvases%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(methodName%20===%20'drawImage'%20&&%20args%5B0%5D%20&&%20args%5B0%5D%20instanceof%20HTMLCanvasElement)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20treatAsUnsafe(args%5B0%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clearCache(thisArg.canvas);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20safeMethodProxy.overload();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20unsafeMethods%20=%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'strokeRect',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'bezierCurveTo',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'quadraticCurveTo',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'arcTo',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'ellipse',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'rect',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'fill',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'stroke',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'lineTo',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'beginPath',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'closePath',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'arc',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'fillText',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'fillRect',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'strokeText',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'createConicGradient',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'createLinearGradient',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'createRadialGradient',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'createPattern',%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20methodName%20of%20unsafeMethods)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Some%20methods%20are%20browser%20specific%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(methodName%20in%20CanvasRenderingContext2D.prototype)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20unsafeProxy%20=%20new%20DDGProxy(this,%20CanvasRenderingContext2D.prototype,%20methodName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20treatAsUnsafe(thisArg.canvas);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unsafeProxy.overload();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(supportsWebGl)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20unsafeGlMethods%20=%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'commit',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'compileShader',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'shaderSource',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'attachShader',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'createProgram',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'linkProgram',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'drawElements',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'drawArrays',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20glContexts%20=%20%5BWebGLRenderingContext%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('WebGL2RenderingContext'%20in%20globalThis)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20glContexts.push(WebGL2RenderingContext);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20context%20of%20glContexts)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20methodName%20of%20unsafeGlMethods)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Some%20methods%20are%20browser%20specific%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(methodName%20in%20context.prototype)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20unsafeProxy%20=%20new%20DDGProxy(this,%20context.prototype,%20methodName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20treatAsUnsafe(thisArg.canvas);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unsafeProxy.overload();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Using%20proxies%20here%20to%20swallow%20calls%20to%20toString%20etc%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20getImageDataProxy%20=%20new%20DDGProxy(this,%20CanvasRenderingContext2D.prototype,%20'getImageData',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!unsafeCanvases.has(thisArg.canvas))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Anything%20we%20do%20here%20should%20be%20caught%20and%20ignored%20silently%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20offScreenCtx%20%7D%20=%20getCachedOffScreenCanvasOrCompute(thisArg.canvas,%20domainKey,%20sessionKey);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Call%20the%20original%20method%20on%20the%20modified%20off-screen%20canvas%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20offScreenCtx,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20%7B%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20getImageDataProxy.overload();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Get%20cached%20offscreen%20if%20one%20exists,%20otherwise%20compute%20one%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLCanvasElement%7D%20canvas%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20domainKey%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20sessionKey%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20getCachedOffScreenCanvasOrCompute(canvas,%20domainKey,%20sessionKey)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20result;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(canvasCache.has(canvas))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result%20=%20canvasCache.get(canvas);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20ctx%20=%20canvasContexts.get(canvas);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result%20=%20computeOffScreenCanvas(canvas,%20domainKey,%20sessionKey,%20getImageDataProxy,%20ctx);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20canvasCache.set(canvas,%20result);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20result;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20canvasMethods%20=%20%5B'toDataURL',%20'toBlob'%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20methodName%20of%20canvasMethods)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20proxy%20=%20new%20DDGProxy(this,%20HTMLCanvasElement.prototype,%20methodName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Short%20circuit%20for%20low%20risk%20canvas%20calls%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!unsafeCanvases.has(thisArg))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS18048:%20'thisArg'%20is%20possibly%20'undefined'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20offScreenCanvas%20%7D%20=%20getCachedOffScreenCanvasOrCompute(thisArg,%20domainKey,%20sessionKey);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Call%20the%20original%20method%20on%20the%20modified%20off-screen%20canvas%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20offScreenCanvas,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Something%20we%20did%20caused%20an%20exception,%20fall%20back%20to%20the%20native%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20proxy.overload();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20GoogleRejected%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('browsingTopics'%20in%20Document.prototype)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20Document.prototype.browsingTopics;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('joinAdInterestGroup'%20in%20Navigator.prototype)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20Navigator.prototype.joinAdInterestGroup;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('leaveAdInterestGroup'%20in%20Navigator.prototype)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20Navigator.prototype.leaveAdInterestGroup;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('updateAdInterestGroups'%20in%20Navigator.prototype)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20Navigator.prototype.updateAdInterestGroups;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('runAdAuction'%20in%20Navigator.prototype)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20Navigator.prototype.runAdAuction;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('adAuctionComponents'%20in%20Navigator.prototype)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20Navigator.prototype.adAuctionComponents;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Throw%20away%20this%20exception,%20it's%20likely%20a%20confict%20with%20another%20extension%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20Set%20Global%20Privacy%20Control%20property%20on%20DOM%0A%20%20%20%20class%20GlobalPrivacyControl%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20GPC%20on,%20set%20DOM%20property%20prototype%20to%20true%20if%20not%20already%20true%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(args.globalPrivacyControlValue)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(navigator.globalPrivacyControl)%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.defineProperty(Navigator.prototype,%20'globalPrivacyControl',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20GPC%20off%20&%20unsupported%20by%20browser,%20set%20DOM%20property%20prototype%20to%20false%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20this%20may%20be%20overwritten%20by%20the%20user%20agent%20or%20other%20extensions%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20navigator.globalPrivacyControl%20!==%20'undefined')%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.defineProperty(Navigator.prototype,%20'globalPrivacyControl',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Ignore%20exceptions%20that%20could%20be%20caused%20by%20conflicting%20with%20other%20extensions%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20FingerprintingHardware%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Navigator.prototype,%20'keyboard',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20error%20TS2554:%20Expected%202%20arguments,%20but%20got%201.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this.getFeatureAttr('keyboard');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Navigator.prototype,%20'hardwareConcurrency',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this.getFeatureAttr('hardwareConcurrency',%202);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Navigator.prototype,%20'deviceMemory',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this.getFeatureAttr('deviceMemory',%208);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20Referrer%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20the%20referer%20is%20a%20different%20host%20to%20the%20current%20one,%20trim%20it.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(document.referrer%20&&%20new%20URL(document.URL).hostname%20!==%20new%20URL(document.referrer).hostname)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20trim%20referrer%20to%20origin.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20trimmedReferer%20=%20new%20URL(document.referrer).origin%20+%20'/';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(Document.prototype,%20'referrer',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20trimmedReferer,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20FingerprintingScreenSize%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20origPropertyValues%20=%20%7B%7D;%0A%0A%20%20%20%20%20%20%20%20init()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20this.origPropertyValues.availTop%20=%20globalThis.screen.availTop;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Screen.prototype,%20'availTop',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20this.getFeatureAttr('availTop',%200),%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20this.origPropertyValues.availLeft%20=%20globalThis.screen.availLeft;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Screen.prototype,%20'availLeft',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20this.getFeatureAttr('availLeft',%200),%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.origPropertyValues.availWidth%20=%20globalThis.screen.availWidth;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20forcedAvailWidthValue%20=%20globalThis.screen.width;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Screen.prototype,%20'availWidth',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20forcedAvailWidthValue,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.origPropertyValues.availHeight%20=%20globalThis.screen.availHeight;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20forcedAvailHeightValue%20=%20globalThis.screen.height;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Screen.prototype,%20'availHeight',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20forcedAvailHeightValue,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.origPropertyValues.colorDepth%20=%20globalThis.screen.colorDepth;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Screen.prototype,%20'colorDepth',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20this.getFeatureAttr('colorDepth',%2024),%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.origPropertyValues.pixelDepth%20=%20globalThis.screen.pixelDepth;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(globalThis.Screen.prototype,%20'pixelDepth',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20this.getFeatureAttr('pixelDepth',%2024),%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20globalThis.window.addEventListener('resize',%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowDimensions();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowDimensions();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20normalize%20window%20dimensions,%20if%20more%20than%20one%20monitor%20is%20in%20play.%0A%20%20%20%20%20%20%20%20%20*%20%20X/Y%20values%20are%20set%20in%20the%20browser%20based%20on%20distance%20to%20the%20main%20monitor%20top%20or%20left,%20which%0A%20%20%20%20%20%20%20%20%20*%20can%20mean%20second%20or%20more%20monitors%20have%20very%20large%20or%20negative%20values.%20This%20function%20maps%20a%20given%0A%20%20%20%20%20%20%20%20%20*%20given%20coordinate%20value%20to%20the%20proper%20place%20on%20the%20main%20screen.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20normalizeWindowDimension(value,%20targetDimension)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(value%20%3E%20targetDimension)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20value%20%25%20targetDimension;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(value%20%3C%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20targetDimension%20+%20value;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20value;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20setWindowPropertyValue(property,%20value)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Here%20we%20don't%20update%20the%20prototype%20getter%20because%20the%20values%20are%20updated%20dynamically%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.defineProperty(globalThis,%20property,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20value,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20set:%20()%20=%3E%20%7B%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Fix%20window%20dimensions.%20The%20extension%20runs%20in%20a%20different%20JS%20context%20than%20the%0A%20%20%20%20%20%20%20%20%20*%20page,%20so%20we%20can%20inject%20the%20correct%20screen%20values%20as%20the%20window%20is%20resized,%0A%20%20%20%20%20%20%20%20%20*%20ensuring%20that%20no%20information%20is%20leaked%20as%20the%20dimensions%20change,%20but%20also%20that%20the%0A%20%20%20%20%20%20%20%20%20*%20values%20change%20correctly%20for%20valid%20use%20cases.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20setWindowDimensions()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20window%20=%20globalThis;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20top%20=%20globalThis.top;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20normalizedY%20=%20this.normalizeWindowDimension(window.screenY,%20window.screen.height);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20normalizedX%20=%20this.normalizeWindowDimension(window.screenX,%20window.screen.width);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(normalizedY%20%3C=%20this.origPropertyValues.availTop)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('screenY',%200);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('screenTop',%200);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('screenY',%20normalizedY);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('screenTop',%20normalizedY);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20%20error%20TS18047:%20'top'%20is%20possibly%20'null'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(top.window.outerHeight%20%3E=%20this.origPropertyValues.availHeight%20-%201)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20%20error%20TS18047:%20'top'%20is%20possibly%20'null'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('outerHeight',%20top.window.screen.height);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20%20error%20TS18047:%20'top'%20is%20possibly%20'null'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('outerHeight',%20top.window.outerHeight);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20top%20not%20accessible%20to%20certain%20iFrames,%20so%20ignore.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(normalizedX%20%3C=%20this.origPropertyValues.availLeft)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('screenX',%200);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('screenLeft',%200);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('screenX',%20normalizedX);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('screenLeft',%20normalizedX);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20%20error%20TS18047:%20'top'%20is%20possibly%20'null'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(top.window.outerWidth%20%3E=%20this.origPropertyValues.availWidth%20-%201)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20%20error%20TS18047:%20'top'%20is%20possibly%20'null'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('outerWidth',%20top.window.screen.width);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20-%20%20error%20TS18047:%20'top'%20is%20possibly%20'null'.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.setWindowPropertyValue('outerWidth',%20top.window.outerWidth);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20top%20not%20accessible%20to%20certain%20iFrames,%20so%20ignore.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20in%20a%20cross%20domain%20iFrame,%20top.window%20is%20not%20accessible.%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20FingerprintingTemporaryStorage%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20navigator%20=%20globalThis.navigator;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20Navigator%20=%20globalThis.Navigator;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Temporary%20storage%20can%20be%20used%20to%20determine%20hard%20disk%20usage%20and%20size.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20This%20will%20limit%20the%20max%20storage%20to%204GB%20without%20completely%20disabling%20the%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20feature.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(navigator.webkitTemporaryStorage)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20org%20=%20navigator.webkitTemporaryStorage.queryUsageAndQuota;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20tStorage%20=%20navigator.webkitTemporaryStorage;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tStorage.queryUsageAndQuota%20=%20function%20queryUsageAndQuota(callback,%20err)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20modifiedCallback%20=%20function%20(usedBytes,%20grantedBytes)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20maxBytesGranted%20=%204%20*%201024%20*%201024%20*%201024;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20spoofedGrantedBytes%20=%20Math.min(grantedBytes,%20maxBytesGranted);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20callback(usedBytes,%20spoofedGrantedBytes);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20org.call(navigator.webkitTemporaryStorage,%20modifiedCallback,%20err);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.defineProperty(Navigator.prototype,%20'webkitTemporaryStorage',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20tStorage,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7Bunknown%7D%20input%0A%20%20%20%20%20*%20@return%20%7Binput%20is%20Object%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isObject(input)%20%7B%0A%20%20%20%20%20%20%20%20return%20toString.call(input)%20===%20'%5Bobject%20Object%5D';%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7Bunknown%7D%20input%0A%20%20%20%20%20*%20@return%20%7Binput%20is%20string%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isString(input)%20%7B%0A%20%20%20%20%20%20%20%20return%20typeof%20input%20===%20'string';%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@import%20%7B%20Messaging%20%7D%20from%20%22@duckduckgo/messaging%22;%0A%20%20%20%20%20*%20@typedef%20%7BPick%3CMessaging,%20'notify'%20%7C%20'request'%20%7C%20'subscribe'%3E%7D%20MessagingInterface%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Sending%20this%20event%0A%20%20%20%20%20*/%0A%20%20%20%20class%20InstallProxy%20%7B%0A%20%20%20%20%20%20%20%20static%20NAME%20=%20'INSTALL_BRIDGE';%0A%20%20%20%20%20%20%20%20get%20name()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20InstallProxy.NAME;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.id%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.id%20=%20params.id;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bunknown%7D%20params%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20create(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isObject(params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.featureName))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.id))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20InstallProxy(%7B%20featureName:%20params.featureName,%20id:%20params.id%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20DidInstall%20%7B%0A%20%20%20%20%20%20%20%20static%20NAME%20=%20'DID_INSTALL';%0A%20%20%20%20%20%20%20%20get%20name()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20DidInstall.NAME;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.id%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.id%20=%20params.id;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bunknown%7D%20params%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20create(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isObject(params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.id))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20DidInstall(%7B%20id:%20params.id%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20ProxyRequest%20%7B%0A%20%20%20%20%20%20%20%20static%20NAME%20=%20'PROXY_REQUEST';%0A%20%20%20%20%20%20%20%20get%20name()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20ProxyRequest.NAME;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.method%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.id%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bparams.params%5D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.method%20=%20params.method;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.params%20=%20params.params;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.id%20=%20params.id;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bunknown%7D%20params%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20create(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isObject(params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.featureName))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.method))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.id))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(params.params%20&&%20!isObject(params.params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20ProxyRequest(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName:%20params.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20method:%20params.method,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params:%20params.params,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id:%20params.id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20ProxyResponse%20%7B%0A%20%20%20%20%20%20%20%20static%20NAME%20=%20'PROXY_RESPONSE';%0A%20%20%20%20%20%20%20%20get%20name()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20ProxyResponse.NAME;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.method%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.id%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bparams.result%5D%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport(%22@duckduckgo/messaging%22).MessageError%7D%20%5Bparams.error%5D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.method%20=%20params.method;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.result%20=%20params.result;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.error%20=%20params.error;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.id%20=%20params.id;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bunknown%7D%20params%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20create(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isObject(params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.featureName))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.method))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.id))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(params.result%20&&%20!isObject(params.result))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(params.error%20&&%20!isObject(params.error))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20ProxyResponse(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName:%20params.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20method:%20params.method,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result:%20params.result,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20error:%20params.error,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id:%20params.id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*/%0A%20%20%20%20class%20ProxyNotification%20%7B%0A%20%20%20%20%20%20%20%20static%20NAME%20=%20'PROXY_NOTIFICATION';%0A%20%20%20%20%20%20%20%20get%20name()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20ProxyNotification.NAME;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.method%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bparams.params%5D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.method%20=%20params.method;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.params%20=%20params.params;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bunknown%7D%20params%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20create(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isObject(params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.featureName))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.method))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(params.params%20&&%20!isObject(params.params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20ProxyNotification(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName:%20params.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20method:%20params.method,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params:%20params.params,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20SubscriptionRequest%20%7B%0A%20%20%20%20%20%20%20%20static%20NAME%20=%20'SUBSCRIPTION_REQUEST';%0A%20%20%20%20%20%20%20%20get%20name()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20SubscriptionRequest.NAME;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.subscriptionName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.id%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.subscriptionName%20=%20params.subscriptionName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.id%20=%20params.id;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bunknown%7D%20params%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20create(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isObject(params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.featureName))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.subscriptionName))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.id))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20SubscriptionRequest(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName:%20params.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20subscriptionName:%20params.subscriptionName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id:%20params.id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20SubscriptionResponse%20%7B%0A%20%20%20%20%20%20%20%20static%20NAME%20=%20'SUBSCRIPTION_RESPONSE';%0A%20%20%20%20%20%20%20%20get%20name()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20SubscriptionResponse.NAME;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.featureName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.subscriptionName%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.id%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20%5Bparams.params%5D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.featureName%20=%20params.featureName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.subscriptionName%20=%20params.subscriptionName;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.id%20=%20params.id;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.params%20=%20params.params;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bunknown%7D%20params%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20create(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isObject(params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.featureName))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.subscriptionName))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.id))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(params.params%20&&%20!isObject(params.params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20SubscriptionResponse(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName:%20params.featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20subscriptionName:%20params.subscriptionName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params:%20params.params,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id:%20params.id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20SubscriptionUnsubscribe%20%7B%0A%20%20%20%20%20%20%20%20static%20NAME%20=%20'SUBSCRIPTION_UNSUBSCRIBE';%0A%20%20%20%20%20%20%20%20get%20name()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20SubscriptionUnsubscribe.NAME;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.id%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.id%20=%20params.id;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bunknown%7D%20params%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20create(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isObject(params))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isString(params.id))%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20SubscriptionUnsubscribe(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id:%20params.id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@import%20%7B%20MessagingInterface%20%7D%20from%20%22./schema.js%22%0A%20%20%20%20%20*%20@typedef%20%7BPick%3Cimport(%22../../captured-globals.js%22),%0A%20%20%20%20%20*%20%20%20%20%22dispatchEvent%22%20%7C%20%22addEventListener%22%20%7C%20%22removeEventListener%22%20%7C%20%22CustomEvent%22%20%7C%20%22String%22%20%7C%20%22Error%22%20%7C%20%22randomUUID%22%3E%0A%20%20%20%20%20*%20%7D%20Captured%0A%20%20%20%20%20*/%0A%20%20%20%20/**%20@type%20%7BCaptured%7D%20*/%0A%20%20%20%20const%20captured%20=%20capturedGlobals;%0A%0A%20%20%20%20const%20ERROR_MSG%20=%20'Did%20not%20install%20Message%20Bridge';%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Try%20to%20create%20a%20message%20bridge.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20Note:%20This%20will%20throw%20an%20exception%20if%20the%20bridge%20cannot%20be%20established.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20featureName%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5Btoken%5D%0A%20%20%20%20%20*%20@return%20%7BMessagingInterface%7D%0A%20%20%20%20%20*%20@throws%20%7BError%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20createPageWorldBridge(featureName,%20token)%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20This%20feature%20never%20operates%20without%20a%20featureName%20or%20token%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20if%20(typeof%20featureName%20!==%20'string'%20%7C%7C%20!token)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20captured.Error(ERROR_MSG);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20This%20feature%20never%20operates%20in%20a%20frame%20or%20insecure%20context%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20if%20(isBeingFramed()%20%7C%7C%20!isSecureContext)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20captured.Error(ERROR_MSG);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20eventName%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7B%60$%7Bstring%7D-$%7Bstring%7D%60%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20const%20appendToken%20=%20(eventName)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%60$%7BeventName%7D-$%7Btoken%7D%60;%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Create%20the%20sender%20to%20centralize%20the%20sending%20logic%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B%7Bname:%20string%7D%20&%20Record%3Cstring,%20any%3E%7D%20incoming%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20const%20send%20=%20(incoming)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20when%20the%20token%20is%20absent,%20just%20silently%20fail%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!token)%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20event%20=%20new%20captured.CustomEvent(appendToken(incoming.name),%20%7B%20detail:%20incoming%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20captured.dispatchEvent(event);%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Events%20are%20synchronous%20(even%20across%20contexts),%20so%20we%20can%20figure%20out%0A%20%20%20%20%20%20%20%20%20*%20the%20result%20of%20installing%20the%20proxy%20before%20we%20return%20and%20give%20a%0A%20%20%20%20%20%20%20%20%20*%20better%20experience%20for%20consumers%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20let%20installed%20=%20false;%0A%20%20%20%20%20%20%20%20const%20id%20=%20random();%0A%20%20%20%20%20%20%20%20const%20evt%20=%20new%20InstallProxy(%7B%20featureName,%20id%20%7D);%0A%20%20%20%20%20%20%20%20const%20evtName%20=%20appendToken(DidInstall.NAME%20+%20'-'%20+%20id);%0A%20%20%20%20%20%20%20%20const%20didInstall%20=%20(/**%20@type%20%7BCustomEvent%3Cunknown%3E%7D%20*/%20e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20result%20=%20DidInstall.create(e.detail);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(result%20&&%20result.id%20===%20id)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20installed%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20captured.removeEventListener(evtName,%20didInstall);%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20captured.addEventListener(evtName,%20didInstall);%0A%20%20%20%20%20%20%20%20send(evt);%0A%0A%20%20%20%20%20%20%20%20if%20(!installed)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20leaving%20this%20as%20a%20generic%20message%20for%20now%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20captured.Error(ERROR_MSG);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20createMessagingInterface(featureName,%20send,%20appendToken);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20We%20are%20executing%20exclusively%20in%20secure%20contexts,%20so%20this%20should%20never%20fail%0A%20%20%20%20%20*/%0A%20%20%20%20function%20random()%20%7B%0A%20%20%20%20%20%20%20%20if%20(typeof%20captured.randomUUID%20!==%20'function')%20throw%20new%20Error('unreachable');%0A%20%20%20%20%20%20%20%20return%20captured.randomUUID();%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20featureName%0A%20%20%20%20%20*%20@param%20%7B(evt:%20%7Bname:%20string%7D%20&%20Record%3Cstring,%20any%3E)%20=%3E%20void%7D%20send%0A%20%20%20%20%20*%20@param%20%7B(s:%20string)%20=%3E%20string%7D%20appendToken%0A%20%20%20%20%20*%20@returns%20%7BMessagingInterface%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20createMessagingInterface(featureName,%20send,%20appendToken)%20%7B%0A%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20method%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20params%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20notify(method,%20params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20send(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new%20ProxyNotification(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20method,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20method%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7BRecord%3Cstring,%20any%3E%7D%20params%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPromise%3Cany%3E%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20request(method,%20params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20id%20=%20random();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20send(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new%20ProxyRequest(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20method,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20params,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20Promise((resolve,%20reject)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20responseName%20=%20appendToken(ProxyResponse.NAME%20+%20'-'%20+%20id);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20handler%20=%20(/**%20@type%20%7BCustomEvent%3Cunknown%3E%7D%20*/%20e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20response%20=%20ProxyResponse.create(e.detail);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(response%20&&%20response.id%20===%20id)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('error'%20in%20response%20&&%20response.error)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20reject(new%20Error(response.error.message));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20('result'%20in%20response)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resolve(response.result);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20captured.removeEventListener(responseName,%20handler);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20captured.addEventListener(responseName,%20handler);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20name%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7B(d:%20any)%20=%3E%20void%7D%20callback%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@returns%20%7B()%20=%3E%20void%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20subscribe(name,%20callback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20id%20=%20random();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20send(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new%20SubscriptionRequest(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20subscriptionName:%20name,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureName,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20handler%20=%20(/**%20@type%20%7BCustomEvent%3Cunknown%3E%7D%20*/%20e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20subscriptionEvent%20=%20SubscriptionResponse.create(e.detail);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(subscriptionEvent)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20id:%20eventId,%20params%20%7D%20=%20subscriptionEvent;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(eventId%20===%20id)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20callback(params);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20type%20=%20appendToken(SubscriptionResponse.NAME%20+%20'-'%20+%20id);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20captured.addEventListener(type,%20handler);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20captured.removeEventListener(type,%20handler);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20evt%20=%20new%20SubscriptionUnsubscribe(%7B%20id%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20send(evt);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20NavigatorInterface%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20load(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error:%20Accessing%20private%20method%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.matchDomainFeatureSetting('privilegedDomains').length)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.injectNavigatorInterface(args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20init(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.injectNavigatorInterface(args);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20injectNavigatorInterface(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(navigator.duckduckgo)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!args.platform%20%7C%7C%20!args.platform.name)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.defineProperty(Navigator.prototype,%20'duckduckgo',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20platform:%20args.platform.name,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20isDuckDuckGo()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGPromise.resolve(true);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@import%20%7B%20MessagingInterface%20%7D%20from%20%22./message-bridge/schema.js%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20featureName%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@return%20%7BMessagingInterface%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@throws%20%7BError%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20createMessageBridge(featureName)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20createPageWorldBridge(featureName,%20args.messageSecret);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20enumerable:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurable:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20writable:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20todo:%20Just%20ignore%20this%20exception?%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20let%20adLabelStrings%20=%20%5B%5D;%0A%20%20%20%20const%20parser%20=%20new%20DOMParser();%0A%20%20%20%20let%20hiddenElements%20=%20new%20WeakMap();%0A%20%20%20%20let%20modifiedElements%20=%20new%20WeakMap();%0A%20%20%20%20let%20appliedRules%20=%20new%20Set();%0A%20%20%20%20let%20shouldInjectStyleTag%20=%20false;%0A%20%20%20%20let%20mediaAndFormSelectors%20=%20'video,canvas,embed,object,audio,map,form,input,textarea,select,option,button';%0A%20%20%20%20let%20hideTimeouts%20=%20%5B0,%20100,%20300,%20500,%201000,%202000,%203000%5D;%0A%20%20%20%20let%20unhideTimeouts%20=%20%5B1250,%202250,%203000%5D;%0A%0A%20%20%20%20/**%20@type%20%7BElementHiding%7D%20*/%0A%20%20%20%20let%20featureInstance;%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Hide%20DOM%20element%20if%20rule%20conditions%20met%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20element%0A%20%20%20%20%20*%20@param%20%7BObject%7D%20rule%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20%5BpreviousElement%5D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20collapseDomNode(element,%20rule,%20previousElement)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!element)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20const%20type%20=%20rule.type;%0A%20%20%20%20%20%20%20%20const%20alreadyHidden%20=%20hiddenElements.has(element);%0A%20%20%20%20%20%20%20%20const%20alreadyModified%20=%20modifiedElements.has(element)%20&&%20modifiedElements.get(element)%20===%20rule.type;%0A%20%20%20%20%20%20%20%20//%20return%20if%20the%20element%20has%20already%20been%20hidden,%20or%20modified%20by%20the%20same%20rule%20type%0A%20%20%20%20%20%20%20%20if%20(alreadyHidden%20%7C%7C%20alreadyModified)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20switch%20(type)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20'hide':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hideNode(element);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20'hide-empty':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(isDomNodeEmpty(element))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hideNode(element);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20appliedRules.add(rule);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20'closest-empty':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20hide%20the%20outermost%20empty%20node%20so%20that%20we%20may%20unhide%20if%20ad%20loads%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(isDomNodeEmpty(element))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20collapseDomNode(element.parentNode,%20rule,%20element);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(previousElement)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hideNode(previousElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20appliedRules.add(rule);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20'modify-attr':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20modifyAttribute(element,%20rule.values);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20'modify-style':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20modifyStyle(element,%20rule.values);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Unhide%20previously%20hidden%20DOM%20element%20if%20content%20loaded%20into%20it%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20element%0A%20%20%20%20%20*%20@param%20%7BObject%7D%20rule%0A%20%20%20%20%20*/%0A%20%20%20%20function%20expandNonEmptyDomNode(element,%20rule)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!element)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20const%20type%20=%20rule.type;%0A%0A%20%20%20%20%20%20%20%20const%20alreadyHidden%20=%20hiddenElements.has(element);%0A%0A%20%20%20%20%20%20%20%20switch%20(type)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20'hide':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20only%20care%20about%20rule%20types%20that%20specifically%20apply%20to%20empty%20elements%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20'hide-empty':%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20'closest-empty':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(alreadyHidden%20&&%20!isDomNodeEmpty(element))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unhideNode(element);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(type%20===%20'closest-empty')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20iterate%20upwards%20from%20matching%20DOM%20elements%20until%20we%20arrive%20at%20previously%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20hidden%20element.%20Unhide%20element%20if%20it%20contains%20visible%20content.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20expandNonEmptyDomNode(element.parentNode,%20rule);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Hide%20DOM%20element%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20element%0A%20%20%20%20%20*/%0A%20%20%20%20function%20hideNode(element)%20%7B%0A%20%20%20%20%20%20%20%20//%20maintain%20a%20reference%20to%20each%20hidden%20element%20along%20with%20the%20properties%0A%20%20%20%20%20%20%20%20//%20that%20are%20being%20overwritten%0A%20%20%20%20%20%20%20%20const%20cachedDisplayProperties%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20display:%20element.style.display,%0A%20%20%20%20%20%20%20%20%20%20%20%20'min-height':%20element.style.minHeight,%0A%20%20%20%20%20%20%20%20%20%20%20%20height:%20element.style.height,%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20hiddenElements.set(element,%20cachedDisplayProperties);%0A%0A%20%20%20%20%20%20%20%20//%20apply%20styles%20to%20hide%20element%0A%20%20%20%20%20%20%20%20element.style.setProperty('display',%20'none',%20'important');%0A%20%20%20%20%20%20%20%20element.style.setProperty('min-height',%20'0px',%20'important');%0A%20%20%20%20%20%20%20%20element.style.setProperty('height',%20'0px',%20'important');%0A%20%20%20%20%20%20%20%20element.hidden%20=%20true;%0A%20%20%20%20%20%20%20%20//%20add%20debug%20flag%20to%20site%20breakage%20reports%0A%20%20%20%20%20%20%20%20featureInstance.addDebugFlag();%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Show%20previously%20hidden%20DOM%20element%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20element%0A%20%20%20%20%20*/%0A%20%20%20%20function%20unhideNode(element)%20%7B%0A%20%20%20%20%20%20%20%20const%20cachedDisplayProperties%20=%20hiddenElements.get(element);%0A%20%20%20%20%20%20%20%20if%20(!cachedDisplayProperties)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20for%20(const%20prop%20in%20cachedDisplayProperties)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20element.style.setProperty(prop,%20cachedDisplayProperties%5Bprop%5D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20hiddenElements.delete(element);%0A%20%20%20%20%20%20%20%20element.hidden%20=%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Check%20if%20DOM%20element%20contains%20visible%20content%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20node%0A%20%20%20%20%20*/%0A%20%20%20%20function%20isDomNodeEmpty(node)%20%7B%0A%20%20%20%20%20%20%20%20//%20no%20sense%20wasting%20cycles%20checking%20if%20the%20page's%20body%20element%20is%20empty%0A%20%20%20%20%20%20%20%20if%20(node.tagName%20===%20'BODY')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20//%20use%20a%20DOMParser%20to%20remove%20all%20metadata%20elements%20before%20checking%20if%0A%20%20%20%20%20%20%20%20//%20the%20node%20is%20empty.%0A%20%20%20%20%20%20%20%20const%20parsedNode%20=%20parser.parseFromString(node.outerHTML,%20'text/html').documentElement;%0A%20%20%20%20%20%20%20%20parsedNode.querySelectorAll('base,link,meta,script,style,template,title,desc').forEach((el)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20el.remove();%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20const%20visibleText%20=%20parsedNode.innerText.trim().toLocaleLowerCase().replace(/:$/,%20'');%0A%20%20%20%20%20%20%20%20const%20mediaAndFormContent%20=%20parsedNode.querySelector(mediaAndFormSelectors);%0A%20%20%20%20%20%20%20%20const%20frameElements%20=%20%5B...parsedNode.querySelectorAll('iframe')%5D;%0A%20%20%20%20%20%20%20%20//%20query%20original%20node%20instead%20of%20parsedNode%20for%20img%20elements%20since%20heuristic%20relies%0A%20%20%20%20%20%20%20%20//%20on%20size%20of%20image%20elements%0A%20%20%20%20%20%20%20%20const%20imageElements%20=%20%5B...node.querySelectorAll('img,svg')%5D;%0A%20%20%20%20%20%20%20%20//%20about:blank%20iframes%20don't%20count%20as%20content,%20return%20true%20if:%0A%20%20%20%20%20%20%20%20//%20-%20node%20doesn't%20contain%20any%20iframes%0A%20%20%20%20%20%20%20%20//%20-%20node%20contains%20iframes,%20all%20of%20which%20are%20hidden%20or%20have%20src='about:blank'%0A%20%20%20%20%20%20%20%20const%20noFramesWithContent%20=%20frameElements.every((frame)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20frame.hidden%20%7C%7C%20frame.src%20===%20'about:blank';%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20//%20ad%20containers%20often%20contain%20tracking%20pixels%20and%20other%20small%20images%20(eg%20adchoices%20logo).%0A%20%20%20%20%20%20%20%20//%20these%20should%20be%20treated%20as%20empty%20and%20hidden,%20but%20real%20images%20should%20not.%0A%20%20%20%20%20%20%20%20const%20visibleImages%20=%20imageElements.some((image)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20image.getBoundingClientRect().width%20%3E%2020%20%7C%7C%20image.getBoundingClientRect().height%20%3E%2020;%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20if%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20(visibleText%20===%20''%20%7C%7C%20adLabelStrings.includes(visibleText))%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20mediaAndFormContent%20===%20null%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20noFramesWithContent%20&&%0A%20%20%20%20%20%20%20%20%20%20%20%20!visibleImages%0A%20%20%20%20%20%20%20%20)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Modify%20specified%20attribute(s)%20on%20element%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20element%0A%20%20%20%20%20*%20@param%20%7BObject%5B%5D%7D%20values%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20values%5B%5D.property%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20values%5B%5D.value%0A%20%20%20%20%20*/%0A%20%20%20%20function%20modifyAttribute(element,%20values)%20%7B%0A%20%20%20%20%20%20%20%20values.forEach((item)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20element.setAttribute(item.property,%20item.value);%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20modifiedElements.set(element,%20'modify-attr');%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Modify%20specified%20style(s)%20on%20element%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20element%0A%20%20%20%20%20*%20@param%20%7BObject%5B%5D%7D%20values%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20values%5B%5D.property%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20values%5B%5D.value%0A%20%20%20%20%20*/%0A%20%20%20%20function%20modifyStyle(element,%20values)%20%7B%0A%20%20%20%20%20%20%20%20values.forEach((item)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20element.style.setProperty(item.property,%20item.value,%20'important');%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20modifiedElements.set(element,%20'modify-style');%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Separate%20strict%20hide%20rules%20to%20inject%20as%20style%20tag%20if%20enabled%0A%20%20%20%20%20*%20@param%20%7BObject%5B%5D%7D%20rules%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20rules%5B%5D.selector%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20rules%5B%5D.type%0A%20%20%20%20%20*/%0A%20%20%20%20function%20extractTimeoutRules(rules)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!shouldInjectStyleTag)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20rules;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20strictHideRules%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20const%20timeoutRules%20=%20%5B%5D;%0A%0A%20%20%20%20%20%20%20%20rules.forEach((rule)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(rule.type%20===%20'hide')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20strictHideRules.push(rule);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20timeoutRules.push(rule);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20injectStyleTag(strictHideRules);%0A%20%20%20%20%20%20%20%20return%20timeoutRules;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20styletag%20for%20strict%20hide%20rules%20and%20append%20it%20to%20the%20document%0A%20%20%20%20%20*%20@param%20%7BObject%5B%5D%7D%20rules%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20rules%5B%5D.selector%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20rules%5B%5D.type%0A%20%20%20%20%20*/%0A%20%20%20%20function%20injectStyleTag(rules)%20%7B%0A%20%20%20%20%20%20%20%20//%20wrap%20selector%20list%20in%20:is(...)%20to%20make%20it%20a%20forgiving%20selector%20list.%20this%20enables%0A%20%20%20%20%20%20%20%20//%20us%20to%20use%20selectors%20not%20supported%20in%20all%20browsers,%20eg%20:has%20in%20Firefox%0A%20%20%20%20%20%20%20%20let%20selector%20=%20'';%0A%0A%20%20%20%20%20%20%20%20rules.forEach((rule,%20i)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(i%20!==%20rules.length%20-%201)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selector%20=%20selector.concat(rule.selector,%20',');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selector%20=%20selector.concat(rule.selector);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20const%20styleTagProperties%20=%20'display:none!important;min-height:0!important;height:0!important;';%0A%20%20%20%20%20%20%20%20const%20styleTagContents%20=%20%60$%7BforgivingSelector(selector)%7D%20%7B$%7BstyleTagProperties%7D%7D%60;%0A%0A%20%20%20%20%20%20%20%20injectGlobalStyles(styleTagContents);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Apply%20list%20of%20active%20element%20hiding%20rules%20to%20page%0A%20%20%20%20%20*%20@param%20%7BObject%5B%5D%7D%20rules%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20rules%5B%5D.selector%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20rules%5B%5D.type%0A%20%20%20%20%20*/%0A%20%20%20%20function%20hideAdNodes(rules)%20%7B%0A%20%20%20%20%20%20%20%20const%20document%20=%20globalThis.document;%0A%0A%20%20%20%20%20%20%20%20rules.forEach((rule)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20selector%20=%20forgivingSelector(rule.selector);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20matchingElementArray%20=%20%5B...document.querySelectorAll(selector)%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20matchingElementArray.forEach((element)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20collapseDomNode(element,%20rule);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Iterate%20over%20previously%20hidden%20elements,%20unhiding%20if%20content%20has%20loaded%20into%20them%0A%20%20%20%20%20*/%0A%20%20%20%20function%20unhideLoadedAds()%20%7B%0A%20%20%20%20%20%20%20%20const%20document%20=%20globalThis.document;%0A%0A%20%20%20%20%20%20%20%20appliedRules.forEach((rule)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20selector%20=%20forgivingSelector(rule.selector);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20matchingElementArray%20=%20%5B...document.querySelectorAll(selector)%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20matchingElementArray.forEach((element)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20expandNonEmptyDomNode(element,%20rule);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Wrap%20selector(s)%20in%20:is(..)%20to%20make%20them%20forgiving%0A%20%20%20%20%20*/%0A%20%20%20%20function%20forgivingSelector(selector)%20%7B%0A%20%20%20%20%20%20%20%20return%20%60:is($%7Bselector%7D)%60;%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20ElementHiding%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/no-this-alias%0A%20%20%20%20%20%20%20%20%20%20%20%20featureInstance%20=%20this;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(isBeingFramed())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20activeRules;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20globalRules%20=%20this.getFeatureSetting('rules');%0A%20%20%20%20%20%20%20%20%20%20%20%20adLabelStrings%20=%20this.getFeatureSetting('adLabelStrings');%0A%20%20%20%20%20%20%20%20%20%20%20%20shouldInjectStyleTag%20=%20this.getFeatureSetting('useStrictHideStyleTag');%0A%20%20%20%20%20%20%20%20%20%20%20%20hideTimeouts%20=%20this.getFeatureSetting('hideTimeouts')%20%7C%7C%20hideTimeouts;%0A%20%20%20%20%20%20%20%20%20%20%20%20unhideTimeouts%20=%20this.getFeatureSetting('unhideTimeouts')%20%7C%7C%20unhideTimeouts;%0A%20%20%20%20%20%20%20%20%20%20%20%20mediaAndFormSelectors%20=%20this.getFeatureSetting('mediaAndFormSelectors')%20%7C%7C%20mediaAndFormSelectors;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20determine%20whether%20strict%20hide%20rules%20should%20be%20injected%20as%20a%20style%20tag%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(shouldInjectStyleTag)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error:%20Accessing%20private%20method%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20shouldInjectStyleTag%20=%20this.matchDomainFeatureSetting('styleTagExceptions').length%20===%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20collect%20all%20matching%20rules%20for%20domain%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error:%20Accessing%20private%20method%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20activeDomainRules%20=%20this.matchDomainFeatureSetting('domains').flatMap((item)%20=%3E%20item.rules);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20overrideRules%20=%20activeDomainRules.filter((rule)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20rule.type%20===%20'override';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20disableDefault%20=%20activeDomainRules.some((rule)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20rule.type%20===%20'disable-default';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20if%20rule%20with%20type%20'disable-default'%20is%20present,%20ignore%20all%20global%20rules%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(disableDefault)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20activeRules%20=%20activeDomainRules.filter((rule)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20rule.type%20!==%20'disable-default';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20activeRules%20=%20activeDomainRules.concat(globalRules);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20remove%20overrides%20and%20rules%20that%20match%20overrides%20from%20array%20of%20rules%20to%20be%20applied%20to%20page%0A%20%20%20%20%20%20%20%20%20%20%20%20overrideRules.forEach((override)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20activeRules%20=%20activeRules.filter((rule)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20rule.selector%20!==%20override.selector;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20applyRules%20=%20this.applyRules.bind(this);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20now%20have%20the%20final%20list%20of%20rules%20to%20apply,%20so%20we%20apply%20them%20when%20document%20is%20loaded%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(document.readyState%20===%20'loading')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20window.addEventListener('DOMContentLoaded',%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20applyRules(activeRules);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20applyRules(activeRules);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20single%20page%20applications%20don't%20have%20a%20DOMContentLoaded%20event%20on%20navigations,%20so%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20we%20use%20proxy/reflect%20on%20history.pushState%20to%20call%20applyRules%20on%20page%20navigations%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20historyMethodProxy%20=%20new%20DDGProxy(this,%20History.prototype,%20'pushState',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20apply(target,%20thisArg,%20args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20applyRules(activeRules);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20DDGReflect.apply(target,%20thisArg,%20args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20historyMethodProxy.overload();%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20listen%20for%20popstate%20events%20in%20order%20to%20run%20on%20back/forward%20navigations%0A%20%20%20%20%20%20%20%20%20%20%20%20window.addEventListener('popstate',%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20applyRules(activeRules);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Apply%20relevant%20hiding%20rules%20to%20page%20at%20set%20intervals%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BObject%5B%5D%7D%20rules%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20rules%5B%5D.selector%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20rules%5B%5D.type%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20applyRules(rules)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20timeoutRules%20=%20extractTimeoutRules(rules);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20clearCacheTimer%20=%20unhideTimeouts.concat(hideTimeouts).reduce((a,%20b)%20=%3E%20Math.max(a,%20b),%200)%20+%20100;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20several%20passes%20are%20made%20to%20hide%20&%20unhide%20elements.%20this%20is%20necessary%20because%20we're%20not%20using%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20a%20mutation%20observer%20but%20we%20want%20to%20hide/unhide%20elements%20as%20soon%20as%20possible,%20and%20ads%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20frequently%20take%20from%20several%20hundred%20milliseconds%20to%20several%20seconds%20to%20load%0A%20%20%20%20%20%20%20%20%20%20%20%20hideTimeouts.forEach((timeout)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20setTimeout(()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hideAdNodes(timeoutRules);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%20timeout);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20check%20previously%20hidden%20ad%20elements%20for%20contents,%20unhide%20if%20content%20has%20loaded%20after%20hiding.%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20we%20do%20this%20in%20order%20to%20display%20non-tracking%20ads%20that%20aren't%20blocked%20at%20the%20request%20level%0A%20%20%20%20%20%20%20%20%20%20%20%20unhideTimeouts.forEach((timeout)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20setTimeout(()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20@ts-expect-error%20https://app.asana.com/0/1201614831475344/1203979574128023/f%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unhideLoadedAds();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%20timeout);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20clear%20appliedRules%20and%20hiddenElements%20caches%20once%20all%20checks%20have%20run%0A%20%20%20%20%20%20%20%20%20%20%20%20setTimeout(()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20appliedRules%20=%20new%20Set();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hiddenElements%20=%20new%20WeakMap();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20modifiedElements%20=%20new%20WeakMap();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%20clearCacheTimer);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20ExceptionHandler%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Report%20to%20the%20debugger%20panel%20if%20an%20uncaught%20exception%20occurs%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20handleUncaughtException%20=%20(e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20postDebugMessage(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'jsException',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20documentUrl:%20document.location.href,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20message:%20e.message,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20filename:%20e.filename,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lineno:%20e.lineno,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20colno:%20e.colno,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20stack:%20e.error?.stack,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.addDebugFlag();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20globalThis.addEventListener('error',%20handleUncaughtException);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20This%20feature%20allows%20remote%20configuration%20of%20APIs%20that%20exist%20within%20the%20DOM.%0A%20%20%20%20%20*%20We%20support%20removal%20of%20APIs%20and%20returning%20different%20values%20from%20getters.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@module%20API%20manipulation%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@internal%0A%20%20%20%20%20*/%0A%20%20%20%20class%20ApiManipulation%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20init()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20apiChanges%20=%20this.getFeatureSetting('apiChanges');%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(apiChanges)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20scope%20in%20apiChanges)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20change%20=%20apiChanges%5Bscope%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this.checkIsValidAPIChange(change))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.applyApiChange(scope,%20change);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Checks%20if%20the%20config%20API%20change%20is%20valid.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bany%7D%20change%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bchange%20is%20APIChange%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20checkIsValidAPIChange(change)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20change%20!==%20'object')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(change.type%20===%20'remove')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(change.type%20===%20'descriptor')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(change.enumerable%20&&%20typeof%20change.enumerable%20!==%20'boolean')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(change.configurable%20&&%20typeof%20change.configurable%20!==%20'boolean')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20typeof%20change.getterValue%20!==%20'undefined';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20TODO%20move%20this%20to%20schema%20definition%20imported%20from%20the%20privacy-config%0A%20%20%20%20%20%20%20%20//%20Additionally%20remove%20checkIsValidAPIChange%20when%20this%20change%20happens.%0A%20%20%20%20%20%20%20%20//%20See:%20https://app.asana.com/0/1201614831475344/1208715421518231/f%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@typedef%20%7BObject%7D%20APIChange%0A%20%20%20%20%20%20%20%20%20*%20@property%20%7B%22remove%22%7C%22descriptor%22%7D%20type%0A%20%20%20%20%20%20%20%20%20*%20@property%20%7Bimport('../utils.js').ConfigSetting%7D%20%5BgetterValue%5D%20-%20The%20value%20returned%20from%20a%20getter.%0A%20%20%20%20%20%20%20%20%20*%20@property%20%7Bboolean%7D%20%5Benumerable%5D%20-%20Whether%20the%20property%20is%20enumerable.%0A%20%20%20%20%20%20%20%20%20*%20@property%20%7Bboolean%7D%20%5Bconfigurable%5D%20-%20Whether%20the%20property%20is%20configurable.%0A%20%20%20%20%20%20%20%20%20*/%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Applies%20a%20change%20to%20DOM%20APIs.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20scope%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BAPIChange%7D%20change%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bvoid%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20applyApiChange(scope,%20change)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20response%20=%20this.getGlobalObject(scope);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!response)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%5Bobj,%20key%5D%20=%20response;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(change.type%20===%20'remove')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.removeApiMethod(obj,%20key);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(change.type%20===%20'descriptor')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.wrapApiDescriptor(obj,%20key,%20change);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Removes%20a%20method%20from%20an%20API.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20api%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20key%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20removeApiMethod(api,%20key)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(hasOwnProperty.call(api,%20key))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20api%5Bkey%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Wraps%20a%20property%20with%20descriptor.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20api%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20key%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BAPIChange%7D%20change%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20wrapApiDescriptor(api,%20key,%20change)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20getterValue%20=%20change.getterValue;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(getterValue)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20descriptor%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20get:%20()%20=%3E%20processAttr(getterValue,%20undefined),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('enumerable'%20in%20change)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20descriptor.enumerable%20=%20change.enumerable;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20('configurable'%20in%20change)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20descriptor.configurable%20=%20change.configurable;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.wrapProperty(api,%20key,%20descriptor);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Looks%20up%20a%20global%20object%20from%20a%20scope,%20e.g.%20'Navigator.prototype'.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20scope%20the%20scope%20of%20the%20object%20to%20get%20to.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7B%5Bobject,%20string%5D%7Cnull%7D%20the%20object%20at%20the%20scope.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20getGlobalObject(scope)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20parts%20=%20scope.split('.');%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20get%20the%20last%20part%20of%20the%20scope%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20lastPart%20=%20parts.pop();%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!lastPart)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20obj%20=%20window;%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20part%20of%20parts)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20obj%20=%20obj%5Bpart%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!obj)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%5Bobj,%20lastPart%5D;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20const%20logoImg%20=%0A%20%20%20%20%20%20%20%20'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAABUCAYAAAAcaxDBAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAABNTSURBVHgBzV0LcFPXmf6PJFt+gkEY8wrYMSEbgst7m02ywZnOZiEJCQlJC+QB25lNs7OzlEJ2ptmZLGayfUy3EEhmW5rM7gCZBtjJgzxmSTvTRSST9IF5pCE0TUosmmBjHIKNZFmWLN2e78hHPvfqXuleSdfONyNLV7q6uve7//uc85vRlwAda25oTFK8lZGn0UPaLI2okUhrTH/KGnU7M+olTevlL0KaeM3e01LaKa/PE2p64dgpGmMwGgN0rGqtS1Ve2cB/fhk/gVbSqI5KAU4wvxlBTdNe9VJ5sOnAb0I0yhg1QiWJTGN3E0gcHQRTpO0dTXJdJ7RjzZJWflHrGaNVdiTRN2kalTfOIU9VLfnqp5ruM9TTxR+dlIqGKX7uI7IDLrl7PFS2zW1iXSMURGqkbaUc0uiprqWqxa1UOXcxVcxdxAmcRoUApMZDH9HAmeMU+8NxQbYV3Ca25ITCwaRY4immcYk0AUgcv3wtJ3CxeLgBEBw++jpF249akusWsSUltGPNoq0aY5vMVLviusU04b5HbJMoVLo/ItRaBUyBp7rGtjTHuNSGj75BkbdeN/2ckdbWdODENioRSkIopFLThl4hpi0wflZzy0pO5D9aEiDsIFfXQagtf4CAXCqronzWHHFc3CQ/f53rZuGYl198zorYEKOyW0shrUUT2rFu8bc1jdqMUplLIkFi9NhRCvOLA4mp/jCVAjAn+N2qJa1UvXSZkGYjQOylfTu4OQjqPxAhl7atef+JnVQEiiK0Y+2ipzSNq7gCXFT9o1vFRRkB6evnFxJ5642SkWgF4fD4OUxYba4dEW4GLr/0bJY2FGsCCiIUMaVWEX6FDB4cF1D/T1uzJANE4uTxPBaoWbbSlNgcZiDIYsl7mg6d6iWHcEyolb0MPLyFxq1Yq9sXqg31ihx9nb4MsCK298VnxQ3XQaNTjJXd49SuOiJUkEmJIyRy7TSgWg2bf5xlK/sO76defpJuq7ZTgMy61Y9Q7bI7de/Dlndvf8xoAhw7K9uECjX3R46okomTm/rEbt0dh1TixIzqDeI9lSPZD/ZDWDT0uT2PXmqYSSvI7HryUT2pkNTB5K121d82oZ+sWQzJbJXbZmRa3GWBces2UuXX7qOKigryeDy6z0A+wqbosaDIdEYLZtdgSiq3qVcfOH6rnWPaIlQE7MTacp1ImHvuL/Ztz63iE+qpZtN2qp8z13IX6Siix4OjYi7gQCdy+6+aADNSecKys3l/+3fyHc+bb4d0nMl+KLfNyIS9vPTfPyAtEbc8jvjevz5F45r/inIBpqF6aSvV/M1twiTYLX4UCpwzYlIRw17TMnIOS5aJ8E5eE5e8Gza2TO17+nTXb3IdLyehaSeUOsBfVsj3pv77z6hsWmNmH5AJycwFQeb3nqfBqvHU399P4XBYPMfjcWK8DOXz+bK+I4mFCo2GGRh479dZpFbMbhGkSvBzvWHTvFkHd53+zNKe5lR5bjc7SPHoE7h3rOPZjwTU/POftlE+4ORS5ZVEly+OvDm1UTw0bldRsmtoaCC/32/6/SvQgDw3rVSY9GibTv2zfps7qasPHl9o9X1LCYXd5HxnKkbIyQPrt2Q+h325uOOxnGqeOQfsE+vXvxnhN7krROzd/6PUlJkU9nOJrK4mrzf7lPxcaiCt0IxE57msgkkpAQdZNf9G8tYFMr8Ns5PoDKV3YDRl47zp7OnTnUGz75tK6HC82SG3jXbTwhM6Q0U1sZvvFERVz77e1PtbwSptLBVwndN/+PNMxocb+OnGu0acJM/7mVa20Cw+Nb2CFCW2qtsIhFUndPml5wq/mAmTiT2yjep2HKKZ/7CF6r+ylKqqqmyTCdRwlcQNRmXfDeDaEP5JgFjUJzLghSDUfM2+m3UVkE4uthvkNvJz1aZAOgpNJbWv3U/jnnyeZi5bQRMmTHBEohFprfmZa6RC9eFwJcCDmg2igI5RCeP3sq7IKJ2BhzdnXosY0Zjz2gHUm0vltAe/TYFAoCgiVUByQGqhQyf5gBxftddwyiqGh3j056RuGKUTjqhoVR8mc8bf/r2wk6VGmtTdIpIoNWRxRwISCk4UtBqlVEeoUTpRaZcAkYWoOtQ8MG+xaaxZKuCmj1u+ltwArlmtS6icABjRVbczhNqRTqfQFvGM57avU21t6aXnvTOd9PKb79O+l9rpnfYOGn/7WlekFFDNnBxykcDweMeqBZnRigyhmAqjHsSY2xbkiLh0Tpw4MbMZiQ5yAo7T1h2/oG89/iL9aHeQLvQ4jynfaQ8JEqsry6lhUi2dPXeJdr/4vmtSCgnVSalqS+HxK30b5GZGD73E1mvyTcNdKEg6m3hsOeWqjKqDuMf+43VOQA09vHoJNTcGqKbKL0h2ipuWNIqHEaloC115c78rRRUM3UhO8Cyyv+HfYZqG2TBiLEpIaDqQHynNVfHCwMhJhrMHtOzguqUi85GAet52y7W0/Ym7aP7caYJMQD6XAnBQmDjhBhAuqh7foA2tUu0FoVnqrngyjE4WdMeb5upy83uXt3DJdGdigwpjJb5UAJn9nAuJSsMIhVR7QejwBC4BqLsaLPcXIp0Az7vLy8szm1Pq3XEYRoh5US45J3UwT6q9BFf7VjynCfWMqDvGtVUUVDrjhWRx8BIF8FaQTk46OGxD7TEBwg1gQoaq9jrzwkjYSU/H/UsXqJMUVGcEz1aIumt1k/OSibDnP3cfoZ/se7cgTw/8ZN+vRdjUzb+/ekUL/fJouhjtFqFylouETu05h/BFnqQv1ah+ya+czKBL1XKQsIV7/F+89VFGygrx9t09V8RzJBrnEnpEhFOAf9a15BZUTjBjUEWSkq0ebj914+uq/SxmYkIqlbL87J3joczrmqp0Ovpue4icAtGCBGJRue1WwQRQJdRYQ2CkNfpI0+bLqqhRVYod4gWpZqof6R8pSr/85u/F880mcWU+IJ6Fs4NkNs8KZKIIT1UNuQWjTwGpsr6B9QE+D6M6GdAbp9Cod8MJWO9FzL+0JHT1innC/kmAlBsLIBRAbIuHCjte3sMVo2o2FyLuP+N8ZCbyAdmCsTgEIZTv8ZHhRp8mVlukRdQ4Pl0wBqLiCYNwZkWRe5d/RQT0cEwNnMx7V7RQKWE26068P0xi7fXc/l2l/8wuoQC4kVzpfwsqz1gdDYuoOqc9FY1QwcD4USxKiUTCchczySoVZGjjG8clqIGTN4M7qsnZJErEPiVHwPA2pSPDrHUAPquFBEXnw5zUoaEhKhpJfh69PEMZ5BoT78q/L394+H6z/oVLj42sNsWDi543yRFyDBI2ulek5KOEA5OnU8EY4Pb7Uz58Gy4s0rBLZtdBrsJ9VDK4R+jlnsIl9NIbRKE2chNQc0hmKckE3CP0Qkh4eTgmNafPi3ina2RCIsOnecHnT87tpl1wQrVQ1npKoqILDKzjA+HrBgYGnBHamb/2CmLiF7Pf940f/jyW3gfSl+DJ1BB/xP6cfi4FrKIIjNfrJBQr1Ea+VGRwzFUenn5w0OFxon/M+XHPYWchjhvAsh4JlTMuQb08rmchua16r5IMzXZ1UCwWc/adpHW4BiLHmkxAF6/rskkW8nC1PCc3jVMHiya185xwTI6cU611ETrp8N64AWN6rg+htD5O6IiEGrMjY23UMTrOiCfYUdsIWFfcx/PTKZ9MYwqjkKnpOefyFCc0FVJ3UEkttmoDxyR+NJ5/hl4GkNDASsuPpz/Mk5QVY0esWi82ajQv3Z3yeSkV1JRZjQNnTvBxmfRd8BdbqEUKygP8ft9sMQXHNq7azE+EO6eoeXGm5vr0A148zn3f4MW0V0+ZlFSRfiLILxufjgJkwA+v7zRDAlROsopHzBPyNR04Ffpk7eJemYKiBioHuuT4TFFpKFf7IT6+ZFV5MoWXhyXXvcBvxrPcsVnPpfINk4SCh2MUsOQN4ZIqoQNqKY+HTGjRIa5QS1FQvq8OGZdkfIYH+ACmgDvGtEeIWl7LaQIKQR/n4dIRcgzjWixdAV4jMSSaFhkPy4yPwmupO9beUtzFsDPHxLMjO6qinJufxq1pYhvbKOUp7AbDHIBI5O5fHEkH/06hrl+F/VT9Da/WH8KzCOw9/qE9WsybmUCKzgjyblRhVe/zRag97GhvD7ejPmd21AhO7BAfVTn/X9sxeCMKw3BM/vqRDEkFCEOWBBuLrMoss3ICaCtWOEuEs6YmpYL4Kwht2nOqt2PN4qCcPYKJ+hOGFyfgQDW33CneKxgfHKOhm253ZkdNgAmw8sYiF3crHzcDpFNNOdEtYgQsCF+EV5mrSzH2aua1Qe2rTZZqO0IxdlSBKOyOEdRpjMYmCYxSe+XrDKFQe9FkahjqFL5i+4MUbUfHGMapnWFl7VIaaXUHMoRC7bmnykip8S4Yp0M7grSjRUqom8PDuZBr4jGPvvZIdQd0Bo0XSvao2+o0RpPp0M4AO+o0rzfAqo+TEVE/o8MLy+hHd1fQQHlxXUDyTzxO6ro/6AhtOtAe5D8flNvG6dCB9ZsLr5MO5/XFSGmlDbMTvN5H2+73c0J99FmAie1CASKdSCdg4nKZjnHVlsLLFar6Mq93XM5TYMxUVFyqZfTMCj+9/NUynVT+9pq864MtYVyfpS5gSCOZ1Zsk69d2ne4MbWqZhuk5YtkwCqh+brvkglks1Ut378ozAmnEUEJMwk1yUurq9AOtF/o76YVP/ofe7v5/ev/ySUqk+LCJ10/Vvuzi9Nnuk/Re8iy9P8tLA34PNfSlhBTubS2n7rps+QC5X/04RZVxjZwg3R5pRHgw4bbvtT2Z7bR0ntxr/J7F0sQFjRrznpT5PSTjqmde0y3VO//dBxxPhtBu30DE49GpU6dSZWVl5v21h2+niC87cbi69hq6a+b91DJxIb392a/of//8PEWTepMBovq9Gnm81vHtA28nOKn2bbedpZiMkk1GdQdMzwI7ahrbJbdBYM9PR6QbxDZs+bFzezpsR41qf2HA/MZ8Ev6Ydn7wfXrglytp95mdWWQCkMBYbIA0zVoCv6ix75hwTcZ+AMb1Wbzuuc2MTPF9skDzgfY2fhsyDU5RNFGX6qFoEnhoMzmBtKNqwRnqXiwY81Aibj1LxQmhgYe2GMh81rgCJiS4sUDOPJBpyXvUYB+NBlSvj0YoaC9kG4hHOamQUDndcUr1NF7tym/ftBzTI7EkPJkjHBuwOeiKa6lR5uijAILliRlgFTIlc/YeyUmoUP2UpvNkxiYt6NXkiNTO9BCWGj5VeXOPjKLrg1bE53ZiUWPfKeOKZCCXqkvkrVQ0HzyxU2Oks6dGA40TwfJnOzaV/SGdhqpqP6V6ak4bCAlM8LTVah9I+1AiwR/mUjoxYn3sdGu5tiwys5q4cDKb97fn7Ytnq/TTvP/4JjXgN/tBqP/0H/w8/0hpV0iM10ej0cxbC+qXWpIhfo+rM8iMRvqFrcQjPhinAX6MSDhMc88O0sLzTLy+0ttHUS79g7FBcUyQXTFobi7kEvGaPB1xUE3KZTdV2I56Ny1peJWSnuX85RRspxeEHRXdY6Rkym4yObvZIB6dM5+0unqxOrmsrIy+iH1O73QeobLyMt2uIDHGJXmiN0Dfv/lp6rzyKSUScQqU1dOc2rnU0j+RVh3ppjs/9tEN5710z4c+uraH0cRwWmL7tDhFEjF6sJ1R3aBe7TGii4Y0+RthsVNscGjFrg8v2MpIHLZq4/EpeXWt2nBCaNVmLFzkamOh3XgH0R3rafz48aLoHEmE6Y5DN9G4upFKMSQQZK6evY6+Oe+fqaYs25zgpp3/7jpyAtx0ZHvGPn1wtt07HjMW0kNwQvnspgpHedmu0xd6N83jkso8raRIavhXL4lbo+baINhKWhk88l//HSWTSUEqsqKTF39H3dEu7q2TQpUDvkn0vZt20arZ3xCfm558XcBR1obsZ8rjT5v26et55t/0DWkgmSy5wgmZ4tqoAHRsWFBHMe8rmqHdpZO2ktoTe7jeVdGMGTPEZLKPL39IG498U5zQfXMepK9f+5CpVBoByep68ls597FqDisTluy1rCzIYkOj0+5Sxdk1S9qYoU2EVfdDQG3Dlly2WqSh6D2CBwDVt0OiEecfX5c1Rg7VxtBNtaFXiARI7Nm9LWusjJvtXc0Hj2+iAlF0y+Cz31i0iXnYVuPUcozBoF+JmdcXDu2zEEXG1YsYEk2wioHsbgYSy2fO4TdzZXpw0WTaoWVzWNEy2F5olAslamqd7awkrMxAKSGXDMp/KGCGdAOa58wbKQh7yVXcob00Q0kIlTAzARIgtparoFu9662Qs10xpJIXgezGmHZQUkKBYWlt4y/Xm30OSUWDA0ygcLPnEqbJXDls3d2BW5pDpCW/Uwqp1B2XXEI+YgHZigNeGJOwCiUY6hw7c0KQCGeTe1IGwzDPNgz3kAtwjVAJO8SqQFkQzgVk+yZZ/HOVz7sEacbpMJYQveq4RBLb6xaRIz81SgCxSfK0esmzXqN09wP3waWRpV6lgdSeQmLKgn6RxgAZcpnnbkFuCf9BFR8KD3K/f3Q0SdSfwpcAHevQVSLVmNLYAg+j+SBYLOrlNQ0TskP4k15swUIp0s5hFvZY/YcvI/4CeAZjCToTSnsAAAAASUVORK5CYII=';%0A%20%20%20%20const%20loadingImages%20=%20%7B%0A%20%20%20%20%20%20%20%20darkMode:%0A%20%20%20%20%20%20%20%20%20%20%20%20'data:image/svg+xml;utf8,%253Csvg%2520width%253D%252220%2522%2520height%253D%252220%2522%2520viewBox%253D%25220%25200%252020%252020%2522%2520fill%253D%2522none%2522%2520xmlns%253D%2522http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg%2522%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Cstyle%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2540keyframes%2520rotate%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520from%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520transform%253A%2520rotate%25280deg%2529%253B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%257D%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520to%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520transform%253A%2520rotate%2528359deg%2529%253B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%257D%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%257D%250A%2520%2520%2520%2520%2520%2520%2520%2520%253C%252Fstyle%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Cg%2520style%253D%2522transform-origin%253A%252050%2525%252050%2525%253B%2520animation%253A%2520rotate%25201s%2520infinite%2520reverse%2520linear%253B%2522%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%252218.0968%2522%2520y%253D%252216.0861%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%2528136.161%252018.0968%252016.0861%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.1%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25228.49878%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.4%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%252219.9976%2522%2520y%253D%25228.37451%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%252890%252019.9976%25208.37451%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.2%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%252216.1727%2522%2520y%253D%25221.9917%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%252846.1607%252016.1727%25201.9917%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.3%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25228.91309%2522%2520y%253D%25226.88501%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%2528136.161%25208.91309%25206.88501%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.6%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25226.79602%2522%2520y%253D%252210.996%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%252846.1607%25206.79602%252010.996%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.7%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25227%2522%2520y%253D%25228.62549%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%252890%25207%25208.62549%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.8%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25228.49878%2522%2520y%253D%252213%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.9%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%253C%252Fg%253E%250A%2520%2520%2520%2520%253C%252Fsvg%253E',%0A%20%20%20%20%20%20%20%20lightMode:%0A%20%20%20%20%20%20%20%20%20%20%20%20'data:image/svg+xml;utf8,%253Csvg%2520width%253D%252220%2522%2520height%253D%252220%2522%2520viewBox%253D%25220%25200%252020%252020%2522%2520fill%253D%2522none%2522%2520xmlns%253D%2522http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg%2522%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Cstyle%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2540keyframes%2520rotate%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520from%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520transform%253A%2520rotate%25280deg%2529%253B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%257D%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520to%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520transform%253A%2520rotate%2528359deg%2529%253B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%257D%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%257D%250A%2520%2520%2520%2520%2520%2520%2520%2520%253C%252Fstyle%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Cg%2520style%253D%2522transform-origin%253A%252050%2525%252050%2525%253B%2520animation%253A%2520rotate%25201s%2520infinite%2520reverse%2520linear%253B%2522%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%252218.0968%2522%2520y%253D%252216.0861%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%2528136.161%252018.0968%252016.0861%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.1%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25228.49878%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.4%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%252219.9976%2522%2520y%253D%25228.37451%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%252890%252019.9976%25208.37451%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.2%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%252216.1727%2522%2520y%253D%25221.9917%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%252846.1607%252016.1727%25201.9917%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.3%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25228.91309%2522%2520y%253D%25226.88501%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%2528136.161%25208.91309%25206.88501%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.6%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25226.79602%2522%2520y%253D%252210.996%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%252846.1607%25206.79602%252010.996%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.7%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25227%2522%2520y%253D%25228.62549%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520transform%253D%2522rotate%252890%25207%25208.62549%2529%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.8%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Crect%2520x%253D%25228.49878%2522%2520y%253D%252213%2522%2520width%253D%25223%2522%2520height%253D%25227%2522%2520rx%253D%25221.5%2522%2520fill%253D%2522%2523111111%2522%2520fill-opacity%253D%25220.9%2522%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%253C%252Fg%253E%250A%2520%2520%2520%2520%253C%252Fsvg%253E',%20//%20'data:application/octet-stream;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KCTxzdHlsZT4KCQlAa2V5ZnJhbWVzIHJvdGF0ZSB7CgkJCWZyb20gewoJCQkJdHJhbnNmb3JtOiByb3RhdGUoMGRlZyk7CgkJCX0KCQkJdG8gewoJCQkJdHJhbnNmb3JtOiByb3RhdGUoMzU5ZGVnKTsKCQkJfQoJCX0KCTwvc3R5bGU+Cgk8ZyBzdHlsZT0idHJhbnNmb3JtLW9yaWdpbjogNTAlIDUwJTsgYW5pbWF0aW9uOiByb3RhdGUgMXMgaW5maW5pdGUgcmV2ZXJzZSBsaW5lYXI7Ij4KCQk8cmVjdCB4PSIxOC4wOTY4IiB5PSIxNi4wODYxIiB3aWR0aD0iMyIgaGVpZ2h0PSI3IiByeD0iMS41IiB0cmFuc2Zvcm09InJvdGF0ZSgxMzYuMTYxIDE4LjA5NjggMTYuMDg2MSkiIGZpbGw9IiNmZmZmZmYiIGZpbGwtb3BhY2l0eT0iMC4xIi8+CQoJCTxyZWN0IHg9IjguNDk4NzgiIHdpZHRoPSIzIiBoZWlnaHQ9IjciIHJ4PSIxLjUiIGZpbGw9IiNmZmZmZmYiIGZpbGwtb3BhY2l0eT0iMC40Ii8+CgkJPHJlY3QgeD0iMTkuOTk3NiIgeT0iOC4zNzQ1MSIgd2lkdGg9IjMiIGhlaWdodD0iNyIgcng9IjEuNSIgdHJhbnNmb3JtPSJyb3RhdGUoOTAgMTkuOTk3NiA4LjM3NDUxKSIgZmlsbD0iI2ZmZmZmZiIgZmlsbC1vcGFjaXR5PSIwLjIiLz4KCQk8cmVjdCB4PSIxNi4xNzI3IiB5PSIxLjk5MTciIHdpZHRoPSIzIiBoZWlnaHQ9IjciIHJ4PSIxLjUiIHRyYW5zZm9ybT0icm90YXRlKDQ2LjE2MDcgMTYuMTcyNyAxLjk5MTcpIiBmaWxsPSIjZmZmZmZmIiBmaWxsLW9wYWNpdHk9IjAuMyIvPgoJCTxyZWN0IHg9IjguOTEzMDkiIHk9IjYuODg1MDEiIHdpZHRoPSIzIiBoZWlnaHQ9IjciIHJ4PSIxLjUiIHRyYW5zZm9ybT0icm90YXRlKDEzNi4xNjEgOC45MTMwOSA2Ljg4NTAxKSIgZmlsbD0iI2ZmZmZmZiIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KCQk8cmVjdCB4PSI2Ljc5NjAyIiB5PSIxMC45OTYiIHdpZHRoPSIzIiBoZWlnaHQ9IjciIHJ4PSIxLjUiIHRyYW5zZm9ybT0icm90YXRlKDQ2LjE2MDcgNi43OTYwMiAxMC45OTYpIiBmaWxsPSIjZmZmZmZmIiBmaWxsLW9wYWNpdHk9IjAuNyIvPgoJCTxyZWN0IHg9IjciIHk9IjguNjI1NDkiIHdpZHRoPSIzIiBoZWlnaHQ9IjciIHJ4PSIxLjUiIHRyYW5zZm9ybT0icm90YXRlKDkwIDcgOC42MjU0OSkiIGZpbGw9IiNmZmZmZmYiIGZpbGwtb3BhY2l0eT0iMC44Ii8+CQkKCQk8cmVjdCB4PSI4LjQ5ODc4IiB5PSIxMyIgd2lkdGg9IjMiIGhlaWdodD0iNyIgcng9IjEuNSIgZmlsbD0iI2ZmZmZmZiIgZmlsbC1vcGFjaXR5PSIwLjkiLz4KCTwvZz4KPC9zdmc+Cg=='%0A%20%20%20%20%7D;%0A%20%20%20%20const%20closeIcon%20=%0A%20%20%20%20%20%20%20%20'data:image/svg+xml;utf8,%253Csvg%2520width%253D%252212%2522%2520height%253D%252212%2522%2520viewBox%253D%25220%25200%252012%252012%2522%2520fill%253D%2522none%2522%2520xmlns%253D%2522http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg%2522%253E%250A%253Cpath%2520fill-rule%253D%2522evenodd%2522%2520clip-rule%253D%2522evenodd%2522%2520d%253D%2522M5.99998%25204.58578L10.2426%25200.34314C10.6331%2520-0.0473839%252011.2663%2520-0.0473839%252011.6568%25200.34314C12.0474%25200.733665%252012.0474%25201.36683%252011.6568%25201.75735L7.41419%25205.99999L11.6568%252010.2426C12.0474%252010.6332%252012.0474%252011.2663%252011.6568%252011.6568C11.2663%252012.0474%252010.6331%252012.0474%252010.2426%252011.6568L5.99998%25207.41421L1.75734%252011.6568C1.36681%252012.0474%25200.733649%252012.0474%25200.343125%252011.6568C-0.0473991%252011.2663%2520-0.0473991%252010.6332%25200.343125%252010.2426L4.58577%25205.99999L0.343125%25201.75735C-0.0473991%25201.36683%2520-0.0473991%25200.733665%25200.343125%25200.34314C0.733649%2520-0.0473839%25201.36681%2520-0.0473839%25201.75734%25200.34314L5.99998%25204.58578Z%2522%2520fill%253D%2522%2523222222%2522%252F%253E%250A%253C%252Fsvg%253E';%0A%0A%20%20%20%20const%20blockedFBLogo%20=%0A%20%20%20%20%20%20%20%20'data:image/svg+xml;utf8,%253Csvg%2520width%253D%252280%2522%2520height%253D%252280%2522%2520viewBox%253D%25220%25200%252080%252080%2522%2520fill%253D%2522none%2522%2520xmlns%253D%2522http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg%2522%253E%250A%253Ccircle%2520cx%253D%252240%2522%2520cy%253D%252240%2522%2520r%253D%252240%2522%2520fill%253D%2522white%2522%252F%253E%250A%253Cg%2520clip-path%253D%2522url%2528%2523clip0%2529%2522%253E%250A%253Cpath%2520d%253D%2522M73.8457%252039.974C73.8457%252021.284%252058.7158%25206.15405%252040.0258%25206.15405C21.3358%25206.15405%25206.15344%252021.284%25206.15344%252039.974C6.15344%252056.884%252018.5611%252070.8622%252034.7381%252073.4275V49.764H26.0999V39.974H34.7381V32.5399C34.7381%252024.0587%252039.764%252019.347%252047.5122%252019.347C51.2293%252019.347%252055.0511%252020.0799%252055.0511%252020.0799V28.3517H50.8105C46.6222%252028.3517%252045.2611%252030.9693%252045.2611%252033.6393V39.974H54.6846L53.1664%252049.764H45.2611V73.4275C61.4381%252070.9146%252073.8457%252056.884%252073.8457%252039.974Z%2522%2520fill%253D%2522%25231877F2%2522%252F%253E%250A%253C%252Fg%253E%250A%253Crect%2520x%253D%25223.01295%2522%2520y%253D%252211.7158%2522%2520width%253D%252212.3077%2522%2520height%253D%252292.3077%2522%2520rx%253D%25226.15385%2522%2520transform%253D%2522rotate%2528-45%25203.01295%252011.7158%2529%2522%2520fill%253D%2522%2523666666%2522%2520stroke%253D%2522white%2522%2520stroke-width%253D%25226.15385%2522%252F%253E%250A%253Cdefs%253E%250A%253CclipPath%2520id%253D%2522clip0%2522%253E%250A%253Crect%2520width%253D%252267.6923%2522%2520height%253D%252267.6923%2522%2520fill%253D%2522white%2522%2520transform%253D%2522translate%25286.15344%25206.15405%2529%2522%252F%253E%250A%253C%252FclipPath%253E%250A%253C%252Fdefs%253E%250A%253C%252Fsvg%253E';%0A%20%20%20%20const%20facebookLogo%20=%0A%20%20%20%20%20%20%20%20'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMSAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTguODUgMTkuOUM0LjEgMTkuMDUgMC41IDE0Ljk1IDAuNSAxMEMwLjUgNC41IDUgMCAxMC41IDBDMTYgMCAyMC41IDQuNSAyMC41IDEwQzIwLjUgMTQuOTUgMTYuOSAxOS4wNSAxMi4xNSAxOS45TDExLjYgMTkuNDVIOS40TDguODUgMTkuOVoiIGZpbGw9IiMxODc3RjIiLz4KPHBhdGggZD0iTTE0LjQgMTIuOEwxNC44NSAxMEgxMi4yVjguMDVDMTIuMiA3LjI1IDEyLjUgNi42NSAxMy43IDYuNjVIMTVWNC4xQzE0LjMgNCAxMy41IDMuOSAxMi44IDMuOUMxMC41IDMuOSA4LjkgNS4zIDguOSA3LjhWMTBINi40VjEyLjhIOC45VjE5Ljg1QzkuNDUgMTkuOTUgMTAgMjAgMTAuNTUgMjBDMTEuMSAyMCAxMS42NSAxOS45NSAxMi4yIDE5Ljg1VjEyLjhIMTQuNFoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo=';%0A%0A%20%20%20%20const%20blockedYTVideo%20=%0A%20%20%20%20%20%20%20%20'data:image/svg+xml;utf8,%253Csvg%2520width%253D%252275%2522%2520height%253D%252275%2522%2520viewBox%253D%25220%25200%252075%252075%2522%2520fill%253D%2522none%2522%2520xmlns%253D%2522http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg%2522%253E%250A%2520%2520%253Crect%2520x%253D%25226.75%2522%2520y%253D%252215.75%2522%2520width%253D%252256.25%2522%2520height%253D%252239%2522%2520rx%253D%252213.5%2522%2520fill%253D%2522%2523DE5833%2522%252F%253E%250A%2520%2520%253Cmask%2520id%253D%2522path-2-outside-1_885_11045%2522%2520maskUnits%253D%2522userSpaceOnUse%2522%2520x%253D%252223.75%2522%2520y%253D%252222.5%2522%2520width%253D%252224%2522%2520height%253D%252226%2522%2520fill%253D%2522black%2522%253E%250A%2520%2520%253Crect%2520fill%253D%2522white%2522%2520x%253D%252223.75%2522%2520y%253D%252222.5%2522%2520width%253D%252224%2522%2520height%253D%252226%2522%252F%253E%250A%2520%2520%253Cpath%2520d%253D%2522M41.9425%252037.5279C43.6677%252036.492%252043.6677%252033.9914%252041.9425%252032.9555L31.0394%252026.4088C29.262%252025.3416%252027%252026.6218%252027%252028.695L27%252041.7884C27%252043.8615%252029.262%252045.1418%252031.0394%252044.0746L41.9425%252037.5279Z%2522%252F%253E%250A%2520%2520%253C%252Fmask%253E%250A%2520%2520%253Cpath%2520d%253D%2522M41.9425%252037.5279C43.6677%252036.492%252043.6677%252033.9914%252041.9425%252032.9555L31.0394%252026.4088C29.262%252025.3416%252027%252026.6218%252027%252028.695L27%252041.7884C27%252043.8615%252029.262%252045.1418%252031.0394%252044.0746L41.9425%252037.5279Z%2522%2520fill%253D%2522white%2522%252F%253E%250A%2520%2520%253Cpath%2520d%253D%2522M30.0296%252044.6809L31.5739%252047.2529L30.0296%252044.6809ZM30.0296%252025.8024L31.5739%252023.2304L30.0296%252025.8024ZM42.8944%252036.9563L44.4387%252039.5283L42.8944%252036.9563ZM41.35%252036.099L28.4852%252028.3744L31.5739%252023.2304L44.4387%252030.955L41.35%252036.099ZM30%252027.5171L30%252042.9663L24%252042.9663L24%252027.5171L30%252027.5171ZM28.4852%252042.1089L41.35%252034.3843L44.4387%252039.5283L31.5739%252047.2529L28.4852%252042.1089ZM30%252042.9663C30%252042.1888%252029.1517%252041.7087%252028.4852%252042.1089L31.5739%252047.2529C28.2413%252049.2539%252024%252046.8535%252024%252042.9663L30%252042.9663ZM28.4852%252028.3744C29.1517%252028.7746%252030%252028.2945%252030%252027.5171L24%252027.5171C24%252023.6299%252028.2413%252021.2294%252031.5739%252023.2304L28.4852%252028.3744ZM44.4387%252030.955C47.6735%252032.8974%252047.6735%252037.586%252044.4387%252039.5283L41.35%252034.3843C40.7031%252034.7728%252040.7031%252035.7105%252041.35%252036.099L44.4387%252030.955Z%2522%2520fill%253D%2522%2523BC4726%2522%2520mask%253D%2522url(%2523path-2-outside-1_885_11045)%2522%252F%253E%250A%2520%2520%253Ccircle%2520cx%253D%252257.75%2522%2520cy%253D%252252.5%2522%2520r%253D%252213.5%2522%2520fill%253D%2522%2523E0E0E0%2522%252F%253E%250A%2520%2520%253Crect%2520x%253D%252248.75%2522%2520y%253D%252250.25%2522%2520width%253D%252218%2522%2520height%253D%25224.5%2522%2520rx%253D%25221.5%2522%2520fill%253D%2522%2523666666%2522%252F%253E%250A%2520%2520%253Cpath%2520fill-rule%253D%2522evenodd%2522%2520clip-rule%253D%2522evenodd%2522%2520d%253D%2522M57.9853%252015.8781C58.2046%252016.1015%252058.5052%252016.2262%252058.8181%252016.2238C59.1311%252016.2262%252059.4316%252016.1015%252059.6509%252015.8781L62.9821%252012.5469C63.2974%252012.2532%252063.4272%252011.8107%252063.3206%252011.3931C63.2139%252010.9756%252062.8879%252010.6495%252062.4703%252010.5429C62.0528%252010.4363%252061.6103%252010.5661%252061.3165%252010.8813L57.9853%252014.2125C57.7627%252014.4325%252057.6374%252014.7324%252057.6374%252015.0453C57.6374%252015.3583%252057.7627%252015.6582%252057.9853%252015.8781ZM61.3598%252018.8363C61.388%252019.4872%252061.9385%252019.9919%252062.5893%252019.9637L62.6915%252019.9559L66.7769%252019.6023C67.4278%252019.5459%252067.9097%252018.9726%252067.8533%252018.3217C67.7968%252017.6708%252067.2235%252017.1889%252066.5726%252017.2453L62.4872%252017.6067C61.8363%252017.6349%252061.3316%252018.1854%252061.3598%252018.8363Z%2522%2520fill%253D%2522%2523AAAAAA%2522%2520fill-opacity%253D%25220.6%2522%252F%253E%250A%2520%2520%253Cpath%2520fill-rule%253D%2522evenodd%2522%2520clip-rule%253D%2522evenodd%2522%2520d%253D%2522M10.6535%252015.8781C10.4342%252016.1015%252010.1336%252016.2262%25209.82067%252016.2238C9.5077%252016.2262%25209.20717%252016.1015%25208.98787%252015.8781L5.65667%252012.5469C5.34138%252012.2532%25205.2116%252011.8107%25205.31823%252011.3931C5.42487%252010.9756%25205.75092%252010.6495%25206.16847%252010.5429C6.58602%252010.4363%25207.02848%252010.5661%25207.32227%252010.8813L10.6535%252014.2125C10.8761%252014.4325%252011.0014%252014.7324%252011.0014%252015.0453C11.0014%252015.3583%252010.8761%252015.6582%252010.6535%252015.8781ZM7.2791%252018.8362C7.25089%252019.4871%25206.7004%252019.9919%25206.04954%252019.9637L5.9474%252019.9558L1.86197%252019.6023C1.44093%252019.5658%25201.07135%252019.3074%25200.892432%252018.9246C0.713515%252018.5417%25200.752449%252018.0924%25200.994567%252017.7461C1.23669%252017.3997%25201.6452%252017.2088%25202.06624%252017.2453L6.15167%252017.6067C6.80254%252017.6349%25207.3073%252018.1854%25207.2791%252018.8362Z%2522%2520fill%253D%2522%2523AAAAAA%2522%2520fill-opacity%253D%25220.6%2522%252F%253E%250A%253C%252Fsvg%253E%250A';%0A%20%20%20%20const%20videoPlayDark%20=%0A%20%20%20%20%20%20%20%20'data:image/svg+xml;utf8,%253Csvg%2520width%253D%252222%2522%2520height%253D%252226%2522%2520viewBox%253D%25220%25200%252022%252026%2522%2520fill%253D%2522none%2522%2520xmlns%253D%2522http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg%2522%253E%250A%2520%2520%253Cpath%2520d%253D%2522M21%252011.2679C22.3333%252012.0377%252022.3333%252013.9622%252021%252014.732L3%252025.1244C1.66667%252025.8942%25202.59376e-06%252024.9319%25202.66105e-06%252023.3923L3.56958e-06%25202.60769C3.63688e-06%25201.06809%25201.66667%25200.105844%25203%25200.875644L21%252011.2679Z%2522%2520fill%253D%2522%2523222222%2522%252F%253E%250A%253C%252Fsvg%253E%250A';%0A%20%20%20%20const%20videoPlayLight%20=%0A%20%20%20%20%20%20%20%20'data:image/svg+xml;utf8,%253Csvg%2520width%253D%252222%2522%2520height%253D%252226%2522%2520viewBox%253D%25220%25200%252022%252026%2522%2520fill%253D%2522none%2522%2520xmlns%253D%2522http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg%2522%253E%250A%2520%2520%253Cpath%2520d%253D%2522M21%252011.2679C22.3333%252012.0377%252022.3333%252013.9622%252021%252014.732L3%252025.1244C1.66667%252025.8942%25202.59376e-06%252024.9319%25202.66105e-06%252023.3923L3.56958e-06%25202.60769C3.63688e-06%25201.06809%25201.66667%25200.105844%25203%25200.875644L21%252011.2679Z%2522%2520fill%253D%2522%2523FFFFFF%2522%252F%253E%250A%253C%252Fsvg%253E';%0A%0A%20%20%20%20var%20localesJSON%20=%20%60%7B%22bg%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22%D0%9F%D1%80%D0%B8%20%D0%B2%D0%BB%D0%B8%D0%B7%D0%B0%D0%BD%D0%B5%20%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D1%88%D0%B0%D0%B2%D0%B0%D1%82%D0%B5%20%D0%BD%D0%B0%20Facebook%20%D0%B4%D0%B0%20%D0%92%D0%B8%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%22,%22informationalModalMessageBody%22:%22%D0%A1%D0%BB%D0%B5%D0%B4%20%D0%BA%D0%B0%D1%82%D0%BE%20%D0%B2%D0%BB%D0%B5%D0%B7%D0%B5%D1%82%D0%B5,%20DuckDuckGo%20%D0%BD%D0%B5%20%D0%BC%D0%BE%D0%B6%D0%B5%20%D0%B4%D0%B0%20%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%D1%82%D0%BE%20%D0%BE%D1%82%20Facebook%20%D0%B2%20%D1%81%D1%8A%D0%B4%D1%8A%D1%80%D0%B6%D0%B0%D0%BD%D0%B8%D0%B5%D1%82%D0%BE%20%D0%BD%D0%B0%20%D1%82%D0%BE%D0%B7%D0%B8%20%D1%81%D0%B0%D0%B9%D1%82.%22,%22informationalModalConfirmButtonText%22:%22%D0%92%D1%85%D0%BE%D0%B4%22,%22informationalModalRejectButtonText%22:%22%D0%9D%D0%B0%D0%B7%D0%B0%D0%B4%22,%22loginButtonText%22:%22%D0%92%D1%85%D0%BE%D0%B4%20%D0%B2%D1%8A%D0%B2%20Facebook%22,%22loginBodyText%22:%22Facebook%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%20%D0%92%D0%B0%D1%88%D0%B0%D1%82%D0%B0%20%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D1%81%D1%82%20%D0%B2%20%D1%81%D1%8A%D0%BE%D1%82%D0%B2%D0%B5%D1%82%D0%BD%D0%B8%D1%8F%20%D1%81%D0%B0%D0%B9%D1%82,%20%D0%BA%D0%BE%D0%B3%D0%B0%D1%82%D0%BE%20%D0%B3%D0%BE%20%D0%B8%D0%B7%D0%BF%D0%BE%D0%BB%D0%B7%D0%B2%D0%B0%D1%82%D0%B5%20%D0%B7%D0%B0%20%D0%B2%D1%85%D0%BE%D0%B4.%22,%22buttonTextUnblockContent%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D1%81%D1%8A%D0%B4%D1%8A%D1%80%D0%B6%D0%B0%D0%BD%D0%B8%D0%B5%20%D0%BE%D1%82%20Facebook%22,%22buttonTextUnblockComment%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%BA%D0%BE%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%20%D0%B2%D1%8A%D0%B2%20Facebook%22,%22buttonTextUnblockComments%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%BA%D0%BE%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%20%D0%B2%D1%8A%D0%B2%20Facebook%22,%22buttonTextUnblockPost%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F%20%D0%BE%D1%82%20Facebook%22,%22buttonTextUnblockVideo%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%20%D0%BE%D1%82%20Facebook%22,%22buttonTextUnblockLogin%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%B2%D1%85%D0%BE%D0%B4%20%D1%81%20Facebook%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%20%D1%82%D0%BE%D0%B2%D0%B0%20%D1%81%D1%8A%D0%B4%D1%8A%D1%80%D0%B6%D0%B0%D0%BD%D0%B8%D0%B5,%20%D0%B7%D0%B0%20%D0%B4%D0%B0%20%D0%BF%D1%80%D0%B5%D0%B4%D0%BE%D1%82%D0%B2%D1%80%D0%B0%D1%82%D0%B8%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%20%D0%BE%D1%82%20Facebook%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%20%D1%82%D0%BE%D0%B7%D0%B8%20%D0%BA%D0%BE%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80,%20%D0%B7%D0%B0%20%D0%B4%D0%B0%20%D0%BF%D1%80%D0%B5%D0%B4%D0%BE%D1%82%D0%B2%D1%80%D0%B0%D1%82%D0%B8%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%20%D0%BE%D1%82%20Facebook%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%20%D1%82%D0%B5%D0%B7%D0%B8%20%D0%BA%D0%BE%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8,%20%D0%B7%D0%B0%20%D0%B4%D0%B0%20%D0%BF%D1%80%D0%B5%D0%B4%D0%BE%D1%82%D0%B2%D1%80%D0%B0%D1%82%D0%B8%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%20%D0%BE%D1%82%20Facebook%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%20%D1%82%D0%B0%D0%B7%D0%B8%20%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F,%20%D0%B7%D0%B0%20%D0%B4%D0%B0%20%D0%BF%D1%80%D0%B5%D0%B4%D0%BE%D1%82%D0%B2%D1%80%D0%B0%D1%82%D0%B8%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%20%D0%BE%D1%82%20Facebook%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%20%D1%82%D0%BE%D0%B2%D0%B0%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE,%20%D0%B7%D0%B0%20%D0%B4%D0%B0%20%D0%BF%D1%80%D0%B5%D0%B4%D0%BE%D1%82%D0%B2%D1%80%D0%B0%D1%82%D0%B8%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%20%D0%BE%D1%82%20Facebook%22,%22infoTextUnblockContent%22:%22%D0%91%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D1%85%D0%BC%D0%B5%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%D1%82%D0%BE%20%D0%BE%D1%82%20Facebook%20%D0%BF%D1%80%D0%B8%20%D0%B7%D0%B0%D1%80%D0%B5%D0%B6%D0%B4%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0%D1%82%D0%B0.%20%D0%90%D0%BA%D0%BE%20%D1%80%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D1%82%D0%B5%20%D1%82%D0%BE%D0%B2%D0%B0%20%D1%81%D1%8A%D0%B4%D1%8A%D1%80%D0%B6%D0%B0%D0%BD%D0%B8%D0%B5,%20Facebook%20%D1%89%D0%B5%20%D1%81%D0%BB%D0%B5%D0%B4%D0%B8%20%D0%92%D0%B0%D1%88%D0%B0%D1%82%D0%B0%20%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D1%81%D1%82.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22%D0%9D%D0%B0%D1%83%D1%87%D0%B5%D1%82%D0%B5%20%D0%BF%D0%BE%D0%B2%D0%B5%D1%87%D0%B5%22,%22readAbout%22:%22%D0%9F%D1%80%D0%BE%D1%87%D0%B5%D1%82%D0%B5%D1%82%D0%B5%20%D0%B7%D0%B0%20%D1%82%D0%B0%D0%B7%D0%B8%20%D0%B7%D0%B0%D1%89%D0%B8%D1%82%D0%B0%20%D0%BD%D0%B0%20%D0%BF%D0%BE%D0%B2%D0%B5%D1%80%D0%B8%D1%82%D0%B5%D0%BB%D0%BD%D0%BE%D1%81%D1%82%D1%82%D0%B0%22,%22shareFeedback%22:%22%D0%A1%D0%BF%D0%BE%D0%B4%D0%B5%D0%BB%D1%8F%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%BE%D1%82%D0%B7%D0%B8%D0%B2%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22%D0%90%D0%BA%D1%82%D0%B8%D0%B2%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%B2%D1%81%D0%B8%D1%87%D0%BA%D0%B8%20%D0%BF%D1%80%D0%B5%D0%B3%D0%BB%D0%B5%D0%B4%D0%B8%20%D0%B2%20YouTube?%22,%22informationalModalMessageBody%22:%22%D0%9F%D0%BE%D0%BA%D0%B0%D0%B7%D0%B2%D0%B0%D0%BD%D0%B5%D1%82%D0%BE%20%D0%BD%D0%B0%20%D0%BF%D1%80%D0%B5%D0%B3%D0%BB%D0%B5%D0%B4%20%D0%BF%D0%BE%D0%B7%D0%B2%D0%BE%D0%BB%D1%8F%D0%B2%D0%B0%20%D0%BD%D0%B0%20Google%20(%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%B8%D0%BA%20%D0%BD%D0%B0%20YouTube)%20%D0%B4%D0%B0%20%D0%B2%D0%B8%D0%B4%D0%B8%20%D1%87%D0%B0%D1%81%D1%82%20%D0%BE%D1%82%20%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%86%D0%B8%D1%8F%D1%82%D0%B0%20%D0%B7%D0%B0%20%D0%92%D0%B0%D1%88%D0%B5%D1%82%D0%BE%20%D1%83%D1%81%D1%82%D1%80%D0%BE%D0%B9%D1%81%D1%82%D0%B2%D0%BE,%20%D0%BD%D0%BE%20%D0%B2%D1%81%D0%B5%20%D0%BF%D0%B0%D0%BA%20%D0%BE%D1%81%D0%B8%D0%B3%D1%83%D1%80%D1%8F%D0%B2%D0%B0%20%D0%BF%D0%BE%D0%B2%D0%B5%D1%87%D0%B5%20%D0%BF%D0%BE%D0%B2%D0%B5%D1%80%D0%B8%D1%82%D0%B5%D0%BB%D0%BD%D0%BE%D1%81%D1%82%20%D0%BE%D1%82%D0%BA%D0%BE%D0%BB%D0%BA%D0%BE%D1%82%D0%BE%20%D0%BF%D1%80%D0%B8%20%D0%B2%D1%8A%D0%B7%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%B5%D0%B6%D0%B4%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%D0%BA%D0%BB%D0%B8%D0%BF%D0%B0.%22,%22informationalModalConfirmButtonText%22:%22%D0%90%D0%BA%D1%82%D0%B8%D0%B2%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%B2%D1%81%D0%B8%D1%87%D0%BA%D0%B8%20%D0%BF%D1%80%D0%B5%D0%B3%D0%BB%D0%B5%D0%B4%D0%B8%22,%22informationalModalRejectButtonText%22:%22%D0%9D%D0%B5,%20%D0%B1%D0%BB%D0%B0%D0%B3%D0%BE%D0%B4%D0%B0%D1%80%D1%8F%22,%22buttonTextUnblockVideo%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%20%D0%BE%D1%82%20YouTube%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%20%D1%82%D0%BE%D0%B7%D0%B8%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%D0%BA%D0%BB%D0%B8%D0%BF%20%D0%B2%20YouTube,%20%D0%B7%D0%B0%20%D0%B4%D0%B0%20%D0%BF%D1%80%D0%B5%D0%B4%D0%BE%D1%82%D0%B2%D1%80%D0%B0%D1%82%D0%B8%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%20%D0%BE%D1%82%20Google%22,%22infoTextUnblockVideo%22:%22%D0%91%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D1%85%D0%BC%D0%B5%20%D0%BF%D1%80%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%D1%82%D0%BE%20%D0%BE%D1%82%20Google%20(%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%B8%D0%BA%20%D0%BD%D0%B0%20YouTube)%20%D0%BF%D1%80%D0%B8%20%D0%B7%D0%B0%D1%80%D0%B5%D0%B6%D0%B4%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0%D1%82%D0%B0.%20%D0%90%D0%BA%D0%BE%20%D1%80%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%B0%D1%82%D0%B5%20%D1%82%D0%BE%D0%B7%D0%B8%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%D0%BA%D0%BB%D0%B8%D0%BF,%20Google%20%D1%89%D0%B5%20%D1%81%D0%BB%D0%B5%D0%B4%D0%B8%20%D0%92%D0%B0%D1%88%D0%B0%D1%82%D0%B0%20%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D1%81%D1%82.%22,%22infoPreviewToggleText%22:%22%D0%9F%D1%80%D0%B5%D0%B3%D0%BB%D0%B5%D0%B4%D0%B8%D1%82%D0%B5%20%D1%81%D0%B0%20%D0%B4%D0%B5%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%B8%D1%80%D0%B0%D0%BD%D0%B8%20%D0%B7%D0%B0%20%D0%BE%D1%81%D0%B8%D0%B3%D1%83%D1%80%D1%8F%D0%B2%D0%B0%D0%BD%D0%B5%20%D0%BD%D0%B0%20%D0%B4%D0%BE%D0%BF%D1%8A%D0%BB%D0%BD%D0%B8%D1%82%D0%B5%D0%BB%D0%BD%D0%B0%20%D0%BF%D0%BE%D0%B2%D0%B5%D1%80%D0%B8%D1%82%D0%B5%D0%BB%D0%BD%D0%BE%D1%81%D1%82%22,%22infoPreviewToggleEnabledText%22:%22%D0%9F%D1%80%D0%B5%D0%B3%D0%BB%D0%B5%D0%B4%D0%B8%D1%82%D0%B5%20%D1%81%D0%B0%20%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%B8%D1%80%D0%B0%D0%BD%D0%B8%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22%D0%92%D0%B8%D0%B7%D1%83%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8%D1%82%D0%B5%20%D0%BE%D1%82%20YouTube%20%D1%81%D0%B0%20%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%B8%D1%80%D0%B0%D0%BD%D0%B8%20%D0%B2%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3E%D0%9D%D0%B0%D1%83%D1%87%D0%B5%D1%82%D0%B5%20%D0%BF%D0%BE%D0%B2%D0%B5%D1%87%D0%B5%3C/a%3E%20%D0%B7%D0%B0%20%D0%B2%D0%B3%D1%80%D0%B0%D0%B4%D0%B5%D0%BD%D0%B0%D1%82%D0%B0%20%D0%B7%D0%B0%D1%89%D0%B8%D1%82%D0%B0%20%D0%BE%D1%82%20%D1%81%D0%BE%D1%86%D0%B8%D0%B0%D0%BB%D0%BD%D0%B8%20%D0%BC%D0%B5%D0%B4%D0%B8%D0%B8%20%D0%BD%D0%B0%20DuckDuckGo%22%7D%7D,%22cs%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Kdy%C5%BE%20se%20p%C5%99ihl%C3%A1s%C3%AD%C5%A1%20p%C5%99es%20Facebook,%20bude%20t%C4%9B%20moct%20sledovat%22,%22informationalModalMessageBody%22:%22Po%20p%C5%99ihl%C3%A1%C5%A1en%C3%AD%20u%C5%BE%20DuckDuckGo%20nem%C5%AF%C5%BEe%20br%C3%A1nit%20Facebooku,%20aby%20t%C4%9B%20na%20t%C3%A9hle%20str%C3%A1nce%20sledoval.%22,%22informationalModalConfirmButtonText%22:%22P%C5%99ihl%C3%A1sit%20se%22,%22informationalModalRejectButtonText%22:%22Zp%C4%9Bt%22,%22loginButtonText%22:%22P%C5%99ihl%C3%A1sit%20se%20pomoc%C3%AD%20Facebooku%22,%22loginBodyText%22:%22Facebook%20sleduje%20tvou%20aktivitu%20na%20webu,%20kdy%C5%BE%20se%20p%C5%99ihl%C3%A1s%C3%AD%C5%A1%20jeho%20prost%C5%99ednictv%C3%ADm.%22,%22buttonTextUnblockContent%22:%22Odblokovat%20obsah%20na%20Facebooku%22,%22buttonTextUnblockComment%22:%22Odblokovat%20koment%C3%A1%C5%99%20na%20Facebooku%22,%22buttonTextUnblockComments%22:%22Odblokovat%20koment%C3%A1%C5%99e%20na%20Facebooku%22,%22buttonTextUnblockPost%22:%22Odblokovat%20p%C5%99%C3%ADsp%C4%9Bvek%20na%20Facebooku%22,%22buttonTextUnblockVideo%22:%22Odblokovat%20video%20na%20Facebooku%22,%22buttonTextUnblockLogin%22:%22Odblokovat%20p%C5%99ihl%C3%A1%C5%A1en%C3%AD%20k%C2%A0Facebooku%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20zablokoval%20tenhle%20obsah,%20aby%20Facebooku%20zabr%C3%A1nil%20t%C4%9B%20sledovat%22,%22infoTitleUnblockComment%22:%22Slu%C5%BEba%20DuckDuckGo%20zablokovala%20tento%20koment%C3%A1%C5%99,%20aby%20Facebooku%20zabr%C3%A1nila%20ve%20tv%C3%A9m%20sledov%C3%A1n%C3%AD%22,%22infoTitleUnblockComments%22:%22Slu%C5%BEba%20DuckDuckGo%20zablokovala%20tyto%20koment%C3%A1%C5%99e,%20aby%20Facebooku%20zabr%C3%A1nila%20ve%20tv%C3%A9m%20sledov%C3%A1n%C3%AD%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20zablokoval%20tenhle%20p%C5%99%C3%ADsp%C4%9Bvek,%20aby%20Facebooku%20zabr%C3%A1nil%20t%C4%9B%20sledovat%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20zablokoval%20tohle%20video,%20aby%20Facebooku%20zabr%C3%A1nil%20t%C4%9B%20sledovat%22,%22infoTextUnblockContent%22:%22P%C5%99i%20na%C4%8D%C3%ADt%C3%A1n%C3%AD%20str%C3%A1nky%20jsme%20Facebooku%20zabr%C3%A1nili,%20aby%20t%C4%9B%20sledoval.%20Kdy%C5%BE%20tenhle%20obsah%20odblokuje%C5%A1,%20Facebook%20bude%20m%C3%ADt%20p%C5%99%C3%ADstup%20ke%20tv%C3%A9%20aktivit%C4%9B.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22V%C3%ADce%20informac%C3%AD%22,%22readAbout%22:%22P%C5%99e%C4%8Dti%20si%20o%C2%A0t%C3%A9hle%20ochran%C4%9B%20soukrom%C3%AD%22,%22shareFeedback%22:%22Pod%C4%9Blte%20se%20o%20zp%C4%9Btnou%20vazbu%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Zapnout%20v%C5%A1echny%20n%C3%A1hledy%20YouTube?%22,%22informationalModalMessageBody%22:%22Zobrazov%C3%A1n%C3%AD%20n%C3%A1hled%C5%AF%20umo%C5%BEn%C3%AD%20spole%C4%8Dnosti%20Google%20(kter%C3%A1%20vlastn%C3%AD%20YouTube)%20zobrazit%20n%C4%9Bkter%C3%A9%20informace%20o%C2%A0tv%C3%A9m%20za%C5%99%C3%ADzen%C3%AD,%20ale%20po%C5%99%C3%A1d%20jde%20o%C2%A0diskr%C3%A9tn%C4%9Bj%C5%A1%C3%AD%20volbu,%20ne%C5%BE%20je%20p%C5%99ehr%C3%A1v%C3%A1n%C3%AD%20videa.%22,%22informationalModalConfirmButtonText%22:%22Zapnout%20v%C5%A1echny%20n%C3%A1hledy%22,%22informationalModalRejectButtonText%22:%22Ne,%20d%C4%9Bkuji%22,%22buttonTextUnblockVideo%22:%22Odblokovat%20video%20na%20YouTube%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20zablokoval%20tohle%20video%20z%C2%A0YouTube,%20aby%20Googlu%20zabr%C3%A1nil%20t%C4%9B%20sledovat%22,%22infoTextUnblockVideo%22:%22Zabr%C3%A1nili%20jsme%20spole%C4%8Dnosti%20Google%20(kter%C3%A1%20vlastn%C3%AD%20YouTube),%20aby%20t%C4%9B%20p%C5%99i%20na%C4%8D%C3%ADt%C3%A1n%C3%AD%20str%C3%A1nky%20sledovala.%20Pokud%20toto%20video%20odblokuje%C5%A1,%20Google%20z%C3%ADsk%C3%A1%20p%C5%99%C3%ADstup%20ke%20tv%C3%A9%20aktivit%C4%9B.%22,%22infoPreviewToggleText%22:%22N%C3%A1hledy%20jsou%20pro%20v%C4%9Bt%C5%A1%C3%AD%20soukrom%C3%AD%20vypnut%C3%A9%22,%22infoPreviewToggleEnabledText%22:%22N%C3%A1hledy%20jsou%20zapnut%C3%A9%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22N%C3%A1hledy%20YouTube%20jsou%20v%C2%A0DuckDuckGo%20povolen%C3%A9.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EDal%C5%A1%C3%AD%20informace%3C/a%3E%20o%C2%A0ochran%C4%9B%20DuckDuckGo%20p%C5%99ed%20sledov%C3%A1n%C3%ADm%20prost%C5%99ednictv%C3%ADm%20vlo%C5%BEen%C3%A9ho%20obsahu%20ze%20soci%C3%A1ln%C3%ADch%20m%C3%A9di%C3%AD%22%7D%7D,%22da%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22N%C3%A5r%20du%20logger%20ind%20med%20Facebook,%20kan%20de%20spore%20dig%22,%22informationalModalMessageBody%22:%22N%C3%A5r%20du%20er%20logget%20ind,%20kan%20DuckDuckGo%20ikke%20blokere%20for,%20at%20indhold%20fra%20Facebook%20sporer%20dig%20p%C3%A5%20dette%20websted.%22,%22informationalModalConfirmButtonText%22:%22Log%20p%C3%A5%22,%22informationalModalRejectButtonText%22:%22G%C3%A5%20tilbage%22,%22loginButtonText%22:%22Log%20ind%20med%20Facebook%22,%22loginBodyText%22:%22Facebook%20sporer%20din%20aktivitet%20p%C3%A5%20et%20websted,%20n%C3%A5r%20du%20bruger%20dem%20til%20at%20logge%20ind.%22,%22buttonTextUnblockContent%22:%22Bloker%20ikke%20Facebook-indhold%22,%22buttonTextUnblockComment%22:%22Bloker%20ikke%20Facebook-kommentar%22,%22buttonTextUnblockComments%22:%22Bloker%20ikke%20Facebook-kommentarer%22,%22buttonTextUnblockPost%22:%22Bloker%20ikke%20Facebook-opslag%22,%22buttonTextUnblockVideo%22:%22Bloker%20ikke%20Facebook-video%22,%22buttonTextUnblockLogin%22:%22Bloker%20ikke%20Facebook-login%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20har%20blokeret%20dette%20indhold%20for%20at%20forhindre%20Facebook%20i%20at%20spore%20dig%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20har%20blokeret%20denne%20kommentar%20for%20at%20forhindre%20Facebook%20i%20at%20spore%20dig%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20har%20blokeret%20disse%20kommentarer%20for%20at%20forhindre%20Facebook%20i%20at%20spore%20dig%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20blokerede%20dette%20indl%C3%A6g%20for%20at%20forhindre%20Facebook%20i%20at%20spore%20dig%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20har%20blokeret%20denne%20video%20for%20at%20forhindre%20Facebook%20i%20at%20spore%20dig%22,%22infoTextUnblockContent%22:%22Vi%20blokerede%20for,%20at%20Facebook%20sporede%20dig,%20da%20siden%20blev%20indl%C3%A6st.%20Hvis%20du%20oph%C3%A6ver%20blokeringen%20af%20dette%20indhold,%20vil%20Facebook%20kende%20din%20aktivitet.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Mere%20info%22,%22readAbout%22:%22L%C3%A6s%20om%20denne%20beskyttelse%20af%20privatlivet%22,%22shareFeedback%22:%22Del%20feedback%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Vil%20du%20aktivere%20alle%20YouTube-forh%C3%A5ndsvisninger?%22,%22informationalModalMessageBody%22:%22Med%20forh%C3%A5ndsvisninger%20kan%20Google%20(som%20ejer%20YouTube)%20se%20nogle%20af%20enhedens%20oplysninger,%20men%20det%20er%20stadig%20mere%20privat%20end%20at%20afspille%20videoen.%22,%22informationalModalConfirmButtonText%22:%22Aktiv%C3%A9r%20alle%20forh%C3%A5ndsvisninger%22,%22informationalModalRejectButtonText%22:%22Nej%20tak.%22,%22buttonTextUnblockVideo%22:%22Bloker%20ikke%20YouTube-video%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20har%20blokeret%20denne%20YouTube-video%20for%20at%20forhindre%20Google%20i%20at%20spore%20dig%22,%22infoTextUnblockVideo%22:%22Vi%20blokerede%20Google%20(som%20ejer%20YouTube)%20fra%20at%20spore%20dig,%20da%20siden%20blev%20indl%C3%A6st.%20Hvis%20du%20fjerner%20blokeringen%20af%20denne%20video,%20vil%20Google%20f%C3%A5%20kendskab%20til%20din%20aktivitet.%22,%22infoPreviewToggleText%22:%22Forh%C3%A5ndsvisninger%20er%20deaktiveret%20for%20at%20give%20yderligere%20privatliv%22,%22infoPreviewToggleEnabledText%22:%22Forh%C3%A5ndsvisninger%20er%20deaktiveret%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube-forh%C3%A5ndsvisninger%20er%20aktiveret%20i%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EF%C3%A5%20mere%20at%20vide%20p%C3%A5%3C/a%3E%20om%20DuckDuckGos%20indbyggede%20beskyttelse%20p%C3%A5%20sociale%20medier%22%7D%7D,%22de%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Wenn%20du%20dich%20bei%20Facebook%20anmeldest,%20kann%20Facebook%20dich%20tracken%22,%22informationalModalMessageBody%22:%22Sobald%20du%20angemeldet%20bist,%20kann%20DuckDuckGo%20nicht%20mehr%20verhindern,%20dass%20Facebook-Inhalte%20dich%20auf%20dieser%20Website%20tracken.%22,%22informationalModalConfirmButtonText%22:%22Anmelden%22,%22informationalModalRejectButtonText%22:%22Zur%C3%BCck%22,%22loginButtonText%22:%22Mit%20Facebook%20anmelden%22,%22loginBodyText%22:%22Facebook%20trackt%20deine%20Aktivit%C3%A4t%20auf%20einer%20Website,%20wenn%20du%20dich%20%C3%BCber%20Facebook%20dort%20anmeldest.%22,%22buttonTextUnblockContent%22:%22Facebook-Inhalt%20entsperren%22,%22buttonTextUnblockComment%22:%22Facebook-Kommentar%20entsperren%22,%22buttonTextUnblockComments%22:%22Facebook-Kommentare%20entsperren%22,%22buttonTextUnblockPost%22:%22Facebook-Beitrag%20entsperren%22,%22buttonTextUnblockVideo%22:%22Facebook-Video%20entsperren%22,%22buttonTextUnblockLogin%22:%22Facebook-Anmeldung%20entsperren%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20hat%20diesen%20Inhalt%20blockiert,%20um%20zu%20verhindern,%20dass%20Facebook%20dich%20trackt%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20hat%20diesen%20Kommentar%20blockiert,%20um%20zu%20verhindern,%20dass%20Facebook%20dich%20trackt%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20hat%20diese%20Kommentare%20blockiert,%20um%20zu%20verhindern,%20dass%20Facebook%20dich%20trackt%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20hat%20diesen%20Beitrag%20blockiert,%20um%20zu%20verhindern,%20dass%20Facebook%20dich%20trackt%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20hat%20dieses%20Video%20blockiert,%20um%20zu%20verhindern,%20dass%20Facebook%20dich%20trackt%22,%22infoTextUnblockContent%22:%22Wir%20haben%20Facebook%20daran%20gehindert,%20dich%20zu%20tracken,%20als%20die%20Seite%20geladen%20wurde.%20Wenn%20du%20die%20Blockierung%20f%C3%BCr%20diesen%20Inhalt%20aufhebst,%20kennt%20Facebook%20deine%20Aktivit%C3%A4ten.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Mehr%20erfahren%22,%22readAbout%22:%22Weitere%20Informationen%20%C3%BCber%20diesen%20Datenschutz%22,%22shareFeedback%22:%22Feedback%20teilen%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Alle%20YouTube-Vorschauen%20aktivieren?%22,%22informationalModalMessageBody%22:%22Durch%20das%20Anzeigen%20von%20Vorschauen%20kann%20Google%20(dem%20YouTube%20geh%C3%B6rt)%20einige%20Informationen%20zu%20deinem%20Ger%C3%A4t%20sehen.%20Dies%20ist%20aber%20immer%20noch%20privater%20als%20das%20Abspielen%20des%20Videos.%22,%22informationalModalConfirmButtonText%22:%22Alle%20Vorschauen%20aktivieren%22,%22informationalModalRejectButtonText%22:%22Nein,%20danke%22,%22buttonTextUnblockVideo%22:%22YouTube-Video%20entsperren%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20hat%20dieses%20YouTube-Video%20blockiert,%20um%20zu%20verhindern,%20dass%20Google%20dich%20trackt.%22,%22infoTextUnblockVideo%22:%22Wir%20haben%20Google%20(dem%20YouTube%20geh%C3%B6rt)%20daran%20gehindert,%20dich%20beim%20Laden%20der%20Seite%20zu%20tracken.%20Wenn%20du%20die%20Blockierung%20f%C3%BCr%20dieses%20Video%20aufhebst,%20kennt%20Google%20deine%20Aktivit%C3%A4ten.%22,%22infoPreviewToggleText%22:%22Vorschau%20f%C3%BCr%20mehr%20Privatsph%C3%A4re%20deaktiviert%22,%22infoPreviewToggleEnabledText%22:%22Vorschau%20aktiviert%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube-Vorschauen%20sind%20in%20DuckDuckGo%20aktiviert.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EErfahre%20mehr%3C/a%3E%20%C3%BCber%20den%20DuckDuckGo-Schutz%20vor%20eingebetteten%20Social%20Media-Inhalten%22%7D%7D,%22el%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22%CE%97%20%CF%83%CF%8D%CE%BD%CE%B4%CE%B5%CF%83%CE%B7%20%CE%BC%CE%AD%CF%83%CF%89%20Facebook%20%CF%84%CE%BF%CF%85%CF%82%20%CE%B5%CF%80%CE%B9%CF%84%CF%81%CE%AD%CF%80%CE%B5%CE%B9%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%BF%CF%8D%CE%BD%22,%22informationalModalMessageBody%22:%22%CE%9C%CF%8C%CE%BB%CE%B9%CF%82%20%CF%83%CF%85%CE%BD%CE%B4%CE%B5%CE%B8%CE%B5%CE%AF%CF%84%CE%B5,%20%CF%84%CE%BF%20DuckDuckGo%20%CE%B4%CE%B5%CE%BD%20%CE%BC%CF%80%CE%BF%CF%81%CE%B5%CE%AF%20%CE%BD%CE%B1%20%CE%B5%CE%BC%CF%80%CE%BF%CE%B4%CE%AF%CF%83%CE%B5%CE%B9%20%CF%84%CE%BF%20%CF%80%CE%B5%CF%81%CE%B9%CE%B5%CF%87%CF%8C%CE%BC%CE%B5%CE%BD%CE%BF%20%CF%84%CE%BF%CF%85%20Facebook%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%BF%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%20%CF%83%CE%B5%20%CE%B1%CF%85%CF%84%CF%8C%CE%BD%20%CF%84%CE%BF%CE%BD%20%CE%B9%CF%83%CF%84%CF%8C%CF%84%CE%BF%CF%80%CE%BF.%22,%22informationalModalConfirmButtonText%22:%22%CE%A3%CF%8D%CE%BD%CE%B4%CE%B5%CF%83%CE%B7%22,%22informationalModalRejectButtonText%22:%22%CE%95%CF%80%CE%B9%CF%83%CF%84%CF%81%CE%BF%CF%86%CE%AE%22,%22loginButtonText%22:%22%CE%A3%CF%8D%CE%BD%CE%B4%CE%B5%CF%83%CE%B7%20%CE%BC%CE%AD%CF%83%CF%89%20Facebook%22,%22loginBodyText%22:%22%CE%A4%CE%BF%20Facebook%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%20%CF%84%CE%B7%20%CE%B4%CF%81%CE%B1%CF%83%CF%84%CE%B7%CF%81%CE%B9%CF%8C%CF%84%CE%B7%CF%84%CE%AC%20%CF%83%CE%B1%CF%82%20%CF%83%CE%B5%20%CE%AD%CE%BD%CE%B1%CE%BD%20%CE%B9%CF%83%CF%84%CF%8C%CF%84%CE%BF%CF%80%CE%BF%20%CF%8C%CF%84%CE%B1%CE%BD%20%CF%84%CE%BF%CE%BD%20%CF%87%CF%81%CE%B7%CF%83%CE%B9%CE%BC%CE%BF%CF%80%CE%BF%CE%B9%CE%B5%CE%AF%CF%84%CE%B5%20%CE%B3%CE%B9%CE%B1%20%CE%BD%CE%B1%20%CF%83%CF%85%CE%BD%CE%B4%CE%B5%CE%B8%CE%B5%CE%AF%CF%84%CE%B5.%22,%22buttonTextUnblockContent%22:%22%CE%86%CF%81%CF%83%CE%B7%20%CE%B1%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%BC%CE%BF%CF%8D%20%CF%80%CE%B5%CF%81%CE%B9%CE%B5%CF%87%CE%BF%CE%BC%CE%AD%CE%BD%CE%BF%CF%85%20%CF%83%CF%84%CE%BF%20Facebook%22,%22buttonTextUnblockComment%22:%22%CE%86%CF%81%CF%83%CE%B7%20%CE%B1%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%BC%CE%BF%CF%8D%20%CF%83%CF%87%CF%8C%CE%BB%CE%B9%CE%BF%CF%85%20%CF%83%CF%84%CE%BF%20Facebook%22,%22buttonTextUnblockComments%22:%22%CE%86%CF%81%CF%83%CE%B7%20%CE%B1%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%BC%CE%BF%CF%8D%20%CF%83%CF%87%CE%BF%CE%BB%CE%AF%CF%89%CE%BD%20%CF%83%CF%84%CE%BF%20Facebook%22,%22buttonTextUnblockPost%22:%22%CE%86%CF%81%CF%83%CE%B7%20%CE%B1%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%BC%CE%BF%CF%8D%20%CE%B1%CE%BD%CE%AC%CF%81%CF%84%CE%B7%CF%83%CE%B7%CF%82%20%CF%83%CF%84%CE%BF%20Facebook%22,%22buttonTextUnblockVideo%22:%22%CE%86%CF%81%CF%83%CE%B7%20%CE%B1%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%BC%CE%BF%CF%8D%20%CE%B2%CE%AF%CE%BD%CF%84%CE%B5%CE%BF%20%CF%83%CF%84%CE%BF%20Facebook%22,%22buttonTextUnblockLogin%22:%22%CE%86%CF%81%CF%83%CE%B7%20%CE%B1%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%BC%CE%BF%CF%8D%20%CF%83%CF%8D%CE%BD%CE%B4%CE%B5%CF%83%CE%B7%CF%82%20%CF%83%CF%84%CE%BF%20Facebook%22,%22infoTitleUnblockContent%22:%22%CE%A4%CE%BF%20DuckDuckGo%20%CE%B1%CF%80%CE%AD%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%B5%20%CF%84%CE%BF%20%CF%80%CE%B5%CF%81%CE%B9%CE%B5%CF%87%CF%8C%CE%BC%CE%B5%CE%BD%CE%BF%20%CE%B1%CF%85%CF%84%CF%8C%20%CE%B3%CE%B9%CE%B1%20%CE%BD%CE%B1%20%CE%B5%CE%BC%CF%80%CE%BF%CE%B4%CE%AF%CF%83%CE%B5%CE%B9%20%CF%84%CE%BF%20Facebook%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%BF%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%22,%22infoTitleUnblockComment%22:%22%CE%A4%CE%BF%20DuckDuckGo%20%CE%B1%CF%80%CE%AD%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%B5%20%CF%84%CE%BF%20%CF%83%CF%87%CF%8C%CE%BB%CE%B9%CE%BF%20%CE%B1%CF%85%CF%84%CF%8C%20%CE%B3%CE%B9%CE%B1%20%CE%BD%CE%B1%20%CE%B5%CE%BC%CF%80%CE%BF%CE%B4%CE%AF%CF%83%CE%B5%CE%B9%20%CF%84%CE%BF%20Facebook%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%BF%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%22,%22infoTitleUnblockComments%22:%22%CE%A4%CE%BF%20DuckDuckGo%20%CE%B1%CF%80%CE%AD%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%B5%20%CF%84%CE%B1%20%CF%83%CF%87%CF%8C%CE%BB%CE%B9%CE%B1%20%CE%B1%CF%85%CF%84%CE%AC%20%CE%B3%CE%B9%CE%B1%20%CE%BD%CE%B1%20%CE%B5%CE%BC%CF%80%CE%BF%CE%B4%CE%AF%CF%83%CE%B5%CE%B9%20%CF%84%CE%BF%20Facebook%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%BF%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%22,%22infoTitleUnblockPost%22:%22%CE%A4%CE%BF%20DuckDuckGo%20%CE%B1%CF%80%CE%AD%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%B5%20%CF%84%CE%B7%CE%BD%20%CE%B1%CE%BD%CE%AC%CF%81%CF%84%CE%B7%CF%83%CE%B7%20%CE%B1%CF%85%CF%84%CE%AE%20%CE%B3%CE%B9%CE%B1%20%CE%BD%CE%B1%20%CE%B5%CE%BC%CF%80%CE%BF%CE%B4%CE%AF%CF%83%CE%B5%CE%B9%20%CF%84%CE%BF%20Facebook%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%BF%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%22,%22infoTitleUnblockVideo%22:%22%CE%A4%CE%BF%20DuckDuckGo%20%CE%B1%CF%80%CE%AD%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%B5%20%CF%84%CE%BF%20%CE%B2%CE%AF%CE%BD%CF%84%CE%B5%CE%BF%20%CE%B1%CF%85%CF%84%CF%8C%20%CE%B3%CE%B9%CE%B1%20%CE%BD%CE%B1%20%CE%B5%CE%BC%CF%80%CE%BF%CE%B4%CE%AF%CF%83%CE%B5%CE%B9%20%CF%84%CE%BF%20Facebook%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%BF%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%22,%22infoTextUnblockContent%22:%22%CE%91%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%AF%CF%83%CE%B1%CE%BC%CE%B5%20%CF%84%CE%BF%20Facebook%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%BF%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%20%CF%8C%CF%84%CE%B1%CE%BD%20%CF%86%CE%BF%CF%81%CF%84%CF%8E%CE%B8%CE%B7%CE%BA%CE%B5%20%CE%B7%20%CF%83%CE%B5%CE%BB%CE%AF%CE%B4%CE%B1.%20%CE%95%CE%AC%CE%BD%20%CE%BA%CE%AC%CE%BD%CE%B5%CF%84%CE%B5%20%CE%AC%CF%81%CF%83%CE%B7%20%CE%B1%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%BC%CE%BF%CF%8D%20%CE%B3%CE%B9'%20%CE%B1%CF%85%CF%84%CF%8C%20%CF%84%CE%BF%20%CF%80%CE%B5%CF%81%CE%B9%CE%B5%CF%87%CF%8C%CE%BC%CE%B5%CE%BD%CE%BF,%20%CF%84%CE%BF%20Facebook%20%CE%B8%CE%B1%20%CE%B3%CE%BD%CF%89%CF%81%CE%AF%CE%B6%CE%B5%CE%B9%20%CF%84%CE%B7%20%CE%B4%CF%81%CE%B1%CF%83%CF%84%CE%B7%CF%81%CE%B9%CF%8C%CF%84%CE%B7%CF%84%CE%AC%20%CF%83%CE%B1%CF%82.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22%CE%9C%CE%AC%CE%B8%CE%B5%CF%84%CE%B5%20%CF%80%CE%B5%CF%81%CE%B9%CF%83%CF%83%CF%8C%CF%84%CE%B5%CF%81%CE%B1%22,%22readAbout%22:%22%CE%94%CE%B9%CE%B1%CE%B2%CE%AC%CF%83%CF%84%CE%B5%20%CF%83%CF%87%CE%B5%CF%84%CE%B9%CE%BA%CE%AC%20%CE%BC%CE%B5%20%CF%84%CE%B7%CE%BD%20%CF%80%CE%B1%CF%81%CE%BF%CF%8D%CF%83%CE%B1%20%CF%80%CF%81%CE%BF%CF%83%CF%84%CE%B1%CF%83%CE%AF%CE%B1%CF%82%20%CF%80%CF%81%CE%BF%CF%83%CF%89%CF%80%CE%B9%CE%BA%CF%8E%CE%BD%20%CE%B4%CE%B5%CE%B4%CE%BF%CE%BC%CE%AD%CE%BD%CF%89%CE%BD%22,%22shareFeedback%22:%22%CE%9A%CE%BF%CE%B9%CE%BD%CE%BF%CF%80%CE%BF%CE%AF%CE%B7%CF%83%CE%B7%20%CF%83%CF%87%CE%BF%CE%BB%CE%AF%CE%BF%CF%85%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22%CE%95%CE%BD%CE%B5%CF%81%CE%B3%CE%BF%CF%80%CE%BF%CE%AF%CE%B7%CF%83%CE%B7%20%CF%8C%CE%BB%CF%89%CE%BD%20%CF%84%CF%89%CE%BD%20%CF%80%CF%81%CE%BF%CE%B5%CF%80%CE%B9%CF%83%CE%BA%CE%BF%CF%80%CE%AE%CF%83%CE%B5%CF%89%CE%BD%20%CF%84%CE%BF%CF%85%20YouTube;%22,%22informationalModalMessageBody%22:%22%CE%97%20%CF%80%CF%81%CE%BF%CE%B2%CE%BF%CE%BB%CE%AE%20%CF%84%CF%89%CE%BD%20%CF%80%CF%81%CE%BF%CE%B5%CF%80%CE%B9%CF%83%CE%BA%CE%BF%CF%80%CE%AE%CF%83%CE%B5%CF%89%CE%BD%20%CE%B8%CE%B1%20%CE%B5%CF%80%CE%B9%CF%84%CF%81%CE%AD%CF%88%CE%B5%CE%B9%20%CF%83%CF%84%CE%B7%CE%BD%20Google%20(%CF%83%CF%84%CE%B7%CE%BD%20%CE%BF%CF%80%CE%BF%CE%AF%CE%B1%20%CE%B1%CE%BD%CE%AE%CE%BA%CE%B5%CE%B9%20%CF%84%CE%BF%20YouTube)%20%CE%BD%CE%B1%20%CE%B2%CE%BB%CE%AD%CF%80%CE%B5%CE%B9%20%CE%BF%CF%81%CE%B9%CF%83%CE%BC%CE%AD%CE%BD%CE%B5%CF%82%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%B9%CF%82%20%CF%80%CE%BB%CE%B7%CF%81%CE%BF%CF%86%CE%BF%CF%81%CE%AF%CE%B5%CF%82%20%CF%84%CE%B7%CF%82%20%CF%83%CF%85%CF%83%CE%BA%CE%B5%CF%85%CE%AE%CF%82%20%CF%83%CE%B1%CF%82,%20%CF%89%CF%83%CF%84%CF%8C%CF%83%CE%BF%20%CE%B5%CE%BE%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%20%CE%BD%CE%B1%20%CE%B5%CE%AF%CE%BD%CE%B1%CE%B9%20%CF%80%CE%B9%CE%BF%20%CE%B9%CE%B4%CE%B9%CF%89%CF%84%CE%B9%CE%BA%CE%AE%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%B7%CE%BD%20%CE%B1%CE%BD%CE%B1%CF%80%CE%B1%CF%81%CE%B1%CE%B3%CF%89%CE%B3%CE%AE%20%CF%84%CE%BF%CF%85%20%CE%B2%CE%AF%CE%BD%CF%84%CE%B5%CE%BF.%22,%22informationalModalConfirmButtonText%22:%22%CE%95%CE%BD%CE%B5%CF%81%CE%B3%CE%BF%CF%80%CE%BF%CE%AF%CE%B7%CF%83%CE%B7%20%CF%8C%CE%BB%CF%89%CE%BD%20%CF%84%CF%89%CE%BD%20%CF%80%CF%81%CE%BF%CE%B5%CF%80%CE%B9%CF%83%CE%BA%CE%BF%CF%80%CE%AE%CF%83%CE%B5%CF%89%CE%BD%22,%22informationalModalRejectButtonText%22:%22%CE%8C%CF%87%CE%B9,%20%CE%B5%CF%85%CF%87%CE%B1%CF%81%CE%B9%CF%83%CF%84%CF%8E%22,%22buttonTextUnblockVideo%22:%22%CE%86%CF%81%CF%83%CE%B7%20%CE%B1%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%BC%CE%BF%CF%8D%20%CE%B2%CE%AF%CE%BD%CF%84%CE%B5%CE%BF%20YouTube%22,%22infoTitleUnblockVideo%22:%22%CE%A4%CE%BF%20DuckDuckGo%20%CE%B1%CF%80%CE%AD%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%B5%20%CF%84%CE%BF%20%CE%B2%CE%AF%CE%BD%CF%84%CE%B5%CE%BF%20%CE%B1%CF%85%CF%84%CF%8C%20%CF%83%CF%84%CE%BF%20YouTube%20%CE%B3%CE%B9%CE%B1%20%CE%BD%CE%B1%20%CE%B5%CE%BC%CF%80%CE%BF%CE%B4%CE%AF%CF%83%CE%B5%CE%B9%20%CF%84%CE%B7%CE%BD%20Google%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%BF%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%22,%22infoTextUnblockVideo%22:%22%CE%91%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%AF%CF%83%CE%B1%CE%BC%CE%B5%20%CF%84%CE%B7%CE%BD%20Google%20(%CF%83%CF%84%CE%B7%CE%BD%20%CE%BF%CF%80%CE%BF%CE%AF%CE%B1%20%CE%B1%CE%BD%CE%AE%CE%BA%CE%B5%CE%B9%20%CF%84%CE%BF%20YouTube)%20%CE%B1%CF%80%CF%8C%20%CF%84%CE%BF%20%CE%BD%CE%B1%20%CF%83%CE%B1%CF%82%20%CF%80%CE%B1%CF%81%CE%B1%CE%BA%CE%BF%CE%BB%CE%BF%CF%85%CE%B8%CE%B5%CE%AF%20%CF%8C%CF%84%CE%B1%CE%BD%20%CF%86%CE%BF%CF%81%CF%84%CF%8E%CE%B8%CE%B7%CE%BA%CE%B5%20%CE%B7%20%CF%83%CE%B5%CE%BB%CE%AF%CE%B4%CE%B1.%20%CE%95%CE%AC%CE%BD%20%CE%BA%CE%AC%CE%BD%CE%B5%CF%84%CE%B5%20%CE%AC%CF%81%CF%83%CE%B7%20%CE%B1%CF%80%CE%BF%CE%BA%CE%BB%CE%B5%CE%B9%CF%83%CE%BC%CE%BF%CF%8D%20%CE%B3%CE%B9'%20%CE%B1%CF%85%CF%84%CF%8C%20%CF%84%CE%BF%20%CE%B2%CE%AF%CE%BD%CF%84%CE%B5%CE%BF,%20%CE%B7%20Google%20%CE%B8%CE%B1%20%CE%B3%CE%BD%CF%89%CF%81%CE%AF%CE%B6%CE%B5%CE%B9%20%CF%84%CE%B7%20%CE%B4%CF%81%CE%B1%CF%83%CF%84%CE%B7%CF%81%CE%B9%CF%8C%CF%84%CE%B7%CF%84%CE%AC%20%CF%83%CE%B1%CF%82.%22,%22infoPreviewToggleText%22:%22%CE%9F%CE%B9%20%CF%80%CF%81%CE%BF%CE%B5%CF%80%CE%B9%CF%83%CE%BA%CE%BF%CF%80%CE%AE%CF%83%CE%B5%CE%B9%CF%82%20%CE%B1%CF%80%CE%B5%CE%BD%CE%B5%CF%81%CE%B3%CE%BF%CF%80%CE%BF%CE%B9%CE%AE%CE%B8%CE%B7%CE%BA%CE%B1%CE%BD%20%CE%B3%CE%B9%CE%B1%20%CF%80%CF%81%CF%8C%CF%83%CE%B8%CE%B5%CF%84%CE%B7%20%CF%80%CF%81%CE%BF%CF%83%CF%84%CE%B1%CF%83%CE%AF%CE%B1%20%CF%84%CF%89%CE%BD%20%CF%80%CF%81%CE%BF%CF%83%CF%89%CF%80%CE%B9%CE%BA%CF%8E%CE%BD%20%CE%B4%CE%B5%CE%B4%CE%BF%CE%BC%CE%AD%CE%BD%CF%89%CE%BD%22,%22infoPreviewToggleEnabledText%22:%22%CE%9F%CE%B9%20%CF%80%CF%81%CE%BF%CE%B5%CF%80%CE%B9%CF%83%CE%BA%CE%BF%CF%80%CE%AE%CF%83%CE%B5%CE%B9%CF%82%20%CE%B5%CE%BD%CE%B5%CF%81%CE%B3%CE%BF%CF%80%CE%BF%CE%B9%CE%AE%CE%B8%CE%B7%CE%BA%CE%B1%CE%BD%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22%CE%9F%CE%B9%20%CF%80%CF%81%CE%BF%CE%B5%CF%80%CE%B9%CF%83%CE%BA%CE%BF%CF%80%CE%AE%CF%83%CE%B5%CE%B9%CF%82%20YouTube%20%CE%B5%CE%BD%CE%B5%CF%81%CE%B3%CE%BF%CF%80%CE%BF%CE%B9%CE%AE%CE%B8%CE%B7%CE%BA%CE%B1%CE%BD%20%CF%83%CF%84%CE%BF%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3E%CE%9C%CE%AC%CE%B8%CE%B5%CF%84%CE%B5%20%CF%80%CE%B5%CF%81%CE%B9%CF%83%CF%83%CF%8C%CF%84%CE%B5%CF%81%CE%B1%3C/a%3E%20%CE%B3%CE%B9%CE%B1%20%CF%84%CE%B7%CE%BD%20%CE%B5%CE%BD%CF%83%CF%89%CE%BC%CE%B1%CF%84%CF%89%CE%BC%CE%AD%CE%BD%CE%B7%20%CF%80%CF%81%CE%BF%CF%83%CF%84%CE%B1%CF%83%CE%AF%CE%B1%20%CE%BA%CE%BF%CE%B9%CE%BD%CF%89%CE%BD%CE%B9%CE%BA%CF%8E%CE%BD%20%CE%BC%CE%AD%CF%83%CF%89%CE%BD%20DuckDuckGo%22%7D%7D,%22en%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Logging%20in%20with%20Facebook%20lets%20them%20track%20you%22,%22informationalModalMessageBody%22:%22Once%20you're%20logged%20in,%20DuckDuckGo%20can't%20block%20Facebook%20content%20from%20tracking%20you%20on%20this%20site.%22,%22informationalModalConfirmButtonText%22:%22Log%20In%22,%22informationalModalRejectButtonText%22:%22Go%20back%22,%22loginButtonText%22:%22Log%20in%20with%20Facebook%22,%22loginBodyText%22:%22Facebook%20tracks%20your%20activity%20on%20a%20site%20when%20you%20use%20them%20to%20login.%22,%22buttonTextUnblockContent%22:%22Unblock%20Facebook%20Content%22,%22buttonTextUnblockComment%22:%22Unblock%20Facebook%20Comment%22,%22buttonTextUnblockComments%22:%22Unblock%20Facebook%20Comments%22,%22buttonTextUnblockPost%22:%22Unblock%20Facebook%20Post%22,%22buttonTextUnblockVideo%22:%22Unblock%20Facebook%20Video%22,%22buttonTextUnblockLogin%22:%22Unblock%20Facebook%20Login%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20blocked%20this%20content%20to%20prevent%20Facebook%20from%20tracking%20you%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20blocked%20this%20comment%20to%20prevent%20Facebook%20from%20tracking%20you%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20blocked%20these%20comments%20to%20prevent%20Facebook%20from%20tracking%20you%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20blocked%20this%20post%20to%20prevent%20Facebook%20from%20tracking%20you%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blocked%20this%20video%20to%20prevent%20Facebook%20from%20tracking%20you%22,%22infoTextUnblockContent%22:%22We%20blocked%20Facebook%20from%20tracking%20you%20when%20the%20page%20loaded.%20If%20you%20unblock%20this%20content,%20Facebook%20will%20know%20your%20activity.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Learn%20More%22,%22readAbout%22:%22Read%20about%20this%20privacy%20protection%22,%22shareFeedback%22:%22Share%20Feedback%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Enable%20all%20YouTube%20previews?%22,%22informationalModalMessageBody%22:%22Showing%20previews%20will%20allow%20Google%20(which%20owns%20YouTube)%20to%20see%20some%20of%20your%20device%E2%80%99s%20information,%20but%20is%20still%20more%20private%20than%20playing%20the%20video.%22,%22informationalModalConfirmButtonText%22:%22Enable%20All%20Previews%22,%22informationalModalRejectButtonText%22:%22No%20Thanks%22,%22buttonTextUnblockVideo%22:%22Unblock%20YouTube%20Video%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blocked%20this%20YouTube%20video%20to%20prevent%20Google%20from%20tracking%20you%22,%22infoTextUnblockVideo%22:%22We%20blocked%20Google%20(which%20owns%20YouTube)%20from%20tracking%20you%20when%20the%20page%20loaded.%20If%20you%20unblock%20this%20video,%20Google%20will%20know%20your%20activity.%22,%22infoPreviewToggleText%22:%22Previews%20disabled%20for%20additional%20privacy%22,%22infoPreviewToggleEnabledText%22:%22Previews%20enabled%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube%20previews%20enabled%20in%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3ELearn%20more%3C/a%3E%20about%20DuckDuckGo%20Embedded%20Social%20Media%20Protection%22%7D%7D,%22es%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Al%20iniciar%20sesi%C3%B3n%20en%20Facebook,%20les%20permites%20que%20te%20rastreen%22,%22informationalModalMessageBody%22:%22Una%20vez%20que%20hayas%20iniciado%20sesi%C3%B3n,%20DuckDuckGo%20no%20puede%20bloquear%20el%20contenido%20de%20Facebook%20para%20que%20no%20te%20rastree%20en%20este%20sitio.%22,%22informationalModalConfirmButtonText%22:%22Iniciar%20sesi%C3%B3n%22,%22informationalModalRejectButtonText%22:%22Volver%20atr%C3%A1s%22,%22loginButtonText%22:%22Iniciar%20sesi%C3%B3n%20con%20Facebook%22,%22loginBodyText%22:%22Facebook%20rastrea%20tu%20actividad%20en%20un%20sitio%20web%20cuando%20lo%20usas%20para%20iniciar%20sesi%C3%B3n.%22,%22buttonTextUnblockContent%22:%22Desbloquear%20contenido%20de%20Facebook%22,%22buttonTextUnblockComment%22:%22Desbloquear%20comentario%20de%20Facebook%22,%22buttonTextUnblockComments%22:%22Desbloquear%20comentarios%20de%20Facebook%22,%22buttonTextUnblockPost%22:%22Desbloquear%20publicaci%C3%B3n%20de%20Facebook%22,%22buttonTextUnblockVideo%22:%22Desbloquear%20v%C3%ADdeo%20de%20Facebook%22,%22buttonTextUnblockLogin%22:%22Desbloquear%20inicio%20de%20sesi%C3%B3n%20de%20Facebook%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20ha%20bloqueado%20este%20contenido%20para%20evitar%20que%20Facebook%20te%20rastree%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20ha%20bloqueado%20este%20comentario%20para%20evitar%20que%20Facebook%20te%20rastree%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20ha%20bloqueado%20estos%20comentarios%20para%20evitar%20que%20Facebook%20te%20rastree%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20ha%20bloqueado%20esta%20publicaci%C3%B3n%20para%20evitar%20que%20Facebook%20te%20rastree%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20ha%20bloqueado%20este%20v%C3%ADdeo%20para%20evitar%20que%20Facebook%20te%20rastree%22,%22infoTextUnblockContent%22:%22Hemos%20bloqueado%20el%20rastreo%20de%20Facebook%20cuando%20se%20ha%20cargado%20la%20p%C3%A1gina.%20Si%20desbloqueas%20este%20contenido,%20Facebook%20tendr%C3%A1%20conocimiento%20de%20tu%20actividad.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22M%C3%A1s%20informaci%C3%B3n%22,%22readAbout%22:%22Lee%20acerca%20de%20esta%20protecci%C3%B3n%20de%20privacidad%22,%22shareFeedback%22:%22Compartir%20opiniones%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22%C2%BFHabilitar%20todas%20las%20vistas%20previas%20de%20YouTube?%22,%22informationalModalMessageBody%22:%22Mostrar%20vistas%20previas%20permitir%C3%A1%20a%20Google%20(que%20es%20el%20propietario%20de%20YouTube)%20ver%20parte%20de%20la%20informaci%C3%B3n%20de%20tu%20dispositivo,%20pero%20sigue%20siendo%20m%C3%A1s%20privado%20que%20reproducir%20el%20v%C3%ADdeo.%22,%22informationalModalConfirmButtonText%22:%22Habilitar%20todas%20las%20vistas%20previas%22,%22informationalModalRejectButtonText%22:%22No,%20gracias%22,%22buttonTextUnblockVideo%22:%22Desbloquear%20v%C3%ADdeo%20de%20YouTube%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20ha%20bloqueado%20este%20v%C3%ADdeo%20de%20YouTube%20para%20evitar%20que%20Google%20te%20rastree%22,%22infoTextUnblockVideo%22:%22Hemos%20bloqueado%20el%20rastreo%20de%20Google%20(que%20es%20el%20propietario%20de%20YouTube)%20al%20cargarse%20la%20p%C3%A1gina.%20Si%20desbloqueas%20este%20v%C3%ADdeo,%20Goggle%20tendr%C3%A1%20conocimiento%20de%20tu%20actividad.%22,%22infoPreviewToggleText%22:%22Vistas%20previas%20desactivadas%20para%20mayor%20privacidad%22,%22infoPreviewToggleEnabledText%22:%22Vistas%20previas%20activadas%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22Vistas%20previas%20de%20YouTube%20habilitadas%20en%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EM%C3%A1s%20informaci%C3%B3n%3C/a%3E%20sobre%20la%20protecci%C3%B3n%20integrada%20de%20redes%20sociales%20DuckDuckGo%22%7D%7D,%22et%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Kui%20logid%20Facebookiga%20sisse,%20saab%20Facebook%20sind%20j%C3%A4lgida%22,%22informationalModalMessageBody%22:%22Kui%20oled%20sisse%20logitud,%20ei%20saa%20DuckDuckGo%20blokeerida%20Facebooki%20sisu%20sind%20j%C3%A4lgimast.%22,%22informationalModalConfirmButtonText%22:%22Logi%20sisse%22,%22informationalModalRejectButtonText%22:%22Mine%20tagasi%22,%22loginButtonText%22:%22Logi%20sisse%20Facebookiga%22,%22loginBodyText%22:%22Kui%20logid%20sisse%20Facebookiga,%20saab%20Facebook%20sinu%20tegevust%20saidil%20j%C3%A4lgida.%22,%22buttonTextUnblockContent%22:%22Deblokeeri%20Facebooki%20sisu%22,%22buttonTextUnblockComment%22:%22Deblokeeri%20Facebooki%20kommentaar%22,%22buttonTextUnblockComments%22:%22Deblokeeri%20Facebooki%20kommentaarid%22,%22buttonTextUnblockPost%22:%22Deblokeeri%20Facebooki%20postitus%22,%22buttonTextUnblockVideo%22:%22Deblokeeri%20Facebooki%20video%22,%22buttonTextUnblockLogin%22:%22Deblokeeri%20Facebooki%20sisselogimine%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20blokeeris%20selle%20sisu,%20et%20Facebook%20ei%20saaks%20sind%20j%C3%A4lgida%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20blokeeris%20selle%20kommentaari,%20et%20Facebook%20ei%20saaks%20sind%20j%C3%A4lgida%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20blokeeris%20need%20kommentaarid,%20et%20Facebook%20ei%20saaks%20sind%20j%C3%A4lgida%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20blokeeris%20selle%20postituse,%20et%20Facebook%20ei%20saaks%20sind%20j%C3%A4lgida%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blokeeris%20selle%20video,%20et%20Facebook%20ei%20saaks%20sind%20j%C3%A4lgida%22,%22infoTextUnblockContent%22:%22Blokeerisime%20lehe%20laadimise%20ajal%20Facebooki%20jaoks%20sinu%20j%C3%A4lgimise.%20Kui%20sa%20selle%20sisu%20deblokeerid,%20saab%20Facebook%20sinu%20tegevust%20j%C3%A4lgida.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Loe%20edasi%22,%22readAbout%22:%22Loe%20selle%20privaatsuskaitse%20kohta%22,%22shareFeedback%22:%22Jaga%20tagasisidet%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Kas%20lubada%20k%C3%B5ik%20YouTube%E2%80%99i%20eelvaated?%22,%22informationalModalMessageBody%22:%22Eelvaate%20n%C3%A4itamine%20v%C3%B5imaldab%20Google%E2%80%99il%20(kellele%20YouTube%20kuulub)%20n%C3%A4ha%20osa%20sinu%20seadme%20teabest,%20kuid%20see%20on%20siiski%20privaatsem%20kui%20video%20esitamine.%22,%22informationalModalConfirmButtonText%22:%22Luba%20k%C3%B5ik%20eelvaated%22,%22informationalModalRejectButtonText%22:%22Ei%20ait%C3%A4h%22,%22buttonTextUnblockVideo%22:%22Deblokeeri%20YouTube%E2%80%99i%20video%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blokeeris%20selle%20YouTube%E2%80%99i%20video,%20et%20takistada%20Google%E2%80%99it%20sind%20j%C3%A4lgimast%22,%22infoTextUnblockVideo%22:%22Me%20blokeerisime%20lehe%20laadimise%20ajal%20Google%E2%80%99i%20(kellele%20YouTube%20kuulub)%20j%C3%A4lgimise.%20Kui%20sa%20selle%20video%20deblokeerid,%20saab%20Google%20sinu%20tegevusest%20teada.%22,%22infoPreviewToggleText%22:%22Eelvaated%20on%20t%C3%A4iendava%20privaatsuse%20tagamiseks%20keelatud%22,%22infoPreviewToggleEnabledText%22:%22Eelvaated%20on%20lubatud%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube%E2%80%99i%20eelvaated%20on%20DuckDuckGos%20lubatud.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3ELisateave%3C/a%3E%20DuckDuckGo%20sisseehitatud%20sotsiaalmeediakaitse%20kohta%22%7D%7D,%22fi%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Kun%20kirjaudut%20sis%C3%A4%C3%A4n%20Facebook-tunnuksilla,%20Facebook%20voi%20seurata%20sinua%22,%22informationalModalMessageBody%22:%22Kun%20olet%20kirjautunut%20sis%C3%A4%C3%A4n,%20DuckDuckGo%20ei%20voi%20est%C3%A4%C3%A4%20Facebook-sis%C3%A4lt%C3%B6%C3%A4%20seuraamasta%20sinua%20t%C3%A4ll%C3%A4%20sivustolla.%22,%22informationalModalConfirmButtonText%22:%22Kirjaudu%20sis%C3%A4%C3%A4n%22,%22informationalModalRejectButtonText%22:%22Edellinen%22,%22loginButtonText%22:%22Kirjaudu%20sis%C3%A4%C3%A4n%20Facebook-tunnuksilla%22,%22loginBodyText%22:%22Facebook%20seuraa%20toimintaasi%20sivustolla,%20kun%20kirjaudut%20sis%C3%A4%C3%A4n%20sen%20kautta.%22,%22buttonTextUnblockContent%22:%22Poista%20Facebook-sis%C3%A4ll%C3%B6n%20esto%22,%22buttonTextUnblockComment%22:%22Poista%20Facebook-kommentin%20esto%22,%22buttonTextUnblockComments%22:%22Poista%20Facebook-kommenttien%20esto%22,%22buttonTextUnblockPost%22:%22Poista%20Facebook-julkaisun%20esto%22,%22buttonTextUnblockVideo%22:%22Poista%20Facebook-videon%20esto%22,%22buttonTextUnblockLogin%22:%22Poista%20Facebook-kirjautumisen%20esto%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20esti%20t%C3%A4m%C3%A4n%20sis%C3%A4ll%C3%B6n%20est%C3%A4%C3%A4kseen%20Facebookia%20seuraamasta%20sinua%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20esti%20t%C3%A4m%C3%A4n%20kommentin%20est%C3%A4%C3%A4kseen%20Facebookia%20seuraamasta%20sinua%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20esti%20n%C3%A4m%C3%A4%20kommentit%20est%C3%A4%C3%A4kseen%20Facebookia%20seuraamasta%20sinua%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20esti%20t%C3%A4m%C3%A4n%20julkaisun%20est%C3%A4%C3%A4kseen%20Facebookia%20seuraamasta%20sinua%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20esti%20t%C3%A4m%C3%A4n%20videon%20est%C3%A4%C3%A4kseen%20Facebookia%20seuraamasta%20sinua%22,%22infoTextUnblockContent%22:%22Estimme%20Facebookia%20seuraamasta%20sinua,%20kun%20sivua%20ladattiin.%20Jos%20poistat%20t%C3%A4m%C3%A4n%20sis%C3%A4ll%C3%B6n%20eston,%20Facebook%20saa%20tiet%C3%A4%C3%A4%20toimintasi.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Lue%20lis%C3%A4%C3%A4%22,%22readAbout%22:%22Lue%20t%C3%A4st%C3%A4%20yksityisyydensuojasta%22,%22shareFeedback%22:%22Jaa%20palaute%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Otetaanko%20k%C3%A4ytt%C3%B6%C3%B6n%20kaikki%20YouTube-esikatselut?%22,%22informationalModalMessageBody%22:%22Kun%20sallit%20esikatselun,%20Google%20(joka%20omistaa%20YouTuben)%20voi%20n%C3%A4hd%C3%A4%20joitakin%20laitteesi%20tietoja,%20mutta%20se%20on%20silti%20yksityisemp%C3%A4%C3%A4%20kuin%20videon%20toistaminen.%22,%22informationalModalConfirmButtonText%22:%22Ota%20k%C3%A4ytt%C3%B6%C3%B6n%20kaikki%20esikatselut%22,%22informationalModalRejectButtonText%22:%22Ei%20kiitos%22,%22buttonTextUnblockVideo%22:%22Poista%20YouTube-videon%20esto%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20esti%20t%C3%A4m%C3%A4n%20YouTube-videon,%20jotta%20Google%20ei%20voi%20seurata%20sinua%22,%22infoTextUnblockVideo%22:%22Estimme%20Googlea%20(joka%20omistaa%20YouTuben)%20seuraamasta%20sinua,%20kun%20sivua%20ladattiin.%20Jos%20poistat%20t%C3%A4m%C3%A4n%20videon%20eston,%20Google%20tiet%C3%A4%C3%A4%20toimintasi.%22,%22infoPreviewToggleText%22:%22Esikatselut%20on%20poistettu%20k%C3%A4yt%C3%B6st%C3%A4%20yksityisyyden%20lis%C3%A4%C3%A4miseksi%22,%22infoPreviewToggleEnabledText%22:%22Esikatselut%20k%C3%A4yt%C3%B6ss%C3%A4%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube-esikatselut%20k%C3%A4yt%C3%B6ss%C3%A4%20DuckDuckGossa.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3ELue%20lis%C3%A4%C3%A4%3C/a%3E%20DuckDuckGon%20upotetusta%20sosiaalisen%20median%20suojauksesta%22%7D%7D,%22fr%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22L'identification%20via%20Facebook%20leur%20permet%20de%20vous%20pister%22,%22informationalModalMessageBody%22:%22Une%20fois%20que%20vous%20%C3%AAtes%20connect%C3%A9(e),%20DuckDuckGo%20ne%20peut%20pas%20emp%C3%AAcher%20le%20contenu%20Facebook%20de%20vous%20pister%20sur%20ce%20site.%22,%22informationalModalConfirmButtonText%22:%22Connexion%22,%22informationalModalRejectButtonText%22:%22Revenir%20en%20arri%C3%A8re%22,%22loginButtonText%22:%22S'identifier%20avec%20Facebook%22,%22loginBodyText%22:%22Facebook%20piste%20votre%20activit%C3%A9%20sur%20un%20site%20lorsque%20vous%20l'utilisez%20pour%20vous%20identifier.%22,%22buttonTextUnblockContent%22:%22D%C3%A9bloquer%20le%20contenu%20Facebook%22,%22buttonTextUnblockComment%22:%22D%C3%A9bloquer%20le%20commentaire%20Facebook%22,%22buttonTextUnblockComments%22:%22D%C3%A9bloquer%20les%20commentaires%20Facebook%22,%22buttonTextUnblockPost%22:%22D%C3%A9bloquer%20la%20publication%20Facebook%22,%22buttonTextUnblockVideo%22:%22D%C3%A9bloquer%20la%20vid%C3%A9o%20Facebook%22,%22buttonTextUnblockLogin%22:%22D%C3%A9bloquer%20la%20connexion%20Facebook%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20a%20bloqu%C3%A9%20ce%20contenu%20pour%20emp%C3%AAcher%20Facebook%20de%20vous%20suivre%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20a%20bloqu%C3%A9%20ce%20commentaire%20pour%20emp%C3%AAcher%20Facebook%20de%20vous%20suivre%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20a%20bloqu%C3%A9%20ces%20commentaires%20pour%20emp%C3%AAcher%20Facebook%20de%20vous%20suivre%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20a%20bloqu%C3%A9%20cette%20publication%20pour%20emp%C3%AAcher%20Facebook%20de%20vous%20pister%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20a%20bloqu%C3%A9%20cette%20vid%C3%A9o%20pour%20emp%C3%AAcher%20Facebook%20de%20vous%20pister%22,%22infoTextUnblockContent%22:%22Nous%20avons%20emp%C3%AAch%C3%A9%20Facebook%20de%20vous%20pister%20lors%20du%20chargement%20de%20la%20page.%20Si%20vous%20d%C3%A9bloquez%20ce%20contenu,%20Facebook%20conna%C3%AEtra%20votre%20activit%C3%A9.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22En%20savoir%20plus%22,%22readAbout%22:%22En%20savoir%20plus%20sur%20cette%20protection%20de%20la%20confidentialit%C3%A9%22,%22shareFeedback%22:%22Partagez%20vos%20commentaires%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Activer%20tous%20les%20aper%C3%A7us%20YouTube%C2%A0?%22,%22informationalModalMessageBody%22:%22L'affichage%20des%20aper%C3%A7us%20permettra%20%C3%A0%20Google%20(propri%C3%A9taire%20de%20YouTube)%20de%20voir%20certaines%20informations%20de%20votre%20appareil,%20mais%20cela%20reste%20davantage%20confidentiel%20qu'en%20lisant%20la%20vid%C3%A9o.%22,%22informationalModalConfirmButtonText%22:%22Activer%20tous%20les%20aper%C3%A7us%22,%22informationalModalRejectButtonText%22:%22Non%20merci%22,%22buttonTextUnblockVideo%22:%22D%C3%A9bloquer%20la%20vid%C3%A9o%20YouTube%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20a%20bloqu%C3%A9%20cette%20vid%C3%A9o%20YouTube%20pour%20emp%C3%AAcher%20Google%20de%20vous%20pister%22,%22infoTextUnblockVideo%22:%22Nous%20avons%20emp%C3%AAch%C3%A9%20Google%20(propri%C3%A9taire%20de%20YouTube)%20de%20vous%20pister%20lors%20du%20chargement%20de%20la%20page.%20Si%20vous%20d%C3%A9bloquez%20cette%20vid%C3%A9o,%20Google%20conna%C3%AEtra%20votre%20activit%C3%A9.%22,%22infoPreviewToggleText%22:%22Aper%C3%A7us%20d%C3%A9sactiv%C3%A9s%20pour%20plus%20de%20confidentialit%C3%A9%22,%22infoPreviewToggleEnabledText%22:%22Aper%C3%A7us%20activ%C3%A9s%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22Les%20aper%C3%A7us%20YouTube%20sont%20activ%C3%A9s%20dans%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EEn%20savoir%20plus%3C/a%3E%20sur%20la%20protection%20int%C3%A9gr%C3%A9e%20DuckDuckGo%20des%20r%C3%A9seaux%20sociaux%22%7D%7D,%22hr%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Prijava%20putem%20Facebooka%20omogu%C4%87uje%20im%20da%20te%20prate%22,%22informationalModalMessageBody%22:%22Nakon%20%C5%A1to%20se%20prijavi%C5%A1,%20DuckDuckGo%20ne%20mo%C5%BEe%20blokirati%20Facebookov%20sadr%C5%BEaj%20da%20te%20prati%20na%20Facebooku.%22,%22informationalModalConfirmButtonText%22:%22Prijavljivanje%22,%22informationalModalRejectButtonText%22:%22Vrati%20se%22,%22loginButtonText%22:%22Prijavi%20se%20putem%20Facebooka%22,%22loginBodyText%22:%22Facebook%20prati%20tvoju%20aktivnost%20na%20toj%20web%20lokaciji%20kad%20je%20koristi%C5%A1%20za%20prijavu.%22,%22buttonTextUnblockContent%22:%22Deblokiraj%20sadr%C5%BEaj%20na%20Facebooku%22,%22buttonTextUnblockComment%22:%22Deblokiraj%20komentar%20na%20Facebooku%22,%22buttonTextUnblockComments%22:%22Deblokiraj%20komentare%20na%20Facebooku%22,%22buttonTextUnblockPost%22:%22Deblokiraj%20objavu%20na%20Facebooku%22,%22buttonTextUnblockVideo%22:%22Deblokiraj%20videozapis%20na%20Facebooku%22,%22buttonTextUnblockLogin%22:%22Deblokiraj%20prijavu%20na%20Facebook%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20je%20blokirao%20ovaj%20sadr%C5%BEaj%20kako%20bi%20sprije%C4%8Dio%20Facebook%20da%20te%20prati%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20je%20blokirao%20ovaj%20komentar%20kako%20bi%20sprije%C4%8Dio%20Facebook%20da%20te%20prati%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20je%20blokirao%20ove%20komentare%20kako%20bi%20sprije%C4%8Dio%20Facebook%20da%20te%20prati%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20je%20blokirao%20ovu%20objavu%20kako%20bi%20sprije%C4%8Dio%20Facebook%20da%20te%20prati%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20je%20blokirao%20ovaj%20video%20kako%20bi%20sprije%C4%8Dio%20Facebook%20da%20te%20prati%22,%22infoTextUnblockContent%22:%22Blokirali%20smo%20Facebook%20da%20te%20prati%20kad%20se%20stranica%20u%C4%8Dita.%20Ako%20deblokira%C5%A1%20ovaj%20sadr%C5%BEaj,%20Facebook%20%C4%87e%20znati%20tvoju%20aktivnost.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Saznajte%20vi%C5%A1e%22,%22readAbout%22:%22Pro%C4%8Ditaj%20vi%C5%A1e%20o%20ovoj%20za%C5%A1titi%20privatnosti%22,%22shareFeedback%22:%22Podijeli%20povratne%20informacije%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Omogu%C4%87iti%20sve%20YouTube%20pretpreglede?%22,%22informationalModalMessageBody%22:%22Prikazivanje%20pretpregleda%20omogu%C4%87it%20%C4%87e%20Googleu%20(u%20%C4%8Dijem%20je%20vlasni%C5%A1tvu%20YouTube)%20da%20vidi%20neke%20podatke%20o%20tvom%20ure%C4%91aju,%20ali%20je%20i%20dalje%20privatnija%20opcija%20od%20reprodukcije%20videozapisa.%22,%22informationalModalConfirmButtonText%22:%22Omogu%C4%87i%20sve%20pretpreglede%22,%22informationalModalRejectButtonText%22:%22Ne,%20hvala%22,%22buttonTextUnblockVideo%22:%22Deblokiraj%20YouTube%20videozapis%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20je%20blokirao%20ovaj%20YouTube%20videozapis%20kako%20bi%20sprije%C4%8Dio%20Google%20da%20te%20prati%22,%22infoTextUnblockVideo%22:%22Blokirali%20smo%20Google%20(u%20%C4%8Dijem%20je%20vlasni%C5%A1tvu%20YouTube)%20da%20te%20prati%20kad%20se%20stranica%20u%C4%8Dita.%20Ako%20deblokira%C5%A1%20ovaj%20videozapis,%20Google%20%C4%87e%20znati%20tvoju%20aktivnost.%22,%22infoPreviewToggleText%22:%22Pretpregledi%20su%20onemogu%C4%87eni%20radi%20dodatne%20privatnosti%22,%22infoPreviewToggleEnabledText%22:%22Pretpregledi%20su%20omogu%C4%87eni%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube%20pretpregledi%20omogu%C4%87eni%20su%20u%20DuckDuckGou.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3ESaznaj%20vi%C5%A1e%3C/a%3E%20o%20uklju%C4%8Denoj%20DuckDuckGo%20za%C5%A1titi%20od%20dru%C5%A1tvenih%20medija%22%7D%7D,%22hu%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22A%20Facebookkal%20val%C3%B3%20bejelentkez%C3%A9skor%20a%20Facebook%20nyomon%20k%C3%B6vethet%22,%22informationalModalMessageBody%22:%22Miut%C3%A1n%20bejelentkezel,%20a%20DuckDuckGo%20nem%20fogja%20tudni%20blokkolni%20a%20Facebook-tartalmat,%20amely%20nyomon%20k%C3%B6vet%20ezen%20az%20oldalon.%22,%22informationalModalConfirmButtonText%22:%22Bejelentkez%C3%A9s%22,%22informationalModalRejectButtonText%22:%22Visszal%C3%A9p%C3%A9s%22,%22loginButtonText%22:%22Bejelentkez%C3%A9s%20Facebookkal%22,%22loginBodyText%22:%22Ha%20a%20Facebookkal%20jelentkezel%20be,%20nyomon%20k%C3%B6vetik%20a%20webhelyen%20v%C3%A9gzett%20tev%C3%A9kenys%C3%A9gedet.%22,%22buttonTextUnblockContent%22:%22Facebook-tartalom%20felold%C3%A1sa%22,%22buttonTextUnblockComment%22:%22Facebook-hozz%C3%A1sz%C3%B3l%C3%A1s%20felold%C3%A1sa%22,%22buttonTextUnblockComments%22:%22Facebook-hozz%C3%A1sz%C3%B3l%C3%A1sok%20felold%C3%A1sa%22,%22buttonTextUnblockPost%22:%22Facebook-bejegyz%C3%A9s%20felold%C3%A1sa%22,%22buttonTextUnblockVideo%22:%22Facebook-vide%C3%B3%20felold%C3%A1sa%22,%22buttonTextUnblockLogin%22:%22Facebook-bejelentkez%C3%A9s%20felold%C3%A1sa%22,%22infoTitleUnblockContent%22:%22A%20DuckDuckGo%20blokkolta%20ezt%20a%20tartalmat,%20hogy%20megakad%C3%A1lyozza%20a%20Facebookot%20a%20nyomon%20k%C3%B6vet%C3%A9sedben%22,%22infoTitleUnblockComment%22:%22A%20DuckDuckGo%20blokkolta%20ezt%20a%20hozz%C3%A1sz%C3%B3l%C3%A1st,%20hogy%20megakad%C3%A1lyozza%20a%20Facebookot%20a%20nyomon%20k%C3%B6vet%C3%A9sedben%22,%22infoTitleUnblockComments%22:%22A%20DuckDuckGo%20blokkolta%20ezeket%20a%20hozz%C3%A1sz%C3%B3l%C3%A1sokat,%20hogy%20megakad%C3%A1lyozza%20a%20Facebookot%20a%20nyomon%20k%C3%B6vet%C3%A9sedben%22,%22infoTitleUnblockPost%22:%22A%20DuckDuckGo%20blokkolta%20ezt%20a%20bejegyz%C3%A9st,%20hogy%20megakad%C3%A1lyozza%20a%20Facebookot%20a%20nyomon%20k%C3%B6vet%C3%A9sedben%22,%22infoTitleUnblockVideo%22:%22A%20DuckDuckGo%20blokkolta%20ezt%20a%20vide%C3%B3t,%20hogy%20megakad%C3%A1lyozza%20a%20Facebookot%20a%20nyomon%20k%C3%B6vet%C3%A9sedben%22,%22infoTextUnblockContent%22:%22Az%20oldal%20bet%C3%B6lt%C3%A9sekor%20blokkoltuk%20a%20Facebookot%20a%20nyomon%20k%C3%B6vet%C3%A9sedben.%20Ha%20feloldod%20ezt%20a%20tartalmat,%20a%20Facebook%20tudni%20fogja,%20hogy%20milyen%20tev%C3%A9kenys%C3%A9get%20v%C3%A9gzel.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Tov%C3%A1bbi%20r%C3%A9szletek%22,%22readAbout%22:%22Tudj%20meg%20t%C3%B6bbet%20err%C5%91l%20az%20adatv%C3%A9delemr%C5%91l%22,%22shareFeedback%22:%22Visszajelz%C3%A9s%20megoszt%C3%A1sa%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Enged%C3%A9lyezed%20minden%20YouTube-vide%C3%B3%20el%C5%91n%C3%A9zet%C3%A9t?%22,%22informationalModalMessageBody%22:%22Az%20el%C5%91n%C3%A9zetek%20megjelen%C3%ADt%C3%A9s%C3%A9vel%20a%20Google%20(a%20YouTube%20tulajdonosa)%20l%C3%A1thatja%20a%20k%C3%A9sz%C3%BCl%C3%A9k%20n%C3%A9h%C3%A1ny%20adat%C3%A1t,%20de%20ez%20adatv%C3%A9delmi%20szempontb%C3%B3l%20m%C3%A9g%20mindig%20el%C5%91ny%C3%B6sebb,%20mint%20a%20vide%C3%B3%20lej%C3%A1tsz%C3%A1sa.%22,%22informationalModalConfirmButtonText%22:%22Minden%20el%C5%91n%C3%A9zet%20enged%C3%A9lyez%C3%A9se%22,%22informationalModalRejectButtonText%22:%22Nem,%20k%C3%B6sz%C3%B6n%C3%B6m%22,%22buttonTextUnblockVideo%22:%22YouTube-vide%C3%B3%20felold%C3%A1sa%22,%22infoTitleUnblockVideo%22:%22A%20DuckDuckGo%20blokkolta%20a%20YouTube-vide%C3%B3t,%20hogy%20a%20Google%20ne%20k%C3%B6vethessen%20nyomon%22,%22infoTextUnblockVideo%22:%22Blokkoltuk,%20hogy%20a%20Google%20(a%20YouTube%20tulajdonosa)%20nyomon%20k%C3%B6vethessen%20az%20oldal%20bet%C3%B6lt%C3%A9sekor.%20Ha%20feloldod%20a%20vide%C3%B3%20blokkol%C3%A1s%C3%A1t,%20a%20Google%20tudni%20fogja,%20hogy%20milyen%20tev%C3%A9kenys%C3%A9get%20v%C3%A9gzel.%22,%22infoPreviewToggleText%22:%22Az%20el%C5%91n%C3%A9zetek%20a%20fokozott%20adatv%C3%A9delem%20%C3%A9rdek%C3%A9ben%20letiltva%22,%22infoPreviewToggleEnabledText%22:%22Az%20el%C5%91n%C3%A9zetek%20enged%C3%A9lyezve%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube-el%C5%91n%C3%A9zetek%20enged%C3%A9lyezve%20a%20DuckDuckGo-ban.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3ETov%C3%A1bbi%20tudnival%C3%B3k%3C/a%3E%20a%20DuckDuckGo%20be%C3%A1gyazott%20k%C3%B6z%C3%B6ss%C3%A9gi%20m%C3%A9dia%20elleni%20v%C3%A9delm%C3%A9r%C5%91l%22%7D%7D,%22it%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22L'accesso%20con%20Facebook%20consente%20di%20tracciarti%22,%22informationalModalMessageBody%22:%22Dopo%20aver%20effettuato%20l'accesso,%20DuckDuckGo%20non%20pu%C3%B2%20bloccare%20il%20tracciamento%20dei%20contenuti%20di%20Facebook%20su%20questo%20sito.%22,%22informationalModalConfirmButtonText%22:%22Accedi%22,%22informationalModalRejectButtonText%22:%22Torna%20indietro%22,%22loginButtonText%22:%22Accedi%20con%20Facebook%22,%22loginBodyText%22:%22Facebook%20tiene%20traccia%20della%20tua%20attivit%C3%A0%20su%20un%20sito%20quando%20lo%20usi%20per%20accedere.%22,%22buttonTextUnblockContent%22:%22Sblocca%20i%20contenuti%20di%20Facebook%22,%22buttonTextUnblockComment%22:%22Sblocca%20il%20commento%20di%20Facebook%22,%22buttonTextUnblockComments%22:%22Sblocca%20i%20commenti%20di%20Facebook%22,%22buttonTextUnblockPost%22:%22Sblocca%20post%20di%20Facebook%22,%22buttonTextUnblockVideo%22:%22Sblocca%20video%20di%20Facebook%22,%22buttonTextUnblockLogin%22:%22Sblocca%20l'accesso%20a%20Facebook%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20ha%20bloccato%20questo%20contenuto%20per%20impedire%20a%20Facebook%20di%20tracciarti%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20ha%20bloccato%20questo%20commento%20per%20impedire%20a%20Facebook%20di%20tracciarti%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20ha%20bloccato%20questi%20commenti%20per%20impedire%20a%20Facebook%20di%20tracciarti%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20ha%20bloccato%20questo%20post%20per%20impedire%20a%20Facebook%20di%20tracciarti%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20ha%20bloccato%20questo%20video%20per%20impedire%20a%20Facebook%20di%20tracciarti%22,%22infoTextUnblockContent%22:%22Abbiamo%20impedito%20a%20Facebook%20di%20tracciarti%20al%20caricamento%20della%20pagina.%20Se%20sblocchi%20questo%20contenuto,%20Facebook%20conoscer%C3%A0%20la%20tua%20attivit%C3%A0.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Ulteriori%20informazioni%22,%22readAbout%22:%22Leggi%20di%20pi%C3%B9%20su%20questa%20protezione%20della%20privacy%22,%22shareFeedback%22:%22Condividi%20feedback%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Abilitare%20tutte%20le%20anteprime%20di%20YouTube?%22,%22informationalModalMessageBody%22:%22La%20visualizzazione%20delle%20anteprime%20consentir%C3%A0%20a%20Google%20(che%20possiede%20YouTube)%20di%20vedere%20alcune%20delle%20informazioni%20del%20tuo%20dispositivo,%20ma%20%C3%A8%20comunque%20pi%C3%B9%20privato%20rispetto%20alla%20riproduzione%20del%20video.%22,%22informationalModalConfirmButtonText%22:%22Abilita%20tutte%20le%20anteprime%22,%22informationalModalRejectButtonText%22:%22No,%20grazie%22,%22buttonTextUnblockVideo%22:%22Sblocca%20video%20YouTube%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20ha%20bloccato%20questo%20video%20di%20YouTube%20per%20impedire%20a%20Google%20di%20tracciarti%22,%22infoTextUnblockVideo%22:%22Abbiamo%20impedito%20a%20Google%20(che%20possiede%20YouTube)%20di%20tracciarti%20quando%20la%20pagina%20%C3%A8%20stata%20caricata.%20Se%20sblocchi%20questo%20video,%20Google%20conoscer%C3%A0%20la%20tua%20attivit%C3%A0.%22,%22infoPreviewToggleText%22:%22Anteprime%20disabilitate%20per%20una%20maggiore%20privacy%22,%22infoPreviewToggleEnabledText%22:%22Anteprime%20abilitate%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22Anteprime%20YouTube%20abilitate%20in%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EScopri%20di%20pi%C3%B9%3C/a%3E%20sulla%20protezione%20dai%20social%20media%20integrata%20di%20DuckDuckGo%22%7D%7D,%22lt%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Prisijung%C4%99%20prie%20%E2%80%9EFacebook%E2%80%9C%20galite%20b%C5%ABti%20sekami%22,%22informationalModalMessageBody%22:%22Kai%20esate%20prisijung%C4%99,%20%E2%80%9EDuckDuckGo%E2%80%9C%20negali%20u%C5%BEblokuoti%20%E2%80%9EFacebook%E2%80%9C%20turinio,%20tod%C4%97l%20esate%20sekami%20%C5%A1ioje%20svetain%C4%97je.%22,%22informationalModalConfirmButtonText%22:%22Prisijungti%22,%22informationalModalRejectButtonText%22:%22Gr%C4%AF%C5%BEti%20atgal%22,%22loginButtonText%22:%22Prisijunkite%20su%20%E2%80%9EFacebook%E2%80%9C%22,%22loginBodyText%22:%22%E2%80%9EFacebook%E2%80%9C%20seka%20j%C5%ABs%C5%B3%20veikl%C4%85%20svetain%C4%97je,%20kai%20prisijungiate%20su%20%C5%A1ia%20svetaine.%22,%22buttonTextUnblockContent%22:%22Atblokuoti%20%E2%80%9EFacebook%E2%80%9C%20turin%C4%AF%22,%22buttonTextUnblockComment%22:%22Atblokuoti%20%E2%80%9EFacebook%E2%80%9C%20komentar%C4%85%22,%22buttonTextUnblockComments%22:%22Atblokuoti%20%E2%80%9EFacebook%E2%80%9C%20komentarus%22,%22buttonTextUnblockPost%22:%22Atblokuoti%20%E2%80%9EFacebook%E2%80%9C%20%C4%AFra%C5%A1%C4%85%22,%22buttonTextUnblockVideo%22:%22Atblokuoti%20%E2%80%9EFacebook%E2%80%9C%20vaizdo%20%C4%AFra%C5%A1%C4%85%22,%22buttonTextUnblockLogin%22:%22Atblokuoti%20%E2%80%9EFacebook%E2%80%9C%20prisijungim%C4%85%22,%22infoTitleUnblockContent%22:%22%E2%80%9EDuckDuckGo%E2%80%9C%20u%C5%BEblokavo%20%C5%A1%C4%AF%20turin%C4%AF,%20kad%20%E2%80%9EFacebook%E2%80%9C%20negal%C4%97t%C5%B3%20j%C5%ABs%C5%B3%20sekti%22,%22infoTitleUnblockComment%22:%22%E2%80%9EDuckDuckGo%E2%80%9C%20u%C5%BEblokavo%20%C5%A1%C4%AF%20komentar%C4%85,%20kad%20%E2%80%9EFacebook%E2%80%9C%20negal%C4%97t%C5%B3%20j%C5%ABs%C5%B3%20sekti%22,%22infoTitleUnblockComments%22:%22%E2%80%9EDuckDuckGo%E2%80%9C%20u%C5%BEblokavo%20%C5%A1iuos%20komentarus,%20kad%20%E2%80%9EFacebook%E2%80%9C%20negal%C4%97t%C5%B3%20j%C5%ABs%C5%B3%20sekti%22,%22infoTitleUnblockPost%22:%22%E2%80%9EDuckDuckGo%E2%80%9C%20u%C5%BEblokavo%20%C5%A1%C4%AF%20%C4%AFra%C5%A1%C4%85,%20kad%20%E2%80%9EFacebook%E2%80%9C%20negal%C4%97t%C5%B3%20j%C5%ABs%C5%B3%20sekti%22,%22infoTitleUnblockVideo%22:%22%E2%80%9EDuckDuckGo%E2%80%9C%20u%C5%BEblokavo%20%C5%A1%C4%AF%20vaizdo%20%C4%AFra%C5%A1%C4%85,%20kad%20%E2%80%9EFacebook%E2%80%9C%20negal%C4%97t%C5%B3%20j%C5%ABs%C5%B3%20sekti%22,%22infoTextUnblockContent%22:%22U%C5%BEblokavome%20%E2%80%9EFacebook%E2%80%9C,%20kad%20negal%C4%97t%C5%B3%20j%C5%ABs%C5%B3%20sekti,%20kai%20puslapis%20buvo%20%C4%AFkeltas.%20Jei%20atblokuosite%20%C5%A1%C4%AF%20turin%C4%AF,%20%E2%80%9EFacebook%E2%80%9C%20%C5%BEinos%20apie%20j%C5%ABs%C5%B3%20veikl%C4%85.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Su%C5%BEinoti%20daugiau%22,%22readAbout%22:%22Skaitykite%20apie%20%C5%A1i%C4%85%20privatumo%20apsaug%C4%85%22,%22shareFeedback%22:%22Bendrinti%20atsiliepim%C4%85%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22%C4%AEjungti%20visas%20%E2%80%9EYouTube%E2%80%9C%20per%C5%BEi%C5%ABras?%22,%22informationalModalMessageBody%22:%22Per%C5%BEi%C5%ABr%C5%B3%20rodymas%20leis%20%E2%80%9EGoogle%E2%80%9C%20(kuriai%20priklauso%20%E2%80%9EYouTube%E2%80%9C)%20matyti%20tam%20tikr%C4%85%20j%C5%ABs%C5%B3%20%C4%AFrenginio%20informacij%C4%85,%20ta%C4%8Diau%20ji%20vis%20tiek%20bus%20privatesn%C4%97%20nei%20leid%C5%BEiant%20vaizdo%20%C4%AFra%C5%A1%C4%85.%22,%22informationalModalConfirmButtonText%22:%22%C4%AEjungti%20visas%20per%C5%BEi%C5%ABras%22,%22informationalModalRejectButtonText%22:%22Ne,%20d%C4%97koju%22,%22buttonTextUnblockVideo%22:%22Atblokuoti%20%E2%80%9EYouTube%E2%80%9C%20vaizdo%20%C4%AFra%C5%A1%C4%85%22,%22infoTitleUnblockVideo%22:%22%E2%80%9EDuckDuckGo%E2%80%9C%20u%C5%BEblokavo%20%C5%A1%C4%AF%20%E2%80%9EYouTube%E2%80%9C%20vaizdo%20%C4%AFra%C5%A1%C4%85,%20kad%20%E2%80%9EGoogle%E2%80%9C%20negal%C4%97t%C5%B3%20j%C5%ABs%C5%B3%20sekti%22,%22infoTextUnblockVideo%22:%22U%C5%BEblokavome%20%E2%80%9EGoogle%E2%80%9C%20(kuriai%20priklauso%20%E2%80%9EYouTube%E2%80%9C)%20galimyb%C4%99%20sekti%20jus,%20kai%20puslapis%20buvo%20%C4%AFkeltas.%20Jei%20atblokuosite%20%C5%A1%C4%AF%20vaizdo%20%C4%AFra%C5%A1%C4%85,%20%E2%80%9EGoogle%E2%80%9C%20su%C5%BEinos%20apie%20j%C5%ABs%C5%B3%20veikl%C4%85.%22,%22infoPreviewToggleText%22:%22Per%C5%BEi%C5%ABros%20i%C5%A1jungtos%20d%C4%97l%20papildomo%20privatumo%22,%22infoPreviewToggleEnabledText%22:%22Per%C5%BEi%C5%ABros%20%C4%AFjungtos%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22%E2%80%9EYouTube%E2%80%9C%20per%C5%BEi%C5%ABros%20%C4%AFjungtos%20%E2%80%9EDuckDuckGo%E2%80%9C.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3ESu%C5%BEinokite%20daugiau%3C/a%3E%20apie%20%E2%80%9EDuckDuckGo%E2%80%9C%20%C4%AFd%C4%97t%C4%85j%C4%85%20socialin%C4%97s%20%C5%BEiniasklaidos%20apsaug%C4%85%22%7D%7D,%22lv%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Ja%20pieteiksies%20ar%20Facebook,%20vi%C5%86i%20var%C4%93s%20tevi%20izsekot%22,%22informationalModalMessageBody%22:%22Kad%20tu%20piesakies,%20DuckDuckGo%20nevar%20nov%C4%93rst,%20ka%20Facebook%20saturs%20tevi%20izseko%20%C5%A1aj%C4%81%20vietn%C4%93.%22,%22informationalModalConfirmButtonText%22:%22Pieteikties%22,%22informationalModalRejectButtonText%22:%22Atgriezties%22,%22loginButtonText%22:%22Pieteikties%20ar%20Facebook%22,%22loginBodyText%22:%22Facebook%20izseko%20tavas%20aktivit%C4%81tes%20vietn%C4%93,%20kad%20esi%20pieteicies%20ar%20Facebook.%22,%22buttonTextUnblockContent%22:%22Atblo%C4%B7%C4%93t%20Facebook%20saturu%22,%22buttonTextUnblockComment%22:%22Atblo%C4%B7%C4%93t%20Facebook%20koment%C4%81ru%22,%22buttonTextUnblockComments%22:%22Atblo%C4%B7%C4%93t%20Facebook%20koment%C4%81rus%22,%22buttonTextUnblockPost%22:%22Atblo%C4%B7%C4%93t%20Facebook%20zi%C5%86u%22,%22buttonTextUnblockVideo%22:%22Atblo%C4%B7%C4%93t%20Facebook%20video%22,%22buttonTextUnblockLogin%22:%22Atblo%C4%B7%C4%93t%20Facebook%20pieteik%C5%A1anos%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20blo%C4%B7%C4%93ja%20%C5%A1o%20saturu,%20lai%20ne%C4%BCautu%20Facebook%20tevi%20izsekot%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20blo%C4%B7%C4%93ja%20%C5%A1o%20koment%C4%81ru,%20lai%20ne%C4%BCautu%20Facebook%20tevi%20izsekot%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20blo%C4%B7%C4%93ja%20%C5%A1os%20koment%C4%81rus,%20lai%20ne%C4%BCautu%20Facebook%20tevi%20izsekot%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20blo%C4%B7%C4%93ja%20%C5%A1o%20zi%C5%86u,%20lai%20ne%C4%BCautu%20Facebook%20tevi%20izsekot%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blo%C4%B7%C4%93ja%20%C5%A1o%20videoklipu,%20lai%20ne%C4%BCautu%20Facebook%20tevi%20izsekot%22,%22infoTextUnblockContent%22:%22M%C4%93s%20blo%C4%B7%C4%93j%C4%81m%20Facebook%20iesp%C4%93ju%20tevi%20izsekot,%20iel%C4%81d%C4%93jot%20lapu.%20Ja%20atblo%C4%B7%C4%93si%20%C5%A1o%20saturu,%20Facebook%20redz%C4%93s,%20ko%20tu%20dari.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Uzzin%C4%81t%20vair%C4%81k%22,%22readAbout%22:%22Lasi%20par%20%C5%A1o%20priv%C4%81tuma%20aizsardz%C4%ABbu%22,%22shareFeedback%22:%22Kop%C4%ABgot%20atsauksmi%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Vai%20iesp%C4%93jot%20visus%20YouTube%20priek%C5%A1skat%C4%ABjumus?%22,%22informationalModalMessageBody%22:%22Priek%C5%A1skat%C4%ABjumu%20r%C4%81d%C4%AB%C5%A1ana%20%C4%BCaus%20Google%20(kam%20pieder%20YouTube)%20redz%C4%93t%20da%C4%BCu%20tavas%20ier%C4%ABces%20inform%C4%81cijas,%20ta%C4%8Du%20tas%20t%C4%81pat%20ir%20priv%C4%81t%C4%81k%20par%20videoklipa%20atska%C5%86o%C5%A1anu.%22,%22informationalModalConfirmButtonText%22:%22Iesp%C4%93jot%20visus%20priek%C5%A1skat%C4%ABjumus%22,%22informationalModalRejectButtonText%22:%22N%C4%93,%20paldies%22,%22buttonTextUnblockVideo%22:%22Atblo%C4%B7%C4%93t%20YouTube%20videoklipu%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blo%C4%B7%C4%93ja%20%C5%A1o%20YouTube%20videoklipu,%20lai%20ne%C4%BCautu%20Google%20tevi%20izsekot%22,%22infoTextUnblockVideo%22:%22M%C4%93s%20ne%C4%BC%C4%81v%C4%81m%20Google%20(kam%20pieder%20YouTube)%20tevi%20izsekot,%20kad%20lapa%20tika%20iel%C4%81d%C4%93ta.%20Ja%20atblo%C4%B7%C4%93si%20%C5%A1o%20videoklipu,%20Google%20zin%C4%81s,%20ko%20tu%20dari.%22,%22infoPreviewToggleText%22:%22Priek%C5%A1skat%C4%ABjumi%20ir%20atsp%C4%93joti,%20lai%20nodro%C5%A1in%C4%81tu%20papildu%20konfidencialit%C4%81ti%22,%22infoPreviewToggleEnabledText%22:%22Priek%C5%A1skat%C4%ABjumi%20ir%20iesp%C4%93joti%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22DuckDuckGo%20iesp%C4%93joti%20YouTube%20priek%C5%A1skat%C4%ABjumi.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EUzzini%20vair%C4%81k%3C/a%3E%20par%20DuckDuckGo%20iegulto%20soci%C4%81lo%20mediju%20aizsardz%C4%ABbu%22%7D%7D,%22nb%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22N%C3%A5r%20du%20logger%20p%C3%A5%20med%20Facebook,%20kan%20de%20spore%20deg%22,%22informationalModalMessageBody%22:%22N%C3%A5r%20du%20er%20logget%20p%C3%A5,%20kan%20ikke%20DuckDuckGo%20hindre%20Facebook-innhold%20i%20%C3%A5%20spore%20deg%20p%C3%A5%20dette%20nettstedet.%22,%22informationalModalConfirmButtonText%22:%22Logg%20inn%22,%22informationalModalRejectButtonText%22:%22G%C3%A5%20tilbake%22,%22loginButtonText%22:%22Logg%20p%C3%A5%20med%20Facebook%22,%22loginBodyText%22:%22N%C3%A5r%20du%20logger%20p%C3%A5%20med%20Facebook,%20sporer%20de%20aktiviteten%20din%20p%C3%A5%20nettstedet.%22,%22buttonTextUnblockContent%22:%22Fjern%20blokkering%20av%20Facebook-innhold%22,%22buttonTextUnblockComment%22:%22Fjern%20blokkering%20av%20Facebook-kommentar%22,%22buttonTextUnblockComments%22:%22Fjern%20blokkering%20av%20Facebook-kommentarer%22,%22buttonTextUnblockPost%22:%22Fjern%20blokkering%20av%20Facebook-innlegg%22,%22buttonTextUnblockVideo%22:%22Fjern%20blokkering%20av%20Facebook-video%22,%22buttonTextUnblockLogin%22:%22Fjern%20blokkering%20av%20Facebook-p%C3%A5logging%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20blokkerte%20dette%20innholdet%20for%20%C3%A5%20hindre%20Facebook%20i%20%C3%A5%20spore%20deg%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20blokkerte%20denne%20kommentaren%20for%20%C3%A5%20hindre%20Facebook%20i%20%C3%A5%20spore%20deg%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20blokkerte%20disse%20kommentarene%20for%20%C3%A5%20hindre%20Facebook%20i%20%C3%A5%20spore%20deg%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20blokkerte%20dette%20innlegget%20for%20%C3%A5%20hindre%20Facebook%20i%20%C3%A5%20spore%20deg%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blokkerte%20denne%20videoen%20for%20%C3%A5%20hindre%20Facebook%20i%20%C3%A5%20spore%20deg%22,%22infoTextUnblockContent%22:%22Vi%20hindret%20Facebook%20i%20%C3%A5%20spore%20deg%20da%20siden%20ble%20lastet.%20Hvis%20du%20opphever%20blokkeringen%20av%20dette%20innholdet,%20f%C3%A5r%20Facebook%20vite%20om%20aktiviteten%20din.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Finn%20ut%20mer%22,%22readAbout%22:%22Les%20om%20denne%20personvernfunksjonen%22,%22shareFeedback%22:%22Del%20tilbakemelding%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Vil%20du%20aktivere%20alle%20YouTube-forh%C3%A5ndsvisninger?%22,%22informationalModalMessageBody%22:%22Forh%C3%A5ndsvisninger%20gj%C3%B8r%20det%20mulig%20for%20Google%20(som%20eier%20YouTube)%20%C3%A5%20se%20enkelte%20opplysninger%20om%20enheten%20din,%20men%20det%20er%20likevel%20mer%20privat%20enn%20%C3%A5%20spille%20av%20videoen.%22,%22informationalModalConfirmButtonText%22:%22Aktiver%20alle%20forh%C3%A5ndsvisninger%22,%22informationalModalRejectButtonText%22:%22Nei%20takk%22,%22buttonTextUnblockVideo%22:%22Fjern%20blokkering%20av%20YouTube-video%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blokkerte%20denne%20YouTube-videoen%20for%20%C3%A5%20hindre%20Google%20i%20%C3%A5%20spore%20deg%22,%22infoTextUnblockVideo%22:%22Vi%20blokkerte%20Google%20(som%20eier%20YouTube)%20mot%20%C3%A5%20spore%20deg%20da%20siden%20ble%20lastet.%20Hvis%20du%20opphever%20blokkeringen%20av%20denne%20videoen,%20f%C3%A5r%20Google%20vite%20om%20aktiviteten%20din.%22,%22infoPreviewToggleText%22:%22Forh%C3%A5ndsvisninger%20er%20deaktivert%20for%20%C3%A5%20gi%20deg%20ekstra%20personvern%22,%22infoPreviewToggleEnabledText%22:%22Forh%C3%A5ndsvisninger%20er%20aktivert%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube-forh%C3%A5ndsvisninger%20er%20aktivert%20i%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EFinn%20ut%20mer%3C/a%3E%20om%20DuckDuckGos%20innebygde%20beskyttelse%20for%20sosiale%20medier%22%7D%7D,%22nl%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Als%20je%20inlogt%20met%20Facebook,%20kunnen%20zij%20je%20volgen%22,%22informationalModalMessageBody%22:%22Als%20je%20eenmaal%20bent%20ingelogd,%20kan%20DuckDuckGo%20niet%20voorkomen%20dat%20Facebook%20je%20op%20deze%20site%20volgt.%22,%22informationalModalConfirmButtonText%22:%22Inloggen%22,%22informationalModalRejectButtonText%22:%22Terug%22,%22loginButtonText%22:%22Inloggen%20met%20Facebook%22,%22loginBodyText%22:%22Facebook%20volgt%20je%20activiteit%20op%20een%20site%20als%20je%20Facebook%20gebruikt%20om%20in%20te%20loggen.%22,%22buttonTextUnblockContent%22:%22Facebook-inhoud%20deblokkeren%22,%22buttonTextUnblockComment%22:%22Facebook-opmerkingen%20deblokkeren%22,%22buttonTextUnblockComments%22:%22Facebook-opmerkingen%20deblokkeren%22,%22buttonTextUnblockPost%22:%22Facebook-bericht%20deblokkeren%22,%22buttonTextUnblockVideo%22:%22Facebook-video%20deblokkeren%22,%22buttonTextUnblockLogin%22:%22Facebook-aanmelding%20deblokkeren%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20heeft%20deze%20inhoud%20geblokkeerd%20om%20te%20voorkomen%20dat%20Facebook%20je%20kan%20volgen%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20heeft%20deze%20opmerking%20geblokkeerd%20om%20te%20voorkomen%20dat%20Facebook%20je%20kan%20volgen%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20heeft%20deze%20opmerkingen%20geblokkeerd%20om%20te%20voorkomen%20dat%20Facebook%20je%20kan%20volgen%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20heeft%20dit%20bericht%20geblokkeerd%20om%20te%20voorkomen%20dat%20Facebook%20je%20kan%20volgen%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20heeft%20deze%20video%20geblokkeerd%20om%20te%20voorkomen%20dat%20Facebook%20je%20kan%20volgen%22,%22infoTextUnblockContent%22:%22We%20hebben%20voorkomen%20dat%20Facebook%20je%20volgde%20toen%20de%20pagina%20werd%20geladen.%20Als%20je%20deze%20inhoud%20deblokkeert,%20kan%20Facebook%20je%20activiteit%20zien.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Meer%20informatie%22,%22readAbout%22:%22Lees%20meer%20over%20deze%20privacybescherming%22,%22shareFeedback%22:%22Feedback%20delen%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Alle%20YouTube-voorbeelden%20inschakelen?%22,%22informationalModalMessageBody%22:%22Bij%20het%20tonen%20van%20voorbeelden%20kan%20Google%20(eigenaar%20van%20YouTube)%20een%20deel%20van%20de%20informatie%20over%20je%20apparaat%20zien,%20maar%20blijft%20je%20privacy%20beter%20beschermd%20dan%20als%20je%20de%20video%20zou%20afspelen.%22,%22informationalModalConfirmButtonText%22:%22Alle%20voorbeelden%20inschakelen%22,%22informationalModalRejectButtonText%22:%22Nee,%20bedankt%22,%22buttonTextUnblockVideo%22:%22YouTube-video%20deblokkeren%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20heeft%20deze%20YouTube-video%20geblokkeerd%20om%20te%20voorkomen%20dat%20Google%20je%20kan%20volgen%22,%22infoTextUnblockVideo%22:%22We%20hebben%20voorkomen%20dat%20Google%20(eigenaar%20van%20YouTube)%20je%20volgde%20toen%20de%20pagina%20werd%20geladen.%20Als%20je%20deze%20video%20deblokkeert,%20kan%20Google%20je%20activiteit%20zien.%22,%22infoPreviewToggleText%22:%22Voorbeelden%20uitgeschakeld%20voor%20extra%20privacy%22,%22infoPreviewToggleEnabledText%22:%22Voorbeelden%20ingeschakeld%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube-voorbeelden%20ingeschakeld%20in%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EMeer%20informatie%3C/a%3E%20over%20DuckDuckGo's%20bescherming%20tegen%20ingesloten%20social%20media%22%7D%7D,%22pl%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Je%C5%9Bli%20zalogujesz%20si%C4%99%20za%20po%C5%9Brednictwem%20Facebooka,%20b%C4%99dzie%20on%20m%C3%B3g%C5%82%20%C5%9Bledzi%C4%87%20Twoj%C4%85%20aktywno%C5%9B%C4%87%22,%22informationalModalMessageBody%22:%22Po%20zalogowaniu%20si%C4%99%20DuckDuckGo%20nie%20mo%C5%BCe%20zablokowa%C4%87%20mo%C5%BCliwo%C5%9Bci%20%C5%9Bledzenia%20Ci%C4%99%20przez%20Facebooka%20na%20tej%20stronie.%22,%22informationalModalConfirmButtonText%22:%22Zaloguj%20si%C4%99%22,%22informationalModalRejectButtonText%22:%22Wr%C3%B3%C4%87%22,%22loginButtonText%22:%22Zaloguj%20si%C4%99%20za%20po%C5%9Brednictwem%20Facebooka%22,%22loginBodyText%22:%22Facebook%20%C5%9Bledzi%20Twoj%C4%85%20aktywno%C5%9B%C4%87%20na%20stronie,%20gdy%20logujesz%20si%C4%99%20za%20jego%20po%C5%9Brednictwem.%22,%22buttonTextUnblockContent%22:%22Odblokuj%20tre%C5%9B%C4%87%20na%20Facebooku%22,%22buttonTextUnblockComment%22:%22Odblokuj%20komentarz%20na%20Facebooku%22,%22buttonTextUnblockComments%22:%22Odblokuj%20komentarze%20na%20Facebooku%22,%22buttonTextUnblockPost%22:%22Odblokuj%20post%20na%20Facebooku%22,%22buttonTextUnblockVideo%22:%22Odblokuj%20wideo%20na%20Facebooku%22,%22buttonTextUnblockLogin%22:%22Odblokuj%20logowanie%20na%20Facebooku%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20zablokowa%C5%82%20t%C4%99%20tre%C5%9B%C4%87,%20aby%20Facebook%20nie%20m%C3%B3g%C5%82%20Ci%C4%99%20%C5%9Bledzi%C4%87%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20zablokowa%C5%82%20ten%20komentarz,%20aby%20Facebook%20nie%20m%C3%B3g%C5%82%20Ci%C4%99%20%C5%9Bledzi%C4%87%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20zablokowa%C5%82%20te%20komentarze,%20aby%20Facebook%20nie%20m%C3%B3g%C5%82%20Ci%C4%99%20%C5%9Bledzi%C4%87%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20zablokowa%C5%82%20ten%20post,%20aby%20Facebook%20nie%20m%C3%B3g%C5%82%20Ci%C4%99%20%C5%9Bledzi%C4%87%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20zablokowa%C5%82%20t%C4%99%20tre%C5%9B%C4%87%20wideo,%20aby%20Facebook%20nie%20m%C3%B3g%C5%82%20Ci%C4%99%20%C5%9Bledzi%C4%87.%22,%22infoTextUnblockContent%22:%22Zablokowali%C5%9Bmy%20Facebookowi%20mo%C5%BCliwo%C5%9B%C4%87%20%C5%9Bledzenia%20Ci%C4%99%20podczas%20%C5%82adowania%20strony.%20Je%C5%9Bli%20odblokujesz%20t%C4%99%20tre%C5%9B%C4%87,%20Facebook%20uzyska%20informacje%20o%20Twojej%20aktywno%C5%9Bci.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Dowiedz%20si%C4%99%20wi%C4%99cej%22,%22readAbout%22:%22Dowiedz%20si%C4%99%20wi%C4%99cej%20o%20tej%20ochronie%20prywatno%C5%9Bci%22,%22shareFeedback%22:%22Podziel%20si%C4%99%20opini%C4%85%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22W%C5%82%C4%85czy%C4%87%20wszystkie%20podgl%C4%85dy%20w%20YouTube?%22,%22informationalModalMessageBody%22:%22Wy%C5%9Bwietlanie%20podgl%C4%85du%20pozwala%20Google%20(kt%C3%B3ry%20jest%20w%C5%82a%C5%9Bcicielem%20YouTube)%20zobaczy%C4%87%20niekt%C3%B3re%20informacje%20o%20Twoim%20urz%C4%85dzeniu,%20ale%20nadal%20jest%20to%20bardziej%20prywatne%20ni%C5%BC%20odtwarzanie%20filmu.%22,%22informationalModalConfirmButtonText%22:%22W%C5%82%C4%85cz%20wszystkie%20podgl%C4%85dy%22,%22informationalModalRejectButtonText%22:%22Nie,%20dzi%C4%99kuj%C4%99%22,%22buttonTextUnblockVideo%22:%22Odblokuj%20wideo%20w%20YouTube%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20zablokowa%C5%82%20ten%20film%20w%20YouTube,%20aby%20uniemo%C5%BCliwi%C4%87%20Google%20%C5%9Bledzenie%20Twojej%20aktywno%C5%9Bci%22,%22infoTextUnblockVideo%22:%22Zablokowali%C5%9Bmy%20mo%C5%BCliwo%C5%9B%C4%87%20%C5%9Bledzenia%20Ci%C4%99%20przez%20Google%20(w%C5%82a%C5%9Bciciela%20YouTube)%20podczas%20%C5%82adowania%20strony.%20Je%C5%9Bli%20odblokujesz%20ten%20film,%20Google%20zobaczy%20Twoj%C4%85%20aktywno%C5%9B%C4%87.%22,%22infoPreviewToggleText%22:%22Podgl%C4%85dy%20zosta%C5%82y%20wy%C5%82%C4%85czone,%20aby%20zapewni%C4%87%20wi%C4%99ksz%C4%85%20ptywatno%C5%9B%C4%87%22,%22infoPreviewToggleEnabledText%22:%22Podgl%C4%85dy%20w%C5%82%C4%85czone%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22Podgl%C4%85dy%20YouTube%20w%C5%82%C4%85czone%20w%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EDowiedz%20si%C4%99%20wi%C4%99cej%3C/a%3E%20o%20zabezpieczeniu%20osadzonych%20tre%C5%9Bci%20spo%C5%82eczno%C5%9Bciowych%20DuckDuckGo%22%7D%7D,%22pt%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Iniciar%20sess%C3%A3o%20no%20Facebook%20permite%20que%20este%20te%20rastreie%22,%22informationalModalMessageBody%22:%22Depois%20de%20iniciares%20sess%C3%A3o,%20o%20DuckDuckGo%20n%C3%A3o%20poder%C3%A1%20bloquear%20o%20rastreio%20por%20parte%20do%20conte%C3%BAdo%20do%20Facebook%20neste%20site.%22,%22informationalModalConfirmButtonText%22:%22Iniciar%20sess%C3%A3o%22,%22informationalModalRejectButtonText%22:%22Retroceder%22,%22loginButtonText%22:%22Iniciar%20sess%C3%A3o%20com%20o%20Facebook%22,%22loginBodyText%22:%22O%20Facebook%20rastreia%20a%20tua%20atividade%20num%20site%20quando%20o%20usas%20para%20iniciares%20sess%C3%A3o.%22,%22buttonTextUnblockContent%22:%22Desbloquear%20Conte%C3%BAdo%20do%20Facebook%22,%22buttonTextUnblockComment%22:%22Desbloquear%20Coment%C3%A1rio%20do%20Facebook%22,%22buttonTextUnblockComments%22:%22Desbloquear%20Coment%C3%A1rios%20do%20Facebook%22,%22buttonTextUnblockPost%22:%22Desbloquear%20Publica%C3%A7%C3%A3o%20no%20Facebook%22,%22buttonTextUnblockVideo%22:%22Desbloquear%20V%C3%ADdeo%20do%20Facebook%22,%22buttonTextUnblockLogin%22:%22Desbloquear%20In%C3%ADcio%20de%20Sess%C3%A3o%20no%20Facebook%22,%22infoTitleUnblockContent%22:%22O%20DuckDuckGo%20bloqueou%20este%20conte%C3%BAdo%20para%20evitar%20que%20o%20Facebook%20te%20rastreie%22,%22infoTitleUnblockComment%22:%22O%20DuckDuckGo%20bloqueou%20este%20coment%C3%A1rio%20para%20evitar%20que%20o%20Facebook%20te%20rastreie%22,%22infoTitleUnblockComments%22:%22O%20DuckDuckGo%20bloqueou%20estes%20coment%C3%A1rios%20para%20evitar%20que%20o%20Facebook%20te%20rastreie%22,%22infoTitleUnblockPost%22:%22O%20DuckDuckGo%20bloqueou%20esta%20publica%C3%A7%C3%A3o%20para%20evitar%20que%20o%20Facebook%20te%20rastreie%22,%22infoTitleUnblockVideo%22:%22O%20DuckDuckGo%20bloqueou%20este%20v%C3%ADdeo%20para%20evitar%20que%20o%20Facebook%20te%20rastreie%22,%22infoTextUnblockContent%22:%22Bloque%C3%A1mos%20o%20rastreio%20por%20parte%20do%20Facebook%20quando%20a%20p%C3%A1gina%20foi%20carregada.%20Se%20desbloqueares%20este%20conte%C3%BAdo,%20o%20Facebook%20fica%20a%20saber%20a%20tua%20atividade.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Saiba%20mais%22,%22readAbout%22:%22Ler%20mais%20sobre%20esta%20prote%C3%A7%C3%A3o%20de%20privacidade%22,%22shareFeedback%22:%22Partilhar%20coment%C3%A1rios%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Ativar%20todas%20as%20pr%C3%A9-visualiza%C3%A7%C3%B5es%20do%20YouTube?%22,%22informationalModalMessageBody%22:%22Mostrar%20visualiza%C3%A7%C3%B5es%20permite%20%C3%A0%20Google%20(que%20det%C3%A9m%20o%20YouTube)%20ver%20algumas%20das%20informa%C3%A7%C3%B5es%20do%20teu%20dispositivo,%20mas%20ainda%20%C3%A9%20mais%20privado%20do%20que%20reproduzir%20o%20v%C3%ADdeo.%22,%22informationalModalConfirmButtonText%22:%22Ativar%20todas%20as%20pr%C3%A9-visualiza%C3%A7%C3%B5es%22,%22informationalModalRejectButtonText%22:%22N%C3%A3o,%20obrigado%22,%22buttonTextUnblockVideo%22:%22Desbloquear%20V%C3%ADdeo%20do%20YouTube%22,%22infoTitleUnblockVideo%22:%22O%20DuckDuckGo%20bloqueou%20este%20v%C3%ADdeo%20do%20YouTube%20para%20impedir%20que%20a%20Google%20te%20rastreie%22,%22infoTextUnblockVideo%22:%22Bloque%C3%A1mos%20o%20rastreio%20por%20parte%20da%20Google%20(que%20det%C3%A9m%20o%20YouTube)%20quando%20a%20p%C3%A1gina%20foi%20carregada.%20Se%20desbloqueares%20este%20v%C3%ADdeo,%20a%20Google%20fica%20a%20saber%20a%20tua%20atividade.%22,%22infoPreviewToggleText%22:%22Pr%C3%A9-visualiza%C3%A7%C3%B5es%20desativadas%20para%20privacidade%20adicional%22,%22infoPreviewToggleEnabledText%22:%22Pr%C3%A9-visualiza%C3%A7%C3%B5es%20ativadas%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22Pr%C3%A9-visualiza%C3%A7%C3%B5es%20do%20YouTube%20ativadas%20no%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3ESaiba%20mais%3C/a%3E%20sobre%20a%20Prote%C3%A7%C3%A3o%20contra%20conte%C3%BAdos%20de%20redes%20sociais%20incorporados%20do%20DuckDuckGo%22%7D%7D,%22ro%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Conectarea%20cu%20Facebook%20%C3%AEi%20permite%20s%C4%83%20te%20urm%C4%83reasc%C4%83%22,%22informationalModalMessageBody%22:%22Odat%C4%83%20ce%20te-ai%20conectat,%20DuckDuckGo%20nu%20poate%20%C3%AEmpiedica%20con%C8%9Binutul%20Facebook%20s%C4%83%20te%20urm%C4%83reasc%C4%83%20pe%20acest%20site.%22,%22informationalModalConfirmButtonText%22:%22Autentificare%22,%22informationalModalRejectButtonText%22:%22%C3%8Enapoi%22,%22loginButtonText%22:%22Conecteaz%C4%83-te%20cu%20Facebook%22,%22loginBodyText%22:%22Facebook%20urm%C4%83re%C8%99te%20activitatea%20ta%20pe%20un%20site%20atunci%20c%C3%A2nd%20%C3%AEl%20utilizezi%20pentru%20a%20te%20conecta.%22,%22buttonTextUnblockContent%22:%22Deblocheaz%C4%83%20con%C8%9Binutul%20Facebook%22,%22buttonTextUnblockComment%22:%22Deblocheaz%C4%83%20comentariul%20de%20pe%20Facebook%22,%22buttonTextUnblockComments%22:%22Deblocheaz%C4%83%20comentariile%20de%20pe%20Facebook%22,%22buttonTextUnblockPost%22:%22Deblocheaz%C4%83%20postarea%20de%20pe%20Facebook%22,%22buttonTextUnblockVideo%22:%22Deblocheaz%C4%83%20videoclipul%20de%20pe%20Facebook%22,%22buttonTextUnblockLogin%22:%22Deblocheaz%C4%83%20conectarea%20cu%20Facebook%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20a%20blocat%20acest%20con%C8%9Binut%20pentru%20a%20%C3%AEmpiedica%20Facebook%20s%C4%83%20te%20urm%C4%83reasc%C4%83%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20a%20blocat%20acest%20comentariu%20pentru%20a%20%C3%AEmpiedica%20Facebook%20s%C4%83%20te%20urm%C4%83reasc%C4%83%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20a%20blocat%20aceste%20comentarii%20pentru%20a%20%C3%AEmpiedica%20Facebook%20s%C4%83%20te%20urm%C4%83reasc%C4%83%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20a%20blocat%20aceast%C4%83%20postare%20pentru%20a%20%C3%AEmpiedica%20Facebook%20s%C4%83%20te%20urm%C4%83reasc%C4%83%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20a%20blocat%20acest%20videoclip%20pentru%20a%20%C3%AEmpiedica%20Facebook%20s%C4%83%20te%20urm%C4%83reasc%C4%83%22,%22infoTextUnblockContent%22:%22Am%20%C3%AEmpiedicat%20Facebook%20s%C4%83%20te%20urm%C4%83reasc%C4%83%20atunci%20c%C3%A2nd%20pagina%20a%20fost%20%C3%AEnc%C4%83rcat%C4%83.%20Dac%C4%83%20deblochezi%20acest%20con%C8%9Binut,%20Facebook%20%C3%AE%C8%9Bi%20va%20cunoa%C8%99te%20activitatea.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Afl%C4%83%20mai%20multe%22,%22readAbout%22:%22Cite%C8%99te%20despre%20aceast%C4%83%20protec%C8%9Bie%20a%20confiden%C8%9Bialit%C4%83%C8%9Bii%22,%22shareFeedback%22:%22Partajeaz%C4%83%20feedback%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Activezi%20toate%20previzualiz%C4%83rile%20YouTube?%22,%22informationalModalMessageBody%22:%22Afi%C8%99area%20previzualiz%C4%83rilor%20va%20permite%20ca%20Google%20(care%20de%C8%9Bine%20YouTube)%20s%C4%83%20vad%C4%83%20unele%20dintre%20informa%C8%9Biile%20despre%20dispozitivul%20t%C4%83u,%20dar%20este%20totu%C8%99i%20mai%20privat%C4%83%20dec%C3%A2t%20redarea%20videoclipului.%22,%22informationalModalConfirmButtonText%22:%22Activeaz%C4%83%20toate%20previzualiz%C4%83rile%22,%22informationalModalRejectButtonText%22:%22Nu,%20mul%C8%9Bumesc%22,%22buttonTextUnblockVideo%22:%22Deblocheaz%C4%83%20videoclipul%20de%20pe%20YouTube%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20a%20blocat%20acest%20videoclip%20de%20pe%20YouTube%20pentru%20a%20%C3%AEmpiedica%20Google%20s%C4%83%20te%20urm%C4%83reasc%C4%83%22,%22infoTextUnblockVideo%22:%22Am%20%C3%AEmpiedicat%20Google%20(care%20de%C8%9Bine%20YouTube)%20s%C4%83%20te%20urm%C4%83reasc%C4%83%20atunci%20c%C3%A2nd%20s-a%20%C3%AEnc%C4%83rcat%20pagina.%20Dac%C4%83%20deblochezi%20acest%20videoclip,%20Google%20va%20cunoa%C8%99te%20activitatea%20ta.%22,%22infoPreviewToggleText%22:%22Previzualiz%C4%83rile%20au%20fost%20dezactivate%20pentru%20o%20confiden%C8%9Bialitate%20suplimentar%C4%83%22,%22infoPreviewToggleEnabledText%22:%22Previzualiz%C4%83ri%20activate%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22Previzualiz%C4%83rile%20YouTube%20sunt%20activate%20%C3%AEn%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EAfl%C4%83%20mai%20multe%3C/a%3E%20despre%20Protec%C8%9Bia%20integrat%C4%83%20DuckDuckGo%20pentru%20re%C8%9Belele%20sociale%22%7D%7D,%22ru%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22%D0%92%D1%85%D0%BE%D0%B4%20%D1%87%D0%B5%D1%80%D0%B5%D0%B7%20Facebook%20%D0%BF%D0%BE%D0%B7%D0%B2%D0%BE%D0%BB%D1%8F%D0%B5%D1%82%20%D1%8D%D1%82%D0%BE%D0%B9%20%D1%81%D0%BE%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9%20%D1%81%D0%B5%D1%82%D0%B8%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D1%82%D1%8C%20%D0%B2%D0%B0%D1%81%22,%22informationalModalMessageBody%22:%22%D0%9F%D0%BE%D1%81%D0%BB%D0%B5%20%D0%B2%D1%85%D0%BE%D0%B4%D0%B0%20DuckDuckGo%20%D0%BD%D0%B5%20%D1%81%D0%BC%D0%BE%D0%B6%D0%B5%D1%82%20%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%20%D0%B2%D0%B0%D1%88%D0%B8%D1%85%20%D0%B4%D0%B5%D0%B9%D1%81%D1%82%D0%B2%D0%B8%D0%B9%20%D1%81%20%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%BD%D1%82%D0%BE%D0%BC%20%D0%BD%D0%B0%20Facebook.%22,%22informationalModalConfirmButtonText%22:%22%D0%92%D0%BE%D0%B9%D1%82%D0%B8%22,%22informationalModalRejectButtonText%22:%22%D0%92%D0%B5%D1%80%D0%BD%D1%83%D1%82%D1%8C%D1%81%D1%8F%22,%22loginButtonText%22:%22%D0%92%D0%BE%D0%B9%D1%82%D0%B8%20%D1%87%D0%B5%D1%80%D0%B5%D0%B7%20Facebook%22,%22loginBodyText%22:%22%D0%9F%D1%80%D0%B8%20%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B8%20%D1%83%D1%87%D1%91%D1%82%D0%BD%D0%BE%D0%B9%20%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D0%B8%20Facebook%20%D0%B4%D0%BB%D1%8F%20%D0%B2%D1%85%D0%BE%D0%B4%D0%B0%20%D0%BD%D0%B0%20%D1%81%D0%B0%D0%B9%D1%82%D1%8B%20%D1%8D%D1%82%D0%B0%20%D1%81%D0%BE%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F%20%D1%81%D0%B5%D1%82%D1%8C%20%D1%81%D0%BC%D0%BE%D0%B6%D0%B5%D1%82%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BD%D0%B0%20%D0%BD%D0%B8%D1%85%20%D0%B2%D0%B0%D1%88%D0%B8%20%D0%B4%D0%B5%D0%B9%D1%81%D1%82%D0%B2%D0%B8%D1%8F.%22,%22buttonTextUnblockContent%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%BD%D1%82%20%D0%B8%D0%B7%20Facebook%22,%22buttonTextUnblockComment%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BA%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B9%20%D0%B8%D0%B7%20Facebook%22,%22buttonTextUnblockComments%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BA%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8%20%D0%B8%D0%B7%20Facebook%22,%22buttonTextUnblockPost%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8E%20%D0%B8%D0%B7%20Facebook%22,%22buttonTextUnblockVideo%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%20%D0%B8%D0%B7%20Facebook%22,%22buttonTextUnblockLogin%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BE%D0%BA%D0%BD%D0%BE%20%D0%B2%D1%85%D0%BE%D0%B4%D0%B0%20%D0%B2%20Facebook%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20%D0%B7%D0%B0%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BB%20%D1%8D%D1%82%D0%BE%D1%82%20%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%BD%D1%82,%20%D1%87%D1%82%D0%BE%D0%B1%D1%8B%20%D0%B2%D0%B0%D1%81%20%D0%BD%D0%B5%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D0%BB%20Facebook%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20%D0%B7%D0%B0%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BB%20%D1%8D%D1%82%D0%BE%D1%82%20%D0%BA%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B9,%20%D1%87%D1%82%D0%BE%D0%B1%D1%8B%20%D0%B2%D0%B0%D1%81%20%D0%BD%D0%B5%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D0%BB%20Facebook%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20%D0%B7%D0%B0%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BB%20%D1%8D%D1%82%D0%B8%20%D0%BA%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8,%20%D1%87%D1%82%D0%BE%D0%B1%D1%8B%20%D0%B2%D0%B0%D1%81%20%D0%BD%D0%B5%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D0%BB%20Facebook%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20%D0%B7%D0%B0%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BB%20%D1%8D%D1%82%D1%83%20%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8E,%20%D1%87%D1%82%D0%BE%D0%B1%D1%8B%20%D0%B2%D0%B0%D1%81%20%D0%BD%D0%B5%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D0%BB%20Facebook%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20%D0%B7%D0%B0%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BB%20%D1%8D%D1%82%D0%BE%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE,%20%D1%87%D1%82%D0%BE%D0%B1%D1%8B%20%D0%B2%D0%B0%D1%81%20%D0%BD%D0%B5%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D0%BB%20Facebook%22,%22infoTextUnblockContent%22:%22%D0%92%D0%BE%20%D0%B2%D1%80%D0%B5%D0%BC%D1%8F%20%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8%20%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D1%8B%20%D0%BC%D1%8B%20%D0%BF%D0%BE%D0%BC%D0%B5%D1%88%D0%B0%D0%BB%D0%B8%20Facebook%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B4%D0%B8%D1%82%D1%8C%20%D0%B2%D0%B0%D1%88%D0%B8%20%D0%B4%D0%B5%D0%B9%D1%81%D1%82%D0%B2%D0%B8%D1%8F.%20%D0%95%D1%81%D0%BB%D0%B8%20%D1%80%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D1%8D%D1%82%D0%BE%D1%82%20%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%BD%D1%82,%20Facebook%20%D1%81%D0%BC%D0%BE%D0%B6%D0%B5%D1%82%20%D1%84%D0%B8%D0%BA%D1%81%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%B2%D0%B0%D1%88%D1%83%20%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D1%81%D1%82%D1%8C.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22%D0%A3%D0%B7%D0%BD%D0%B0%D1%82%D1%8C%20%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%22,%22readAbout%22:%22%D0%9F%D0%BE%D0%B4%D1%80%D0%BE%D0%B1%D0%BD%D0%B5%D0%B5%20%D0%BE%D0%B1%20%D1%8D%D1%82%D0%BE%D0%BC%20%D0%B2%D0%B8%D0%B4%D0%B5%20%D0%B7%D0%B0%D1%89%D0%B8%D1%82%D1%8B%20%D0%BA%D0%BE%D0%BD%D1%84%D0%B8%D0%B4%D0%B5%D0%BD%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8%22,%22shareFeedback%22:%22%D0%9E%D1%81%D1%82%D0%B0%D0%B2%D1%8C%D1%82%D0%B5%20%D0%BD%D0%B0%D0%BC%20%D0%BE%D1%82%D0%B7%D1%8B%D0%B2%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22%D0%92%D0%BA%D0%BB%D1%8E%D1%87%D0%B8%D1%82%D1%8C%20%D0%BF%D1%80%D0%B5%D0%B4%D0%BF%D1%80%D0%BE%D1%81%D0%BC%D0%BE%D1%82%D1%80%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%20%D0%B8%D0%B7%20YouTube?%22,%22informationalModalMessageBody%22:%22%D0%92%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%BF%D1%80%D0%B5%D0%B4%D0%B2%D0%B0%D1%80%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%20%D0%BF%D1%80%D0%BE%D1%81%D0%BC%D0%BE%D1%82%D1%80%D0%B0%20%D0%BF%D0%BE%D0%B7%D0%B2%D0%BE%D0%BB%D0%B8%D1%82%20Google%20(%D0%B2%D0%BB%D0%B0%D0%B4%D0%B5%D0%BB%D1%8C%D1%86%D1%83%20YouTube)%20%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C%20%D0%BD%D0%B5%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D1%8B%D0%B5%20%D1%81%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D1%8F%20%D0%BE%20%D0%B2%D0%B0%D1%88%D0%B5%D0%BC%20%D1%83%D1%81%D1%82%D1%80%D0%BE%D0%B9%D1%81%D1%82%D0%B2%D0%B5,%20%D0%BE%D0%B4%D0%BD%D0%B0%D0%BA%D0%BE%20%D1%8D%D1%82%D0%BE%20%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5%20%D0%B1%D0%B5%D0%B7%D0%BE%D0%BF%D0%B0%D1%81%D0%BD%D1%8B%D0%B9%20%D0%B2%D0%B0%D1%80%D0%B8%D0%B0%D0%BD%D1%82,%20%D1%87%D0%B5%D0%BC%20%D0%B2%D0%BE%D1%81%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%20%D1%86%D0%B5%D0%BB%D0%B8%D0%BA%D0%BE%D0%BC.%22,%22informationalModalConfirmButtonText%22:%22%D0%92%D0%BA%D0%BB%D1%8E%D1%87%D0%B8%D1%82%D1%8C%20%D0%BF%D1%80%D0%B5%D0%B4%D0%BF%D1%80%D0%BE%D1%81%D0%BC%D0%BE%D1%82%D1%80%22,%22informationalModalRejectButtonText%22:%22%D0%9D%D0%B5%D1%82,%20%D1%81%D0%BF%D0%B0%D1%81%D0%B8%D0%B1%D0%BE%22,%22buttonTextUnblockVideo%22:%22%D0%A0%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%20%D0%B8%D0%B7%20YouTube%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20%D0%B7%D0%B0%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BB%20%D1%8D%D1%82%D0%BE%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%20%D0%B8%D0%B7%20YouTube,%20%D1%87%D1%82%D0%BE%D0%B1%D1%8B%20%D0%B2%D0%B0%D1%81%20%D0%BD%D0%B5%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D0%BB%20Google%22,%22infoTextUnblockVideo%22:%22%D0%92%D0%BE%20%D0%B2%D1%80%D0%B5%D0%BC%D1%8F%20%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8%20%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D1%8B%20%D0%BC%D1%8B%20%D0%BF%D0%BE%D0%BC%D0%B5%D1%88%D0%B0%D0%BB%D0%B8%20Google%20(%D0%B2%D0%BB%D0%B0%D0%B4%D0%B5%D0%BB%D1%8C%D1%86%D1%83%20YouTube)%20%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B4%D0%B8%D1%82%D1%8C%20%D0%B2%D0%B0%D1%88%D0%B8%20%D0%B4%D0%B5%D0%B9%D1%81%D1%82%D0%B2%D0%B8%D1%8F.%20%D0%95%D1%81%D0%BB%D0%B8%20%D1%80%D0%B0%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE,%20Google%20%D1%81%D0%BC%D0%BE%D0%B6%D0%B5%D1%82%20%D1%84%D0%B8%D0%BA%D1%81%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%B2%D0%B0%D1%88%D1%83%20%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D1%81%D1%82%D1%8C.%22,%22infoPreviewToggleText%22:%22%D0%9F%D1%80%D0%B5%D0%B4%D0%B2%D0%B0%D1%80%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9%20%D0%BF%D1%80%D0%BE%D1%81%D0%BC%D0%BE%D1%82%D1%80%20%D0%BE%D1%82%D0%BA%D0%BB%D1%8E%D1%87%D1%91%D0%BD%20%D0%B4%D0%BB%D1%8F%20%D0%B4%D0%BE%D0%BF%D0%BE%D0%BB%D0%BD%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9%20%D0%B7%D0%B0%D1%89%D0%B8%D1%82%D1%8B%20%D0%BA%D0%BE%D0%BD%D1%84%D0%B8%D0%B4%D0%B5%D0%BD%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8%22,%22infoPreviewToggleEnabledText%22:%22%D0%9F%D1%80%D0%B5%D0%B4%D0%B2%D0%B0%D1%80%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9%20%D0%BF%D1%80%D0%BE%D1%81%D0%BC%D0%BE%D1%82%D1%80%20%D0%B2%D0%BA%D0%BB%D1%8E%D1%87%D1%91%D0%BD%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22%D0%92%20DuckDuckGo%20%D0%B2%D0%BA%D0%BB%D1%8E%D1%87%D1%91%D0%BD%20%D0%BF%D1%80%D0%B5%D0%B4%D0%BF%D1%80%D0%BE%D1%81%D0%BC%D0%BE%D1%82%D1%80%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%20%D0%B8%D0%B7%20YouTube.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3E%D0%9F%D0%BE%D0%B4%D1%80%D0%BE%D0%B1%D0%BD%D0%B5%D0%B5%3C/a%3E%20%D0%BE%20%D0%B7%D0%B0%D1%89%D0%B8%D1%82%D0%B5%20DuckDuckGo%20%D0%BE%D1%82%20%D0%B2%D0%BD%D0%B5%D0%B4%D1%80%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE%20%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%BD%D1%82%D0%B0%20%D1%81%D0%BE%D1%86%D1%81%D0%B5%D1%82%D0%B5%D0%B9%22%7D%7D,%22sk%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Prihl%C3%A1senie%20cez%20Facebook%20mu%20umo%C5%BEn%C3%AD%20sledova%C5%A5%20v%C3%A1s%22,%22informationalModalMessageBody%22:%22DuckDuckGo%20po%20prihl%C3%A1sen%C3%AD%20nem%C3%B4%C5%BEe%20na%20tejto%20lokalite%20zablokova%C5%A5%20sledovanie%20va%C5%A1ej%20osoby%20obsahom%20Facebooku.%22,%22informationalModalConfirmButtonText%22:%22Prihl%C3%A1si%C5%A5%20sa%22,%22informationalModalRejectButtonText%22:%22Prejs%C5%A5%20sp%C3%A4%C5%A5%22,%22loginButtonText%22:%22Prihl%C3%A1ste%20sa%20pomocou%20slu%C5%BEby%20Facebook%22,%22loginBodyText%22:%22Ke%C4%8F%20pou%C5%BEijete%20prihlasovanie%20cez%20Facebook,%20Facebook%20bude%20na%20lokalite%20sledova%C5%A5%20va%C5%A1u%20aktivitu.%22,%22buttonTextUnblockContent%22:%22Odblokova%C5%A5%20obsah%20Facebooku%22,%22buttonTextUnblockComment%22:%22Odblokova%C5%A5%20koment%C3%A1r%20na%20Facebooku%22,%22buttonTextUnblockComments%22:%22Odblokova%C5%A5%20koment%C3%A1re%20na%20Facebooku%22,%22buttonTextUnblockPost%22:%22Odblokova%C5%A5%20pr%C3%ADspevok%20na%20Facebooku%22,%22buttonTextUnblockVideo%22:%22Odblokovanie%20videa%20na%20Facebooku%22,%22buttonTextUnblockLogin%22:%22Odblokova%C5%A5%20prihl%C3%A1senie%20na%20Facebook%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20zablokoval%20tento%20obsah,%20aby%20v%C3%A1s%20Facebook%20nesledoval%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20zablokoval%20tento%20koment%C3%A1r,%20aby%20zabr%C3%A1nil%20sledovaniu%20zo%20strany%20Facebooku%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20zablokoval%20tieto%20koment%C3%A1re,%20aby%20v%C3%A1s%20Facebook%20nesledoval%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20zablokoval%20tento%20pr%C3%ADspevok,%20aby%20v%C3%A1s%20Facebook%20nesledoval%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20zablokoval%20toto%20video,%20aby%20v%C3%A1s%20Facebook%20nesledoval%22,%22infoTextUnblockContent%22:%22Pri%20na%C4%8D%C3%ADtan%C3%AD%20str%C3%A1nky%20sme%20zablokovali%20Facebook,%20aby%20v%C3%A1s%20nesledoval.%20Ak%20tento%20obsah%20odblokujete,%20Facebook%20bude%20vedie%C5%A5%20o%20va%C5%A1ej%20aktivite.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Zistite%20viac%22,%22readAbout%22:%22Pre%C4%8D%C3%ADtajte%20si%20o%20tejto%20ochrane%20s%C3%BAkromia%22,%22shareFeedback%22:%22Zdie%C4%BEa%C5%A5%20sp%C3%A4tn%C3%BA%20v%C3%A4zbu%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Chcete%20povoli%C5%A5%20v%C5%A1etky%20uk%C3%A1%C5%BEky%20zo%20slu%C5%BEby%20YouTube?%22,%22informationalModalMessageBody%22:%22Zobrazenie%20uk%C3%A1%C5%BEok%20umo%C5%BEn%C3%AD%20spolo%C4%8Dnosti%20Google%20(ktor%C3%A1%20vlastn%C3%AD%20YouTube)%20vidie%C5%A5%20niektor%C3%A9%20inform%C3%A1cie%20o%20va%C5%A1om%20zariaden%C3%AD,%20ale%20st%C3%A1le%20je%20to%20s%C3%BAkromnej%C5%A1ie%20ako%20prehr%C3%A1vanie%20videa.%22,%22informationalModalConfirmButtonText%22:%22Povoli%C5%A5%20v%C5%A1etky%20uk%C3%A1%C5%BEky%22,%22informationalModalRejectButtonText%22:%22Nie,%20%C4%8Fakujem%22,%22buttonTextUnblockVideo%22:%22Odblokova%C5%A5%20YouTube%20video%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20toto%20video%20v%20slu%C5%BEbe%20YouTube%20zablokoval%20s%20cie%C4%BEom%20pred%C3%ADs%C5%A5%20tomu,%20aby%20v%C3%A1s%20spolo%C4%8Dnos%C5%A5%20Google%20mohla%20sledova%C5%A5%22,%22infoTextUnblockVideo%22:%22Zablokovali%20sme%20pre%20spolo%C4%8Dnos%C5%A5%20Google%20(ktor%C3%A1%20vlastn%C3%AD%20YouTube),%20aby%20v%C3%A1s%20nemohla%20sledova%C5%A5,%20ke%C4%8F%20sa%20str%C3%A1nka%20na%C4%8D%C3%ADta.%20Ak%20toto%20video%20odblokujete,%20Google%20bude%20pozna%C5%A5%20va%C5%A1u%20aktivitu.%22,%22infoPreviewToggleText%22:%22Uk%C3%A1%C5%BEky%20s%C3%BA%20zak%C3%A1zan%C3%A9%20s%20cie%C4%BEom%20zv%C3%BD%C5%A1i%C5%A5%20ochranu%20s%C3%BAkromia%22,%22infoPreviewToggleEnabledText%22:%22Uk%C3%A1%C5%BEky%20s%C3%BA%20povolen%C3%A9%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22Uk%C3%A1%C5%BEky%20YouTube%20s%C3%BA%20v%20DuckDuckGo%20povolen%C3%A9.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EZ%C3%ADskajte%20viac%20inform%C3%A1ci%C3%AD%3C/a%3E%20o%20DuckDuckGo,%20vlo%C5%BEenej%20ochrane%20soci%C3%A1lnych%20m%C3%A9di%C3%AD%22%7D%7D,%22sl%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22%C4%8Ce%20se%20prijavite%20s%20Facebookom,%20vam%20Facebook%20lahko%20sledi%22,%22informationalModalMessageBody%22:%22Ko%20ste%20enkrat%20prijavljeni,%20DuckDuckGo%20ne%20more%20blokirati%20Facebookove%20vsebine,%20da%20bi%20vam%20sledila%20na%20tem%20spletnem%20mestu.%22,%22informationalModalConfirmButtonText%22:%22Prijava%22,%22informationalModalRejectButtonText%22:%22Pojdi%20nazaj%22,%22loginButtonText%22:%22Prijavite%20se%20s%20Facebookom%22,%22loginBodyText%22:%22%C4%8Ce%20se%20prijavite%20s%20Facebookom,%20bo%20nato%20spremljal%20va%C5%A1a%20dejanja%20na%20spletnem%20mestu.%22,%22buttonTextUnblockContent%22:%22Odblokiraj%20vsebino%20na%20Facebooku%22,%22buttonTextUnblockComment%22:%22Odblokiraj%20komentar%20na%20Facebooku%22,%22buttonTextUnblockComments%22:%22Odblokiraj%20komentarje%20na%20Facebooku%22,%22buttonTextUnblockPost%22:%22Odblokiraj%20objavo%20na%20Facebooku%22,%22buttonTextUnblockVideo%22:%22Odblokiraj%20videoposnetek%20na%20Facebooku%22,%22buttonTextUnblockLogin%22:%22Odblokiraj%20prijavo%20na%20Facebooku%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20je%20blokiral%20to%20vsebino,%20da%20bi%20Facebooku%20prepre%C4%8Dil%20sledenje%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20je%20blokiral%20ta%20komentar,%20da%20bi%20Facebooku%20prepre%C4%8Dil%20sledenje%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20je%20blokiral%20te%20komentarje,%20da%20bi%20Facebooku%20prepre%C4%8Dil%20sledenje%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20je%20blokiral%20to%20objavo,%20da%20bi%20Facebooku%20prepre%C4%8Dil%20sledenje%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20je%20blokiral%20ta%20videoposnetek,%20da%20bi%20Facebooku%20prepre%C4%8Dil%20sledenje%22,%22infoTextUnblockContent%22:%22Ko%20se%20je%20stran%20nalo%C5%BEila,%20smo%20Facebooku%20prepre%C4%8Dili,%20da%20bi%20vam%20sledil.%20%C4%8Ce%20to%20vsebino%20odblokirate,%20bo%20Facebook%20izvedel%20za%20va%C5%A1a%20dejanja.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Ve%C4%8D%22,%22readAbout%22:%22Preberite%20ve%C4%8D%20o%20tej%20za%C5%A1%C4%8Diti%20zasebnosti%22,%22shareFeedback%22:%22Deli%20povratne%20informacije%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22%C5%BDelite%20omogo%C4%8Diti%20vse%20YouTubove%20predoglede?%22,%22informationalModalMessageBody%22:%22Prikaz%20predogledov%20omogo%C4%8Da%20Googlu%20(ki%20je%20lastnik%20YouTuba)%20vpogled%20v%20nekatere%20podatke%20o%20napravi,%20vendar%20je%20%C5%A1e%20vedno%20bolj%20zasebno%20kot%20predvajanje%20videoposnetka.%22,%22informationalModalConfirmButtonText%22:%22Omogo%C4%8Di%20vse%20predoglede%22,%22informationalModalRejectButtonText%22:%22Ne,%20hvala%22,%22buttonTextUnblockVideo%22:%22Odblokiraj%20videoposnetek%20na%20YouTubu%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20je%20blokiral%20ta%20videoposnetek%20v%20YouTubu,%20da%20bi%20Googlu%20prepre%C4%8Dil%20sledenje%22,%22infoTextUnblockVideo%22:%22Googlu%20(ki%20je%20lastnik%20YouTuba)%20smo%20prepre%C4%8Dili,%20da%20bi%20vam%20sledil,%20ko%20se%20je%20stran%20nalo%C5%BEila.%20%C4%8Ce%20odblokirate%20ta%20videoposnetek,%20bo%20Google%20izvedel%20za%20va%C5%A1o%20dejavnost.%22,%22infoPreviewToggleText%22:%22Predogledi%20so%20zaradi%20dodatne%20zasebnosti%20onemogo%C4%8Deni%22,%22infoPreviewToggleEnabledText%22:%22Predogledi%20so%20omogo%C4%8Deni%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTubovi%20predogledi%20so%20omogo%C4%8Deni%20v%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EVe%C4%8D%3C/a%3E%20o%20vgrajeni%20za%C5%A1%C4%8Diti%20dru%C5%BEbenih%20medijev%20DuckDuckGo%22%7D%7D,%22sv%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Om%20du%20loggar%20in%20med%20Facebook%20kan%20de%20sp%C3%A5ra%20dig%22,%22informationalModalMessageBody%22:%22N%C3%A4r%20du%20v%C3%A4l%20%C3%A4r%20inloggad%20kan%20DuckDuckGo%20inte%20hindra%20Facebooks%20inneh%C3%A5ll%20fr%C3%A5n%20att%20sp%C3%A5ra%20dig%20p%C3%A5%20den%20h%C3%A4r%20webbplatsen.%22,%22informationalModalConfirmButtonText%22:%22Logga%20in%22,%22informationalModalRejectButtonText%22:%22G%C3%A5%20tillbaka%22,%22loginButtonText%22:%22Logga%20in%20med%20Facebook%22,%22loginBodyText%22:%22Facebook%20sp%C3%A5rar%20din%20aktivitet%20p%C3%A5%20en%20webbplats%20om%20du%20anv%C3%A4nder%20det%20f%C3%B6r%20att%20logga%20in.%22,%22buttonTextUnblockContent%22:%22Avblockera%20Facebook-inneh%C3%A5ll%22,%22buttonTextUnblockComment%22:%22Avblockera%20Facebook-kommentar%22,%22buttonTextUnblockComments%22:%22Avblockera%20Facebook-kommentarer%22,%22buttonTextUnblockPost%22:%22Avblockera%20Facebook-inl%C3%A4gg%22,%22buttonTextUnblockVideo%22:%22Avblockera%20Facebook-video%22,%22buttonTextUnblockLogin%22:%22Avblockera%20Facebook-inloggning%22,%22infoTitleUnblockContent%22:%22DuckDuckGo%20blockerade%20det%20h%C3%A4r%20inneh%C3%A5llet%20f%C3%B6r%20att%20f%C3%B6rhindra%20att%20Facebook%20sp%C3%A5rar%20dig%22,%22infoTitleUnblockComment%22:%22DuckDuckGo%20blockerade%20den%20h%C3%A4r%20kommentaren%20f%C3%B6r%20att%20f%C3%B6rhindra%20att%20Facebook%20sp%C3%A5rar%20dig%22,%22infoTitleUnblockComments%22:%22DuckDuckGo%20blockerade%20de%20h%C3%A4r%20kommentarerna%20f%C3%B6r%20att%20f%C3%B6rhindra%20att%20Facebook%20sp%C3%A5rar%20dig%22,%22infoTitleUnblockPost%22:%22DuckDuckGo%20blockerade%20det%20h%C3%A4r%20inl%C3%A4gget%20f%C3%B6r%20att%20f%C3%B6rhindra%20att%20Facebook%20sp%C3%A5rar%20dig%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blockerade%20den%20h%C3%A4r%20videon%20f%C3%B6r%20att%20f%C3%B6rhindra%20att%20Facebook%20sp%C3%A5rar%20dig%22,%22infoTextUnblockContent%22:%22Vi%20hindrade%20Facebook%20fr%C3%A5n%20att%20sp%C3%A5ra%20dig%20n%C3%A4r%20sidan%20l%C3%A4stes%20in.%20Om%20du%20avblockerar%20det%20h%C3%A4r%20inneh%C3%A5llet%20kommer%20Facebook%20att%20k%C3%A4nna%20till%20din%20aktivitet.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22L%C3%A4s%20mer%22,%22readAbout%22:%22L%C3%A4s%20mer%20om%20detta%20integritetsskydd%22,%22shareFeedback%22:%22Ber%C3%A4tta%20vad%20du%20tycker%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22Aktivera%20alla%20f%C3%B6rhandsvisningar%20f%C3%B6r%20YouTube?%22,%22informationalModalMessageBody%22:%22Genom%20att%20visa%20f%C3%B6rhandsvisningar%20kan%20Google%20(som%20%C3%A4ger%20YouTube)%20se%20en%20del%20av%20enhetens%20information,%20men%20det%20%C3%A4r%20%C3%A4nd%C3%A5%20mer%20privat%20%C3%A4n%20att%20spela%20upp%20videon.%22,%22informationalModalConfirmButtonText%22:%22Aktivera%20alla%20f%C3%B6rhandsvisningar%22,%22informationalModalRejectButtonText%22:%22Nej%20tack%22,%22buttonTextUnblockVideo%22:%22Avblockera%20YouTube-video%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo%20blockerade%20den%20h%C3%A4r%20YouTube-videon%20f%C3%B6r%20att%20f%C3%B6rhindra%20att%20Google%20sp%C3%A5rar%20dig%22,%22infoTextUnblockVideo%22:%22Vi%20hindrade%20Google%20(som%20%C3%A4ger%20YouTube)%20fr%C3%A5n%20att%20sp%C3%A5ra%20dig%20n%C3%A4r%20sidan%20laddades.%20Om%20du%20tar%20bort%20blockeringen%20av%20videon%20kommer%20Google%20att%20k%C3%A4nna%20till%20din%20aktivitet.%22,%22infoPreviewToggleText%22:%22F%C3%B6rhandsvisningar%20har%20inaktiverats%20f%C3%B6r%20ytterligare%20integritet%22,%22infoPreviewToggleEnabledText%22:%22F%C3%B6rhandsvisningar%20aktiverade%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22YouTube-f%C3%B6rhandsvisningar%20aktiverade%20i%20DuckDuckGo.%22,%22infoPreviewInfoText%22:%22%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3EL%C3%A4s%20mer%3C/a%3E%20om%20DuckDuckGos%20skydd%20mot%20inb%C3%A4ddade%20sociala%20medier%22%7D%7D,%22tr%22:%7B%22facebook.json%22:%7B%22informationalModalMessageTitle%22:%22Facebook%20ile%20giri%C5%9F%20yapmak,%20sizi%20takip%20etmelerini%20sa%C4%9Flar%22,%22informationalModalMessageBody%22:%22Giri%C5%9F%20yapt%C4%B1ktan%20sonra,%20DuckDuckGo%20Facebook%20i%C3%A7eri%C4%9Finin%20sizi%20bu%20sitede%20izlemesini%20engelleyemez.%22,%22informationalModalConfirmButtonText%22:%22Oturum%20A%C3%A7%22,%22informationalModalRejectButtonText%22:%22Geri%20d%C3%B6n%22,%22loginButtonText%22:%22Facebook%20ile%20giri%C5%9F%20yap%C4%B1n%22,%22loginBodyText%22:%22Facebook,%20giri%C5%9F%20yapmak%20i%C3%A7in%20kulland%C4%B1%C4%9F%C4%B1n%C4%B1zda%20bir%20sitedeki%20etkinli%C4%9Finizi%20izler.%22,%22buttonTextUnblockContent%22:%22Facebook%20%C4%B0%C3%A7eri%C4%9Finin%20Engelini%20Kald%C4%B1r%22,%22buttonTextUnblockComment%22:%22Facebook%20Yorumunun%20Engelini%20Kald%C4%B1r%22,%22buttonTextUnblockComments%22:%22Facebook%20Yorumlar%C4%B1n%C4%B1n%20Engelini%20Kald%C4%B1r%22,%22buttonTextUnblockPost%22:%22Facebook%20G%C3%B6nderisinin%20Engelini%20Kald%C4%B1r%22,%22buttonTextUnblockVideo%22:%22Facebook%20Videosunun%20Engelini%20Kald%C4%B1r%22,%22buttonTextUnblockLogin%22:%22Facebook%20Giri%C5%9Finin%20Engelini%20Kald%C4%B1r%22,%22infoTitleUnblockContent%22:%22DuckDuckGo,%20Facebook'un%20sizi%20izlemesini%20%C3%B6nlemek%20i%C3%A7in%20bu%20i%C3%A7eri%C4%9Fi%20engelledi%22,%22infoTitleUnblockComment%22:%22DuckDuckGo,%20Facebook'un%20sizi%20izlemesini%20%C3%B6nlemek%20i%C3%A7in%20bu%20yorumu%20engelledi%22,%22infoTitleUnblockComments%22:%22DuckDuckGo,%20Facebook'un%20sizi%20izlemesini%20%C3%B6nlemek%20i%C3%A7in%20bu%20yorumlar%C4%B1%20engelledi%22,%22infoTitleUnblockPost%22:%22DuckDuckGo,%20Facebook'un%20sizi%20izlemesini%20%C3%B6nlemek%20i%C3%A7in%20bu%20g%C3%B6nderiyi%20engelledi%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo,%20Facebook'un%20sizi%20izlemesini%20%C3%B6nlemek%20i%C3%A7in%20bu%20videoyu%20engelledi%22,%22infoTextUnblockContent%22:%22Sayfa%20y%C3%BCklendi%C4%9Finde%20Facebook'un%20sizi%20izlemesini%20engelledik.%20Bu%20i%C3%A7eri%C4%9Fin%20engelini%20kald%C4%B1r%C4%B1rsan%C4%B1z%20Facebook%20etkinli%C4%9Finizi%20%C3%B6%C4%9Frenecektir.%22%7D,%22shared.json%22:%7B%22learnMore%22:%22Daha%20Fazla%20Bilgi%22,%22readAbout%22:%22Bu%20gizlilik%20korumas%C4%B1%20hakk%C4%B1nda%20bilgi%20edinin%22,%22shareFeedback%22:%22Geri%20Bildirim%20Payla%C5%9F%22%7D,%22youtube.json%22:%7B%22informationalModalMessageTitle%22:%22T%C3%BCm%20YouTube%20%C3%B6nizlemeleri%20etkinle%C5%9Ftirilsin%20mi?%22,%22informationalModalMessageBody%22:%22%C3%96nizlemelerin%20g%C3%B6sterilmesi%20Google'%C4%B1n%20(YouTube'un%20sahibi)%20cihaz%C4%B1n%C4%B1z%C4%B1n%20baz%C4%B1%20bilgilerini%20g%C3%B6rmesine%20izin%20verir,%20ancak%20yine%20de%20videoyu%20oynatmaktan%20daha%20%C3%B6zeldir.%22,%22informationalModalConfirmButtonText%22:%22T%C3%BCm%20%C3%96nizlemeleri%20Etkinle%C5%9Ftir%22,%22informationalModalRejectButtonText%22:%22Hay%C4%B1r%20Te%C5%9Fekk%C3%BCrler%22,%22buttonTextUnblockVideo%22:%22YouTube%20Videosunun%20Engelini%20Kald%C4%B1r%22,%22infoTitleUnblockVideo%22:%22DuckDuckGo,%20Google'%C4%B1n%20sizi%20izlemesini%20%C3%B6nlemek%20i%C3%A7in%20bu%20YouTube%20videosunu%20engelledi%22,%22infoTextUnblockVideo%22:%22Sayfa%20y%C3%BCklendi%C4%9Finde%20Google'%C4%B1n%20(YouTube'un%20sahibi)%20sizi%20izlemesini%20engelledik.%20Bu%20videonun%20engelini%20kald%C4%B1r%C4%B1rsan%C4%B1z,%20Google%20etkinli%C4%9Finizi%20%C3%B6%C4%9Frenecektir.%22,%22infoPreviewToggleText%22:%22Ek%20gizlilik%20i%C3%A7in%20%C3%B6nizlemeler%20devre%20d%C4%B1%C5%9F%C4%B1%20b%C4%B1rak%C4%B1ld%C4%B1%22,%22infoPreviewToggleEnabledText%22:%22%C3%96nizlemeler%20etkinle%C5%9Ftirildi%22,%22infoPreviewToggleEnabledDuckDuckGoText%22:%22DuckDuckGo'da%20YouTube%20%C3%B6nizlemeleri%20etkinle%C5%9Ftirildi.%22,%22infoPreviewInfoText%22:%22DuckDuckGo%20Yerle%C5%9Fik%20Sosyal%20Medya%20Korumas%C4%B1%20hakk%C4%B1nda%20%3Ca%20href=%5C%5C%5C%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%5C%5C%5C%22%3Edaha%20fazla%20bilgi%20edinin%3C/a%3E%22%7D%7D%7D%60;%0A%0A%20%20%20%20/*********************************************************%0A%20%20%20%20%20*%20%20Style%20Definitions%0A%20%20%20%20%20*********************************************************/%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Get%20CSS%20style%20defintions%20for%20CTL,%20using%20the%20provided%20AssetConfig%20for%20any%20non-embedded%20assets%0A%20%20%20%20%20*%20(e.g.%20fonts.)%0A%20%20%20%20%20*%20@param%20%7Bimport('../../content-feature.js').AssetConfig%7D%20%5Bassets%5D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20getStyles(assets)%20%7B%0A%20%20%20%20%20%20%20%20let%20fontStyle%20=%20'';%0A%20%20%20%20%20%20%20%20let%20regularFontFamily%20=%0A%20%20%20%20%20%20%20%20%20%20%20%20%22system,%20-apple-system,%20system-ui,%20BlinkMacSystemFont,%20'Segoe%20UI',%20Roboto,%20Helvetica,%20Arial,%20sans-serif,%20'Apple%20Color%20Emoji',%20'Segoe%20UI%20Emoji',%20'Segoe%20UI%20Symbol'%22;%0A%20%20%20%20%20%20%20%20let%20boldFontFamily%20=%20regularFontFamily;%0A%20%20%20%20%20%20%20%20if%20(assets?.regularFontUrl%20&&%20assets?.boldFontUrl)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20fontStyle%20=%20%60%0A%20%20%20%20%20%20%20%20@font-face%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-family:%20DuckDuckGoPrivacyEssentials;%0A%20%20%20%20%20%20%20%20%20%20%20%20src:%20url($%7Bassets.regularFontUrl%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20@font-face%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-family:%20DuckDuckGoPrivacyEssentialsBold;%0A%20%20%20%20%20%20%20%20%20%20%20%20font-weight:%20bold;%0A%20%20%20%20%20%20%20%20%20%20%20%20src:%20url($%7Bassets.boldFontUrl%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20regularFontFamily%20=%20'DuckDuckGoPrivacyEssentials';%0A%20%20%20%20%20%20%20%20%20%20%20%20boldFontFamily%20=%20'DuckDuckGoPrivacyEssentialsBold';%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20fontStyle,%0A%20%20%20%20%20%20%20%20%20%20%20%20darkMode:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20background:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20#111111;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20textFont:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20rgba(255,%20255,%20255,%200.9);%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonFont:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20#111111;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20linkFont:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20#7295F6;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackground:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20#5784FF;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackgroundHover:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20#557FF3;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackgroundPress:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20#3969EF;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20toggleButtonText:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20#EEEEEE;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20toggleButtonBgState:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20active:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20background:%20#5784FF;%0A%20%20%20%20%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inactive:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20background-color:%20#666666;%0A%20%20%20%20%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20lightMode:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20background:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20#FFFFFF;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20textFont:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20#222222;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonFont:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20#FFFFFF;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20linkFont:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20#3969EF;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackground:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20#3969EF;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackgroundHover:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20#2B55CA;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackgroundPress:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20#1E42A4;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20toggleButtonText:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20#666666;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20toggleButtonBgState:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20active:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20background:%20#3969EF;%0A%20%20%20%20%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inactive:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20background-color:%20#666666;%0A%20%20%20%20%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20loginMode:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackground:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20#666666;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonFont:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20#FFFFFF;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20cancelMode:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackground:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20rgba(34,%2034,%2034,%200.1);%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonFont:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20color:%20#222222;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackgroundHover:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20rgba(0,%200,%200,%200.12);%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonBackgroundPress:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20background:%20rgba(0,%200,%200,%200.18);%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20button:%20%60%0A%20%20%20%20%20%20%20%20border-radius:%208px;%0A%0A%20%20%20%20%20%20%20%20padding:%2011px%2022px;%0A%20%20%20%20%20%20%20%20font-weight:%20bold;%0A%20%20%20%20%20%20%20%20margin:%200px%20auto;%0A%20%20%20%20%20%20%20%20border-color:%20#3969EF;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%0A%20%20%20%20%20%20%20%20font-family:%20$%7BboldFontFamily%7D;%0A%20%20%20%20%20%20%20%20font-size:%2014px;%0A%0A%20%20%20%20%20%20%20%20position:%20relative;%0A%20%20%20%20%20%20%20%20cursor:%20pointer;%0A%20%20%20%20%20%20%20%20box-shadow:%20none;%0A%20%20%20%20%20%20%20%20z-index:%202147483646;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20circle:%20%60%0A%20%20%20%20%20%20%20%20border-radius:%2050%25;%0A%20%20%20%20%20%20%20%20width:%2018px;%0A%20%20%20%20%20%20%20%20height:%2018px;%0A%20%20%20%20%20%20%20%20background:%20#E0E0E0;%0A%20%20%20%20%20%20%20%20border:%201px%20solid%20#E0E0E0;%0A%20%20%20%20%20%20%20%20position:%20absolute;%0A%20%20%20%20%20%20%20%20top:%20-8px;%0A%20%20%20%20%20%20%20%20right:%20-8px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20loginIcon:%20%60%0A%20%20%20%20%20%20%20%20position:%20absolute;%0A%20%20%20%20%20%20%20%20top:%20-13px;%0A%20%20%20%20%20%20%20%20right:%20-10px;%0A%20%20%20%20%20%20%20%20height:%2028px;%0A%20%20%20%20%20%20%20%20width:%2028px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20rectangle:%20%60%0A%20%20%20%20%20%20%20%20width:%2012px;%0A%20%20%20%20%20%20%20%20height:%203px;%0A%20%20%20%20%20%20%20%20background:%20#666666;%0A%20%20%20%20%20%20%20%20position:%20relative;%0A%20%20%20%20%20%20%20%20top:%2042.5%25;%0A%20%20%20%20%20%20%20%20margin:%20auto;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20textBubble:%20%60%0A%20%20%20%20%20%20%20%20background:%20#FFFFFF;%0A%20%20%20%20%20%20%20%20border:%201px%20solid%20rgba(0,%200,%200,%200.1);%0A%20%20%20%20%20%20%20%20border-radius:%2016px;%0A%20%20%20%20%20%20%20%20box-shadow:%200px%202px%206px%20rgba(0,%200,%200,%200.12),%200px%208px%2016px%20rgba(0,%200,%200,%200.08);%0A%20%20%20%20%20%20%20%20width:%20360px;%0A%20%20%20%20%20%20%20%20margin-top:%2010px;%0A%20%20%20%20%20%20%20%20z-index:%202147483647;%0A%20%20%20%20%20%20%20%20position:%20absolute;%0A%20%20%20%20%20%20%20%20line-height:%20normal;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20textBubbleWidth:%20360,%20//%20Should%20match%20the%20width%20rule%20in%20textBubble%0A%20%20%20%20%20%20%20%20%20%20%20%20textBubbleLeftShift:%20100,%20//%20Should%20match%20the%20CSS%20left:%20rule%20in%20textBubble%0A%20%20%20%20%20%20%20%20%20%20%20%20textArrow:%20%60%0A%20%20%20%20%20%20%20%20display:%20inline-block;%0A%20%20%20%20%20%20%20%20background:%20#FFFFFF;%0A%20%20%20%20%20%20%20%20border:%20solid%20rgba(0,%200,%200,%200.1);%0A%20%20%20%20%20%20%20%20border-width:%200%201px%201px%200;%0A%20%20%20%20%20%20%20%20padding:%205px;%0A%20%20%20%20%20%20%20%20transform:%20rotate(-135deg);%0A%20%20%20%20%20%20%20%20-webkit-transform:%20rotate(-135deg);%0A%20%20%20%20%20%20%20%20position:%20relative;%0A%20%20%20%20%20%20%20%20top:%20-9px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20arrowDefaultLocationPercent:%2050,%0A%20%20%20%20%20%20%20%20%20%20%20%20hoverTextTitle:%20%60%0A%20%20%20%20%20%20%20%20padding:%200px%2012px%2012px;%0A%20%20%20%20%20%20%20%20margin-top:%20-5px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20hoverTextBody:%20%60%0A%20%20%20%20%20%20%20%20font-family:%20$%7BregularFontFamily%7D;%0A%20%20%20%20%20%20%20%20font-size:%2014px;%0A%20%20%20%20%20%20%20%20line-height:%2021px;%0A%20%20%20%20%20%20%20%20margin:%20auto;%0A%20%20%20%20%20%20%20%20padding:%2017px;%0A%20%20%20%20%20%20%20%20text-align:%20left;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20hoverContainer:%20%60%0A%20%20%20%20%20%20%20%20padding-bottom:%2010px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20buttonTextContainer:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20flex-direction:%20row;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%20%20%20%20margin:%200;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20headerRow:%20%60%0A%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20block:%20%60%0A%20%20%20%20%20%20%20%20box-sizing:%20border-box;%0A%20%20%20%20%20%20%20%20border:%201px%20solid%20rgba(0,0,0,0.1);%0A%20%20%20%20%20%20%20%20border-radius:%2012px;%0A%20%20%20%20%20%20%20%20max-width:%20600px;%0A%20%20%20%20%20%20%20%20min-height:%20300px;%0A%20%20%20%20%20%20%20%20margin:%20auto;%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20flex-direction:%20column;%0A%0A%20%20%20%20%20%20%20%20font-family:%20$%7BregularFontFamily%7D;%0A%20%20%20%20%20%20%20%20line-height:%201;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubeDialogBlock:%20%60%0A%20%20%20%20%20%20%20%20height:%20calc(100%25%20-%2030px);%0A%20%20%20%20%20%20%20%20max-width:%20initial;%0A%20%20%20%20%20%20%20%20min-height:%20initial;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20imgRow:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20flex-direction:%20column;%0A%20%20%20%20%20%20%20%20margin:%2020px%200px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20content:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20flex-direction:%20column;%0A%20%20%20%20%20%20%20%20padding:%2016px%200;%0A%20%20%20%20%20%20%20%20flex:%201%201%201px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20feedbackLink:%20%60%0A%20%20%20%20%20%20%20%20font-family:%20$%7BregularFontFamily%7D;%0A%20%20%20%20%20%20%20%20font-style:%20normal;%0A%20%20%20%20%20%20%20%20font-weight:%20400;%0A%20%20%20%20%20%20%20%20font-size:%2012px;%0A%20%20%20%20%20%20%20%20line-height:%2012px;%0A%20%20%20%20%20%20%20%20color:%20#ABABAB;%0A%20%20%20%20%20%20%20%20text-decoration:%20none;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20feedbackRow:%20%60%0A%20%20%20%20%20%20%20%20height:%2030px;%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20justify-content:%20flex-end;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20titleBox:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20padding:%2012px;%0A%20%20%20%20%20%20%20%20max-height:%2044px;%0A%20%20%20%20%20%20%20%20border-bottom:%201px%20solid;%0A%20%20%20%20%20%20%20%20border-color:%20rgba(196,%20196,%20196,%200.3);%0A%20%20%20%20%20%20%20%20margin:%200;%0A%20%20%20%20%20%20%20%20margin-bottom:%204px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20title:%20%60%0A%20%20%20%20%20%20%20%20font-family:%20$%7BregularFontFamily%7D;%0A%20%20%20%20%20%20%20%20line-height:%201.4;%0A%20%20%20%20%20%20%20%20font-size:%2014px;%0A%20%20%20%20%20%20%20%20margin:%20auto%2010px;%0A%20%20%20%20%20%20%20%20flex-basis:%20100%25;%0A%20%20%20%20%20%20%20%20height:%201.4em;%0A%20%20%20%20%20%20%20%20flex-wrap:%20wrap;%0A%20%20%20%20%20%20%20%20overflow:%20hidden;%0A%20%20%20%20%20%20%20%20text-align:%20left;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20buttonRow:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20height:%20100%25%0A%20%20%20%20%20%20%20%20flex-direction:%20row;%0A%20%20%20%20%20%20%20%20margin:%2020px%20auto%200px;%0A%20%20%20%20%20%20%20%20height:%20100%25;%0A%20%20%20%20%20%20%20%20align-items:%20flex-start;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20modalContentTitle:%20%60%0A%20%20%20%20%20%20%20%20font-family:%20$%7BboldFontFamily%7D;%0A%20%20%20%20%20%20%20%20font-size:%2017px;%0A%20%20%20%20%20%20%20%20font-weight:%20bold;%0A%20%20%20%20%20%20%20%20line-height:%2021px;%0A%20%20%20%20%20%20%20%20margin:%2010px%20auto;%0A%20%20%20%20%20%20%20%20text-align:%20center;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%20%20%20%20padding:%200px%2032px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20modalContentText:%20%60%0A%20%20%20%20%20%20%20%20font-family:%20$%7BregularFontFamily%7D;%0A%20%20%20%20%20%20%20%20font-size:%2014px;%0A%20%20%20%20%20%20%20%20line-height:%2021px;%0A%20%20%20%20%20%20%20%20margin:%200px%20auto%2014px;%0A%20%20%20%20%20%20%20%20text-align:%20center;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20modalButtonRow:%20%60%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%20%20%20%20margin:%20auto;%0A%20%20%20%20%20%20%20%20width:%20100%25;%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20flex-direction:%20column;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20modalButton:%20%60%0A%20%20%20%20%20%20%20%20width:%20100%25;%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20justify-content:%20center;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20modalIcon:%20%60%0A%20%20%20%20%20%20%20%20display:%20block;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20contentTitle:%20%60%0A%20%20%20%20%20%20%20%20font-family:%20$%7BboldFontFamily%7D;%0A%20%20%20%20%20%20%20%20font-size:%2017px;%0A%20%20%20%20%20%20%20%20font-weight:%20bold;%0A%20%20%20%20%20%20%20%20margin:%2020px%20auto%2010px;%0A%20%20%20%20%20%20%20%20padding:%200px%2030px;%0A%20%20%20%20%20%20%20%20text-align:%20center;%0A%20%20%20%20%20%20%20%20margin-top:%20auto;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20contentText:%20%60%0A%20%20%20%20%20%20%20%20font-family:%20$%7BregularFontFamily%7D;%0A%20%20%20%20%20%20%20%20font-size:%2014px;%0A%20%20%20%20%20%20%20%20line-height:%2021px;%0A%20%20%20%20%20%20%20%20padding:%200px%2040px;%0A%20%20%20%20%20%20%20%20text-align:%20center;%0A%20%20%20%20%20%20%20%20margin:%200%20auto%20auto;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20icon:%20%60%0A%20%20%20%20%20%20%20%20height:%2080px;%0A%20%20%20%20%20%20%20%20width:%2080px;%0A%20%20%20%20%20%20%20%20margin:%20auto;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20closeIcon:%20%60%0A%20%20%20%20%20%20%20%20height:%2012px;%0A%20%20%20%20%20%20%20%20width:%2012px;%0A%20%20%20%20%20%20%20%20margin:%20auto;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20closeButton:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20justify-content:%20center;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%20%20%20%20min-width:%2020px;%0A%20%20%20%20%20%20%20%20height:%2021px;%0A%20%20%20%20%20%20%20%20border:%200;%0A%20%20%20%20%20%20%20%20background:%20transparent;%0A%20%20%20%20%20%20%20%20cursor:%20pointer;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20logo:%20%60%0A%20%20%20%20%20%20%20%20flex-basis:%200%25;%0A%20%20%20%20%20%20%20%20min-width:%2020px;%0A%20%20%20%20%20%20%20%20height:%2021px;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%20%20%20%20margin:%200;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20logoImg:%20%60%0A%20%20%20%20%20%20%20%20height:%2021px;%0A%20%20%20%20%20%20%20%20width:%2021px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20loadingImg:%20%60%0A%20%20%20%20%20%20%20%20display:%20block;%0A%20%20%20%20%20%20%20%20margin:%200px%208px%200px%200px;%0A%20%20%20%20%20%20%20%20height:%2014px;%0A%20%20%20%20%20%20%20%20width:%2014px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20modal:%20%60%0A%20%20%20%20%20%20%20%20width:%20340px;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%20%20%20%20margin:%20auto;%0A%20%20%20%20%20%20%20%20background-color:%20#FFFFFF;%0A%20%20%20%20%20%20%20%20position:%20absolute;%0A%20%20%20%20%20%20%20%20top:%2050%25;%0A%20%20%20%20%20%20%20%20left:%2050%25;%0A%20%20%20%20%20%20%20%20transform:%20translate(-50%25,%20-50%25);%0A%20%20%20%20%20%20%20%20display:%20block;%0A%20%20%20%20%20%20%20%20box-shadow:%200px%201px%203px%20rgba(0,%200,%200,%200.08),%200px%202px%204px%20rgba(0,%200,%200,%200.1);%0A%20%20%20%20%20%20%20%20border-radius:%2012px;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20modalContent:%20%60%0A%20%20%20%20%20%20%20%20padding:%2024px;%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20flex-direction:%20column;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%20%20%20%20margin:%200;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20overlay:%20%60%0A%20%20%20%20%20%20%20%20height:%20100%25;%0A%20%20%20%20%20%20%20%20width:%20100%25;%0A%20%20%20%20%20%20%20%20background-color:%20#666666;%0A%20%20%20%20%20%20%20%20opacity:%20.5;%0A%20%20%20%20%20%20%20%20display:%20block;%0A%20%20%20%20%20%20%20%20position:%20fixed;%0A%20%20%20%20%20%20%20%20top:%200;%0A%20%20%20%20%20%20%20%20right:%200;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%20%20%20%20margin:%200;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20modalContainer:%20%60%0A%20%20%20%20%20%20%20%20height:%20100vh;%0A%20%20%20%20%20%20%20%20width:%20100vw;%0A%20%20%20%20%20%20%20%20box-sizing:%20border-box;%0A%20%20%20%20%20%20%20%20z-index:%202147483647;%0A%20%20%20%20%20%20%20%20display:%20block;%0A%20%20%20%20%20%20%20%20position:%20fixed;%0A%20%20%20%20%20%20%20%20border:%200;%0A%20%20%20%20%20%20%20%20margin:%200;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20headerLinkContainer:%20%60%0A%20%20%20%20%20%20%20%20flex-basis:%20100%25;%0A%20%20%20%20%20%20%20%20display:%20grid;%0A%20%20%20%20%20%20%20%20justify-content:%20flex-end;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20headerLink:%20%60%0A%20%20%20%20%20%20%20%20line-height:%201.4;%0A%20%20%20%20%20%20%20%20font-size:%2014px;%0A%20%20%20%20%20%20%20%20font-weight:%20bold;%0A%20%20%20%20%20%20%20%20font-family:%20$%7BboldFontFamily%7D;%0A%20%20%20%20%20%20%20%20text-decoration:%20none;%0A%20%20%20%20%20%20%20%20cursor:%20pointer;%0A%20%20%20%20%20%20%20%20min-width:%20100px;%0A%20%20%20%20%20%20%20%20text-align:%20end;%0A%20%20%20%20%20%20%20%20float:%20right;%0A%20%20%20%20%20%20%20%20display:%20none;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20generalLink:%20%60%0A%20%20%20%20%20%20%20%20line-height:%201.4;%0A%20%20%20%20%20%20%20%20font-size:%2014px;%0A%20%20%20%20%20%20%20%20font-weight:%20bold;%0A%20%20%20%20%20%20%20%20font-family:%20$%7BboldFontFamily%7D;%0A%20%20%20%20%20%20%20%20cursor:%20pointer;%0A%20%20%20%20%20%20%20%20text-decoration:%20none;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20wrapperDiv:%20%60%0A%20%20%20%20%20%20%20%20display:%20inline-block;%0A%20%20%20%20%20%20%20%20border:%200;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%20%20%20%20margin:%200;%0A%20%20%20%20%20%20%20%20max-width:%20600px;%0A%20%20%20%20%20%20%20%20min-height:%20300px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20toggleButtonWrapper:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%20%20%20%20cursor:%20pointer;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20toggleButton:%20%60%0A%20%20%20%20%20%20%20%20cursor:%20pointer;%0A%20%20%20%20%20%20%20%20position:%20relative;%0A%20%20%20%20%20%20%20%20width:%2030px;%0A%20%20%20%20%20%20%20%20height:%2016px;%0A%20%20%20%20%20%20%20%20margin-top:%20-3px;%0A%20%20%20%20%20%20%20%20margin:%200;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%20%20%20%20border:%20none;%0A%20%20%20%20%20%20%20%20background-color:%20transparent;%0A%20%20%20%20%20%20%20%20text-align:%20left;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20toggleButtonBg:%20%60%0A%20%20%20%20%20%20%20%20right:%200;%0A%20%20%20%20%20%20%20%20width:%2030px;%0A%20%20%20%20%20%20%20%20height:%2016px;%0A%20%20%20%20%20%20%20%20overflow:%20visible;%0A%20%20%20%20%20%20%20%20border-radius:%2010px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20toggleButtonText:%20%60%0A%20%20%20%20%20%20%20%20display:%20inline-block;%0A%20%20%20%20%20%20%20%20margin:%200%200%200%207px;%0A%20%20%20%20%20%20%20%20padding:%200;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20toggleButtonKnob:%20%60%0A%20%20%20%20%20%20%20%20position:%20absolute;%0A%20%20%20%20%20%20%20%20display:%20inline-block;%0A%20%20%20%20%20%20%20%20width:%2014px;%0A%20%20%20%20%20%20%20%20height:%2014px;%0A%20%20%20%20%20%20%20%20border-radius:%2010px;%0A%20%20%20%20%20%20%20%20background-color:%20#ffffff;%0A%20%20%20%20%20%20%20%20margin-top:%201px;%0A%20%20%20%20%20%20%20%20top:%20calc(50%25%20-%2014px/2%20-%201px);%0A%20%20%20%20%20%20%20%20box-shadow:%200px%200px%201px%20rgba(0,%200,%200,%200.05),%200px%201px%201px%20rgba(0,%200,%200,%200.1);%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20toggleButtonKnobState:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20active:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20right:%201px;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inactive:%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20left:%201px;%0A%20%20%20%20%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20placeholderWrapperDiv:%20%60%0A%20%20%20%20%20%20%20%20position:%20relative;%0A%20%20%20%20%20%20%20%20overflow:%20hidden;%0A%20%20%20%20%20%20%20%20border-radius:%2012px;%0A%20%20%20%20%20%20%20%20box-sizing:%20border-box;%0A%20%20%20%20%20%20%20%20max-width:%20initial;%0A%20%20%20%20%20%20%20%20min-width:%20380px;%0A%20%20%20%20%20%20%20%20min-height:%20300px;%0A%20%20%20%20%20%20%20%20margin:%20auto;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubeWrapperDiv:%20%60%0A%20%20%20%20%20%20%20%20position:%20relative;%0A%20%20%20%20%20%20%20%20overflow:%20hidden;%0A%20%20%20%20%20%20%20%20max-width:%20initial;%0A%20%20%20%20%20%20%20%20min-width:%20380px;%0A%20%20%20%20%20%20%20%20min-height:%20300px;%0A%20%20%20%20%20%20%20%20height:%20100%25;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubeDialogDiv:%20%60%0A%20%20%20%20%20%20%20%20position:%20relative;%0A%20%20%20%20%20%20%20%20overflow:%20hidden;%0A%20%20%20%20%20%20%20%20border-radius:%2012px;%0A%20%20%20%20%20%20%20%20max-width:%20initial;%0A%20%20%20%20%20%20%20%20min-height:%20initial;%0A%20%20%20%20%20%20%20%20height:%20calc(100%25%20-%2030px);%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubeDialogBottomRow:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20flex-direction:%20column;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%20%20%20%20justify-content:%20flex-end;%0A%20%20%20%20%20%20%20%20margin-top:%20auto;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubePlaceholder:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20flex-direction:%20column;%0A%20%20%20%20%20%20%20%20justify-content:%20flex-start;%0A%20%20%20%20%20%20%20%20position:%20relative;%0A%20%20%20%20%20%20%20%20width:%20100%25;%0A%20%20%20%20%20%20%20%20height:%20100%25;%0A%20%20%20%20%20%20%20%20background:%20rgba(45,%2045,%2045,%200.8);%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubePreviewWrapperImg:%20%60%0A%20%20%20%20%20%20%20%20position:%20absolute;%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20justify-content:%20center;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%20%20%20%20width:%20100%25;%0A%20%20%20%20%20%20%20%20height:%20100%25;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubePreviewImg:%20%60%0A%20%20%20%20%20%20%20%20min-width:%20100%25;%0A%20%20%20%20%20%20%20%20min-height:%20100%25;%0A%20%20%20%20%20%20%20%20height:%20auto;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubeTopSection:%20%60%0A%20%20%20%20%20%20%20%20font-family:%20$%7BboldFontFamily%7D;%0A%20%20%20%20%20%20%20%20flex:%201;%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20justify-content:%20space-between;%0A%20%20%20%20%20%20%20%20position:%20relative;%0A%20%20%20%20%20%20%20%20padding:%2018px%2012px%200;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubeTitle:%20%60%0A%20%20%20%20%20%20%20%20font-size:%2014px;%0A%20%20%20%20%20%20%20%20font-weight:%20bold;%0A%20%20%20%20%20%20%20%20line-height:%2014px;%0A%20%20%20%20%20%20%20%20color:%20#FFFFFF;%0A%20%20%20%20%20%20%20%20margin:%200;%0A%20%20%20%20%20%20%20%20width:%20100%25;%0A%20%20%20%20%20%20%20%20white-space:%20nowrap;%0A%20%20%20%20%20%20%20%20overflow:%20hidden;%0A%20%20%20%20%20%20%20%20text-overflow:%20ellipsis;%0A%20%20%20%20%20%20%20%20box-sizing:%20border-box;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubePlayButtonRow:%20%60%0A%20%20%20%20%20%20%20%20flex:%202;%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%20%20%20%20justify-content:%20center;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubePlayButton:%20%60%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20justify-content:%20center;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%20%20%20%20height:%2048px;%0A%20%20%20%20%20%20%20%20width:%2080px;%0A%20%20%20%20%20%20%20%20padding:%200px%2024px;%0A%20%20%20%20%20%20%20%20border-radius:%208px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubePreviewToggleRow:%20%60%0A%20%20%20%20%20%20%20%20flex:%201;%0A%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20flex-direction:%20column;%0A%20%20%20%20%20%20%20%20justify-content:%20flex-end;%0A%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%20%20%20%20padding:%200%2012px%2018px;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubePreviewToggleText:%20%60%0A%20%20%20%20%20%20%20%20color:%20#EEEEEE;%0A%20%20%20%20%20%20%20%20font-weight:%20400;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20youTubePreviewInfoText:%20%60%0A%20%20%20%20%20%20%20%20color:%20#ABABAB;%0A%20%20%20%20%60,%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20locale%20UI%20locale%0A%20%20%20%20%20*/%0A%20%20%20%20function%20getConfig(locale)%20%7B%0A%20%20%20%20%20%20%20%20const%20allLocales%20=%20JSON.parse(localesJSON);%0A%20%20%20%20%20%20%20%20const%20localeStrings%20=%20allLocales%5Blocale%5D%20%7C%7C%20allLocales.en;%0A%0A%20%20%20%20%20%20%20%20const%20fbStrings%20=%20localeStrings%5B'facebook.json'%5D;%0A%20%20%20%20%20%20%20%20const%20ytStrings%20=%20localeStrings%5B'youtube.json'%5D;%0A%20%20%20%20%20%20%20%20const%20sharedStrings%20=%20localeStrings%5B'shared.json'%5D;%0A%0A%20%20%20%20%20%20%20%20const%20config%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20'Facebook,%20Inc.':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20informationalModal:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20icon:%20blockedFBLogo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20messageTitle:%20fbStrings.informationalModalMessageTitle,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20messageBody:%20fbStrings.informationalModalMessageBody,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20confirmButtonText:%20fbStrings.informationalModalConfirmButtonText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20rejectButtonText:%20fbStrings.informationalModalRejectButtonText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20elementData:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Like%20Button':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-like'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'blank',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Button%20iFrames':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/plugins/like.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/v2.0/plugins/like.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/plugins/share_button.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/v2.0/plugins/share_button.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'blank',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Save%20Button':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-save'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'blank',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Share%20Button':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-share-button'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'blank',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Page%20iFrames':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/plugins/page.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/v2.0/plugins/page.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'originalElement',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Page%20Div':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-page'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'iFrame',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20targetURL:%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'https://www.facebook.com/plugins/page.php?href=data-href&tabs=data-tabs&width=data-width&height=data-height',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20urlDataAttributesToPreserve:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-href':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20required:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-tabs':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'timeline',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-height':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'500',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-width':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'500',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20styleDataAttributes:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20'data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unit:%20'px',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20height:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20'data-height',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unit:%20'px',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Comment%20iFrames':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/plugins/comment_embed.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/v2.0/plugins/comment_embed.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockComment,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockComment,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'originalElement',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Comments':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-comments',%20'fb%5C%5C:comments'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockComments,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockComments,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'allowFull',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20targetURL:%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'https://www.facebook.com/v9.0/plugins/comments.php?href=data-href&numposts=data-numposts&sdk=joey&version=v9.0&width=data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20urlDataAttributesToPreserve:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-href':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20required:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-numposts':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%2010,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-width':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'500',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Embedded%20Comment%20Div':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-comment-embed'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockComment,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockComment,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'iFrame',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20targetURL:%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'https://www.facebook.com/v9.0/plugins/comment_embed.php?href=data-href&sdk=joey&width=data-width&include_parent=data-include-parent',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20urlDataAttributesToPreserve:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-href':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20required:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-width':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'500',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-include-parent':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'false',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20styleDataAttributes:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20'data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unit:%20'px',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Post%20iFrames':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/plugins/post.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/v2.0/plugins/post.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockPost,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockPost,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'originalElement',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Posts%20Div':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-post'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockPost,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockPost,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'allowFull',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20targetURL:%20'https://www.facebook.com/v9.0/plugins/post.php?href=data-href&sdk=joey&show_text=true&width=data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20urlDataAttributesToPreserve:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-href':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20required:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-width':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'500',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20styleDataAttributes:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20'data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unit:%20'px',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20height:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20'data-height',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unit:%20'px',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fallbackAttribute:%20'data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Video%20iFrames':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/plugins/video.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/v2.0/plugins/video.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockVideo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockVideo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'originalElement',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Video':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-video'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockVideo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockVideo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'iFrame',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20targetURL:%20'https://www.facebook.com/plugins/video.php?href=data-href&show_text=true&width=data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20urlDataAttributesToPreserve:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-href':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20required:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-width':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'500',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20styleDataAttributes:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20'data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unit:%20'px',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20height:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20'data-height',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unit:%20'px',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fallbackAttribute:%20'data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Group%20iFrames':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/plugins/group.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.facebook.com/v2.0/plugins/group.php'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'originalElement',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Group':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-group'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'dialog',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.buttonTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20fbStrings.infoTitleUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20fbStrings.infoTextUnblockContent,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'iFrame',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20targetURL:%20'https://www.facebook.com/plugins/group.php?href=data-href&width=data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20urlDataAttributesToPreserve:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-href':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20required:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-width':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'500',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20styleDataAttributes:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20'data-width',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unit:%20'px',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'FB%20Login%20Button':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B'.fb-login-button'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'loginButton',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20icon:%20blockedFBLogo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20fbStrings.loginButtonText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonTextUnblockLogin:%20fbStrings.buttonTextUnblockLogin,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20popupBodyText:%20fbStrings.loginBodyText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'allowFull',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20targetURL:%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'https://www.facebook.com/v9.0/plugins/login_button.php?app_id=app_id_replace&auto_logout_link=false&button_type=continue_with&sdk=joey&size=large&use_continue_as=false&width=',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20urlDataAttributesToPreserve:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-href':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20required:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'data-width':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'500',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20app_id_replace:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%20'null',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20Youtube:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20informationalModal:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20icon:%20blockedYTVideo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20messageTitle:%20ytStrings.informationalModalMessageTitle,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20messageBody:%20ytStrings.informationalModalMessageBody,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20confirmButtonText:%20ytStrings.informationalModalConfirmButtonText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20rejectButtonText:%20ytStrings.informationalModalRejectButtonText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20elementData:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'YouTube%20embedded%20video':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//youtube.com/embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//youtube-nocookie.com/embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.youtube.com/embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.youtube-nocookie.com/embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bdata-src*='//youtube.com/embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bdata-src*='//youtube-nocookie.com/embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bdata-src*='//www.youtube.com/embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bdata-src*='//www.youtube-nocookie.com/embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'youtube-video',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buttonText:%20ytStrings.buttonTextUnblockVideo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoTitle:%20ytStrings.infoTitleUnblockVideo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20infoText:%20ytStrings.infoTextUnblockVideo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20previewToggleText:%20ytStrings.infoPreviewToggleText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20placeholder:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20previewToggleEnabledText:%20ytStrings.infoPreviewToggleEnabledText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20previewInfoText:%20ytStrings.infoPreviewInfoText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20previewToggleEnabledDuckDuckGoText:%20ytStrings.infoPreviewToggleEnabledText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20videoPlayIcon:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lightMode:%20videoPlayLight,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20darkMode:%20videoPlayDark,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickAction:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'youtube-video',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'YouTube%20embedded%20subscription%20button':%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectors:%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//youtube.com/subscribe_embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//youtube-nocookie.com/subscribe_embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.youtube.com/subscribe_embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bsrc*='//www.youtube-nocookie.com/subscribe_embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bdata-src*='//youtube.com/subscribe_embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bdata-src*='//youtube-nocookie.com/subscribe_embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bdata-src*='//www.youtube.com/subscribe_embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22iframe%5Bdata-src*='//www.youtube-nocookie.com/subscribe_embed'%5D%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type:%20'blank',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20return%20%7B%20config,%20sharedStrings%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20The%20following%20code%20is%20originally%20from%20https://github.com/mozilla-extensions/secure-proxy/blob/db4d1b0e2bfe0abae416bf04241916f9e4768fd2/src/commons/template.js%0A%20%20%20%20%20*/%0A%20%20%20%20class%20Template%20%7B%0A%20%20%20%20%20%20%20%20constructor(strings,%20values)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.values%20=%20values;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.strings%20=%20strings;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Escapes%20any%20occurrences%20of%20&,%20%22,%20%3C,%20%3E%20or%20/%20with%20XML%20entities.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20str%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20The%20string%20to%20escape.%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7Bstring%7D%20The%20escaped%20string.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20escapeXML(str)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20replacements%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'&':%20'&',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'%22':%20'"',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22'%22:%20''',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'%3C':%20'<',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'%3E':%20'>',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'/':%20'/',%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20String(str).replace(/%5B&%22'%3C%3E/%5D/g,%20(m)%20=%3E%20replacements%5Bm%5D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20potentiallyEscape(value)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20value%20===%20'object')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(value%20instanceof%20Array)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20value.map((val)%20=%3E%20this.potentiallyEscape(val)).join('');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20we%20are%20an%20escaped%20template%20let%20join%20call%20toString%20on%20it%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(value%20instanceof%20Template)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20value;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('Unknown%20object%20to%20escape');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.escapeXML(value);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20toString()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20result%20=%20%5B%5D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20%5Bi,%20string%5D%20of%20this.strings.entries())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result.push(string);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(i%20%3C%20this.values.length)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result.push(this.potentiallyEscape(this.values%5Bi%5D));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20result.join('');%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20html(strings,%20...values)%20%7B%0A%20%20%20%20%20%20%20%20return%20new%20Template(strings,%20values);%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20cssVars%20=%20%22:host%20%7B%5Cn%20%20%20%20/*%20Color%20palette%20*/%5Cn%20%20%20%20--ddg-shade-06:%20rgba(0,%200,%200,%200.06);%5Cn%20%20%20%20--ddg-shade-12:%20rgba(0,%200,%200,%200.12);%5Cn%20%20%20%20--ddg-shade-18:%20rgba(0,%200,%200,%200.18);%5Cn%20%20%20%20--ddg-shade-36:%20rgba(0,%200,%200,%200.36);%5Cn%20%20%20%20--ddg-shade-84:%20rgba(0,%200,%200,%200.84);%5Cn%20%20%20%20--ddg-tint-12:%20rgba(255,%20255,%20255,%200.12);%5Cn%20%20%20%20--ddg-tint-18:%20rgba(255,%20255,%20255,%200.18);%5Cn%20%20%20%20--ddg-tint-24:%20rgba(255,%20255,%20255,%200.24);%5Cn%20%20%20%20--ddg-tint-84:%20rgba(255,%20255,%20255,%200.84);%5Cn%20%20%20%20/*%20Tokens%20*/%5Cn%20%20%20%20--ddg-color-primary:%20#3969ef;%5Cn%20%20%20%20--ddg-color-bg-01:%20#ffffff;%5Cn%20%20%20%20--ddg-color-bg-02:%20#ababab;%5Cn%20%20%20%20--ddg-color-border:%20var(--ddg-shade-12);%5Cn%20%20%20%20--ddg-color-txt:%20var(--ddg-shade-84);%5Cn%20%20%20%20--ddg-color-txt-link-02:%20#ababab;%5Cn%7D%5Cn@media%20(prefers-color-scheme:%20dark)%20%7B%5Cn%20%20%20%20:host%20%7B%5Cn%20%20%20%20%20%20%20%20--ddg-color-primary:%20#7295f6;%5Cn%20%20%20%20%20%20%20%20--ddg-color-bg-01:%20#222222;%5Cn%20%20%20%20%20%20%20%20--ddg-color-bg-02:%20#444444;%5Cn%20%20%20%20%20%20%20%20--ddg-color-border:%20var(--ddg-tint-12);%5Cn%20%20%20%20%20%20%20%20--ddg-color-txt:%20var(--ddg-tint-84);%5Cn%20%20%20%20%7D%5Cn%7D%5Cn%5Cn/*%20SHARED%20STYLES%20*/%5Cn/*%20Text%20Link%20*/%5Cn.ddg-text-link%20%7B%5Cn%20%20%20%20line-height:%201.4;%5Cn%20%20%20%20font-size:%2014px;%5Cn%20%20%20%20font-weight:%20700;%5Cn%20%20%20%20cursor:%20pointer;%5Cn%20%20%20%20text-decoration:%20none;%5Cn%20%20%20%20color:%20var(--ddg-color-primary);%5Cn%7D%5Cn%5Cn/*%20Button%20*/%5Cn.DuckDuckGoButton%20%7B%5Cn%20%20%20%20border-radius:%208px;%5Cn%20%20%20%20padding:%208px%2016px;%5Cn%20%20%20%20border-color:%20var(--ddg-color-primary);%5Cn%20%20%20%20border:%20none;%5Cn%20%20%20%20min-height:%2036px;%5Cn%5Cn%20%20%20%20position:%20relative;%5Cn%20%20%20%20cursor:%20pointer;%5Cn%20%20%20%20box-shadow:%20none;%5Cn%20%20%20%20z-index:%202147483646;%5Cn%7D%5Cn.DuckDuckGoButton%20%3E%20div%20%7B%5Cn%20%20%20%20display:%20flex;%5Cn%20%20%20%20flex-direction:%20row;%5Cn%20%20%20%20align-items:%20center;%5Cn%20%20%20%20border:%20none;%5Cn%20%20%20%20padding:%200;%5Cn%20%20%20%20margin:%200;%5Cn%7D%5Cn.DuckDuckGoButton,%5Cn.DuckDuckGoButton%20%3E%20div%20%7B%5Cn%20%20%20%20font-size:%2014px;%5Cn%20%20%20%20font-family:%20DuckDuckGoPrivacyEssentialsBold;%5Cn%20%20%20%20font-weight:%20600;%5Cn%7D%5Cn.DuckDuckGoButton.tertiary%20%7B%5Cn%20%20%20%20color:%20var(--ddg-color-txt);%5Cn%20%20%20%20background-color:%20transparent;%5Cn%20%20%20%20display:%20flex;%5Cn%20%20%20%20justify-content:%20center;%5Cn%20%20%20%20align-items:%20center;%5Cn%20%20%20%20border:%201px%20solid%20var(--ddg-color-border);%5Cn%20%20%20%20border-radius:%208px;%5Cn%7D%5Cn.DuckDuckGoButton.tertiary:hover%20%7B%5Cn%20%20%20%20background:%20var(--ddg-shade-06);%5Cn%20%20%20%20border-color:%20var(--ddg-shade-18);%5Cn%7D%5Cn@media%20(prefers-color-scheme:%20dark)%20%7B%5Cn%20%20%20%20.DuckDuckGoButton.tertiary:hover%20%7B%5Cn%20%20%20%20%20%20%20%20background:%20var(--ddg-tint-18);%5Cn%20%20%20%20%20%20%20%20border-color:%20var(--ddg-tint-24);%5Cn%20%20%20%20%7D%5Cn%7D%5Cn.DuckDuckGoButton.tertiary:active%20%7B%5Cn%20%20%20%20background:%20var(--ddg-shade-12);%5Cn%20%20%20%20border-color:%20var(--ddg-shade-36);%5Cn%7D%5Cn@media%20(prefers-color-scheme:%20dark)%20%7B%5Cn%20%20%20%20.DuckDuckGoButton.tertiary:active%20%7B%5Cn%20%20%20%20%20%20%20%20background:%20var(--ddg-tint-24);%5Cn%20%20%20%20%20%20%20%20border-color:%20var(--ddg-tint-24);%5Cn%20%20%20%20%7D%5Cn%7D%5Cn%22;%0A%0A%20%20%20%20var%20css$1%20=%20%22:host,%5Cn*%20%7B%5Cn%20%20%20%20font-family:%20DuckDuckGoPrivacyEssentials,%20system,%20-apple-system,%20system-ui,%20BlinkMacSystemFont,%20'Segoe%20UI',%20Roboto,%5Cn%20%20%20%20%20%20%20%20Helvetica,%20Arial,%20sans-serif,%20'Apple%20Color%20Emoji',%20'Segoe%20UI%20Emoji',%20'Segoe%20UI%20Symbol';%5Cn%20%20%20%20box-sizing:%20border-box;%5Cn%20%20%20%20font-weight:%20normal;%5Cn%20%20%20%20font-style:%20normal;%5Cn%20%20%20%20margin:%200;%5Cn%20%20%20%20padding:%200;%5Cn%20%20%20%20text-align:%20left;%5Cn%7D%5Cn%5Cn:host,%5Cn.DuckDuckGoSocialContainer%20%7B%5Cn%20%20%20%20display:%20inline-block;%5Cn%20%20%20%20border:%200;%5Cn%20%20%20%20padding:%200;%5Cn%20%20%20%20margin:%20auto;%5Cn%20%20%20%20inset:%20initial;%5Cn%20%20%20%20max-width:%20600px;%5Cn%20%20%20%20min-height:%20180px;%5Cn%7D%5Cn%5Cn/*%20SHARED%20STYLES%20*/%5Cn/*%20Toggle%20Button%20*/%5Cn.ddg-toggle-button-container%20%7B%5Cn%20%20%20%20display:%20flex;%5Cn%20%20%20%20align-items:%20center;%5Cn%20%20%20%20cursor:%20pointer;%5Cn%7D%5Cn.ddg-toggle-button%20%7B%5Cn%20%20%20%20cursor:%20pointer;%5Cn%20%20%20%20position:%20relative;%5Cn%20%20%20%20margin-top:%20-3px;%5Cn%20%20%20%20margin:%200;%5Cn%20%20%20%20padding:%200;%5Cn%20%20%20%20border:%20none;%5Cn%20%20%20%20background-color:%20transparent;%5Cn%20%20%20%20text-align:%20left;%5Cn%7D%5Cn.ddg-toggle-button,%5Cn.ddg-toggle-button.md,%5Cn.ddg-toggle-button-bg,%5Cn.ddg-toggle-button.md%20.ddg-toggle-button-bg%20%7B%5Cn%20%20%20%20width:%2032px;%5Cn%20%20%20%20height:%2016px;%5Cn%20%20%20%20border-radius:%2020px;%5Cn%7D%5Cn.ddg-toggle-button.lg,%5Cn.ddg-toggle-button.lg%20.ddg-toggle-button-bg%20%7B%5Cn%20%20%20%20width:%2056px;%5Cn%20%20%20%20height:%2034px;%5Cn%20%20%20%20border-radius:%2050px;%5Cn%7D%5Cn.ddg-toggle-button-bg%20%7B%5Cn%20%20%20%20right:%200;%5Cn%20%20%20%20overflow:%20visible;%5Cn%7D%5Cn.ddg-toggle-button.active%20.ddg-toggle-button-bg%20%7B%5Cn%20%20%20%20background:%20var(--ddg-color-primary);%5Cn%7D%5Cn.ddg-toggle-button.inactive%20.ddg-toggle-button-bg%20%7B%5Cn%20%20%20%20background:%20var(--ddg-color-bg-02);%5Cn%7D%5Cn.ddg-toggle-button-knob%20%7B%5Cn%20%20%20%20--ddg-toggle-knob-margin:%202px;%5Cn%20%20%20%20position:%20absolute;%5Cn%20%20%20%20display:%20inline-block;%5Cn%20%20%20%20border-radius:%2050%25;%5Cn%20%20%20%20background-color:%20#ffffff;%5Cn%20%20%20%20margin-top:%20var(--ddg-toggle-knob-margin);%5Cn%7D%5Cn.ddg-toggle-button-knob,%5Cn.ddg-toggle-button.md%20.ddg-toggle-button-knob%20%7B%5Cn%20%20%20%20width:%2012px;%5Cn%20%20%20%20height:%2012px;%5Cn%20%20%20%20top:%20calc(50%25%20-%2016px%20/%202);%5Cn%7D%5Cn.ddg-toggle-button.lg%20.ddg-toggle-button-knob%20%7B%5Cn%20%20%20%20--ddg-toggle-knob-margin:%204px;%5Cn%20%20%20%20width:%2026px;%5Cn%20%20%20%20height:%2026px;%5Cn%20%20%20%20top:%20calc(50%25%20-%2034px%20/%202);%5Cn%7D%5Cn.ddg-toggle-button.active%20.ddg-toggle-button-knob%20%7B%5Cn%20%20%20%20right:%20var(--ddg-toggle-knob-margin);%5Cn%7D%5Cn.ddg-toggle-button.inactive%20.ddg-toggle-button-knob%20%7B%5Cn%20%20%20%20left:%20var(--ddg-toggle-knob-margin);%5Cn%7D%5Cn.ddg-toggle-button-label%20%7B%5Cn%20%20%20%20font-size:%2014px;%5Cn%20%20%20%20line-height:%2020px;%5Cn%20%20%20%20color:%20var(--ddg-color-txt);%5Cn%20%20%20%20margin-left:%2012px;%5Cn%7D%5Cn%5Cn/*%20Styles%20for%20DDGCtlPlaceholderBlocked%20*/%5Cn.DuckDuckGoButton.ddg-ctl-unblock-btn%20%7B%5Cn%20%20%20%20width:%20100%25;%5Cn%20%20%20%20margin:%200%20auto;%5Cn%7D%5Cn.DuckDuckGoSocialContainer:is(.size-md,%20.size-lg)%20.DuckDuckGoButton.ddg-ctl-unblock-btn%20%7B%5Cn%20%20%20%20width:%20auto;%5Cn%7D%5Cn%5Cn.ddg-ctl-placeholder-card%20%7B%5Cn%20%20%20%20height:%20100%25;%5Cn%20%20%20%20overflow:%20auto;%5Cn%20%20%20%20padding:%2016px;%5Cn%20%20%20%20color:%20var(--ddg-color-txt);%5Cn%20%20%20%20background:%20var(--ddg-color-bg-01);%5Cn%20%20%20%20border:%201px%20solid%20var(--ddg-color-border);%5Cn%20%20%20%20border-radius:%2012px;%5Cn%20%20%20%20margin:%20auto;%5Cn%20%20%20%20display:%20grid;%5Cn%20%20%20%20justify-content:%20center;%5Cn%20%20%20%20align-items:%20center;%5Cn%20%20%20%20line-height:%201;%5Cn%7D%5Cn.ddg-ctl-placeholder-card.slim-card%20%7B%5Cn%20%20%20%20padding:%2012px;%5Cn%7D%5Cn.DuckDuckGoSocialContainer.size-xs%20.ddg-ctl-placeholder-card-body%20%7B%5Cn%20%20%20%20margin:%20auto;%5Cn%7D%5Cn.DuckDuckGoSocialContainer:is(.size-md,%20.size-lg)%20.ddg-ctl-placeholder-card.with-feedback-link%20%7B%5Cn%20%20%20%20height:%20calc(100%25%20-%2030px);%5Cn%20%20%20%20max-width:%20initial;%5Cn%20%20%20%20min-height:%20initial;%5Cn%7D%5Cn%5Cn.ddg-ctl-placeholder-card-header%20%7B%5Cn%20%20%20%20width:%20100%25;%5Cn%20%20%20%20display:%20flex;%5Cn%20%20%20%20align-items:%20center;%5Cn%20%20%20%20margin:%20auto;%5Cn%20%20%20%20margin-bottom:%208px;%5Cn%20%20%20%20text-align:%20left;%5Cn%7D%5Cn.DuckDuckGoSocialContainer:is(.size-md,%20.size-lg)%20.ddg-ctl-placeholder-card-header%20%7B%5Cn%20%20%20%20flex-direction:%20column;%5Cn%20%20%20%20align-items:%20center;%5Cn%20%20%20%20justify-content:%20center;%5Cn%20%20%20%20margin-bottom:%2012px;%5Cn%20%20%20%20width:%2080%25;%5Cn%20%20%20%20text-align:%20center;%5Cn%7D%5Cn%5Cn.DuckDuckGoSocialContainer:is(.size-md,%20.size-lg)%20.ddg-ctl-placeholder-card-header%20.ddg-ctl-placeholder-card-title,%5Cn.DuckDuckGoSocialContainer:is(.size-md,%20.size-lg)%20.ddg-ctl-placeholder-card-header%20.ddg-text-link%20%7B%5Cn%20%20%20%20text-align:%20center;%5Cn%7D%5Cn%5Cn/*%20Show%20Learn%20More%20link%20in%20the%20header%20on%20mobile%20and%5Cn%20*%20tablet%20size%20screens%20and%20hide%20it%20on%20desktop%20size%20*/%5Cn.DuckDuckGoSocialContainer.size-lg%20.ddg-ctl-placeholder-card-header%20.ddg-learn-more%20%7B%5Cn%20%20%20%20display:%20none;%5Cn%7D%5Cn%5Cn.ddg-ctl-placeholder-card-title,%5Cn.ddg-ctl-placeholder-card-title%20.ddg-text-link%20%7B%5Cn%20%20%20%20font-family:%20DuckDuckGoPrivacyEssentialsBold;%5Cn%20%20%20%20font-weight:%20700;%5Cn%20%20%20%20font-size:%2016px;%5Cn%20%20%20%20line-height:%2024px;%5Cn%7D%5Cn%5Cn.ddg-ctl-placeholder-card-header-dax%20%7B%5Cn%20%20%20%20align-self:%20flex-start;%5Cn%20%20%20%20width:%2048px;%5Cn%20%20%20%20height:%2048px;%5Cn%20%20%20%20margin:%200%208px%200%200;%5Cn%7D%5Cn.DuckDuckGoSocialContainer:is(.size-md,%20.size-lg)%20.ddg-ctl-placeholder-card-header-dax%20%7B%5Cn%20%20%20%20align-self:%20inherit;%5Cn%20%20%20%20margin:%200%200%2012px%200;%5Cn%7D%5Cn%5Cn.DuckDuckGoSocialContainer.size-lg%20.ddg-ctl-placeholder-card-header-dax%20%7B%5Cn%20%20%20%20width:%2056px;%5Cn%20%20%20%20height:%2056px;%5Cn%7D%5Cn%5Cn.ddg-ctl-placeholder-card-body-text%20%7B%5Cn%20%20%20%20font-size:%2016px;%5Cn%20%20%20%20line-height:%2024px;%5Cn%20%20%20%20text-align:%20center;%5Cn%20%20%20%20margin:%200%20auto%2012px;%5Cn%5Cn%20%20%20%20display:%20none;%5Cn%7D%5Cn.DuckDuckGoSocialContainer.size-lg%20.ddg-ctl-placeholder-card-body-text%20%7B%5Cn%20%20%20%20width:%2080%25;%5Cn%20%20%20%20display:%20block;%5Cn%7D%5Cn%5Cn.ddg-ctl-placeholder-card-footer%20%7B%5Cn%20%20%20%20width:%20100%25;%5Cn%20%20%20%20margin-top:%2012px;%5Cn%20%20%20%20display:%20flex;%5Cn%20%20%20%20align-items:%20center;%5Cn%20%20%20%20justify-content:%20flex-start;%5Cn%20%20%20%20align-self:%20end;%5Cn%7D%5Cn%5Cn/*%20Only%20display%20the%20unblock%20button%20on%20really%20small%20placeholders%20*/%5Cn.DuckDuckGoSocialContainer.size-xs%20.ddg-ctl-placeholder-card-header,%5Cn.DuckDuckGoSocialContainer.size-xs%20.ddg-ctl-placeholder-card-body-text,%5Cn.DuckDuckGoSocialContainer.size-xs%20.ddg-ctl-placeholder-card-footer%20%7B%5Cn%20%20%20%20display:%20none;%5Cn%7D%5Cn%5Cn.ddg-ctl-feedback-row%20%7B%5Cn%20%20%20%20display:%20none;%5Cn%7D%5Cn.DuckDuckGoSocialContainer:is(.size-md,%20.size-lg)%20.ddg-ctl-feedback-row%20%7B%5Cn%20%20%20%20height:%2030px;%5Cn%20%20%20%20justify-content:%20flex-end;%5Cn%20%20%20%20align-items:%20center;%5Cn%20%20%20%20display:%20flex;%5Cn%7D%5Cn%5Cn.ddg-ctl-feedback-link%20%7B%5Cn%20%20%20%20font-style:%20normal;%5Cn%20%20%20%20font-weight:%20400;%5Cn%20%20%20%20font-size:%2012px;%5Cn%20%20%20%20line-height:%2012px;%5Cn%20%20%20%20color:%20var(--ddg-color-txt-link-02);%5Cn%20%20%20%20text-decoration:%20none;%5Cn%20%20%20%20display:%20inline;%5Cn%20%20%20%20background-color:%20transparent;%5Cn%20%20%20%20border:%200;%5Cn%20%20%20%20padding:%200;%5Cn%20%20%20%20cursor:%20pointer;%5Cn%7D%5Cn%22;%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Size%20keys%20for%20a%20placeholder%0A%20%20%20%20%20*%20@typedef%20%7B%20'size-xs'%20%7C%20'size-sm'%20%7C%20'size-md'%20%7C%20'size-lg'%7C%20null%20%7D%20placeholderSize%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20WithToggleParams%20-%20Toggle%20params%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20isActive%20-%20Toggle%20state%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20dataKey%20-%20data-key%20attribute%20for%20toggle%20button%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20label%20-%20Text%20to%20be%20presented%20with%20toggle%0A%20%20%20%20%20*%20@property%20%7B'md'%20%7C%20'lg'%7D%20%5Bsize=md%5D%20-%20Toggle%20size%20variant,%20'md'%20by%20default%0A%20%20%20%20%20*%20@property%20%7B()%20=%3E%20void%7D%20onClick%20-%20Toggle%20on%20click%20callback%0A%20%20%20%20%20*/%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20WithFeedbackParams%20-%20Feedback%20link%20params%0A%20%20%20%20%20*%20@property%20%7Bstring=%7D%20label%20-%20%22Share%20Feedback%22%20link%20text%0A%20%20%20%20%20*%20@property%20%7B()%20=%3E%20void%7D%20onClick%20-%20Feedback%20element%20on%20click%20callback%0A%20%20%20%20%20*/%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20LearnMoreParams%20-%20%22Learn%20More%22%20link%20params%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20readAbout%20-%20%22Learn%20More%22%20aria-label%20text%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20learnMore%20-%20%22Learn%20More%22%20link%20text%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20The%20custom%20HTML%20element%20(Web%20Component)%20template%20with%20the%20placeholder%20for%20blocked%0A%20%20%20%20%20*%20embedded%20content.%20The%20constructor%20gets%20a%20list%20of%20parameters%20with%20the%0A%20%20%20%20%20*%20content%20and%20event%20handlers%20for%20this%20template.%0A%20%20%20%20%20*%20This%20is%20currently%20only%20used%20in%20our%20Mobile%20Apps,%20but%20can%20be%20expanded%20in%20the%20future.%0A%20%20%20%20%20*/%0A%20%20%20%20class%20DDGCtlPlaceholderBlockedElement%20extends%20HTMLElement%20%7B%0A%20%20%20%20%20%20%20%20static%20CUSTOM_TAG_NAME%20=%20'ddg-ctl-placeholder-blocked';%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Min%20height%20that%20the%20placeholder%20needs%20to%20have%20in%20order%20to%0A%20%20%20%20%20%20%20%20%20*%20have%20enough%20room%20to%20display%20content.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20MIN_CONTENT_HEIGHT%20=%20110;%0A%20%20%20%20%20%20%20%20static%20MAX_CONTENT_WIDTH_SMALL%20=%20480;%0A%20%20%20%20%20%20%20%20static%20MAX_CONTENT_WIDTH_MEDIUM%20=%20650;%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Set%20observed%20attributes%20that%20will%20trigger%20attributeChangedCallback()%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20static%20get%20observedAttributes()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%5B'style'%5D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Placeholder%20element%20for%20blocked%20content%0A%20%20%20%20%20%20%20%20%20*%20@type%20%7BHTMLDivElement%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20placeholderBlocked;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Size%20variant%20of%20the%20latest%20calculated%20size%20of%20the%20placeholder.%0A%20%20%20%20%20%20%20%20%20*%20This%20is%20used%20to%20add%20the%20appropriate%20CSS%20class%20to%20the%20placeholder%20container%0A%20%20%20%20%20%20%20%20%20*%20and%20adapt%20the%20layout%20for%20each%20size.%0A%20%20%20%20%20%20%20%20%20*%20@type%20%7BplaceholderSize%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20size%20=%20null;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%20-%20Params%20for%20building%20a%20custom%20element%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20with%20a%20placeholder%20for%20blocked%20content%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean%7D%20params.devMode%20-%20Used%20to%20create%20the%20Shadow%20DOM%20on%20'open'(true)%20or%20'closed'(false)%20mode%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.title%20-%20Card%20title%20text%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.body%20-%20Card%20body%20text%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.unblockBtnText%20-%20Unblock%20button%20text%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean=%7D%20params.useSlimCard%20-%20Flag%20for%20using%20less%20padding%20on%20card%20(ie%20YT%20CTL%20on%20mobile)%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20params.originalElement%20-%20The%20original%20element%20this%20placeholder%20is%20replacing.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BLearnMoreParams%7D%20params.learnMore%20-%20Localized%20strings%20for%20%22Learn%20More%22%20link.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BWithToggleParams=%7D%20params.withToggle%20-%20Toggle%20config%20to%20be%20displayed%20in%20the%20bottom%20of%20the%20placeholder%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BWithFeedbackParams=%7D%20params.withFeedback%20-%20Shows%20feedback%20link%20on%20tablet%20and%20desktop%20sizes,%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(originalElement:%20HTMLIFrameElement%20%7C%20HTMLElement,%20replacementElement:%20HTMLElement)%20=%3E%20(e:%20any)%20=%3E%20void%7D%20params.onButtonClick%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20super();%0A%20%20%20%20%20%20%20%20%20%20%20%20this.params%20=%20params;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Create%20the%20shadow%20root,%20closed%20to%20prevent%20any%20outside%20observers%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7BShadowRoot%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20shadow%20=%20this.attachShadow(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mode:%20this.params.devMode%20?%20'open'%20:%20'closed',%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Add%20our%20styles%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7BHTMLStyleElement%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20style%20=%20document.createElement('style');%0A%20%20%20%20%20%20%20%20%20%20%20%20style.innerText%20=%20cssVars%20+%20css$1;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Creates%20the%20placeholder%20for%20blocked%20content%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7BHTMLDivElement%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.placeholderBlocked%20=%20this.createPlaceholder();%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Creates%20the%20Share%20Feedback%20element%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7BHTMLDivElement%20%7C%20null%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20feedbackLink%20=%20this.params.withFeedback%20?%20this.createShareFeedbackLink()%20:%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Setup%20the%20click%20handlers%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.setupEventListeners(this.placeholderBlocked,%20feedbackLink);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Append%20both%20to%20the%20shadow%20root%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20@typescript-eslint/no-unused-expressions%0A%20%20%20%20%20%20%20%20%20%20%20%20feedbackLink%20&&%20this.placeholderBlocked.appendChild(feedbackLink);%0A%20%20%20%20%20%20%20%20%20%20%20%20shadow.appendChild(this.placeholderBlocked);%0A%20%20%20%20%20%20%20%20%20%20%20%20shadow.appendChild(style);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Creates%20a%20placeholder%20for%20content%20blocked%20by%20Click%20to%20Load.%0A%20%20%20%20%20%20%20%20%20*%20Note:%20We're%20using%20arrow%20functions%20()%20=%3E%20%7B%7D%20in%20this%20class%20due%20to%20a%20bug%0A%20%20%20%20%20%20%20%20%20*%20found%20in%20Firefox%20where%20it%20is%20getting%20the%20wrong%20%22this%22%20context%20on%20calls%20in%20the%20constructor.%0A%20%20%20%20%20%20%20%20%20*%20This%20is%20a%20temporary%20workaround.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BHTMLDivElement%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20createPlaceholder%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20title,%20body,%20unblockBtnText,%20useSlimCard,%20withToggle,%20withFeedback%20%7D%20=%20this.params;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20container%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20%20%20%20%20container.classList.add('DuckDuckGoSocialContainer');%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cardClassNames%20=%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'slim-card',%20!!useSlimCard%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'with-feedback-link',%20!!withFeedback%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.map((%5BclassName,%20active%5D)%20=%3E%20(active%20?%20className%20:%20''))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.join('%20');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Only%20add%20a%20card%20footer%20if%20we%20have%20the%20toggle%20button%20to%20display%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cardFooterSection%20=%20withToggle%20?%20html%60%3Cdiv%20class=%22ddg-ctl-placeholder-card-footer%22%3E$%7Bthis.createToggleButton()%7D%3C/div%3E%20%60%20:%20'';%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20learnMoreLink%20=%20this.createLearnMoreLink();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20container.innerHTML%20=%20html%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-ctl-placeholder-card%20$%7BcardClassNames%7D%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-ctl-placeholder-card-header%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cimg%20class=%22ddg-ctl-placeholder-card-header-dax%22%20src=$%7BlogoImg%7D%20alt=%22DuckDuckGo%20Dax%22%20/%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-ctl-placeholder-card-title%22%3E$%7Btitle%7D.%20$%7BlearnMoreLink%7D%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-ctl-placeholder-card-body%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-ctl-placeholder-card-body-text%22%3E$%7Bbody%7D%20$%7BlearnMoreLink%7D%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20class=%22DuckDuckGoButton%20tertiary%20ddg-ctl-unblock-btn%22%20type=%22button%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%3E$%7BunblockBtnText%7D%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20$%7BcardFooterSection%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%60.toString();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20container;%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Creates%20a%20template%20string%20for%20Learn%20More%20link.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20createLearnMoreLink%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20learnMore%20%7D%20=%20this.params;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20html%60%3Ca%0A%20%20%20%20%20%20%20%20%20%20%20%20class=%22ddg-text-link%20ddg-learn-more%22%0A%20%20%20%20%20%20%20%20%20%20%20%20aria-label=%22$%7BlearnMore.readAbout%7D%22%0A%20%20%20%20%20%20%20%20%20%20%20%20href=%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%22%0A%20%20%20%20%20%20%20%20%20%20%20%20target=%22_blank%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%3E$%7BlearnMore.learnMore%7D%3C/a%0A%20%20%20%20%20%20%20%20%3E%60;%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Creates%20a%20Feedback%20Link%20container%20row%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BHTMLDivElement%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20createShareFeedbackLink%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20withFeedback%20%7D%20=%20this.params;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20container%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20%20%20%20%20container.classList.add('ddg-ctl-feedback-row');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20container.innerHTML%20=%20html%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20class=%22ddg-ctl-feedback-link%22%20type=%22button%22%3E$%7BwithFeedback?.label%20%7C%7C%20'Share%20Feedback'%7D%3C/button%3E%0A%20%20%20%20%20%20%20%20%60.toString();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20container;%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Creates%20a%20template%20string%20for%20a%20toggle%20button%20with%20text.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20createToggleButton%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20withToggle%20%7D%20=%20this.params;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!withToggle)%20return;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20isActive,%20dataKey,%20label,%20size:%20toggleSize%20=%20'md'%20%7D%20=%20withToggle;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20toggleButton%20=%20html%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-toggle-button-container%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20class=%22ddg-toggle-button%20$%7BisActive%20?%20'active'%20:%20'inactive'%7D%20$%7BtoggleSize%7D%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type=%22button%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20aria-pressed=$%7B!!isActive%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20data-key=$%7BdataKey%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-toggle-button-bg%22%3E%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-toggle-button-knob%22%3E%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-toggle-button-label%22%3E$%7Blabel%7D%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20toggleButton;%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20containerElement%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement?%7D%20feedbackLink%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20setupEventListeners%20=%20(containerElement,%20feedbackLink)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20withToggle,%20withFeedback,%20originalElement,%20onButtonClick%20%7D%20=%20this.params;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20containerElement.querySelector('button.ddg-ctl-unblock-btn')?.addEventListener('click',%20onButtonClick(originalElement,%20this));%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(withToggle)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20containerElement.querySelector('.ddg-toggle-button-container')?.addEventListener('click',%20withToggle.onClick);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(withFeedback%20&&%20feedbackLink)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20feedbackLink.querySelector('.ddg-ctl-feedback-link')?.addEventListener('click',%20withFeedback.onClick);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Use%20JS%20to%20calculate%20the%20width%20and%20height%20of%20the%20root%20element%20placeholder.%20We%20could%20use%20a%20CSS%20Container%20Query,%20but%20full%0A%20%20%20%20%20%20%20%20%20*%20support%20to%20it%20was%20only%20added%20recently,%20so%20we're%20not%20using%20it%20for%20now.%0A%20%20%20%20%20%20%20%20%20*%20https://caniuse.com/css-container-queries%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20updatePlaceholderSize%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7BplaceholderSize%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20newSize%20=%20null;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20height,%20width%20%7D%20=%20this.getBoundingClientRect();%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(height%20&&%20height%20%3C%20DDGCtlPlaceholderBlockedElement.MIN_CONTENT_HEIGHT)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20newSize%20=%20'size-xs';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(width)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(width%20%3C%20DDGCtlPlaceholderBlockedElement.MAX_CONTENT_WIDTH_SMALL)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20newSize%20=%20'size-sm';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(width%20%3C%20DDGCtlPlaceholderBlockedElement.MAX_CONTENT_WIDTH_MEDIUM)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20newSize%20=%20'size-md';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20newSize%20=%20'size-lg';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(newSize%20&&%20newSize%20!==%20this.size)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.size)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.placeholderBlocked.classList.remove(this.size);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.placeholderBlocked.classList.add(newSize);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.size%20=%20newSize;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Web%20Component%20lifecycle%20function.%0A%20%20%20%20%20%20%20%20%20*%20When%20element%20is%20first%20added%20to%20the%20DOM,%20trigger%20this%20callback%20and%0A%20%20%20%20%20%20%20%20%20*%20update%20the%20element%20CSS%20size%20class.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20connectedCallback()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.updatePlaceholderSize();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Web%20Component%20lifecycle%20function.%0A%20%20%20%20%20%20%20%20%20*%20When%20the%20root%20element%20gets%20the%20'style'%20attribute%20updated,%20reflect%20that%20in%20the%20container%0A%20%20%20%20%20%20%20%20%20*%20element%20inside%20the%20shadow%20root.%20This%20way,%20we%20can%20copy%20the%20size%20and%20other%20styles%20from%20the%20root%0A%20%20%20%20%20%20%20%20%20*%20element%20and%20have%20the%20inner%20context%20be%20able%20to%20use%20the%20same%20sizes%20to%20adapt%20the%20template%20layout.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20attr%20Observed%20attribute%20key%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B*%7D%20_%20Attribute%20old%20value,%20ignored%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B*%7D%20newValue%20Attribute%20new%20value%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20attributeChangedCallback(attr,%20_,%20newValue)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(attr%20===%20'style')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.placeholderBlocked%5Battr%5D.cssText%20=%20newValue;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.updatePlaceholderSize();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20css%20=%20%22:host,%5Cn*%20%7B%5Cn%20%20%20%20font-family:%20DuckDuckGoPrivacyEssentials,%20system,%20-apple-system,%20system-ui,%20BlinkMacSystemFont,%20'Segoe%20UI',%20Roboto,%5Cn%20%20%20%20%20%20%20%20Helvetica,%20Arial,%20sans-serif,%20'Apple%20Color%20Emoji',%20'Segoe%20UI%20Emoji',%20'Segoe%20UI%20Symbol';%5Cn%20%20%20%20box-sizing:%20border-box;%5Cn%20%20%20%20font-weight:%20normal;%5Cn%20%20%20%20font-style:%20normal;%5Cn%20%20%20%20margin:%200;%5Cn%20%20%20%20padding:%200;%5Cn%20%20%20%20text-align:%20left;%5Cn%7D%5Cn%5Cn/*%20SHARED%20STYLES%20*/%5Cn/*%20Popover%20*/%5Cn.ddg-popover%20%7B%5Cn%20%20%20%20background:%20#ffffff;%5Cn%20%20%20%20border:%201px%20solid%20rgba(0,%200,%200,%200.1);%5Cn%20%20%20%20border-radius:%2016px;%5Cn%20%20%20%20box-shadow:%200px%202px%206px%20rgba(0,%200,%200,%200.12),%200px%208px%2016px%20rgba(0,%200,%200,%200.08);%5Cn%20%20%20%20width:%20360px;%5Cn%20%20%20%20margin-top:%2010px;%5Cn%20%20%20%20z-index:%202147483647;%5Cn%20%20%20%20position:%20absolute;%5Cn%20%20%20%20line-height:%20normal;%5Cn%7D%5Cn.ddg-popover-arrow%20%7B%5Cn%20%20%20%20display:%20inline-block;%5Cn%20%20%20%20background:%20#ffffff;%5Cn%20%20%20%20border:%20solid%20rgba(0,%200,%200,%200.1);%5Cn%20%20%20%20border-width:%200%201px%201px%200;%5Cn%20%20%20%20padding:%205px;%5Cn%20%20%20%20transform:%20rotate(-135deg);%5Cn%20%20%20%20-webkit-transform:%20rotate(-135deg);%5Cn%20%20%20%20position:%20relative;%5Cn%20%20%20%20top:%20-9px;%5Cn%7D%5Cn.ddg-popover%20.ddg-title-header%20%7B%5Cn%20%20%20%20padding:%200px%2012px%2012px;%5Cn%20%20%20%20margin-top:%20-5px;%5Cn%7D%5Cn.ddg-popover-body%20%7B%5Cn%20%20%20%20font-size:%2014px;%5Cn%20%20%20%20line-height:%2021px;%5Cn%20%20%20%20margin:%20auto;%5Cn%20%20%20%20padding:%2017px;%5Cn%20%20%20%20text-align:%20left;%5Cn%7D%5Cn%5Cn/*%20DDG%20common%20header%20*/%5Cn.ddg-title-header%20%7B%5Cn%20%20%20%20display:%20flex;%5Cn%20%20%20%20padding:%2012px;%5Cn%20%20%20%20max-height:%2044px;%5Cn%20%20%20%20border-bottom:%201px%20solid;%5Cn%20%20%20%20border-color:%20rgba(196,%20196,%20196,%200.3);%5Cn%20%20%20%20margin:%200;%5Cn%20%20%20%20margin-bottom:%204px;%5Cn%7D%5Cn.ddg-title-header%20.ddg-title-text%20%7B%5Cn%20%20%20%20line-height:%201.4;%5Cn%20%20%20%20font-size:%2014px;%5Cn%20%20%20%20margin:%20auto%2010px;%5Cn%20%20%20%20flex-basis:%20100%25;%5Cn%20%20%20%20height:%201.4em;%5Cn%20%20%20%20flex-wrap:%20wrap;%5Cn%20%20%20%20overflow:%20hidden;%5Cn%20%20%20%20text-align:%20left;%5Cn%20%20%20%20border:%20none;%5Cn%20%20%20%20padding:%200;%5Cn%7D%5Cn.ddg-title-header%20.ddg-logo%20%7B%5Cn%20%20%20%20flex-basis:%200%25;%5Cn%20%20%20%20min-width:%2020px;%5Cn%20%20%20%20height:%2021px;%5Cn%20%20%20%20border:%20none;%5Cn%20%20%20%20padding:%200;%5Cn%20%20%20%20margin:%200;%5Cn%7D%5Cn.ddg-title-header%20.ddg-logo%20.ddg-logo-img%20%7B%5Cn%20%20%20%20height:%2021px;%5Cn%20%20%20%20width:%2021px;%5Cn%7D%5Cn%5Cn/*%20CTL%20Login%20Button%20styles%20*/%5Cn#DuckDuckGoPrivacyEssentialsHoverable%20%7B%5Cn%20%20%20%20padding-bottom:%2010px;%5Cn%7D%5Cn%5Cn#DuckDuckGoPrivacyEssentialsHoverableText%20%7B%5Cn%20%20%20%20display:%20none;%5Cn%7D%5Cn#DuckDuckGoPrivacyEssentialsHoverable:hover%20#DuckDuckGoPrivacyEssentialsHoverableText%20%7B%5Cn%20%20%20%20display:%20block;%5Cn%7D%5Cn%5Cn.DuckDuckGoButton.tertiary.ddg-ctl-fb-login-btn%20%7B%5Cn%20%20%20%20background-color:%20var(--ddg-color-bg-01);%5Cn%7D%5Cn@media%20(prefers-color-scheme:%20dark)%20%7B%5Cn%20%20%20%20.DuckDuckGoButton.tertiary.ddg-ctl-fb-login-btn%20%7B%5Cn%20%20%20%20%20%20%20%20background:%20#111111;%5Cn%20%20%20%20%7D%5Cn%7D%5Cn.DuckDuckGoButton.tertiary:hover%20%7B%5Cn%20%20%20%20background:%20rgb(238,%20238,%20238);%5Cn%20%20%20%20border-color:%20var(--ddg-shade-18);%5Cn%7D%5Cn@media%20(prefers-color-scheme:%20dark)%20%7B%5Cn%20%20%20%20.DuckDuckGoButton.tertiary:hover%20%7B%5Cn%20%20%20%20%20%20%20%20background:%20rgb(39,%2039,%2039);%5Cn%20%20%20%20%20%20%20%20border-color:%20var(--ddg-tint-24);%5Cn%20%20%20%20%7D%5Cn%7D%5Cn.DuckDuckGoButton.tertiary:active%20%7B%5Cn%20%20%20%20background:%20rgb(220,%20220,%20220);%5Cn%20%20%20%20border-color:%20var(--ddg-shade-36);%5Cn%7D%5Cn@media%20(prefers-color-scheme:%20dark)%20%7B%5Cn%20%20%20%20.DuckDuckGoButton.tertiary:active%20%7B%5Cn%20%20%20%20%20%20%20%20background:%20rgb(65,%2065,%2065);%5Cn%20%20%20%20%20%20%20%20border-color:%20var(--ddg-tint-24);%5Cn%20%20%20%20%7D%5Cn%7D%5Cn%5Cn.ddg-ctl-button-login-icon%20%7B%5Cn%20%20%20%20margin-right:%208px;%5Cn%20%20%20%20height:%2020px;%5Cn%20%20%20%20width:%2020px;%5Cn%7D%5Cn%5Cn.ddg-fb-login-container%20%7B%5Cn%20%20%20%20position:%20relative;%5Cn%20%20%20%20margin:%20auto;%5Cn%20%20%20%20width:%20auto;%5Cn%7D%5Cn%22;%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20LearnMoreParams%20-%20%22Learn%20More%22%20link%20params%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20readAbout%20-%20%22Learn%20More%22%20aria-label%20text%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20learnMore%20-%20%22Learn%20More%22%20link%20text%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Template%20for%20creating%20a%20%3Cdiv/%3E%20element%20placeholder%20for%20blocked%20login%20embedded%20buttons.%0A%20%20%20%20%20*%20The%20constructor%20gets%20a%20list%20of%20parameters%20with%20the%0A%20%20%20%20%20*%20content%20and%20event%20handlers%20for%20this%20template.%0A%20%20%20%20%20*%20This%20is%20currently%20only%20used%20in%20our%20Mobile%20Apps,%20but%20can%20be%20expanded%20in%20the%20future.%0A%20%20%20%20%20*/%0A%20%20%20%20class%20DDGCtlLoginButton%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Placeholder%20container%20element%20for%20blocked%20login%20button%0A%20%20%20%20%20%20%20%20%20*%20@type%20%7BHTMLDivElement%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20#element;%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bobject%7D%20params%20-%20Params%20for%20building%20a%20custom%20element%20with%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%20placeholder%20for%20a%20blocked%20login%20button%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean%7D%20params.devMode%20-%20Used%20to%20create%20the%20Shadow%20DOM%20on%20'open'(true)%20or%20'closed'(false)%20mode%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.label%20-%20Button%20text%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.logoIcon%20-%20Logo%20image%20to%20be%20displayed%20in%20the%20Login%20Button%20to%20the%20left%20of%20the%20label%20text%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20params.hoverText%20-%20Text%20for%20popover%20on%20button%20hover%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean=%7D%20params.useSlimCard%20-%20Flag%20for%20using%20less%20padding%20on%20card%20(ie%20YT%20CTL%20on%20mobile)%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20params.originalElement%20-%20The%20original%20element%20this%20placeholder%20is%20replacing.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BLearnMoreParams%7D%20params.learnMore%20-%20Localized%20strings%20for%20%22Learn%20More%22%20link.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7B(originalElement:%20HTMLIFrameElement%20%7C%20HTMLElement,%20replacementElement:%20HTMLElement)%20=%3E%20(e:%20any)%20=%3E%20void%7D%20params.onClick%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(params)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.params%20=%20params;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Create%20the%20placeholder%20element%20to%20be%20inject%20in%20the%20page%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7BHTMLDivElement%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this.element%20=%20document.createElement('div');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Create%20the%20shadow%20root,%20closed%20to%20prevent%20any%20outside%20observers%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7BShadowRoot%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20shadow%20=%20this.element.attachShadow(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mode:%20this.params.devMode%20?%20'open'%20:%20'closed',%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Add%20our%20styles%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7BHTMLStyleElement%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20style%20=%20document.createElement('style');%0A%20%20%20%20%20%20%20%20%20%20%20%20style.innerText%20=%20cssVars%20+%20css;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Create%20the%20Facebook%20login%20button%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20@type%20%7BHTMLDivElement%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20loginButton%20=%20this._createLoginButton();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Setup%20the%20click%20handlers%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20this._setupEventListeners(loginButton);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Append%20both%20to%20the%20shadow%20root%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20shadow.appendChild(loginButton);%0A%20%20%20%20%20%20%20%20%20%20%20%20shadow.appendChild(style);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BHTMLDivElement%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20get%20element()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.#element;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLDivElement%7D%20el%20-%20New%20placeholder%20element%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20set%20element(el)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.#element%20=%20el;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Creates%20a%20placeholder%20Facebook%20login%20button.%20When%20clicked,%20a%20warning%20dialog%0A%20%20%20%20%20%20%20%20%20*%20is%20displayed%20to%20the%20user.%20The%20login%20flow%20only%20continues%20if%20the%20user%20clicks%20to%0A%20%20%20%20%20%20%20%20%20*%20proceed.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BHTMLDivElement%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_createLoginButton()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20label,%20hoverText,%20logoIcon,%20learnMore%20%7D%20=%20this.params;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20popoverStyle,%20arrowStyle%20%7D%20=%20this._calculatePopoverPosition();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20container%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Add%20our%20own%20styles%20and%20inherit%20any%20local%20class%20styles%20on%20the%20button%0A%20%20%20%20%20%20%20%20%20%20%20%20container.classList.add('ddg-fb-login-container');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20container.innerHTML%20=%20html%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22DuckDuckGoPrivacyEssentialsHoverable%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Login%20Button%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20class=%22DuckDuckGoButton%20tertiary%20ddg-ctl-fb-login-btn%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cimg%20class=%22ddg-ctl-button-login-icon%22%20height=%2220px%22%20width=%2220px%22%20src=%22$%7BlogoIcon%7D%22%20/%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%3E$%7Blabel%7D%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/button%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Popover%20-%20hover%20box%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22DuckDuckGoPrivacyEssentialsHoverableText%22%20class=%22ddg-popover%22%20style=%22$%7BpopoverStyle%7D%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-popover-arrow%22%20style=%22$%7BarrowStyle%7D%22%3E%3C/div%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-title-header%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-logo%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cimg%20class=%22ddg-logo-img%22%20src=%22$%7BlogoImg%7D%22%20height=%2221px%22%20/%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22DuckDuckGoPrivacyEssentialsCTLElementTitle%22%20class=%22ddg-title-text%22%3EDuckDuckGo%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22ddg-popover-body%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20$%7BhoverText%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ca%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20class=%22ddg-text-link%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20aria-label=%22$%7BlearnMore.readAbout%7D%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20href=%22https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20target=%22_blank%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id=%22learnMoreLink%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20$%7BlearnMore.learnMore%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/a%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%60.toString();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20container;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20The%20left%20side%20of%20the%20popover%20may%20go%20offscreen%20if%20the%0A%20%20%20%20%20%20%20%20%20*%20login%20button%20is%20all%20the%20way%20on%20the%20left%20side%20of%20the%20page.%20This%0A%20%20%20%20%20%20%20%20%20*%20If%20that%20is%20the%20case,%20dynamically%20shift%20the%20box%20right%20so%20it%20shows%0A%20%20%20%20%20%20%20%20%20*%20properly.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7B%7B%0A%20%20%20%20%20%20%20%20%20*%20%20popoverStyle:%20string,%20//%20CSS%20styles%20to%20be%20applied%20in%20the%20Popover%20container%0A%20%20%20%20%20%20%20%20%20*%20%20arrowStyle:%20string,%20%20%20//%20CSS%20styles%20to%20be%20applied%20in%20the%20Popover%20arrow%0A%20%20%20%20%20%20%20%20%20*%20%7D%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_calculatePopoverPosition()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20originalElement%20%7D%20=%20this.params;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20rect%20=%20originalElement.getBoundingClientRect();%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20textBubbleWidth%20=%20360;%20//%20Should%20match%20the%20width%20rule%20in%20.ddg-popover%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20textBubbleLeftShift%20=%20100;%20//%20Should%20match%20the%20CSS%20left:%20rule%20in%20.ddg-popover%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20arrowDefaultLocationPercent%20=%2050;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20popoverStyle;%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20arrowStyle;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(rect.left%20%3C%20textBubbleLeftShift)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20leftShift%20=%20-rect.left%20+%2010;%20//%2010px%20away%20from%20edge%20of%20the%20screen%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20popoverStyle%20=%20%60left:%20$%7BleftShift%7Dpx;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20change%20=%20(1%20-%20rect.left%20/%20textBubbleLeftShift)%20*%20(100%20-%20arrowDefaultLocationPercent);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20arrowStyle%20=%20%60left:%20$%7BMath.max(10,%20arrowDefaultLocationPercent%20-%20change)%7D%25;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(rect.left%20+%20textBubbleWidth%20-%20textBubbleLeftShift%20%3E%20window.innerWidth)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20rightShift%20=%20rect.left%20+%20textBubbleWidth%20-%20textBubbleLeftShift;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20diff%20=%20Math.min(rightShift%20-%20window.innerWidth,%20textBubbleLeftShift);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20rightMargin%20=%2020;%20//%20Add%20some%20margin%20to%20the%20page,%20so%20scrollbar%20doesn't%20overlap.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20popoverStyle%20=%20%60left:%20-$%7BtextBubbleLeftShift%20+%20diff%20+%20rightMargin%7Dpx;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20change%20=%20(diff%20/%20textBubbleLeftShift)%20*%20(100%20-%20arrowDefaultLocationPercent);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20arrowStyle%20=%20%60left:%20$%7BMath.max(10,%20arrowDefaultLocationPercent%20+%20change)%7D%25;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20popoverStyle%20=%20%60left:%20-$%7BtextBubbleLeftShift%7Dpx;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20arrowStyle%20=%20%60left:%20$%7BarrowDefaultLocationPercent%7D%25;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%20popoverStyle,%20arrowStyle%20%7D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20loginButton%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20_setupEventListeners(loginButton)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20originalElement,%20onClick%20%7D%20=%20this.params;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20loginButton.querySelector('.ddg-ctl-fb-login-btn')?.addEventListener('click',%20onClick(originalElement,%20this.element));%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Register%20custom%20elements%20in%20this%20wrapper%20function%20to%20be%20called%20only%20when%20we%20need%20to%0A%20%20%20%20%20*%20and%20also%20to%20allow%20remote-config%20later%20if%20needed.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20registerCustomElements()%20%7B%0A%20%20%20%20%20%20%20%20if%20(!customElements.get(DDGCtlPlaceholderBlockedElement.CUSTOM_TAG_NAME))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20customElements.define(DDGCtlPlaceholderBlockedElement.CUSTOM_TAG_NAME,%20DDGCtlPlaceholderBlockedElement);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7B'darkMode'%20%7C%20'lightMode'%20%7C%20'loginMode'%20%7C%20'cancelMode'%7D%20displayMode%0A%20%20%20%20%20*%20%20%20Key%20for%20theme%20value%20to%20determine%20the%20styling%20of%20buttons/placeholders.%0A%20%20%20%20%20*%20%20%20Matches%20%60styles%5Bmode%5D%60%20keys:%0A%20%20%20%20%20*%20%20%20%20%20-%20%60'lightMode'%60:%20Primary%20colors%20styling%20for%20light%20theme%0A%20%20%20%20%20*%20%20%20%20%20-%20%60'darkMode'%60:%20Primary%20colors%20styling%20for%20dark%20theme%0A%20%20%20%20%20*%20%20%20%20%20-%20%60'cancelMode'%60:%20Secondary%20colors%20styling%20for%20all%20themes%0A%20%20%20%20%20*/%0A%0A%20%20%20%20let%20devMode%20=%20false;%0A%20%20%20%20let%20isYoutubePreviewsEnabled%20=%20false;%0A%20%20%20%20let%20appID;%0A%0A%20%20%20%20const%20titleID%20=%20'DuckDuckGoPrivacyEssentialsCTLElementTitle';%0A%0A%20%20%20%20//%20Configuration%20for%20how%20the%20placeholder%20elements%20should%20look%20and%20behave.%0A%20%20%20%20//%20@see%20%7BgetConfig%7D%0A%20%20%20%20let%20config%20=%20null;%0A%20%20%20%20let%20sharedStrings%20=%20null;%0A%20%20%20%20let%20styles%20=%20null;%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20List%20of%20platforms%20where%20we%20can%20skip%20showing%20a%20Web%20Modal%20from%20C-S-S.%0A%20%20%20%20%20*%20It%20is%20generally%20expected%20that%20the%20platform%20will%20show%20a%20native%20modal%20instead.%0A%20%20%20%20%20*%20@type%20%7Bimport('../utils').Platform%5B%22name%22%5D%5B%5D%7D%20*/%0A%20%20%20%20const%20platformsWithNativeModalSupport%20=%20%5B'android',%20'ios'%5D;%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Platforms%20supporting%20the%20new%20layout%20using%20Web%20Components.%0A%20%20%20%20%20*%20@type%20%7Bimport('../utils').Platform%5B%22name%22%5D%5B%5D%7D%20*/%0A%20%20%20%20const%20platformsWithWebComponentsEnabled%20=%20%5B'android',%20'ios'%5D;%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Based%20on%20the%20current%20Platform%20where%20the%20Widget%20is%20running,%20it%20will%0A%20%20%20%20%20*%20return%20if%20it%20is%20one%20of%20our%20mobile%20apps%20or%20not.%20This%20should%20be%20used%20to%0A%20%20%20%20%20*%20define%20which%20layout%20to%20use%20between%20Mobile%20and%20Desktop%20Platforms%20variations.%0A%20%20%20%20%20*%20@type%20%7Bimport('../utils').Platform%5B%22name%22%5D%5B%5D%7D%20*/%0A%20%20%20%20const%20mobilePlatforms%20=%20%5B'android',%20'ios'%5D;%0A%0A%20%20%20%20//%20TODO:%20Remove%20these%20redundant%20data%20structures%20and%20refactor%20the%20related%20code.%0A%20%20%20%20//%20%20%20%20%20%20%20There%20should%20be%20no%20need%20to%20have%20the%20entity%20configuration%20stored%20in%20two%0A%20%20%20%20//%20%20%20%20%20%20%20places.%0A%20%20%20%20const%20entities%20=%20%5B%5D;%0A%20%20%20%20const%20entityData%20=%20%7B%7D;%0A%0A%20%20%20%20//%20Used%20to%20avoid%20displaying%20placeholders%20for%20the%20same%20tracking%20element%20twice.%0A%20%20%20%20const%20knownTrackingElements%20=%20new%20WeakSet();%0A%0A%20%20%20%20//%20Promise%20that%20is%20resolved%20when%20the%20Click%20to%20Load%20feature%20init()%20function%20has%0A%20%20%20%20//%20finished%20its%20work,%20enough%20that%20it's%20now%20safe%20to%20replace%20elements%20with%0A%20%20%20%20//%20placeholders.%0A%20%20%20%20let%20readyToDisplayPlaceholdersResolver;%0A%20%20%20%20const%20readyToDisplayPlaceholders%20=%20new%20Promise((resolve)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20readyToDisplayPlaceholdersResolver%20=%20resolve;%0A%20%20%20%20%7D);%0A%0A%20%20%20%20//%20Promise%20that%20is%20resolved%20when%20the%20page%20has%20finished%20loading%20(and%0A%20%20%20%20//%20readyToDisplayPlaceholders%20has%20resolved).%20Wait%20for%20this%20before%20sending%0A%20%20%20%20//%20essential%20messages%20to%20surrogate%20scripts.%0A%20%20%20%20let%20afterPageLoadResolver;%0A%20%20%20%20const%20afterPageLoad%20=%20new%20Promise((resolve)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20afterPageLoadResolver%20=%20resolve;%0A%20%20%20%20%7D);%0A%0A%20%20%20%20//%20Messaging%20layer%20for%20Click%20to%20Load.%20The%20messaging%20instance%20is%20initialized%20in%0A%20%20%20%20//%20ClickToLoad.init()%20and%20updated%20here%20to%20be%20used%20outside%20ClickToLoad%20class%0A%20%20%20%20//%20we%20need%20a%20module%20scoped%20reference.%0A%20%20%20%20/**%20@type%20%7Bimport(%22@duckduckgo/messaging%22).Messaging%7D%20*/%0A%20%20%20%20let%20_messagingModuleScope;%0A%20%20%20%20/**%20@type%20function%20*/%0A%20%20%20%20let%20_addDebugFlag;%0A%20%20%20%20const%20ctl%20=%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@return%20%7Bimport(%22@duckduckgo/messaging%22).Messaging%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20get%20messaging()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!_messagingModuleScope)%20throw%20new%20Error('Messaging%20not%20initialized');%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20_messagingModuleScope;%0A%20%20%20%20%20%20%20%20%7D,%0A%0A%20%20%20%20%20%20%20%20addDebugFlag()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!_addDebugFlag)%20throw%20new%20Error('addDebugFlag%20not%20initialized');%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20_addDebugFlag();%0A%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%7D;%0A%0A%20%20%20%20/*********************************************************%0A%20%20%20%20%20*%20%20Widget%20Replacement%20logic%0A%20%20%20%20%20*********************************************************/%0A%20%20%20%20class%20DuckWidget%20%7B%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BObject%7D%20widgetData%0A%20%20%20%20%20%20%20%20%20*%20%20%20The%20configuration%20for%20this%20%22widget%22%20as%20determined%20in%20ctl-config.js.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20originalElement%0A%20%20%20%20%20%20%20%20%20*%20%20%20The%20original%20tracking%20element%20to%20replace%20with%20a%20placeholder.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20entity%0A%20%20%20%20%20%20%20%20%20*%20%20%20The%20entity%20behind%20the%20tracking%20element%20(e.g.%20%22Facebook,%20Inc.%22).%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bimport('../utils').Platform%7D%20platform%0A%20%20%20%20%20%20%20%20%20*%20%20%20The%20platform%20where%20Click%20to%20Load%20and%20the%20Duck%20Widget%20is%20running%20on%20(ie%20Extension,%20Android%20App,%20etc)%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20constructor(widgetData,%20originalElement,%20entity,%20platform)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20this.clickAction%20=%20%7B%20...widgetData.clickAction%20%7D;%20//%20shallow%20copy%0A%20%20%20%20%20%20%20%20%20%20%20%20this.replaceSettings%20=%20widgetData.replaceSettings;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.originalElement%20=%20originalElement;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.placeholderElement%20=%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.dataElements%20=%20%7B%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.gatherDataElements();%0A%20%20%20%20%20%20%20%20%20%20%20%20this.entity%20=%20entity;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.widgetID%20=%20Math.random();%0A%20%20%20%20%20%20%20%20%20%20%20%20this.autoplay%20=%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Boolean%20if%20widget%20is%20unblocked%20and%20content%20should%20not%20be%20blocked%0A%20%20%20%20%20%20%20%20%20%20%20%20this.isUnblocked%20=%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.platform%20=%20platform;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Dispatch%20an%20event%20on%20the%20target%20element,%20including%20the%20widget's%20ID%20and%0A%20%20%20%20%20%20%20%20%20*%20other%20details.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BEventTarget%7D%20eventTarget%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bstring%7D%20eventName%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20dispatchEvent(eventTarget,%20eventName)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20eventTarget.dispatchEvent(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20createCustomEvent(eventName,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20detail:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20entity:%20this.entity,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceSettings:%20this.replaceSettings,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20widgetID:%20this.widgetID,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D),%0A%20%20%20%20%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Take%20note%20of%20some%20of%20the%20tracking%20element's%20attributes%20(as%20determined%20by%0A%20%20%20%20%20%20%20%20%20*%20clickAction.urlDataAttributesToPreserve)%20and%20store%20those%20in%0A%20%20%20%20%20%20%20%20%20*%20this.dataElement.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20gatherDataElements()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this.clickAction.urlDataAttributesToPreserve)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20%5BattrName,%20attrSettings%5D%20of%20Object.entries(this.clickAction.urlDataAttributesToPreserve))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20value%20=%20this.originalElement.getAttribute(attrName);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!value)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(attrSettings.required)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Missing%20a%20required%20attribute%20means%20we%20won't%20be%20able%20to%20replace%20it%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20with%20a%20light%20version,%20replace%20with%20full%20version.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.clickAction.type%20=%20'allowFull';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20the%20attribute%20is%20%22width%22,%20try%20first%20to%20measure%20the%20parent's%20width%20and%20use%20that%20as%20a%20default%20value.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(attrName%20===%20'data-width')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20windowWidth%20=%20window.innerWidth;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20parentElement%20%7D%20=%20this.originalElement;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20parentStyles%20=%20parentElement%20?%20window.getComputedStyle(parentElement)%20:%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20parentInnerWidth%20=%20null;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20We%20want%20to%20calculate%20the%20inner%20width%20of%20the%20parent%20element%20as%20the%20iframe,%20when%20added%20back,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20should%20not%20be%20bigger%20than%20the%20space%20available%20in%20the%20parent%20element.%20There%20is%20no%20straightforward%20way%20of%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20doing%20this.%20We%20need%20to%20get%20the%20parent's%20.clientWidth%20and%20remove%20the%20paddings%20size%20from%20it.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(parentElement%20&&%20parentStyles%20&&%20parentStyles.display%20!==%20'inline')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20parentInnerWidth%20=%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20parentElement.clientWidth%20-%20parseFloat(parentStyles.paddingLeft)%20-%20parseFloat(parentStyles.paddingRight);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(parentInnerWidth%20&&%20parentInnerWidth%20%3C%20windowWidth)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value%20=%20parentInnerWidth.toString();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Our%20default%20value%20for%20width%20is%20often%20greater%20than%20the%20window%20size%20of%20smaller%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20screens%20(ie%20mobile).%20Then%20use%20whatever%20is%20the%20smallest%20value.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value%20=%20Math.min(attrSettings.default,%20windowWidth).toString();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value%20=%20attrSettings.default;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.dataElements%5BattrName%5D%20=%20value;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Return%20the%20URL%20of%20the%20Facebook%20content,%20for%20use%20when%20a%20Facebook%20Click%20to%0A%20%20%20%20%20%20%20%20%20*%20Load%20placeholder%20has%20been%20clicked%20by%20the%20user.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bstring%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20getTargetURL()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Copying%20over%20data%20fields%20should%20be%20done%20lazily,%20since%20some%20required%20data%20may%20not%20be%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20captured%20until%20after%20page%20scripts%20run.%0A%20%20%20%20%20%20%20%20%20%20%20%20this.copySocialDataFields();%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.clickAction.targetURL;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Determines%20which%20display%20mode%20the%20placeholder%20element%20should%20render%20in.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BdisplayMode%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20getMode()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Login%20buttons%20are%20always%20the%20login%20style%20types%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.replaceSettings.type%20===%20'loginButton')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20'loginMode';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(window?.matchMedia('(prefers-color-scheme:%20dark)')?.matches)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20'darkMode';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20'lightMode';%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Take%20note%20of%20some%20of%20the%20tracking%20element's%20style%20attributes%20(as%0A%20%20%20%20%20%20%20%20%20*%20determined%20by%20clickAction.styleDataAttributes)%20as%20a%20CSS%20string.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bstring%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20getStyle()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20styleString%20=%20'border:%20none;';%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.clickAction.styleDataAttributes)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Copy%20elements%20from%20the%20original%20div%20into%20style%20attributes%20as%20directed%20by%20config%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20%5Battr,%20valAttr%5D%20of%20Object.entries(this.clickAction.styleDataAttributes))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20valueFound%20=%20this.dataElements%5BvalAttr.name%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!valueFound)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20valueFound%20=%20this.dataElements%5BvalAttr.fallbackAttribute%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20partialStyleString%20=%20'';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(valueFound)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20partialStyleString%20+=%20%60$%7Battr%7D:%20$%7BvalueFound%7D%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!partialStyleString.includes(valAttr.unit))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20partialStyleString%20+=%20valAttr.unit;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20partialStyleString%20+=%20';';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20styleString%20+=%20partialStyleString;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20styleString;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Store%20some%20attributes%20from%20the%20original%20tracking%20element,%20used%20for%20both%0A%20%20%20%20%20%20%20%20%20*%20placeholder%20element%20styling,%20and%20when%20restoring%20the%20original%20tracking%0A%20%20%20%20%20%20%20%20%20*%20element.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20copySocialDataFields()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this.clickAction.urlDataAttributesToPreserve)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20App%20ID%20may%20be%20set%20by%20client%20scripts,%20and%20is%20required%20for%20some%20elements.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.dataElements.app_id_replace%20&&%20appID%20!=%20null)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.clickAction.targetURL%20=%20this.clickAction.targetURL.replace('app_id_replace',%20appID);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20key%20of%20Object.keys(this.dataElements))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20attrValue%20=%20this.dataElements%5Bkey%5D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!attrValue)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20The%20URL%20for%20Facebook%20videos%20are%20specified%20as%20the%20data-href%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20attribute%20on%20a%20div,%20that%20is%20then%20used%20to%20create%20the%20iframe.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Some%20websites%20omit%20the%20protocol%20part%20of%20the%20URL%20when%20doing%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20that,%20which%20then%20prevents%20the%20iframe%20from%20loading%20correctly.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(key%20===%20'data-href'%20&&%20attrValue.startsWith('//'))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20attrValue%20=%20window.location.protocol%20+%20attrValue;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.clickAction.targetURL%20=%20this.clickAction.targetURL.replace(key,%20encodeURIComponent(attrValue));%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Creates%20an%20iFrame%20for%20this%20facebook%20content.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BHTMLIFrameElement%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20createFBIFrame()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20frame%20=%20document.createElement('iframe');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20frame.setAttribute('src',%20this.getTargetURL());%0A%20%20%20%20%20%20%20%20%20%20%20%20frame.setAttribute('style',%20this.getStyle());%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20frame;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Tweaks%20an%20embedded%20YouTube%20video%20element%20ready%20for%20when%20it's%0A%20%20%20%20%20%20%20%20%20*%20reloaded.%0A%20%20%20%20%20%20%20%20%20*%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLIFrameElement%7D%20videoElement%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BEventListener?%7D%20onError%0A%20%20%20%20%20%20%20%20%20*%20%20%20Function%20to%20be%20called%20if%20the%20video%20fails%20to%20load.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20adjustYouTubeVideoElement(videoElement)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20onError%20=%20null;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!videoElement.src)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20onError;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20url%20=%20new%20URL(videoElement.src);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20hostname:%20originalHostname%20%7D%20=%20url;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Upgrade%20video%20to%20YouTube's%20%22privacy%20enhanced%22%20mode,%20but%20fall%20back%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20to%20standard%20mode%20if%20the%20video%20fails%20to%20load.%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Note:%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20%201.%20Changing%20the%20iframe's%20host%20like%20this%20won't%20cause%20a%20CSP%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20%20%20violation%20on%20Chrome,%20see%20https://crbug.com/1271196.%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20%202.%20The%20onError%20event%20doesn't%20fire%20for%20blocked%20iframes%20on%20Chrome.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(originalHostname%20!==%20'www.youtube-nocookie.com')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20url.hostname%20=%20'www.youtube-nocookie.com';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20onError%20=%20(event)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20url.hostname%20=%20originalHostname;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20videoElement.src%20=%20url.href;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20event.stopImmediatePropagation();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Configure%20auto-play%20correctly%20depending%20on%20if%20the%20video's%20preview%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20loaded,%20otherwise%20it%20doesn't%20allow%20autoplay.%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20allowString%20=%20videoElement.getAttribute('allow')%20%7C%7C%20'';%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20allowed%20=%20new%20Set(allowString.split(';').map((s)%20=%3E%20s.trim()));%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.autoplay)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20allowed.add('autoplay');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20url.searchParams.set('autoplay',%20'1');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20allowed.delete('autoplay');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20url.searchParams.delete('autoplay');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20allowString%20=%20Array.from(allowed).join(';%20');%0A%20%20%20%20%20%20%20%20%20%20%20%20videoElement.setAttribute('allow',%20allowString);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20videoElement.src%20=%20url.href;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20onError;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Fades%20the%20given%20element%20in/out.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20element%0A%20%20%20%20%20%20%20%20%20*%20%20%20The%20element%20to%20fade%20in%20or%20out.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bnumber%7D%20interval%0A%20%20%20%20%20%20%20%20%20*%20%20%20Frequency%20of%20opacity%20updates%20(ms).%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean%7D%20fadeIn%0A%20%20%20%20%20%20%20%20%20*%20%20%20True%20if%20the%20element%20should%20fade%20in%20instead%20of%20out.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPromise%3Cvoid%3E%7D%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20Promise%20that%20resolves%20when%20the%20fade%20in/out%20is%20complete.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20fadeElement(element,%20interval,%20fadeIn)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20Promise((resolve)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20opacity%20=%20fadeIn%20?%200%20:%201;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20originStyle%20=%20element.style.cssText;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20fadeOut%20=%20setInterval(function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20opacity%20+=%20fadeIn%20?%200.03%20:%20-0.03;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20element.style.cssText%20=%20originStyle%20+%20%60opacity:%20$%7Bopacity%7D;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(opacity%20%3C=%200%20%7C%7C%20opacity%20%3E=%201)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clearInterval(fadeOut);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resolve();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%20interval);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Fades%20the%20given%20element%20out.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20element%0A%20%20%20%20%20%20%20%20%20*%20%20%20The%20element%20to%20fade%20out.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPromise%3Cvoid%3E%7D%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20Promise%20that%20resolves%20when%20the%20fade%20out%20is%20complete.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20fadeOutElement(element)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.fadeElement(element,%2010,%20false);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Fades%20the%20given%20element%20in.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20element%0A%20%20%20%20%20%20%20%20%20*%20%20%20The%20element%20to%20fade%20in.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BPromise%3Cvoid%3E%7D%0A%20%20%20%20%20%20%20%20%20*%20%20%20%20Promise%20that%20resolves%20when%20the%20fade%20in%20is%20complete.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20fadeInElement(element)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.fadeElement(element,%2010,%20true);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20The%20function%20that's%20called%20when%20the%20user%20clicks%20to%20load%20some%20content.%0A%20%20%20%20%20%20%20%20%20*%20Unblocks%20the%20content,%20puts%20it%20back%20in%20the%20page,%20and%20removes%20the%0A%20%20%20%20%20%20%20%20%20*%20placeholder.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLIFrameElement%7D%20originalElement%0A%20%20%20%20%20%20%20%20%20*%20%20%20The%20original%20tracking%20element.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20replacementElement%0A%20%20%20%20%20%20%20%20%20*%20%20%20The%20placeholder%20element.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20clickFunction(originalElement,%20replacementElement)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20clicked%20=%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20handleClick%20=%20(e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Ensure%20that%20the%20click%20is%20created%20by%20a%20user%20event%20&%20prevent%20double%20clicks%20from%20adding%20more%20animations%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(e.isTrusted%20&&%20!clicked)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20e.stopPropagation();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.isUnblocked%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clicked%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20isLogin%20=%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Logins%20triggered%20by%20user%20click%20means%20they%20were%20not%20triggered%20by%20the%20surrogate%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20isSurrogateLogin%20=%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20clickElement%20=%20e.srcElement;%20//%20Object.assign(%7B%7D,%20e)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.replaceSettings.type%20===%20'loginButton')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20isLogin%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20action%20=%20this.entity%20===%20'Youtube'%20?%20'block-ctl-yt'%20:%20'block-ctl-fb';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20promise/prefer-await-to-then%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unblockClickToLoadContent(%7B%20entity:%20this.entity,%20action,%20isLogin,%20isSurrogateLogin%20%7D).then((response)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20user%20rejected%20confirmation%20modal%20and%20content%20was%20not%20unblocked,%20inform%20surrogate%20and%20stop.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(response%20&&%20response.type%20===%20'ddg-ctp-user-cancel')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20abortSurrogateConfirmation(this.entity);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20parent%20=%20replacementElement.parentNode;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20The%20placeholder%20was%20removed%20from%20the%20DOM%20while%20we%20loaded%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20the%20original%20content,%20give%20up.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!parent)%20return;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20we%20allow%20everything%20when%20this%20element%20is%20clicked,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20notify%20surrogate%20to%20enable%20SDK%20and%20replace%20original%20element.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.clickAction.type%20===%20'allowFull')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20parent.replaceChild(originalElement,%20replacementElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.dispatchEvent(window,%20'ddg-ctp-load-sdk');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Create%20a%20container%20for%20the%20new%20FB%20element%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20fbContainer%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbContainer.style.cssText%20=%20styles.wrapperDiv;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20fadeIn%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fadeIn.style.cssText%20=%20'display:%20none;%20opacity:%200;';%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Loading%20animation%20(FB%20can%20take%20some%20time%20to%20load)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20loadingImg%20=%20document.createElement('img');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loadingImg.setAttribute('src',%20loadingImages%5Bthis.getMode()%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loadingImg.setAttribute('height',%20'14px');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loadingImg.style.cssText%20=%20styles.loadingImg;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Always%20add%20the%20animation%20to%20the%20button,%20regardless%20of%20click%20source%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(clickElement.nodeName%20===%20'BUTTON')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20clickElement.firstElementChild.insertBefore(loadingImg,%20clickElement.firstElementChild.firstChild);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20try%20to%20find%20the%20button%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20el%20=%20clickElement;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20button%20=%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20while%20(button%20===%20null%20&&%20el%20!==%20null)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20button%20=%20el.querySelector('button');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20el%20=%20el.parentElement;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(button)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20button.firstElementChild.insertBefore(loadingImg,%20button.firstElementChild.firstChild);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbContainer.appendChild(fadeIn);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20fbElement;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20onError%20=%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20switch%20(this.clickAction.type)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20case%20'iFrame':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbElement%20=%20this.createFBIFrame();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20case%20'youtube-video':%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20onError%20=%20this.adjustYouTubeVideoElement(originalElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbElement%20=%20originalElement;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default:%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbElement%20=%20originalElement;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Modify%20the%20overlay%20to%20include%20a%20Facebook%20iFrame,%20which%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20starts%20invisible.%20Once%20loaded,%20fade%20out%20and%20remove%20the%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20overlay%20then%20fade%20in%20the%20Facebook%20content.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20parent.replaceChild(fbContainer,%20replacementElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbContainer.appendChild(replacementElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fadeIn.appendChild(fbElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbElement.addEventListener(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'load',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20async%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20await%20this.fadeOutElement(replacementElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbContainer.replaceWith(fbElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.dispatchEvent(fbElement,%20'ddg-ctp-placeholder-clicked');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20await%20this.fadeInElement(fadeIn);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Focus%20on%20new%20element%20for%20screen%20readers.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbElement.focus();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20once:%20true%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Note:%20This%20event%20only%20fires%20on%20Firefox,%20on%20Chrome%20the%20frame's%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20load%20event%20will%20always%20fire.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(onError)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fbElement.addEventListener('error',%20onError,%20%7B%20once:%20true%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20If%20this%20is%20a%20login%20button,%20show%20modal%20if%20needed%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.replaceSettings.type%20===%20'loginButton'%20&&%20entityData%5Bthis.entity%5D.shouldShowLoginModal)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20(e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Even%20if%20the%20user%20cancels%20the%20login%20attempt,%20consider%20Facebook%20Click%20to%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Load%20to%20have%20been%20active%20on%20the%20page%20if%20the%20user%20reports%20the%20page%20as%20broken.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.entity%20===%20'Facebook,%20Inc.')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20notifyFacebookLogin();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20handleUnblockConfirmation(this.platform.name,%20this.entity,%20handleClick,%20e);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20handleClick;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Based%20on%20the%20current%20Platform%20where%20the%20Widget%20is%20running,%20it%20will%0A%20%20%20%20%20%20%20%20%20*%20return%20if%20the%20new%20layout%20using%20Web%20Components%20is%20supported%20or%20not.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20shouldUseCustomElement()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20platformsWithWebComponentsEnabled.includes(this.platform.name);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Based%20on%20the%20current%20Platform%20where%20the%20Widget%20is%20running,%20it%20will%0A%20%20%20%20%20%20%20%20%20*%20return%20if%20it%20is%20one%20of%20our%20mobile%20apps%20or%20not.%20This%20should%20be%20used%20to%0A%20%20%20%20%20%20%20%20%20*%20define%20which%20layout%20to%20use%20between%20Mobile%20and%20Desktop%20Platforms%20variations.%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7Bboolean%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20isMobilePlatform()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20mobilePlatforms.includes(this.platform.name);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Replace%20the%20given%20tracking%20element%20with%20the%20given%20placeholder.%0A%20%20%20%20%20*%20Notes:%0A%20%20%20%20%20*%20%201.%20This%20function%20also%20dispatches%20events%20targeting%20the%20original%20and%0A%20%20%20%20%20*%20%20%20%20%20placeholder%20elements.%20That%20way,%20the%20surrogate%20scripts%20can%20use%20the%20event%0A%20%20%20%20%20*%20%20%20%20%20targets%20to%20keep%20track%20of%20which%20placeholder%20corresponds%20to%20which%20tracking%0A%20%20%20%20%20*%20%20%20%20%20element.%0A%20%20%20%20%20*%20%202.%20To%20achieve%20that,%20the%20original%20and%20placeholder%20elements%20must%20be%20in%20the%20DOM%0A%20%20%20%20%20*%20%20%20%20%20at%20the%20time%20the%20events%20are%20dispatched.%20Otherwise,%20the%20events%20will%20not%0A%20%20%20%20%20*%20%20%20%20%20bubble%20up%20and%20the%20surrogate%20script%20will%20miss%20them.%0A%20%20%20%20%20*%20%203.%20Placeholder%20must%20be%20shown%20immediately%20(to%20avoid%20a%20flicker%20for%20the%20user),%0A%20%20%20%20%20*%20%20%20%20%20but%20the%20events%20must%20only%20be%20sent%20once%20the%20document%20(and%20therefore%0A%20%20%20%20%20*%20%20%20%20%20surrogate%20scripts)%20have%20loaded.%0A%20%20%20%20%20*%20%204.%20Therefore,%20we%20hide%20the%20element%20until%20the%20page%20has%20loaded,%20then%20dispatch%0A%20%20%20%20%20*%20%20%20%20%20the%20events%20after%20page%20load,%20and%20then%20remove%20the%20element%20from%20the%20DOM.%0A%20%20%20%20%20*%20%205.%20The%20%22ddg-ctp-ready%22%20event%20needs%20to%20be%20dispatched%20_after_%20the%20element%0A%20%20%20%20%20*%20%20%20%20%20replacement%20events%20have%20fired.%20That%20is%20why%20a%20setTimeout%20is%20required%0A%20%20%20%20%20*%20%20%20%20%20before%20dispatching%20%22ddg-ctp-ready%22.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%20Also%20note,%20this%20all%20assumes%20that%20the%20surrogate%20script%20that%20needs%20these%0A%20%20%20%20%20*%20%20events%20will%20not%20be%20loaded%20asynchronously%20after%20the%20page%20has%20finished%0A%20%20%20%20%20*%20%20loading.%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20@param%20%7BDuckWidget%7D%20widget%0A%20%20%20%20%20*%20%20%20The%20DuckWidget%20associated%20with%20the%20tracking%20element.%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20trackingElement%0A%20%20%20%20%20*%20%20%20The%20tracking%20element%20on%20the%20page%20to%20replace.%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20placeholderElement%0A%20%20%20%20%20*%20%20%20The%20placeholder%20element%20that%20should%20be%20shown%20instead.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20replaceTrackingElement(widget,%20trackingElement,%20placeholderElement)%20%7B%0A%20%20%20%20%20%20%20%20//%20In%20some%20situations%20(e.g.%20YouTube%20Click%20to%20Load%20previews%20are%0A%20%20%20%20%20%20%20%20//%20enabled/disabled),%20a%20second%20placeholder%20will%20be%20shown%20for%20a%20tracking%0A%20%20%20%20%20%20%20%20//%20element.%0A%20%20%20%20%20%20%20%20const%20elementToReplace%20=%20widget.placeholderElement%20%7C%7C%20trackingElement;%0A%0A%20%20%20%20%20%20%20%20//%20Note%20the%20placeholder%20element,%20so%20that%20it%20can%20also%20be%20replaced%20later%20if%0A%20%20%20%20%20%20%20%20//%20necessary.%0A%20%20%20%20%20%20%20%20widget.placeholderElement%20=%20placeholderElement;%0A%0A%20%20%20%20%20%20%20%20//%20First%20hide%20the%20element,%20since%20we%20need%20to%20keep%20it%20in%20the%20DOM%20until%20the%0A%20%20%20%20%20%20%20%20//%20events%20have%20been%20dispatched.%0A%20%20%20%20%20%20%20%20const%20originalDisplay%20=%20%5BelementToReplace.style.getPropertyValue('display'),%20elementToReplace.style.getPropertyPriority('display')%5D;%0A%20%20%20%20%20%20%20%20elementToReplace.style.setProperty('display',%20'none',%20'important');%0A%0A%20%20%20%20%20%20%20%20//%20Add%20the%20placeholder%20element%20to%20the%20page.%0A%20%20%20%20%20%20%20%20elementToReplace.parentElement.insertBefore(placeholderElement,%20elementToReplace);%0A%0A%20%20%20%20%20%20%20%20//%20While%20the%20placeholder%20is%20shown%20(and%20original%20element%20hidden)%0A%20%20%20%20%20%20%20%20//%20synchronously,%20the%20events%20are%20dispatched%20(and%20original%20element%20removed%0A%20%20%20%20%20%20%20%20//%20from%20the%20DOM)%20asynchronously%20after%20the%20page%20has%20finished%20loading.%0A%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20promise/prefer-await-to-then%0A%20%20%20%20%20%20%20%20afterPageLoad.then(()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20With%20page%20load%20complete,%20and%20both%20elements%20in%20the%20DOM,%20the%20events%20can%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20be%20dispatched.%0A%20%20%20%20%20%20%20%20%20%20%20%20widget.dispatchEvent(trackingElement,%20'ddg-ctp-tracking-element');%0A%20%20%20%20%20%20%20%20%20%20%20%20widget.dispatchEvent(placeholderElement,%20'ddg-ctp-placeholder-element');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Once%20the%20events%20are%20sent,%20the%20tracking%20element%20(or%20previous%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20placeholder)%20can%20finally%20be%20removed%20from%20the%20DOM.%0A%20%20%20%20%20%20%20%20%20%20%20%20elementToReplace.remove();%0A%20%20%20%20%20%20%20%20%20%20%20%20elementToReplace.style.setProperty('display',%20...originalDisplay);%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Creates%20a%20placeholder%20element%20for%20the%20given%20tracking%20element%20and%20replaces%0A%20%20%20%20%20*%20it%20on%20the%20page.%0A%20%20%20%20%20*%20@param%20%7BDuckWidget%7D%20widget%0A%20%20%20%20%20*%20%20%20The%20CTL%20'widget'%20associated%20with%20the%20tracking%20element.%0A%20%20%20%20%20*%20@param%20%7BHTMLIFrameElement%7D%20trackingElement%0A%20%20%20%20%20*%20%20%20The%20tracking%20element%20on%20the%20page%20that%20should%20be%20replaced%20with%20a%20placeholder.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20createPlaceholderElementAndReplace(widget,%20trackingElement)%20%7B%0A%20%20%20%20%20%20%20%20if%20(widget.replaceSettings.type%20===%20'blank')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20replaceTrackingElement(widget,%20trackingElement,%20document.createElement('div'));%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if%20(widget.replaceSettings.type%20===%20'loginButton')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20icon%20=%20widget.replaceSettings.icon;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Create%20a%20button%20to%20replace%20old%20element%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(widget.shouldUseCustomElement())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20facebookLoginButton%20=%20new%20DDGCtlLoginButton(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20devMode,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20label:%20widget.replaceSettings.buttonTextUnblockLogin,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hoverText:%20widget.replaceSettings.popupBodyText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20logoIcon:%20facebookLogo,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20originalElement:%20trackingElement,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20learnMore:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Localized%20strings%20for%20%22Learn%20More%22%20link.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20readAbout:%20sharedStrings.readAbout,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20learnMore:%20sharedStrings.learnMore,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20onClick:%20widget.clickFunction.bind(widget),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D).element;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20facebookLoginButton.classList.add('fb-login-button',%20'FacebookLogin__button');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20facebookLoginButton.appendChild(makeFontFaceStyleElement());%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceTrackingElement(widget,%20trackingElement,%20facebookLoginButton);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20button,%20container%20%7D%20=%20makeLoginButton(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20widget.replaceSettings.buttonText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20widget.getMode(),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20widget.replaceSettings.popupBodyText,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20icon,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20trackingElement,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20button.addEventListener('click',%20widget.clickFunction(trackingElement,%20container));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceTrackingElement(widget,%20trackingElement,%20container);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Facebook%0A%20%20%20%20%20%20%20%20if%20(widget.replaceSettings.type%20===%20'dialog')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20ctl.addDebugFlag();%0A%20%20%20%20%20%20%20%20%20%20%20%20ctl.messaging.notify('updateFacebookCTLBreakageFlags',%20%7B%20ctlFacebookPlaceholderShown:%20true%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(widget.shouldUseCustomElement())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Creates%20a%20custom%20HTML%20element%20with%20the%20placeholder%20element%20for%20blocked%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20embedded%20content.%20The%20constructor%20gets%20a%20list%20of%20parameters%20with%20the%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20content%20and%20event%20handlers%20for%20this%20HTML%20element.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20mobileBlockedPlaceholder%20=%20new%20DDGCtlPlaceholderBlockedElement(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20devMode,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20title:%20widget.replaceSettings.infoTitle,%20//%20Card%20title%20text%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20body:%20widget.replaceSettings.infoText,%20//%20Card%20body%20text%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unblockBtnText:%20widget.replaceSettings.buttonText,%20//%20Unblock%20button%20text%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20useSlimCard:%20false,%20//%20Flag%20for%20using%20less%20padding%20on%20card%20(ie%20YT%20CTL%20on%20mobile)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20originalElement:%20trackingElement,%20//%20The%20original%20element%20this%20placeholder%20is%20replacing.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20learnMore:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Localized%20strings%20for%20%22Learn%20More%22%20link.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20readAbout:%20sharedStrings.readAbout,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20learnMore:%20sharedStrings.learnMore,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20onButtonClick:%20widget.clickFunction.bind(widget),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mobileBlockedPlaceholder.appendChild(makeFontFaceStyleElement());%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceTrackingElement(widget,%20trackingElement,%20mobileBlockedPlaceholder);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20showExtraUnblockIfShortPlaceholder(null,%20mobileBlockedPlaceholder);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20icon%20=%20widget.replaceSettings.icon;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20button%20=%20makeButton(widget.replaceSettings.buttonText,%20widget.getMode());%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20textButton%20=%20makeTextButton(widget.replaceSettings.buttonText,%20widget.getMode());%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20contentBlock,%20shadowRoot%20%7D%20=%20createContentBlock(widget,%20button,%20textButton,%20icon);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20button.addEventListener('click',%20widget.clickFunction(trackingElement,%20contentBlock));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20textButton.addEventListener('click',%20widget.clickFunction(trackingElement,%20contentBlock));%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceTrackingElement(widget,%20trackingElement,%20contentBlock);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20showExtraUnblockIfShortPlaceholder(shadowRoot,%20contentBlock);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20YouTube%0A%20%20%20%20%20%20%20%20if%20(widget.replaceSettings.type%20===%20'youtube-video')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20ctl.addDebugFlag();%0A%20%20%20%20%20%20%20%20%20%20%20%20ctl.messaging.notify('updateYouTubeCTLAddedFlag',%20%7B%20youTubeCTLAddedFlag:%20true%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20replaceYouTubeCTL(trackingElement,%20widget);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Subscribe%20to%20changes%20to%20youtubePreviewsEnabled%20setting%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20and%20update%20the%20CTL%20state%0A%20%20%20%20%20%20%20%20%20%20%20%20ctl.messaging.subscribe('setYoutubePreviewsEnabled',%20(%7B%20value%20%7D)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20isYoutubePreviewsEnabled%20=%20value;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceYouTubeCTL(trackingElement,%20widget);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7BHTMLIFrameElement%7D%20trackingElement%0A%20%20%20%20%20*%20%20%20The%20original%20tracking%20element%20(YouTube%20video%20iframe)%0A%20%20%20%20%20*%20@param%20%7BDuckWidget%7D%20widget%0A%20%20%20%20%20*%20%20%20The%20CTL%20'widget'%20associated%20with%20the%20tracking%20element.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20replaceYouTubeCTL(trackingElement,%20widget)%20%7B%0A%20%20%20%20%20%20%20%20//%20Skip%20replacing%20tracking%20element%20if%20it%20has%20already%20been%20unblocked%0A%20%20%20%20%20%20%20%20if%20(widget.isUnblocked)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if%20(isYoutubePreviewsEnabled%20===%20true)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Show%20YouTube%20Preview%20for%20embedded%20video%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20oldPlaceholder%20=%20widget.placeholderElement;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20youTubePreview,%20shadowRoot%20%7D%20=%20createYouTubePreview(trackingElement,%20widget);%0A%20%20%20%20%20%20%20%20%20%20%20%20resizeElementToMatch(oldPlaceholder%20%7C%7C%20trackingElement,%20youTubePreview);%0A%20%20%20%20%20%20%20%20%20%20%20%20replaceTrackingElement(widget,%20trackingElement,%20youTubePreview);%0A%20%20%20%20%20%20%20%20%20%20%20%20showExtraUnblockIfShortPlaceholder(shadowRoot,%20youTubePreview);%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Block%20YouTube%20embedded%20video%20and%20display%20blocking%20dialog%0A%20%20%20%20%20%20%20%20%20%20%20%20widget.autoplay%20=%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20oldPlaceholder%20=%20widget.placeholderElement;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(widget.shouldUseCustomElement())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Creates%20a%20custom%20HTML%20element%20with%20the%20placeholder%20element%20for%20blocked%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20embedded%20content.%20The%20constructor%20gets%20a%20list%20of%20parameters%20with%20the%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20content%20and%20event%20handlers%20for%20this%20HTML%20element.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20mobileBlockedPlaceholderElement%20=%20new%20DDGCtlPlaceholderBlockedElement(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20devMode,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20title:%20widget.replaceSettings.infoTitle,%20//%20Card%20title%20text%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20body:%20widget.replaceSettings.infoText,%20//%20Card%20body%20text%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unblockBtnText:%20widget.replaceSettings.buttonText,%20//%20Unblock%20button%20text%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20useSlimCard:%20true,%20//%20Flag%20for%20using%20less%20padding%20on%20card%20(ie%20YT%20CTL%20on%20mobile)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20originalElement:%20trackingElement,%20//%20The%20original%20element%20this%20placeholder%20is%20replacing.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20learnMore:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Localized%20strings%20for%20%22Learn%20More%22%20link.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20readAbout:%20sharedStrings.readAbout,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20learnMore:%20sharedStrings.learnMore,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20withToggle:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Toggle%20config%20to%20be%20displayed%20in%20the%20bottom%20of%20the%20placeholder%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20isActive:%20false,%20//%20Toggle%20state%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20dataKey:%20'yt-preview-toggle',%20//%20data-key%20attribute%20for%20button%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20label:%20widget.replaceSettings.previewToggleText,%20//%20Text%20to%20be%20presented%20with%20toggle%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20size:%20widget.isMobilePlatform()%20?%20'lg'%20:%20'md',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20onClick:%20()%20=%3E%20ctl.messaging.notify('setYoutubePreviewsEnabled',%20%7B%20youtubePreviewsEnabled:%20true%20%7D),%20//%20Toggle%20click%20callback%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20withFeedback:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20label:%20sharedStrings.shareFeedback,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20onClick:%20()%20=%3E%20openShareFeedbackPage(),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20onButtonClick:%20widget.clickFunction.bind(widget),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mobileBlockedPlaceholderElement.appendChild(makeFontFaceStyleElement());%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mobileBlockedPlaceholderElement.id%20=%20trackingElement.id;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resizeElementToMatch(oldPlaceholder%20%7C%7C%20trackingElement,%20mobileBlockedPlaceholderElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceTrackingElement(widget,%20trackingElement,%20mobileBlockedPlaceholderElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20showExtraUnblockIfShortPlaceholder(null,%20mobileBlockedPlaceholderElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20blockingDialog,%20shadowRoot%20%7D%20=%20createYouTubeBlockingDialog(trackingElement,%20widget);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resizeElementToMatch(oldPlaceholder%20%7C%7C%20trackingElement,%20blockingDialog);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20replaceTrackingElement(widget,%20trackingElement,%20blockingDialog);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20showExtraUnblockIfShortPlaceholder(shadowRoot,%20blockingDialog);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hideInfoTextIfNarrowPlaceholder(shadowRoot,%20blockingDialog,%20460);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Show%20the%20extra%20unblock%20link%20in%20the%20header%20if%20the%20placeholder%20or%0A%20%20%20%20%20*%20its%20parent%20is%20too%20short%20for%20the%20normal%20unblock%20button%20to%20be%20visible.%0A%20%20%20%20%20*%20Note:%20This%20does%20not%20take%20into%20account%20the%20placeholder's%20vertical%0A%20%20%20%20%20*%20%20%20%20%20%20%20position%20in%20the%20parent%20element.%0A%20%20%20%20%20*%20@param%20%7BShadowRoot?%7D%20shadowRoot%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20placeholder%20Placeholder%20for%20tracking%20element%0A%20%20%20%20%20*/%0A%20%20%20%20function%20showExtraUnblockIfShortPlaceholder(shadowRoot,%20placeholder)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!placeholder.parentElement)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20const%20parentStyles%20=%20window.getComputedStyle(placeholder.parentElement);%0A%20%20%20%20%20%20%20%20//%20Inline%20elements,%20like%20span%20or%20p,%20don't%20have%20a%20height%20value%20that%20we%20can%20use%20because%20they're%0A%20%20%20%20%20%20%20%20//%20not%20a%20%22block%22%20like%20element%20with%20defined%20sizes.%20Because%20we%20skip%20this%20check%20on%20%22inline%22%0A%20%20%20%20%20%20%20%20//%20parents,%20it%20might%20be%20necessary%20to%20traverse%20up%20the%20DOM%20tree%20until%20we%20find%20the%20nearest%20non%0A%20%20%20%20%20%20%20%20//%20%22inline%22%20parent%20to%20get%20a%20reliable%20height%20for%20this%20check.%0A%20%20%20%20%20%20%20%20if%20(parentStyles.display%20===%20'inline')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20const%20%7B%20height:%20placeholderHeight%20%7D%20=%20placeholder.getBoundingClientRect();%0A%20%20%20%20%20%20%20%20const%20%7B%20height:%20parentHeight%20%7D%20=%20placeholder.parentElement.getBoundingClientRect();%0A%0A%20%20%20%20%20%20%20%20if%20((placeholderHeight%20%3E%200%20&&%20placeholderHeight%20%3C=%20200)%20%7C%7C%20(parentHeight%20%3E%200%20&&%20parentHeight%20%3C=%20230))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(shadowRoot)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7BHTMLElement?%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20titleRowTextButton%20=%20shadowRoot.querySelector(%60#$%7BtitleID%20+%20'TextButton'%7D%60);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(titleRowTextButton)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20titleRowTextButton.style.display%20=%20'block';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Avoid%20the%20placeholder%20being%20taller%20than%20the%20containing%20element%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20and%20overflowing.%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7BHTMLElement?%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20blockedDiv%20=%20shadowRoot?.querySelector('.DuckDuckGoSocialContainer')%20%7C%7C%20placeholder;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(blockedDiv)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20blockedDiv.style.minHeight%20=%20'initial';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20blockedDiv.style.maxHeight%20=%20parentHeight%20+%20'px';%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20blockedDiv.style.overflow%20=%20'hidden';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Hide%20the%20info%20text%20(and%20move%20the%20%22Learn%20More%22%20link)%20if%20the%20placeholder%20is%20too%0A%20%20%20%20%20*%20narrow.%0A%20%20%20%20%20*%20@param%20%7BShadowRoot%7D%20shadowRoot%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20placeholder%20Placeholder%20for%20tracking%20element%0A%20%20%20%20%20*%20@param%20%7Bnumber%7D%20narrowWidth%0A%20%20%20%20%20*%20%20%20%20Maximum%20placeholder%20width%20(in%20pixels)%20for%20the%20placeholder%20to%20be%20considered%0A%20%20%20%20%20*%20%20%20%20narrow.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20hideInfoTextIfNarrowPlaceholder(shadowRoot,%20placeholder,%20narrowWidth)%20%7B%0A%20%20%20%20%20%20%20%20const%20%7B%20width:%20placeholderWidth%20%7D%20=%20placeholder.getBoundingClientRect();%0A%20%20%20%20%20%20%20%20if%20(placeholderWidth%20%3E%200%20&&%20placeholderWidth%20%3C=%20narrowWidth)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20buttonContainer%20=%20shadowRoot.querySelector('.DuckDuckGoButton.primary')?.parentElement;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20contentTitle%20=%20shadowRoot.getElementById('contentTitle');%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20infoText%20=%20shadowRoot.getElementById('infoText');%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%20@type%20%7BHTMLElement?%7D%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20learnMoreLink%20=%20shadowRoot.getElementById('learnMoreLink');%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20These%20elements%20will%20exist,%20but%20this%20check%20keeps%20TypeScript%20happy.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!buttonContainer%20%7C%7C%20!contentTitle%20%7C%7C%20!infoText%20%7C%7C%20!learnMoreLink)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Remove%20the%20information%20text.%0A%20%20%20%20%20%20%20%20%20%20%20%20infoText.remove();%0A%20%20%20%20%20%20%20%20%20%20%20%20learnMoreLink.remove();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Append%20the%20%22Learn%20More%22%20link%20to%20the%20title.%0A%20%20%20%20%20%20%20%20%20%20%20%20contentTitle.innerText%20+=%20'.%20';%0A%20%20%20%20%20%20%20%20%20%20%20%20learnMoreLink.style.removeProperty('font-size');%0A%20%20%20%20%20%20%20%20%20%20%20%20contentTitle.appendChild(learnMoreLink);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Improve%20margin/padding,%20to%20ensure%20as%20much%20is%20displayed%20as%20possible.%0A%20%20%20%20%20%20%20%20%20%20%20%20buttonContainer.style.removeProperty('margin');%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/*********************************************************%0A%20%20%20%20%20*%20%20Messaging%20to%20surrogates%20&%20extension%0A%20%20%20%20%20*********************************************************/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20unblockClickToLoadContentRequest%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20entity%0A%20%20%20%20%20*%20%20%20The%20entity%20to%20unblock%20requests%20for%20(e.g.%20%22Facebook,%20Inc.%22).%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20%5BisLogin=false%5D%0A%20%20%20%20%20*%20%20%20True%20if%20we%20should%20%22allow%20social%20login%22,%20defaults%20to%20false.%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20%5BisSurrogateLogin=false%5D%0A%20%20%20%20%20*%20%20%20True%20if%20logins%20triggered%20by%20the%20surrogate%20(custom%20login),%20False%20if%20login%20trigger%0A%20%20%20%20%20*%20%20%20by%20user%20clicking%20in%20our%20Login%20button%20placeholder.%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20action%0A%20%20%20%20%20*%20%20%20The%20Click%20to%20Load%20blocklist%20rule%20action%20(e.g.%20%22block-ctl-fb%22)%20that%20should%0A%20%20%20%20%20*%20%20%20be%20allowed.%20Important%20since%20in%20the%20future%20there%20might%20be%20multiple%20types%20of%0A%20%20%20%20%20*%20%20%20embedded%20content%20from%20the%20same%20entity%20that%20the%20user%20can%20allow%0A%20%20%20%20%20*%20%20%20independently.%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Send%20a%20message%20to%20the%20background%20to%20unblock%20requests%20for%20the%20given%20entity%20for%0A%20%20%20%20%20*%20the%20page.%0A%20%20%20%20%20*%20@param%20%7BunblockClickToLoadContentRequest%7D%20message%0A%20%20%20%20%20*%20@see%20%7B@link%20ddg-ctp-unblockClickToLoadContent-complete%7D%20for%20the%20response%20handler.%0A%20%20%20%20%20*%20@returns%20%7BPromise%3Cany%3E%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20unblockClickToLoadContent(message)%20%7B%0A%20%20%20%20%20%20%20%20return%20ctl.messaging.request('unblockClickToLoadContent',%20message);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Handle%20showing%20a%20web%20modal%20to%20request%20the%20user%20for%20a%20confirmation%20or,%20in%20some%20platforms,%0A%20%20%20%20%20*%20proceed%20with%20the%20%22acceptFunction%22%20call%20and%20let%20the%20platform%20handle%20with%20each%20request%0A%20%20%20%20%20*%20accordingly.%0A%20%20%20%20%20*%20@param%20%7Bimport('../utils').Platform%5B%22name%22%5D%7D%20platformName%0A%20%20%20%20%20*%20%20%20The%20current%20platform%20name%20where%20Click%20to%20Load%20is%20running%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20entity%0A%20%20%20%20%20*%20%20%20The%20entity%20to%20unblock%20requests%20for%20(e.g.%20%22Facebook,%20Inc.%22)%20if%20the%20user%0A%20%20%20%20%20*%20%20%20clicks%20to%20proceed.%0A%20%20%20%20%20*%20@param%20%7Bfunction%7D%20acceptFunction%0A%20%20%20%20%20*%20%20%20The%20function%20to%20call%20if%20the%20user%20has%20clicked%20to%20proceed.%0A%20%20%20%20%20*%20@param%20%7B...any%7D%20acceptFunctionParams%0A%20%20%20%20%20*%20%20%20The%20parameters%20passed%20to%20acceptFunction%20when%20it%20is%20called.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20handleUnblockConfirmation(platformName,%20entity,%20acceptFunction,%20...acceptFunctionParams)%20%7B%0A%20%20%20%20%20%20%20%20//%20In%20our%20mobile%20platforms,%20we%20want%20to%20show%20a%20native%20UI%20to%20request%20user%20unblock%0A%20%20%20%20%20%20%20%20//%20confirmation.%20In%20these%20cases%20we%20send%20directly%20the%20unblock%20request%20to%20the%20platform%0A%20%20%20%20%20%20%20%20//%20and%20the%20platform%20chooses%20how%20to%20best%20handle%20it.%0A%20%20%20%20%20%20%20%20if%20(platformsWithNativeModalSupport.includes(platformName))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20acceptFunction(...acceptFunctionParams);%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20By%20default,%20for%20other%20platforms%20(ie%20Extension),%20we%20show%20a%20web%20modal%20with%20a%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20confirmation%20request%20to%20the%20user%20before%20we%20proceed%20to%20unblock%20the%20content.%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20makeModal(entity,%20acceptFunction,%20...acceptFunctionParams);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Set%20the%20ctlFacebookLogin%20breakage%20flag%20for%20the%20page,%20to%20indicate%20that%20the%0A%20%20%20%20%20*%20Facebook%20Click%20to%20Load%20login%20flow%20had%20started%20if%20the%20user%20should%20then%20report%0A%20%20%20%20%20*%20the%20website%20as%20broken.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20notifyFacebookLogin()%20%7B%0A%20%20%20%20%20%20%20%20ctl.addDebugFlag();%0A%20%20%20%20%20%20%20%20ctl.messaging.notify('updateFacebookCTLBreakageFlags',%20%7B%20ctlFacebookLogin:%20true%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Unblock%20the%20entity,%20close%20the%20login%20dialog%20and%20continue%20the%20Facebook%20login%0A%20%20%20%20%20*%20flow.%20Called%20after%20the%20user%20clicks%20to%20proceed%20after%20the%20warning%20dialog%20is%0A%20%20%20%20%20*%20shown.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20entity%0A%20%20%20%20%20*/%0A%20%20%20%20async%20function%20runLogin(entity)%20%7B%0A%20%20%20%20%20%20%20%20if%20(entity%20===%20'Facebook,%20Inc.')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20notifyFacebookLogin();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20action%20=%20entity%20===%20'Youtube'%20?%20'block-ctl-yt'%20:%20'block-ctl-fb';%0A%20%20%20%20%20%20%20%20const%20response%20=%20await%20unblockClickToLoadContent(%7B%20entity,%20action,%20isLogin:%20true,%20isSurrogateLogin:%20true%20%7D);%0A%20%20%20%20%20%20%20%20//%20If%20user%20rejected%20confirmation%20modal%20and%20content%20was%20not%20unblocked,%20inform%20surrogate%20and%20stop.%0A%20%20%20%20%20%20%20%20if%20(response%20&&%20response.type%20===%20'ddg-ctp-user-cancel')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20abortSurrogateConfirmation(this.entity);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20//%20Communicate%20with%20surrogate%20to%20run%20login%0A%20%20%20%20%20%20%20%20originalWindowDispatchEvent(%0A%20%20%20%20%20%20%20%20%20%20%20%20createCustomEvent('ddg-ctp-run-login',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20detail:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20entity,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D),%0A%20%20%20%20%20%20%20%20);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Communicate%20with%20the%20surrogate%20to%20abort%20(ie%20Abort%20login%20when%20user%20rejects%20confirmation%20dialog)%0A%20%20%20%20%20*%20Called%20after%20the%20user%20cancel%20from%20a%20warning%20dialog.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20entity%0A%20%20%20%20%20*/%0A%20%20%20%20function%20abortSurrogateConfirmation(entity)%20%7B%0A%20%20%20%20%20%20%20%20originalWindowDispatchEvent(%0A%20%20%20%20%20%20%20%20%20%20%20%20createCustomEvent('ddg-ctp-cancel-modal',%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20detail:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20entity,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D),%0A%20%20%20%20%20%20%20%20);%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20openShareFeedbackPage()%20%7B%0A%20%20%20%20%20%20%20%20ctl.messaging.notify('openShareFeedbackPage');%0A%20%20%20%20%7D%0A%0A%20%20%20%20/*********************************************************%0A%20%20%20%20%20*%20%20Widget%20building%20blocks%0A%20%20%20%20%20*********************************************************/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Creates%20a%20%22Learn%20more%22%20link%20element.%0A%20%20%20%20%20*%20@param%20%7BdisplayMode%7D%20%5Bmode='lightMode'%5D%0A%20%20%20%20%20*%20@returns%20%7BHTMLAnchorElement%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20getLearnMoreLink(mode%20=%20'lightMode')%20%7B%0A%20%20%20%20%20%20%20%20const%20linkElement%20=%20document.createElement('a');%0A%20%20%20%20%20%20%20%20linkElement.style.cssText%20=%20styles.generalLink%20+%20styles%5Bmode%5D.linkFont;%0A%20%20%20%20%20%20%20%20linkElement.ariaLabel%20=%20sharedStrings.readAbout;%0A%20%20%20%20%20%20%20%20linkElement.href%20=%20'https://help.duckduckgo.com/duckduckgo-help-pages/privacy/embedded-content-protection/';%0A%20%20%20%20%20%20%20%20linkElement.target%20=%20'_blank';%0A%20%20%20%20%20%20%20%20linkElement.textContent%20=%20sharedStrings.learnMore;%0A%20%20%20%20%20%20%20%20linkElement.id%20=%20'learnMoreLink';%0A%20%20%20%20%20%20%20%20return%20linkElement;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Resizes%20and%20positions%20the%20target%20element%20to%20match%20the%20source%20element.%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20sourceElement%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20targetElement%0A%20%20%20%20%20*/%0A%20%20%20%20function%20resizeElementToMatch(sourceElement,%20targetElement)%20%7B%0A%20%20%20%20%20%20%20%20const%20computedStyle%20=%20window.getComputedStyle(sourceElement);%0A%20%20%20%20%20%20%20%20const%20stylesToCopy%20=%20%5B'position',%20'top',%20'bottom',%20'left',%20'right',%20'transform',%20'margin'%5D;%0A%0A%20%20%20%20%20%20%20%20//%20It's%20apparently%20preferable%20to%20use%20the%20source%20element's%20size%20relative%20to%0A%20%20%20%20%20%20%20%20//%20the%20current%20viewport,%20when%20resizing%20the%20target%20element.%20However,%20the%0A%20%20%20%20%20%20%20%20//%20declarativeNetRequest%20API%20%22collapses%22%20(hides)%20blocked%20elements.%20When%0A%20%20%20%20%20%20%20%20//%20that%20happens,%20getBoundingClientRect%20will%20return%20all%20zeros.%0A%20%20%20%20%20%20%20%20//%20TODO:%20Remove%20this%20entirely,%20and%20always%20use%20the%20computed%20height/width%20of%0A%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20the%20source%20element%20instead?%0A%20%20%20%20%20%20%20%20const%20%7B%20height,%20width%20%7D%20=%20sourceElement.getBoundingClientRect();%0A%20%20%20%20%20%20%20%20if%20(height%20%3E%200%20&&%20width%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20targetElement.style.height%20=%20height%20+%20'px';%0A%20%20%20%20%20%20%20%20%20%20%20%20targetElement.style.width%20=%20width%20+%20'px';%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20stylesToCopy.push('height',%20'width');%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20for%20(const%20key%20of%20stylesToCopy)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20targetElement.style%5Bkey%5D%20=%20computedStyle%5Bkey%5D;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20If%20the%20parent%20element%20is%20very%20small%20(and%20its%20dimensions%20can%20be%20trusted)%20set%20a%20max%20height/width%0A%20%20%20%20%20%20%20%20//%20to%20avoid%20the%20placeholder%20overflowing.%0A%20%20%20%20%20%20%20%20if%20(computedStyle.display%20!==%20'inline')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(targetElement.style.maxHeight%20%3C%20computedStyle.height)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20targetElement.style.maxHeight%20=%20'initial';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(targetElement.style.maxWidth%20%3C%20computedStyle.width)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20targetElement.style.maxWidth%20=%20'initial';%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20a%20%60%3Cstyle/%3E%60%20element%20with%20DDG%20font-face%20styles/CSS%0A%20%20%20%20%20*%20to%20be%20attached%20to%20DDG%20wrapper%20elements%0A%20%20%20%20%20*%20@returns%20HTMLStyleElement%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeFontFaceStyleElement()%20%7B%0A%20%20%20%20%20%20%20%20//%20Put%20our%20custom%20font-faces%20inside%20the%20wrapper%20element,%20since%0A%20%20%20%20%20%20%20%20//%20@font-face%20does%20not%20work%20inside%20a%20shadowRoot.%0A%20%20%20%20%20%20%20%20//%20See%20https://github.com/mdn/interactive-examples/issues/887.%0A%20%20%20%20%20%20%20%20const%20fontFaceStyleElement%20=%20document.createElement('style');%0A%20%20%20%20%20%20%20%20fontFaceStyleElement.textContent%20=%20styles.fontStyle;%0A%20%20%20%20%20%20%20%20return%20fontFaceStyleElement;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20a%20%60%3Cstyle/%3E%60%20element%20with%20base%20styles%20for%20DDG%20social%20container%20and%0A%20%20%20%20%20*%20button%20to%20be%20attached%20to%20DDG%20wrapper%20elements/shadowRoot,%20also%20returns%20a%20wrapper%0A%20%20%20%20%20*%20class%20name%20for%20Social%20Container%20link%20styles%0A%20%20%20%20%20*%20@param%20%7BdisplayMode%7D%20%5Bmode='lightMode'%5D%0A%20%20%20%20%20*%20@returns%20%7B%7BwrapperClass:%20string,%20styleElement:%20HTMLStyleElement;%20%7D%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeBaseStyleElement(mode%20=%20'lightMode')%20%7B%0A%20%20%20%20%20%20%20%20//%20Style%20element%20includes%20our%20font%20&%20overwrites%20page%20styles%0A%20%20%20%20%20%20%20%20const%20styleElement%20=%20document.createElement('style');%0A%20%20%20%20%20%20%20%20const%20wrapperClass%20=%20'DuckDuckGoSocialContainer';%0A%20%20%20%20%20%20%20%20styleElement.textContent%20=%20%60%0A%20%20%20%20%20%20%20%20.$%7BwrapperClass%7D%20a%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles%5Bmode%5D.linkFont%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20font-weight:%20bold;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.$%7BwrapperClass%7D%20a:hover%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles%5Bmode%5D.linkFont%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20font-weight:%20bold;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles.button%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton%20%3E%20div%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles.buttonTextContainer%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton.primary%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles%5Bmode%5D.buttonBackground%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton.primary%20%3E%20div%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles%5Bmode%5D.buttonFont%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton.primary:hover%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles%5Bmode%5D.buttonBackgroundHover%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton.primary:active%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles%5Bmode%5D.buttonBackgroundPress%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton.secondary%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles.cancelMode.buttonBackground%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton.secondary%20%3E%20div%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles.cancelMode.buttonFont%7D%0A%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton.secondary:hover%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles.cancelMode.buttonBackgroundHover%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.DuckDuckGoButton.secondary:active%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20$%7Bstyles.cancelMode.buttonBackgroundPress%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%60;%0A%20%20%20%20%20%20%20%20return%20%7B%20wrapperClass,%20styleElement%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Creates%20an%20anchor%20element%20with%20no%20destination.%20It%20is%20expected%20that%20a%20click%0A%20%20%20%20%20*%20handler%20is%20added%20to%20the%20element%20later.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20linkText%0A%20%20%20%20%20*%20@param%20%7BdisplayMode%7D%20mode%0A%20%20%20%20%20*%20@returns%20%7BHTMLAnchorElement%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeTextButton(linkText,%20mode%20=%20'lightMode')%20%7B%0A%20%20%20%20%20%20%20%20const%20linkElement%20=%20document.createElement('a');%0A%20%20%20%20%20%20%20%20linkElement.style.cssText%20=%20styles.headerLink%20+%20styles%5Bmode%5D.linkFont;%0A%20%20%20%20%20%20%20%20linkElement.textContent%20=%20linkText;%0A%20%20%20%20%20%20%20%20return%20linkElement;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20a%20button%20element.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20buttonText%0A%20%20%20%20%20*%20%20%20Text%20to%20be%20displayed%20inside%20the%20button.%0A%20%20%20%20%20*%20@param%20%7BdisplayMode%7D%20%5Bmode='lightMode'%5D%0A%20%20%20%20%20*%20%20%20The%20button%20is%20usually%20styled%20as%20the%20primary%20call%20to%20action,%20but%20if%0A%20%20%20%20%20*%20%20%20'cancelMode'%20is%20specified%20the%20button%20is%20styled%20as%20a%20secondary%20call%20to%0A%20%20%20%20%20*%20%20%20action.%0A%20%20%20%20%20*%20@returns%20%7BHTMLButtonElement%7D%20Button%20element%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeButton(buttonText,%20mode%20=%20'lightMode')%20%7B%0A%20%20%20%20%20%20%20%20const%20button%20=%20document.createElement('button');%0A%20%20%20%20%20%20%20%20button.classList.add('DuckDuckGoButton');%0A%20%20%20%20%20%20%20%20button.classList.add(mode%20===%20'cancelMode'%20?%20'secondary'%20:%20'primary');%0A%20%20%20%20%20%20%20%20if%20(buttonText)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20textContainer%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20%20%20%20%20textContainer.textContent%20=%20buttonText;%0A%20%20%20%20%20%20%20%20%20%20%20%20button.appendChild(textContainer);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20button;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20a%20toggle%20button.%0A%20%20%20%20%20*%20@param%20%7BdisplayMode%7D%20mode%0A%20%20%20%20%20*%20@param%20%7Bboolean%7D%20%5BisActive=false%5D%0A%20%20%20%20%20*%20%20%20True%20if%20the%20button%20should%20be%20toggled%20by%20default.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BclassNames=''%5D%0A%20%20%20%20%20*%20%20%20Class%20names%20to%20assign%20to%20the%20button%20(space%20delimited).%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BdataKey=''%5D%0A%20%20%20%20%20*%20%20%20Value%20to%20assign%20to%20the%20button's%20'data-key'%20attribute.%0A%20%20%20%20%20*%20@returns%20%7BHTMLButtonElement%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeToggleButton(mode,%20isActive%20=%20false,%20classNames%20=%20'',%20dataKey%20=%20'')%20%7B%0A%20%20%20%20%20%20%20%20const%20toggleButton%20=%20document.createElement('button');%0A%20%20%20%20%20%20%20%20toggleButton.className%20=%20classNames;%0A%20%20%20%20%20%20%20%20toggleButton.style.cssText%20=%20styles.toggleButton;%0A%20%20%20%20%20%20%20%20toggleButton.type%20=%20'button';%0A%20%20%20%20%20%20%20%20toggleButton.setAttribute('aria-pressed',%20isActive%20?%20'true'%20:%20'false');%0A%20%20%20%20%20%20%20%20toggleButton.setAttribute('data-key',%20dataKey);%0A%0A%20%20%20%20%20%20%20%20const%20activeKey%20=%20isActive%20?%20'active'%20:%20'inactive';%0A%0A%20%20%20%20%20%20%20%20const%20toggleBg%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20toggleBg.style.cssText%20=%20styles.toggleButtonBg%20+%20styles%5Bmode%5D.toggleButtonBgState%5BactiveKey%5D;%0A%0A%20%20%20%20%20%20%20%20const%20toggleKnob%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20toggleKnob.style.cssText%20=%20styles.toggleButtonKnob%20+%20styles.toggleButtonKnobState%5BactiveKey%5D;%0A%0A%20%20%20%20%20%20%20%20toggleButton.appendChild(toggleBg);%0A%20%20%20%20%20%20%20%20toggleButton.appendChild(toggleKnob);%0A%0A%20%20%20%20%20%20%20%20return%20toggleButton;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20a%20toggle%20button%20that's%20wrapped%20in%20a%20div%20with%20some%20text.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20text%0A%20%20%20%20%20*%20%20%20Text%20to%20display%20by%20the%20button.%0A%20%20%20%20%20*%20@param%20%7BdisplayMode%7D%20mode%0A%20%20%20%20%20*%20@param%20%7Bboolean%7D%20%5BisActive=false%5D%0A%20%20%20%20%20*%20%20%20True%20if%20the%20button%20should%20be%20toggled%20by%20default.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BtoggleClassNames=''%5D%0A%20%20%20%20%20*%20%20%20Class%20names%20to%20assign%20to%20the%20toggle%20button.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BtextCssStyles=''%5D%0A%20%20%20%20%20*%20%20%20Styles%20to%20apply%20to%20the%20wrapping%20div%20(on%20top%20of%20ones%20determined%20by%20the%0A%20%20%20%20%20*%20%20%20display%20mode.)%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20%5BdataKey=''%5D%0A%20%20%20%20%20*%20%20%20Value%20to%20assign%20to%20the%20button's%20'data-key'%20attribute.%0A%20%20%20%20%20*%20@returns%20%7BHTMLDivElement%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeToggleButtonWithText(text,%20mode,%20isActive%20=%20false,%20toggleClassNames%20=%20'',%20textCssStyles%20=%20'',%20dataKey%20=%20'')%20%7B%0A%20%20%20%20%20%20%20%20const%20wrapper%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20wrapper.style.cssText%20=%20styles.toggleButtonWrapper;%0A%0A%20%20%20%20%20%20%20%20const%20toggleButton%20=%20makeToggleButton(mode,%20isActive,%20toggleClassNames,%20dataKey);%0A%0A%20%20%20%20%20%20%20%20const%20textDiv%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20textDiv.style.cssText%20=%20styles.contentText%20+%20styles.toggleButtonText%20+%20styles%5Bmode%5D.toggleButtonText%20+%20textCssStyles;%0A%20%20%20%20%20%20%20%20textDiv.textContent%20=%20text;%0A%0A%20%20%20%20%20%20%20%20wrapper.appendChild(toggleButton);%0A%20%20%20%20%20%20%20%20wrapper.appendChild(textDiv);%0A%20%20%20%20%20%20%20%20return%20wrapper;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20the%20default%20block%20symbol,%20for%20when%20the%20image%20isn't%20available.%0A%20%20%20%20%20*%20@returns%20%7BHTMLDivElement%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeDefaultBlockIcon()%20%7B%0A%20%20%20%20%20%20%20%20const%20blockedIcon%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20const%20dash%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20blockedIcon.appendChild(dash);%0A%20%20%20%20%20%20%20%20blockedIcon.style.cssText%20=%20styles.circle;%0A%20%20%20%20%20%20%20%20dash.style.cssText%20=%20styles.rectangle;%0A%20%20%20%20%20%20%20%20return%20blockedIcon;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Creates%20a%20share%20feedback%20link%20element.%0A%20%20%20%20%20*%20@returns%20%7BHTMLAnchorElement%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeShareFeedbackLink()%20%7B%0A%20%20%20%20%20%20%20%20const%20feedbackLink%20=%20document.createElement('a');%0A%20%20%20%20%20%20%20%20feedbackLink.style.cssText%20=%20styles.feedbackLink;%0A%20%20%20%20%20%20%20%20feedbackLink.target%20=%20'_blank';%0A%20%20%20%20%20%20%20%20feedbackLink.href%20=%20'#';%0A%20%20%20%20%20%20%20%20feedbackLink.text%20=%20sharedStrings.shareFeedback;%0A%20%20%20%20%20%20%20%20//%20Open%20Feedback%20Form%20page%20through%20background%20event%20to%20avoid%20browser%20blocking%20extension%20link%0A%20%20%20%20%20%20%20%20feedbackLink.addEventListener('click',%20function%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20e.preventDefault();%0A%20%20%20%20%20%20%20%20%20%20%20%20openShareFeedbackPage();%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20return%20feedbackLink;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Creates%20a%20share%20feedback%20link%20element,%20wrapped%20in%20a%20styled%20div.%0A%20%20%20%20%20*%20@returns%20%7BHTMLDivElement%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeShareFeedbackRow()%20%7B%0A%20%20%20%20%20%20%20%20const%20feedbackRow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20feedbackRow.style.cssText%20=%20styles.feedbackRow;%0A%0A%20%20%20%20%20%20%20%20const%20feedbackLink%20=%20makeShareFeedbackLink();%0A%20%20%20%20%20%20%20%20feedbackRow.appendChild(feedbackLink);%0A%0A%20%20%20%20%20%20%20%20return%20feedbackRow;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Creates%20a%20placeholder%20Facebook%20login%20button.%20When%20clicked,%20a%20warning%20dialog%0A%20%20%20%20%20*%20is%20displayed%20to%20the%20user.%20The%20login%20flow%20only%20continues%20if%20the%20user%20clicks%20to%0A%20%20%20%20%20*%20proceed.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20buttonText%0A%20%20%20%20%20*%20@param%20%7BdisplayMode%7D%20mode%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20hoverTextBody%0A%20%20%20%20%20*%20%20%20The%20hover%20text%20to%20display%20for%20the%20button.%0A%20%20%20%20%20*%20@param%20%7Bstring?%7D%20icon%0A%20%20%20%20%20*%20%20%20The%20source%20of%20the%20icon%20to%20display%20in%20the%20button,%20if%20null%20the%20default%20block%0A%20%20%20%20%20*%20%20%20icon%20is%20used%20instead.%0A%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20originalElement%0A%20%20%20%20%20*%20%20%20The%20original%20Facebook%20login%20button%20that%20this%20placeholder%20is%20replacing.%0A%20%20%20%20%20*%20%20%20Note:%20This%20function%20does%20not%20actually%20replace%20the%20button,%20the%20caller%20is%0A%20%20%20%20%20*%20%20%20%20%20%20%20%20%20expected%20to%20do%20that.%0A%20%20%20%20%20*%20@returns%20%7B%7B%20container:%20HTMLDivElement,%20button:%20HTMLButtonElement%20%7D%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeLoginButton(buttonText,%20mode,%20hoverTextBody,%20icon,%20originalElement)%20%7B%0A%20%20%20%20%20%20%20%20const%20container%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20container.style.cssText%20=%20'position:%20relative;';%0A%20%20%20%20%20%20%20%20container.appendChild(makeFontFaceStyleElement());%0A%0A%20%20%20%20%20%20%20%20const%20shadowRoot%20=%20container.attachShadow(%7B%20mode:%20devMode%20?%20'open'%20:%20'closed'%20%7D);%0A%20%20%20%20%20%20%20%20//%20inherit%20any%20class%20styles%20on%20the%20button%0A%20%20%20%20%20%20%20%20container.className%20=%20'fb-login-button%20FacebookLogin__button';%0A%20%20%20%20%20%20%20%20const%20%7B%20styleElement%20%7D%20=%20makeBaseStyleElement(mode);%0A%20%20%20%20%20%20%20%20styleElement.textContent%20+=%20%60%0A%20%20%20%20%20%20%20%20#DuckDuckGoPrivacyEssentialsHoverableText%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20display:%20none;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20#DuckDuckGoPrivacyEssentialsHoverable:hover%20#DuckDuckGoPrivacyEssentialsHoverableText%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20display:%20block;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%60;%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(styleElement);%0A%0A%20%20%20%20%20%20%20%20const%20hoverContainer%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20hoverContainer.id%20=%20'DuckDuckGoPrivacyEssentialsHoverable';%0A%20%20%20%20%20%20%20%20hoverContainer.style.cssText%20=%20styles.hoverContainer;%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(hoverContainer);%0A%0A%20%20%20%20%20%20%20%20//%20Make%20the%20button%0A%20%20%20%20%20%20%20%20const%20button%20=%20makeButton(buttonText,%20mode);%0A%20%20%20%20%20%20%20%20//%20Add%20blocked%20icon%0A%20%20%20%20%20%20%20%20if%20(!icon)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20button.appendChild(makeDefaultBlockIcon());%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20imgElement%20=%20document.createElement('img');%0A%20%20%20%20%20%20%20%20%20%20%20%20imgElement.style.cssText%20=%20styles.loginIcon;%0A%20%20%20%20%20%20%20%20%20%20%20%20imgElement.setAttribute('src',%20icon);%0A%20%20%20%20%20%20%20%20%20%20%20%20imgElement.setAttribute('height',%20'28px');%0A%20%20%20%20%20%20%20%20%20%20%20%20button.appendChild(imgElement);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20hoverContainer.appendChild(button);%0A%0A%20%20%20%20%20%20%20%20//%20hover%20action%0A%20%20%20%20%20%20%20%20const%20hoverBox%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20hoverBox.id%20=%20'DuckDuckGoPrivacyEssentialsHoverableText';%0A%20%20%20%20%20%20%20%20hoverBox.style.cssText%20=%20styles.textBubble;%0A%20%20%20%20%20%20%20%20const%20arrow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20arrow.style.cssText%20=%20styles.textArrow;%0A%20%20%20%20%20%20%20%20hoverBox.appendChild(arrow);%0A%20%20%20%20%20%20%20%20const%20branding%20=%20createTitleRow('DuckDuckGo');%0A%20%20%20%20%20%20%20%20branding.style.cssText%20+=%20styles.hoverTextTitle;%0A%20%20%20%20%20%20%20%20hoverBox.appendChild(branding);%0A%20%20%20%20%20%20%20%20const%20hoverText%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20hoverText.style.cssText%20=%20styles.hoverTextBody;%0A%20%20%20%20%20%20%20%20hoverText.textContent%20=%20hoverTextBody%20+%20'%20';%0A%20%20%20%20%20%20%20%20hoverText.appendChild(getLearnMoreLink(mode));%0A%20%20%20%20%20%20%20%20hoverBox.appendChild(hoverText);%0A%0A%20%20%20%20%20%20%20%20hoverContainer.appendChild(hoverBox);%0A%20%20%20%20%20%20%20%20const%20rect%20=%20originalElement.getBoundingClientRect();%0A%0A%20%20%20%20%20%20%20%20//%20The%20left%20side%20of%20the%20hover%20popup%20may%20go%20offscreen%20if%20the%0A%20%20%20%20%20%20%20%20//%20login%20button%20is%20all%20the%20way%20on%20the%20left%20side%20of%20the%20page.%20This%0A%20%20%20%20%20%20%20%20//%20If%20that%20is%20the%20case,%20dynamically%20shift%20the%20box%20right%20so%20it%20shows%0A%20%20%20%20%20%20%20%20//%20properly.%0A%20%20%20%20%20%20%20%20if%20(rect.left%20%3C%20styles.textBubbleLeftShift)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20leftShift%20=%20-rect.left%20+%2010;%20//%2010px%20away%20from%20edge%20of%20the%20screen%0A%20%20%20%20%20%20%20%20%20%20%20%20hoverBox.style.cssText%20+=%20%60left:%20$%7BleftShift%7Dpx;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20change%20=%20(1%20-%20rect.left%20/%20styles.textBubbleLeftShift)%20*%20(100%20-%20styles.arrowDefaultLocationPercent);%0A%20%20%20%20%20%20%20%20%20%20%20%20arrow.style.cssText%20+=%20%60left:%20$%7BMath.max(10,%20styles.arrowDefaultLocationPercent%20-%20change)%7D%25;%60;%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(rect.left%20+%20styles.textBubbleWidth%20-%20styles.textBubbleLeftShift%20%3E%20window.innerWidth)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20rightShift%20=%20rect.left%20+%20styles.textBubbleWidth%20-%20styles.textBubbleLeftShift;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20diff%20=%20Math.min(rightShift%20-%20window.innerWidth,%20styles.textBubbleLeftShift);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20rightMargin%20=%2020;%20//%20Add%20some%20margin%20to%20the%20page,%20so%20scrollbar%20doesn't%20overlap.%0A%20%20%20%20%20%20%20%20%20%20%20%20hoverBox.style.cssText%20+=%20%60left:%20-$%7Bstyles.textBubbleLeftShift%20+%20diff%20+%20rightMargin%7Dpx;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20change%20=%20(diff%20/%20styles.textBubbleLeftShift)%20*%20(100%20-%20styles.arrowDefaultLocationPercent);%0A%20%20%20%20%20%20%20%20%20%20%20%20arrow.style.cssText%20+=%20%60left:%20$%7BMath.max(10,%20styles.arrowDefaultLocationPercent%20+%20change)%7D%25;%60;%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20hoverBox.style.cssText%20+=%20%60left:%20-$%7Bstyles.textBubbleLeftShift%7Dpx;%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20arrow.style.cssText%20+=%20%60left:%20$%7Bstyles.arrowDefaultLocationPercent%7D%25;%60;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20button,%0A%20%20%20%20%20%20%20%20%20%20%20%20container,%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Creates%20a%20privacy%20warning%20dialog%20for%20the%20user,%20so%20that%20the%20user%20can%20choose%20to%0A%20%20%20%20%20*%20proceed/abort.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20entity%0A%20%20%20%20%20*%20%20%20The%20entity%20to%20unblock%20requests%20for%20(e.g.%20%22Facebook,%20Inc.%22)%20if%20the%20user%0A%20%20%20%20%20*%20%20%20clicks%20to%20proceed.%0A%20%20%20%20%20*%20@param%20%7Bfunction%7D%20acceptFunction%0A%20%20%20%20%20*%20%20%20The%20function%20to%20call%20if%20the%20user%20has%20clicked%20to%20proceed.%0A%20%20%20%20%20*%20@param%20%7B...any%7D%20acceptFunctionParams%0A%20%20%20%20%20*%20%20%20The%20parameters%20passed%20to%20acceptFunction%20when%20it%20is%20called.%0A%20%20%20%20%20*%20%20%20TODO:%20Have%20the%20caller%20bind%20these%20arguments%20to%20the%20function%20instead.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20makeModal(entity,%20acceptFunction,%20...acceptFunctionParams)%20%7B%0A%20%20%20%20%20%20%20%20const%20icon%20=%20entityData%5Bentity%5D.modalIcon;%0A%0A%20%20%20%20%20%20%20%20const%20modalContainer%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20modalContainer.setAttribute('data-key',%20'modal');%0A%20%20%20%20%20%20%20%20modalContainer.style.cssText%20=%20styles.modalContainer;%0A%0A%20%20%20%20%20%20%20%20modalContainer.appendChild(makeFontFaceStyleElement());%0A%0A%20%20%20%20%20%20%20%20const%20closeModal%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20document.body.removeChild(modalContainer);%0A%20%20%20%20%20%20%20%20%20%20%20%20abortSurrogateConfirmation(entity);%0A%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20//%20Protect%20the%20contents%20of%20our%20modal%20inside%20a%20shadowRoot,%20to%20avoid%0A%20%20%20%20%20%20%20%20//%20it%20being%20styled%20by%20the%20website's%20stylesheets.%0A%20%20%20%20%20%20%20%20const%20shadowRoot%20=%20modalContainer.attachShadow(%7B%20mode:%20devMode%20?%20'open'%20:%20'closed'%20%7D);%0A%20%20%20%20%20%20%20%20const%20%7B%20styleElement%20%7D%20=%20makeBaseStyleElement('lightMode');%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(styleElement);%0A%0A%20%20%20%20%20%20%20%20const%20pageOverlay%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20pageOverlay.style.cssText%20=%20styles.overlay;%0A%0A%20%20%20%20%20%20%20%20const%20modal%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20modal.style.cssText%20=%20styles.modal;%0A%0A%20%20%20%20%20%20%20%20//%20Title%0A%20%20%20%20%20%20%20%20const%20modalTitle%20=%20createTitleRow('DuckDuckGo',%20null,%20closeModal);%0A%20%20%20%20%20%20%20%20modal.appendChild(modalTitle);%0A%0A%20%20%20%20%20%20%20%20const%20iconElement%20=%20document.createElement('img');%0A%20%20%20%20%20%20%20%20iconElement.style.cssText%20=%20styles.icon%20+%20styles.modalIcon;%0A%20%20%20%20%20%20%20%20iconElement.setAttribute('src',%20icon);%0A%20%20%20%20%20%20%20%20iconElement.setAttribute('height',%20'70px');%0A%0A%20%20%20%20%20%20%20%20const%20title%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20title.style.cssText%20=%20styles.modalContentTitle;%0A%20%20%20%20%20%20%20%20title.textContent%20=%20entityData%5Bentity%5D.modalTitle;%0A%0A%20%20%20%20%20%20%20%20//%20Content%0A%20%20%20%20%20%20%20%20const%20modalContent%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20modalContent.style.cssText%20=%20styles.modalContent;%0A%0A%20%20%20%20%20%20%20%20const%20message%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20message.style.cssText%20=%20styles.modalContentText;%0A%20%20%20%20%20%20%20%20message.textContent%20=%20entityData%5Bentity%5D.modalText%20+%20'%20';%0A%20%20%20%20%20%20%20%20message.appendChild(getLearnMoreLink());%0A%0A%20%20%20%20%20%20%20%20modalContent.appendChild(iconElement);%0A%20%20%20%20%20%20%20%20modalContent.appendChild(title);%0A%20%20%20%20%20%20%20%20modalContent.appendChild(message);%0A%0A%20%20%20%20%20%20%20%20//%20Buttons%0A%20%20%20%20%20%20%20%20const%20buttonRow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20buttonRow.style.cssText%20=%20styles.modalButtonRow;%0A%20%20%20%20%20%20%20%20const%20allowButton%20=%20makeButton(entityData%5Bentity%5D.modalAcceptText,%20'lightMode');%0A%20%20%20%20%20%20%20%20allowButton.style.cssText%20+=%20styles.modalButton%20+%20'margin-bottom:%208px;';%0A%20%20%20%20%20%20%20%20allowButton.setAttribute('data-key',%20'allow');%0A%20%20%20%20%20%20%20%20allowButton.addEventListener('click',%20function%20doLogin()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20acceptFunction(...acceptFunctionParams);%0A%20%20%20%20%20%20%20%20%20%20%20%20document.body.removeChild(modalContainer);%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20const%20rejectButton%20=%20makeButton(entityData%5Bentity%5D.modalRejectText,%20'cancelMode');%0A%20%20%20%20%20%20%20%20rejectButton.setAttribute('data-key',%20'reject');%0A%20%20%20%20%20%20%20%20rejectButton.style.cssText%20+=%20styles.modalButton;%0A%20%20%20%20%20%20%20%20rejectButton.addEventListener('click',%20closeModal);%0A%0A%20%20%20%20%20%20%20%20buttonRow.appendChild(allowButton);%0A%20%20%20%20%20%20%20%20buttonRow.appendChild(rejectButton);%0A%20%20%20%20%20%20%20%20modalContent.appendChild(buttonRow);%0A%0A%20%20%20%20%20%20%20%20modal.appendChild(modalContent);%0A%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(pageOverlay);%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(modal);%0A%0A%20%20%20%20%20%20%20%20document.body.insertBefore(modalContainer,%20document.body.childNodes%5B0%5D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20the%20%22title%20row%22%20div%20that%20contains%20a%20placeholder's%20heading.%0A%20%20%20%20%20*%20@param%20%7Bstring%7D%20message%0A%20%20%20%20%20*%20%20%20The%20title%20text%20to%20display.%0A%20%20%20%20%20*%20@param%20%7BHTMLAnchorElement?%7D%20%5BtextButton%5D%0A%20%20%20%20%20*%20%20%20The%20link%20to%20display%20with%20the%20title,%20if%20any.%0A%20%20%20%20%20*%20@param%20%7BEventListener%7D%20%5BcloseBtnFn%5D%0A%20%20%20%20%20*%20%20%20If%20provided,%20a%20close%20button%20is%20added%20that%20calls%20this%20function%20when%20clicked.%0A%20%20%20%20%20*%20@returns%20%7BHTMLDivElement%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20createTitleRow(message,%20textButton,%20closeBtnFn)%20%7B%0A%20%20%20%20%20%20%20%20//%20Create%20row%20container%0A%20%20%20%20%20%20%20%20const%20row%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20row.style.cssText%20=%20styles.titleBox;%0A%0A%20%20%20%20%20%20%20%20//%20Logo%0A%20%20%20%20%20%20%20%20const%20logoContainer%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20logoContainer.style.cssText%20=%20styles.logo;%0A%20%20%20%20%20%20%20%20const%20logoElement%20=%20document.createElement('img');%0A%20%20%20%20%20%20%20%20logoElement.setAttribute('src',%20logoImg);%0A%20%20%20%20%20%20%20%20logoElement.setAttribute('height',%20'21px');%0A%20%20%20%20%20%20%20%20logoElement.style.cssText%20=%20styles.logoImg;%0A%20%20%20%20%20%20%20%20logoContainer.appendChild(logoElement);%0A%20%20%20%20%20%20%20%20row.appendChild(logoContainer);%0A%0A%20%20%20%20%20%20%20%20//%20Content%20box%20title%0A%20%20%20%20%20%20%20%20const%20msgElement%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20msgElement.id%20=%20titleID;%20//%20Ensure%20we%20can%20find%20this%20to%20potentially%20hide%20it%20later.%0A%20%20%20%20%20%20%20%20msgElement.textContent%20=%20message;%0A%20%20%20%20%20%20%20%20msgElement.style.cssText%20=%20styles.title;%0A%20%20%20%20%20%20%20%20row.appendChild(msgElement);%0A%0A%20%20%20%20%20%20%20%20//%20Close%20Button%0A%20%20%20%20%20%20%20%20if%20(typeof%20closeBtnFn%20===%20'function')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20closeButton%20=%20document.createElement('button');%0A%20%20%20%20%20%20%20%20%20%20%20%20closeButton.style.cssText%20=%20styles.closeButton;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20closeIconImg%20=%20document.createElement('img');%0A%20%20%20%20%20%20%20%20%20%20%20%20closeIconImg.setAttribute('src',%20closeIcon);%0A%20%20%20%20%20%20%20%20%20%20%20%20closeIconImg.setAttribute('height',%20'12px');%0A%20%20%20%20%20%20%20%20%20%20%20%20closeIconImg.style.cssText%20=%20styles.closeIcon;%0A%20%20%20%20%20%20%20%20%20%20%20%20closeButton.appendChild(closeIconImg);%0A%20%20%20%20%20%20%20%20%20%20%20%20closeButton.addEventListener('click',%20closeBtnFn);%0A%20%20%20%20%20%20%20%20%20%20%20%20row.appendChild(closeButton);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Text%20button%20for%20very%20small%20boxes%0A%20%20%20%20%20%20%20%20if%20(textButton)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20textButton.id%20=%20titleID%20+%20'TextButton';%0A%20%20%20%20%20%20%20%20%20%20%20%20row.appendChild(textButton);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20row;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20a%20placeholder%20element%20(wrapped%20in%20a%20div%20and%20shadowRoot),%20to%20replace%20a%0A%20%20%20%20%20*%20tracking%20element%20with.%0A%20%20%20%20%20*%20@param%20%7BDuckWidget%7D%20widget%0A%20%20%20%20%20*%20%20%20Widget%20corresponding%20to%20the%20tracking%20element.%0A%20%20%20%20%20*%20@param%20%7BHTMLButtonElement%7D%20button%0A%20%20%20%20%20*%20%20%20Primary%20button%20that%20loads%20the%20original%20tracking%20element%20(and%20removed%20this%0A%20%20%20%20%20*%20%20%20placeholder)%20when%20clicked.%0A%20%20%20%20%20*%20@param%20%7BHTMLAnchorElement?%7D%20textButton%0A%20%20%20%20%20*%20%20%20Link%20to%20display%20next%20to%20the%20title,%20if%20any.%0A%20%20%20%20%20*%20@param%20%7Bstring?%7D%20img%0A%20%20%20%20%20*%20%20%20Source%20of%20image%20to%20display%20in%20the%20placeholder%20(if%20any).%0A%20%20%20%20%20*%20@param%20%7BHTMLDivElement%7D%20%5BbottomRow%5D%0A%20%20%20%20%20*%20%20%20Bottom%20row%20to%20append%20to%20the%20placeholder,%20if%20any.%0A%20%20%20%20%20*%20@returns%20%7B%7B%20contentBlock:%20HTMLDivElement,%20shadowRoot:%20ShadowRoot%20%7D%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20createContentBlock(widget,%20button,%20textButton,%20img,%20bottomRow)%20%7B%0A%20%20%20%20%20%20%20%20const%20contentBlock%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20contentBlock.style.cssText%20=%20styles.wrapperDiv;%0A%0A%20%20%20%20%20%20%20%20contentBlock.appendChild(makeFontFaceStyleElement());%0A%0A%20%20%20%20%20%20%20%20//%20Put%20everything%20else%20inside%20the%20shadowRoot%20of%20the%20wrapper%20element%20to%0A%20%20%20%20%20%20%20%20//%20reduce%20the%20chances%20of%20the%20website's%20stylesheets%20messing%20up%20the%0A%20%20%20%20%20%20%20%20//%20placeholder's%20appearance.%0A%20%20%20%20%20%20%20%20const%20shadowRootMode%20=%20devMode%20?%20'open'%20:%20'closed';%0A%20%20%20%20%20%20%20%20const%20shadowRoot%20=%20contentBlock.attachShadow(%7B%20mode:%20shadowRootMode%20%7D);%0A%0A%20%20%20%20%20%20%20%20//%20Style%20element%20includes%20our%20font%20&%20overwrites%20page%20styles%0A%20%20%20%20%20%20%20%20const%20%7B%20wrapperClass,%20styleElement%20%7D%20=%20makeBaseStyleElement(widget.getMode());%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(styleElement);%0A%0A%20%20%20%20%20%20%20%20//%20Create%20overall%20grid%20structure%0A%20%20%20%20%20%20%20%20const%20element%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20element.style.cssText%20=%20styles.block%20+%20styles%5Bwidget.getMode()%5D.background%20+%20styles%5Bwidget.getMode()%5D.textFont;%0A%20%20%20%20%20%20%20%20if%20(widget.replaceSettings.type%20===%20'youtube-video')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20element.style.cssText%20+=%20styles.youTubeDialogBlock;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20element.className%20=%20wrapperClass;%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(element);%0A%0A%20%20%20%20%20%20%20%20//%20grid%20of%20three%20rows%0A%20%20%20%20%20%20%20%20const%20titleRow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20titleRow.style.cssText%20=%20styles.headerRow;%0A%20%20%20%20%20%20%20%20element.appendChild(titleRow);%0A%20%20%20%20%20%20%20%20titleRow.appendChild(createTitleRow('DuckDuckGo',%20textButton));%0A%0A%20%20%20%20%20%20%20%20const%20contentRow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20contentRow.style.cssText%20=%20styles.content;%0A%0A%20%20%20%20%20%20%20%20if%20(img)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20imageRow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20%20%20%20%20imageRow.style.cssText%20=%20styles.imgRow;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20imgElement%20=%20document.createElement('img');%0A%20%20%20%20%20%20%20%20%20%20%20%20imgElement.style.cssText%20=%20styles.icon;%0A%20%20%20%20%20%20%20%20%20%20%20%20imgElement.setAttribute('src',%20img);%0A%20%20%20%20%20%20%20%20%20%20%20%20imgElement.setAttribute('height',%20'70px');%0A%20%20%20%20%20%20%20%20%20%20%20%20imageRow.appendChild(imgElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20element.appendChild(imageRow);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20contentTitle%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20contentTitle.style.cssText%20=%20styles.contentTitle;%0A%20%20%20%20%20%20%20%20contentTitle.textContent%20=%20widget.replaceSettings.infoTitle;%0A%20%20%20%20%20%20%20%20contentTitle.id%20=%20'contentTitle';%0A%20%20%20%20%20%20%20%20contentRow.appendChild(contentTitle);%0A%20%20%20%20%20%20%20%20const%20contentText%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20contentText.style.cssText%20=%20styles.contentText;%0A%20%20%20%20%20%20%20%20const%20contentTextSpan%20=%20document.createElement('span');%0A%20%20%20%20%20%20%20%20contentTextSpan.id%20=%20'infoText';%0A%20%20%20%20%20%20%20%20contentTextSpan.textContent%20=%20widget.replaceSettings.infoText%20+%20'%20';%0A%20%20%20%20%20%20%20%20contentText.appendChild(contentTextSpan);%0A%20%20%20%20%20%20%20%20contentText.appendChild(getLearnMoreLink());%0A%20%20%20%20%20%20%20%20contentRow.appendChild(contentText);%0A%20%20%20%20%20%20%20%20element.appendChild(contentRow);%0A%0A%20%20%20%20%20%20%20%20const%20buttonRow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20buttonRow.style.cssText%20=%20styles.buttonRow;%0A%20%20%20%20%20%20%20%20buttonRow.appendChild(button);%0A%20%20%20%20%20%20%20%20contentText.appendChild(buttonRow);%0A%0A%20%20%20%20%20%20%20%20if%20(bottomRow)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20contentRow.appendChild(bottomRow);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%20Share%20Feedback%20Link%20*/%0A%20%20%20%20%20%20%20%20if%20(widget.replaceSettings.type%20===%20'youtube-video')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20feedbackRow%20=%20makeShareFeedbackRow();%0A%20%20%20%20%20%20%20%20%20%20%20%20shadowRoot.appendChild(feedbackRow);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20%7B%20contentBlock,%20shadowRoot%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Create%20the%20content%20block%20to%20replace%20embedded%20YouTube%20videos/iframes%20with.%0A%20%20%20%20%20*%20@param%20%7BHTMLIFrameElement%7D%20trackingElement%0A%20%20%20%20%20*%20@param%20%7BDuckWidget%7D%20widget%0A%20%20%20%20%20*%20@returns%20%7B%7B%20blockingDialog:%20HTMLElement,%20shadowRoot:%20ShadowRoot%20%7D%7D%0A%20%20%20%20%20*/%0A%20%20%20%20function%20createYouTubeBlockingDialog(trackingElement,%20widget)%20%7B%0A%20%20%20%20%20%20%20%20const%20button%20=%20makeButton(widget.replaceSettings.buttonText,%20widget.getMode());%0A%20%20%20%20%20%20%20%20const%20textButton%20=%20makeTextButton(widget.replaceSettings.buttonText,%20widget.getMode());%0A%0A%20%20%20%20%20%20%20%20const%20bottomRow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20bottomRow.style.cssText%20=%20styles.youTubeDialogBottomRow;%0A%20%20%20%20%20%20%20%20const%20previewToggle%20=%20makeToggleButtonWithText(%0A%20%20%20%20%20%20%20%20%20%20%20%20widget.replaceSettings.previewToggleText,%0A%20%20%20%20%20%20%20%20%20%20%20%20widget.getMode(),%0A%20%20%20%20%20%20%20%20%20%20%20%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20'yt-preview-toggle',%0A%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20previewToggle.addEventListener('click',%20()%20=%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20makeModal(widget.entity,%20()%20=%3E%20ctl.messaging.notify('setYoutubePreviewsEnabled',%20%7B%20youtubePreviewsEnabled:%20true%20%7D),%20widget.entity),%0A%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20bottomRow.appendChild(previewToggle);%0A%0A%20%20%20%20%20%20%20%20const%20%7B%20contentBlock,%20shadowRoot%20%7D%20=%20createContentBlock(widget,%20button,%20textButton,%20null,%20bottomRow);%0A%20%20%20%20%20%20%20%20contentBlock.id%20=%20trackingElement.id;%0A%20%20%20%20%20%20%20%20contentBlock.style.cssText%20+=%20styles.wrapperDiv%20+%20styles.youTubeWrapperDiv;%0A%0A%20%20%20%20%20%20%20%20button.addEventListener('click',%20widget.clickFunction(trackingElement,%20contentBlock));%0A%20%20%20%20%20%20%20%20textButton.addEventListener('click',%20widget.clickFunction(trackingElement,%20contentBlock));%0A%0A%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20blockingDialog:%20contentBlock,%0A%20%20%20%20%20%20%20%20%20%20%20%20shadowRoot,%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20Creates%20the%20placeholder%20element%20to%20replace%20a%20YouTube%20video%20iframe%20element%0A%20%20%20%20%20*%20with%20a%20preview%20image.%20Mutates%20widget%20Object%20to%20set%20the%20autoplay%20property%0A%20%20%20%20%20*%20as%20the%20preview%20details%20load.%0A%20%20%20%20%20*%20@param%20%7BHTMLIFrameElement%7D%20originalElement%0A%20%20%20%20%20*%20%20%20The%20YouTube%20video%20iframe%20element.%0A%20%20%20%20%20*%20@param%20%7BDuckWidget%7D%20widget%0A%20%20%20%20%20*%20%20%20The%20widget%20Object.%20We%20mutate%20this%20to%20set%20the%20autoplay%20property.%0A%20%20%20%20%20*%20@returns%20%7B%7B%20youTubePreview:%20HTMLElement,%20shadowRoot:%20ShadowRoot%20%7D%7D%0A%20%20%20%20%20*%20%20%20Object%20containing%20the%20YouTube%20Preview%20element%20and%20its%20shadowRoot.%0A%20%20%20%20%20*/%0A%20%20%20%20function%20createYouTubePreview(originalElement,%20widget)%20%7B%0A%20%20%20%20%20%20%20%20const%20youTubePreview%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20youTubePreview.id%20=%20originalElement.id;%0A%20%20%20%20%20%20%20%20youTubePreview.style.cssText%20=%20styles.wrapperDiv%20+%20styles.placeholderWrapperDiv;%0A%0A%20%20%20%20%20%20%20%20youTubePreview.appendChild(makeFontFaceStyleElement());%0A%0A%20%20%20%20%20%20%20%20//%20Protect%20the%20contents%20of%20our%20placeholder%20inside%20a%20shadowRoot,%20to%20avoid%0A%20%20%20%20%20%20%20%20//%20it%20being%20styled%20by%20the%20website's%20stylesheets.%0A%20%20%20%20%20%20%20%20const%20shadowRoot%20=%20youTubePreview.attachShadow(%7B%20mode:%20devMode%20?%20'open'%20:%20'closed'%20%7D);%0A%20%20%20%20%20%20%20%20const%20%7B%20wrapperClass,%20styleElement%20%7D%20=%20makeBaseStyleElement(widget.getMode());%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(styleElement);%0A%0A%20%20%20%20%20%20%20%20const%20youTubePreviewDiv%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20youTubePreviewDiv.style.cssText%20=%20styles.youTubeDialogDiv;%0A%20%20%20%20%20%20%20%20youTubePreviewDiv.classList.add(wrapperClass);%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(youTubePreviewDiv);%0A%0A%20%20%20%20%20%20%20%20/**%20Preview%20Image%20*/%0A%20%20%20%20%20%20%20%20const%20previewImageWrapper%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20previewImageWrapper.style.cssText%20=%20styles.youTubePreviewWrapperImg;%0A%20%20%20%20%20%20%20%20youTubePreviewDiv.appendChild(previewImageWrapper);%0A%20%20%20%20%20%20%20%20//%20We%20use%20an%20image%20element%20for%20the%20preview%20image%20so%20that%20we%20can%20ensure%0A%20%20%20%20%20%20%20%20//%20the%20referrer%20isn't%20passed.%0A%20%20%20%20%20%20%20%20const%20previewImageElement%20=%20document.createElement('img');%0A%20%20%20%20%20%20%20%20previewImageElement.setAttribute('referrerPolicy',%20'no-referrer');%0A%20%20%20%20%20%20%20%20previewImageElement.style.cssText%20=%20styles.youTubePreviewImg;%0A%20%20%20%20%20%20%20%20previewImageWrapper.appendChild(previewImageElement);%0A%0A%20%20%20%20%20%20%20%20const%20innerDiv%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20innerDiv.style.cssText%20=%20styles.youTubePlaceholder;%0A%0A%20%20%20%20%20%20%20%20/**%20Top%20section%20*/%0A%20%20%20%20%20%20%20%20const%20topSection%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20topSection.style.cssText%20=%20styles.youTubeTopSection;%0A%20%20%20%20%20%20%20%20innerDiv.appendChild(topSection);%0A%0A%20%20%20%20%20%20%20%20/**%20Video%20Title%20*/%0A%20%20%20%20%20%20%20%20const%20titleElement%20=%20document.createElement('p');%0A%20%20%20%20%20%20%20%20titleElement.style.cssText%20=%20styles.youTubeTitle;%0A%20%20%20%20%20%20%20%20topSection.appendChild(titleElement);%0A%0A%20%20%20%20%20%20%20%20/**%20Text%20Button%20on%20top%20section%20*/%0A%20%20%20%20%20%20%20%20//%20Use%20darkMode%20styles%20because%20the%20preview%20background%20is%20dark%20and%20causes%20poor%20contrast%0A%20%20%20%20%20%20%20%20//%20with%20lightMode%20button,%20making%20it%20hard%20to%20read.%0A%20%20%20%20%20%20%20%20const%20textButton%20=%20makeTextButton(widget.replaceSettings.buttonText,%20'darkMode');%0A%20%20%20%20%20%20%20%20textButton.id%20=%20titleID%20+%20'TextButton';%0A%0A%20%20%20%20%20%20%20%20textButton.addEventListener('click',%20widget.clickFunction(originalElement,%20youTubePreview));%0A%20%20%20%20%20%20%20%20topSection.appendChild(textButton);%0A%0A%20%20%20%20%20%20%20%20/**%20Play%20Button%20*/%0A%20%20%20%20%20%20%20%20const%20playButtonRow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20playButtonRow.style.cssText%20=%20styles.youTubePlayButtonRow;%0A%0A%20%20%20%20%20%20%20%20const%20playButton%20=%20makeButton('',%20widget.getMode());%0A%20%20%20%20%20%20%20%20playButton.style.cssText%20+=%20styles.youTubePlayButton;%0A%0A%20%20%20%20%20%20%20%20const%20videoPlayImg%20=%20document.createElement('img');%0A%20%20%20%20%20%20%20%20const%20videoPlayIcon%20=%20widget.replaceSettings.placeholder.videoPlayIcon%5Bwidget.getMode()%5D;%0A%20%20%20%20%20%20%20%20videoPlayImg.setAttribute('src',%20videoPlayIcon);%0A%20%20%20%20%20%20%20%20playButton.appendChild(videoPlayImg);%0A%0A%20%20%20%20%20%20%20%20playButton.addEventListener('click',%20widget.clickFunction(originalElement,%20youTubePreview));%0A%20%20%20%20%20%20%20%20playButtonRow.appendChild(playButton);%0A%20%20%20%20%20%20%20%20innerDiv.appendChild(playButtonRow);%0A%0A%20%20%20%20%20%20%20%20/**%20Preview%20Toggle%20*/%0A%20%20%20%20%20%20%20%20const%20previewToggleRow%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20previewToggleRow.style.cssText%20=%20styles.youTubePreviewToggleRow;%0A%0A%20%20%20%20%20%20%20%20//%20TODO:%20Use%20%60widget.replaceSettings.placeholder.previewToggleEnabledDuckDuckGoText%60%20for%20toggle%0A%20%20%20%20%20%20%20%20//%20copy%20when%20implementing%20mobile%20YT%20CTL%20Preview%0A%20%20%20%20%20%20%20%20const%20previewToggle%20=%20makeToggleButtonWithText(%0A%20%20%20%20%20%20%20%20%20%20%20%20widget.replaceSettings.placeholder.previewToggleEnabledText,%0A%20%20%20%20%20%20%20%20%20%20%20%20widget.getMode(),%0A%20%20%20%20%20%20%20%20%20%20%20%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20styles.youTubePreviewToggleText,%0A%20%20%20%20%20%20%20%20%20%20%20%20'yt-preview-toggle',%0A%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20previewToggle.addEventListener('click',%20()%20=%3E%20ctl.messaging.notify('setYoutubePreviewsEnabled',%20%7B%20youtubePreviewsEnabled:%20false%20%7D));%0A%0A%20%20%20%20%20%20%20%20/**%20Preview%20Info%20Text%20*/%0A%20%20%20%20%20%20%20%20const%20previewText%20=%20document.createElement('div');%0A%20%20%20%20%20%20%20%20previewText.style.cssText%20=%20styles.contentText%20+%20styles.toggleButtonText%20+%20styles.youTubePreviewInfoText;%0A%20%20%20%20%20%20%20%20//%20Since%20this%20string%20contains%20an%20anchor%20element,%20setting%20innerText%20won't%0A%20%20%20%20%20%20%20%20//%20work.%0A%20%20%20%20%20%20%20%20//%20Warning:%20This%20is%20not%20ideal!%20The%20translated%20(and%20original)%20strings%20must%20be%0A%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20%20%20%20checked%20very%20carefully!%20Any%20HTML%20they%20contain%20will%20be%20inserted.%0A%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20%20%20%20Ideally,%20the%20translation%20system%20would%20allow%20only%20certain%20element%0A%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20%20%20%20types%20to%20be%20included,%20and%20would%20avoid%20the%20URLs%20for%20links%20being%0A%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20%20%20%20included%20in%20the%20translations.%0A%20%20%20%20%20%20%20%20previewText.insertAdjacentHTML('beforeend',%20widget.replaceSettings.placeholder.previewInfoText);%0A%20%20%20%20%20%20%20%20const%20previewTextLink%20=%20previewText.querySelector('a');%0A%20%20%20%20%20%20%20%20if%20(previewTextLink)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20newPreviewTextLink%20=%20getLearnMoreLink(widget.getMode());%0A%20%20%20%20%20%20%20%20%20%20%20%20newPreviewTextLink.innerText%20=%20previewTextLink.innerText;%0A%20%20%20%20%20%20%20%20%20%20%20%20previewTextLink.replaceWith(newPreviewTextLink);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20previewToggleRow.appendChild(previewToggle);%0A%20%20%20%20%20%20%20%20previewToggleRow.appendChild(previewText);%0A%20%20%20%20%20%20%20%20innerDiv.appendChild(previewToggleRow);%0A%0A%20%20%20%20%20%20%20%20youTubePreviewDiv.appendChild(innerDiv);%0A%0A%20%20%20%20%20%20%20%20//%20We%20use%20.then()%20instead%20of%20await%20here%20to%20show%20the%20placeholder%20right%20away%0A%20%20%20%20%20%20%20%20//%20while%20the%20YouTube%20endpoint%20takes%20it%20time%20to%20respond.%0A%20%20%20%20%20%20%20%20const%20videoURL%20=%20originalElement.src%20%7C%7C%20originalElement.getAttribute('data-src');%0A%20%20%20%20%20%20%20%20ctl.messaging%0A%20%20%20%20%20%20%20%20%20%20%20%20.request('getYouTubeVideoDetails',%20%7B%20videoURL%20%7D)%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20eslint-disable-next-line%20promise/prefer-await-to-then%0A%20%20%20%20%20%20%20%20%20%20%20%20.then((%7B%20videoURL:%20videoURLResp,%20status,%20title,%20previewImage%20%7D)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!status%20%7C%7C%20videoURLResp%20!==%20videoURL)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(status%20===%20'success')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20titleElement.innerText%20=%20title;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20titleElement.title%20=%20title;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(previewImage)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20previewImageElement.setAttribute('src',%20previewImage);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20widget.autoplay%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20/**%20Share%20Feedback%20Link%20*/%0A%20%20%20%20%20%20%20%20const%20feedbackRow%20=%20makeShareFeedbackRow();%0A%20%20%20%20%20%20%20%20shadowRoot.appendChild(feedbackRow);%0A%0A%20%20%20%20%20%20%20%20return%20%7B%20youTubePreview,%20shadowRoot%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7Bimport('@duckduckgo/messaging').MessagingContext%7D%20MessagingContext%0A%20%20%20%20%20*/%0A%0A%20%20%20%20class%20ClickToLoad%20extends%20ContentFeature%20%7B%0A%20%20%20%20%20%20%20%20/**%20@type%20%7BMessagingContext%7D%20*/%0A%20%20%20%20%20%20%20%20#messagingContext;%0A%0A%20%20%20%20%20%20%20%20async%20init(args)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Bail%20if%20no%20messaging%20backend%20-%20this%20is%20a%20debugging%20feature%20to%20ensure%20we%20don't%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20accidentally%20enabled%20this%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this.messaging)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('Cannot%20operate%20click%20to%20load%20without%20a%20messaging%20backend');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20_messagingModuleScope%20=%20this.messaging;%0A%20%20%20%20%20%20%20%20%20%20%20%20_addDebugFlag%20=%20this.addDebugFlag.bind(this);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20websiteOwner%20=%20args?.site?.parentEntity;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20settings%20=%20args?.featureSettings?.clickToLoad%20%7C%7C%20%7B%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20locale%20=%20args?.locale%20%7C%7C%20'en';%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20localizedConfig%20=%20getConfig(locale);%0A%20%20%20%20%20%20%20%20%20%20%20%20config%20=%20localizedConfig.config;%0A%20%20%20%20%20%20%20%20%20%20%20%20sharedStrings%20=%20localizedConfig.sharedStrings;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20update%20styles%20if%20asset%20config%20was%20sent%0A%20%20%20%20%20%20%20%20%20%20%20%20styles%20=%20getStyles(this.assetConfig);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Register%20Custom%20Elements%20only%20when%20Click%20to%20Load%20is%20initialized,%20to%20ensure%20it%20is%20only%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20called%20when%20config%20is%20ready%20and%20any%20previous%20context%20have%20been%20appropriately%20invalidated%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20prior%20when%20applicable%20(ie%20Firefox%20when%20hot%20reloading%20the%20Extension)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20%20%20%20%20registerCustomElements();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20entity%20of%20Object.keys(config))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Strip%20config%20entities%20that%20are%20first-party,%20or%20aren't%20enabled%20in%20the%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20extension's%20clickToLoad%20settings.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20((websiteOwner%20&&%20entity%20===%20websiteOwner)%20%7C%7C%20!settings%5Bentity%5D%20%7C%7C%20settings%5Bentity%5D.state%20!==%20'enabled')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delete%20config%5Bentity%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Populate%20the%20entities%20and%20entityData%20data%20structures.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20TODO:%20Remove%20them%20and%20this%20logic,%20they%20seem%20unnecessary.%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20entities.push(entity);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20shouldShowLoginModal%20=%20!!config%5Bentity%5D.informationalModal;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20currentEntityData%20=%20%7B%20shouldShowLoginModal%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(shouldShowLoginModal)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20%7B%20informationalModal%20%7D%20=%20config%5Bentity%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20currentEntityData.modalIcon%20=%20informationalModal.icon;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20currentEntityData.modalTitle%20=%20informationalModal.messageTitle;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20currentEntityData.modalText%20=%20informationalModal.messageBody;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20currentEntityData.modalAcceptText%20=%20informationalModal.confirmButtonText;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20currentEntityData.modalRejectText%20=%20informationalModal.rejectButtonText;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20entityData%5Bentity%5D%20=%20currentEntityData;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Listen%20for%20window%20events%20from%20%22surrogate%22%20scripts.%0A%20%20%20%20%20%20%20%20%20%20%20%20window.addEventListener('ddg-ctp',%20(/**%20@type%20%7BCustomEvent%7D%20*/%20event)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!('detail'%20in%20event))%20return;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20entity%20=%20event.detail?.entity;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!entities.includes(entity))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Unknown%20entity,%20reject%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(event.detail?.appID)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20appID%20=%20JSON.stringify(event.detail.appID).replace(/%22/g,%20'');%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Handle%20login%20call%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(event.detail?.action%20===%20'login')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Even%20if%20the%20user%20cancels%20the%20login%20attempt,%20consider%20Facebook%20Click%20to%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Load%20to%20have%20been%20active%20on%20the%20page%20if%20the%20user%20reports%20the%20page%20as%20broken.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(entity%20===%20'Facebook,%20Inc.')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20notifyFacebookLogin();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(entityData%5Bentity%5D.shouldShowLoginModal)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20handleUnblockConfirmation(this.platform.name,%20entity,%20runLogin,%20entity);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20runLogin(entity);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Listen%20to%20message%20from%20Platform%20letting%20CTL%20know%20that%20we're%20ready%20to%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20replace%20elements%20in%20the%20page%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20this.messaging.subscribe(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'displayClickToLoadPlaceholders',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20TODO:%20Pass%20%60message.options.ruleAction%60%20through,%20that%20way%20only%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20content%20corresponding%20to%20the%20entity%20for%20that%20ruleAction%20need%20to%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20be%20replaced%20with%20a%20placeholder.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20()%20=%3E%20this.replaceClickToLoadElements(),%0A%20%20%20%20%20%20%20%20%20%20%20%20);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Request%20the%20current%20state%20of%20Click%20to%20Load%20from%20the%20platform.%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Note:%20When%20the%20response%20is%20received,%20the%20response%20handler%20resolves%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20the%20readyToDisplayPlaceholders%20Promise.%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20clickToLoadState%20=%20await%20this.messaging.request('getClickToLoadState');%0A%20%20%20%20%20%20%20%20%20%20%20%20this.onClickToLoadState(clickToLoadState);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Then%20wait%20for%20the%20page%20to%20finish%20loading,%20and%20resolve%20the%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20afterPageLoad%20Promise.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(document.readyState%20===%20'complete')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20afterPageLoadResolver();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20window.addEventListener('load',%20afterPageLoadResolver,%20%7B%20once:%20true%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20await%20afterPageLoad;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20On%20some%20websites,%20the%20%22ddg-ctp-ready%22%20event%20is%20occasionally%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20dispatched%20too%20early,%20before%20the%20listener%20is%20ready%20to%20receive%20it.%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20To%20counter%20that,%20catch%20%22ddg-ctp-surrogate-load%22%20events%20dispatched%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20_after_%20page,%20so%20the%20%22ddg-ctp-ready%22%20event%20can%20be%20dispatched%20again.%0A%20%20%20%20%20%20%20%20%20%20%20%20window.addEventListener('ddg-ctp-surrogate-load',%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20originalWindowDispatchEvent(createCustomEvent('ddg-ctp-ready'));%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Then%20wait%20for%20any%20in-progress%20element%20replacements,%20before%20letting%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20the%20surrogate%20scripts%20know%20to%20start.%0A%20%20%20%20%20%20%20%20%20%20%20%20window.setTimeout(()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20originalWindowDispatchEvent(createCustomEvent('ddg-ctp-ready'));%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%200);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20This%20is%20only%20called%20by%20the%20current%20integration%20between%20Android%20and%20Extension%20and%20is%20now%0A%20%20%20%20%20%20%20%20%20*%20used%20to%20connect%20only%20these%20Platforms%20responses%20with%20the%20temporary%20implementation%20of%0A%20%20%20%20%20%20%20%20%20*%20SendMessageMessagingTransport%20that%20wraps%20this%20communication.%0A%20%20%20%20%20%20%20%20%20*%20This%20can%20be%20removed%20once%20they%20have%20their%20own%20Messaging%20integration.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20update(message)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20TODO:%20Once%20all%20Click%20to%20Load%20messages%20include%20the%20feature%20property,%20drop%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20%20%20%20%20%20%20messages%20that%20don't%20include%20the%20feature%20property%20too.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(message?.feature%20&&%20message?.feature%20!==%20'clickToLoad')%20return;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20messageType%20=%20message?.messageType;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!messageType)%20return;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!this._clickToLoadMessagingTransport)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('_clickToLoadMessagingTransport%20not%20ready.%20Cannot%20operate%20click%20to%20load%20without%20a%20messaging%20backend');%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Send%20to%20Messaging%20layer%20the%20response%20or%20subscription%20message%20received%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20from%20the%20Platform.%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this._clickToLoadMessagingTransport.onResponse(message);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Update%20Click%20to%20Load%20internal%20state%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BObject%7D%20state%20Click%20to%20Load%20state%20response%20from%20the%20Platform%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean%7D%20state.devMode%20Developer%20or%20Production%20environment%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7Bboolean%7D%20state.youtubePreviewsEnabled%20YouTube%20Click%20to%20Load%20-%20YT%20Previews%20enabled%20flag%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20onClickToLoadState(state)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20devMode%20=%20state.devMode;%0A%20%20%20%20%20%20%20%20%20%20%20%20isYoutubePreviewsEnabled%20=%20state.youtubePreviewsEnabled;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Mark%20the%20feature%20as%20ready,%20to%20allow%20placeholder%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20replacements%20to%20start.%0A%20%20%20%20%20%20%20%20%20%20%20%20readyToDisplayPlaceholdersResolver();%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20Replace%20the%20blocked%20CTL%20elements%20on%20the%20page%20with%20placeholders.%0A%20%20%20%20%20%20%20%20%20*%20@param%20%7BHTMLElement%7D%20%5BtargetElement%5D%0A%20%20%20%20%20%20%20%20%20*%20%20%20If%20specified,%20only%20this%20element%20will%20be%20replaced%20(assuming%20it%20matches%0A%20%20%20%20%20%20%20%20%20*%20%20%20one%20of%20the%20expected%20CSS%20selectors).%20If%20omitted,%20all%20matching%20elements%0A%20%20%20%20%20%20%20%20%20*%20%20%20in%20the%20document%20will%20be%20replaced%20instead.%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20async%20replaceClickToLoadElements(targetElement)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20await%20readyToDisplayPlaceholders;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20entity%20of%20Object.keys(config))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20widgetData%20of%20Object.values(config%5Bentity%5D.elementData))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20selector%20=%20widgetData.selectors.join();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20trackingElements%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(targetElement)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(targetElement.matches(selector))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20trackingElements.push(targetElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20trackingElements%20=%20Array.from(document.querySelectorAll(selector));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20await%20Promise.all(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20trackingElements.map((trackingElement)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(knownTrackingElements.has(trackingElement))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20Promise.resolve();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20knownTrackingElements.add(trackingElement);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20widget%20=%20new%20DuckWidget(widgetData,%20trackingElement,%20entity,%20this.platform);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20createPlaceholderElementAndReplace(widget,%20trackingElement);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20@returns%20%7BMessagingContext%7D%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20get%20messagingContext()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.#messagingContext)%20return%20this.#messagingContext;%0A%20%20%20%20%20%20%20%20%20%20%20%20this.#messagingContext%20=%20this._createMessagingContext();%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.#messagingContext;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Messaging%20layer%20between%20Click%20to%20Load%20and%20the%20Platform%0A%20%20%20%20%20%20%20%20get%20messaging()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this._messaging)%20return%20this._messaging;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(this.platform.name%20===%20'android'%20%7C%7C%20this.platform.name%20===%20'extension')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._clickToLoadMessagingTransport%20=%20new%20SendMessageMessagingTransport();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20config%20=%20new%20TestTransportConfig(this._clickToLoadMessagingTransport);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._messaging%20=%20new%20Messaging(this.messagingContext,%20config);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this._messaging;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(this.platform.name%20===%20'ios'%20%7C%7C%20this.platform.name%20===%20'macos')%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20config%20=%20new%20WebkitMessagingConfig(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20secret:%20'',%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hasModernWebkitAPI:%20true,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20webkitMessageHandlerNames:%20%5B'contentScopeScriptsIsolated'%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20this._messaging%20=%20new%20Messaging(this.messagingContext,%20config);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20this._messaging;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('Messaging%20not%20supported%20yet%20on%20platform:%20'%20+%20this.name);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20var%20platformFeatures%20=%20%7B%0A%20%20%20%20%20%20%20%20ddg_feature_cookie:%20CookieFeature,%0A%20%20%20%20%20%20%20%20ddg_feature_fingerprintingAudio:%20FingerprintingAudio,%0A%20%20%20%20%20%20%20%20ddg_feature_fingerprintingBattery:%20FingerprintingBattery,%0A%20%20%20%20%20%20%20%20ddg_feature_fingerprintingCanvas:%20FingerprintingCanvas,%0A%20%20%20%20%20%20%20%20ddg_feature_googleRejected:%20GoogleRejected,%0A%20%20%20%20%20%20%20%20ddg_feature_gpc:%20GlobalPrivacyControl,%0A%20%20%20%20%20%20%20%20ddg_feature_fingerprintingHardware:%20FingerprintingHardware,%0A%20%20%20%20%20%20%20%20ddg_feature_referrer:%20Referrer,%0A%20%20%20%20%20%20%20%20ddg_feature_fingerprintingScreenSize:%20FingerprintingScreenSize,%0A%20%20%20%20%20%20%20%20ddg_feature_fingerprintingTemporaryStorage:%20FingerprintingTemporaryStorage,%0A%20%20%20%20%20%20%20%20ddg_feature_navigatorInterface:%20NavigatorInterface,%0A%20%20%20%20%20%20%20%20ddg_feature_elementHiding:%20ElementHiding,%0A%20%20%20%20%20%20%20%20ddg_feature_exceptionHandler:%20ExceptionHandler,%0A%20%20%20%20%20%20%20%20ddg_feature_apiManipulation:%20ApiManipulation,%0A%20%20%20%20%20%20%20%20ddg_feature_clickToLoad:%20ClickToLoad%0A%20%20%20%20%7D;%0A%0A%20%20%20%20let%20initArgs%20=%20null;%0A%20%20%20%20const%20updates%20=%20%5B%5D;%0A%20%20%20%20const%20features%20=%20%5B%5D;%0A%20%20%20%20const%20alwaysInitFeatures%20=%20new%20Set(%5B'cookie'%5D);%0A%20%20%20%20const%20performanceMonitor%20=%20new%20PerformanceMonitor();%0A%0A%20%20%20%20//%20It's%20important%20to%20avoid%20enabling%20the%20features%20for%20non-HTML%20documents%20(such%20as%0A%20%20%20%20//%20XML%20documents%20that%20aren't%20XHTML).%20Note%20that%20it's%20necessary%20to%20check%20the%0A%20%20%20%20//%20document%20type%20in%20advance,%20to%20minimise%20the%20risk%20of%20a%20website%20breaking%20the%0A%20%20%20%20//%20checks%20by%20altering%20document.__proto__.%20In%20the%20future,%20it%20might%20be%20worth%0A%20%20%20%20//%20running%20the%20checks%20even%20earlier%20(and%20in%20the%20%22isolated%20world%22%20for%20the%20Chrome%0A%20%20%20%20//%20extension),%20to%20further%20reduce%20that%20risk.%0A%20%20%20%20const%20isHTMLDocument%20=%0A%20%20%20%20%20%20%20%20document%20instanceof%20HTMLDocument%20%7C%7C%20(document%20instanceof%20XMLDocument%20&&%20document.createElement('div')%20instanceof%20HTMLDivElement);%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@typedef%20%7Bobject%7D%20LoadArgs%0A%20%20%20%20%20*%20@property%20%7Bimport('./content-feature').Site%7D%20site%0A%20%20%20%20%20*%20@property%20%7Bimport('./utils.js').Platform%7D%20platform%0A%20%20%20%20%20*%20@property%20%7Bboolean%7D%20documentOriginIsTracker%0A%20%20%20%20%20*%20@property%20%7Bimport('./utils.js').RemoteConfig%7D%20bundledConfig%0A%20%20%20%20%20*%20@property%20%7Bstring%7D%20%5BinjectName%5D%0A%20%20%20%20%20*%20@property%20%7Bobject%7D%20trackerLookup%20-%20provided%20currently%20only%20by%20the%20extension%0A%20%20%20%20%20*%20@property%20%7Bimport('@duckduckgo/messaging').MessagingConfig%7D%20%5BmessagingConfig%5D%0A%20%20%20%20%20*/%0A%0A%20%20%20%20/**%0A%20%20%20%20%20*%20@param%20%7BLoadArgs%7D%20args%0A%20%20%20%20%20*/%0A%20%20%20%20function%20load(args)%20%7B%0A%20%20%20%20%20%20%20%20const%20mark%20=%20performanceMonitor.mark('load');%0A%20%20%20%20%20%20%20%20if%20(!isHTMLDocument)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20featureNames%20=%20platformSupport%5B%22chrome%22%5D%20;%0A%0A%20%20%20%20%20%20%20%20for%20(const%20featureName%20of%20featureNames)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20ContentFeature%20=%20platformFeatures%5B'ddg_feature_'%20+%20featureName%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20featureInstance%20=%20new%20ContentFeature(featureName);%0A%20%20%20%20%20%20%20%20%20%20%20%20featureInstance.callLoad(args);%0A%20%20%20%20%20%20%20%20%20%20%20%20features.push(%7B%20featureName,%20featureInstance%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20mark.end();%0A%20%20%20%20%7D%0A%0A%20%20%20%20async%20function%20init(args)%20%7B%0A%20%20%20%20%20%20%20%20const%20mark%20=%20performanceMonitor.mark('init');%0A%20%20%20%20%20%20%20%20initArgs%20=%20args;%0A%20%20%20%20%20%20%20%20if%20(!isHTMLDocument)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20registerMessageSecret(args.messageSecret);%0A%20%20%20%20%20%20%20%20initStringExemptionLists(args);%0A%20%20%20%20%20%20%20%20const%20resolvedFeatures%20=%20await%20Promise.all(features);%0A%20%20%20%20%20%20%20%20resolvedFeatures.forEach((%7B%20featureInstance,%20featureName%20%7D)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isFeatureBroken(args,%20featureName)%20%7C%7C%20alwaysInitExtensionFeatures(args,%20featureName))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureInstance.callInit(args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20//%20Fire%20off%20updates%20that%20came%20in%20faster%20than%20the%20init%0A%20%20%20%20%20%20%20%20while%20(updates.length)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20update%20=%20updates.pop();%0A%20%20%20%20%20%20%20%20%20%20%20%20await%20updateFeaturesInner(update);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20mark.end();%0A%20%20%20%20%20%20%20%20if%20(args.debug)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20performanceMonitor.measureAll();%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20update(args)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!isHTMLDocument)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(initArgs%20===%20null)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20updates.push(args);%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20updateFeaturesInner(args);%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20alwaysInitExtensionFeatures(args,%20featureName)%20%7B%0A%20%20%20%20%20%20%20%20return%20args.platform.name%20===%20'extension'%20&&%20alwaysInitFeatures.has(featureName);%0A%20%20%20%20%7D%0A%0A%20%20%20%20async%20function%20updateFeaturesInner(args)%20%7B%0A%20%20%20%20%20%20%20%20const%20resolvedFeatures%20=%20await%20Promise.all(features);%0A%20%20%20%20%20%20%20%20resolvedFeatures.forEach((%7B%20featureInstance,%20featureName%20%7D)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isFeatureBroken(initArgs,%20featureName)%20&&%20featureInstance.update)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20featureInstance.update(args);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20exports.init%20=%20init;%0A%20%20%20%20exports.load%20=%20load;%0A%20%20%20%20exports.update%20=%20update;%0A%0A%20%20%20%20return%20exports;%0A%0A%7D)(%7B%7D);%0A")} contentScopeFeatures.load({ platform: { name: 'extension' diff --git a/build/firefox/inject.js b/build/firefox/inject.js index 0291bc660..d939b5aaf 100644 --- a/build/firefox/inject.js +++ b/build/firefox/inject.js @@ -27,7 +27,7 @@ const String$1 = globalThis.String; const Map$1 = globalThis.Map; const Error$2 = globalThis.Error; - const randomUUID = globalThis.crypto?.randomUUID.bind(globalThis.crypto); + const randomUUID = globalThis.crypto?.randomUUID?.bind(globalThis.crypto); var capturedGlobals = /*#__PURE__*/Object.freeze({ __proto__: null, diff --git a/build/integration/contentScope.js b/build/integration/contentScope.js index 6fe9098a7..681b16e88 100644 --- a/build/integration/contentScope.js +++ b/build/integration/contentScope.js @@ -27,7 +27,7 @@ const String$1 = globalThis.String; const Map$1 = globalThis.Map; const Error$2 = globalThis.Error; - const randomUUID = globalThis.crypto?.randomUUID.bind(globalThis.crypto); + const randomUUID = globalThis.crypto?.randomUUID?.bind(globalThis.crypto); var capturedGlobals = /*#__PURE__*/Object.freeze({ __proto__: null, @@ -16745,6 +16745,7 @@ /** * @typedef {{url: string} & Record} BuildUrlAction + * @typedef {Record} BuildActionWithoutUrl * @typedef {Record} UserData */ @@ -16791,7 +16792,7 @@ * Example, `/a/b/${name|capitalize}` -> applies the `capitalize` transform * to the name field * - * @type {Map string)>} + * @type {Map string)>} */ const optionalTransforms = new Map([ ['hyphenated', (value) => value.split(' ').join('-')], @@ -16876,7 +16877,7 @@ * allowing the function to replace them with corresponding data from `userData` after applying any specified transformations. * * @param {string} input - * @param {BuildUrlAction} action + * @param {BuildUrlAction | BuildActionWithoutUrl} action * @param {Record} userData */ function processTemplateStringWithUserData(input, action, userData) { @@ -16896,7 +16897,7 @@ * @param {string} dataKey * @param {string|number} value * @param {string[]} transformNames - * @param {BuildUrlAction} action + * @param {BuildUrlAction | BuildActionWithoutUrl} action */ function applyTransforms(dataKey, value, transformNames, action) { const subject = String(value || ''); @@ -16951,6 +16952,7 @@ * @param {string} params.actionID * @param {string} params.actionType * @param {any} params.response + * @param {import("./actions/extract").Action[]} [params.next] * @param {Record} [params.meta] - optional meta data */ constructor(params) { @@ -21044,9 +21046,44 @@ * @return {import('../types.js').ActionResponse} */ function click(action, userData, root = document) { + /** @type {Array | null} */ + let elements = []; + + if (action.choices?.length) { + const choices = evaluateChoices(action, userData); + + // If we returned null, the intention is to skip execution, so return success + if (choices === null) { + return new SuccessResponse({ actionID: action.id, actionType: action.actionType, response: null }); + } else if ('error' in choices) { + return new ErrorResponse({ actionID: action.id, message: `Unable to evaluate choices: ${choices.error}` }); + } else if (!('elements' in choices)) { + return new ErrorResponse({ actionID: action.id, message: 'No elements provided to click action' }); + } + + elements = choices.elements; + } else { + if (!('elements' in action)) { + return new ErrorResponse({ actionID: action.id, message: 'No elements provided to click action' }); + } + + elements = action.elements; + } + + if (!elements || !elements.length) { + return new ErrorResponse({ actionID: action.id, message: 'No elements provided to click action' }); + } + // there can be multiple elements provided by the action - for (const element of action.elements) { - const rootElement = selectRootElement(element, userData, root); + for (const element of elements) { + let rootElement; + + try { + rootElement = selectRootElement(element, userData, root); + } catch (error) { + return new ErrorResponse({ actionID: action.id, message: `Could not find root element: ${error.message}` }); + } + const elements = getElements(rootElement, element.selector); if (!elements?.length) { @@ -21101,12 +21138,120 @@ } /** + * Evaluate a comparator and return the appropriate function + * @param {string} operator + * @returns {(a: any, b: any) => boolean} + */ + function getComparisonFunction(operator) { + switch (operator) { + case '=': + case '==': + case '===': + return (a, b) => a === b; + case '!=': + case '!==': + return (a, b) => a !== b; + case '<': + return (a, b) => a < b; + case '<=': + return (a, b) => a <= b; + case '>': + return (a, b) => a > b; + case '>=': + return (a, b) => a >= b; + default: + throw new Error(`Invalid operator: ${operator}`); + } + } + + /** + * Evaluates the defined choices (and/or the default) and returns an array of the elements to be clicked + * + * @param {Record} action + * @param {Record} userData + * @returns {{ elements: [Record] } | { error: String } | null} + */ + function evaluateChoices(action, userData) { + if ('elements' in action) { + return { error: 'Elements should be nested inside of choices' }; + } + + for (const choice of action.choices) { + if (!('condition' in choice) || !('elements' in choice)) { + return { error: 'All choices must have a condition and elements' }; + } + + const comparison = runComparison(choice, action, userData); + + if ('error' in comparison) { + return { error: comparison.error }; + } else if ('result' in comparison && comparison.result === true) { + return { elements: choice.elements }; + } + } + + // If there's no default defined, return an error. + if (!('default' in action)) { + return { error: 'All conditions failed and no default action was provided' }; + } + + // If there is a default and it's null (meaning skip any further action) return success. + if (action.default === null) { + // Nothing else to do, return null + return null; + } + + // If the default is defined and not null (without elements), return an error. + if (!('elements' in action.default)) { + return { error: 'Default action must have elements' }; + } + + return { elements: action.default.elements }; + } + + /** + * Attempts to turn a choice definition into an executable comparison and returns the result + * + * @param {Record} choice * @param {Record} action * @param {Record} userData + * @returns {{ result: Boolean } | { error: String }} + */ + function runComparison(choice, action, userData) { + let compare; + let left; + let right; + + try { + compare = getComparisonFunction(choice.condition.operation); + } catch (error) { + return { error: `Unable to get comparison function: ${error.message}` }; + } + + try { + left = processTemplateStringWithUserData(choice.condition.left, action, userData); + right = processTemplateStringWithUserData(choice.condition.right, action, userData); + } catch (error) { + return { error: `Unable to resolve left/right comparison arguments: ${error.message}` }; + } + + let result; + + try { + result = compare(left, right); + } catch (error) { + return { error: `Comparison failed with the following error: ${error.message}` }; + } + + return { result }; + } + + /** + * @param {Record} action * @param {Document} root - * @return {Promise} + * @return {import('../types.js').ActionResponse} */ - async function expectation(action, userData, root = document) { + function expectation(action, root = document) { const results = expectMany(action.expectations, root); // filter out good results + silent failures, leaving only fatal errors @@ -21126,20 +21271,14 @@ // only run later actions if every expectation was met const runActions = results.every((x) => x.result === true); - const secondaryErrors = []; if (action.actions?.length && runActions) { - for (const subAction of action.actions) { - const result = await execute(subAction, userData, root); - - if ('error' in result) { - secondaryErrors.push(result.error); - } - } - - if (secondaryErrors.length > 0) { - return new ErrorResponse({ actionID: action.id, message: secondaryErrors.join(', ') }); - } + return new SuccessResponse({ + actionID: action.id, + actionType: action.actionType, + response: null, + next: action.actions, + }); } return new SuccessResponse({ actionID: action.id, actionType: action.actionType, response: null }); @@ -21286,7 +21425,7 @@ case 'click': return click(action, data(action, inputData, 'userProfile'), root); case 'expectation': - return await expectation(action, data(action, inputData, 'userProfile'), root); + return expectation(action, root); case 'fillForm': return fillForm(action, data(action, inputData, 'extractedProfile'), root); case 'getCaptchaInfo': @@ -21364,7 +21503,6 @@ /** * @typedef {import("./broker-protection/types.js").ActionResponse} ActionResponse */ - class BrokerProtection extends ContentFeature { init() { this.messaging.subscribe('onActionReceived', async (/** @type {any} */ params) => { @@ -21376,40 +21514,30 @@ return this.messaging.notify('actionError', { error: 'No action found.' }); } - /** - * Note: We're not currently guarding against concurrent actions here - * since the native side contains the scheduling logic to prevent it. - */ - let retryConfig = action.retry?.environment === 'web' ? action.retry : undefined; + const { results, exceptions } = await this.exec(action, data); - /** - * Special case for the exact action - */ - if (!retryConfig && action.actionType === 'extract') { - retryConfig = { - interval: { ms: 1000 }, - maxAttempts: 30, - }; - } + if (results) { + // there might only be a single result. + const parent = results[0]; + const errors = results.filter((x) => 'error' in x); - /** - * Special case for when expectation contains a check for an element, retry it - */ - if (!retryConfig && action.actionType === 'expectation') { - if (action.expectations.some((x) => x.type === 'element')) { - retryConfig = { - interval: { ms: 1000 }, - maxAttempts: 30, - }; + // if there are no secondary actions, or just no errors in general, just report the parent action + if (results.length === 1 || errors.length === 0) { + return this.messaging.notify('actionCompleted', { result: parent }); } - } - const { result, exceptions } = await retry(() => execute(action, data), retryConfig); + // here we must have secondary actions that failed. + // so we want to create an error response with the parent ID, but with the errors messages from + // the children + const joinedErrors = errors.map((x) => x.error.message).join(', '); + const response = new ErrorResponse({ + actionID: action.id, + message: 'Secondary actions failed: ' + joinedErrors, + }); - if (result) { - this.messaging.notify('actionCompleted', { result }); + return this.messaging.notify('actionCompleted', { result: response }); } else { - this.messaging.notify('actionError', { error: 'No response found, exceptions: ' + exceptions.join(', ') }); + return this.messaging.notify('actionError', { error: 'No response found, exceptions: ' + exceptions.join(', ') }); } } catch (e) { console.log('unhandled exception: ', e); @@ -21417,6 +21545,70 @@ } }); } + + /** + * Recursively execute actions with the same dataset, collecting all results/exceptions for + * later analysis + * @param {any} action + * @param {Record} data + * @return {Promise<{results: ActionResponse[], exceptions: string[]}>} + */ + async exec(action, data) { + const retryConfig = this.retryConfigFor(action); + const { result, exceptions } = await retry(() => execute(action, data), retryConfig); + + if (result) { + if ('success' in result && Array.isArray(result.success.next)) { + const nextResults = []; + const nextExceptions = []; + + for (const nextAction of result.success.next) { + const { results: subResults, exceptions: subExceptions } = await this.exec(nextAction, data); + + nextResults.push(...subResults); + nextExceptions.push(...subExceptions); + } + return { results: [result, ...nextResults], exceptions: exceptions.concat(nextExceptions) }; + } + return { results: [result], exceptions: [] }; + } + return { results: [], exceptions }; + } + + /** + * Define default retry configurations for certain actions + * + * @param {any} action + * @returns + */ + retryConfigFor(action) { + /** + * Note: We're not currently guarding against concurrent actions here + * since the native side contains the scheduling logic to prevent it. + */ + const retryConfig = action.retry?.environment === 'web' ? action.retry : undefined; + /** + * Special case for the exact action + */ + if (!retryConfig && action.actionType === 'extract') { + return { + interval: { ms: 1000 }, + maxAttempts: 30, + }; + } + /** + * Special case for when expectation contains a check for an element, retry it + */ + if (!retryConfig && action.actionType === 'expectation') { + if (action.expectations.some((x) => x.type === 'element')) { + return { + interval: { ms: 1000 }, + maxAttempts: 30, + }; + } + } + return retryConfig; + } } /** diff --git a/build/windows/contentScope.js b/build/windows/contentScope.js index 747130c4b..9a7a475aa 100644 --- a/build/windows/contentScope.js +++ b/build/windows/contentScope.js @@ -27,7 +27,7 @@ const String$1 = globalThis.String; const Map$1 = globalThis.Map; const Error$2 = globalThis.Error; - const randomUUID = globalThis.crypto?.randomUUID.bind(globalThis.crypto); + const randomUUID = globalThis.crypto?.randomUUID?.bind(globalThis.crypto); var capturedGlobals = /*#__PURE__*/Object.freeze({ __proto__: null, @@ -11799,6 +11799,7 @@ /** * @typedef {{url: string} & Record} BuildUrlAction + * @typedef {Record} BuildActionWithoutUrl * @typedef {Record} UserData */ @@ -11845,7 +11846,7 @@ * Example, `/a/b/${name|capitalize}` -> applies the `capitalize` transform * to the name field * - * @type {Map string)>} + * @type {Map string)>} */ const optionalTransforms = new Map([ ['hyphenated', (value) => value.split(' ').join('-')], @@ -11930,7 +11931,7 @@ * allowing the function to replace them with corresponding data from `userData` after applying any specified transformations. * * @param {string} input - * @param {BuildUrlAction} action + * @param {BuildUrlAction | BuildActionWithoutUrl} action * @param {Record} userData */ function processTemplateStringWithUserData(input, action, userData) { @@ -11950,7 +11951,7 @@ * @param {string} dataKey * @param {string|number} value * @param {string[]} transformNames - * @param {BuildUrlAction} action + * @param {BuildUrlAction | BuildActionWithoutUrl} action */ function applyTransforms(dataKey, value, transformNames, action) { const subject = String(value || ''); @@ -12005,6 +12006,7 @@ * @param {string} params.actionID * @param {string} params.actionType * @param {any} params.response + * @param {import("./actions/extract").Action[]} [params.next] * @param {Record} [params.meta] - optional meta data */ constructor(params) { @@ -16098,9 +16100,44 @@ * @return {import('../types.js').ActionResponse} */ function click(action, userData, root = document) { + /** @type {Array | null} */ + let elements = []; + + if (action.choices?.length) { + const choices = evaluateChoices(action, userData); + + // If we returned null, the intention is to skip execution, so return success + if (choices === null) { + return new SuccessResponse({ actionID: action.id, actionType: action.actionType, response: null }); + } else if ('error' in choices) { + return new ErrorResponse({ actionID: action.id, message: `Unable to evaluate choices: ${choices.error}` }); + } else if (!('elements' in choices)) { + return new ErrorResponse({ actionID: action.id, message: 'No elements provided to click action' }); + } + + elements = choices.elements; + } else { + if (!('elements' in action)) { + return new ErrorResponse({ actionID: action.id, message: 'No elements provided to click action' }); + } + + elements = action.elements; + } + + if (!elements || !elements.length) { + return new ErrorResponse({ actionID: action.id, message: 'No elements provided to click action' }); + } + // there can be multiple elements provided by the action - for (const element of action.elements) { - const rootElement = selectRootElement(element, userData, root); + for (const element of elements) { + let rootElement; + + try { + rootElement = selectRootElement(element, userData, root); + } catch (error) { + return new ErrorResponse({ actionID: action.id, message: `Could not find root element: ${error.message}` }); + } + const elements = getElements(rootElement, element.selector); if (!elements?.length) { @@ -16155,12 +16192,120 @@ } /** + * Evaluate a comparator and return the appropriate function + * @param {string} operator + * @returns {(a: any, b: any) => boolean} + */ + function getComparisonFunction(operator) { + switch (operator) { + case '=': + case '==': + case '===': + return (a, b) => a === b; + case '!=': + case '!==': + return (a, b) => a !== b; + case '<': + return (a, b) => a < b; + case '<=': + return (a, b) => a <= b; + case '>': + return (a, b) => a > b; + case '>=': + return (a, b) => a >= b; + default: + throw new Error(`Invalid operator: ${operator}`); + } + } + + /** + * Evaluates the defined choices (and/or the default) and returns an array of the elements to be clicked + * + * @param {Record} action + * @param {Record} userData + * @returns {{ elements: [Record] } | { error: String } | null} + */ + function evaluateChoices(action, userData) { + if ('elements' in action) { + return { error: 'Elements should be nested inside of choices' }; + } + + for (const choice of action.choices) { + if (!('condition' in choice) || !('elements' in choice)) { + return { error: 'All choices must have a condition and elements' }; + } + + const comparison = runComparison(choice, action, userData); + + if ('error' in comparison) { + return { error: comparison.error }; + } else if ('result' in comparison && comparison.result === true) { + return { elements: choice.elements }; + } + } + + // If there's no default defined, return an error. + if (!('default' in action)) { + return { error: 'All conditions failed and no default action was provided' }; + } + + // If there is a default and it's null (meaning skip any further action) return success. + if (action.default === null) { + // Nothing else to do, return null + return null; + } + + // If the default is defined and not null (without elements), return an error. + if (!('elements' in action.default)) { + return { error: 'Default action must have elements' }; + } + + return { elements: action.default.elements }; + } + + /** + * Attempts to turn a choice definition into an executable comparison and returns the result + * + * @param {Record} choice * @param {Record} action * @param {Record} userData + * @returns {{ result: Boolean } | { error: String }} + */ + function runComparison(choice, action, userData) { + let compare; + let left; + let right; + + try { + compare = getComparisonFunction(choice.condition.operation); + } catch (error) { + return { error: `Unable to get comparison function: ${error.message}` }; + } + + try { + left = processTemplateStringWithUserData(choice.condition.left, action, userData); + right = processTemplateStringWithUserData(choice.condition.right, action, userData); + } catch (error) { + return { error: `Unable to resolve left/right comparison arguments: ${error.message}` }; + } + + let result; + + try { + result = compare(left, right); + } catch (error) { + return { error: `Comparison failed with the following error: ${error.message}` }; + } + + return { result }; + } + + /** + * @param {Record} action * @param {Document} root - * @return {Promise} + * @return {import('../types.js').ActionResponse} */ - async function expectation(action, userData, root = document) { + function expectation(action, root = document) { const results = expectMany(action.expectations, root); // filter out good results + silent failures, leaving only fatal errors @@ -16180,20 +16325,14 @@ // only run later actions if every expectation was met const runActions = results.every((x) => x.result === true); - const secondaryErrors = []; if (action.actions?.length && runActions) { - for (const subAction of action.actions) { - const result = await execute(subAction, userData, root); - - if ('error' in result) { - secondaryErrors.push(result.error); - } - } - - if (secondaryErrors.length > 0) { - return new ErrorResponse({ actionID: action.id, message: secondaryErrors.join(', ') }); - } + return new SuccessResponse({ + actionID: action.id, + actionType: action.actionType, + response: null, + next: action.actions, + }); } return new SuccessResponse({ actionID: action.id, actionType: action.actionType, response: null }); @@ -16340,7 +16479,7 @@ case 'click': return click(action, data(action, inputData, 'userProfile'), root); case 'expectation': - return await expectation(action, data(action, inputData, 'userProfile'), root); + return expectation(action, root); case 'fillForm': return fillForm(action, data(action, inputData, 'extractedProfile'), root); case 'getCaptchaInfo': @@ -16418,7 +16557,6 @@ /** * @typedef {import("./broker-protection/types.js").ActionResponse} ActionResponse */ - class BrokerProtection extends ContentFeature { init() { this.messaging.subscribe('onActionReceived', async (/** @type {any} */ params) => { @@ -16430,40 +16568,30 @@ return this.messaging.notify('actionError', { error: 'No action found.' }); } - /** - * Note: We're not currently guarding against concurrent actions here - * since the native side contains the scheduling logic to prevent it. - */ - let retryConfig = action.retry?.environment === 'web' ? action.retry : undefined; + const { results, exceptions } = await this.exec(action, data); - /** - * Special case for the exact action - */ - if (!retryConfig && action.actionType === 'extract') { - retryConfig = { - interval: { ms: 1000 }, - maxAttempts: 30, - }; - } + if (results) { + // there might only be a single result. + const parent = results[0]; + const errors = results.filter((x) => 'error' in x); - /** - * Special case for when expectation contains a check for an element, retry it - */ - if (!retryConfig && action.actionType === 'expectation') { - if (action.expectations.some((x) => x.type === 'element')) { - retryConfig = { - interval: { ms: 1000 }, - maxAttempts: 30, - }; + // if there are no secondary actions, or just no errors in general, just report the parent action + if (results.length === 1 || errors.length === 0) { + return this.messaging.notify('actionCompleted', { result: parent }); } - } - const { result, exceptions } = await retry(() => execute(action, data), retryConfig); + // here we must have secondary actions that failed. + // so we want to create an error response with the parent ID, but with the errors messages from + // the children + const joinedErrors = errors.map((x) => x.error.message).join(', '); + const response = new ErrorResponse({ + actionID: action.id, + message: 'Secondary actions failed: ' + joinedErrors, + }); - if (result) { - this.messaging.notify('actionCompleted', { result }); + return this.messaging.notify('actionCompleted', { result: response }); } else { - this.messaging.notify('actionError', { error: 'No response found, exceptions: ' + exceptions.join(', ') }); + return this.messaging.notify('actionError', { error: 'No response found, exceptions: ' + exceptions.join(', ') }); } } catch (e) { console.log('unhandled exception: ', e); @@ -16471,6 +16599,70 @@ } }); } + + /** + * Recursively execute actions with the same dataset, collecting all results/exceptions for + * later analysis + * @param {any} action + * @param {Record} data + * @return {Promise<{results: ActionResponse[], exceptions: string[]}>} + */ + async exec(action, data) { + const retryConfig = this.retryConfigFor(action); + const { result, exceptions } = await retry(() => execute(action, data), retryConfig); + + if (result) { + if ('success' in result && Array.isArray(result.success.next)) { + const nextResults = []; + const nextExceptions = []; + + for (const nextAction of result.success.next) { + const { results: subResults, exceptions: subExceptions } = await this.exec(nextAction, data); + + nextResults.push(...subResults); + nextExceptions.push(...subExceptions); + } + return { results: [result, ...nextResults], exceptions: exceptions.concat(nextExceptions) }; + } + return { results: [result], exceptions: [] }; + } + return { results: [], exceptions }; + } + + /** + * Define default retry configurations for certain actions + * + * @param {any} action + * @returns + */ + retryConfigFor(action) { + /** + * Note: We're not currently guarding against concurrent actions here + * since the native side contains the scheduling logic to prevent it. + */ + const retryConfig = action.retry?.environment === 'web' ? action.retry : undefined; + /** + * Special case for the exact action + */ + if (!retryConfig && action.actionType === 'extract') { + return { + interval: { ms: 1000 }, + maxAttempts: 30, + }; + } + /** + * Special case for when expectation contains a check for an element, retry it + */ + if (!retryConfig && action.actionType === 'expectation') { + if (action.expectations.some((x) => x.type === 'element')) { + return { + interval: { ms: 1000 }, + maxAttempts: 30, + }; + } + } + return retryConfig; + } } /** diff --git a/injected/integration-test/broker-protection.spec.js b/injected/integration-test/broker-protection.spec.js index 622e22ca5..efe89a7e0 100644 --- a/injected/integration-test/broker-protection.spec.js +++ b/injected/integration-test/broker-protection.spec.js @@ -395,6 +395,70 @@ test.describe('Broker Protection communications', () => { await page.waitForURL((url) => url.hash === '#1-2', { timeout: 2000 }); }); + test('conditional clicks - hard-coded success', async ({ page }, workerInfo) => { + const dbp = BrokerProtectionPage.create(page, workerInfo.project.use); + await dbp.enabled(); + await dbp.navigatesTo('conditional-clicks.html'); + await dbp.receivesAction('conditional-clicks-hard-coded-success.json'); + const response = await dbp.collector.waitForMessage('actionCompleted'); + + dbp.isSuccessMessage(response); + await page.waitForURL((url) => url.hash === '#yes', { timeout: 2000 }); + }); + + test('conditional clicks - hard-coded default', async ({ page }, workerInfo) => { + const dbp = BrokerProtectionPage.create(page, workerInfo.project.use); + await dbp.enabled(); + await dbp.navigatesTo('conditional-clicks.html'); + await dbp.receivesAction('conditional-clicks-hard-coded-default.json'); + const response = await dbp.collector.waitForMessage('actionCompleted'); + + dbp.isSuccessMessage(response); + await page.waitForURL((url) => url.hash === '#no', { timeout: 2000 }); + }); + + test('conditional clicks - do not throw error on defined (but empty) default', async ({ page }, workerInfo) => { + const dbp = BrokerProtectionPage.create(page, workerInfo.project.use); + await dbp.enabled(); + await dbp.navigatesTo('conditional-clicks.html'); + await dbp.receivesAction('conditional-clicks-hard-coded-null-default.json'); + const response = await dbp.collector.waitForMessage('actionCompleted'); + + dbp.isSuccessMessage(response); + }); + + test('conditional clicks - throw error if default is undefined', async ({ page }, workerInfo) => { + const dbp = BrokerProtectionPage.create(page, workerInfo.project.use); + await dbp.enabled(); + await dbp.navigatesTo('conditional-clicks.html'); + await dbp.receivesAction('conditional-clicks-hard-coded-undefined-default.json'); + const response = await dbp.collector.waitForMessage('actionCompleted'); + + dbp.isErrorMessage(response); + }); + + test('conditional clicks - interpolated success', async ({ page }, workerInfo) => { + const dbp = BrokerProtectionPage.create(page, workerInfo.project.use); + await dbp.enabled(); + await dbp.navigatesTo('conditional-clicks.html'); + await dbp.receivesAction('conditional-clicks-interpolated-success.json'); + const response = await dbp.collector.waitForMessage('actionCompleted'); + + dbp.isSuccessMessage(response); + await page.waitForURL((url) => url.hash === '#yes', { timeout: 2000 }); + }); + + test('conditional clicks - interpolated default', async ({ page }, workerInfo) => { + const dbp = BrokerProtectionPage.create(page, workerInfo.project.use); + await dbp.enabled(); + await dbp.navigatesTo('conditional-clicks.html'); + await dbp.receivesAction('conditional-clicks-interpolated-default.json'); + const response = await dbp.collector.waitForMessage('actionCompleted'); + + dbp.isSuccessMessage(response); + await page.waitForURL((url) => url.hash === '#no', { timeout: 2000 }); + }); + test('getCaptchaInfo', async ({ page }, workerInfo) => { const dbp = BrokerProtectionPage.create(page, workerInfo.project.use); await dbp.enabled(); @@ -524,6 +588,17 @@ test.describe('Broker Protection communications', () => { expect(currentUrl).not.toContain('#'); }); + test('expectation with conditional subaction', async ({ page }, workerInfo) => { + const dbp = BrokerProtectionPage.create(page, workerInfo.project.use); + await dbp.enabled(); + await dbp.navigatesTo('expectation-actions.html'); + await dbp.receivesAction('expectation-actions-conditional-subaction.json'); + const response = await dbp.collector.waitForMessage('actionCompleted'); + + dbp.isSuccessMessage(response); + await page.waitForURL((url) => url.hash === '#2', { timeout: 2000 }); + }); + test.describe('retrying', () => { test('retrying a click', async ({ page }, workerInfo) => { const dbp = BrokerProtectionPage.create(page, workerInfo.project.use); diff --git a/injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-hard-coded-default.json b/injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-hard-coded-default.json new file mode 100644 index 000000000..1f48acc00 --- /dev/null +++ b/injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-hard-coded-default.json @@ -0,0 +1,26 @@ +{ + "state": { + "action": { + "actionType": "click", + "id": "1", + "choices": [ + { + "condition": { + "left": "40", + "operation": ">=", + "right": "45" + }, + "elements": [ + { "type": "button", "selector": ".//a[text()='Yes']" } + ] + } + ], + "default": { + "elements": [ + { "type": "button", "selector": ".//a[text()='No']" } + ] + } + } + } + } + \ No newline at end of file diff --git a/injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-hard-coded-null-default.json b/injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-hard-coded-null-default.json new file mode 100644 index 000000000..cfc5b2b9a --- /dev/null +++ b/injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-hard-coded-null-default.json @@ -0,0 +1,22 @@ +{ + "state": { + "action": { + "actionType": "click", + "id": "1", + "choices": [ + { + "condition": { + "left": "40", + "operation": ">=", + "right": "45" + }, + "elements": [ + { "type": "button", "selector": ".//a[text()='Yes']" } + ] + } + ], + "default": null + } + } + } + \ No newline at end of file diff --git a/injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-hard-coded-success.json b/injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-hard-coded-success.json new file mode 100644 index 000000000..67a1dae18 --- /dev/null +++ b/injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-hard-coded-success.json @@ -0,0 +1,26 @@ +{ + "state": { + "action": { + "actionType": "click", + "id": "1", + "choices": [ + { + "condition": { + "left": "50", + "operation": ">=", + "right": "45" + }, + "elements": [ + { "type": "button", "selector": ".//a[text()='Yes']" } + ] + } + ], + "default": { + "elements": [ + { "type": "button", "selector": ".//a[text()='No']" } + ] + } + } + } + } + \ No newline at end of file diff --git a/injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-hard-coded-undefined-default.json b/injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-hard-coded-undefined-default.json new file mode 100644 index 000000000..71eaa363c --- /dev/null +++ b/injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-hard-coded-undefined-default.json @@ -0,0 +1,26 @@ +{ + "state": { + "action": { + "actionType": "click", + "id": "1", + "retry": { + "environment": "web", + "interval": { "ms": 1000 }, + "maxAttempts": 1 + }, + "choices": [ + { + "condition": { + "left": "40", + "operation": ">=", + "right": "45" + }, + "elements": [ + { "type": "button", "selector": ".//a[text()='Yes']" } + ] + } + ] + } + } + } + \ No newline at end of file diff --git a/injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-interpolated-default.json b/injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-interpolated-default.json new file mode 100644 index 000000000..59c87b140 --- /dev/null +++ b/injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-interpolated-default.json @@ -0,0 +1,33 @@ +{ + "state": { + "action": { + "actionType": "click", + "id": "1", + "choices": [ + { + "condition": { + "left": "${age}", + "operation": ">=", + "right": "45" + }, + "elements": [ + { "type": "button", "selector": ".//a[text()='Yes']" } + ] + } + ], + "default": { + "elements": [ + { "type": "button", "selector": ".//a[text()='No']" } + ] + } + }, + "data": { + "userProfile": { + "age": "40" + } + } + } +} + + + diff --git a/injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-interpolated-success.json b/injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-interpolated-success.json new file mode 100644 index 000000000..6256aad8d --- /dev/null +++ b/injected/integration-test/test-pages/broker-protection/actions/conditional-clicks-interpolated-success.json @@ -0,0 +1,33 @@ +{ + "state": { + "action": { + "actionType": "click", + "id": "1", + "choices": [ + { + "condition": { + "left": "${age}", + "operation": ">=", + "right": "45" + }, + "elements": [ + { "type": "button", "selector": ".//a[text()='Yes']" } + ] + } + ], + "default": { + "elements": [ + { "type": "button", "selector": ".//a[text()='No']" } + ] + } + }, + "data": { + "userProfile": { + "age": "50" + } + } + } +} + + + diff --git a/injected/integration-test/test-pages/broker-protection/actions/expectation-actions-conditional-subaction.json b/injected/integration-test/test-pages/broker-protection/actions/expectation-actions-conditional-subaction.json new file mode 100644 index 000000000..4f9a2346e --- /dev/null +++ b/injected/integration-test/test-pages/broker-protection/actions/expectation-actions-conditional-subaction.json @@ -0,0 +1,43 @@ +{ + "state": { + "action": { + "actionType": "expectation", + "id": "2", + "expectations": [ + { + "type": "text", + "selector": "body", + "expect": "How old is John Doe?" + } + ], + "actions": [ + { + "actionType": "click", + "id": "1", + "choices": [ + { + "condition": { + "left": "${age}", + "operation": ">=", + "right": "45" + }, + "elements": [ + { "type": "button", "selector": ".//a[text()='Yes']" } + ] + } + ], + "default": { + "elements": [ + { "type": "button", "selector": ".//a[text()='No']" } + ] + } + } + ] + }, + "data": { + "userProfile": { + "age": "40" + } + } + } + } \ No newline at end of file diff --git a/injected/integration-test/test-pages/broker-protection/pages/conditional-clicks.html b/injected/integration-test/test-pages/broker-protection/pages/conditional-clicks.html new file mode 100644 index 000000000..20dd4d0e0 --- /dev/null +++ b/injected/integration-test/test-pages/broker-protection/pages/conditional-clicks.html @@ -0,0 +1,26 @@ + + + + + + Broker Protection + + +
+

Is John Doe over the age of 45?

+ Yes + No +
+ + + \ No newline at end of file diff --git a/injected/integration-test/test-pages/broker-protection/pages/expectation-actions.html b/injected/integration-test/test-pages/broker-protection/pages/expectation-actions.html index 7b5aaa1b4..b5f7a1938 100644 --- a/injected/integration-test/test-pages/broker-protection/pages/expectation-actions.html +++ b/injected/integration-test/test-pages/broker-protection/pages/expectation-actions.html @@ -8,16 +8,19 @@
How old is John Doe? - View More + Yes + No
\ No newline at end of file diff --git a/injected/src/captured-globals.js b/injected/src/captured-globals.js index 849bf2a4d..88d58d762 100644 --- a/injected/src/captured-globals.js +++ b/injected/src/captured-globals.js @@ -23,4 +23,4 @@ export const Promise = globalThis.Promise; export const String = globalThis.String; export const Map = globalThis.Map; export const Error = globalThis.Error; -export const randomUUID = globalThis.crypto?.randomUUID.bind(globalThis.crypto); +export const randomUUID = globalThis.crypto?.randomUUID?.bind(globalThis.crypto); diff --git a/injected/src/features/broker-protection.js b/injected/src/features/broker-protection.js index 899001fb1..0f32586b7 100644 --- a/injected/src/features/broker-protection.js +++ b/injected/src/features/broker-protection.js @@ -1,11 +1,11 @@ import ContentFeature from '../content-feature.js'; import { execute } from './broker-protection/execute.js'; import { retry } from '../timer-utils.js'; +import { ErrorResponse } from './broker-protection/types.js'; /** * @typedef {import("./broker-protection/types.js").ActionResponse} ActionResponse */ - export default class BrokerProtection extends ContentFeature { init() { this.messaging.subscribe('onActionReceived', async (/** @type {any} */ params) => { @@ -17,40 +17,30 @@ export default class BrokerProtection extends ContentFeature { return this.messaging.notify('actionError', { error: 'No action found.' }); } - /** - * Note: We're not currently guarding against concurrent actions here - * since the native side contains the scheduling logic to prevent it. - */ - let retryConfig = action.retry?.environment === 'web' ? action.retry : undefined; - - /** - * Special case for the exact action - */ - if (!retryConfig && action.actionType === 'extract') { - retryConfig = { - interval: { ms: 1000 }, - maxAttempts: 30, - }; - } + const { results, exceptions } = await this.exec(action, data); - /** - * Special case for when expectation contains a check for an element, retry it - */ - if (!retryConfig && action.actionType === 'expectation') { - if (action.expectations.some((x) => x.type === 'element')) { - retryConfig = { - interval: { ms: 1000 }, - maxAttempts: 30, - }; + if (results) { + // there might only be a single result. + const parent = results[0]; + const errors = results.filter((x) => 'error' in x); + + // if there are no secondary actions, or just no errors in general, just report the parent action + if (results.length === 1 || errors.length === 0) { + return this.messaging.notify('actionCompleted', { result: parent }); } - } - const { result, exceptions } = await retry(() => execute(action, data), retryConfig); + // here we must have secondary actions that failed. + // so we want to create an error response with the parent ID, but with the errors messages from + // the children + const joinedErrors = errors.map((x) => x.error.message).join(', '); + const response = new ErrorResponse({ + actionID: action.id, + message: 'Secondary actions failed: ' + joinedErrors, + }); - if (result) { - this.messaging.notify('actionCompleted', { result }); + return this.messaging.notify('actionCompleted', { result: response }); } else { - this.messaging.notify('actionError', { error: 'No response found, exceptions: ' + exceptions.join(', ') }); + return this.messaging.notify('actionError', { error: 'No response found, exceptions: ' + exceptions.join(', ') }); } } catch (e) { console.log('unhandled exception: ', e); @@ -58,4 +48,68 @@ export default class BrokerProtection extends ContentFeature { } }); } + + /** + * Recursively execute actions with the same dataset, collecting all results/exceptions for + * later analysis + * @param {any} action + * @param {Record} data + * @return {Promise<{results: ActionResponse[], exceptions: string[]}>} + */ + async exec(action, data) { + const retryConfig = this.retryConfigFor(action); + const { result, exceptions } = await retry(() => execute(action, data), retryConfig); + + if (result) { + if ('success' in result && Array.isArray(result.success.next)) { + const nextResults = []; + const nextExceptions = []; + + for (const nextAction of result.success.next) { + const { results: subResults, exceptions: subExceptions } = await this.exec(nextAction, data); + + nextResults.push(...subResults); + nextExceptions.push(...subExceptions); + } + return { results: [result, ...nextResults], exceptions: exceptions.concat(nextExceptions) }; + } + return { results: [result], exceptions: [] }; + } + return { results: [], exceptions }; + } + + /** + * Define default retry configurations for certain actions + * + * @param {any} action + * @returns + */ + retryConfigFor(action) { + /** + * Note: We're not currently guarding against concurrent actions here + * since the native side contains the scheduling logic to prevent it. + */ + const retryConfig = action.retry?.environment === 'web' ? action.retry : undefined; + /** + * Special case for the exact action + */ + if (!retryConfig && action.actionType === 'extract') { + return { + interval: { ms: 1000 }, + maxAttempts: 30, + }; + } + /** + * Special case for when expectation contains a check for an element, retry it + */ + if (!retryConfig && action.actionType === 'expectation') { + if (action.expectations.some((x) => x.type === 'element')) { + return { + interval: { ms: 1000 }, + maxAttempts: 30, + }; + } + } + return retryConfig; + } } diff --git a/injected/src/features/broker-protection/actions/build-url-transforms.js b/injected/src/features/broker-protection/actions/build-url-transforms.js index 9bed5d270..f942a5523 100644 --- a/injected/src/features/broker-protection/actions/build-url-transforms.js +++ b/injected/src/features/broker-protection/actions/build-url-transforms.js @@ -2,6 +2,7 @@ import { getStateFromAbbreviation } from '../comparisons/address.js'; /** * @typedef {{url: string} & Record} BuildUrlAction + * @typedef {Record} BuildActionWithoutUrl * @typedef {Record} UserData */ @@ -48,7 +49,7 @@ const baseTransforms = new Map([ * Example, `/a/b/${name|capitalize}` -> applies the `capitalize` transform * to the name field * - * @type {Map string)>} + * @type {Map string)>} */ const optionalTransforms = new Map([ ['hyphenated', (value) => value.split(' ').join('-')], @@ -133,7 +134,7 @@ function processPathname(pathname, action, userData) { * allowing the function to replace them with corresponding data from `userData` after applying any specified transformations. * * @param {string} input - * @param {BuildUrlAction} action + * @param {BuildUrlAction | BuildActionWithoutUrl} action * @param {Record} userData */ export function processTemplateStringWithUserData(input, action, userData) { @@ -153,7 +154,7 @@ export function processTemplateStringWithUserData(input, action, userData) { * @param {string} dataKey * @param {string|number} value * @param {string[]} transformNames - * @param {BuildUrlAction} action + * @param {BuildUrlAction | BuildActionWithoutUrl} action */ function applyTransforms(dataKey, value, transformNames, action) { const subject = String(value || ''); diff --git a/injected/src/features/broker-protection/actions/click.js b/injected/src/features/broker-protection/actions/click.js index 75a7197c8..7beed13f0 100644 --- a/injected/src/features/broker-protection/actions/click.js +++ b/injected/src/features/broker-protection/actions/click.js @@ -1,6 +1,7 @@ import { getElements } from '../utils.js'; import { ErrorResponse, SuccessResponse } from '../types.js'; import { extractProfiles } from './extract.js'; +import { processTemplateStringWithUserData } from './build-url-transforms.js'; /** * @param {Record} action @@ -9,9 +10,44 @@ import { extractProfiles } from './extract.js'; * @return {import('../types.js').ActionResponse} */ export function click(action, userData, root = document) { + /** @type {Array | null} */ + let elements = []; + + if (action.choices?.length) { + const choices = evaluateChoices(action, userData); + + // If we returned null, the intention is to skip execution, so return success + if (choices === null) { + return new SuccessResponse({ actionID: action.id, actionType: action.actionType, response: null }); + } else if ('error' in choices) { + return new ErrorResponse({ actionID: action.id, message: `Unable to evaluate choices: ${choices.error}` }); + } else if (!('elements' in choices)) { + return new ErrorResponse({ actionID: action.id, message: 'No elements provided to click action' }); + } + + elements = choices.elements; + } else { + if (!('elements' in action)) { + return new ErrorResponse({ actionID: action.id, message: 'No elements provided to click action' }); + } + + elements = action.elements; + } + + if (!elements || !elements.length) { + return new ErrorResponse({ actionID: action.id, message: 'No elements provided to click action' }); + } + // there can be multiple elements provided by the action - for (const element of action.elements) { - const rootElement = selectRootElement(element, userData, root); + for (const element of elements) { + let rootElement; + + try { + rootElement = selectRootElement(element, userData, root); + } catch (error) { + return new ErrorResponse({ actionID: action.id, message: `Could not find root element: ${error.message}` }); + } + const elements = getElements(rootElement, element.selector); if (!elements?.length) { @@ -64,3 +100,112 @@ function selectRootElement(clickElement, userData, root = document) { throw new Error('`parent` was present on the element, but the configuration is not supported'); } + +/** + * Evaluate a comparator and return the appropriate function + * @param {string} operator + * @returns {(a: any, b: any) => boolean} + */ +export function getComparisonFunction(operator) { + switch (operator) { + case '=': + case '==': + case '===': + return (a, b) => a === b; + case '!=': + case '!==': + return (a, b) => a !== b; + case '<': + return (a, b) => a < b; + case '<=': + return (a, b) => a <= b; + case '>': + return (a, b) => a > b; + case '>=': + return (a, b) => a >= b; + default: + throw new Error(`Invalid operator: ${operator}`); + } +} + +/** + * Evaluates the defined choices (and/or the default) and returns an array of the elements to be clicked + * + * @param {Record} action + * @param {Record} userData + * @returns {{ elements: [Record] } | { error: String } | null} + */ +function evaluateChoices(action, userData) { + if ('elements' in action) { + return { error: 'Elements should be nested inside of choices' }; + } + + for (const choice of action.choices) { + if (!('condition' in choice) || !('elements' in choice)) { + return { error: 'All choices must have a condition and elements' }; + } + + const comparison = runComparison(choice, action, userData); + + if ('error' in comparison) { + return { error: comparison.error }; + } else if ('result' in comparison && comparison.result === true) { + return { elements: choice.elements }; + } + } + + // If there's no default defined, return an error. + if (!('default' in action)) { + return { error: 'All conditions failed and no default action was provided' }; + } + + // If there is a default and it's null (meaning skip any further action) return success. + if (action.default === null) { + // Nothing else to do, return null + return null; + } + + // If the default is defined and not null (without elements), return an error. + if (!('elements' in action.default)) { + return { error: 'Default action must have elements' }; + } + + return { elements: action.default.elements }; +} + +/** + * Attempts to turn a choice definition into an executable comparison and returns the result + * + * @param {Record} choice + * @param {Record} action + * @param {Record} userData + * @returns {{ result: Boolean } | { error: String }} + */ +function runComparison(choice, action, userData) { + let compare; + let left; + let right; + + try { + compare = getComparisonFunction(choice.condition.operation); + } catch (error) { + return { error: `Unable to get comparison function: ${error.message}` }; + } + + try { + left = processTemplateStringWithUserData(choice.condition.left, action, userData); + right = processTemplateStringWithUserData(choice.condition.right, action, userData); + } catch (error) { + return { error: `Unable to resolve left/right comparison arguments: ${error.message}` }; + } + + let result; + + try { + result = compare(left, right); + } catch (error) { + return { error: `Comparison failed with the following error: ${error.message}` }; + } + + return { result }; +} diff --git a/injected/src/features/broker-protection/actions/expectation.js b/injected/src/features/broker-protection/actions/expectation.js index cbdd4bf2c..0af3a71bb 100644 --- a/injected/src/features/broker-protection/actions/expectation.js +++ b/injected/src/features/broker-protection/actions/expectation.js @@ -1,14 +1,12 @@ import { getElement } from '../utils.js'; import { ErrorResponse, SuccessResponse } from '../types.js'; -import { execute } from '../execute.js'; /** * @param {Record} action - * @param {Record} userData * @param {Document} root - * @return {Promise} + * @return {import('../types.js').ActionResponse} */ -export async function expectation(action, userData, root = document) { +export function expectation(action, root = document) { const results = expectMany(action.expectations, root); // filter out good results + silent failures, leaving only fatal errors @@ -28,20 +26,14 @@ export async function expectation(action, userData, root = document) { // only run later actions if every expectation was met const runActions = results.every((x) => x.result === true); - const secondaryErrors = []; if (action.actions?.length && runActions) { - for (const subAction of action.actions) { - const result = await execute(subAction, userData, root); - - if ('error' in result) { - secondaryErrors.push(result.error); - } - } - - if (secondaryErrors.length > 0) { - return new ErrorResponse({ actionID: action.id, message: secondaryErrors.join(', ') }); - } + return new SuccessResponse({ + actionID: action.id, + actionType: action.actionType, + response: null, + next: action.actions, + }); } return new SuccessResponse({ actionID: action.id, actionType: action.actionType, response: null }); diff --git a/injected/src/features/broker-protection/execute.js b/injected/src/features/broker-protection/execute.js index 8cd5b1014..78b139bd1 100644 --- a/injected/src/features/broker-protection/execute.js +++ b/injected/src/features/broker-protection/execute.js @@ -25,7 +25,7 @@ export async function execute(action, inputData, root = document) { case 'click': return click(action, data(action, inputData, 'userProfile'), root); case 'expectation': - return await expectation(action, data(action, inputData, 'userProfile'), root); + return expectation(action, root); case 'fillForm': return fillForm(action, data(action, inputData, 'extractedProfile'), root); case 'getCaptchaInfo': diff --git a/injected/src/features/broker-protection/types.js b/injected/src/features/broker-protection/types.js index cef09cb70..669bac9cc 100644 --- a/injected/src/features/broker-protection/types.js +++ b/injected/src/features/broker-protection/types.js @@ -27,6 +27,7 @@ export class SuccessResponse { * @param {string} params.actionID * @param {string} params.actionType * @param {any} params.response + * @param {import("./actions/extract").Action[]} [params.next] * @param {Record} [params.meta] - optional meta data */ constructor(params) { diff --git a/injected/unit-test/broker-protection.js b/injected/unit-test/broker-protection.js index 147bb77f5..495692dfa 100644 --- a/injected/unit-test/broker-protection.js +++ b/injected/unit-test/broker-protection.js @@ -10,6 +10,7 @@ import { generateRandomInt, hashObject, sortAddressesByStateAndCity } from '../s import { generatePhoneNumber, generateZipCode, generateStreetAddress } from '../src/features/broker-protection/actions/generators.js'; import { CityStateExtractor } from '../src/features/broker-protection/extractors/address.js'; import { ProfileHashTransformer } from '../src/features/broker-protection/extractors/profile-url.js'; +import { getComparisonFunction } from '../src/features/broker-protection/actions/click.js'; describe('Actions', () => { describe('extract', () => { @@ -619,6 +620,32 @@ describe('Actions', () => { ); }); }); + + describe('click', () => { + it('should return the appropriate comparison function for a valid comparator', () => { + const areEqual = getComparisonFunction('='); + expect(areEqual(5, 5)).toBe(true); + + const areNotEqual = getComparisonFunction('!=='); + expect(areNotEqual(6, 5)).toBe(true); + + const isLessThan = getComparisonFunction('<'); + expect(isLessThan(5, 6)).toBe(true); + + const isLessThanOrEqualTo = getComparisonFunction('<='); + expect(isLessThanOrEqualTo(6, 6)).toBe(true); + + const isMoreThan = getComparisonFunction('>'); + expect(isMoreThan(7, 6)).toBe(true); + + const isMoreThanOrEqualTo = getComparisonFunction('>='); + expect(isMoreThanOrEqualTo(7, 7)).toBe(true); + }); + + it('should return an error for an invalid comparator', () => { + expect(() => getComparisonFunction('!!')).toThrow(); + }); + }); }); describe('generators', () => {