1 line
106 KiB
JavaScript
1 line
106 KiB
JavaScript
["^ ","~:resource-id",["~:shadow.build.classpath/resource","goog/html/safehtml.js"],"~:js","goog.loadModule(function(exports) {\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 \"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 = 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 = 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 = 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 = result + \"\\x3e\";\n } else {\n const html = SafeHtml.concat(content);\n result = 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 = 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 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 * <br>.\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 * <br> 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",1730900725403,"~: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 * <br>.\\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 * <br> 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\":[\"getAttrNameAndValue\",\"tagName\",\"name\",\"value\",\"Const\",\"unwrap\",\"toLowerCase\",\"SafeHtml\",\"SUPPORT_STYLE_ATTRIBUTE\",\"getStyleValue\",\"Error\",\"ENABLE_ERROR_MESSAGES\",\"test\",\"URL_ATTRIBUTES\",\"TrustedResourceUrl\",\"SafeUrl\",\"sanitize\",\"getTypedStringValue\",\"implementsGoogStringTypedString\",\"asserts\",\"assert\",\"internal\",\"htmlEscape\",\"String\",\"goog\",\"isObject\",\"SafeStyle\",\"create\",\"module\",\"declareLegacyNamespace\",\"require\",\"SafeScript\",\"SafeStyleSheet\",\"TagName\",\"TypedString\",\"browser\",\"googArray\",\"googObject\",\"tags\",\"trustedtypes\",\"CONSTRUCTOR_TOKEN_PRIVATE\",\"constructor\",\"token\",\"privateDoNotAccessOrElseSafeHtmlWrappedValue_\",\"toString\",\"safeHtml\",\"unwrapTrustedHTML\",\"fail\",\"typeOf\",\"textOrHtml\",\"textIsObject\",\"textAsString\",\"createSafeHtmlSecurityPrivateDoNotAccessOrElse\",\"htmlEscapePreservingNewlines\",\"html\",\"newLineToBr\",\"htmlEscapePreservingNewlinesAndSpaces\",\"whitespaceEscape\",\"comment\",\"text\",\"attributes\",\"undefined\",\"content\",\"verifyTagName\",\"createSafeHtmlTagSecurityPrivateDoNotAccessOrElse\",\"VALID_NAMES_IN_TAG\",\"toUpperCase\",\"NOT_ALLOWED_TAG_NAMES\",\"createIframe\",\"src\",\"srcdoc\",\"fixedAttributes\",\"defaultAttributes\",\"combinedAttrs\",\"combineAttributes\",\"createSandboxIframe\",\"canUseSandboxIframe\",\"global\",\"prototype\",\"createScriptSrc\",\"createScript\",\"script\",\"attr\",\"Object\",\"hasOwnProperty\",\"call\",\"attrLower\",\"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\",\"combinedAttributes\",\"nameLower\",\"define\",\"DEBUG\",\"TextOrHtml_\",\"from\",\"createSet\",\"APPLET\",\"BASE\",\"EMBED\",\"IFRAME\",\"LINK\",\"MATH\",\"META\",\"OBJECT\",\"SCRIPT\",\"STYLE\",\"SVG\",\"TEMPLATE\",\"AttributeValue\",\"DOCTYPE_HTML\",\"valueOf\",\"trustedTypes\",\"emptyHTML\",\"BR\",\"exports\"]\n}\n"] |