tfcconnection-zola/.shadow-cljs/builds/app/dev/goog-js/goog.html.safehtml.js

1 line
106 KiB
JavaScript

["^ ","~:resource-id",["~:shadow.build.classpath/resource","goog/html/safehtml.js"],"~:js","goog.loadModule(function(exports) {\n \"use strict\";\n goog.module(\"goog.html.SafeHtml\");\n goog.module.declareLegacyNamespace();\n const Const = goog.require(\"goog.string.Const\");\n const SafeScript = goog.require(\"goog.html.SafeScript\");\n const SafeStyle = goog.require(\"goog.html.SafeStyle\");\n const SafeStyleSheet = goog.require(\"goog.html.SafeStyleSheet\");\n const SafeUrl = goog.require(\"goog.html.SafeUrl\");\n const TagName = goog.require(\"goog.dom.TagName\");\n const TrustedResourceUrl = goog.require(\"goog.html.TrustedResourceUrl\");\n const TypedString = goog.require(\"goog.string.TypedString\");\n const asserts = goog.require(\"goog.asserts\");\n const browser = goog.require(\"goog.labs.userAgent.browser\");\n const googArray = goog.require(\"goog.array\");\n const googObject = goog.require(\"goog.object\");\n const internal = goog.require(\"goog.string.internal\");\n const tags = goog.require(\"goog.dom.tags\");\n const trustedtypes = goog.require(\"goog.html.trustedtypes\");\n const CONSTRUCTOR_TOKEN_PRIVATE = {};\n class SafeHtml {\n constructor(value, token) {\n this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ = token === CONSTRUCTOR_TOKEN_PRIVATE ? value : \"\";\n this.implementsGoogStringTypedString = true;\n }\n getTypedStringValue() {\n return this.privateDoNotAccessOrElseSafeHtmlWrappedValue_.toString();\n }\n toString() {\n return this.privateDoNotAccessOrElseSafeHtmlWrappedValue_.toString();\n }\n static unwrap(safeHtml) {\n return SafeHtml.unwrapTrustedHTML(safeHtml).toString();\n }\n static unwrapTrustedHTML(safeHtml) {\n if (safeHtml instanceof SafeHtml && safeHtml.constructor === SafeHtml) {\n return safeHtml.privateDoNotAccessOrElseSafeHtmlWrappedValue_;\n } else {\n asserts.fail(`expected object of type SafeHtml, got '${safeHtml}' of type ` + goog.typeOf(safeHtml));\n return \"type_error:SafeHtml\";\n }\n }\n static htmlEscape(textOrHtml) {\n if (textOrHtml instanceof SafeHtml) {\n return textOrHtml;\n }\n const textIsObject = typeof textOrHtml == \"object\";\n let textAsString;\n if (textIsObject && textOrHtml.implementsGoogStringTypedString) {\n textAsString = textOrHtml.getTypedStringValue();\n } else {\n textAsString = String(textOrHtml);\n }\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(internal.htmlEscape(textAsString));\n }\n static htmlEscapePreservingNewlines(textOrHtml) {\n if (textOrHtml instanceof SafeHtml) {\n return textOrHtml;\n }\n const html = SafeHtml.htmlEscape(textOrHtml);\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(internal.newLineToBr(SafeHtml.unwrap(html)));\n }\n static htmlEscapePreservingNewlinesAndSpaces(textOrHtml) {\n if (textOrHtml instanceof SafeHtml) {\n return textOrHtml;\n }\n const html = SafeHtml.htmlEscape(textOrHtml);\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(internal.whitespaceEscape(SafeHtml.unwrap(html)));\n }\n static comment(text) {\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\"\\x3c!--\" + internal.htmlEscape(text) + \"--\\x3e\");\n }\n static create(tagName, attributes = undefined, content = undefined) {\n SafeHtml.verifyTagName(String(tagName));\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(String(tagName), attributes, content);\n }\n static verifyTagName(tagName) {\n if (!VALID_NAMES_IN_TAG.test(tagName)) {\n throw new Error(SafeHtml.ENABLE_ERROR_MESSAGES ? `Invalid tag name <${tagName}>.` : \"\");\n }\n if (tagName.toUpperCase() in NOT_ALLOWED_TAG_NAMES) {\n throw new Error(SafeHtml.ENABLE_ERROR_MESSAGES ? `Tag name <${tagName}> is not allowed for SafeHtml.` : \"\");\n }\n }\n static createIframe(src = undefined, srcdoc = undefined, attributes = undefined, content = undefined) {\n if (src) {\n TrustedResourceUrl.unwrap(src);\n }\n const fixedAttributes = {};\n fixedAttributes[\"src\"] = src || null;\n fixedAttributes[\"srcdoc\"] = srcdoc && SafeHtml.unwrap(srcdoc);\n const defaultAttributes = {\"sandbox\":\"\"};\n const combinedAttrs = SafeHtml.combineAttributes(fixedAttributes, defaultAttributes, attributes);\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\"iframe\", combinedAttrs, content);\n }\n static createSandboxIframe(src = undefined, srcdoc = undefined, attributes = undefined, content = undefined) {\n if (!SafeHtml.canUseSandboxIframe()) {\n throw new Error(SafeHtml.ENABLE_ERROR_MESSAGES ? \"The browser does not support sandboxed iframes.\" : \"\");\n }\n const fixedAttributes = {};\n if (src) {\n fixedAttributes[\"src\"] = SafeUrl.unwrap(SafeUrl.sanitize(src));\n } else {\n fixedAttributes[\"src\"] = null;\n }\n fixedAttributes[\"srcdoc\"] = srcdoc || null;\n fixedAttributes[\"sandbox\"] = \"\";\n const combinedAttrs = SafeHtml.combineAttributes(fixedAttributes, {}, attributes);\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\"iframe\", combinedAttrs, content);\n }\n static canUseSandboxIframe() {\n return goog.global[\"HTMLIFrameElement\"] && \"sandbox\" in goog.global[\"HTMLIFrameElement\"].prototype;\n }\n static createScriptSrc(src, attributes = undefined) {\n TrustedResourceUrl.unwrap(src);\n const fixedAttributes = {\"src\":src};\n const defaultAttributes = {};\n const combinedAttrs = SafeHtml.combineAttributes(fixedAttributes, defaultAttributes, attributes);\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\"script\", combinedAttrs);\n }\n static createScript(script, attributes = undefined) {\n for (let attr in attributes) {\n if (Object.prototype.hasOwnProperty.call(attributes, attr)) {\n const attrLower = attr.toLowerCase();\n if (attrLower == \"language\" || attrLower == \"src\" || attrLower == \"text\") {\n throw new Error(SafeHtml.ENABLE_ERROR_MESSAGES ? `Cannot set \"${attrLower}\" attribute` : \"\");\n }\n }\n }\n let content = \"\";\n script = googArray.concat(script);\n for (let i = 0; i < script.length; i++) {\n content += SafeScript.unwrap(script[i]);\n }\n const htmlContent = SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(content);\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\"script\", attributes, htmlContent);\n }\n static createStyle(styleSheet, attributes = undefined) {\n const fixedAttributes = {\"type\":\"text/css\"};\n const defaultAttributes = {};\n const combinedAttrs = SafeHtml.combineAttributes(fixedAttributes, defaultAttributes, attributes);\n let content = \"\";\n styleSheet = googArray.concat(styleSheet);\n for (let i = 0; i < styleSheet.length; i++) {\n content += SafeStyleSheet.unwrap(styleSheet[i]);\n }\n const htmlContent = SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(content);\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\"style\", combinedAttrs, htmlContent);\n }\n static createMetaRefresh(url, secs = undefined) {\n let unwrappedUrl = SafeUrl.unwrap(SafeUrl.sanitize(url));\n if (browser.isIE() || browser.isEdge()) {\n if (internal.contains(unwrappedUrl, \";\")) {\n unwrappedUrl = \"'\" + unwrappedUrl.replace(/'/g, \"%27\") + \"'\";\n }\n }\n const attributes = {\"http-equiv\":\"refresh\", \"content\":(secs || 0) + \"; url\\x3d\" + unwrappedUrl,};\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\"meta\", attributes);\n }\n static join(separator, parts) {\n const separatorHtml = SafeHtml.htmlEscape(separator);\n const content = [];\n const addArgument = argument => {\n if (Array.isArray(argument)) {\n argument.forEach(addArgument);\n } else {\n const html = SafeHtml.htmlEscape(argument);\n content.push(SafeHtml.unwrap(html));\n }\n };\n parts.forEach(addArgument);\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(content.join(SafeHtml.unwrap(separatorHtml)));\n }\n static concat(var_args) {\n return SafeHtml.join(SafeHtml.EMPTY, Array.prototype.slice.call(arguments));\n }\n static createSafeHtmlSecurityPrivateDoNotAccessOrElse(html) {\n const noinlineHtml = html;\n const policy = trustedtypes.getPolicyPrivateDoNotAccessOrElse();\n const trustedHtml = policy ? policy.createHTML(noinlineHtml) : noinlineHtml;\n return new SafeHtml(trustedHtml, CONSTRUCTOR_TOKEN_PRIVATE);\n }\n static createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(tagName, attributes = undefined, content = undefined) {\n let result = `<${tagName}`;\n result += SafeHtml.stringifyAttributes(tagName, attributes);\n if (content == null) {\n content = [];\n } else if (!Array.isArray(content)) {\n content = [content];\n }\n if (tags.isVoidTag(tagName.toLowerCase())) {\n asserts.assert(!content.length, `Void tag <${tagName}> does not allow content.`);\n result += \"\\x3e\";\n } else {\n const html = SafeHtml.concat(content);\n result += \"\\x3e\" + SafeHtml.unwrap(html) + \"\\x3c/\" + tagName + \"\\x3e\";\n }\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(result);\n }\n static stringifyAttributes(tagName, attributes = undefined) {\n let result = \"\";\n if (attributes) {\n for (let name in attributes) {\n if (Object.prototype.hasOwnProperty.call(attributes, name)) {\n if (!VALID_NAMES_IN_TAG.test(name)) {\n throw new Error(SafeHtml.ENABLE_ERROR_MESSAGES ? `Invalid attribute name \"${name}\".` : \"\");\n }\n const value = attributes[name];\n if (value == null) {\n continue;\n }\n result += \" \" + getAttrNameAndValue(tagName, name, value);\n }\n }\n }\n return result;\n }\n static combineAttributes(fixedAttributes, defaultAttributes, attributes = undefined) {\n const combinedAttributes = {};\n for (const name in fixedAttributes) {\n if (Object.prototype.hasOwnProperty.call(fixedAttributes, name)) {\n asserts.assert(name.toLowerCase() == name, \"Must be lower case\");\n combinedAttributes[name] = fixedAttributes[name];\n }\n }\n for (const name in defaultAttributes) {\n if (Object.prototype.hasOwnProperty.call(defaultAttributes, name)) {\n asserts.assert(name.toLowerCase() == name, \"Must be lower case\");\n combinedAttributes[name] = defaultAttributes[name];\n }\n }\n if (attributes) {\n for (const name in attributes) {\n if (Object.prototype.hasOwnProperty.call(attributes, name)) {\n const nameLower = name.toLowerCase();\n if (nameLower in fixedAttributes) {\n throw new Error(SafeHtml.ENABLE_ERROR_MESSAGES ? `Cannot override \"${nameLower}\" attribute, got \"` + name + '\" with value \"' + attributes[name] + '\"' : \"\");\n }\n if (nameLower in defaultAttributes) {\n delete combinedAttributes[nameLower];\n }\n combinedAttributes[name] = attributes[name];\n }\n }\n }\n return combinedAttributes;\n }\n }\n SafeHtml.ENABLE_ERROR_MESSAGES = goog.define(\"goog.html.SafeHtml.ENABLE_ERROR_MESSAGES\", goog.DEBUG);\n SafeHtml.SUPPORT_STYLE_ATTRIBUTE = goog.define(\"goog.html.SafeHtml.SUPPORT_STYLE_ATTRIBUTE\", true);\n SafeHtml.TextOrHtml_;\n SafeHtml.from = SafeHtml.htmlEscape;\n const VALID_NAMES_IN_TAG = /^[a-zA-Z0-9-]+$/;\n const URL_ATTRIBUTES = googObject.createSet(\"action\", \"cite\", \"data\", \"formaction\", \"href\", \"manifest\", \"poster\", \"src\");\n const NOT_ALLOWED_TAG_NAMES = googObject.createSet(TagName.APPLET, TagName.BASE, TagName.EMBED, TagName.IFRAME, TagName.LINK, TagName.MATH, TagName.META, TagName.OBJECT, TagName.SCRIPT, TagName.STYLE, TagName.SVG, TagName.TEMPLATE);\n SafeHtml.AttributeValue;\n function getAttrNameAndValue(tagName, name, value) {\n if (value instanceof Const) {\n value = Const.unwrap(value);\n } else if (name.toLowerCase() == \"style\") {\n if (SafeHtml.SUPPORT_STYLE_ATTRIBUTE) {\n value = getStyleValue(value);\n } else {\n throw new Error(SafeHtml.ENABLE_ERROR_MESSAGES ? 'Attribute \"style\" not supported.' : \"\");\n }\n } else if (/^on/i.test(name)) {\n throw new Error(SafeHtml.ENABLE_ERROR_MESSAGES ? `Attribute \"${name}` + '\" requires goog.string.Const value, \"' + value + '\" given.' : \"\");\n } else if (name.toLowerCase() in URL_ATTRIBUTES) {\n if (value instanceof TrustedResourceUrl) {\n value = TrustedResourceUrl.unwrap(value);\n } else if (value instanceof SafeUrl) {\n value = SafeUrl.unwrap(value);\n } else if (typeof value === \"string\") {\n value = SafeUrl.sanitize(value).getTypedStringValue();\n } else {\n throw new Error(SafeHtml.ENABLE_ERROR_MESSAGES ? `Attribute \"${name}\" on tag \"${tagName}` + '\" requires goog.html.SafeUrl, goog.string.Const, or' + ' string, value \"' + value + '\" given.' : \"\");\n }\n }\n if (value.implementsGoogStringTypedString) {\n value = value.getTypedStringValue();\n }\n asserts.assert(typeof value === \"string\" || typeof value === \"number\", \"String or number value expected, got \" + typeof value + \" with value: \" + value);\n return `${name}=\"` + internal.htmlEscape(String(value)) + '\"';\n }\n function getStyleValue(value) {\n if (!goog.isObject(value)) {\n throw new Error(SafeHtml.ENABLE_ERROR_MESSAGES ? 'The \"style\" attribute requires goog.html.SafeStyle or map ' + \"of style properties, \" + typeof value + \" given: \" + value : \"\");\n }\n if (!(value instanceof SafeStyle)) {\n value = SafeStyle.create(value);\n }\n return SafeStyle.unwrap(value);\n }\n SafeHtml.DOCTYPE_HTML = {valueOf:function() {\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\"\\x3c!DOCTYPE html\\x3e\");\n },}.valueOf();\n SafeHtml.EMPTY = new SafeHtml(goog.global.trustedTypes && goog.global.trustedTypes.emptyHTML || \"\", CONSTRUCTOR_TOKEN_PRIVATE);\n SafeHtml.BR = {valueOf:function() {\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\"\\x3cbr\\x3e\");\n },}.valueOf();\n exports = SafeHtml;\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/**\n * @fileoverview The SafeHtml type and its builders.\n *\n * TODO(xtof): Link to document stating type contract.\n */\n\ngoog.module('goog.html.SafeHtml');\ngoog.module.declareLegacyNamespace();\n\nconst Const = goog.require('goog.string.Const');\nconst SafeScript = goog.require('goog.html.SafeScript');\nconst SafeStyle = goog.require('goog.html.SafeStyle');\nconst SafeStyleSheet = goog.require('goog.html.SafeStyleSheet');\nconst SafeUrl = goog.require('goog.html.SafeUrl');\nconst TagName = goog.require('goog.dom.TagName');\nconst TrustedResourceUrl = goog.require('goog.html.TrustedResourceUrl');\nconst TypedString = goog.require('goog.string.TypedString');\nconst asserts = goog.require('goog.asserts');\nconst browser = goog.require('goog.labs.userAgent.browser');\nconst googArray = goog.require('goog.array');\nconst googObject = goog.require('goog.object');\nconst internal = goog.require('goog.string.internal');\nconst tags = goog.require('goog.dom.tags');\nconst trustedtypes = goog.require('goog.html.trustedtypes');\n\n\n/**\n * Token used to ensure that object is created only from this file. No code\n * outside of this file can access this token.\n * @type {!Object}\n * @const\n */\nconst CONSTRUCTOR_TOKEN_PRIVATE = {};\n\n/**\n * A string that is safe to use in HTML context in DOM APIs and HTML documents.\n *\n * A SafeHtml is a string-like object that carries the security type contract\n * that its value as a string will not cause untrusted script execution when\n * evaluated as HTML in a browser.\n *\n * Values of this type are guaranteed to be safe to use in HTML contexts,\n * such as, assignment to the innerHTML DOM property, or interpolation into\n * a HTML template in HTML PC_DATA context, in the sense that the use will not\n * result in a Cross-Site-Scripting vulnerability.\n *\n * Instances of this type must be created via the factory methods\n * (`SafeHtml.create`, `SafeHtml.htmlEscape`),\n * etc and not by invoking its constructor. The constructor intentionally takes\n * an extra parameter that cannot be constructed outside of this file and the\n * type is immutable; hence only a default instance corresponding to the empty\n * string can be obtained via constructor invocation.\n *\n * Creating SafeHtml objects HAS SIDE-EFFECTS due to calling Trusted Types Web\n * API.\n *\n * Note that there is no `SafeHtml.fromConstant`. The reason is that\n * the following code would create an unsafe HTML:\n *\n * ```\n * SafeHtml.concat(\n * SafeHtml.fromConstant(Const.from('<script>')),\n * SafeHtml.htmlEscape(userInput),\n * SafeHtml.fromConstant(Const.from('<\\/script>')));\n * ```\n *\n * There's `goog.dom.constHtmlToNode` to create a node from constant strings\n * only.\n *\n * @see SafeHtml.create\n * @see SafeHtml.htmlEscape\n * @final\n * @struct\n * @implements {TypedString}\n */\nclass SafeHtml {\n /**\n * @param {!TrustedHTML|string} value\n * @param {!Object} token package-internal implementation detail.\n */\n constructor(value, token) {\n /**\n * The contained value of this SafeHtml. The field has a purposely ugly\n * name to make (non-compiled) code that attempts to directly access this\n * field stand out.\n * @private {!TrustedHTML|string}\n */\n this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ =\n (token === CONSTRUCTOR_TOKEN_PRIVATE) ? value : '';\n\n /**\n * @override\n * @const {boolean}\n */\n this.implementsGoogStringTypedString = true;\n }\n\n\n /**\n * Returns this SafeHtml's value as string.\n *\n * IMPORTANT: In code where it is security relevant that an object's type is\n * indeed `SafeHtml`, use `SafeHtml.unwrap` instead of\n * this method. If in doubt, assume that it's security relevant. In\n * particular, note that goog.html functions which return a goog.html type do\n * not guarantee that the returned instance is of the right type. For example:\n *\n * <pre>\n * var fakeSafeHtml = new String('fake');\n * fakeSafeHtml.__proto__ = SafeHtml.prototype;\n * var newSafeHtml = SafeHtml.htmlEscape(fakeSafeHtml);\n * // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by\n * // SafeHtml.htmlEscape() as fakeSafeHtml\n * // instanceof SafeHtml.\n * </pre>\n *\n * @return {string}\n * @see SafeHtml.unwrap\n * @override\n */\n getTypedStringValue() {\n return this.privateDoNotAccessOrElseSafeHtmlWrappedValue_.toString();\n }\n\n\n /**\n * Returns a string-representation of this value.\n *\n * To obtain the actual string value wrapped in a SafeHtml, use\n * `SafeHtml.unwrap`.\n *\n * @return {string}\n * @see SafeHtml.unwrap\n * @override\n */\n toString() {\n return this.privateDoNotAccessOrElseSafeHtmlWrappedValue_.toString();\n }\n\n /**\n * Performs a runtime check that the provided object is indeed a SafeHtml\n * object, and returns its value.\n * @param {!SafeHtml} safeHtml The object to extract from.\n * @return {string} The SafeHtml object's contained string, unless the\n * run-time type check fails. In that case, `unwrap` returns an innocuous\n * string, or, if assertions are enabled, throws\n * `asserts.AssertionError`.\n */\n static unwrap(safeHtml) {\n return SafeHtml.unwrapTrustedHTML(safeHtml).toString();\n }\n\n\n /**\n * Unwraps value as TrustedHTML if supported or as a string if not.\n * @param {!SafeHtml} safeHtml\n * @return {!TrustedHTML|string}\n * @see SafeHtml.unwrap\n */\n static unwrapTrustedHTML(safeHtml) {\n // Perform additional run-time type-checking to ensure that safeHtml is\n // indeed an instance of the expected type. This provides some additional\n // protection against security bugs due to application code that disables\n // type checks. Specifically, the following checks are performed:\n // 1. The object is an instance of the expected type.\n // 2. The object is not an instance of a subclass.\n if (safeHtml instanceof SafeHtml && safeHtml.constructor === SafeHtml) {\n return safeHtml.privateDoNotAccessOrElseSafeHtmlWrappedValue_;\n } else {\n asserts.fail(\n `expected object of type SafeHtml, got '${safeHtml}' of type ` +\n goog.typeOf(safeHtml));\n return 'type_error:SafeHtml';\n }\n }\n\n /**\n * Returns HTML-escaped text as a SafeHtml object.\n *\n * @param {!SafeHtml.TextOrHtml_} textOrHtml The text to escape. If\n * the parameter is of type SafeHtml it is returned directly (no escaping\n * is done).\n * @return {!SafeHtml} The escaped text, wrapped as a SafeHtml.\n */\n static htmlEscape(textOrHtml) {\n if (textOrHtml instanceof SafeHtml) {\n return textOrHtml;\n }\n const textIsObject = typeof textOrHtml == 'object';\n let textAsString;\n if (textIsObject &&\n /** @type {?} */ (textOrHtml).implementsGoogStringTypedString) {\n textAsString =\n /** @type {!TypedString} */ (textOrHtml).getTypedStringValue();\n } else {\n textAsString = String(textOrHtml);\n }\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\n internal.htmlEscape(textAsString));\n }\n\n\n /**\n * Returns HTML-escaped text as a SafeHtml object, with newlines changed to\n * &lt;br&gt;.\n * @param {!SafeHtml.TextOrHtml_} textOrHtml The text to escape. If\n * the parameter is of type SafeHtml it is returned directly (no escaping\n * is done).\n * @return {!SafeHtml} The escaped text, wrapped as a SafeHtml.\n */\n static htmlEscapePreservingNewlines(textOrHtml) {\n if (textOrHtml instanceof SafeHtml) {\n return textOrHtml;\n }\n const html = SafeHtml.htmlEscape(textOrHtml);\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\n internal.newLineToBr(SafeHtml.unwrap(html)));\n }\n\n\n /**\n * Returns HTML-escaped text as a SafeHtml object, with newlines changed to\n * &lt;br&gt; and escaping whitespace to preserve spatial formatting.\n * Character entity #160 is used to make it safer for XML.\n * @param {!SafeHtml.TextOrHtml_} textOrHtml The text to escape. If\n * the parameter is of type SafeHtml it is returned directly (no escaping\n * is done).\n * @return {!SafeHtml} The escaped text, wrapped as a SafeHtml.\n */\n static htmlEscapePreservingNewlinesAndSpaces(textOrHtml) {\n if (textOrHtml instanceof SafeHtml) {\n return textOrHtml;\n }\n const html = SafeHtml.htmlEscape(textOrHtml);\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\n internal.whitespaceEscape(SafeHtml.unwrap(html)));\n }\n\n /**\n * Converts an arbitrary string into an HTML comment by HTML-escaping the\n * contents and embedding the result between HTML comment markers.\n *\n * Escaping is needed because Internet Explorer supports conditional comments\n * and so may render HTML markup within comments.\n *\n * @param {string} text\n * @return {!SafeHtml}\n */\n static comment(text) {\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\n '<!--' + internal.htmlEscape(text) + '-->');\n }\n\n /**\n * Creates a SafeHtml content consisting of a tag with optional attributes and\n * optional content.\n *\n * For convenience tag names and attribute names are accepted as regular\n * strings, instead of Const. Nevertheless, you should not pass\n * user-controlled values to these parameters. Note that these parameters are\n * syntactically validated at runtime, and invalid values will result in\n * an exception.\n *\n * Example usage:\n *\n * SafeHtml.create('br');\n * SafeHtml.create('div', {'class': 'a'});\n * SafeHtml.create('p', {}, 'a');\n * SafeHtml.create('p', {}, SafeHtml.create('br'));\n *\n * SafeHtml.create('span', {\n * 'style': {'margin': '0'}\n * });\n *\n * To guarantee SafeHtml's type contract is upheld there are restrictions on\n * attribute values and tag names.\n *\n * - For attributes which contain script code (on*), a Const is\n * required.\n * - For attributes which contain style (style), a SafeStyle or a\n * SafeStyle.PropertyMap is required.\n * - For attributes which are interpreted as URLs (e.g. src, href) a\n * SafeUrl, Const or string is required. If a string\n * is passed, it will be sanitized with SafeUrl.sanitize().\n * - For tags which can load code or set security relevant page metadata,\n * more specific SafeHtml.create*() functions must be used. Tags\n * which are not supported by this function are applet, base, embed, iframe,\n * link, math, meta, object, script, style, svg, and template.\n *\n * @param {!TagName|string} tagName The name of the tag. Only tag names\n * consisting of [a-zA-Z0-9-] are allowed. Tag names documented above are\n * disallowed.\n * @param {?Object<string, ?SafeHtml.AttributeValue>=} attributes Mapping\n * from attribute names to their values. Only attribute names consisting\n * of [a-zA-Z0-9-] are allowed. Value of null or undefined causes the\n * attribute to be omitted.\n * @param {!SafeHtml.TextOrHtml_|\n * !Array<!SafeHtml.TextOrHtml_>=} content Content to HTML-escape and put\n * inside the tag. This must be empty for void tags like <br>. Array elements\n * are concatenated.\n * @return {!SafeHtml} The SafeHtml content with the tag.\n * @throws {!Error} If invalid tag name, attribute name, or attribute value is\n * provided.\n * @throws {!asserts.AssertionError} If content for void tag is provided.\n * @deprecated Use a recommended templating system like Lit instead.\n * More information: go/goog.html-readme // LINE-INTERNAL\n */\n static create(tagName, attributes = undefined, content = undefined) {\n SafeHtml.verifyTagName(String(tagName));\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\n String(tagName), attributes, content);\n }\n\n\n /**\n * Verifies if the tag name is valid and if it doesn't change the context.\n * E.g. STRONG is fine but SCRIPT throws because it changes context. See\n * SafeHtml.create for an explanation of allowed tags.\n * @param {string} tagName\n * @return {void}\n * @throws {!Error} If invalid tag name is provided.\n * @package\n */\n static verifyTagName(tagName) {\n if (!VALID_NAMES_IN_TAG.test(tagName)) {\n throw new Error(\n SafeHtml.ENABLE_ERROR_MESSAGES ? `Invalid tag name <${tagName}>.` :\n '');\n }\n if (tagName.toUpperCase() in NOT_ALLOWED_TAG_NAMES) {\n throw new Error(\n SafeHtml.ENABLE_ERROR_MESSAGES ?\n\n `Tag name <${tagName}> is not allowed for SafeHtml.` :\n '');\n }\n }\n\n\n /**\n * Creates a SafeHtml representing an iframe tag.\n *\n * This by default restricts the iframe as much as possible by setting the\n * sandbox attribute to the empty string. If the iframe requires less\n * restrictions, set the sandbox attribute as tight as possible, but do not\n * rely on the sandbox as a security feature because it is not supported by\n * older browsers. If a sandbox is essential to security (e.g. for third-party\n * frames), use createSandboxIframe which checks for browser support.\n *\n * @see https://developer.mozilla.org/en/docs/Web/HTML/Element/iframe#attr-sandbox\n *\n * @param {?TrustedResourceUrl=} src The value of the src\n * attribute. If null or undefined src will not be set.\n * @param {?SafeHtml=} srcdoc The value of the srcdoc attribute.\n * If null or undefined srcdoc will not be set.\n * @param {?Object<string, ?SafeHtml.AttributeValue>=} attributes Mapping\n * from attribute names to their values. Only attribute names consisting\n * of [a-zA-Z0-9-] are allowed. Value of null or undefined causes the\n * attribute to be omitted.\n * @param {!SafeHtml.TextOrHtml_|\n * !Array<!SafeHtml.TextOrHtml_>=} content Content to HTML-escape and put\n * inside the tag. Array elements are concatenated.\n * @return {!SafeHtml} The SafeHtml content with the tag.\n * @throws {!Error} If invalid tag name, attribute name, or attribute value is\n * provided. If attributes\n * contains the src or srcdoc attributes.\n */\n static createIframe(\n src = undefined, srcdoc = undefined, attributes = undefined,\n content = undefined) {\n if (src) {\n // Check whether this is really TrustedResourceUrl.\n TrustedResourceUrl.unwrap(src);\n }\n\n const fixedAttributes = {};\n fixedAttributes['src'] = src || null;\n fixedAttributes['srcdoc'] = srcdoc && SafeHtml.unwrap(srcdoc);\n const defaultAttributes = {'sandbox': ''};\n const combinedAttrs = SafeHtml.combineAttributes(\n fixedAttributes, defaultAttributes, attributes);\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\n 'iframe', combinedAttrs, content);\n }\n\n\n /**\n * Creates a SafeHtml representing a sandboxed iframe tag.\n *\n * The sandbox attribute is enforced in its most restrictive mode, an empty\n * string. Consequently, the security requirements for the src and srcdoc\n * attributes are relaxed compared to SafeHtml.createIframe. This function\n * will throw on browsers that do not support the sandbox attribute, as\n * determined by SafeHtml.canUseSandboxIframe.\n *\n * The SafeHtml returned by this function can trigger downloads with no\n * user interaction on Chrome (though only a few, further attempts are\n * blocked). Firefox and IE will block all downloads from the sandbox.\n *\n * @see https://developer.mozilla.org/en/docs/Web/HTML/Element/iframe#attr-sandbox\n * @see https://lists.w3.org/Archives/Public/public-whatwg-archive/2013Feb/0112.html\n *\n * @param {string|!SafeUrl=} src The value of the src\n * attribute. If null or undefined src will not be set.\n * @param {string=} srcdoc The value of the srcdoc attribute.\n * If null or undefined srcdoc will not be set. Will not be sanitized.\n * @param {!Object<string, ?SafeHtml.AttributeValue>=} attributes Mapping\n * from attribute names to their values. Only attribute names consisting\n * of [a-zA-Z0-9-] are allowed. Value of null or undefined causes the\n * attribute to be omitted.\n * @param {!SafeHtml.TextOrHtml_|\n * !Array<!SafeHtml.TextOrHtml_>=} content Content to HTML-escape and put\n * inside the tag. Array elements are concatenated.\n * @return {!SafeHtml} The SafeHtml content with the tag.\n * @throws {!Error} If invalid tag name, attribute name, or attribute value is\n * provided. If attributes\n * contains the src, srcdoc or sandbox attributes. If browser does not support\n * the sandbox attribute on iframe.\n */\n static createSandboxIframe(\n src = undefined, srcdoc = undefined, attributes = undefined,\n content = undefined) {\n if (!SafeHtml.canUseSandboxIframe()) {\n throw new Error(\n SafeHtml.ENABLE_ERROR_MESSAGES ?\n 'The browser does not support sandboxed iframes.' :\n '');\n }\n\n const fixedAttributes = {};\n if (src) {\n // Note that sanitize is a no-op on SafeUrl.\n fixedAttributes['src'] = SafeUrl.unwrap(SafeUrl.sanitize(src));\n } else {\n fixedAttributes['src'] = null;\n }\n fixedAttributes['srcdoc'] = srcdoc || null;\n fixedAttributes['sandbox'] = '';\n const combinedAttrs =\n SafeHtml.combineAttributes(fixedAttributes, {}, attributes);\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\n 'iframe', combinedAttrs, content);\n }\n\n\n /**\n * Checks if the user agent supports sandboxed iframes.\n * @return {boolean}\n */\n static canUseSandboxIframe() {\n return goog.global['HTMLIFrameElement'] &&\n ('sandbox' in goog.global['HTMLIFrameElement'].prototype);\n }\n\n\n /**\n * Creates a SafeHtml representing a script tag with the src attribute.\n * @param {!TrustedResourceUrl} src The value of the src\n * attribute.\n * @param {?Object<string, ?SafeHtml.AttributeValue>=}\n * attributes\n * Mapping from attribute names to their values. Only attribute names\n * consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined\n * causes the attribute to be omitted.\n * @return {!SafeHtml} The SafeHtml content with the tag.\n * @throws {!Error} If invalid attribute name or value is provided. If\n * attributes contains the\n * src attribute.\n */\n static createScriptSrc(src, attributes = undefined) {\n // TODO(mlourenco): The charset attribute should probably be blocked. If\n // its value is attacker controlled, the script contains attacker controlled\n // sub-strings (even if properly escaped) and the server does not set\n // charset then XSS is likely possible.\n // https://html.spec.whatwg.org/multipage/scripting.html#dom-script-charset\n\n // Check whether this is really TrustedResourceUrl.\n TrustedResourceUrl.unwrap(src);\n\n const fixedAttributes = {'src': src};\n const defaultAttributes = {};\n const combinedAttrs = SafeHtml.combineAttributes(\n fixedAttributes, defaultAttributes, attributes);\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\n 'script', combinedAttrs);\n }\n\n /**\n * Creates a SafeHtml representing a script tag. Does not allow the language,\n * src, text or type attributes to be set.\n * @param {!SafeScript|!Array<!SafeScript>}\n * script Content to put inside the tag. Array elements are\n * concatenated.\n * @param {?Object<string, ?SafeHtml.AttributeValue>=} attributes Mapping\n * from attribute names to their values. Only attribute names consisting\n * of [a-zA-Z0-9-] are allowed. Value of null or undefined causes the\n * attribute to be omitted.\n * @return {!SafeHtml} The SafeHtml content with the tag.\n * @throws {!Error} If invalid attribute name or attribute value is provided.\n * If attributes contains the\n * language, src or text attribute.\n */\n static createScript(script, attributes = undefined) {\n for (let attr in attributes) {\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty#Using_hasOwnProperty_as_a_property_name\n if (Object.prototype.hasOwnProperty.call(attributes, attr)) {\n const attrLower = attr.toLowerCase();\n if (attrLower == 'language' || attrLower == 'src' ||\n attrLower == 'text') {\n throw new Error(\n SafeHtml.ENABLE_ERROR_MESSAGES ?\n `Cannot set \"${attrLower}\" attribute` :\n '');\n }\n }\n }\n\n let content = '';\n script = googArray.concat(script);\n for (let i = 0; i < script.length; i++) {\n content += SafeScript.unwrap(script[i]);\n }\n // Convert to SafeHtml so that it's not HTML-escaped. This is safe because\n // as part of its contract, SafeScript should have no dangerous '<'.\n const htmlContent =\n SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(content);\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\n 'script', attributes, htmlContent);\n }\n\n\n /**\n * Creates a SafeHtml representing a style tag. The type attribute is set\n * to \"text/css\".\n * @param {!SafeStyleSheet|!Array<!SafeStyleSheet>}\n * styleSheet Content to put inside the tag. Array elements are\n * concatenated.\n * @param {?Object<string, ?SafeHtml.AttributeValue>=} attributes Mapping\n * from attribute names to their values. Only attribute names consisting\n * of [a-zA-Z0-9-] are allowed. Value of null or undefined causes the\n * attribute to be omitted.\n * @return {!SafeHtml} The SafeHtml content with the tag.\n * @throws {!Error} If invalid attribute name or attribute value is provided.\n * If attributes contains the\n * type attribute.\n */\n static createStyle(styleSheet, attributes = undefined) {\n const fixedAttributes = {'type': 'text/css'};\n const defaultAttributes = {};\n const combinedAttrs = SafeHtml.combineAttributes(\n fixedAttributes, defaultAttributes, attributes);\n\n let content = '';\n styleSheet = googArray.concat(styleSheet);\n for (let i = 0; i < styleSheet.length; i++) {\n content += SafeStyleSheet.unwrap(styleSheet[i]);\n }\n // Convert to SafeHtml so that it's not HTML-escaped. This is safe because\n // as part of its contract, SafeStyleSheet should have no dangerous '<'.\n const htmlContent =\n SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(content);\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\n 'style', combinedAttrs, htmlContent);\n }\n\n\n /**\n * Creates a SafeHtml representing a meta refresh tag.\n * @param {!SafeUrl|string} url Where to redirect. If a string is\n * passed, it will be sanitized with SafeUrl.sanitize().\n * @param {number=} secs Number of seconds until the page should be\n * reloaded. Will be set to 0 if unspecified.\n * @return {!SafeHtml} The SafeHtml content with the tag.\n */\n static createMetaRefresh(url, secs = undefined) {\n // Note that sanitize is a no-op on SafeUrl.\n let unwrappedUrl = SafeUrl.unwrap(SafeUrl.sanitize(url));\n\n if (browser.isIE() || browser.isEdge()) {\n // IE/EDGE can't parse the content attribute if the url contains a\n // semicolon. We can fix this by adding quotes around the url, but then we\n // can't parse quotes in the URL correctly. Also, it seems that IE/EDGE\n // did not unescape semicolons in these URLs at some point in the past. We\n // take a best-effort approach.\n //\n // If the URL has semicolons (which may happen in some cases, see\n // http://www.w3.org/TR/1999/REC-html401-19991224/appendix/notes.html#h-B.2\n // for instance), wrap it in single quotes to protect the semicolons.\n // If the URL has semicolons and single quotes, url-encode the single\n // quotes as well.\n //\n // This is imperfect. Notice that both ' and ; are reserved characters in\n // URIs, so this could do the wrong thing, but at least it will do the\n // wrong thing in only rare cases.\n if (internal.contains(unwrappedUrl, ';')) {\n unwrappedUrl = '\\'' + unwrappedUrl.replace(/'/g, '%27') + '\\'';\n }\n }\n const attributes = {\n 'http-equiv': 'refresh',\n 'content': (secs || 0) + '; url=' + unwrappedUrl,\n };\n\n // This function will handle the HTML escaping for attributes.\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\n 'meta', attributes);\n }\n\n /**\n * Creates a new SafeHtml object by joining the parts with separator.\n * @param {!SafeHtml.TextOrHtml_} separator\n * @param {!Array<!SafeHtml.TextOrHtml_|\n * !Array<!SafeHtml.TextOrHtml_>>} parts Parts to join. If a part\n * contains an array then each member of this array is also joined with\n * the separator.\n * @return {!SafeHtml}\n */\n static join(separator, parts) {\n const separatorHtml = SafeHtml.htmlEscape(separator);\n const content = [];\n\n /**\n * @param {!SafeHtml.TextOrHtml_|\n * !Array<!SafeHtml.TextOrHtml_>} argument\n */\n const addArgument = (argument) => {\n if (Array.isArray(argument)) {\n argument.forEach(addArgument);\n } else {\n const html = SafeHtml.htmlEscape(argument);\n content.push(SafeHtml.unwrap(html));\n }\n };\n\n parts.forEach(addArgument);\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\n content.join(SafeHtml.unwrap(separatorHtml)));\n }\n\n\n /**\n * Creates a new SafeHtml object by concatenating values.\n * @param {...(!SafeHtml.TextOrHtml_|\n * !Array<!SafeHtml.TextOrHtml_>)} var_args Values to concatenate.\n * @return {!SafeHtml}\n */\n static concat(var_args) {\n return SafeHtml.join(SafeHtml.EMPTY, Array.prototype.slice.call(arguments));\n }\n\n /**\n * Package-internal utility method to create SafeHtml instances.\n *\n * @param {string} html The string to initialize the SafeHtml object with.\n * @return {!SafeHtml} The initialized SafeHtml object.\n * @package\n */\n static createSafeHtmlSecurityPrivateDoNotAccessOrElse(html) {\n /** @noinline */\n const noinlineHtml = html;\n const policy = trustedtypes.getPolicyPrivateDoNotAccessOrElse();\n const trustedHtml = policy ? policy.createHTML(noinlineHtml) : noinlineHtml;\n return new SafeHtml(trustedHtml, CONSTRUCTOR_TOKEN_PRIVATE);\n }\n\n\n /**\n * Like create() but does not restrict which tags can be constructed.\n *\n * @param {string} tagName Tag name. Set or validated by caller.\n * @param {?Object<string, ?SafeHtml.AttributeValue>=} attributes\n * @param {(!SafeHtml.TextOrHtml_|\n * !Array<!SafeHtml.TextOrHtml_>)=} content\n * @return {!SafeHtml}\n * @throws {!Error} If invalid or unsafe attribute name or value is provided.\n * @throws {!asserts.AssertionError} If content for void tag is provided.\n * @package\n */\n static createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\n tagName, attributes = undefined, content = undefined) {\n let result = `<${tagName}`;\n result += SafeHtml.stringifyAttributes(tagName, attributes);\n\n if (content == null) {\n content = [];\n } else if (!Array.isArray(content)) {\n content = [content];\n }\n\n if (tags.isVoidTag(tagName.toLowerCase())) {\n asserts.assert(\n !content.length, `Void tag <${tagName}> does not allow content.`);\n result += '>';\n } else {\n const html = SafeHtml.concat(content);\n result += '>' + SafeHtml.unwrap(html) + '</' + tagName + '>';\n }\n\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(result);\n }\n\n\n /**\n * Creates a string with attributes to insert after tagName.\n * @param {string} tagName\n * @param {?Object<string, ?SafeHtml.AttributeValue>=} attributes\n * @return {string} Returns an empty string if there are no attributes,\n * returns a string starting with a space otherwise.\n * @throws {!Error} If attribute value is unsafe for the given tag and\n * attribute.\n * @package\n */\n static stringifyAttributes(tagName, attributes = undefined) {\n let result = '';\n if (attributes) {\n for (let name in attributes) {\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty#Using_hasOwnProperty_as_a_property_name\n if (Object.prototype.hasOwnProperty.call(attributes, name)) {\n if (!VALID_NAMES_IN_TAG.test(name)) {\n throw new Error(\n SafeHtml.ENABLE_ERROR_MESSAGES ?\n `Invalid attribute name \"${name}\".` :\n '');\n }\n const value = attributes[name];\n if (value == null) {\n continue;\n }\n result += ' ' + getAttrNameAndValue(tagName, name, value);\n }\n }\n }\n return result;\n }\n\n\n /**\n * @param {!Object<string, ?SafeHtml.AttributeValue>} fixedAttributes\n * @param {!Object<string, string>} defaultAttributes\n * @param {?Object<string, ?SafeHtml.AttributeValue>=} attributes Optional\n * attributes passed to create*().\n * @return {!Object<string, ?SafeHtml.AttributeValue>}\n * @throws {!Error} If attributes contains an attribute with the same name as\n * an attribute in fixedAttributes.\n * @package\n */\n static combineAttributes(\n fixedAttributes, defaultAttributes, attributes = undefined) {\n const combinedAttributes = {};\n\n for (const name in fixedAttributes) {\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty#Using_hasOwnProperty_as_a_property_name\n if (Object.prototype.hasOwnProperty.call(fixedAttributes, name)) {\n asserts.assert(name.toLowerCase() == name, 'Must be lower case');\n combinedAttributes[name] = fixedAttributes[name];\n }\n }\n for (const name in defaultAttributes) {\n if (Object.prototype.hasOwnProperty.call(defaultAttributes, name)) {\n asserts.assert(name.toLowerCase() == name, 'Must be lower case');\n combinedAttributes[name] = defaultAttributes[name];\n }\n }\n\n if (attributes) {\n for (const name in attributes) {\n if (Object.prototype.hasOwnProperty.call(attributes, name)) {\n const nameLower = name.toLowerCase();\n if (nameLower in fixedAttributes) {\n throw new Error(\n SafeHtml.ENABLE_ERROR_MESSAGES ?\n `Cannot override \"${nameLower}\" attribute, got \"` + name +\n '\" with value \"' + attributes[name] + '\"' :\n '');\n }\n if (nameLower in defaultAttributes) {\n delete combinedAttributes[nameLower];\n }\n combinedAttributes[name] = attributes[name];\n }\n }\n }\n\n return combinedAttributes;\n }\n}\n\n\n/**\n * @define {boolean} Whether to strip out error messages or to leave them in.\n */\nSafeHtml.ENABLE_ERROR_MESSAGES =\n goog.define('goog.html.SafeHtml.ENABLE_ERROR_MESSAGES', goog.DEBUG);\n\n\n/**\n * Whether the `style` attribute is supported. Set to false to avoid the byte\n * weight of `SafeStyle` where unneeded. An error will be thrown if\n * the `style` attribute is used.\n * @define {boolean}\n */\nSafeHtml.SUPPORT_STYLE_ATTRIBUTE =\n goog.define('goog.html.SafeHtml.SUPPORT_STYLE_ATTRIBUTE', true);\n\n\n/**\n * Shorthand for union of types that can sensibly be converted to strings\n * or might already be SafeHtml (as SafeHtml is a TypedString).\n * @private\n * @typedef {string|number|boolean|!TypedString}\n */\nSafeHtml.TextOrHtml_;\n\n\n/**\n * Coerces an arbitrary object into a SafeHtml object.\n *\n * If `textOrHtml` is already of type `SafeHtml`, the same\n * object is returned. Otherwise, `textOrHtml` is coerced to string, and\n * HTML-escaped.\n *\n * @param {!SafeHtml.TextOrHtml_} textOrHtml The text or SafeHtml to\n * coerce.\n * @return {!SafeHtml} The resulting SafeHtml object.\n * @deprecated Use SafeHtml.htmlEscape.\n */\nSafeHtml.from = SafeHtml.htmlEscape;\n\n\n/**\n * @const\n */\nconst VALID_NAMES_IN_TAG = /^[a-zA-Z0-9-]+$/;\n\n\n/**\n * Set of attributes containing URL as defined at\n * http://www.w3.org/TR/html5/index.html#attributes-1.\n * @const {!Object<string,boolean>}\n */\nconst URL_ATTRIBUTES = googObject.createSet(\n 'action', 'cite', 'data', 'formaction', 'href', 'manifest', 'poster',\n 'src');\n\n\n/**\n * Tags which are unsupported via create(). They might be supported via a\n * tag-specific create method. These are tags which might require a\n * TrustedResourceUrl in one of their attributes or a restricted type for\n * their content.\n * @const {!Object<string,boolean>}\n */\nconst NOT_ALLOWED_TAG_NAMES = googObject.createSet(\n TagName.APPLET, TagName.BASE, TagName.EMBED, TagName.IFRAME, TagName.LINK,\n TagName.MATH, TagName.META, TagName.OBJECT, TagName.SCRIPT, TagName.STYLE,\n TagName.SVG, TagName.TEMPLATE);\n\n\n/**\n * @typedef {string|number|!TypedString|\n * !SafeStyle.PropertyMap|undefined|null}\n */\nSafeHtml.AttributeValue;\n\n\n/**\n * @param {string} tagName The tag name.\n * @param {string} name The attribute name.\n * @param {!SafeHtml.AttributeValue} value The attribute value.\n * @return {string} A \"name=value\" string.\n * @throws {!Error} If attribute value is unsafe for the given tag and\n * attribute.\n * @private\n */\nfunction getAttrNameAndValue(tagName, name, value) {\n // If it's goog.string.Const, allow any valid attribute name.\n if (value instanceof Const) {\n value = Const.unwrap(value);\n } else if (name.toLowerCase() == 'style') {\n if (SafeHtml.SUPPORT_STYLE_ATTRIBUTE) {\n value = getStyleValue(value);\n } else {\n throw new Error(\n SafeHtml.ENABLE_ERROR_MESSAGES ? 'Attribute \"style\" not supported.' :\n '');\n }\n } else if (/^on/i.test(name)) {\n // TODO(jakubvrana): Disallow more attributes with a special meaning.\n throw new Error(\n SafeHtml.ENABLE_ERROR_MESSAGES ? `Attribute \"${name}` +\n '\" requires goog.string.Const value, \"' + value + '\" given.' :\n '');\n // URL attributes handled differently according to tag.\n } else if (name.toLowerCase() in URL_ATTRIBUTES) {\n if (value instanceof TrustedResourceUrl) {\n value = TrustedResourceUrl.unwrap(value);\n } else if (value instanceof SafeUrl) {\n value = SafeUrl.unwrap(value);\n } else if (typeof value === 'string') {\n value = SafeUrl.sanitize(value).getTypedStringValue();\n } else {\n throw new Error(\n SafeHtml.ENABLE_ERROR_MESSAGES ?\n `Attribute \"${name}\" on tag \"${tagName}` +\n '\" requires goog.html.SafeUrl, goog.string.Const, or' +\n ' string, value \"' + value + '\" given.' :\n '');\n }\n }\n\n // Accept SafeUrl, TrustedResourceUrl, etc. for attributes which only require\n // HTML-escaping.\n if (/** @type {?} */ (value).implementsGoogStringTypedString) {\n // Ok to call getTypedStringValue() since there's no reliance on the type\n // contract for security here.\n value =\n /** @type {!TypedString} */ (value).getTypedStringValue();\n }\n\n asserts.assert(\n typeof value === 'string' || typeof value === 'number',\n 'String or number value expected, got ' + (typeof value) +\n ' with value: ' + value);\n return `${name}=\"` + internal.htmlEscape(String(value)) + '\"';\n}\n\n\n/**\n * Gets value allowed in \"style\" attribute.\n * @param {!SafeHtml.AttributeValue} value It could be SafeStyle or a\n * map which will be passed to SafeStyle.create.\n * @return {string} Unwrapped value.\n * @throws {!Error} If string value is given.\n * @private\n */\nfunction getStyleValue(value) {\n if (!goog.isObject(value)) {\n throw new Error(\n SafeHtml.ENABLE_ERROR_MESSAGES ?\n 'The \"style\" attribute requires goog.html.SafeStyle or map ' +\n 'of style properties, ' + (typeof value) + ' given: ' + value :\n '');\n }\n if (!(value instanceof SafeStyle)) {\n // Process the property bag into a style object.\n value = SafeStyle.create(value);\n }\n return SafeStyle.unwrap(value);\n}\n\n\n/**\n * A SafeHtml instance corresponding to the HTML doctype: \"<!DOCTYPE html>\".\n * @const {!SafeHtml}\n */\nSafeHtml.DOCTYPE_HTML = /** @type {!SafeHtml} */ ({\n // NOTE: this compiles to nothing, but hides the possible side effect of\n // SafeHtml creation (due to calling trustedTypes.createPolicy) from the\n // compiler so that the entire call can be removed if the result is not used.\n valueOf: function() {\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\n '<!DOCTYPE html>');\n },\n}.valueOf());\n\n/**\n * A SafeHtml instance corresponding to the empty string.\n * @const {!SafeHtml}\n */\nSafeHtml.EMPTY = new SafeHtml(\n (goog.global.trustedTypes && goog.global.trustedTypes.emptyHTML) || '',\n CONSTRUCTOR_TOKEN_PRIVATE);\n\n/**\n * A SafeHtml instance corresponding to the <br> tag.\n * @const {!SafeHtml}\n */\nSafeHtml.BR = /** @type {!SafeHtml} */ ({\n // NOTE: this compiles to nothing, but hides the possible side effect of\n // SafeHtml creation (due to calling trustedTypes.createPolicy) from the\n // compiler so that the entire call can be removed if the result is not used.\n valueOf: function() {\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse('<br>');\n },\n}.valueOf());\n\n\nexports = SafeHtml;\n","~:compiled-at",1684858197913,"~:source-map-json","{\n\"version\":3,\n\"file\":\"goog.html.safehtml.js\",\n\"lineCount\":304,\n\"mappings\":\"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\",\n\"sources\":[\"goog/html/safehtml.js\"],\n\"sourcesContent\":[\"/**\\n * @license\\n * Copyright The Closure Library Authors.\\n * SPDX-License-Identifier: Apache-2.0\\n */\\n\\n\\n/**\\n * @fileoverview The SafeHtml type and its builders.\\n *\\n * TODO(xtof): Link to document stating type contract.\\n */\\n\\ngoog.module('goog.html.SafeHtml');\\ngoog.module.declareLegacyNamespace();\\n\\nconst Const = goog.require('goog.string.Const');\\nconst SafeScript = goog.require('goog.html.SafeScript');\\nconst SafeStyle = goog.require('goog.html.SafeStyle');\\nconst SafeStyleSheet = goog.require('goog.html.SafeStyleSheet');\\nconst SafeUrl = goog.require('goog.html.SafeUrl');\\nconst TagName = goog.require('goog.dom.TagName');\\nconst TrustedResourceUrl = goog.require('goog.html.TrustedResourceUrl');\\nconst TypedString = goog.require('goog.string.TypedString');\\nconst asserts = goog.require('goog.asserts');\\nconst browser = goog.require('goog.labs.userAgent.browser');\\nconst googArray = goog.require('goog.array');\\nconst googObject = goog.require('goog.object');\\nconst internal = goog.require('goog.string.internal');\\nconst tags = goog.require('goog.dom.tags');\\nconst trustedtypes = goog.require('goog.html.trustedtypes');\\n\\n\\n/**\\n * Token used to ensure that object is created only from this file. No code\\n * outside of this file can access this token.\\n * @type {!Object}\\n * @const\\n */\\nconst CONSTRUCTOR_TOKEN_PRIVATE = {};\\n\\n/**\\n * A string that is safe to use in HTML context in DOM APIs and HTML documents.\\n *\\n * A SafeHtml is a string-like object that carries the security type contract\\n * that its value as a string will not cause untrusted script execution when\\n * evaluated as HTML in a browser.\\n *\\n * Values of this type are guaranteed to be safe to use in HTML contexts,\\n * such as, assignment to the innerHTML DOM property, or interpolation into\\n * a HTML template in HTML PC_DATA context, in the sense that the use will not\\n * result in a Cross-Site-Scripting vulnerability.\\n *\\n * Instances of this type must be created via the factory methods\\n * (`SafeHtml.create`, `SafeHtml.htmlEscape`),\\n * etc and not by invoking its constructor. The constructor intentionally takes\\n * an extra parameter that cannot be constructed outside of this file and the\\n * type is immutable; hence only a default instance corresponding to the empty\\n * string can be obtained via constructor invocation.\\n *\\n * Creating SafeHtml objects HAS SIDE-EFFECTS due to calling Trusted Types Web\\n * API.\\n *\\n * Note that there is no `SafeHtml.fromConstant`. The reason is that\\n * the following code would create an unsafe HTML:\\n *\\n * ```\\n * SafeHtml.concat(\\n * SafeHtml.fromConstant(Const.from('<script>')),\\n * SafeHtml.htmlEscape(userInput),\\n * SafeHtml.fromConstant(Const.from('<\\\\/script>')));\\n * ```\\n *\\n * There's `goog.dom.constHtmlToNode` to create a node from constant strings\\n * only.\\n *\\n * @see SafeHtml.create\\n * @see SafeHtml.htmlEscape\\n * @final\\n * @struct\\n * @implements {TypedString}\\n */\\nclass SafeHtml {\\n /**\\n * @param {!TrustedHTML|string} value\\n * @param {!Object} token package-internal implementation detail.\\n */\\n constructor(value, token) {\\n /**\\n * The contained value of this SafeHtml. The field has a purposely ugly\\n * name to make (non-compiled) code that attempts to directly access this\\n * field stand out.\\n * @private {!TrustedHTML|string}\\n */\\n this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ =\\n (token === CONSTRUCTOR_TOKEN_PRIVATE) ? value : '';\\n\\n /**\\n * @override\\n * @const {boolean}\\n */\\n this.implementsGoogStringTypedString = true;\\n }\\n\\n\\n /**\\n * Returns this SafeHtml's value as string.\\n *\\n * IMPORTANT: In code where it is security relevant that an object's type is\\n * indeed `SafeHtml`, use `SafeHtml.unwrap` instead of\\n * this method. If in doubt, assume that it's security relevant. In\\n * particular, note that goog.html functions which return a goog.html type do\\n * not guarantee that the returned instance is of the right type. For example:\\n *\\n * <pre>\\n * var fakeSafeHtml = new String('fake');\\n * fakeSafeHtml.__proto__ = SafeHtml.prototype;\\n * var newSafeHtml = SafeHtml.htmlEscape(fakeSafeHtml);\\n * // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by\\n * // SafeHtml.htmlEscape() as fakeSafeHtml\\n * // instanceof SafeHtml.\\n * </pre>\\n *\\n * @return {string}\\n * @see SafeHtml.unwrap\\n * @override\\n */\\n getTypedStringValue() {\\n return this.privateDoNotAccessOrElseSafeHtmlWrappedValue_.toString();\\n }\\n\\n\\n /**\\n * Returns a string-representation of this value.\\n *\\n * To obtain the actual string value wrapped in a SafeHtml, use\\n * `SafeHtml.unwrap`.\\n *\\n * @return {string}\\n * @see SafeHtml.unwrap\\n * @override\\n */\\n toString() {\\n return this.privateDoNotAccessOrElseSafeHtmlWrappedValue_.toString();\\n }\\n\\n /**\\n * Performs a runtime check that the provided object is indeed a SafeHtml\\n * object, and returns its value.\\n * @param {!SafeHtml} safeHtml The object to extract from.\\n * @return {string} The SafeHtml object's contained string, unless the\\n * run-time type check fails. In that case, `unwrap` returns an innocuous\\n * string, or, if assertions are enabled, throws\\n * `asserts.AssertionError`.\\n */\\n static unwrap(safeHtml) {\\n return SafeHtml.unwrapTrustedHTML(safeHtml).toString();\\n }\\n\\n\\n /**\\n * Unwraps value as TrustedHTML if supported or as a string if not.\\n * @param {!SafeHtml} safeHtml\\n * @return {!TrustedHTML|string}\\n * @see SafeHtml.unwrap\\n */\\n static unwrapTrustedHTML(safeHtml) {\\n // Perform additional run-time type-checking to ensure that safeHtml is\\n // indeed an instance of the expected type. This provides some additional\\n // protection against security bugs due to application code that disables\\n // type checks. Specifically, the following checks are performed:\\n // 1. The object is an instance of the expected type.\\n // 2. The object is not an instance of a subclass.\\n if (safeHtml instanceof SafeHtml && safeHtml.constructor === SafeHtml) {\\n return safeHtml.privateDoNotAccessOrElseSafeHtmlWrappedValue_;\\n } else {\\n asserts.fail(\\n `expected object of type SafeHtml, got '${safeHtml}' of type ` +\\n goog.typeOf(safeHtml));\\n return 'type_error:SafeHtml';\\n }\\n }\\n\\n /**\\n * Returns HTML-escaped text as a SafeHtml object.\\n *\\n * @param {!SafeHtml.TextOrHtml_} textOrHtml The text to escape. If\\n * the parameter is of type SafeHtml it is returned directly (no escaping\\n * is done).\\n * @return {!SafeHtml} The escaped text, wrapped as a SafeHtml.\\n */\\n static htmlEscape(textOrHtml) {\\n if (textOrHtml instanceof SafeHtml) {\\n return textOrHtml;\\n }\\n const textIsObject = typeof textOrHtml == 'object';\\n let textAsString;\\n if (textIsObject &&\\n /** @type {?} */ (textOrHtml).implementsGoogStringTypedString) {\\n textAsString =\\n /** @type {!TypedString} */ (textOrHtml).getTypedStringValue();\\n } else {\\n textAsString = String(textOrHtml);\\n }\\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\\n internal.htmlEscape(textAsString));\\n }\\n\\n\\n /**\\n * Returns HTML-escaped text as a SafeHtml object, with newlines changed to\\n * &lt;br&gt;.\\n * @param {!SafeHtml.TextOrHtml_} textOrHtml The text to escape. If\\n * the parameter is of type SafeHtml it is returned directly (no escaping\\n * is done).\\n * @return {!SafeHtml} The escaped text, wrapped as a SafeHtml.\\n */\\n static htmlEscapePreservingNewlines(textOrHtml) {\\n if (textOrHtml instanceof SafeHtml) {\\n return textOrHtml;\\n }\\n const html = SafeHtml.htmlEscape(textOrHtml);\\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\\n internal.newLineToBr(SafeHtml.unwrap(html)));\\n }\\n\\n\\n /**\\n * Returns HTML-escaped text as a SafeHtml object, with newlines changed to\\n * &lt;br&gt; and escaping whitespace to preserve spatial formatting.\\n * Character entity #160 is used to make it safer for XML.\\n * @param {!SafeHtml.TextOrHtml_} textOrHtml The text to escape. If\\n * the parameter is of type SafeHtml it is returned directly (no escaping\\n * is done).\\n * @return {!SafeHtml} The escaped text, wrapped as a SafeHtml.\\n */\\n static htmlEscapePreservingNewlinesAndSpaces(textOrHtml) {\\n if (textOrHtml instanceof SafeHtml) {\\n return textOrHtml;\\n }\\n const html = SafeHtml.htmlEscape(textOrHtml);\\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\\n internal.whitespaceEscape(SafeHtml.unwrap(html)));\\n }\\n\\n /**\\n * Converts an arbitrary string into an HTML comment by HTML-escaping the\\n * contents and embedding the result between HTML comment markers.\\n *\\n * Escaping is needed because Internet Explorer supports conditional comments\\n * and so may render HTML markup within comments.\\n *\\n * @param {string} text\\n * @return {!SafeHtml}\\n */\\n static comment(text) {\\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\\n '\\u003c!--' + internal.htmlEscape(text) + '--\\u003e');\\n }\\n\\n /**\\n * Creates a SafeHtml content consisting of a tag with optional attributes and\\n * optional content.\\n *\\n * For convenience tag names and attribute names are accepted as regular\\n * strings, instead of Const. Nevertheless, you should not pass\\n * user-controlled values to these parameters. Note that these parameters are\\n * syntactically validated at runtime, and invalid values will result in\\n * an exception.\\n *\\n * Example usage:\\n *\\n * SafeHtml.create('br');\\n * SafeHtml.create('div', {'class': 'a'});\\n * SafeHtml.create('p', {}, 'a');\\n * SafeHtml.create('p', {}, SafeHtml.create('br'));\\n *\\n * SafeHtml.create('span', {\\n * 'style': {'margin': '0'}\\n * });\\n *\\n * To guarantee SafeHtml's type contract is upheld there are restrictions on\\n * attribute values and tag names.\\n *\\n * - For attributes which contain script code (on*), a Const is\\n * required.\\n * - For attributes which contain style (style), a SafeStyle or a\\n * SafeStyle.PropertyMap is required.\\n * - For attributes which are interpreted as URLs (e.g. src, href) a\\n * SafeUrl, Const or string is required. If a string\\n * is passed, it will be sanitized with SafeUrl.sanitize().\\n * - For tags which can load code or set security relevant page metadata,\\n * more specific SafeHtml.create*() functions must be used. Tags\\n * which are not supported by this function are applet, base, embed, iframe,\\n * link, math, meta, object, script, style, svg, and template.\\n *\\n * @param {!TagName|string} tagName The name of the tag. Only tag names\\n * consisting of [a-zA-Z0-9-] are allowed. Tag names documented above are\\n * disallowed.\\n * @param {?Object<string, ?SafeHtml.AttributeValue>=} attributes Mapping\\n * from attribute names to their values. Only attribute names consisting\\n * of [a-zA-Z0-9-] are allowed. Value of null or undefined causes the\\n * attribute to be omitted.\\n * @param {!SafeHtml.TextOrHtml_|\\n * !Array<!SafeHtml.TextOrHtml_>=} content Content to HTML-escape and put\\n * inside the tag. This must be empty for void tags like <br>. Array elements\\n * are concatenated.\\n * @return {!SafeHtml} The SafeHtml content with the tag.\\n * @throws {!Error} If invalid tag name, attribute name, or attribute value is\\n * provided.\\n * @throws {!asserts.AssertionError} If content for void tag is provided.\\n * @deprecated Use a recommended templating system like Lit instead.\\n * More information: go/goog.html-readme // LINE-INTERNAL\\n */\\n static create(tagName, attributes = undefined, content = undefined) {\\n SafeHtml.verifyTagName(String(tagName));\\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\\n String(tagName), attributes, content);\\n }\\n\\n\\n /**\\n * Verifies if the tag name is valid and if it doesn't change the context.\\n * E.g. STRONG is fine but SCRIPT throws because it changes context. See\\n * SafeHtml.create for an explanation of allowed tags.\\n * @param {string} tagName\\n * @return {void}\\n * @throws {!Error} If invalid tag name is provided.\\n * @package\\n */\\n static verifyTagName(tagName) {\\n if (!VALID_NAMES_IN_TAG.test(tagName)) {\\n throw new Error(\\n SafeHtml.ENABLE_ERROR_MESSAGES ? `Invalid tag name <${tagName}>.` :\\n '');\\n }\\n if (tagName.toUpperCase() in NOT_ALLOWED_TAG_NAMES) {\\n throw new Error(\\n SafeHtml.ENABLE_ERROR_MESSAGES ?\\n\\n `Tag name <${tagName}> is not allowed for SafeHtml.` :\\n '');\\n }\\n }\\n\\n\\n /**\\n * Creates a SafeHtml representing an iframe tag.\\n *\\n * This by default restricts the iframe as much as possible by setting the\\n * sandbox attribute to the empty string. If the iframe requires less\\n * restrictions, set the sandbox attribute as tight as possible, but do not\\n * rely on the sandbox as a security feature because it is not supported by\\n * older browsers. If a sandbox is essential to security (e.g. for third-party\\n * frames), use createSandboxIframe which checks for browser support.\\n *\\n * @see https://developer.mozilla.org/en/docs/Web/HTML/Element/iframe#attr-sandbox\\n *\\n * @param {?TrustedResourceUrl=} src The value of the src\\n * attribute. If null or undefined src will not be set.\\n * @param {?SafeHtml=} srcdoc The value of the srcdoc attribute.\\n * If null or undefined srcdoc will not be set.\\n * @param {?Object<string, ?SafeHtml.AttributeValue>=} attributes Mapping\\n * from attribute names to their values. Only attribute names consisting\\n * of [a-zA-Z0-9-] are allowed. Value of null or undefined causes the\\n * attribute to be omitted.\\n * @param {!SafeHtml.TextOrHtml_|\\n * !Array<!SafeHtml.TextOrHtml_>=} content Content to HTML-escape and put\\n * inside the tag. Array elements are concatenated.\\n * @return {!SafeHtml} The SafeHtml content with the tag.\\n * @throws {!Error} If invalid tag name, attribute name, or attribute value is\\n * provided. If attributes\\n * contains the src or srcdoc attributes.\\n */\\n static createIframe(\\n src = undefined, srcdoc = undefined, attributes = undefined,\\n content = undefined) {\\n if (src) {\\n // Check whether this is really TrustedResourceUrl.\\n TrustedResourceUrl.unwrap(src);\\n }\\n\\n const fixedAttributes = {};\\n fixedAttributes['src'] = src || null;\\n fixedAttributes['srcdoc'] = srcdoc && SafeHtml.unwrap(srcdoc);\\n const defaultAttributes = {'sandbox': ''};\\n const combinedAttrs = SafeHtml.combineAttributes(\\n fixedAttributes, defaultAttributes, attributes);\\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\\n 'iframe', combinedAttrs, content);\\n }\\n\\n\\n /**\\n * Creates a SafeHtml representing a sandboxed iframe tag.\\n *\\n * The sandbox attribute is enforced in its most restrictive mode, an empty\\n * string. Consequently, the security requirements for the src and srcdoc\\n * attributes are relaxed compared to SafeHtml.createIframe. This function\\n * will throw on browsers that do not support the sandbox attribute, as\\n * determined by SafeHtml.canUseSandboxIframe.\\n *\\n * The SafeHtml returned by this function can trigger downloads with no\\n * user interaction on Chrome (though only a few, further attempts are\\n * blocked). Firefox and IE will block all downloads from the sandbox.\\n *\\n * @see https://developer.mozilla.org/en/docs/Web/HTML/Element/iframe#attr-sandbox\\n * @see https://lists.w3.org/Archives/Public/public-whatwg-archive/2013Feb/0112.html\\n *\\n * @param {string|!SafeUrl=} src The value of the src\\n * attribute. If null or undefined src will not be set.\\n * @param {string=} srcdoc The value of the srcdoc attribute.\\n * If null or undefined srcdoc will not be set. Will not be sanitized.\\n * @param {!Object<string, ?SafeHtml.AttributeValue>=} attributes Mapping\\n * from attribute names to their values. Only attribute names consisting\\n * of [a-zA-Z0-9-] are allowed. Value of null or undefined causes the\\n * attribute to be omitted.\\n * @param {!SafeHtml.TextOrHtml_|\\n * !Array<!SafeHtml.TextOrHtml_>=} content Content to HTML-escape and put\\n * inside the tag. Array elements are concatenated.\\n * @return {!SafeHtml} The SafeHtml content with the tag.\\n * @throws {!Error} If invalid tag name, attribute name, or attribute value is\\n * provided. If attributes\\n * contains the src, srcdoc or sandbox attributes. If browser does not support\\n * the sandbox attribute on iframe.\\n */\\n static createSandboxIframe(\\n src = undefined, srcdoc = undefined, attributes = undefined,\\n content = undefined) {\\n if (!SafeHtml.canUseSandboxIframe()) {\\n throw new Error(\\n SafeHtml.ENABLE_ERROR_MESSAGES ?\\n 'The browser does not support sandboxed iframes.' :\\n '');\\n }\\n\\n const fixedAttributes = {};\\n if (src) {\\n // Note that sanitize is a no-op on SafeUrl.\\n fixedAttributes['src'] = SafeUrl.unwrap(SafeUrl.sanitize(src));\\n } else {\\n fixedAttributes['src'] = null;\\n }\\n fixedAttributes['srcdoc'] = srcdoc || null;\\n fixedAttributes['sandbox'] = '';\\n const combinedAttrs =\\n SafeHtml.combineAttributes(fixedAttributes, {}, attributes);\\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\\n 'iframe', combinedAttrs, content);\\n }\\n\\n\\n /**\\n * Checks if the user agent supports sandboxed iframes.\\n * @return {boolean}\\n */\\n static canUseSandboxIframe() {\\n return goog.global['HTMLIFrameElement'] &&\\n ('sandbox' in goog.global['HTMLIFrameElement'].prototype);\\n }\\n\\n\\n /**\\n * Creates a SafeHtml representing a script tag with the src attribute.\\n * @param {!TrustedResourceUrl} src The value of the src\\n * attribute.\\n * @param {?Object<string, ?SafeHtml.AttributeValue>=}\\n * attributes\\n * Mapping from attribute names to their values. Only attribute names\\n * consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined\\n * causes the attribute to be omitted.\\n * @return {!SafeHtml} The SafeHtml content with the tag.\\n * @throws {!Error} If invalid attribute name or value is provided. If\\n * attributes contains the\\n * src attribute.\\n */\\n static createScriptSrc(src, attributes = undefined) {\\n // TODO(mlourenco): The charset attribute should probably be blocked. If\\n // its value is attacker controlled, the script contains attacker controlled\\n // sub-strings (even if properly escaped) and the server does not set\\n // charset then XSS is likely possible.\\n // https://html.spec.whatwg.org/multipage/scripting.html#dom-script-charset\\n\\n // Check whether this is really TrustedResourceUrl.\\n TrustedResourceUrl.unwrap(src);\\n\\n const fixedAttributes = {'src': src};\\n const defaultAttributes = {};\\n const combinedAttrs = SafeHtml.combineAttributes(\\n fixedAttributes, defaultAttributes, attributes);\\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\\n 'script', combinedAttrs);\\n }\\n\\n /**\\n * Creates a SafeHtml representing a script tag. Does not allow the language,\\n * src, text or type attributes to be set.\\n * @param {!SafeScript|!Array<!SafeScript>}\\n * script Content to put inside the tag. Array elements are\\n * concatenated.\\n * @param {?Object<string, ?SafeHtml.AttributeValue>=} attributes Mapping\\n * from attribute names to their values. Only attribute names consisting\\n * of [a-zA-Z0-9-] are allowed. Value of null or undefined causes the\\n * attribute to be omitted.\\n * @return {!SafeHtml} The SafeHtml content with the tag.\\n * @throws {!Error} If invalid attribute name or attribute value is provided.\\n * If attributes contains the\\n * language, src or text attribute.\\n */\\n static createScript(script, attributes = undefined) {\\n for (let attr in attributes) {\\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty#Using_hasOwnProperty_as_a_property_name\\n if (Object.prototype.hasOwnProperty.call(attributes, attr)) {\\n const attrLower = attr.toLowerCase();\\n if (attrLower == 'language' || attrLower == 'src' ||\\n attrLower == 'text') {\\n throw new Error(\\n SafeHtml.ENABLE_ERROR_MESSAGES ?\\n `Cannot set \\\"${attrLower}\\\" attribute` :\\n '');\\n }\\n }\\n }\\n\\n let content = '';\\n script = googArray.concat(script);\\n for (let i = 0; i < script.length; i++) {\\n content += SafeScript.unwrap(script[i]);\\n }\\n // Convert to SafeHtml so that it's not HTML-escaped. This is safe because\\n // as part of its contract, SafeScript should have no dangerous '<'.\\n const htmlContent =\\n SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(content);\\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\\n 'script', attributes, htmlContent);\\n }\\n\\n\\n /**\\n * Creates a SafeHtml representing a style tag. The type attribute is set\\n * to \\\"text/css\\\".\\n * @param {!SafeStyleSheet|!Array<!SafeStyleSheet>}\\n * styleSheet Content to put inside the tag. Array elements are\\n * concatenated.\\n * @param {?Object<string, ?SafeHtml.AttributeValue>=} attributes Mapping\\n * from attribute names to their values. Only attribute names consisting\\n * of [a-zA-Z0-9-] are allowed. Value of null or undefined causes the\\n * attribute to be omitted.\\n * @return {!SafeHtml} The SafeHtml content with the tag.\\n * @throws {!Error} If invalid attribute name or attribute value is provided.\\n * If attributes contains the\\n * type attribute.\\n */\\n static createStyle(styleSheet, attributes = undefined) {\\n const fixedAttributes = {'type': 'text/css'};\\n const defaultAttributes = {};\\n const combinedAttrs = SafeHtml.combineAttributes(\\n fixedAttributes, defaultAttributes, attributes);\\n\\n let content = '';\\n styleSheet = googArray.concat(styleSheet);\\n for (let i = 0; i < styleSheet.length; i++) {\\n content += SafeStyleSheet.unwrap(styleSheet[i]);\\n }\\n // Convert to SafeHtml so that it's not HTML-escaped. This is safe because\\n // as part of its contract, SafeStyleSheet should have no dangerous '<'.\\n const htmlContent =\\n SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(content);\\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\\n 'style', combinedAttrs, htmlContent);\\n }\\n\\n\\n /**\\n * Creates a SafeHtml representing a meta refresh tag.\\n * @param {!SafeUrl|string} url Where to redirect. If a string is\\n * passed, it will be sanitized with SafeUrl.sanitize().\\n * @param {number=} secs Number of seconds until the page should be\\n * reloaded. Will be set to 0 if unspecified.\\n * @return {!SafeHtml} The SafeHtml content with the tag.\\n */\\n static createMetaRefresh(url, secs = undefined) {\\n // Note that sanitize is a no-op on SafeUrl.\\n let unwrappedUrl = SafeUrl.unwrap(SafeUrl.sanitize(url));\\n\\n if (browser.isIE() || browser.isEdge()) {\\n // IE/EDGE can't parse the content attribute if the url contains a\\n // semicolon. We can fix this by adding quotes around the url, but then we\\n // can't parse quotes in the URL correctly. Also, it seems that IE/EDGE\\n // did not unescape semicolons in these URLs at some point in the past. We\\n // take a best-effort approach.\\n //\\n // If the URL has semicolons (which may happen in some cases, see\\n // http://www.w3.org/TR/1999/REC-html401-19991224/appendix/notes.html#h-B.2\\n // for instance), wrap it in single quotes to protect the semicolons.\\n // If the URL has semicolons and single quotes, url-encode the single\\n // quotes as well.\\n //\\n // This is imperfect. Notice that both ' and ; are reserved characters in\\n // URIs, so this could do the wrong thing, but at least it will do the\\n // wrong thing in only rare cases.\\n if (internal.contains(unwrappedUrl, ';')) {\\n unwrappedUrl = '\\\\'' + unwrappedUrl.replace(/'/g, '%27') + '\\\\'';\\n }\\n }\\n const attributes = {\\n 'http-equiv': 'refresh',\\n 'content': (secs || 0) + '; url=' + unwrappedUrl,\\n };\\n\\n // This function will handle the HTML escaping for attributes.\\n return SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\\n 'meta', attributes);\\n }\\n\\n /**\\n * Creates a new SafeHtml object by joining the parts with separator.\\n * @param {!SafeHtml.TextOrHtml_} separator\\n * @param {!Array<!SafeHtml.TextOrHtml_|\\n * !Array<!SafeHtml.TextOrHtml_>>} parts Parts to join. If a part\\n * contains an array then each member of this array is also joined with\\n * the separator.\\n * @return {!SafeHtml}\\n */\\n static join(separator, parts) {\\n const separatorHtml = SafeHtml.htmlEscape(separator);\\n const content = [];\\n\\n /**\\n * @param {!SafeHtml.TextOrHtml_|\\n * !Array<!SafeHtml.TextOrHtml_>} argument\\n */\\n const addArgument = (argument) => {\\n if (Array.isArray(argument)) {\\n argument.forEach(addArgument);\\n } else {\\n const html = SafeHtml.htmlEscape(argument);\\n content.push(SafeHtml.unwrap(html));\\n }\\n };\\n\\n parts.forEach(addArgument);\\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\\n content.join(SafeHtml.unwrap(separatorHtml)));\\n }\\n\\n\\n /**\\n * Creates a new SafeHtml object by concatenating values.\\n * @param {...(!SafeHtml.TextOrHtml_|\\n * !Array<!SafeHtml.TextOrHtml_>)} var_args Values to concatenate.\\n * @return {!SafeHtml}\\n */\\n static concat(var_args) {\\n return SafeHtml.join(SafeHtml.EMPTY, Array.prototype.slice.call(arguments));\\n }\\n\\n /**\\n * Package-internal utility method to create SafeHtml instances.\\n *\\n * @param {string} html The string to initialize the SafeHtml object with.\\n * @return {!SafeHtml} The initialized SafeHtml object.\\n * @package\\n */\\n static createSafeHtmlSecurityPrivateDoNotAccessOrElse(html) {\\n /** @noinline */\\n const noinlineHtml = html;\\n const policy = trustedtypes.getPolicyPrivateDoNotAccessOrElse();\\n const trustedHtml = policy ? policy.createHTML(noinlineHtml) : noinlineHtml;\\n return new SafeHtml(trustedHtml, CONSTRUCTOR_TOKEN_PRIVATE);\\n }\\n\\n\\n /**\\n * Like create() but does not restrict which tags can be constructed.\\n *\\n * @param {string} tagName Tag name. Set or validated by caller.\\n * @param {?Object<string, ?SafeHtml.AttributeValue>=} attributes\\n * @param {(!SafeHtml.TextOrHtml_|\\n * !Array<!SafeHtml.TextOrHtml_>)=} content\\n * @return {!SafeHtml}\\n * @throws {!Error} If invalid or unsafe attribute name or value is provided.\\n * @throws {!asserts.AssertionError} If content for void tag is provided.\\n * @package\\n */\\n static createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\\n tagName, attributes = undefined, content = undefined) {\\n let result = `<${tagName}`;\\n result += SafeHtml.stringifyAttributes(tagName, attributes);\\n\\n if (content == null) {\\n content = [];\\n } else if (!Array.isArray(content)) {\\n content = [content];\\n }\\n\\n if (tags.isVoidTag(tagName.toLowerCase())) {\\n asserts.assert(\\n !content.length, `Void tag <${tagName}> does not allow content.`);\\n result += '>';\\n } else {\\n const html = SafeHtml.concat(content);\\n result += '>' + SafeHtml.unwrap(html) + '</' + tagName + '>';\\n }\\n\\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(result);\\n }\\n\\n\\n /**\\n * Creates a string with attributes to insert after tagName.\\n * @param {string} tagName\\n * @param {?Object<string, ?SafeHtml.AttributeValue>=} attributes\\n * @return {string} Returns an empty string if there are no attributes,\\n * returns a string starting with a space otherwise.\\n * @throws {!Error} If attribute value is unsafe for the given tag and\\n * attribute.\\n * @package\\n */\\n static stringifyAttributes(tagName, attributes = undefined) {\\n let result = '';\\n if (attributes) {\\n for (let name in attributes) {\\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty#Using_hasOwnProperty_as_a_property_name\\n if (Object.prototype.hasOwnProperty.call(attributes, name)) {\\n if (!VALID_NAMES_IN_TAG.test(name)) {\\n throw new Error(\\n SafeHtml.ENABLE_ERROR_MESSAGES ?\\n `Invalid attribute name \\\"${name}\\\".` :\\n '');\\n }\\n const value = attributes[name];\\n if (value == null) {\\n continue;\\n }\\n result += ' ' + getAttrNameAndValue(tagName, name, value);\\n }\\n }\\n }\\n return result;\\n }\\n\\n\\n /**\\n * @param {!Object<string, ?SafeHtml.AttributeValue>} fixedAttributes\\n * @param {!Object<string, string>} defaultAttributes\\n * @param {?Object<string, ?SafeHtml.AttributeValue>=} attributes Optional\\n * attributes passed to create*().\\n * @return {!Object<string, ?SafeHtml.AttributeValue>}\\n * @throws {!Error} If attributes contains an attribute with the same name as\\n * an attribute in fixedAttributes.\\n * @package\\n */\\n static combineAttributes(\\n fixedAttributes, defaultAttributes, attributes = undefined) {\\n const combinedAttributes = {};\\n\\n for (const name in fixedAttributes) {\\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty#Using_hasOwnProperty_as_a_property_name\\n if (Object.prototype.hasOwnProperty.call(fixedAttributes, name)) {\\n asserts.assert(name.toLowerCase() == name, 'Must be lower case');\\n combinedAttributes[name] = fixedAttributes[name];\\n }\\n }\\n for (const name in defaultAttributes) {\\n if (Object.prototype.hasOwnProperty.call(defaultAttributes, name)) {\\n asserts.assert(name.toLowerCase() == name, 'Must be lower case');\\n combinedAttributes[name] = defaultAttributes[name];\\n }\\n }\\n\\n if (attributes) {\\n for (const name in attributes) {\\n if (Object.prototype.hasOwnProperty.call(attributes, name)) {\\n const nameLower = name.toLowerCase();\\n if (nameLower in fixedAttributes) {\\n throw new Error(\\n SafeHtml.ENABLE_ERROR_MESSAGES ?\\n `Cannot override \\\"${nameLower}\\\" attribute, got \\\"` + name +\\n '\\\" with value \\\"' + attributes[name] + '\\\"' :\\n '');\\n }\\n if (nameLower in defaultAttributes) {\\n delete combinedAttributes[nameLower];\\n }\\n combinedAttributes[name] = attributes[name];\\n }\\n }\\n }\\n\\n return combinedAttributes;\\n }\\n}\\n\\n\\n/**\\n * @define {boolean} Whether to strip out error messages or to leave them in.\\n */\\nSafeHtml.ENABLE_ERROR_MESSAGES =\\n goog.define('goog.html.SafeHtml.ENABLE_ERROR_MESSAGES', goog.DEBUG);\\n\\n\\n/**\\n * Whether the `style` attribute is supported. Set to false to avoid the byte\\n * weight of `SafeStyle` where unneeded. An error will be thrown if\\n * the `style` attribute is used.\\n * @define {boolean}\\n */\\nSafeHtml.SUPPORT_STYLE_ATTRIBUTE =\\n goog.define('goog.html.SafeHtml.SUPPORT_STYLE_ATTRIBUTE', true);\\n\\n\\n/**\\n * Shorthand for union of types that can sensibly be converted to strings\\n * or might already be SafeHtml (as SafeHtml is a TypedString).\\n * @private\\n * @typedef {string|number|boolean|!TypedString}\\n */\\nSafeHtml.TextOrHtml_;\\n\\n\\n/**\\n * Coerces an arbitrary object into a SafeHtml object.\\n *\\n * If `textOrHtml` is already of type `SafeHtml`, the same\\n * object is returned. Otherwise, `textOrHtml` is coerced to string, and\\n * HTML-escaped.\\n *\\n * @param {!SafeHtml.TextOrHtml_} textOrHtml The text or SafeHtml to\\n * coerce.\\n * @return {!SafeHtml} The resulting SafeHtml object.\\n * @deprecated Use SafeHtml.htmlEscape.\\n */\\nSafeHtml.from = SafeHtml.htmlEscape;\\n\\n\\n/**\\n * @const\\n */\\nconst VALID_NAMES_IN_TAG = /^[a-zA-Z0-9-]+$/;\\n\\n\\n/**\\n * Set of attributes containing URL as defined at\\n * http://www.w3.org/TR/html5/index.html#attributes-1.\\n * @const {!Object<string,boolean>}\\n */\\nconst URL_ATTRIBUTES = googObject.createSet(\\n 'action', 'cite', 'data', 'formaction', 'href', 'manifest', 'poster',\\n 'src');\\n\\n\\n/**\\n * Tags which are unsupported via create(). They might be supported via a\\n * tag-specific create method. These are tags which might require a\\n * TrustedResourceUrl in one of their attributes or a restricted type for\\n * their content.\\n * @const {!Object<string,boolean>}\\n */\\nconst NOT_ALLOWED_TAG_NAMES = googObject.createSet(\\n TagName.APPLET, TagName.BASE, TagName.EMBED, TagName.IFRAME, TagName.LINK,\\n TagName.MATH, TagName.META, TagName.OBJECT, TagName.SCRIPT, TagName.STYLE,\\n TagName.SVG, TagName.TEMPLATE);\\n\\n\\n/**\\n * @typedef {string|number|!TypedString|\\n * !SafeStyle.PropertyMap|undefined|null}\\n */\\nSafeHtml.AttributeValue;\\n\\n\\n/**\\n * @param {string} tagName The tag name.\\n * @param {string} name The attribute name.\\n * @param {!SafeHtml.AttributeValue} value The attribute value.\\n * @return {string} A \\\"name=value\\\" string.\\n * @throws {!Error} If attribute value is unsafe for the given tag and\\n * attribute.\\n * @private\\n */\\nfunction getAttrNameAndValue(tagName, name, value) {\\n // If it's goog.string.Const, allow any valid attribute name.\\n if (value instanceof Const) {\\n value = Const.unwrap(value);\\n } else if (name.toLowerCase() == 'style') {\\n if (SafeHtml.SUPPORT_STYLE_ATTRIBUTE) {\\n value = getStyleValue(value);\\n } else {\\n throw new Error(\\n SafeHtml.ENABLE_ERROR_MESSAGES ? 'Attribute \\\"style\\\" not supported.' :\\n '');\\n }\\n } else if (/^on/i.test(name)) {\\n // TODO(jakubvrana): Disallow more attributes with a special meaning.\\n throw new Error(\\n SafeHtml.ENABLE_ERROR_MESSAGES ? `Attribute \\\"${name}` +\\n '\\\" requires goog.string.Const value, \\\"' + value + '\\\" given.' :\\n '');\\n // URL attributes handled differently according to tag.\\n } else if (name.toLowerCase() in URL_ATTRIBUTES) {\\n if (value instanceof TrustedResourceUrl) {\\n value = TrustedResourceUrl.unwrap(value);\\n } else if (value instanceof SafeUrl) {\\n value = SafeUrl.unwrap(value);\\n } else if (typeof value === 'string') {\\n value = SafeUrl.sanitize(value).getTypedStringValue();\\n } else {\\n throw new Error(\\n SafeHtml.ENABLE_ERROR_MESSAGES ?\\n `Attribute \\\"${name}\\\" on tag \\\"${tagName}` +\\n '\\\" requires goog.html.SafeUrl, goog.string.Const, or' +\\n ' string, value \\\"' + value + '\\\" given.' :\\n '');\\n }\\n }\\n\\n // Accept SafeUrl, TrustedResourceUrl, etc. for attributes which only require\\n // HTML-escaping.\\n if (/** @type {?} */ (value).implementsGoogStringTypedString) {\\n // Ok to call getTypedStringValue() since there's no reliance on the type\\n // contract for security here.\\n value =\\n /** @type {!TypedString} */ (value).getTypedStringValue();\\n }\\n\\n asserts.assert(\\n typeof value === 'string' || typeof value === 'number',\\n 'String or number value expected, got ' + (typeof value) +\\n ' with value: ' + value);\\n return `${name}=\\\"` + internal.htmlEscape(String(value)) + '\\\"';\\n}\\n\\n\\n/**\\n * Gets value allowed in \\\"style\\\" attribute.\\n * @param {!SafeHtml.AttributeValue} value It could be SafeStyle or a\\n * map which will be passed to SafeStyle.create.\\n * @return {string} Unwrapped value.\\n * @throws {!Error} If string value is given.\\n * @private\\n */\\nfunction getStyleValue(value) {\\n if (!goog.isObject(value)) {\\n throw new Error(\\n SafeHtml.ENABLE_ERROR_MESSAGES ?\\n 'The \\\"style\\\" attribute requires goog.html.SafeStyle or map ' +\\n 'of style properties, ' + (typeof value) + ' given: ' + value :\\n '');\\n }\\n if (!(value instanceof SafeStyle)) {\\n // Process the property bag into a style object.\\n value = SafeStyle.create(value);\\n }\\n return SafeStyle.unwrap(value);\\n}\\n\\n\\n/**\\n * A SafeHtml instance corresponding to the HTML doctype: \\\"<!DOCTYPE html>\\\".\\n * @const {!SafeHtml}\\n */\\nSafeHtml.DOCTYPE_HTML = /** @type {!SafeHtml} */ ({\\n // NOTE: this compiles to nothing, but hides the possible side effect of\\n // SafeHtml creation (due to calling trustedTypes.createPolicy) from the\\n // compiler so that the entire call can be removed if the result is not used.\\n valueOf: function() {\\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\\n '<!DOCTYPE html>');\\n },\\n}.valueOf());\\n\\n/**\\n * A SafeHtml instance corresponding to the empty string.\\n * @const {!SafeHtml}\\n */\\nSafeHtml.EMPTY = new SafeHtml(\\n (goog.global.trustedTypes && goog.global.trustedTypes.emptyHTML) || '',\\n CONSTRUCTOR_TOKEN_PRIVATE);\\n\\n/**\\n * A SafeHtml instance corresponding to the <br> tag.\\n * @const {!SafeHtml}\\n */\\nSafeHtml.BR = /** @type {!SafeHtml} */ ({\\n // NOTE: this compiles to nothing, but hides the possible side effect of\\n // SafeHtml creation (due to calling trustedTypes.createPolicy) from the\\n // compiler so that the entire call can be removed if the result is not used.\\n valueOf: function() {\\n return SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse('<br>');\\n },\\n}.valueOf());\\n\\n\\nexports = SafeHtml;\\n\"],\n\"names\":[\"goog\",\"module\",\"declareLegacyNamespace\",\"Const\",\"require\",\"SafeScript\",\"SafeStyle\",\"SafeStyleSheet\",\"SafeUrl\",\"TagName\",\"TrustedResourceUrl\",\"TypedString\",\"asserts\",\"browser\",\"googArray\",\"googObject\",\"internal\",\"tags\",\"trustedtypes\",\"CONSTRUCTOR_TOKEN_PRIVATE\",\"SafeHtml\",\"constructor\",\"value\",\"token\",\"privateDoNotAccessOrElseSafeHtmlWrappedValue_\",\"implementsGoogStringTypedString\",\"getTypedStringValue\",\"toString\",\"unwrap\",\"safeHtml\",\"unwrapTrustedHTML\",\"fail\",\"typeOf\",\"htmlEscape\",\"textOrHtml\",\"textIsObject\",\"textAsString\",\"String\",\"createSafeHtmlSecurityPrivateDoNotAccessOrElse\",\"htmlEscapePreservingNewlines\",\"html\",\"newLineToBr\",\"htmlEscapePreservingNewlinesAndSpaces\",\"whitespaceEscape\",\"comment\",\"text\",\"create\",\"tagName\",\"attributes\",\"undefined\",\"content\",\"verifyTagName\",\"createSafeHtmlTagSecurityPrivateDoNotAccessOrElse\",\"VALID_NAMES_IN_TAG\",\"test\",\"Error\",\"ENABLE_ERROR_MESSAGES\",\"toUpperCase\",\"NOT_ALLOWED_TAG_NAMES\",\"createIframe\",\"src\",\"srcdoc\",\"fixedAttributes\",\"defaultAttributes\",\"combinedAttrs\",\"combineAttributes\",\"createSandboxIframe\",\"canUseSandboxIframe\",\"sanitize\",\"global\",\"prototype\",\"createScriptSrc\",\"createScript\",\"script\",\"attr\",\"Object\",\"hasOwnProperty\",\"call\",\"attrLower\",\"toLowerCase\",\"concat\",\"i\",\"length\",\"htmlContent\",\"createStyle\",\"styleSheet\",\"createMetaRefresh\",\"url\",\"secs\",\"unwrappedUrl\",\"isIE\",\"isEdge\",\"contains\",\"replace\",\"join\",\"separator\",\"parts\",\"separatorHtml\",\"addArgument\",\"argument\",\"Array\",\"isArray\",\"forEach\",\"push\",\"var_args\",\"EMPTY\",\"slice\",\"arguments\",\"noinlineHtml\",\"policy\",\"getPolicyPrivateDoNotAccessOrElse\",\"trustedHtml\",\"createHTML\",\"result\",\"stringifyAttributes\",\"isVoidTag\",\"assert\",\"name\",\"getAttrNameAndValue\",\"combinedAttributes\",\"nameLower\",\"define\",\"DEBUG\",\"SUPPORT_STYLE_ATTRIBUTE\",\"TextOrHtml_\",\"from\",\"URL_ATTRIBUTES\",\"createSet\",\"APPLET\",\"BASE\",\"EMBED\",\"IFRAME\",\"LINK\",\"MATH\",\"META\",\"OBJECT\",\"SCRIPT\",\"STYLE\",\"SVG\",\"TEMPLATE\",\"AttributeValue\",\"getStyleValue\",\"isObject\",\"DOCTYPE_HTML\",\"valueOf\",\"trustedTypes\",\"emptyHTML\",\"BR\",\"exports\"]\n}\n"]