tfcconnection-zola/.shadow-cljs/builds/app/dev/goog-js/goog.labs.useragent.browser.js

1 line
82 KiB
JavaScript

["^ ","~:resource-id",["~:shadow.build.classpath/resource","goog/labs/useragent/browser.js"],"~:js","goog.loadModule(function(exports) {\n \"use strict\";\n goog.module(\"goog.labs.userAgent.browser\");\n goog.module.declareLegacyNamespace();\n const util = goog.require(\"goog.labs.userAgent.util\");\n const {AsyncValue, Version} = goog.require(\"goog.labs.userAgent.highEntropy.highEntropyValue\");\n const {assert, assertExists} = goog.require(\"goog.asserts\");\n const {compareVersions} = goog.require(\"goog.string.internal\");\n const {fullVersionList} = goog.require(\"goog.labs.userAgent.highEntropy.highEntropyData\");\n const {useClientHints} = goog.require(\"goog.labs.userAgent\");\n const Brand = {ANDROID_BROWSER:\"Android Browser\", CHROMIUM:\"Chromium\", EDGE:\"Microsoft Edge\", FIREFOX:\"Firefox\", IE:\"Internet Explorer\", OPERA:\"Opera\", SAFARI:\"Safari\", SILK:\"Silk\",};\n exports.Brand = Brand;\n function useUserAgentDataBrand(ignoreClientHintsFlag = false) {\n if (util.ASSUME_CLIENT_HINTS_SUPPORT) {\n return true;\n }\n if (!ignoreClientHintsFlag && !useClientHints()) {\n return false;\n }\n const userAgentData = util.getUserAgentData();\n return !!userAgentData && userAgentData.brands.length > 0;\n }\n function hasFullVersionList() {\n return isAtLeast(Brand.CHROMIUM, 98);\n }\n function matchOpera() {\n if (useUserAgentDataBrand()) {\n return false;\n }\n return util.matchUserAgent(\"Opera\");\n }\n function matchIE() {\n if (useUserAgentDataBrand()) {\n return false;\n }\n return util.matchUserAgent(\"Trident\") || util.matchUserAgent(\"MSIE\");\n }\n function matchEdgeHtml() {\n if (useUserAgentDataBrand()) {\n return false;\n }\n return util.matchUserAgent(\"Edge\");\n }\n function matchEdgeChromium() {\n if (useUserAgentDataBrand()) {\n return util.matchUserAgentDataBrand(Brand.EDGE);\n }\n return util.matchUserAgent(\"Edg/\");\n }\n function matchOperaChromium() {\n if (useUserAgentDataBrand()) {\n return util.matchUserAgentDataBrand(Brand.OPERA);\n }\n return util.matchUserAgent(\"OPR\");\n }\n function matchFirefox() {\n return util.matchUserAgent(\"Firefox\") || util.matchUserAgent(\"FxiOS\");\n }\n function matchSafari() {\n return util.matchUserAgent(\"Safari\") && !(matchChrome() || matchCoast() || matchOpera() || matchEdgeHtml() || matchEdgeChromium() || matchOperaChromium() || matchFirefox() || isSilk() || util.matchUserAgent(\"Android\"));\n }\n function matchCoast() {\n if (useUserAgentDataBrand()) {\n return false;\n }\n return util.matchUserAgent(\"Coast\");\n }\n function matchIosWebview() {\n return (util.matchUserAgent(\"iPad\") || util.matchUserAgent(\"iPhone\")) && !matchSafari() && !matchChrome() && !matchCoast() && !matchFirefox() && util.matchUserAgent(\"AppleWebKit\");\n }\n function matchChrome() {\n if (useUserAgentDataBrand()) {\n return util.matchUserAgentDataBrand(Brand.CHROMIUM);\n }\n return (util.matchUserAgent(\"Chrome\") || util.matchUserAgent(\"CriOS\")) && !matchEdgeHtml() || isSilk();\n }\n function matchAndroidBrowser() {\n return util.matchUserAgent(\"Android\") && !(isChrome() || isFirefox() || isOpera() || isSilk());\n }\n const isOpera = matchOpera;\n exports.isOpera = isOpera;\n const isIE = matchIE;\n exports.isIE = isIE;\n const isEdge = matchEdgeHtml;\n exports.isEdge = isEdge;\n const isEdgeChromium = matchEdgeChromium;\n exports.isEdgeChromium = isEdgeChromium;\n const isOperaChromium = matchOperaChromium;\n exports.isOperaChromium = isOperaChromium;\n const isFirefox = matchFirefox;\n exports.isFirefox = isFirefox;\n const isSafari = matchSafari;\n exports.isSafari = isSafari;\n const isCoast = matchCoast;\n exports.isCoast = isCoast;\n const isIosWebview = matchIosWebview;\n exports.isIosWebview = isIosWebview;\n const isChrome = matchChrome;\n exports.isChrome = isChrome;\n const isAndroidBrowser = matchAndroidBrowser;\n exports.isAndroidBrowser = isAndroidBrowser;\n function isSilk() {\n return util.matchUserAgent(\"Silk\");\n }\n exports.isSilk = isSilk;\n function createVersionMap(versionTuples) {\n const versionMap = {};\n versionTuples.forEach(tuple => {\n const key = tuple[0];\n const value = tuple[1];\n versionMap[key] = value;\n });\n return keys => versionMap[keys.find(key => key in versionMap)] || \"\";\n }\n function getVersion() {\n const userAgentString = util.getUserAgent();\n if (isIE()) {\n return getIEVersion(userAgentString);\n }\n const versionTuples = util.extractVersionTuples(userAgentString);\n const lookUpValueWithKeys = createVersionMap(versionTuples);\n if (isOpera()) {\n return lookUpValueWithKeys([\"Version\", \"Opera\"]);\n }\n if (isEdge()) {\n return lookUpValueWithKeys([\"Edge\"]);\n }\n if (isEdgeChromium()) {\n return lookUpValueWithKeys([\"Edg\"]);\n }\n if (isSilk()) {\n return lookUpValueWithKeys([\"Silk\"]);\n }\n if (isChrome()) {\n return lookUpValueWithKeys([\"Chrome\", \"CriOS\", \"HeadlessChrome\"]);\n }\n const tuple = versionTuples[2];\n return tuple && tuple[1] || \"\";\n }\n exports.getVersion = getVersion;\n function isVersionOrHigher(version) {\n return compareVersions(getVersion(), version) >= 0;\n }\n exports.isVersionOrHigher = isVersionOrHigher;\n function getIEVersion(userAgent) {\n const rv = /rv: *([\\d\\.]*)/.exec(userAgent);\n if (rv && rv[1]) {\n return rv[1];\n }\n let version = \"\";\n const msie = /MSIE +([\\d\\.]+)/.exec(userAgent);\n if (msie && msie[1]) {\n const tridentVersion = /Trident\\/(\\d.\\d)/.exec(userAgent);\n if (msie[1] == \"7.0\") {\n if (tridentVersion && tridentVersion[1]) {\n switch(tridentVersion[1]) {\n case \"4.0\":\n version = \"8.0\";\n break;\n case \"5.0\":\n version = \"9.0\";\n break;\n case \"6.0\":\n version = \"10.0\";\n break;\n case \"7.0\":\n version = \"11.0\";\n break;\n }\n } else {\n version = \"7.0\";\n }\n } else {\n version = msie[1];\n }\n }\n return version;\n }\n function getFullVersionFromUserAgentString(browser) {\n const userAgentString = util.getUserAgent();\n if (browser === Brand.IE) {\n return isIE() ? getIEVersion(userAgentString) : \"\";\n }\n const versionTuples = util.extractVersionTuples(userAgentString);\n const lookUpValueWithKeys = createVersionMap(versionTuples);\n switch(browser) {\n case Brand.OPERA:\n if (isOpera()) {\n return lookUpValueWithKeys([\"Version\", \"Opera\"]);\n } else if (isOperaChromium()) {\n return lookUpValueWithKeys([\"OPR\"]);\n }\n break;\n case Brand.EDGE:\n if (isEdge()) {\n return lookUpValueWithKeys([\"Edge\"]);\n } else if (isEdgeChromium()) {\n return lookUpValueWithKeys([\"Edg\"]);\n }\n break;\n case Brand.CHROMIUM:\n if (isChrome()) {\n return lookUpValueWithKeys([\"Chrome\", \"CriOS\", \"HeadlessChrome\"]);\n }\n break;\n }\n if (browser === Brand.FIREFOX && isFirefox() || browser === Brand.SAFARI && isSafari() || browser === Brand.ANDROID_BROWSER && isAndroidBrowser() || browser === Brand.SILK && isSilk()) {\n const tuple = versionTuples[2];\n return tuple && tuple[1] || \"\";\n }\n return \"\";\n }\n function versionOf_(browser) {\n let versionParts;\n if (useUserAgentDataBrand() && browser !== Brand.SILK) {\n const data = util.getUserAgentData();\n const matchingBrand = data.brands.find(({brand}) => brand === browser);\n if (!matchingBrand || !matchingBrand.version) {\n return NaN;\n }\n versionParts = matchingBrand.version.split(\".\");\n } else {\n const fullVersion = getFullVersionFromUserAgentString(browser);\n if (fullVersion === \"\") {\n return NaN;\n }\n versionParts = fullVersion.split(\".\");\n }\n if (versionParts.length === 0) {\n return NaN;\n }\n const majorVersion = versionParts[0];\n return Number(majorVersion);\n }\n function isAtLeast(brand, majorVersion) {\n assert(Math.floor(majorVersion) === majorVersion, \"Major version must be an integer\");\n return versionOf_(brand) >= majorVersion;\n }\n exports.isAtLeast = isAtLeast;\n function isAtMost(brand, majorVersion) {\n assert(Math.floor(majorVersion) === majorVersion, \"Major version must be an integer\");\n return versionOf_(brand) <= majorVersion;\n }\n exports.isAtMost = isAtMost;\n class HighEntropyBrandVersion {\n constructor(brand, useUach, fallbackVersion) {\n this.brand_ = brand;\n this.version_ = new Version(fallbackVersion);\n this.useUach_ = useUach;\n }\n getIfLoaded() {\n if (this.useUach_) {\n const loadedVersionList = fullVersionList.getIfLoaded();\n if (loadedVersionList !== undefined) {\n const matchingBrand = loadedVersionList.find(({brand}) => this.brand_ === brand);\n assertExists(matchingBrand);\n return new Version(matchingBrand.version);\n }\n }\n if (preUachHasLoaded) {\n return this.version_;\n }\n return;\n }\n async load() {\n if (this.useUach_) {\n const loadedVersionList = await fullVersionList.load();\n if (loadedVersionList !== undefined) {\n const matchingBrand = loadedVersionList.find(({brand}) => this.brand_ === brand);\n assertExists(matchingBrand);\n return new Version(matchingBrand.version);\n }\n } else {\n await 0;\n }\n preUachHasLoaded = true;\n return this.version_;\n }\n }\n let preUachHasLoaded = false;\n async function loadFullVersions() {\n if (useUserAgentDataBrand(true)) {\n await fullVersionList.load();\n }\n preUachHasLoaded = true;\n }\n exports.loadFullVersions = loadFullVersions;\n exports.resetForTesting = () => {\n preUachHasLoaded = false;\n fullVersionList.resetForTesting();\n };\n function fullVersionOf(browser) {\n let fallbackVersionString = \"\";\n if (!hasFullVersionList()) {\n fallbackVersionString = getFullVersionFromUserAgentString(browser);\n }\n const useUach = browser !== Brand.SILK && useUserAgentDataBrand(true);\n if (useUach) {\n const data = util.getUserAgentData();\n if (!data.brands.find(({brand}) => brand === browser)) {\n return undefined;\n }\n } else if (fallbackVersionString === \"\") {\n return undefined;\n }\n return new HighEntropyBrandVersion(browser, useUach, fallbackVersionString);\n }\n exports.fullVersionOf = fullVersionOf;\n function getVersionStringForLogging(browser) {\n if (useUserAgentDataBrand(true)) {\n const fullVersionObj = fullVersionOf(browser);\n if (fullVersionObj) {\n const fullVersion = fullVersionObj.getIfLoaded();\n if (fullVersion) {\n return fullVersion.toVersionStringForLogging();\n }\n const data = util.getUserAgentData();\n const matchingBrand = data.brands.find(({brand}) => brand === browser);\n assertExists(matchingBrand);\n return matchingBrand.version;\n }\n return \"\";\n } else {\n return getFullVersionFromUserAgentString(browser);\n }\n }\n exports.getVersionStringForLogging = getVersionStringForLogging;\n return exports;\n});\n","~:source","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Closure user agent detection (Browser).\n * @see <a href=\"http://www.useragentstring.com/\">User agent strings</a>\n * For more information on rendering engine, platform, or device see the other\n * sub-namespaces in goog.labs.userAgent, goog.labs.userAgent.platform,\n * goog.labs.userAgent.device respectively.)\n */\n\ngoog.module('goog.labs.userAgent.browser');\ngoog.module.declareLegacyNamespace();\n\nconst util = goog.require('goog.labs.userAgent.util');\nconst {AsyncValue, Version} = goog.require('goog.labs.userAgent.highEntropy.highEntropyValue');\nconst {assert, assertExists} = goog.require('goog.asserts');\nconst {compareVersions} = goog.require('goog.string.internal');\nconst {fullVersionList} = goog.require('goog.labs.userAgent.highEntropy.highEntropyData');\nconst {useClientHints} = goog.require('goog.labs.userAgent');\n\n// TODO(nnaze): Refactor to remove excessive exclusion logic in matching\n// functions.\n\n/**\n * A browser brand represents an opaque string that is used for making\n * brand-specific version checks in userAgentData.\n * @enum {string}\n */\nconst Brand = {\n /**\n * The browser brand for Android Browser.\n * Do not depend on the value of this string. Because Android Browser has not\n * implemented userAgentData yet, the value of this string is not guaranteed\n * to stay the same in future revisions.\n */\n ANDROID_BROWSER: 'Android Browser',\n /**\n * The browser brand for Chromium, including Chromium-based Edge and Opera.\n */\n CHROMIUM: 'Chromium',\n /**\n * The browser brand for Edge.\n * This brand can be used to get the version of both EdgeHTML and\n * Chromium-based Edge.\n */\n EDGE: 'Microsoft Edge',\n /**\n * The browser brand for Firefox.\n * Do not depend on the value of this string. Because Firefox has not\n * implemented userAgentData yet, the value of this string is not guaranteed\n * to stay the same in future revisions.\n */\n FIREFOX: 'Firefox',\n /**\n * The browser brand for Internet Explorer.\n * Do not depend on the value of this string. Because IE will never support\n * userAgentData, the value of this string should be treated as opaque (it's\n * used internally for legacy-userAgent fallback).\n */\n IE: 'Internet Explorer',\n /**\n * The browser brand for Opera.\n * This brand can be used to get the version of both Presto- and\n * Chromium-based Opera.\n */\n OPERA: 'Opera',\n /**\n * The browser brand for Safari.\n * Do not depend on the value of this string. Because Safari has not\n * implemented userAgentData yet, the value of this string is not guaranteed\n * to stay the same in future revisions.\n */\n SAFARI: 'Safari',\n /**\n * The browser brand for Silk.\n * See\n * https://docs.aws.amazon.com/silk/latest/developerguide/what-is-silk.html\n * Do not depend on the value of this string. Because Silk does not\n * identify itself in userAgentData yet, the value of this string is not\n * guaranteed to stay the same in future revisions.\n */\n SILK: 'Silk',\n};\nexports.Brand = Brand;\n\n/**\n * @param {boolean=} ignoreClientHintsFlag Iff truthy, the `useClientHints`\n * function will not be called when evaluating if User-Agent Client Hints\n * Brand data can be used. For existing labs.userAgent API surfaces with\n * widespread use, this should be a falsy value so that usage of the Client\n * Hints APIs can be gated behind flags / experiment rollouts.\n * @return {boolean} Whether to use navigator.userAgentData to determine\n * browser's brand.\n */\nfunction useUserAgentDataBrand(ignoreClientHintsFlag = false) {\n if (util.ASSUME_CLIENT_HINTS_SUPPORT) return true;\n // High-entropy API surfaces should not be gated behind the useClientHints\n // check (as in production it is gated behind a define).\n if (!ignoreClientHintsFlag && !useClientHints()) return false;\n const userAgentData = util.getUserAgentData();\n return !!userAgentData && userAgentData.brands.length > 0;\n}\n\n/**\n * @return {boolean} Whether this browser is likely to have the fullVersionList\n * high-entropy Client Hint.\n */\nfunction hasFullVersionList() {\n // https://chromiumdash.appspot.com/commits?commit=1eb643c3057e64ff4d22468432ad16c4cab12879&platform=Linux\n // indicates that for all platforms Chromium 98 shipped this feature.\n // See also\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-CH-UA-Full-Version-List#browser_compatibility\n return isAtLeast(Brand.CHROMIUM, 98);\n}\n\n/**\n * @return {boolean} Whether the user's browser is Opera. Note: Chromium based\n * Opera (Opera 15+) is detected as Chrome to avoid unnecessary special\n * casing.\n */\nfunction matchOpera() {\n if (useUserAgentDataBrand()) {\n // Pre-Chromium Edge doesn't support navigator.userAgentData.\n return false;\n }\n return util.matchUserAgent('Opera');\n}\n\n/** @return {boolean} Whether the user's browser is IE. */\nfunction matchIE() {\n if (useUserAgentDataBrand()) {\n // IE doesn't support navigator.userAgentData.\n return false;\n }\n return util.matchUserAgent('Trident') || util.matchUserAgent('MSIE');\n}\n\n/**\n * @return {boolean} Whether the user's browser is Edge. This refers to\n * EdgeHTML based Edge.\n */\nfunction matchEdgeHtml() {\n if (useUserAgentDataBrand()) {\n // Pre-Chromium Edge doesn't support navigator.userAgentData.\n return false;\n }\n return util.matchUserAgent('Edge');\n}\n\n/** @return {boolean} Whether the user's browser is Chromium based Edge. */\nfunction matchEdgeChromium() {\n if (useUserAgentDataBrand()) {\n return util.matchUserAgentDataBrand(Brand.EDGE);\n }\n return util.matchUserAgent('Edg/');\n}\n\n/** @return {boolean} Whether the user's browser is Chromium based Opera. */\nfunction matchOperaChromium() {\n if (useUserAgentDataBrand()) {\n return util.matchUserAgentDataBrand(Brand.OPERA);\n }\n return util.matchUserAgent('OPR');\n}\n\n/** @return {boolean} Whether the user's browser is Firefox. */\nfunction matchFirefox() {\n // Firefox doesn't support navigator.userAgentData yet, so use\n // navigator.userAgent.\n return util.matchUserAgent('Firefox') || util.matchUserAgent('FxiOS');\n}\n\n/** @return {boolean} Whether the user's browser is Safari. */\nfunction matchSafari() {\n // Apple-based browsers don't support navigator.userAgentData yet, so use\n // navigator.userAgent.\n return util.matchUserAgent('Safari') &&\n !(matchChrome() || matchCoast() || matchOpera() || matchEdgeHtml() ||\n matchEdgeChromium() || matchOperaChromium() || matchFirefox() ||\n isSilk() || util.matchUserAgent('Android'));\n}\n\n/**\n * @return {boolean} Whether the user's browser is Coast (Opera's Webkit-based\n * iOS browser).\n */\nfunction matchCoast() {\n if (useUserAgentDataBrand()) {\n // Coast doesn't support navigator.userAgentData.\n return false;\n }\n return util.matchUserAgent('Coast');\n}\n\n/** @return {boolean} Whether the user's browser is iOS Webview. */\nfunction matchIosWebview() {\n // Apple-based browsers don't support navigator.userAgentData yet, so use\n // navigator.userAgent.\n // iOS Webview does not show up as Chrome or Safari.\n return (util.matchUserAgent('iPad') || util.matchUserAgent('iPhone')) &&\n !matchSafari() && !matchChrome() && !matchCoast() && !matchFirefox() &&\n util.matchUserAgent('AppleWebKit');\n}\n\n/**\n * @return {boolean} Whether the user's browser is any Chromium browser. This\n * returns true for Chrome, Opera 15+, and Edge Chromium.\n */\nfunction matchChrome() {\n if (useUserAgentDataBrand()) {\n return util.matchUserAgentDataBrand(Brand.CHROMIUM);\n }\n return ((util.matchUserAgent('Chrome') || util.matchUserAgent('CriOS')) &&\n !matchEdgeHtml()) ||\n isSilk();\n}\n\n/** @return {boolean} Whether the user's browser is the Android browser. */\nfunction matchAndroidBrowser() {\n // Android can appear in the user agent string for Chrome on Android.\n // This is not the Android standalone browser if it does.\n return util.matchUserAgent('Android') &&\n !(isChrome() || isFirefox() || isOpera() || isSilk());\n}\n\n/** @return {boolean} Whether the user's browser is Opera. */\nconst isOpera = matchOpera;\nexports.isOpera = isOpera;\n\n/** @return {boolean} Whether the user's browser is IE. */\nconst isIE = matchIE;\nexports.isIE = isIE;\n\n/** @return {boolean} Whether the user's browser is EdgeHTML based Edge. */\nconst isEdge = matchEdgeHtml;\nexports.isEdge = isEdge;\n\n/** @return {boolean} Whether the user's browser is Chromium based Edge. */\nconst isEdgeChromium = matchEdgeChromium;\nexports.isEdgeChromium = isEdgeChromium;\n\n/** @return {boolean} Whether the user's browser is Chromium based Opera. */\nconst isOperaChromium = matchOperaChromium;\nexports.isOperaChromium = isOperaChromium;\n\n/** @return {boolean} Whether the user's browser is Firefox. */\nconst isFirefox = matchFirefox;\nexports.isFirefox = isFirefox;\n\n/** @return {boolean} Whether the user's browser is Safari. */\nconst isSafari = matchSafari;\nexports.isSafari = isSafari;\n\n/**\n * @return {boolean} Whether the user's browser is Coast (Opera's Webkit-based\n * iOS browser).\n */\nconst isCoast = matchCoast;\nexports.isCoast = isCoast;\n\n/** @return {boolean} Whether the user's browser is iOS Webview. */\nconst isIosWebview = matchIosWebview;\nexports.isIosWebview = isIosWebview;\n\n/**\n * @return {boolean} Whether the user's browser is any Chromium based browser (\n * Chrome, Blink-based Opera (15+) and Edge Chromium).\n */\nconst isChrome = matchChrome;\nexports.isChrome = isChrome;\n\n/** @return {boolean} Whether the user's browser is the Android browser. */\nconst isAndroidBrowser = matchAndroidBrowser;\nexports.isAndroidBrowser = isAndroidBrowser;\n\n/**\n * For more information, see:\n * http://docs.aws.amazon.com/silk/latest/developerguide/user-agent.html\n * @return {boolean} Whether the user's browser is Silk.\n */\nfunction isSilk() {\n // As of Silk 93, Silk does not identify itself in userAgentData.brands.\n // When Silk changes this behavior, update this method to call\n // matchUserAgentDataBrand (akin to isChrome, etc.)\n return util.matchUserAgent('Silk');\n}\nexports.isSilk = isSilk;\n\n/**\n * A helper function that returns a function mapping a list of candidate\n * version tuple keys to the first version string present under a key.\n * Ex:\n * <code>\n * // Arg extracted from \"Foo/1.2.3 Bar/0.2021\"\n * const mapVersion = createVersionMap([[\"Foo\", \"1.2.3\"], [\"Bar\", \"0.2021\"]]);\n * mapVersion([\"Bar\", \"Foo\"]); // returns \"0.2021\"\n * mapVersion([\"Baz\", \"Foo\"]); // returns \"1.2.3\"\n * mapVersion([\"Baz\", \"???\"]); // returns \"\"\n * </code>\n * @param {!Array<!Array<string>>} versionTuples Version tuples pre-extracted\n * from a user agent string.\n * @return {function(!Array<string>): string} The version string, or empty\n * string if it doesn't exist under the given key.\n */\nfunction createVersionMap(versionTuples) {\n // Construct a map for easy lookup.\n const versionMap = {};\n versionTuples.forEach((tuple) => {\n // Note that the tuple is of length three, but we only care about the\n // first two.\n const key = tuple[0];\n const value = tuple[1];\n versionMap[key] = value;\n });\n\n // Gives the value with the first key it finds, otherwise empty string.\n return (keys) => versionMap[keys.find((key) => key in versionMap)] || '';\n}\n\n/**\n * Returns the browser version.\n *\n * Note that for browsers with multiple brands, this function assumes a primary\n * brand and returns the version for that brand.\n *\n * Additionally, this function is not userAgentData-aware and will return\n * incorrect values when the User Agent string is frozen. The current status of\n * User Agent string freezing is available here:\n * https://www.chromestatus.com/feature/5704553745874944\n *\n * To mitigate both of these potential issues, use\n * getVersionStringForLogging() or fullVersionOf() instead.\n *\n * @return {string} The browser version or empty string if version cannot be\n * determined. Note that for Internet Explorer, this returns the version of\n * the browser, not the version of the rendering engine. (IE 8 in\n * compatibility mode will return 8.0 rather than 7.0. To determine the\n * rendering engine version, look at document.documentMode instead. See\n * http://msdn.microsoft.com/en-us/library/cc196988(v=vs.85).aspx for more\n * details.)\n */\nfunction getVersion() {\n const userAgentString = util.getUserAgent();\n\n // Special case IE since IE's version is inside the parenthesis and\n // without the '/'.\n if (isIE()) {\n return getIEVersion(userAgentString);\n }\n\n const versionTuples = util.extractVersionTuples(userAgentString);\n const lookUpValueWithKeys = createVersionMap(versionTuples);\n\n // Check Opera before Chrome since Opera 15+ has \"Chrome\" in the string.\n // See\n // http://my.opera.com/ODIN/blog/2013/07/15/opera-user-agent-strings-opera-15-and-beyond\n if (isOpera()) {\n // Opera 10 has Version/10.0 but Opera/9.8, so look for \"Version\" first.\n // Opera uses 'OPR' for more recent UAs.\n return lookUpValueWithKeys(['Version', 'Opera']);\n }\n\n // Check Edge before Chrome since it has Chrome in the string.\n if (isEdge()) {\n return lookUpValueWithKeys(['Edge']);\n }\n\n // Check Chromium Edge before Chrome since it has Chrome in the string.\n if (isEdgeChromium()) {\n return lookUpValueWithKeys(['Edg']);\n }\n\n // Check Silk before Chrome since it may have Chrome in its string and be\n // treated as Chrome.\n if (isSilk()) {\n return lookUpValueWithKeys(['Silk']);\n }\n\n if (isChrome()) {\n return lookUpValueWithKeys(['Chrome', 'CriOS', 'HeadlessChrome']);\n }\n\n // Usually products browser versions are in the third tuple after \"Mozilla\"\n // and the engine.\n const tuple = versionTuples[2];\n return tuple && tuple[1] || '';\n}\nexports.getVersion = getVersion;\n\n/**\n * Returns whether the current browser's version is at least as high as the\n * given one.\n *\n * Note that for browsers with multiple brands, this function assumes a primary\n * brand and checks the version for that brand.\n *\n * Additionally, this function is not userAgentData-aware and will return\n * incorrect values when the User Agent string is frozen. The current status of\n * User Agent string freezing is available here:\n * https://www.chromestatus.com/feature/5704553745874944\n *\n * To mitigate both of these potential issues, use isAtLeast()/isAtMost() or\n * fullVersionOf() instead.\n *\n * @param {string|number} version The version to check.\n * @return {boolean} Whether the browser version is higher or the same as the\n * given version.\n * @deprecated Use isAtLeast()/isAtMost() instead.\n */\nfunction isVersionOrHigher(version) {\n return compareVersions(getVersion(), version) >= 0;\n}\nexports.isVersionOrHigher = isVersionOrHigher;\n\n/**\n * A helper function to determine IE version. More information:\n * http://msdn.microsoft.com/en-us/library/ie/bg182625(v=vs.85).aspx#uaString\n * http://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx\n * http://blogs.msdn.com/b/ie/archive/2010/03/23/introducing-ie9-s-user-agent-string.aspx\n * http://blogs.msdn.com/b/ie/archive/2009/01/09/the-internet-explorer-8-user-agent-string-updated-edition.aspx\n * @param {string} userAgent the User-Agent.\n * @return {string}\n */\nfunction getIEVersion(userAgent) {\n // IE11 may identify itself as MSIE 9.0 or MSIE 10.0 due to an IE 11 upgrade\n // bug. Example UA:\n // Mozilla/5.0 (MSIE 9.0; Windows NT 6.1; WOW64; Trident/7.0; rv:11.0)\n // like Gecko.\n // See http://www.whatismybrowser.com/developers/unknown-user-agent-fragments.\n const rv = /rv: *([\\d\\.]*)/.exec(userAgent);\n if (rv && rv[1]) {\n return rv[1];\n }\n\n let version = '';\n const msie = /MSIE +([\\d\\.]+)/.exec(userAgent);\n if (msie && msie[1]) {\n // IE in compatibility mode usually identifies itself as MSIE 7.0; in this\n // case, use the Trident version to determine the version of IE. For more\n // details, see the links above.\n const tridentVersion = /Trident\\/(\\d.\\d)/.exec(userAgent);\n if (msie[1] == '7.0') {\n if (tridentVersion && tridentVersion[1]) {\n switch (tridentVersion[1]) {\n case '4.0':\n version = '8.0';\n break;\n case '5.0':\n version = '9.0';\n break;\n case '6.0':\n version = '10.0';\n break;\n case '7.0':\n version = '11.0';\n break;\n }\n } else {\n version = '7.0';\n }\n } else {\n version = msie[1];\n }\n }\n return version;\n}\n\n/**\n * A helper function to return the navigator.userAgent-supplied full version\n * number of the current browser or an empty string, based on whether the\n * current browser is the one specified.\n * @param {string} browser The brand whose version should be returned.\n * @return {string}\n */\nfunction getFullVersionFromUserAgentString(browser) {\n const userAgentString = util.getUserAgent();\n // Special case IE since IE's version is inside the parenthesis and\n // without the '/'.\n if (browser === Brand.IE) {\n return isIE() ? getIEVersion(userAgentString) : '';\n }\n\n const versionTuples = util.extractVersionTuples(userAgentString);\n const lookUpValueWithKeys = createVersionMap(versionTuples);\n switch (browser) {\n case Brand.OPERA:\n // Opera 10 has Version/10.0 but Opera/9.8, so look for \"Version\"\n // first. Opera uses 'OPR' for more recent UAs.\n if (isOpera()) {\n return lookUpValueWithKeys(['Version', 'Opera']);\n } else if (isOperaChromium()) {\n return lookUpValueWithKeys(['OPR']);\n }\n break;\n case Brand.EDGE:\n if (isEdge()) {\n return lookUpValueWithKeys(['Edge']);\n } else if (isEdgeChromium()) {\n return lookUpValueWithKeys(['Edg']);\n }\n break;\n case Brand.CHROMIUM:\n if (isChrome()) {\n return lookUpValueWithKeys(['Chrome', 'CriOS', 'HeadlessChrome']);\n }\n break;\n }\n\n // For the following browsers, the browser version is in the third tuple after\n // \"Mozilla\" and the engine.\n if ((browser === Brand.FIREFOX && isFirefox()) ||\n (browser === Brand.SAFARI && isSafari()) ||\n (browser === Brand.ANDROID_BROWSER && isAndroidBrowser()) ||\n (browser === Brand.SILK && isSilk())) {\n const tuple = versionTuples[2];\n return tuple && tuple[1] || '';\n }\n\n return '';\n}\n\n/**\n * Returns the major version of the given browser brand, or NaN if the current\n * browser is not the given brand.\n * Note that the major version number may be different depending on which\n * browser is specified. The returned value can be used to make browser version\n * comparisons using comparison operators.\n * @private\n * @param {!Brand} browser The brand whose version should be returned.\n * @return {number} The major version number associated with the current\n * browser under the given brand, or NaN if the current browser doesn't match\n * the given brand.\n */\nfunction versionOf_(browser) {\n let versionParts;\n // Silk currently does not identify itself in its userAgentData.brands array,\n // so if checking its version, always fall back to the user agent string.\n if (useUserAgentDataBrand() && browser !== Brand.SILK) {\n const data = util.getUserAgentData();\n const matchingBrand = data.brands.find(({brand}) => brand === browser);\n if (!matchingBrand || !matchingBrand.version) {\n return NaN;\n }\n versionParts = matchingBrand.version.split('.');\n } else {\n const fullVersion = getFullVersionFromUserAgentString(browser);\n if (fullVersion === '') {\n return NaN;\n }\n versionParts = fullVersion.split('.');\n }\n if (versionParts.length === 0) {\n return NaN;\n }\n const majorVersion = versionParts[0];\n return Number(majorVersion); // Returns NaN if it is not parseable.\n}\n\n/**\n * Returns true if the current browser matches the given brand and is at least\n * the given major version. The major version must be a whole number (i.e.\n * decimals should not be used to represent a minor version).\n * @param {!Brand} brand The brand whose version should be returned.\n * @param {number} majorVersion The major version number to compare against.\n * This must be a whole number.\n * @return {boolean} Whether the current browser both matches the given brand\n * and is at least the given version.\n */\nfunction isAtLeast(brand, majorVersion) {\n assert(\n Math.floor(majorVersion) === majorVersion,\n 'Major version must be an integer');\n return versionOf_(brand) >= majorVersion;\n}\nexports.isAtLeast = isAtLeast;\n\n/**\n * Returns true if the current browser matches the given brand and is at most\n * the given version. The major version must be a whole number (i.e. decimals\n * should not be used to represent a minor version).\n * @param {!Brand} brand The brand whose version should be returned.\n * @param {number} majorVersion The major version number to compare against.\n * This must be a whole number.\n * @return {boolean} Whether the current browser both matches the given brand\n * and is at most the given version.\n */\nfunction isAtMost(brand, majorVersion) {\n assert(\n Math.floor(majorVersion) === majorVersion,\n 'Major version must be an integer');\n return versionOf_(brand) <= majorVersion;\n}\nexports.isAtMost = isAtMost;\n\n/**\n * Loads the high-entropy browser brand/version data and wraps the correct\n * version string in a Version object.\n * @implements {AsyncValue<!Version>}\n */\nclass HighEntropyBrandVersion {\n /**\n * @param {string} brand The brand whose version is retrieved in this\n * container.\n * @param {boolean} useUach Whether to attempt to use the User-Agent Client\n * Hints (UACH) API surface.\n * @param {string} fallbackVersion The fallback version derived from the\n * userAgent string.\n */\n constructor(brand, useUach, fallbackVersion) {\n /** @private @const {string} */\n this.brand_ = brand;\n\n /** @private @const {!Version} */\n this.version_ = new Version(fallbackVersion);\n\n /** @private @const {boolean} */\n this.useUach_ = useUach;\n }\n\n /**\n * @return {!Version|undefined}\n * @override\n */\n getIfLoaded() {\n if (this.useUach_) {\n const loadedVersionList = fullVersionList.getIfLoaded();\n if (loadedVersionList !== undefined) {\n const matchingBrand =\n loadedVersionList.find(({brand}) => this.brand_ === brand);\n // We assumed in fullVersionOf that if the fullVersionList is defined\n // the brands must match. Double-check this here.\n assertExists(matchingBrand);\n return new Version(matchingBrand.version);\n }\n // Fallthrough to fallback on Pre-UACH implementation\n }\n // We want to make sure the loading semantics of the Pre-UACH implementation\n // match those of the UACH implementation. Loading must happen before any\n // data can be retrieved from getIfLoaded.\n // For HighEntropyBrandVersion, loading can either be done by calling #load\n // or by calling the module-local loadFullVersions function.\n if (preUachHasLoaded) {\n return this.version_;\n }\n return;\n }\n\n /**\n * @return {!Promise<!Version>}\n * @override\n */\n async load() {\n if (this.useUach_) {\n const loadedVersionList = await fullVersionList.load();\n if (loadedVersionList !== undefined) {\n const matchingBrand =\n loadedVersionList.find(({brand}) => this.brand_ === brand);\n assertExists(matchingBrand);\n return new Version(matchingBrand.version);\n }\n // Fallthrough to fallback on Pre-UACH implementation\n } else {\n // Await something so that calling load with or without UACH API\n // availability results in waiting at least one macrotask before allowing\n // access to the cached version information.\n await 0;\n }\n // Regardless of whether we are using UACH APIs, we can now allow access to\n // the fallback case\n preUachHasLoaded = true;\n return this.version_;\n }\n}\n\n/**\n * Whether full version data should be considered available when using UACH\n * fallback implementations. This is flipped to true when either\n * loadFullVersions or HighEntropyBrandVersion.prototype.load are called,\n * matching the global singleton semantics of the UACH codepaths.\n */\nlet preUachHasLoaded = false;\n\n/**\n * Requests all full browser versions to be cached. When the returned promise\n * resolves, subsequent calls to `fullVersionOf(...).getIfLoaded()` will return\n * a value.\n *\n * This method should be avoided in favor of directly awaiting\n * `fullVersionOf(...).load()` where it is used.\n *\n * @return {!Promise<void>}\n */\nasync function loadFullVersions() {\n if (useUserAgentDataBrand(true)) {\n await fullVersionList.load();\n }\n preUachHasLoaded = true;\n}\nexports.loadFullVersions = loadFullVersions;\n\n/**\n * Resets module-local caches used by functionality in this module.\n * This is only for use by goog.labs.userAgent.testUtil.resetUserAgent (and\n * labs.userAgent tests).\n * @package\n */\nexports.resetForTesting = () => {\n preUachHasLoaded = false;\n fullVersionList.resetForTesting();\n};\n\n\n/**\n * Returns an object that provides access to the full version string of the\n * current browser -- or undefined, based on whether the current browser matches\n * the requested browser brand. Note that the full version string is a\n * high-entropy value, and must be asynchronously loaded before it can be\n * accessed synchronously.\n * @param {!Brand} browser The brand whose version should be returned.\n * @return {!AsyncValue<!Version>|undefined} An object that can be used\n * to get or load the full version string as a high-entropy value, or\n * undefined if the current browser doesn't match the given brand.\n */\nfunction fullVersionOf(browser) {\n let fallbackVersionString = '';\n // If we are reasonably certain now that the browser we are on has the\n // fullVersionList high-entropy hint, then we can skip computing the fallback\n // value as we won't end up using it.\n if (!hasFullVersionList()) {\n fallbackVersionString = getFullVersionFromUserAgentString(browser);\n }\n // Silk has the UACH API surface, but currently does not identify itself in\n // the userAgentData.brands array. Fallback to using userAgent string version\n // for Silk.\n const useUach = browser !== Brand.SILK && useUserAgentDataBrand(true);\n if (useUach) {\n const data = util.getUserAgentData();\n // Operate under the assumption that the low-entropy and high-entropy lists\n // of brand/version pairs contain an identical set of brands. Therefore, if\n // the low-entropy list doesn't contain the given brand, return undefined.\n if (!data.brands.find(({brand}) => brand === browser)) {\n return undefined;\n }\n } else if (fallbackVersionString === '') {\n return undefined;\n }\n return new HighEntropyBrandVersion(browser, useUach, fallbackVersionString);\n}\nexports.fullVersionOf = fullVersionOf;\n\n\n/**\n * Returns a version string for the current browser or undefined, based on\n * whether the current browser is the one specified.\n * This value should ONLY be used for logging/debugging purposes. Do not use it\n * to branch code paths. For comparing versions, use isAtLeast()/isAtMost() or\n * fullVersionOf() instead.\n * @param {!Brand} browser The brand whose version should be returned.\n * @return {string} The version as a string.\n */\nfunction getVersionStringForLogging(browser) {\n if (useUserAgentDataBrand(true)) {\n const fullVersionObj = fullVersionOf(browser);\n if (fullVersionObj) {\n const fullVersion = fullVersionObj.getIfLoaded();\n if (fullVersion) {\n return fullVersion.toVersionStringForLogging();\n }\n // No full version, return the major version instead.\n const data = util.getUserAgentData();\n const matchingBrand = data.brands.find(({brand}) => brand === browser);\n // Checking for the existence of matchingBrand is not necessary because\n // the existence of fullVersionObj implies that there is already a\n // matching brand.\n assertExists(matchingBrand);\n return matchingBrand.version;\n }\n // If fullVersionObj is undefined, this doesn't mean that the full version\n // is unavailable, but rather that the current browser doesn't match the\n // input `browser` argument.\n return '';\n } else {\n return getFullVersionFromUserAgentString(browser);\n }\n}\nexports.getVersionStringForLogging = getVersionStringForLogging;\n","~:compiled-at",1684858197898,"~:source-map-json","{\n\"version\":3,\n\"file\":\"goog.labs.useragent.browser.js\",\n\"lineCount\":330,\n\"mappings\":\"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\",\n\"sources\":[\"goog/labs/useragent/browser.js\"],\n\"sourcesContent\":[\"/**\\n * @license\\n * Copyright The Closure Library Authors.\\n * SPDX-License-Identifier: Apache-2.0\\n */\\n\\n/**\\n * @fileoverview Closure user agent detection (Browser).\\n * @see <a href=\\\"http://www.useragentstring.com/\\\">User agent strings</a>\\n * For more information on rendering engine, platform, or device see the other\\n * sub-namespaces in goog.labs.userAgent, goog.labs.userAgent.platform,\\n * goog.labs.userAgent.device respectively.)\\n */\\n\\ngoog.module('goog.labs.userAgent.browser');\\ngoog.module.declareLegacyNamespace();\\n\\nconst util = goog.require('goog.labs.userAgent.util');\\nconst {AsyncValue, Version} = goog.require('goog.labs.userAgent.highEntropy.highEntropyValue');\\nconst {assert, assertExists} = goog.require('goog.asserts');\\nconst {compareVersions} = goog.require('goog.string.internal');\\nconst {fullVersionList} = goog.require('goog.labs.userAgent.highEntropy.highEntropyData');\\nconst {useClientHints} = goog.require('goog.labs.userAgent');\\n\\n// TODO(nnaze): Refactor to remove excessive exclusion logic in matching\\n// functions.\\n\\n/**\\n * A browser brand represents an opaque string that is used for making\\n * brand-specific version checks in userAgentData.\\n * @enum {string}\\n */\\nconst Brand = {\\n /**\\n * The browser brand for Android Browser.\\n * Do not depend on the value of this string. Because Android Browser has not\\n * implemented userAgentData yet, the value of this string is not guaranteed\\n * to stay the same in future revisions.\\n */\\n ANDROID_BROWSER: 'Android Browser',\\n /**\\n * The browser brand for Chromium, including Chromium-based Edge and Opera.\\n */\\n CHROMIUM: 'Chromium',\\n /**\\n * The browser brand for Edge.\\n * This brand can be used to get the version of both EdgeHTML and\\n * Chromium-based Edge.\\n */\\n EDGE: 'Microsoft Edge',\\n /**\\n * The browser brand for Firefox.\\n * Do not depend on the value of this string. Because Firefox has not\\n * implemented userAgentData yet, the value of this string is not guaranteed\\n * to stay the same in future revisions.\\n */\\n FIREFOX: 'Firefox',\\n /**\\n * The browser brand for Internet Explorer.\\n * Do not depend on the value of this string. Because IE will never support\\n * userAgentData, the value of this string should be treated as opaque (it's\\n * used internally for legacy-userAgent fallback).\\n */\\n IE: 'Internet Explorer',\\n /**\\n * The browser brand for Opera.\\n * This brand can be used to get the version of both Presto- and\\n * Chromium-based Opera.\\n */\\n OPERA: 'Opera',\\n /**\\n * The browser brand for Safari.\\n * Do not depend on the value of this string. Because Safari has not\\n * implemented userAgentData yet, the value of this string is not guaranteed\\n * to stay the same in future revisions.\\n */\\n SAFARI: 'Safari',\\n /**\\n * The browser brand for Silk.\\n * See\\n * https://docs.aws.amazon.com/silk/latest/developerguide/what-is-silk.html\\n * Do not depend on the value of this string. Because Silk does not\\n * identify itself in userAgentData yet, the value of this string is not\\n * guaranteed to stay the same in future revisions.\\n */\\n SILK: 'Silk',\\n};\\nexports.Brand = Brand;\\n\\n/**\\n * @param {boolean=} ignoreClientHintsFlag Iff truthy, the `useClientHints`\\n * function will not be called when evaluating if User-Agent Client Hints\\n * Brand data can be used. For existing labs.userAgent API surfaces with\\n * widespread use, this should be a falsy value so that usage of the Client\\n * Hints APIs can be gated behind flags / experiment rollouts.\\n * @return {boolean} Whether to use navigator.userAgentData to determine\\n * browser's brand.\\n */\\nfunction useUserAgentDataBrand(ignoreClientHintsFlag = false) {\\n if (util.ASSUME_CLIENT_HINTS_SUPPORT) return true;\\n // High-entropy API surfaces should not be gated behind the useClientHints\\n // check (as in production it is gated behind a define).\\n if (!ignoreClientHintsFlag && !useClientHints()) return false;\\n const userAgentData = util.getUserAgentData();\\n return !!userAgentData && userAgentData.brands.length > 0;\\n}\\n\\n/**\\n * @return {boolean} Whether this browser is likely to have the fullVersionList\\n * high-entropy Client Hint.\\n */\\nfunction hasFullVersionList() {\\n // https://chromiumdash.appspot.com/commits?commit=1eb643c3057e64ff4d22468432ad16c4cab12879&platform=Linux\\n // indicates that for all platforms Chromium 98 shipped this feature.\\n // See also\\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-CH-UA-Full-Version-List#browser_compatibility\\n return isAtLeast(Brand.CHROMIUM, 98);\\n}\\n\\n/**\\n * @return {boolean} Whether the user's browser is Opera. Note: Chromium based\\n * Opera (Opera 15+) is detected as Chrome to avoid unnecessary special\\n * casing.\\n */\\nfunction matchOpera() {\\n if (useUserAgentDataBrand()) {\\n // Pre-Chromium Edge doesn't support navigator.userAgentData.\\n return false;\\n }\\n return util.matchUserAgent('Opera');\\n}\\n\\n/** @return {boolean} Whether the user's browser is IE. */\\nfunction matchIE() {\\n if (useUserAgentDataBrand()) {\\n // IE doesn't support navigator.userAgentData.\\n return false;\\n }\\n return util.matchUserAgent('Trident') || util.matchUserAgent('MSIE');\\n}\\n\\n/**\\n * @return {boolean} Whether the user's browser is Edge. This refers to\\n * EdgeHTML based Edge.\\n */\\nfunction matchEdgeHtml() {\\n if (useUserAgentDataBrand()) {\\n // Pre-Chromium Edge doesn't support navigator.userAgentData.\\n return false;\\n }\\n return util.matchUserAgent('Edge');\\n}\\n\\n/** @return {boolean} Whether the user's browser is Chromium based Edge. */\\nfunction matchEdgeChromium() {\\n if (useUserAgentDataBrand()) {\\n return util.matchUserAgentDataBrand(Brand.EDGE);\\n }\\n return util.matchUserAgent('Edg/');\\n}\\n\\n/** @return {boolean} Whether the user's browser is Chromium based Opera. */\\nfunction matchOperaChromium() {\\n if (useUserAgentDataBrand()) {\\n return util.matchUserAgentDataBrand(Brand.OPERA);\\n }\\n return util.matchUserAgent('OPR');\\n}\\n\\n/** @return {boolean} Whether the user's browser is Firefox. */\\nfunction matchFirefox() {\\n // Firefox doesn't support navigator.userAgentData yet, so use\\n // navigator.userAgent.\\n return util.matchUserAgent('Firefox') || util.matchUserAgent('FxiOS');\\n}\\n\\n/** @return {boolean} Whether the user's browser is Safari. */\\nfunction matchSafari() {\\n // Apple-based browsers don't support navigator.userAgentData yet, so use\\n // navigator.userAgent.\\n return util.matchUserAgent('Safari') &&\\n !(matchChrome() || matchCoast() || matchOpera() || matchEdgeHtml() ||\\n matchEdgeChromium() || matchOperaChromium() || matchFirefox() ||\\n isSilk() || util.matchUserAgent('Android'));\\n}\\n\\n/**\\n * @return {boolean} Whether the user's browser is Coast (Opera's Webkit-based\\n * iOS browser).\\n */\\nfunction matchCoast() {\\n if (useUserAgentDataBrand()) {\\n // Coast doesn't support navigator.userAgentData.\\n return false;\\n }\\n return util.matchUserAgent('Coast');\\n}\\n\\n/** @return {boolean} Whether the user's browser is iOS Webview. */\\nfunction matchIosWebview() {\\n // Apple-based browsers don't support navigator.userAgentData yet, so use\\n // navigator.userAgent.\\n // iOS Webview does not show up as Chrome or Safari.\\n return (util.matchUserAgent('iPad') || util.matchUserAgent('iPhone')) &&\\n !matchSafari() && !matchChrome() && !matchCoast() && !matchFirefox() &&\\n util.matchUserAgent('AppleWebKit');\\n}\\n\\n/**\\n * @return {boolean} Whether the user's browser is any Chromium browser. This\\n * returns true for Chrome, Opera 15+, and Edge Chromium.\\n */\\nfunction matchChrome() {\\n if (useUserAgentDataBrand()) {\\n return util.matchUserAgentDataBrand(Brand.CHROMIUM);\\n }\\n return ((util.matchUserAgent('Chrome') || util.matchUserAgent('CriOS')) &&\\n !matchEdgeHtml()) ||\\n isSilk();\\n}\\n\\n/** @return {boolean} Whether the user's browser is the Android browser. */\\nfunction matchAndroidBrowser() {\\n // Android can appear in the user agent string for Chrome on Android.\\n // This is not the Android standalone browser if it does.\\n return util.matchUserAgent('Android') &&\\n !(isChrome() || isFirefox() || isOpera() || isSilk());\\n}\\n\\n/** @return {boolean} Whether the user's browser is Opera. */\\nconst isOpera = matchOpera;\\nexports.isOpera = isOpera;\\n\\n/** @return {boolean} Whether the user's browser is IE. */\\nconst isIE = matchIE;\\nexports.isIE = isIE;\\n\\n/** @return {boolean} Whether the user's browser is EdgeHTML based Edge. */\\nconst isEdge = matchEdgeHtml;\\nexports.isEdge = isEdge;\\n\\n/** @return {boolean} Whether the user's browser is Chromium based Edge. */\\nconst isEdgeChromium = matchEdgeChromium;\\nexports.isEdgeChromium = isEdgeChromium;\\n\\n/** @return {boolean} Whether the user's browser is Chromium based Opera. */\\nconst isOperaChromium = matchOperaChromium;\\nexports.isOperaChromium = isOperaChromium;\\n\\n/** @return {boolean} Whether the user's browser is Firefox. */\\nconst isFirefox = matchFirefox;\\nexports.isFirefox = isFirefox;\\n\\n/** @return {boolean} Whether the user's browser is Safari. */\\nconst isSafari = matchSafari;\\nexports.isSafari = isSafari;\\n\\n/**\\n * @return {boolean} Whether the user's browser is Coast (Opera's Webkit-based\\n * iOS browser).\\n */\\nconst isCoast = matchCoast;\\nexports.isCoast = isCoast;\\n\\n/** @return {boolean} Whether the user's browser is iOS Webview. */\\nconst isIosWebview = matchIosWebview;\\nexports.isIosWebview = isIosWebview;\\n\\n/**\\n * @return {boolean} Whether the user's browser is any Chromium based browser (\\n * Chrome, Blink-based Opera (15+) and Edge Chromium).\\n */\\nconst isChrome = matchChrome;\\nexports.isChrome = isChrome;\\n\\n/** @return {boolean} Whether the user's browser is the Android browser. */\\nconst isAndroidBrowser = matchAndroidBrowser;\\nexports.isAndroidBrowser = isAndroidBrowser;\\n\\n/**\\n * For more information, see:\\n * http://docs.aws.amazon.com/silk/latest/developerguide/user-agent.html\\n * @return {boolean} Whether the user's browser is Silk.\\n */\\nfunction isSilk() {\\n // As of Silk 93, Silk does not identify itself in userAgentData.brands.\\n // When Silk changes this behavior, update this method to call\\n // matchUserAgentDataBrand (akin to isChrome, etc.)\\n return util.matchUserAgent('Silk');\\n}\\nexports.isSilk = isSilk;\\n\\n/**\\n * A helper function that returns a function mapping a list of candidate\\n * version tuple keys to the first version string present under a key.\\n * Ex:\\n * <code>\\n * // Arg extracted from \\\"Foo/1.2.3 Bar/0.2021\\\"\\n * const mapVersion = createVersionMap([[\\\"Foo\\\", \\\"1.2.3\\\"], [\\\"Bar\\\", \\\"0.2021\\\"]]);\\n * mapVersion([\\\"Bar\\\", \\\"Foo\\\"]); // returns \\\"0.2021\\\"\\n * mapVersion([\\\"Baz\\\", \\\"Foo\\\"]); // returns \\\"1.2.3\\\"\\n * mapVersion([\\\"Baz\\\", \\\"???\\\"]); // returns \\\"\\\"\\n * </code>\\n * @param {!Array<!Array<string>>} versionTuples Version tuples pre-extracted\\n * from a user agent string.\\n * @return {function(!Array<string>): string} The version string, or empty\\n * string if it doesn't exist under the given key.\\n */\\nfunction createVersionMap(versionTuples) {\\n // Construct a map for easy lookup.\\n const versionMap = {};\\n versionTuples.forEach((tuple) => {\\n // Note that the tuple is of length three, but we only care about the\\n // first two.\\n const key = tuple[0];\\n const value = tuple[1];\\n versionMap[key] = value;\\n });\\n\\n // Gives the value with the first key it finds, otherwise empty string.\\n return (keys) => versionMap[keys.find((key) => key in versionMap)] || '';\\n}\\n\\n/**\\n * Returns the browser version.\\n *\\n * Note that for browsers with multiple brands, this function assumes a primary\\n * brand and returns the version for that brand.\\n *\\n * Additionally, this function is not userAgentData-aware and will return\\n * incorrect values when the User Agent string is frozen. The current status of\\n * User Agent string freezing is available here:\\n * https://www.chromestatus.com/feature/5704553745874944\\n *\\n * To mitigate both of these potential issues, use\\n * getVersionStringForLogging() or fullVersionOf() instead.\\n *\\n * @return {string} The browser version or empty string if version cannot be\\n * determined. Note that for Internet Explorer, this returns the version of\\n * the browser, not the version of the rendering engine. (IE 8 in\\n * compatibility mode will return 8.0 rather than 7.0. To determine the\\n * rendering engine version, look at document.documentMode instead. See\\n * http://msdn.microsoft.com/en-us/library/cc196988(v=vs.85).aspx for more\\n * details.)\\n */\\nfunction getVersion() {\\n const userAgentString = util.getUserAgent();\\n\\n // Special case IE since IE's version is inside the parenthesis and\\n // without the '/'.\\n if (isIE()) {\\n return getIEVersion(userAgentString);\\n }\\n\\n const versionTuples = util.extractVersionTuples(userAgentString);\\n const lookUpValueWithKeys = createVersionMap(versionTuples);\\n\\n // Check Opera before Chrome since Opera 15+ has \\\"Chrome\\\" in the string.\\n // See\\n // http://my.opera.com/ODIN/blog/2013/07/15/opera-user-agent-strings-opera-15-and-beyond\\n if (isOpera()) {\\n // Opera 10 has Version/10.0 but Opera/9.8, so look for \\\"Version\\\" first.\\n // Opera uses 'OPR' for more recent UAs.\\n return lookUpValueWithKeys(['Version', 'Opera']);\\n }\\n\\n // Check Edge before Chrome since it has Chrome in the string.\\n if (isEdge()) {\\n return lookUpValueWithKeys(['Edge']);\\n }\\n\\n // Check Chromium Edge before Chrome since it has Chrome in the string.\\n if (isEdgeChromium()) {\\n return lookUpValueWithKeys(['Edg']);\\n }\\n\\n // Check Silk before Chrome since it may have Chrome in its string and be\\n // treated as Chrome.\\n if (isSilk()) {\\n return lookUpValueWithKeys(['Silk']);\\n }\\n\\n if (isChrome()) {\\n return lookUpValueWithKeys(['Chrome', 'CriOS', 'HeadlessChrome']);\\n }\\n\\n // Usually products browser versions are in the third tuple after \\\"Mozilla\\\"\\n // and the engine.\\n const tuple = versionTuples[2];\\n return tuple && tuple[1] || '';\\n}\\nexports.getVersion = getVersion;\\n\\n/**\\n * Returns whether the current browser's version is at least as high as the\\n * given one.\\n *\\n * Note that for browsers with multiple brands, this function assumes a primary\\n * brand and checks the version for that brand.\\n *\\n * Additionally, this function is not userAgentData-aware and will return\\n * incorrect values when the User Agent string is frozen. The current status of\\n * User Agent string freezing is available here:\\n * https://www.chromestatus.com/feature/5704553745874944\\n *\\n * To mitigate both of these potential issues, use isAtLeast()/isAtMost() or\\n * fullVersionOf() instead.\\n *\\n * @param {string|number} version The version to check.\\n * @return {boolean} Whether the browser version is higher or the same as the\\n * given version.\\n * @deprecated Use isAtLeast()/isAtMost() instead.\\n */\\nfunction isVersionOrHigher(version) {\\n return compareVersions(getVersion(), version) >= 0;\\n}\\nexports.isVersionOrHigher = isVersionOrHigher;\\n\\n/**\\n * A helper function to determine IE version. More information:\\n * http://msdn.microsoft.com/en-us/library/ie/bg182625(v=vs.85).aspx#uaString\\n * http://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx\\n * http://blogs.msdn.com/b/ie/archive/2010/03/23/introducing-ie9-s-user-agent-string.aspx\\n * http://blogs.msdn.com/b/ie/archive/2009/01/09/the-internet-explorer-8-user-agent-string-updated-edition.aspx\\n * @param {string} userAgent the User-Agent.\\n * @return {string}\\n */\\nfunction getIEVersion(userAgent) {\\n // IE11 may identify itself as MSIE 9.0 or MSIE 10.0 due to an IE 11 upgrade\\n // bug. Example UA:\\n // Mozilla/5.0 (MSIE 9.0; Windows NT 6.1; WOW64; Trident/7.0; rv:11.0)\\n // like Gecko.\\n // See http://www.whatismybrowser.com/developers/unknown-user-agent-fragments.\\n const rv = /rv: *([\\\\d\\\\.]*)/.exec(userAgent);\\n if (rv && rv[1]) {\\n return rv[1];\\n }\\n\\n let version = '';\\n const msie = /MSIE +([\\\\d\\\\.]+)/.exec(userAgent);\\n if (msie && msie[1]) {\\n // IE in compatibility mode usually identifies itself as MSIE 7.0; in this\\n // case, use the Trident version to determine the version of IE. For more\\n // details, see the links above.\\n const tridentVersion = /Trident\\\\/(\\\\d.\\\\d)/.exec(userAgent);\\n if (msie[1] == '7.0') {\\n if (tridentVersion && tridentVersion[1]) {\\n switch (tridentVersion[1]) {\\n case '4.0':\\n version = '8.0';\\n break;\\n case '5.0':\\n version = '9.0';\\n break;\\n case '6.0':\\n version = '10.0';\\n break;\\n case '7.0':\\n version = '11.0';\\n break;\\n }\\n } else {\\n version = '7.0';\\n }\\n } else {\\n version = msie[1];\\n }\\n }\\n return version;\\n}\\n\\n/**\\n * A helper function to return the navigator.userAgent-supplied full version\\n * number of the current browser or an empty string, based on whether the\\n * current browser is the one specified.\\n * @param {string} browser The brand whose version should be returned.\\n * @return {string}\\n */\\nfunction getFullVersionFromUserAgentString(browser) {\\n const userAgentString = util.getUserAgent();\\n // Special case IE since IE's version is inside the parenthesis and\\n // without the '/'.\\n if (browser === Brand.IE) {\\n return isIE() ? getIEVersion(userAgentString) : '';\\n }\\n\\n const versionTuples = util.extractVersionTuples(userAgentString);\\n const lookUpValueWithKeys = createVersionMap(versionTuples);\\n switch (browser) {\\n case Brand.OPERA:\\n // Opera 10 has Version/10.0 but Opera/9.8, so look for \\\"Version\\\"\\n // first. Opera uses 'OPR' for more recent UAs.\\n if (isOpera()) {\\n return lookUpValueWithKeys(['Version', 'Opera']);\\n } else if (isOperaChromium()) {\\n return lookUpValueWithKeys(['OPR']);\\n }\\n break;\\n case Brand.EDGE:\\n if (isEdge()) {\\n return lookUpValueWithKeys(['Edge']);\\n } else if (isEdgeChromium()) {\\n return lookUpValueWithKeys(['Edg']);\\n }\\n break;\\n case Brand.CHROMIUM:\\n if (isChrome()) {\\n return lookUpValueWithKeys(['Chrome', 'CriOS', 'HeadlessChrome']);\\n }\\n break;\\n }\\n\\n // For the following browsers, the browser version is in the third tuple after\\n // \\\"Mozilla\\\" and the engine.\\n if ((browser === Brand.FIREFOX && isFirefox()) ||\\n (browser === Brand.SAFARI && isSafari()) ||\\n (browser === Brand.ANDROID_BROWSER && isAndroidBrowser()) ||\\n (browser === Brand.SILK && isSilk())) {\\n const tuple = versionTuples[2];\\n return tuple && tuple[1] || '';\\n }\\n\\n return '';\\n}\\n\\n/**\\n * Returns the major version of the given browser brand, or NaN if the current\\n * browser is not the given brand.\\n * Note that the major version number may be different depending on which\\n * browser is specified. The returned value can be used to make browser version\\n * comparisons using comparison operators.\\n * @private\\n * @param {!Brand} browser The brand whose version should be returned.\\n * @return {number} The major version number associated with the current\\n * browser under the given brand, or NaN if the current browser doesn't match\\n * the given brand.\\n */\\nfunction versionOf_(browser) {\\n let versionParts;\\n // Silk currently does not identify itself in its userAgentData.brands array,\\n // so if checking its version, always fall back to the user agent string.\\n if (useUserAgentDataBrand() && browser !== Brand.SILK) {\\n const data = util.getUserAgentData();\\n const matchingBrand = data.brands.find(({brand}) => brand === browser);\\n if (!matchingBrand || !matchingBrand.version) {\\n return NaN;\\n }\\n versionParts = matchingBrand.version.split('.');\\n } else {\\n const fullVersion = getFullVersionFromUserAgentString(browser);\\n if (fullVersion === '') {\\n return NaN;\\n }\\n versionParts = fullVersion.split('.');\\n }\\n if (versionParts.length === 0) {\\n return NaN;\\n }\\n const majorVersion = versionParts[0];\\n return Number(majorVersion); // Returns NaN if it is not parseable.\\n}\\n\\n/**\\n * Returns true if the current browser matches the given brand and is at least\\n * the given major version. The major version must be a whole number (i.e.\\n * decimals should not be used to represent a minor version).\\n * @param {!Brand} brand The brand whose version should be returned.\\n * @param {number} majorVersion The major version number to compare against.\\n * This must be a whole number.\\n * @return {boolean} Whether the current browser both matches the given brand\\n * and is at least the given version.\\n */\\nfunction isAtLeast(brand, majorVersion) {\\n assert(\\n Math.floor(majorVersion) === majorVersion,\\n 'Major version must be an integer');\\n return versionOf_(brand) >= majorVersion;\\n}\\nexports.isAtLeast = isAtLeast;\\n\\n/**\\n * Returns true if the current browser matches the given brand and is at most\\n * the given version. The major version must be a whole number (i.e. decimals\\n * should not be used to represent a minor version).\\n * @param {!Brand} brand The brand whose version should be returned.\\n * @param {number} majorVersion The major version number to compare against.\\n * This must be a whole number.\\n * @return {boolean} Whether the current browser both matches the given brand\\n * and is at most the given version.\\n */\\nfunction isAtMost(brand, majorVersion) {\\n assert(\\n Math.floor(majorVersion) === majorVersion,\\n 'Major version must be an integer');\\n return versionOf_(brand) <= majorVersion;\\n}\\nexports.isAtMost = isAtMost;\\n\\n/**\\n * Loads the high-entropy browser brand/version data and wraps the correct\\n * version string in a Version object.\\n * @implements {AsyncValue<!Version>}\\n */\\nclass HighEntropyBrandVersion {\\n /**\\n * @param {string} brand The brand whose version is retrieved in this\\n * container.\\n * @param {boolean} useUach Whether to attempt to use the User-Agent Client\\n * Hints (UACH) API surface.\\n * @param {string} fallbackVersion The fallback version derived from the\\n * userAgent string.\\n */\\n constructor(brand, useUach, fallbackVersion) {\\n /** @private @const {string} */\\n this.brand_ = brand;\\n\\n /** @private @const {!Version} */\\n this.version_ = new Version(fallbackVersion);\\n\\n /** @private @const {boolean} */\\n this.useUach_ = useUach;\\n }\\n\\n /**\\n * @return {!Version|undefined}\\n * @override\\n */\\n getIfLoaded() {\\n if (this.useUach_) {\\n const loadedVersionList = fullVersionList.getIfLoaded();\\n if (loadedVersionList !== undefined) {\\n const matchingBrand =\\n loadedVersionList.find(({brand}) => this.brand_ === brand);\\n // We assumed in fullVersionOf that if the fullVersionList is defined\\n // the brands must match. Double-check this here.\\n assertExists(matchingBrand);\\n return new Version(matchingBrand.version);\\n }\\n // Fallthrough to fallback on Pre-UACH implementation\\n }\\n // We want to make sure the loading semantics of the Pre-UACH implementation\\n // match those of the UACH implementation. Loading must happen before any\\n // data can be retrieved from getIfLoaded.\\n // For HighEntropyBrandVersion, loading can either be done by calling #load\\n // or by calling the module-local loadFullVersions function.\\n if (preUachHasLoaded) {\\n return this.version_;\\n }\\n return;\\n }\\n\\n /**\\n * @return {!Promise<!Version>}\\n * @override\\n */\\n async load() {\\n if (this.useUach_) {\\n const loadedVersionList = await fullVersionList.load();\\n if (loadedVersionList !== undefined) {\\n const matchingBrand =\\n loadedVersionList.find(({brand}) => this.brand_ === brand);\\n assertExists(matchingBrand);\\n return new Version(matchingBrand.version);\\n }\\n // Fallthrough to fallback on Pre-UACH implementation\\n } else {\\n // Await something so that calling load with or without UACH API\\n // availability results in waiting at least one macrotask before allowing\\n // access to the cached version information.\\n await 0;\\n }\\n // Regardless of whether we are using UACH APIs, we can now allow access to\\n // the fallback case\\n preUachHasLoaded = true;\\n return this.version_;\\n }\\n}\\n\\n/**\\n * Whether full version data should be considered available when using UACH\\n * fallback implementations. This is flipped to true when either\\n * loadFullVersions or HighEntropyBrandVersion.prototype.load are called,\\n * matching the global singleton semantics of the UACH codepaths.\\n */\\nlet preUachHasLoaded = false;\\n\\n/**\\n * Requests all full browser versions to be cached. When the returned promise\\n * resolves, subsequent calls to `fullVersionOf(...).getIfLoaded()` will return\\n * a value.\\n *\\n * This method should be avoided in favor of directly awaiting\\n * `fullVersionOf(...).load()` where it is used.\\n *\\n * @return {!Promise<void>}\\n */\\nasync function loadFullVersions() {\\n if (useUserAgentDataBrand(true)) {\\n await fullVersionList.load();\\n }\\n preUachHasLoaded = true;\\n}\\nexports.loadFullVersions = loadFullVersions;\\n\\n/**\\n * Resets module-local caches used by functionality in this module.\\n * This is only for use by goog.labs.userAgent.testUtil.resetUserAgent (and\\n * labs.userAgent tests).\\n * @package\\n */\\nexports.resetForTesting = () => {\\n preUachHasLoaded = false;\\n fullVersionList.resetForTesting();\\n};\\n\\n\\n/**\\n * Returns an object that provides access to the full version string of the\\n * current browser -- or undefined, based on whether the current browser matches\\n * the requested browser brand. Note that the full version string is a\\n * high-entropy value, and must be asynchronously loaded before it can be\\n * accessed synchronously.\\n * @param {!Brand} browser The brand whose version should be returned.\\n * @return {!AsyncValue<!Version>|undefined} An object that can be used\\n * to get or load the full version string as a high-entropy value, or\\n * undefined if the current browser doesn't match the given brand.\\n */\\nfunction fullVersionOf(browser) {\\n let fallbackVersionString = '';\\n // If we are reasonably certain now that the browser we are on has the\\n // fullVersionList high-entropy hint, then we can skip computing the fallback\\n // value as we won't end up using it.\\n if (!hasFullVersionList()) {\\n fallbackVersionString = getFullVersionFromUserAgentString(browser);\\n }\\n // Silk has the UACH API surface, but currently does not identify itself in\\n // the userAgentData.brands array. Fallback to using userAgent string version\\n // for Silk.\\n const useUach = browser !== Brand.SILK && useUserAgentDataBrand(true);\\n if (useUach) {\\n const data = util.getUserAgentData();\\n // Operate under the assumption that the low-entropy and high-entropy lists\\n // of brand/version pairs contain an identical set of brands. Therefore, if\\n // the low-entropy list doesn't contain the given brand, return undefined.\\n if (!data.brands.find(({brand}) => brand === browser)) {\\n return undefined;\\n }\\n } else if (fallbackVersionString === '') {\\n return undefined;\\n }\\n return new HighEntropyBrandVersion(browser, useUach, fallbackVersionString);\\n}\\nexports.fullVersionOf = fullVersionOf;\\n\\n\\n/**\\n * Returns a version string for the current browser or undefined, based on\\n * whether the current browser is the one specified.\\n * This value should ONLY be used for logging/debugging purposes. Do not use it\\n * to branch code paths. For comparing versions, use isAtLeast()/isAtMost() or\\n * fullVersionOf() instead.\\n * @param {!Brand} browser The brand whose version should be returned.\\n * @return {string} The version as a string.\\n */\\nfunction getVersionStringForLogging(browser) {\\n if (useUserAgentDataBrand(true)) {\\n const fullVersionObj = fullVersionOf(browser);\\n if (fullVersionObj) {\\n const fullVersion = fullVersionObj.getIfLoaded();\\n if (fullVersion) {\\n return fullVersion.toVersionStringForLogging();\\n }\\n // No full version, return the major version instead.\\n const data = util.getUserAgentData();\\n const matchingBrand = data.brands.find(({brand}) => brand === browser);\\n // Checking for the existence of matchingBrand is not necessary because\\n // the existence of fullVersionObj implies that there is already a\\n // matching brand.\\n assertExists(matchingBrand);\\n return matchingBrand.version;\\n }\\n // If fullVersionObj is undefined, this doesn't mean that the full version\\n // is unavailable, but rather that the current browser doesn't match the\\n // input `browser` argument.\\n return '';\\n } else {\\n return getFullVersionFromUserAgentString(browser);\\n }\\n}\\nexports.getVersionStringForLogging = getVersionStringForLogging;\\n\"],\n\"names\":[\"goog\",\"module\",\"declareLegacyNamespace\",\"util\",\"require\",\"AsyncValue\",\"Version\",\"assert\",\"assertExists\",\"compareVersions\",\"fullVersionList\",\"useClientHints\",\"Brand\",\"ANDROID_BROWSER\",\"CHROMIUM\",\"EDGE\",\"FIREFOX\",\"IE\",\"OPERA\",\"SAFARI\",\"SILK\",\"exports\",\"useUserAgentDataBrand\",\"ignoreClientHintsFlag\",\"ASSUME_CLIENT_HINTS_SUPPORT\",\"userAgentData\",\"getUserAgentData\",\"brands\",\"length\",\"hasFullVersionList\",\"isAtLeast\",\"matchOpera\",\"matchUserAgent\",\"matchIE\",\"matchEdgeHtml\",\"matchEdgeChromium\",\"matchUserAgentDataBrand\",\"matchOperaChromium\",\"matchFirefox\",\"matchSafari\",\"matchChrome\",\"matchCoast\",\"isSilk\",\"matchIosWebview\",\"matchAndroidBrowser\",\"isChrome\",\"isFirefox\",\"isOpera\",\"isIE\",\"isEdge\",\"isEdgeChromium\",\"isOperaChromium\",\"isSafari\",\"isCoast\",\"isIosWebview\",\"isAndroidBrowser\",\"createVersionMap\",\"versionTuples\",\"versionMap\",\"forEach\",\"tuple\",\"key\",\"value\",\"keys\",\"find\",\"getVersion\",\"userAgentString\",\"getUserAgent\",\"getIEVersion\",\"extractVersionTuples\",\"lookUpValueWithKeys\",\"isVersionOrHigher\",\"version\",\"userAgent\",\"rv\",\"exec\",\"msie\",\"tridentVersion\",\"getFullVersionFromUserAgentString\",\"browser\",\"versionOf_\",\"versionParts\",\"data\",\"matchingBrand\",\"brand\",\"NaN\",\"split\",\"fullVersion\",\"majorVersion\",\"Number\",\"Math\",\"floor\",\"isAtMost\",\"HighEntropyBrandVersion\",\"constructor\",\"useUach\",\"fallbackVersion\",\"brand_\",\"version_\",\"useUach_\",\"getIfLoaded\",\"loadedVersionList\",\"undefined\",\"preUachHasLoaded\",\"load\",\"loadFullVersions\",\"resetForTesting\",\"exports.resetForTesting\",\"fullVersionOf\",\"fallbackVersionString\",\"getVersionStringForLogging\",\"fullVersionObj\",\"toVersionStringForLogging\"]\n}\n"]