["^ ","~:resource-id",["~:shadow.build.classpath/resource","goog/html/safestyle.js"],"~:js","goog.loadModule(function(exports) {\n  \"use strict\";\n  goog.module(\"goog.html.SafeStyle\");\n  goog.module.declareLegacyNamespace();\n  const Const = goog.require(\"goog.string.Const\");\n  const SafeUrl = goog.require(\"goog.html.SafeUrl\");\n  const TypedString = goog.require(\"goog.string.TypedString\");\n  const {AssertionError, assert, fail} = goog.require(\"goog.asserts\");\n  const {contains, endsWith} = goog.require(\"goog.string.internal\");\n  const CONSTRUCTOR_TOKEN_PRIVATE = {};\n  class SafeStyle {\n    constructor(value, token) {\n      this.privateDoNotAccessOrElseSafeStyleWrappedValue_ = token === CONSTRUCTOR_TOKEN_PRIVATE ? value : \"\";\n      this.implementsGoogStringTypedString = true;\n    }\n    static fromConstant(style) {\n      const styleString = Const.unwrap(style);\n      if (styleString.length === 0) {\n        return SafeStyle.EMPTY;\n      }\n      assert(endsWith(styleString, \";\"), `Last character of style string is not ';': ${styleString}`);\n      assert(contains(styleString, \":\"), \"Style string must contain at least one ':', to \" + 'specify a \"name: value\" pair: ' + styleString);\n      return SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(styleString);\n    }\n    getTypedStringValue() {\n      return this.privateDoNotAccessOrElseSafeStyleWrappedValue_;\n    }\n    toString() {\n      return this.privateDoNotAccessOrElseSafeStyleWrappedValue_.toString();\n    }\n    static unwrap(safeStyle) {\n      if (safeStyle instanceof SafeStyle && safeStyle.constructor === SafeStyle) {\n        return safeStyle.privateDoNotAccessOrElseSafeStyleWrappedValue_;\n      } else {\n        fail(`expected object of type SafeStyle, got '${safeStyle}` + \"' of type \" + goog.typeOf(safeStyle));\n        return \"type_error:SafeStyle\";\n      }\n    }\n    static createSafeStyleSecurityPrivateDoNotAccessOrElse(style) {\n      return new SafeStyle(style, CONSTRUCTOR_TOKEN_PRIVATE);\n    }\n    static create(map) {\n      let style = \"\";\n      for (let name in map) {\n        if (Object.prototype.hasOwnProperty.call(map, name)) {\n          if (!/^[-_a-zA-Z0-9]+$/.test(name)) {\n            throw new Error(`Name allows only [-_a-zA-Z0-9], got: ${name}`);\n          }\n          let value = map[name];\n          if (value == null) {\n            continue;\n          }\n          if (Array.isArray(value)) {\n            value = value.map(sanitizePropertyValue).join(\" \");\n          } else {\n            value = sanitizePropertyValue(value);\n          }\n          style += `${name}:${value};`;\n        }\n      }\n      if (!style) {\n        return SafeStyle.EMPTY;\n      }\n      return SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(style);\n    }\n    static concat(var_args) {\n      let style = \"\";\n      const addArgument = argument => {\n        if (Array.isArray(argument)) {\n          argument.forEach(addArgument);\n        } else {\n          style += SafeStyle.unwrap(argument);\n        }\n      };\n      Array.prototype.forEach.call(arguments, addArgument);\n      if (!style) {\n        return SafeStyle.EMPTY;\n      }\n      return SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(style);\n    }\n  }\n  SafeStyle.EMPTY = SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(\"\");\n  SafeStyle.INNOCUOUS_STRING = \"zClosurez\";\n  SafeStyle.PropertyValue;\n  SafeStyle.PropertyMap;\n  function sanitizePropertyValue(value) {\n    if (value instanceof SafeUrl) {\n      const url = SafeUrl.unwrap(value);\n      return 'url(\"' + url.replace(/</g, \"%3c\").replace(/[\\\\\"]/g, \"\\\\$\\x26\") + '\")';\n    }\n    const result = value instanceof Const ? Const.unwrap(value) : sanitizePropertyValueString(String(value));\n    if (/[{;}]/.test(result)) {\n      throw new AssertionError(\"Value does not allow [{;}], got: %s.\", [result]);\n    }\n    return result;\n  }\n  function sanitizePropertyValueString(value) {\n    const valueWithoutFunctions = value.replace(FUNCTIONS_RE, \"$1\").replace(FUNCTIONS_RE, \"$1\").replace(URL_RE, \"url\");\n    if (!VALUE_RE.test(valueWithoutFunctions)) {\n      fail(`String value allows only ${VALUE_ALLOWED_CHARS}` + \" and simple functions, got: \" + value);\n      return SafeStyle.INNOCUOUS_STRING;\n    } else if (COMMENT_RE.test(value)) {\n      fail(`String value disallows comments, got: ${value}`);\n      return SafeStyle.INNOCUOUS_STRING;\n    } else if (!hasBalancedQuotes(value)) {\n      fail(`String value requires balanced quotes, got: ${value}`);\n      return SafeStyle.INNOCUOUS_STRING;\n    } else if (!hasBalancedSquareBrackets(value)) {\n      fail(\"String value requires balanced square brackets and one\" + \" identifier per pair of brackets, got: \" + value);\n      return SafeStyle.INNOCUOUS_STRING;\n    }\n    return sanitizeUrl(value);\n  }\n  function hasBalancedQuotes(value) {\n    let outsideSingle = true;\n    let outsideDouble = true;\n    for (let i = 0; i < value.length; i++) {\n      const c = value.charAt(i);\n      if (c == \"'\" && outsideDouble) {\n        outsideSingle = !outsideSingle;\n      } else if (c == '\"' && outsideSingle) {\n        outsideDouble = !outsideDouble;\n      }\n    }\n    return outsideSingle && outsideDouble;\n  }\n  function hasBalancedSquareBrackets(value) {\n    let outside = true;\n    const tokenRe = /^[-_a-zA-Z0-9]$/;\n    for (let i = 0; i < value.length; i++) {\n      const c = value.charAt(i);\n      if (c == \"]\") {\n        if (outside) {\n          return false;\n        }\n        outside = true;\n      } else if (c == \"[\") {\n        if (!outside) {\n          return false;\n        }\n        outside = false;\n      } else if (!outside && !tokenRe.test(c)) {\n        return false;\n      }\n    }\n    return outside;\n  }\n  const VALUE_ALLOWED_CHARS = \"[-+,.\\\"'%_!#/ a-zA-Z0-9\\\\[\\\\]]\";\n  const VALUE_RE = new RegExp(`^${VALUE_ALLOWED_CHARS}+\\$`);\n  const URL_RE = new RegExp(\"\\\\b(url\\\\([ \\t\\n]*)(\" + \"'[ -\\x26(-\\\\[\\\\]-~]*'\" + '|\"[ !#-\\\\[\\\\]-~]*\"' + \"|[!#-\\x26*-\\\\[\\\\]-~]*\" + \")([ \\t\\n]*\\\\))\", \"g\");\n  const ALLOWED_FUNCTIONS = [\"calc\", \"cubic-bezier\", \"fit-content\", \"hsl\", \"hsla\", \"linear-gradient\", \"matrix\", \"minmax\", \"radial-gradient\", \"repeat\", \"rgb\", \"rgba\", \"(rotate|scale|translate)(X|Y|Z|3d)?\", \"steps\", \"var\",];\n  const FUNCTIONS_RE = new RegExp(\"\\\\b(\" + ALLOWED_FUNCTIONS.join(\"|\") + \")\" + \"\\\\([-+*/0-9a-zA-Z.%#\\\\[\\\\], ]+\\\\)\", \"g\");\n  const COMMENT_RE = /\\/\\*/;\n  function sanitizeUrl(value) {\n    return value.replace(URL_RE, (match, before, url, after) => {\n      let quote = \"\";\n      url = url.replace(/^(['\"])(.*)\\1$/, (match, start, inside) => {\n        quote = start;\n        return inside;\n      });\n      const sanitized = SafeUrl.sanitize(url).getTypedStringValue();\n      return before + quote + sanitized + quote + after;\n    });\n  }\n  exports = SafeStyle;\n  return exports;\n});\n","~:source","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview The SafeStyle type and its builders.\n *\n * TODO(xtof): Link to document stating type contract.\n */\n\ngoog.module('goog.html.SafeStyle');\ngoog.module.declareLegacyNamespace();\n\nconst Const = goog.require('goog.string.Const');\nconst SafeUrl = goog.require('goog.html.SafeUrl');\nconst TypedString = goog.require('goog.string.TypedString');\nconst {AssertionError, assert, fail} = goog.require('goog.asserts');\nconst {contains, endsWith} = goog.require('goog.string.internal');\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-like object which represents a sequence of CSS declarations\n * (`propertyName1: propertyvalue1; propertyName2: propertyValue2; ...`)\n * and that carries the security type contract that its value, as a string,\n * will not cause untrusted script execution (XSS) when evaluated as CSS in a\n * browser.\n *\n * Instances of this type must be created via the factory methods\n * (`SafeStyle.create` or `SafeStyle.fromConstant`)\n * and not by invoking its constructor. The constructor intentionally takes an\n * extra parameter that cannot be constructed outside of this file and the type\n * is immutable; hence only a default instance corresponding to the empty string\n * can be obtained via constructor invocation.\n *\n * SafeStyle's string representation can safely be:\n * <ul>\n *   <li>Interpolated as the content of a *quoted* HTML style attribute.\n *       However, the SafeStyle string *must be HTML-attribute-escaped* before\n *       interpolation.\n *   <li>Interpolated as the content of a {}-wrapped block within a stylesheet.\n *       '<' characters in the SafeStyle string *must be CSS-escaped* before\n *       interpolation. The SafeStyle string is also guaranteed not to be able\n *       to introduce new properties or elide existing ones.\n *   <li>Interpolated as the content of a {}-wrapped block within an HTML\n *       &lt;style&gt; element. '<' characters in the SafeStyle string\n *       *must be CSS-escaped* before interpolation.\n *   <li>Assigned to the style property of a DOM node. The SafeStyle string\n *       should not be escaped before being assigned to the property.\n * </ul>\n *\n * A SafeStyle may never contain literal angle brackets. Otherwise, it could\n * be unsafe to place a SafeStyle into a &lt;style&gt; tag (where it can't\n * be HTML escaped). For example, if the SafeStyle containing\n * `font: 'foo &lt;style/&gt;&lt;script&gt;evil&lt;/script&gt;'` were\n * interpolated within a &lt;style&gt; tag, this would then break out of the\n * style context into HTML.\n *\n * A SafeStyle may contain literal single or double quotes, and as such the\n * entire style string must be escaped when used in a style attribute (if\n * this were not the case, the string could contain a matching quote that\n * would escape from the style attribute).\n *\n * Values of this type must be composable, i.e. for any two values\n * `style1` and `style2` of this type,\n * `SafeStyle.unwrap(style1) +\n * SafeStyle.unwrap(style2)` must itself be a value that satisfies\n * the SafeStyle type constraint. This requirement implies that for any value\n * `style` of this type, `SafeStyle.unwrap(style)` must\n * not end in a \"property value\" or \"property name\" context. For example,\n * a value of `background:url(\"` or `font-` would not satisfy the\n * SafeStyle contract. This is because concatenating such strings with a\n * second value that itself does not contain unsafe CSS can result in an\n * overall string that does. For example, if `javascript:evil())\"` is\n * appended to `background:url(\"}, the resulting string may result in\n * the execution of a malicious script.\n *\n * TODO(mlourenco): Consider whether we should implement UTF-8 interchange\n * validity checks and blacklisting of newlines (including Unicode ones) and\n * other whitespace characters (\\t, \\f). Document here if so and also update\n * SafeStyle.fromConstant().\n *\n * The following example values comply with this type's contract:\n * <ul>\n *   <li><pre>width: 1em;</pre>\n *   <li><pre>height:1em;</pre>\n *   <li><pre>width: 1em;height: 1em;</pre>\n *   <li><pre>background:url('http://url');</pre>\n * </ul>\n * In addition, the empty string is safe for use in a CSS attribute.\n *\n * The following example values do NOT comply with this type's contract:\n * <ul>\n *   <li><pre>background: red</pre> (missing a trailing semi-colon)\n *   <li><pre>background:</pre> (missing a value and a trailing semi-colon)\n *   <li><pre>1em</pre> (missing an attribute name, which provides context for\n *       the value)\n * </ul>\n *\n * @see SafeStyle#create\n * @see SafeStyle#fromConstant\n * @see http://www.w3.org/TR/css3-syntax/\n * @final\n * @struct\n * @implements {TypedString}\n */\nclass SafeStyle {\n  /**\n   * @param {string} value\n   * @param {!Object} token package-internal implementation detail.\n   */\n  constructor(value, token) {\n    /**\n     * The contained value of this SafeStyle.  The field has a purposely\n     * ugly name to make (non-compiled) code that attempts to directly access\n     * this field stand out.\n     * @private {string}\n     */\n    this.privateDoNotAccessOrElseSafeStyleWrappedValue_ =\n        (token === CONSTRUCTOR_TOKEN_PRIVATE) ? value : '';\n\n    /**\n     * @override\n     * @const {boolean}\n     */\n    this.implementsGoogStringTypedString = true;\n  }\n\n\n  /**\n   * Creates a SafeStyle object from a compile-time constant string.\n   *\n   * `style` should be in the format\n   * `name: value; [name: value; ...]` and must not have any < or >\n   * characters in it. This is so that SafeStyle's contract is preserved,\n   * allowing the SafeStyle to correctly be interpreted as a sequence of CSS\n   * declarations and without affecting the syntactic structure of any\n   * surrounding CSS and HTML.\n   *\n   * This method performs basic sanity checks on the format of `style`\n   * but does not constrain the format of `name` and `value`, except\n   * for disallowing tag characters.\n   *\n   * @param {!Const} style A compile-time-constant string from which\n   *     to create a SafeStyle.\n   * @return {!SafeStyle} A SafeStyle object initialized to\n   *     `style`.\n   */\n  static fromConstant(style) {\n    const styleString = Const.unwrap(style);\n    if (styleString.length === 0) {\n      return SafeStyle.EMPTY;\n    }\n    assert(\n        endsWith(styleString, ';'),\n        `Last character of style string is not ';': ${styleString}`);\n    assert(\n        contains(styleString, ':'),\n        'Style string must contain at least one \\':\\', to ' +\n            'specify a \"name: value\" pair: ' + styleString);\n    return SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(\n        styleString);\n  };\n\n\n  /**\n   * Returns this SafeStyle's value as a string.\n   *\n   * IMPORTANT: In code where it is security relevant that an object's type is\n   * indeed `SafeStyle`, use `SafeStyle.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 the returned instance is of the right type. For example:\n   *\n   * <pre>\n   * var fakeSafeHtml = new String('fake');\n   * fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype;\n   * var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml);\n   * // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by\n   * // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml\n   * // instanceof goog.html.SafeHtml.\n   * </pre>\n   *\n   * @return {string}\n   * @see SafeStyle#unwrap\n   * @override\n   */\n  getTypedStringValue() {\n    return this.privateDoNotAccessOrElseSafeStyleWrappedValue_;\n  }\n\n\n  /**\n   * Returns a string-representation of this value.\n   *\n   * To obtain the actual string value wrapped in a SafeStyle, use\n   * `SafeStyle.unwrap`.\n   *\n   * @return {string}\n   * @see SafeStyle#unwrap\n   * @override\n   */\n  toString() {\n    return this.privateDoNotAccessOrElseSafeStyleWrappedValue_.toString();\n  }\n\n\n  /**\n   * Performs a runtime check that the provided object is indeed a\n   * SafeStyle object, and returns its value.\n   *\n   * @param {!SafeStyle} safeStyle The object to extract from.\n   * @return {string} The safeStyle object's contained string, unless\n   *     the run-time type check fails. In that case, `unwrap` returns an\n   *     innocuous string, or, if assertions are enabled, throws\n   *     `AssertionError`.\n   */\n  static unwrap(safeStyle) {\n    // Perform additional Run-time type-checking to ensure that\n    // safeStyle is indeed an instance of the expected type.  This\n    // provides some additional protection against security bugs due to\n    // application code that disables type checks.\n    // 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 (safeStyle instanceof SafeStyle && safeStyle.constructor === SafeStyle) {\n      return safeStyle.privateDoNotAccessOrElseSafeStyleWrappedValue_;\n    } else {\n      fail(\n          `expected object of type SafeStyle, got '${safeStyle}` +\n          '\\' of type ' + goog.typeOf(safeStyle));\n      return 'type_error:SafeStyle';\n    }\n  }\n\n\n  /**\n   * Package-internal utility method to create SafeStyle instances.\n   *\n   * @param {string} style The string to initialize the SafeStyle object with.\n   * @return {!SafeStyle} The initialized SafeStyle object.\n   * @package\n   */\n  static createSafeStyleSecurityPrivateDoNotAccessOrElse(style) {\n    return new SafeStyle(style, CONSTRUCTOR_TOKEN_PRIVATE);\n  }\n\n  /**\n   * Creates a new SafeStyle object from the properties specified in the map.\n   * @param {!SafeStyle.PropertyMap} map Mapping of property names to\n   *     their values, for example {'margin': '1px'}. Names must consist of\n   *     [-_a-zA-Z0-9]. Values might be strings consisting of\n   *     [-,.'\"%_!# a-zA-Z0-9[\\]], where \", ', and [] must be properly balanced.\n   *     We also allow simple functions like rgb() and url() which sanitizes its\n   *     contents. Other values must be wrapped in Const. URLs might\n   *     be passed as SafeUrl which will be wrapped into url(\"\"). We\n   *     also support array whose elements are joined with ' '. Null value\n   * causes skipping the property.\n   * @return {!SafeStyle}\n   * @throws {!Error} If invalid name is provided.\n   * @throws {!AssertionError} If invalid value is provided. With\n   *     disabled assertions, invalid value is replaced by\n   *     SafeStyle.INNOCUOUS_STRING.\n   */\n  static create(map) {\n    let style = '';\n    for (let name in map) {\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(map, name)) {\n        if (!/^[-_a-zA-Z0-9]+$/.test(name)) {\n          throw new Error(`Name allows only [-_a-zA-Z0-9], got: ${name}`);\n        }\n        let value = map[name];\n        if (value == null) {\n          continue;\n        }\n        if (Array.isArray(value)) {\n          value = value.map(sanitizePropertyValue).join(' ');\n        } else {\n          value = sanitizePropertyValue(value);\n        }\n        style += `${name}:${value};`;\n      }\n    }\n    if (!style) {\n      return SafeStyle.EMPTY;\n    }\n    return SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(style);\n  };\n\n  /**\n   * Creates a new SafeStyle object by concatenating the values.\n   * @param {...(!SafeStyle|!Array<!SafeStyle>)} var_args\n   *     SafeStyles to concatenate.\n   * @return {!SafeStyle}\n   */\n  static concat(var_args) {\n    let style = '';\n\n    /**\n     * @param {!SafeStyle|!Array<!SafeStyle>} argument\n     */\n    const addArgument = argument => {\n      if (Array.isArray(argument)) {\n        argument.forEach(addArgument);\n      } else {\n        style += SafeStyle.unwrap(argument);\n      }\n    };\n\n    Array.prototype.forEach.call(arguments, addArgument);\n    if (!style) {\n      return SafeStyle.EMPTY;\n    }\n    return SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(style);\n  };\n}\n\n/**\n * A SafeStyle instance corresponding to the empty string.\n * @const {!SafeStyle}\n */\nSafeStyle.EMPTY = SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse('');\n\n\n/**\n * The innocuous string generated by SafeStyle.create when passed\n * an unsafe value.\n * @const {string}\n */\nSafeStyle.INNOCUOUS_STRING = 'zClosurez';\n\n\n/**\n * A single property value.\n * @typedef {string|!Const|!SafeUrl}\n */\nSafeStyle.PropertyValue;\n\n\n/**\n * Mapping of property names to their values.\n * We don't support numbers even though some values might be numbers (e.g.\n * line-height or 0 for any length). The reason is that most numeric values need\n * units (e.g. '1px') and allowing numbers could cause users forgetting about\n * them.\n * @typedef {!Object<string, ?SafeStyle.PropertyValue|\n *     ?Array<!SafeStyle.PropertyValue>>}\n */\nSafeStyle.PropertyMap;\n\n\n\n/**\n * Checks and converts value to string.\n * @param {!SafeStyle.PropertyValue} value\n * @return {string}\n */\nfunction sanitizePropertyValue(value) {\n  if (value instanceof SafeUrl) {\n    const url = SafeUrl.unwrap(value);\n    return 'url(\"' + url.replace(/</g, '%3c').replace(/[\\\\\"]/g, '\\\\$&') + '\")';\n  }\n  const result = value instanceof Const ?\n      Const.unwrap(value) :\n      sanitizePropertyValueString(String(value));\n  // These characters can be used to change context and we don't want that even\n  // with const values.\n  if (/[{;}]/.test(result)) {\n    throw new AssertionError('Value does not allow [{;}], got: %s.', [result]);\n  }\n  return result;\n}\n\n\n/**\n * Checks string value.\n * @param {string} value\n * @return {string}\n */\nfunction sanitizePropertyValueString(value) {\n  // Some CSS property values permit nested functions. We allow one level of\n  // nesting, and all nested functions must also be in the FUNCTIONS_RE_ list.\n  const valueWithoutFunctions = value.replace(FUNCTIONS_RE, '$1')\n                                    .replace(FUNCTIONS_RE, '$1')\n                                    .replace(URL_RE, 'url');\n  if (!VALUE_RE.test(valueWithoutFunctions)) {\n    fail(\n        `String value allows only ${VALUE_ALLOWED_CHARS}` +\n        ' and simple functions, got: ' + value);\n    return SafeStyle.INNOCUOUS_STRING;\n  } else if (COMMENT_RE.test(value)) {\n    fail(`String value disallows comments, got: ${value}`);\n    return SafeStyle.INNOCUOUS_STRING;\n  } else if (!hasBalancedQuotes(value)) {\n    fail(`String value requires balanced quotes, got: ${value}`);\n    return SafeStyle.INNOCUOUS_STRING;\n  } else if (!hasBalancedSquareBrackets(value)) {\n    fail(\n        'String value requires balanced square brackets and one' +\n        ' identifier per pair of brackets, got: ' + value);\n    return SafeStyle.INNOCUOUS_STRING;\n  }\n  return sanitizeUrl(value);\n}\n\n\n/**\n * Checks that quotes (\" and ') are properly balanced inside a string. Assumes\n * that neither escape (\\) nor any other character that could result in\n * breaking out of a string parsing context are allowed;\n * see http://www.w3.org/TR/css3-syntax/#string-token-diagram.\n * @param {string} value Untrusted CSS property value.\n * @return {boolean} True if property value is safe with respect to quote\n *     balancedness.\n */\nfunction hasBalancedQuotes(value) {\n  let outsideSingle = true;\n  let outsideDouble = true;\n  for (let i = 0; i < value.length; i++) {\n    const c = value.charAt(i);\n    if (c == '\\'' && outsideDouble) {\n      outsideSingle = !outsideSingle;\n    } else if (c == '\"' && outsideSingle) {\n      outsideDouble = !outsideDouble;\n    }\n  }\n  return outsideSingle && outsideDouble;\n}\n\n\n/**\n * Checks that square brackets ([ and ]) are properly balanced inside a string,\n * and that the content in the square brackets is one ident-token;\n * see https://www.w3.org/TR/css-syntax-3/#ident-token-diagram.\n * For practicality, and in line with other restrictions posed on SafeStyle\n * strings, we restrict the character set allowable in the ident-token to\n * [-_a-zA-Z0-9].\n * @param {string} value Untrusted CSS property value.\n * @return {boolean} True if property value is safe with respect to square\n *     bracket balancedness.\n */\nfunction hasBalancedSquareBrackets(value) {\n  let outside = true;\n  const tokenRe = /^[-_a-zA-Z0-9]$/;\n  for (let i = 0; i < value.length; i++) {\n    const c = value.charAt(i);\n    if (c == ']') {\n      if (outside) return false;  // Unbalanced ].\n      outside = true;\n    } else if (c == '[') {\n      if (!outside) return false;  // No nesting.\n      outside = false;\n    } else if (!outside && !tokenRe.test(c)) {\n      return false;\n    }\n  }\n  return outside;\n}\n\n\n/**\n * Characters allowed in VALUE_RE.\n * @type {string}\n */\nconst VALUE_ALLOWED_CHARS = '[-+,.\"\\'%_!#/ a-zA-Z0-9\\\\[\\\\]]';\n\n\n/**\n * Regular expression for safe values.\n * Quotes (\" and ') are allowed, but a check must be done elsewhere to ensure\n * they're balanced.\n * Square brackets ([ and ]) are allowed, but a check must be done elsewhere\n * to ensure they're balanced. The content inside a pair of square brackets must\n * be one alphanumeric identifier.\n * ',' allows multiple values to be assigned to the same property\n * (e.g. background-attachment or font-family) and hence could allow\n * multiple values to get injected, but that should pose no risk of XSS.\n * The expression checks only for XSS safety, not for CSS validity.\n * @const {!RegExp}\n */\nconst VALUE_RE = new RegExp(`^${VALUE_ALLOWED_CHARS}+\\$`);\n\n\n/**\n * Regular expression for url(). We support URLs allowed by\n * https://www.w3.org/TR/css-syntax-3/#url-token-diagram without using escape\n * sequences. Use percent-encoding if you need to use special characters like\n * backslash.\n * @const {!RegExp}\n */\nconst URL_RE = new RegExp(\n    '\\\\b(url\\\\([ \\t\\n]*)(' +\n        '\\'[ -&(-\\\\[\\\\]-~]*\\'' +  // Printable characters except ' and \\.\n        '|\"[ !#-\\\\[\\\\]-~]*\"' +    // Printable characters except \" and \\.\n        '|[!#-&*-\\\\[\\\\]-~]*' +    // Printable characters except [ \"'()\\\\].\n        ')([ \\t\\n]*\\\\))',\n    'g');\n\n/**\n * Names of functions allowed in FUNCTIONS_RE.\n * @const {!Array<string>}\n */\nconst ALLOWED_FUNCTIONS = [\n  'calc',\n  'cubic-bezier',\n  'fit-content',\n  'hsl',\n  'hsla',\n  'linear-gradient',\n  'matrix',\n  'minmax',\n  'radial-gradient',\n  'repeat',\n  'rgb',\n  'rgba',\n  '(rotate|scale|translate)(X|Y|Z|3d)?',\n  'steps',\n  'var',\n];\n\n\n/**\n * Regular expression for simple functions.\n * @const {!RegExp}\n */\nconst FUNCTIONS_RE = new RegExp(\n    '\\\\b(' + ALLOWED_FUNCTIONS.join('|') + ')' +\n        '\\\\([-+*/0-9a-zA-Z.%#\\\\[\\\\], ]+\\\\)',\n    'g');\n\n\n/**\n * Regular expression for comments. These are disallowed in CSS property values.\n * @const {!RegExp}\n */\nconst COMMENT_RE = /\\/\\*/;\n\n\n/**\n * Sanitize URLs inside url().\n * NOTE: We could also consider using CSS.escape once that's available in the\n * browsers. However, loosely matching URL e.g. with url\\(.*\\) and then escaping\n * the contents would result in a slightly different language than CSS leading\n * to confusion of users. E.g. url(\")\") is valid in CSS but it would be invalid\n * as seen by our parser. On the other hand, url(\\) is invalid in CSS but our\n * parser would be fine with it.\n * @param {string} value Untrusted CSS property value.\n * @return {string}\n */\nfunction sanitizeUrl(value) {\n  return value.replace(URL_RE, (match, before, url, after) => {\n    let quote = '';\n    url = url.replace(/^(['\"])(.*)\\1$/, (match, start, inside) => {\n      quote = start;\n      return inside;\n    });\n    const sanitized = SafeUrl.sanitize(url).getTypedStringValue();\n    return before + quote + sanitized + quote + after;\n  });\n}\n\n\nexports = SafeStyle;\n","~:compiled-at",1684858197880,"~:source-map-json","{\n\"version\":3,\n\"file\":\"goog.html.safestyle.js\",\n\"lineCount\":168,\n\"mappings\":\"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\",\n\"sources\":[\"goog/html/safestyle.js\"],\n\"sourcesContent\":[\"/**\\n * @license\\n * Copyright The Closure Library Authors.\\n * SPDX-License-Identifier: Apache-2.0\\n */\\n\\n/**\\n * @fileoverview The SafeStyle type and its builders.\\n *\\n * TODO(xtof): Link to document stating type contract.\\n */\\n\\ngoog.module('goog.html.SafeStyle');\\ngoog.module.declareLegacyNamespace();\\n\\nconst Const = goog.require('goog.string.Const');\\nconst SafeUrl = goog.require('goog.html.SafeUrl');\\nconst TypedString = goog.require('goog.string.TypedString');\\nconst {AssertionError, assert, fail} = goog.require('goog.asserts');\\nconst {contains, endsWith} = goog.require('goog.string.internal');\\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-like object which represents a sequence of CSS declarations\\n * (`propertyName1: propertyvalue1; propertyName2: propertyValue2; ...`)\\n * and that carries the security type contract that its value, as a string,\\n * will not cause untrusted script execution (XSS) when evaluated as CSS in a\\n * browser.\\n *\\n * Instances of this type must be created via the factory methods\\n * (`SafeStyle.create` or `SafeStyle.fromConstant`)\\n * and not by invoking its constructor. The constructor intentionally takes an\\n * extra parameter that cannot be constructed outside of this file and the type\\n * is immutable; hence only a default instance corresponding to the empty string\\n * can be obtained via constructor invocation.\\n *\\n * SafeStyle's string representation can safely be:\\n * <ul>\\n *   <li>Interpolated as the content of a *quoted* HTML style attribute.\\n *       However, the SafeStyle string *must be HTML-attribute-escaped* before\\n *       interpolation.\\n *   <li>Interpolated as the content of a {}-wrapped block within a stylesheet.\\n *       '<' characters in the SafeStyle string *must be CSS-escaped* before\\n *       interpolation. The SafeStyle string is also guaranteed not to be able\\n *       to introduce new properties or elide existing ones.\\n *   <li>Interpolated as the content of a {}-wrapped block within an HTML\\n *       &lt;style&gt; element. '<' characters in the SafeStyle string\\n *       *must be CSS-escaped* before interpolation.\\n *   <li>Assigned to the style property of a DOM node. The SafeStyle string\\n *       should not be escaped before being assigned to the property.\\n * </ul>\\n *\\n * A SafeStyle may never contain literal angle brackets. Otherwise, it could\\n * be unsafe to place a SafeStyle into a &lt;style&gt; tag (where it can't\\n * be HTML escaped). For example, if the SafeStyle containing\\n * `font: 'foo &lt;style/&gt;&lt;script&gt;evil&lt;/script&gt;'` were\\n * interpolated within a &lt;style&gt; tag, this would then break out of the\\n * style context into HTML.\\n *\\n * A SafeStyle may contain literal single or double quotes, and as such the\\n * entire style string must be escaped when used in a style attribute (if\\n * this were not the case, the string could contain a matching quote that\\n * would escape from the style attribute).\\n *\\n * Values of this type must be composable, i.e. for any two values\\n * `style1` and `style2` of this type,\\n * `SafeStyle.unwrap(style1) +\\n * SafeStyle.unwrap(style2)` must itself be a value that satisfies\\n * the SafeStyle type constraint. This requirement implies that for any value\\n * `style` of this type, `SafeStyle.unwrap(style)` must\\n * not end in a \\\"property value\\\" or \\\"property name\\\" context. For example,\\n * a value of `background:url(\\\"` or `font-` would not satisfy the\\n * SafeStyle contract. This is because concatenating such strings with a\\n * second value that itself does not contain unsafe CSS can result in an\\n * overall string that does. For example, if `javascript:evil())\\\"` is\\n * appended to `background:url(\\\"}, the resulting string may result in\\n * the execution of a malicious script.\\n *\\n * TODO(mlourenco): Consider whether we should implement UTF-8 interchange\\n * validity checks and blacklisting of newlines (including Unicode ones) and\\n * other whitespace characters (\\\\t, \\\\f). Document here if so and also update\\n * SafeStyle.fromConstant().\\n *\\n * The following example values comply with this type's contract:\\n * <ul>\\n *   <li><pre>width: 1em;</pre>\\n *   <li><pre>height:1em;</pre>\\n *   <li><pre>width: 1em;height: 1em;</pre>\\n *   <li><pre>background:url('http://url');</pre>\\n * </ul>\\n * In addition, the empty string is safe for use in a CSS attribute.\\n *\\n * The following example values do NOT comply with this type's contract:\\n * <ul>\\n *   <li><pre>background: red</pre> (missing a trailing semi-colon)\\n *   <li><pre>background:</pre> (missing a value and a trailing semi-colon)\\n *   <li><pre>1em</pre> (missing an attribute name, which provides context for\\n *       the value)\\n * </ul>\\n *\\n * @see SafeStyle#create\\n * @see SafeStyle#fromConstant\\n * @see http://www.w3.org/TR/css3-syntax/\\n * @final\\n * @struct\\n * @implements {TypedString}\\n */\\nclass SafeStyle {\\n  /**\\n   * @param {string} value\\n   * @param {!Object} token package-internal implementation detail.\\n   */\\n  constructor(value, token) {\\n    /**\\n     * The contained value of this SafeStyle.  The field has a purposely\\n     * ugly name to make (non-compiled) code that attempts to directly access\\n     * this field stand out.\\n     * @private {string}\\n     */\\n    this.privateDoNotAccessOrElseSafeStyleWrappedValue_ =\\n        (token === CONSTRUCTOR_TOKEN_PRIVATE) ? value : '';\\n\\n    /**\\n     * @override\\n     * @const {boolean}\\n     */\\n    this.implementsGoogStringTypedString = true;\\n  }\\n\\n\\n  /**\\n   * Creates a SafeStyle object from a compile-time constant string.\\n   *\\n   * `style` should be in the format\\n   * `name: value; [name: value; ...]` and must not have any < or >\\n   * characters in it. This is so that SafeStyle's contract is preserved,\\n   * allowing the SafeStyle to correctly be interpreted as a sequence of CSS\\n   * declarations and without affecting the syntactic structure of any\\n   * surrounding CSS and HTML.\\n   *\\n   * This method performs basic sanity checks on the format of `style`\\n   * but does not constrain the format of `name` and `value`, except\\n   * for disallowing tag characters.\\n   *\\n   * @param {!Const} style A compile-time-constant string from which\\n   *     to create a SafeStyle.\\n   * @return {!SafeStyle} A SafeStyle object initialized to\\n   *     `style`.\\n   */\\n  static fromConstant(style) {\\n    const styleString = Const.unwrap(style);\\n    if (styleString.length === 0) {\\n      return SafeStyle.EMPTY;\\n    }\\n    assert(\\n        endsWith(styleString, ';'),\\n        `Last character of style string is not ';': ${styleString}`);\\n    assert(\\n        contains(styleString, ':'),\\n        'Style string must contain at least one \\\\':\\\\', to ' +\\n            'specify a \\\"name: value\\\" pair: ' + styleString);\\n    return SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(\\n        styleString);\\n  };\\n\\n\\n  /**\\n   * Returns this SafeStyle's value as a string.\\n   *\\n   * IMPORTANT: In code where it is security relevant that an object's type is\\n   * indeed `SafeStyle`, use `SafeStyle.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 the returned instance is of the right type. For example:\\n   *\\n   * <pre>\\n   * var fakeSafeHtml = new String('fake');\\n   * fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype;\\n   * var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml);\\n   * // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by\\n   * // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml\\n   * // instanceof goog.html.SafeHtml.\\n   * </pre>\\n   *\\n   * @return {string}\\n   * @see SafeStyle#unwrap\\n   * @override\\n   */\\n  getTypedStringValue() {\\n    return this.privateDoNotAccessOrElseSafeStyleWrappedValue_;\\n  }\\n\\n\\n  /**\\n   * Returns a string-representation of this value.\\n   *\\n   * To obtain the actual string value wrapped in a SafeStyle, use\\n   * `SafeStyle.unwrap`.\\n   *\\n   * @return {string}\\n   * @see SafeStyle#unwrap\\n   * @override\\n   */\\n  toString() {\\n    return this.privateDoNotAccessOrElseSafeStyleWrappedValue_.toString();\\n  }\\n\\n\\n  /**\\n   * Performs a runtime check that the provided object is indeed a\\n   * SafeStyle object, and returns its value.\\n   *\\n   * @param {!SafeStyle} safeStyle The object to extract from.\\n   * @return {string} The safeStyle object's contained string, unless\\n   *     the run-time type check fails. In that case, `unwrap` returns an\\n   *     innocuous string, or, if assertions are enabled, throws\\n   *     `AssertionError`.\\n   */\\n  static unwrap(safeStyle) {\\n    // Perform additional Run-time type-checking to ensure that\\n    // safeStyle is indeed an instance of the expected type.  This\\n    // provides some additional protection against security bugs due to\\n    // application code that disables type checks.\\n    // 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 (safeStyle instanceof SafeStyle && safeStyle.constructor === SafeStyle) {\\n      return safeStyle.privateDoNotAccessOrElseSafeStyleWrappedValue_;\\n    } else {\\n      fail(\\n          `expected object of type SafeStyle, got '${safeStyle}` +\\n          '\\\\' of type ' + goog.typeOf(safeStyle));\\n      return 'type_error:SafeStyle';\\n    }\\n  }\\n\\n\\n  /**\\n   * Package-internal utility method to create SafeStyle instances.\\n   *\\n   * @param {string} style The string to initialize the SafeStyle object with.\\n   * @return {!SafeStyle} The initialized SafeStyle object.\\n   * @package\\n   */\\n  static createSafeStyleSecurityPrivateDoNotAccessOrElse(style) {\\n    return new SafeStyle(style, CONSTRUCTOR_TOKEN_PRIVATE);\\n  }\\n\\n  /**\\n   * Creates a new SafeStyle object from the properties specified in the map.\\n   * @param {!SafeStyle.PropertyMap} map Mapping of property names to\\n   *     their values, for example {'margin': '1px'}. Names must consist of\\n   *     [-_a-zA-Z0-9]. Values might be strings consisting of\\n   *     [-,.'\\\"%_!# a-zA-Z0-9[\\\\]], where \\\", ', and [] must be properly balanced.\\n   *     We also allow simple functions like rgb() and url() which sanitizes its\\n   *     contents. Other values must be wrapped in Const. URLs might\\n   *     be passed as SafeUrl which will be wrapped into url(\\\"\\\"). We\\n   *     also support array whose elements are joined with ' '. Null value\\n   * causes skipping the property.\\n   * @return {!SafeStyle}\\n   * @throws {!Error} If invalid name is provided.\\n   * @throws {!AssertionError} If invalid value is provided. With\\n   *     disabled assertions, invalid value is replaced by\\n   *     SafeStyle.INNOCUOUS_STRING.\\n   */\\n  static create(map) {\\n    let style = '';\\n    for (let name in map) {\\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(map, name)) {\\n        if (!/^[-_a-zA-Z0-9]+$/.test(name)) {\\n          throw new Error(`Name allows only [-_a-zA-Z0-9], got: ${name}`);\\n        }\\n        let value = map[name];\\n        if (value == null) {\\n          continue;\\n        }\\n        if (Array.isArray(value)) {\\n          value = value.map(sanitizePropertyValue).join(' ');\\n        } else {\\n          value = sanitizePropertyValue(value);\\n        }\\n        style += `${name}:${value};`;\\n      }\\n    }\\n    if (!style) {\\n      return SafeStyle.EMPTY;\\n    }\\n    return SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(style);\\n  };\\n\\n  /**\\n   * Creates a new SafeStyle object by concatenating the values.\\n   * @param {...(!SafeStyle|!Array<!SafeStyle>)} var_args\\n   *     SafeStyles to concatenate.\\n   * @return {!SafeStyle}\\n   */\\n  static concat(var_args) {\\n    let style = '';\\n\\n    /**\\n     * @param {!SafeStyle|!Array<!SafeStyle>} argument\\n     */\\n    const addArgument = argument => {\\n      if (Array.isArray(argument)) {\\n        argument.forEach(addArgument);\\n      } else {\\n        style += SafeStyle.unwrap(argument);\\n      }\\n    };\\n\\n    Array.prototype.forEach.call(arguments, addArgument);\\n    if (!style) {\\n      return SafeStyle.EMPTY;\\n    }\\n    return SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(style);\\n  };\\n}\\n\\n/**\\n * A SafeStyle instance corresponding to the empty string.\\n * @const {!SafeStyle}\\n */\\nSafeStyle.EMPTY = SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse('');\\n\\n\\n/**\\n * The innocuous string generated by SafeStyle.create when passed\\n * an unsafe value.\\n * @const {string}\\n */\\nSafeStyle.INNOCUOUS_STRING = 'zClosurez';\\n\\n\\n/**\\n * A single property value.\\n * @typedef {string|!Const|!SafeUrl}\\n */\\nSafeStyle.PropertyValue;\\n\\n\\n/**\\n * Mapping of property names to their values.\\n * We don't support numbers even though some values might be numbers (e.g.\\n * line-height or 0 for any length). The reason is that most numeric values need\\n * units (e.g. '1px') and allowing numbers could cause users forgetting about\\n * them.\\n * @typedef {!Object<string, ?SafeStyle.PropertyValue|\\n *     ?Array<!SafeStyle.PropertyValue>>}\\n */\\nSafeStyle.PropertyMap;\\n\\n\\n\\n/**\\n * Checks and converts value to string.\\n * @param {!SafeStyle.PropertyValue} value\\n * @return {string}\\n */\\nfunction sanitizePropertyValue(value) {\\n  if (value instanceof SafeUrl) {\\n    const url = SafeUrl.unwrap(value);\\n    return 'url(\\\"' + url.replace(/</g, '%3c').replace(/[\\\\\\\\\\\"]/g, '\\\\\\\\$&') + '\\\")';\\n  }\\n  const result = value instanceof Const ?\\n      Const.unwrap(value) :\\n      sanitizePropertyValueString(String(value));\\n  // These characters can be used to change context and we don't want that even\\n  // with const values.\\n  if (/[{;}]/.test(result)) {\\n    throw new AssertionError('Value does not allow [{;}], got: %s.', [result]);\\n  }\\n  return result;\\n}\\n\\n\\n/**\\n * Checks string value.\\n * @param {string} value\\n * @return {string}\\n */\\nfunction sanitizePropertyValueString(value) {\\n  // Some CSS property values permit nested functions. We allow one level of\\n  // nesting, and all nested functions must also be in the FUNCTIONS_RE_ list.\\n  const valueWithoutFunctions = value.replace(FUNCTIONS_RE, '$1')\\n                                    .replace(FUNCTIONS_RE, '$1')\\n                                    .replace(URL_RE, 'url');\\n  if (!VALUE_RE.test(valueWithoutFunctions)) {\\n    fail(\\n        `String value allows only ${VALUE_ALLOWED_CHARS}` +\\n        ' and simple functions, got: ' + value);\\n    return SafeStyle.INNOCUOUS_STRING;\\n  } else if (COMMENT_RE.test(value)) {\\n    fail(`String value disallows comments, got: ${value}`);\\n    return SafeStyle.INNOCUOUS_STRING;\\n  } else if (!hasBalancedQuotes(value)) {\\n    fail(`String value requires balanced quotes, got: ${value}`);\\n    return SafeStyle.INNOCUOUS_STRING;\\n  } else if (!hasBalancedSquareBrackets(value)) {\\n    fail(\\n        'String value requires balanced square brackets and one' +\\n        ' identifier per pair of brackets, got: ' + value);\\n    return SafeStyle.INNOCUOUS_STRING;\\n  }\\n  return sanitizeUrl(value);\\n}\\n\\n\\n/**\\n * Checks that quotes (\\\" and ') are properly balanced inside a string. Assumes\\n * that neither escape (\\\\) nor any other character that could result in\\n * breaking out of a string parsing context are allowed;\\n * see http://www.w3.org/TR/css3-syntax/#string-token-diagram.\\n * @param {string} value Untrusted CSS property value.\\n * @return {boolean} True if property value is safe with respect to quote\\n *     balancedness.\\n */\\nfunction hasBalancedQuotes(value) {\\n  let outsideSingle = true;\\n  let outsideDouble = true;\\n  for (let i = 0; i < value.length; i++) {\\n    const c = value.charAt(i);\\n    if (c == '\\\\'' && outsideDouble) {\\n      outsideSingle = !outsideSingle;\\n    } else if (c == '\\\"' && outsideSingle) {\\n      outsideDouble = !outsideDouble;\\n    }\\n  }\\n  return outsideSingle && outsideDouble;\\n}\\n\\n\\n/**\\n * Checks that square brackets ([ and ]) are properly balanced inside a string,\\n * and that the content in the square brackets is one ident-token;\\n * see https://www.w3.org/TR/css-syntax-3/#ident-token-diagram.\\n * For practicality, and in line with other restrictions posed on SafeStyle\\n * strings, we restrict the character set allowable in the ident-token to\\n * [-_a-zA-Z0-9].\\n * @param {string} value Untrusted CSS property value.\\n * @return {boolean} True if property value is safe with respect to square\\n *     bracket balancedness.\\n */\\nfunction hasBalancedSquareBrackets(value) {\\n  let outside = true;\\n  const tokenRe = /^[-_a-zA-Z0-9]$/;\\n  for (let i = 0; i < value.length; i++) {\\n    const c = value.charAt(i);\\n    if (c == ']') {\\n      if (outside) return false;  // Unbalanced ].\\n      outside = true;\\n    } else if (c == '[') {\\n      if (!outside) return false;  // No nesting.\\n      outside = false;\\n    } else if (!outside && !tokenRe.test(c)) {\\n      return false;\\n    }\\n  }\\n  return outside;\\n}\\n\\n\\n/**\\n * Characters allowed in VALUE_RE.\\n * @type {string}\\n */\\nconst VALUE_ALLOWED_CHARS = '[-+,.\\\"\\\\'%_!#/ a-zA-Z0-9\\\\\\\\[\\\\\\\\]]';\\n\\n\\n/**\\n * Regular expression for safe values.\\n * Quotes (\\\" and ') are allowed, but a check must be done elsewhere to ensure\\n * they're balanced.\\n * Square brackets ([ and ]) are allowed, but a check must be done elsewhere\\n * to ensure they're balanced. The content inside a pair of square brackets must\\n * be one alphanumeric identifier.\\n * ',' allows multiple values to be assigned to the same property\\n * (e.g. background-attachment or font-family) and hence could allow\\n * multiple values to get injected, but that should pose no risk of XSS.\\n * The expression checks only for XSS safety, not for CSS validity.\\n * @const {!RegExp}\\n */\\nconst VALUE_RE = new RegExp(`^${VALUE_ALLOWED_CHARS}+\\\\$`);\\n\\n\\n/**\\n * Regular expression for url(). We support URLs allowed by\\n * https://www.w3.org/TR/css-syntax-3/#url-token-diagram without using escape\\n * sequences. Use percent-encoding if you need to use special characters like\\n * backslash.\\n * @const {!RegExp}\\n */\\nconst URL_RE = new RegExp(\\n    '\\\\\\\\b(url\\\\\\\\([ \\\\t\\\\n]*)(' +\\n        '\\\\'[ -&(-\\\\\\\\[\\\\\\\\]-~]*\\\\'' +  // Printable characters except ' and \\\\.\\n        '|\\\"[ !#-\\\\\\\\[\\\\\\\\]-~]*\\\"' +    // Printable characters except \\\" and \\\\.\\n        '|[!#-&*-\\\\\\\\[\\\\\\\\]-~]*' +    // Printable characters except [ \\\"'()\\\\\\\\].\\n        ')([ \\\\t\\\\n]*\\\\\\\\))',\\n    'g');\\n\\n/**\\n * Names of functions allowed in FUNCTIONS_RE.\\n * @const {!Array<string>}\\n */\\nconst ALLOWED_FUNCTIONS = [\\n  'calc',\\n  'cubic-bezier',\\n  'fit-content',\\n  'hsl',\\n  'hsla',\\n  'linear-gradient',\\n  'matrix',\\n  'minmax',\\n  'radial-gradient',\\n  'repeat',\\n  'rgb',\\n  'rgba',\\n  '(rotate|scale|translate)(X|Y|Z|3d)?',\\n  'steps',\\n  'var',\\n];\\n\\n\\n/**\\n * Regular expression for simple functions.\\n * @const {!RegExp}\\n */\\nconst FUNCTIONS_RE = new RegExp(\\n    '\\\\\\\\b(' + ALLOWED_FUNCTIONS.join('|') + ')' +\\n        '\\\\\\\\([-+*/0-9a-zA-Z.%#\\\\\\\\[\\\\\\\\], ]+\\\\\\\\)',\\n    'g');\\n\\n\\n/**\\n * Regular expression for comments. These are disallowed in CSS property values.\\n * @const {!RegExp}\\n */\\nconst COMMENT_RE = /\\\\/\\\\*/;\\n\\n\\n/**\\n * Sanitize URLs inside url().\\n * NOTE: We could also consider using CSS.escape once that's available in the\\n * browsers. However, loosely matching URL e.g. with url\\\\(.*\\\\) and then escaping\\n * the contents would result in a slightly different language than CSS leading\\n * to confusion of users. E.g. url(\\\")\\\") is valid in CSS but it would be invalid\\n * as seen by our parser. On the other hand, url(\\\\) is invalid in CSS but our\\n * parser would be fine with it.\\n * @param {string} value Untrusted CSS property value.\\n * @return {string}\\n */\\nfunction sanitizeUrl(value) {\\n  return value.replace(URL_RE, (match, before, url, after) => {\\n    let quote = '';\\n    url = url.replace(/^(['\\\"])(.*)\\\\1$/, (match, start, inside) => {\\n      quote = start;\\n      return inside;\\n    });\\n    const sanitized = SafeUrl.sanitize(url).getTypedStringValue();\\n    return before + quote + sanitized + quote + after;\\n  });\\n}\\n\\n\\nexports = SafeStyle;\\n\"],\n\"names\":[\"goog\",\"module\",\"declareLegacyNamespace\",\"Const\",\"require\",\"SafeUrl\",\"TypedString\",\"AssertionError\",\"assert\",\"fail\",\"contains\",\"endsWith\",\"CONSTRUCTOR_TOKEN_PRIVATE\",\"SafeStyle\",\"constructor\",\"value\",\"token\",\"privateDoNotAccessOrElseSafeStyleWrappedValue_\",\"implementsGoogStringTypedString\",\"fromConstant\",\"style\",\"styleString\",\"unwrap\",\"length\",\"EMPTY\",\"createSafeStyleSecurityPrivateDoNotAccessOrElse\",\"getTypedStringValue\",\"toString\",\"safeStyle\",\"typeOf\",\"create\",\"map\",\"name\",\"Object\",\"prototype\",\"hasOwnProperty\",\"call\",\"test\",\"Error\",\"Array\",\"isArray\",\"sanitizePropertyValue\",\"join\",\"concat\",\"var_args\",\"addArgument\",\"argument\",\"forEach\",\"arguments\",\"INNOCUOUS_STRING\",\"PropertyValue\",\"PropertyMap\",\"url\",\"replace\",\"result\",\"sanitizePropertyValueString\",\"String\",\"valueWithoutFunctions\",\"FUNCTIONS_RE\",\"URL_RE\",\"VALUE_RE\",\"VALUE_ALLOWED_CHARS\",\"COMMENT_RE\",\"hasBalancedQuotes\",\"hasBalancedSquareBrackets\",\"sanitizeUrl\",\"outsideSingle\",\"outsideDouble\",\"i\",\"c\",\"charAt\",\"outside\",\"tokenRe\",\"RegExp\",\"ALLOWED_FUNCTIONS\",\"match\",\"before\",\"after\",\"quote\",\"start\",\"inside\",\"sanitized\",\"sanitize\",\"exports\"]\n}\n"]