{
  "version": 3,
  "sources": ["../../../../../node_modules/crypt/crypt.js", "../../../../../node_modules/charenc/charenc.js", "../../../../../node_modules/md5/node_modules/is-buffer/index.js", "../../../../../node_modules/md5/md5.js", "../../src/document/components/chrome/statusBar/versions.ts", "../../src/document/utils/sitesAPI.ts", "../../src/utils/base16.ts", "../../src/utils/sha256.ts", "../../src/document/components/chrome/Pages/utils/getRouteSegmentFullPath.ts", "../../src/utils/fetch.ts", "../../src/web/pages/project/projectChanges.ts", "../../../../shared/src/ssg/ssgData.ts", "../../../../shared/src/ssg/editor.ts", "../../src/document/components/chrome/properties/utils/regenerateModulesForFitImage.ts", "../../src/document/components/chrome/properties/utils/regenerateModulesForLayoutTemplateFlowEffect.ts", "../../src/document/components/chrome/shared/UpsellModal/utils/bandwidthUpsellModals.tsx", "../../src/document/components/chrome/shared/UpsellModal/utils/getCmsCollectionsLimitUpsell.tsx", "../../src/document/components/chrome/shared/UpsellModal/utils/getCmsItemsLimitUpsell.tsx", "../../src/document/components/chrome/shared/UpsellModal/utils/publishMultiPageSiteUpsell.ts", "../../src/document/components/chrome/shared/UpsellModal/utils/getPagesLimitUpsell.ts", "../../src/document/components/chrome/localization/canBeBatchTranslated.ts", "../../src/document/components/chrome/localization/isGroupExcludedInLocale.ts", "../../src/document/components/chrome/localization/localizationSourceGroupUtils.ts", "../../src/document/components/chrome/localization/calculateLocalizationSourceState.ts", "../../src/document/components/chrome/localization/getTranslationLimits.ts", "../../src/document/components/chrome/shared/UpsellModal/utils/localizationUpsellModals.tsx", "../../src/document/components/chrome/shared/UpsellModal/utils/recoverCustomDomainUpsell.ts", "../../src/document/components/chrome/shared/UpsellModal/getUpsell.tsx", "../../src/document/components/chrome/siteSettings/openSupportArticle.ts", "../../src/document/components/chrome/siteSettings/Domains/CustomDomain/customDomainToasts.ts", "../../src/document/components/chrome/siteSettings/SiteSettings.styles.ts", "../../src/document/components/chrome/siteSettings/StatusIndicator.tsx", "../../src/document/models/CanvasTree/nodes/utils/predictRecoverableModules.ts", "../../src/document/utils/publishToastUtils.tsx", "../../src/app/features.ts", "../../src/renderer/setDefaultFont.ts", "../../src/utils/getParsedHTML.ts", "../../src/utils/customHTML.ts", "../../src/export/ExportToHTMLMetrics.ts", "import-bundle:/Users/alex/Projects/FramerStudio/src/app/vekter/src/export/bundled/captureFormsUTMTagsInCookie.ts?bundleSites", "import-bundle:/Users/alex/Projects/FramerStudio/src/app/vekter/src/export/bundled/formatRelativeDate.ts?bundleSites", "import-bundle:/Users/alex/Projects/FramerStudio/src/app/vekter/src/export/bundled/rewriteLinksWithQueryParams.ts?bundleSites", "../../src/web/pages/projects/components/Domains/validation/validateHeader.ts", "../../src/export/routeLocaleExpansion.ts", "../../src/export/collectHeaderRoutes.ts", "../../src/export/collectProxyRoutes.ts", "../../src/export/collectRedirectRoutes.ts", "../../src/export/collectRewriteRoutes.ts", "../../src/export/generateFonts.ts", "../../src/export/getAbTestCumulativeDistributions.ts", "../../src/export/getBundleId.ts", "../../src/export/prepareProjectSnapshotForExport.ts", "../../src/export/exportToHTML.ts", "../../src/document/stores/PublishStore.ts", "../../src/web/pages/project/components/PublishPopover/utils/changeSummary.ts", "../../src/document/stores/SiteSettingsStore.ts", "../../src/document/components/chrome/shared/utils/limitError.ts"],
  "sourcesContent": ["(function() {\n  var base64map\n      = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',\n\n  crypt = {\n    // Bit-wise rotation left\n    rotl: function(n, b) {\n      return (n << b) | (n >>> (32 - b));\n    },\n\n    // Bit-wise rotation right\n    rotr: function(n, b) {\n      return (n << (32 - b)) | (n >>> b);\n    },\n\n    // Swap big-endian to little-endian and vice versa\n    endian: function(n) {\n      // If number given, swap endian\n      if (n.constructor == Number) {\n        return crypt.rotl(n, 8) & 0x00FF00FF | crypt.rotl(n, 24) & 0xFF00FF00;\n      }\n\n      // Else, assume array and swap all items\n      for (var i = 0; i < n.length; i++)\n        n[i] = crypt.endian(n[i]);\n      return n;\n    },\n\n    // Generate an array of any length of random bytes\n    randomBytes: function(n) {\n      for (var bytes = []; n > 0; n--)\n        bytes.push(Math.floor(Math.random() * 256));\n      return bytes;\n    },\n\n    // Convert a byte array to big-endian 32-bit words\n    bytesToWords: function(bytes) {\n      for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8)\n        words[b >>> 5] |= bytes[i] << (24 - b % 32);\n      return words;\n    },\n\n    // Convert big-endian 32-bit words to a byte array\n    wordsToBytes: function(words) {\n      for (var bytes = [], b = 0; b < words.length * 32; b += 8)\n        bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);\n      return bytes;\n    },\n\n    // Convert a byte array to a hex string\n    bytesToHex: function(bytes) {\n      for (var hex = [], i = 0; i < bytes.length; i++) {\n        hex.push((bytes[i] >>> 4).toString(16));\n        hex.push((bytes[i] & 0xF).toString(16));\n      }\n      return hex.join('');\n    },\n\n    // Convert a hex string to a byte array\n    hexToBytes: function(hex) {\n      for (var bytes = [], c = 0; c < hex.length; c += 2)\n        bytes.push(parseInt(hex.substr(c, 2), 16));\n      return bytes;\n    },\n\n    // Convert a byte array to a base-64 string\n    bytesToBase64: function(bytes) {\n      for (var base64 = [], i = 0; i < bytes.length; i += 3) {\n        var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];\n        for (var j = 0; j < 4; j++)\n          if (i * 8 + j * 6 <= bytes.length * 8)\n            base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F));\n          else\n            base64.push('=');\n      }\n      return base64.join('');\n    },\n\n    // Convert a base-64 string to a byte array\n    base64ToBytes: function(base64) {\n      // Remove non-base-64 characters\n      base64 = base64.replace(/[^A-Z0-9+\\/]/ig, '');\n\n      for (var bytes = [], i = 0, imod4 = 0; i < base64.length;\n          imod4 = ++i % 4) {\n        if (imod4 == 0) continue;\n        bytes.push(((base64map.indexOf(base64.charAt(i - 1))\n            & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2))\n            | (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2)));\n      }\n      return bytes;\n    }\n  };\n\n  module.exports = crypt;\n})();\n", "var charenc = {\n  // UTF-8 encoding\n  utf8: {\n    // Convert a string to a byte array\n    stringToBytes: function(str) {\n      return charenc.bin.stringToBytes(unescape(encodeURIComponent(str)));\n    },\n\n    // Convert a byte array to a string\n    bytesToString: function(bytes) {\n      return decodeURIComponent(escape(charenc.bin.bytesToString(bytes)));\n    }\n  },\n\n  // Binary encoding\n  bin: {\n    // Convert a string to a byte array\n    stringToBytes: function(str) {\n      for (var bytes = [], i = 0; i < str.length; i++)\n        bytes.push(str.charCodeAt(i) & 0xFF);\n      return bytes;\n    },\n\n    // Convert a byte array to a string\n    bytesToString: function(bytes) {\n      for (var str = [], i = 0; i < bytes.length; i++)\n        str.push(String.fromCharCode(bytes[i]));\n      return str.join('');\n    }\n  }\n};\n\nmodule.exports = charenc;\n", "/*!\n * Determine if an object is a Buffer\n *\n * @author   Feross Aboukhadijeh <https://feross.org>\n * @license  MIT\n */\n\n// The _isBuffer check is for Safari 5-7 support, because it's missing\n// Object.prototype.constructor. Remove this eventually\nmodule.exports = function (obj) {\n  return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)\n}\n\nfunction isBuffer (obj) {\n  return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)\n}\n\n// For Node v0.10 support. Remove this eventually.\nfunction isSlowBuffer (obj) {\n  return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))\n}\n", "(function(){\r\n  var crypt = require('crypt'),\r\n      utf8 = require('charenc').utf8,\r\n      isBuffer = require('is-buffer'),\r\n      bin = require('charenc').bin,\r\n\r\n  // The core\r\n  md5 = function (message, options) {\r\n    // Convert to byte array\r\n    if (message.constructor == String)\r\n      if (options && options.encoding === 'binary')\r\n        message = bin.stringToBytes(message);\r\n      else\r\n        message = utf8.stringToBytes(message);\r\n    else if (isBuffer(message))\r\n      message = Array.prototype.slice.call(message, 0);\r\n    else if (!Array.isArray(message) && message.constructor !== Uint8Array)\r\n      message = message.toString();\r\n    // else, assume byte array already\r\n\r\n    var m = crypt.bytesToWords(message),\r\n        l = message.length * 8,\r\n        a =  1732584193,\r\n        b = -271733879,\r\n        c = -1732584194,\r\n        d =  271733878;\r\n\r\n    // Swap endian\r\n    for (var i = 0; i < m.length; i++) {\r\n      m[i] = ((m[i] <<  8) | (m[i] >>> 24)) & 0x00FF00FF |\r\n             ((m[i] << 24) | (m[i] >>>  8)) & 0xFF00FF00;\r\n    }\r\n\r\n    // Padding\r\n    m[l >>> 5] |= 0x80 << (l % 32);\r\n    m[(((l + 64) >>> 9) << 4) + 14] = l;\r\n\r\n    // Method shortcuts\r\n    var FF = md5._ff,\r\n        GG = md5._gg,\r\n        HH = md5._hh,\r\n        II = md5._ii;\r\n\r\n    for (var i = 0; i < m.length; i += 16) {\r\n\r\n      var aa = a,\r\n          bb = b,\r\n          cc = c,\r\n          dd = d;\r\n\r\n      a = FF(a, b, c, d, m[i+ 0],  7, -680876936);\r\n      d = FF(d, a, b, c, m[i+ 1], 12, -389564586);\r\n      c = FF(c, d, a, b, m[i+ 2], 17,  606105819);\r\n      b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);\r\n      a = FF(a, b, c, d, m[i+ 4],  7, -176418897);\r\n      d = FF(d, a, b, c, m[i+ 5], 12,  1200080426);\r\n      c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);\r\n      b = FF(b, c, d, a, m[i+ 7], 22, -45705983);\r\n      a = FF(a, b, c, d, m[i+ 8],  7,  1770035416);\r\n      d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);\r\n      c = FF(c, d, a, b, m[i+10], 17, -42063);\r\n      b = FF(b, c, d, a, m[i+11], 22, -1990404162);\r\n      a = FF(a, b, c, d, m[i+12],  7,  1804603682);\r\n      d = FF(d, a, b, c, m[i+13], 12, -40341101);\r\n      c = FF(c, d, a, b, m[i+14], 17, -1502002290);\r\n      b = FF(b, c, d, a, m[i+15], 22,  1236535329);\r\n\r\n      a = GG(a, b, c, d, m[i+ 1],  5, -165796510);\r\n      d = GG(d, a, b, c, m[i+ 6],  9, -1069501632);\r\n      c = GG(c, d, a, b, m[i+11], 14,  643717713);\r\n      b = GG(b, c, d, a, m[i+ 0], 20, -373897302);\r\n      a = GG(a, b, c, d, m[i+ 5],  5, -701558691);\r\n      d = GG(d, a, b, c, m[i+10],  9,  38016083);\r\n      c = GG(c, d, a, b, m[i+15], 14, -660478335);\r\n      b = GG(b, c, d, a, m[i+ 4], 20, -405537848);\r\n      a = GG(a, b, c, d, m[i+ 9],  5,  568446438);\r\n      d = GG(d, a, b, c, m[i+14],  9, -1019803690);\r\n      c = GG(c, d, a, b, m[i+ 3], 14, -187363961);\r\n      b = GG(b, c, d, a, m[i+ 8], 20,  1163531501);\r\n      a = GG(a, b, c, d, m[i+13],  5, -1444681467);\r\n      d = GG(d, a, b, c, m[i+ 2],  9, -51403784);\r\n      c = GG(c, d, a, b, m[i+ 7], 14,  1735328473);\r\n      b = GG(b, c, d, a, m[i+12], 20, -1926607734);\r\n\r\n      a = HH(a, b, c, d, m[i+ 5],  4, -378558);\r\n      d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);\r\n      c = HH(c, d, a, b, m[i+11], 16,  1839030562);\r\n      b = HH(b, c, d, a, m[i+14], 23, -35309556);\r\n      a = HH(a, b, c, d, m[i+ 1],  4, -1530992060);\r\n      d = HH(d, a, b, c, m[i+ 4], 11,  1272893353);\r\n      c = HH(c, d, a, b, m[i+ 7], 16, -155497632);\r\n      b = HH(b, c, d, a, m[i+10], 23, -1094730640);\r\n      a = HH(a, b, c, d, m[i+13],  4,  681279174);\r\n      d = HH(d, a, b, c, m[i+ 0], 11, -358537222);\r\n      c = HH(c, d, a, b, m[i+ 3], 16, -722521979);\r\n      b = HH(b, c, d, a, m[i+ 6], 23,  76029189);\r\n      a = HH(a, b, c, d, m[i+ 9],  4, -640364487);\r\n      d = HH(d, a, b, c, m[i+12], 11, -421815835);\r\n      c = HH(c, d, a, b, m[i+15], 16,  530742520);\r\n      b = HH(b, c, d, a, m[i+ 2], 23, -995338651);\r\n\r\n      a = II(a, b, c, d, m[i+ 0],  6, -198630844);\r\n      d = II(d, a, b, c, m[i+ 7], 10,  1126891415);\r\n      c = II(c, d, a, b, m[i+14], 15, -1416354905);\r\n      b = II(b, c, d, a, m[i+ 5], 21, -57434055);\r\n      a = II(a, b, c, d, m[i+12],  6,  1700485571);\r\n      d = II(d, a, b, c, m[i+ 3], 10, -1894986606);\r\n      c = II(c, d, a, b, m[i+10], 15, -1051523);\r\n      b = II(b, c, d, a, m[i+ 1], 21, -2054922799);\r\n      a = II(a, b, c, d, m[i+ 8],  6,  1873313359);\r\n      d = II(d, a, b, c, m[i+15], 10, -30611744);\r\n      c = II(c, d, a, b, m[i+ 6], 15, -1560198380);\r\n      b = II(b, c, d, a, m[i+13], 21,  1309151649);\r\n      a = II(a, b, c, d, m[i+ 4],  6, -145523070);\r\n      d = II(d, a, b, c, m[i+11], 10, -1120210379);\r\n      c = II(c, d, a, b, m[i+ 2], 15,  718787259);\r\n      b = II(b, c, d, a, m[i+ 9], 21, -343485551);\r\n\r\n      a = (a + aa) >>> 0;\r\n      b = (b + bb) >>> 0;\r\n      c = (c + cc) >>> 0;\r\n      d = (d + dd) >>> 0;\r\n    }\r\n\r\n    return crypt.endian([a, b, c, d]);\r\n  };\r\n\r\n  // Auxiliary functions\r\n  md5._ff  = function (a, b, c, d, x, s, t) {\r\n    var n = a + (b & c | ~b & d) + (x >>> 0) + t;\r\n    return ((n << s) | (n >>> (32 - s))) + b;\r\n  };\r\n  md5._gg  = function (a, b, c, d, x, s, t) {\r\n    var n = a + (b & d | c & ~d) + (x >>> 0) + t;\r\n    return ((n << s) | (n >>> (32 - s))) + b;\r\n  };\r\n  md5._hh  = function (a, b, c, d, x, s, t) {\r\n    var n = a + (b ^ c ^ d) + (x >>> 0) + t;\r\n    return ((n << s) | (n >>> (32 - s))) + b;\r\n  };\r\n  md5._ii  = function (a, b, c, d, x, s, t) {\r\n    var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;\r\n    return ((n << s) | (n >>> (32 - s))) + b;\r\n  };\r\n\r\n  // Package private blocksize\r\n  md5._blocksize = 16;\r\n  md5._digestsize = 16;\r\n\r\n  module.exports = function (message, options) {\r\n    if (message === undefined || message === null)\r\n      throw new Error('Illegal argument ' + message);\r\n\r\n    var digestbytes = crypt.wordsToBytes(md5(message, options));\r\n    return options && options.asBytes ? digestbytes :\r\n        options && options.asString ? bin.bytesToString(digestbytes) :\r\n        crypt.bytesToHex(digestbytes);\r\n  };\r\n\r\n})();\r\n", "import type { BootstrappedWindow } from \"@framerjs/bootstrap\"\nexport const framerStudioVersion: string = process.env.VERSION || \"unknown\"\nexport const framerWebVersion: string = (window as BootstrappedWindow).bootstrap?.hostInfo?.version || \"unknown\"\n", "import type { ServerDeployment, ServerVersionDeployment } from \"@framerjs/app-shared\"\nimport { MAIN_BRANCH_ID } from \"@framerjs/crdtree2\"\nimport { apiFetcher } from \"web/lib/apiFetcher.ts\"\n\nexport interface ListVersionDeploymentsResponse {\n\tdeployments: ServerVersionDeployment[]\n\tcursor?: string\n\thasNextPage: boolean\n}\n\nexport const DEPLOYMENTS_LIST_LIMIT = 30\n\n/** This endpoint returns just the deployedBy user ID. */\ntype GetDeploymentResponse = Omit<ServerDeployment, \"deployedBy\"> & { deployedBy: string }\n\nexport async function getDeployment(projectId: string, deploymentId: string): Promise<GetDeploymentResponse> {\n\treturn apiFetcher.get(`/web/v1/sites/deployments/${projectId}/${deploymentId}`)\n}\n\nexport async function listVersionDeployments(\n\tprojectId: string,\n\tlimit = DEPLOYMENTS_LIST_LIMIT,\n\tcursor?: string,\n\tbranchId?: string,\n): Promise<ListVersionDeploymentsResponse> {\n\treturn apiFetcher.get(`/web/v1/sites/deployments/${projectId}`, {\n\t\tcursor,\n\t\tlimit,\n\t\tonlyVersionHostnames: true,\n\t\tbranchId: branchId === MAIN_BRANCH_ID ? undefined : branchId,\n\t})\n}\n", "const BASE_16_ALPHABET = \"0123456789abcdef\"\n\n/**\n * Compatible with `sha256`. Zero-padded to the length of a `0xFF`-filled byte\n * array of the same length as `byteArray`. See the tests for examples.\n *\n * See benchmarks/base16.mts for why this algorithm.\n */\nexport const encodeByteArrayToBase16 = (byteArray: Uint8Array): string => {\n\tlet result = \"\"\n\tfor (let index = 0; index < byteArray.length; index += 1) {\n\t\t// biome-ignore lint/style/noNonNullAssertion: @TODO: Add explanation\n\t\tresult += BASE_16_ALPHABET[Math.floor(byteArray[index]! / 16)]\n\t\t// biome-ignore lint/style/noNonNullAssertion: @TODO: Add explanation\n\t\tresult += BASE_16_ALPHABET[byteArray[index]! % 16]\n\t}\n\n\treturn result\n}\n", "// Inspiration: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#converting_a_digest_to_a_hex_string\n\nimport { encodeByteArrayToBase16 } from \"./base16.ts\"\n\ntype Range1to32 =\n\t| 1\n\t| 2\n\t| 3\n\t| 4\n\t| 5\n\t| 6\n\t| 7\n\t| 8\n\t| 9\n\t| 10\n\t| 11\n\t| 12\n\t| 13\n\t| 14\n\t| 15\n\t| 16\n\t| 17\n\t| 18\n\t| 19\n\t| 20\n\t| 21\n\t| 22\n\t| 23\n\t| 24\n\t| 25\n\t| 26\n\t| 27\n\t| 28\n\t| 29\n\t| 30\n\t| 31\n\t| 32\n\n/**\n * Hash `input` string using SHA-256 and encode using `outputEncoder`.\n *\n * @param outputSize How many bytes to use from hashing function's output. Defaults to 32 (maximum).\n * @param outputEncoder How to encode the output bytes. Defaults to base16 (hex).\n */\nexport async function sha256(\n\tinput: string,\n\toutputSize: Range1to32 = 32,\n\toutputEncoder: (byteArray: Uint8Array) => string = encodeByteArrayToBase16,\n): Promise<string> {\n\tconst data = new TextEncoder().encode(input)\n\tconst buffer = await crypto.subtle.digest(\"SHA-256\", data)\n\treturn outputEncoder(new Uint8Array(buffer.slice(0, outputSize)))\n}\n", "import type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport type { ModuleExportIdentifierString } from \"@framerjs/shared\"\nimport { convertIdPathVariablesToReadable } from \"document/components/utils/convertIdPathVariablesToReadable.ts\"\nimport { FALLBACK_PATH } from \"document/components/utils/getWebPagePath.ts\"\nimport type { CanvasTree, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport type { RouteSegmentNode } from \"document/models/CanvasTree/nodes/RouteSegmentNode.ts\"\nimport type { RouteSegmentRootNode } from \"document/models/CanvasTree/nodes/RouteSegmentRootNode.ts\"\nimport { isRouteSegmentNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { getPathForDisplay } from \"web/pages/projects/components/Domains/validation/validateRouteNode.ts\"\n\nfunction getReadableSegment(\n\tcomponentLoader: ComponentLoader,\n\tsegment: string,\n\tdataIdentifier: ModuleExportIdentifierString | undefined,\n) {\n\tif (!dataIdentifier) return segment\n\tconst collectionData = componentLoader.dataForIdentifier(dataIdentifier)\n\tif (!collectionData) return segment\n\treturn convertIdPathVariablesToReadable(collectionData, segment)\n}\n\n/**\n * Returns a path for the provided segment, replacing path variables if necessary.\n *\n * - If path variables are provided, they will be used.\n *   (e.g., `/blog/:kpPYRAjRC` \u2192 `/blog/hello-world`)\n * - Otherwise, path variable IDs will be replaced with their human-readable titles.\n *   (e.g., `/blog/:kpPYRAjRC` \u2192 `/blog/:title`)\n *\n * Returns `/unknown` if the correct page path cannot be determined.\n */\nexport function getReadableRouteSegmentFullPath(tree: CanvasTree, componentLoader: ComponentLoader, segmentId: NodeID) {\n\tconst segmentNode = tree.get<RouteSegmentNode | RouteSegmentRootNode>(segmentId)\n\tif (!segmentNode || !isRouteSegmentNode(segmentNode)) return FALLBACK_PATH\n\n\tconst segments = getRouteSegmentChain(segmentNode)\n\treturn getRouteSegmentFullPathFromSegments(componentLoader, segments, true)\n}\n\n/**\n * Returns the segment path without any conversions.\n * For example, `/blog/:kpPYRAjRC` remains unchanged.\n */\nexport function getRawRouteSegmentFullPath(tree: CanvasTree, componentLoader: ComponentLoader, segmentId: NodeID) {\n\tconst segmentNode = tree.get<RouteSegmentNode | RouteSegmentRootNode>(segmentId)\n\tif (!segmentNode || !isRouteSegmentNode(segmentNode)) return FALLBACK_PATH\n\n\tconst segments = getRouteSegmentChain(segmentNode)\n\treturn getRouteSegmentFullPathFromSegments(componentLoader, segments, false)\n}\n\nfunction getRouteSegmentChain(leafNode: RouteSegmentNode): RouteSegmentNode[] {\n\tconst segments = [leafNode]\n\tfor (const segment of leafNode.ancestors()) {\n\t\tif (!isRouteSegmentNode(segment) || !segment.segment) break\n\t\tsegments.push(segment)\n\t}\n\treturn segments\n}\n\n/**\n * Returns the full path for the given segments.\n * If useReadableSegment is true, the segments will be converted to readable segments\n * and parentheses will be unescaped for display.\n *\n * NOTE: The segments must be in reverse order, meaning the first segment is the leaf node.\n * i.e. [{segment: \"page\"}, {segment: \"contact\"}, {segment: \"my\"}] => \"/my/contact/page\"\n */\nexport function getRouteSegmentFullPathFromSegments(\n\tcomponentLoader: ComponentLoader,\n\tsegments: RouteSegmentNode[],\n\tuseReadableSegment: boolean,\n) {\n\tlet path = \"\"\n\tfor (const segmentNode of segments) {\n\t\tif (path !== \"\" && !segmentNode.segment) break\n\n\t\tlet segment = useReadableSegment\n\t\t\t? getReadableSegment(componentLoader, segmentNode.segment, segmentNode.dataIdentifier)\n\t\t\t: segmentNode.segment\n\t\tif (useReadableSegment) segment = getPathForDisplay(segment)\n\t\tpath = `/${segment}${path}`\n\t}\n\n\treturn path || FALLBACK_PATH\n}\n", "import { delay, getLogger } from \"@framerjs/shared\"\nimport { accessTokenRefresher } from \"web/lib/accessTokenRefresherWeb.ts\"\n\nexport const MAX_FETCH_RETRIES = 5\n\nconst log = getLogger(\"fetchJSON\")\n\nexport async function fetchWithRetry(url: string, init: RequestInit, baseRetryDelay = 5000): Promise<Response> {\n\tlog.debug(\"fetch json:\", url)\n\tfor (let retryCount = 0; retryCount < MAX_FETCH_RETRIES; retryCount++) {\n\t\tif (retryCount > 0) {\n\t\t\tawait backoffWithRandomFactor(retryCount, baseRetryDelay)\n\t\t}\n\t\tconst options = await accessTokenRefresher.withAuthorizationHeader(init)\n\t\tconst response = await fetch(url, options)\n\t\tif (response.status === 423) {\n\t\t\ttry {\n\t\t\t\tconst payload = await response.json()\n\t\t\t\tif (payload.retry) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\t/* nothing */\n\t\t\t}\n\t\t}\n\t\treturn response\n\t}\n\tthrow Error(`Failed to fetch after ${MAX_FETCH_RETRIES} retries: ` + url)\n}\n\nfunction backoffWithRandomFactor(retryCount: number, baseRetryDelay: number): Promise<void> {\n\tconst randomFactor = 0.5 + Math.random()\n\tconst retryPeriod = baseRetryDelay * retryCount * randomFactor\n\treturn delay(retryPeriod)\n}\n", "import type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { assert, ModuleType } from \"@framerjs/shared\"\nimport { Dictionary } from \"app/dictionary.ts\"\nimport { getRouteSegmentFullPathFromSegments } from \"document/components/chrome/Pages/utils/getRouteSegmentFullPath.ts\"\nimport { getRawWebPagePath, getWebPagePath } from \"document/components/utils/getWebPagePath.ts\"\nimport { getDefaultName } from \"document/components/utils/nodes.ts\"\nimport type { CanvasTree } from \"document/models/CanvasTree/CanvasTree.ts\"\nimport type { AnyWebPageNode, CanvasNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport type { MaybeNodeID } from \"document/models/CanvasTree/nodes/NodeID.ts\"\nimport type { RootNode } from \"document/models/CanvasTree/nodes/RootNode.ts\"\nimport type { RouteSegmentNode } from \"document/models/CanvasTree/nodes/RouteSegmentNode.ts\"\nimport { canvasNodeFromValue } from \"document/models/CanvasTree/nodes/canvasNodeFromValue.ts\"\nimport {\n\tisCollectionItemNode,\n\tisCollectionNode,\n\tisLayoutTemplateNode,\n\tisProxyRouteNode,\n\tisRootNode,\n\tisRouteSegmentNode,\n\tisSmartComponentNode,\n\tisWebPageNode,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { withDraft } from \"document/models/CanvasTree/traits/WithDraft.ts\"\nimport { getTypeSlashName } from \"modules/utils.ts\"\nimport { fetchWithRetry } from \"utils/fetch.ts\"\nimport { isString } from \"utils/typeChecks.ts\"\nimport { ClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { getMultiplayerServiceURL } from \"web/lib/multiplayerService.ts\"\n\nexport interface ProjectChange {\n\ttype: ChangeType\n\tnodeId: string\n\tname: string\n\tstatus: ChangeStatus\n\tuserIds?: Set<string>\n}\n\nexport enum ChangeType {\n\tWebPage = \"WebPage\",\n\tSmartComponent = \"SmartComponent\",\n\tLayoutTemplate = \"LayoutTemplate\",\n\tCollectionItem = \"CollectionItem\",\n\tProxyRoute = \"ProxyRoute\",\n}\n\nexport enum ChangeStatus {\n\tUpdated = 0,\n\tAdded = 1,\n\tRemoved = 2,\n}\n\nfunction projectChangeSortComparator(a: ProjectChange, b: ProjectChange) {\n\treturn a.name.localeCompare(b.name, undefined, { sensitivity: \"base\" }) // case-insensitive ordering\n}\n\nfunction projectChangeWebPageSortComparator(a: ProjectChange, b: ProjectChange) {\n\t// Home page sorts before other pages.\n\tif (a.name === Dictionary.Home && b.name === Dictionary.Home) {\n\t\treturn 0\n\t} else if (a.name === Dictionary.Home) {\n\t\treturn -1\n\t} else if (b.name === Dictionary.Home) {\n\t\treturn 1\n\t}\n\treturn projectChangeSortComparator(a, b)\n}\n\nexport function sortedChangesFromGroups(groups: Record<ChangeType, ProjectChange[]>) {\n\tconst allChanges: ProjectChange[] = []\n\tlet type: ChangeType\n\tfor (type in groups) {\n\t\tconst changes = groups[type]\n\t\tchanges.sort(type === ChangeType.WebPage ? projectChangeWebPageSortComparator : projectChangeSortComparator)\n\t\tallChanges.push(...changes)\n\t}\n\treturn allChanges\n}\n\nexport function getNodeChange(\n\tnode: CanvasNode,\n\tstatus: ChangeStatus,\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n): ProjectChange | undefined {\n\tconst root = tree.root\n\n\tif (isLayoutTemplateNode(node)) {\n\t\treturn {\n\t\t\ttype: ChangeType.LayoutTemplate,\n\t\t\tname: node.resolveValue(\"name\") || getDefaultName(componentLoader, node),\n\t\t\tstatus,\n\t\t\tnodeId: node.id,\n\t\t}\n\t}\n\n\tif (isWebPageNode(node)) {\n\t\tconst homePageId = root.homePageNodeId\n\t\tconst name = node.id === homePageId ? Dictionary.Home : getWebPagePath(tree, node) || getRawWebPagePath(tree, node)\n\n\t\treturn {\n\t\t\ttype: ChangeType.WebPage,\n\t\t\tname: name || getDefaultName(componentLoader, node),\n\t\t\tstatus,\n\t\t\tnodeId: node.id,\n\t\t}\n\t}\n\n\tif (isSmartComponentNode(node)) {\n\t\treturn {\n\t\t\ttype: ChangeType.SmartComponent,\n\t\t\tname: node.resolveValue(\"name\") || getDefaultName(componentLoader, node),\n\t\t\tstatus,\n\t\t\tnodeId: node.id,\n\t\t}\n\t}\n\n\tif (isCollectionItemNode(node)) {\n\t\tassert(node.parentid, \"Expected CollectionItemNode to have parentid\")\n\t\tconst collectionNode = tree.getParent(node.id)\n\t\tassert(isCollectionNode(collectionNode))\n\t\tconst collectionName = (\n\t\t\tcollectionNode.resolveValue(\"name\") || getDefaultName(componentLoader, collectionNode)\n\t\t).toLocaleLowerCase()\n\n\t\tconst slugVariable = collectionNode.variables.find(v => v.type === \"slug\")\n\t\tconst slug = slugVariable && node.getControlProp(slugVariable.id)?.value\n\n\t\tconst name = isString(slug) ? `${collectionName}/${slug}` : `${collectionName}/item`\n\t\treturn { type: ChangeType.CollectionItem, name, status, nodeId: node.id }\n\t}\n\n\tif (isProxyRouteNode(node)) {\n\t\treturn { type: ChangeType.ProxyRoute, name: node.path, nodeId: node.id, status }\n\t}\n\n\treturn undefined\n}\n\nconst changeTypeForModuleType = {\n\t[ModuleType.Screen]: ChangeType.WebPage,\n\t[ModuleType.Canvas]: ChangeType.SmartComponent,\n\t[ModuleType.LayoutTemplate]: ChangeType.LayoutTemplate,\n}\n\nfunction projectChangeForDeletedModuleType(\n\tid: NodeID,\n\ttype: ModuleType.Screen | ModuleType.Canvas,\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tdefaultName: string,\n\tpath?: string,\n): ProjectChange | undefined {\n\tconst webPageTypeSlashName = getTypeSlashName({ type, name: id })\n\tconst localModuleNode = tree.get(webPageTypeSlashName)\n\tif (!localModuleNode) return undefined\n\tconst name =\n\t\tpath ?? componentLoader.componentForIdentifier(`local-module:${webPageTypeSlashName}:default`)?.name ?? defaultName\n\n\treturn {\n\t\ttype: changeTypeForModuleType[type],\n\t\tname,\n\t\tstatus: ChangeStatus.Removed,\n\t\tnodeId: id,\n\t}\n}\n\n/**\n * Show deleted changes for smart components and web pages that are no longer in\n * the document. Determine the type by checking what the ModuleType was.\n * Determine the name by checking the component loader, or the previous path.\n */\nexport function getRemovedChange(\n\tid: NodeID,\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tpath?: string,\n): ProjectChange | undefined {\n\tconst webPage = projectChangeForDeletedModuleType(id, ModuleType.Screen, tree, componentLoader, \"Page\", path)\n\tif (webPage) return webPage\n\n\tconst component = projectChangeForDeletedModuleType(id, ModuleType.Canvas, tree, componentLoader, \"Component\")\n\tif (component) return component\n}\n\n/**\n * Tree changes API\n */\n\nexport interface ChangesResponse {\n\tdiffs: Record<string, NodeDiff>\n}\n\ninterface NodeDiff {\n\tid: string\n\tuserIds: string[]\n\tfrom: TreeNode | null\n\tto: TreeNode | null\n}\n\ninterface TreeNode {\n\t__class?: string\n\tparentid?: MaybeNodeID\n\t[key: string]: unknown\n}\n\nfunction isChangesResponse(data: unknown): data is ChangesResponse {\n\treturn typeof data === \"object\" && data !== null && \"diffs\" in data && typeof data.diffs === \"object\"\n}\n\nexport async function fetchChanges(\n\tprojectId: string,\n\tfromVersion: number,\n\ttoVersion: number,\n\tisMPSSocket: boolean,\n\tabortSignal?: AbortSignal,\n): Promise<ChangesResponse> {\n\tconst path = `/projects/${projectId}/tree/v2/changes/${fromVersion}-${toVersion}`\n\t// TODO: Remove the conditional once we've fully migrated to FramerMultiplayerService\n\tconst url = isMPSSocket ? getMultiplayerServiceURL(path) : path\n\tconst res = await fetchWithRetry(url, {\n\t\tsignal: abortSignal,\n\t})\n\tif (!res.ok) {\n\t\tthrow new Error(`Non-OK HTTP response: ${res.status}`)\n\t}\n\tconst jsonResponse = await res.json()\n\tif (isChangesResponse(jsonResponse)) return jsonResponse\n\tthrow new Error(\"Invalid response format\")\n}\n\nexport function computeChanges(\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tdiffs: Record<string, NodeDiff>,\n): ProjectChange[] {\n\tif (Object.entries(diffs).length === 0) {\n\t\treturn []\n\t}\n\n\t// The order of these defines the order of the output.\n\tconst groups: Record<ChangeType, ProjectChange[]> = {\n\t\t[ChangeType.LayoutTemplate]: [],\n\t\t[ChangeType.WebPage]: [],\n\t\t[ChangeType.SmartComponent]: [],\n\t\t[ChangeType.CollectionItem]: [],\n\t\t[ChangeType.ProxyRoute]: [],\n\t}\n\n\t// Every non-empty diff is expected to have the RootNode.\n\tlet root: RootNode | undefined\n\tfor (const diff of Object.values(diffs)) {\n\t\t// We look for the RootNode in diff.to, because you can't delete a RootNode.\n\t\tif (diff.to?.[\"__class\"] !== ClassDiscriminator.RootNode) {\n\t\t\tcontinue\n\t\t}\n\t\tconst node = canvasNodeFromValue(diff.to)\n\t\tassert(isRootNode(node), \"Expected RootNode to deserialize as RootNode\")\n\t\troot = node\n\t}\n\tassert(root, \"Expected RootNode to be in diffs\")\n\tfor (const diff of Object.values(diffs)) {\n\t\tconst nodeValue = diff.to || diff.from\n\t\tif (!nodeValue) {\n\t\t\tcontinue\n\t\t}\n\n\t\tconst node = canvasNodeFromValue(nodeValue, nodeValue.parentid)\n\t\tif (!node) {\n\t\t\tcontinue\n\t\t}\n\n\t\tconst change = classifyChange(tree, componentLoader, node, diffs, root)\n\t\tif (!change) {\n\t\t\tcontinue\n\t\t}\n\n\t\tconst status = classifyStatus(diff)\n\t\tif (status === undefined) {\n\t\t\tcontinue\n\t\t}\n\n\t\tgroups[change.type].push({\n\t\t\ttype: change.type,\n\t\t\tnodeId: node.id,\n\t\t\tname: change.name,\n\t\t\tstatus,\n\t\t\tuserIds: new Set(diff.userIds),\n\t\t})\n\t}\n\n\treturn sortedChangesFromGroups(groups)\n}\n\n/**\n * Very primitive way of computing changes based on the nodes the user has selected for patching.\n *\n * This isn't 100% accurate, but it should be good enough until we build a proper changelog for patching.\n */\nexport function computePatchedChanges(\n\tpatchedNodeIds: readonly string[],\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n): ProjectChange[] | undefined {\n\tconst seenNodeIds = new Set<string>()\n\tconst groups: Record<ChangeType, ProjectChange[]> = {\n\t\t[ChangeType.LayoutTemplate]: [],\n\t\t[ChangeType.WebPage]: [],\n\t\t[ChangeType.SmartComponent]: [],\n\t\t[ChangeType.CollectionItem]: [],\n\t\t[ChangeType.ProxyRoute]: [],\n\t}\n\n\tfor (const id of new Set(patchedNodeIds)) {\n\t\tconst node = tree.get(id)\n\t\tif (!node) continue\n\n\t\t// We don't have a good way to distinguish between ChangeStatus.Added and Updated, so we\n\t\t// hard-code the latter. We don't support Removed at all.\n\t\tlet change = getNodeChange(node, ChangeStatus.Updated, tree, componentLoader)\n\t\tif (!change) {\n\t\t\tconst scopeNode = tree.getScopeNodeFor(node)\n\t\t\tif (scopeNode) {\n\t\t\t\tchange = getNodeChange(scopeNode, ChangeStatus.Updated, tree, componentLoader)\n\t\t\t}\n\t\t}\n\t\tif (!change) continue\n\t\tif (seenNodeIds.has(change.nodeId)) continue\n\n\t\tseenNodeIds.add(change.nodeId)\n\t\tgroups[change.type].push(change)\n\t}\n\n\tif (seenNodeIds.size === 0 && patchedNodeIds.length > 0) {\n\t\t// Let's not pretend there are actually no changes, and instead acknowledge\n\t\t// that this method is flawed and may have simply failed to produce a result.\n\t\treturn\n\t}\n\n\treturn sortedChangesFromGroups(groups)\n}\n\nfunction getSegmentFromWebPage(\n\twebPageNode: AnyWebPageNode,\n\tdiffs: Record<string, NodeDiff>,\n): RouteSegmentNode | undefined {\n\tfor (const diff of Object.values(diffs)) {\n\t\tconst nodeValue = diff.to || diff.from\n\t\tconst node = canvasNodeFromValue(nodeValue, nodeValue?.parentid)\n\t\tif (isRouteSegmentNode(node) && node.webPageId === webPageNode.id) {\n\t\t\treturn node\n\t\t}\n\t}\n}\n\nfunction buildAncestorsFromSegment(segment: RouteSegmentNode, diffs: Record<string, NodeDiff>) {\n\tconst ancestors: RouteSegmentNode[] = []\n\n\tlet current: RouteSegmentNode | null = segment\n\twhile (current) {\n\t\tancestors.push(current)\n\n\t\tif (!current.parentid) break\n\n\t\tconst item = diffs[current.parentid]\n\t\tconst nodeValue = item?.to || item?.from\n\t\tif (!nodeValue) break\n\n\t\tconst next = canvasNodeFromValue(nodeValue, nodeValue?.parentid)\n\n\t\tcurrent = isRouteSegmentNode(next) ? next : null\n\t}\n\n\treturn ancestors\n}\n\nfunction classifyChange(\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tnode: CanvasNode,\n\tdiffs: Record<string, NodeDiff>,\n\troot: RootNode,\n): Pick<ProjectChange, \"type\" | \"name\"> | undefined {\n\tif (isRouteSegmentNode(node)) {\n\t\tconst webPageNode = tree.get(node.webPageId)\n\t\t// Currently, updating a page's path still changes the deprecated pagePath. If we're removing pagePath, changes\n\t\t// will only affect route segment nodes. To prepare for this, associate changes in route segment nodes not\n\t\t// reflected by a web page node in the diffs with the corresponding web page node.\n\t\tif (webPageNode && !(webPageNode.id in diffs)) node = webPageNode\n\t}\n\n\tif (isLayoutTemplateNode(node)) {\n\t\tconst name = node.resolveValue(\"name\") || getDefaultName(componentLoader, node)\n\t\treturn { type: ChangeType.LayoutTemplate, name }\n\t}\n\n\tif (isWebPageNode(node)) {\n\t\tconst homePageId = root.homePageNodeId\n\t\tlet name = node.id === homePageId ? Dictionary.Home : getWebPagePath(tree, node) || getRawWebPagePath(tree, node)\n\n\t\tif (!name) {\n\t\t\tconst segment = getSegmentFromWebPage(node, diffs)\n\t\t\tif (segment) {\n\t\t\t\tconst ancestors = buildAncestorsFromSegment(segment, diffs)\n\t\t\t\tname = getRouteSegmentFullPathFromSegments(componentLoader, ancestors, true)\n\t\t\t}\n\t\t}\n\n\t\tif (!name) {\n\t\t\tname = getDefaultName(componentLoader, node)\n\t\t}\n\n\t\treturn { type: ChangeType.WebPage, name }\n\t}\n\n\tif (isSmartComponentNode(node)) {\n\t\tconst name = node.resolveValue(\"name\") || getDefaultName(componentLoader, node)\n\t\treturn { type: ChangeType.SmartComponent, name }\n\t} else if (isCollectionItemNode(node)) {\n\t\tassert(node.parentid, \"Expected CollectionItemNode to have parentid\")\n\n\t\tconst collectionNodeValue = diffs[node.parentid]?.to || diffs[node.parentid]?.from\n\t\tassert(collectionNodeValue, \"Expected CollectionItemNode's parent to exist in the diffs map\")\n\n\t\tconst collectionNode = canvasNodeFromValue(collectionNodeValue, collectionNodeValue.parentid)\n\t\tassert(isCollectionNode(collectionNode), \"Expected CollectionItemNode's parent to be a CollectionNode\")\n\n\t\tconst collectionName = (\n\t\t\tcollectionNode.resolveValue(\"name\") || getDefaultName(componentLoader, collectionNode)\n\t\t).toLocaleLowerCase()\n\n\t\tconst slugVariable = collectionNode.variables.find(v => v.type === \"slug\")\n\t\tconst slug = slugVariable && node.getControlProp(slugVariable.id)?.value\n\n\t\tconst name = isString(slug) ? `${collectionName}/${slug}` : `${collectionName}/item`\n\t\treturn { type: ChangeType.CollectionItem, name }\n\t} else if (isProxyRouteNode(node)) {\n\t\treturn { type: ChangeType.ProxyRoute, name: node.path }\n\t}\n}\n\n/** Classify the status of a change taking into account whether the change is a draft.\n\nDraft items are not public.\n*/\nfunction classifyStatus(diff: NodeDiff): ChangeStatus | undefined {\n\tif (isPublic(diff.from)) {\n\t\treturn isPublic(diff.to) ? ChangeStatus.Updated : ChangeStatus.Removed\n\t} else {\n\t\treturn isPublic(diff.to) ? ChangeStatus.Added : undefined\n\t}\n}\n\n/** Check if a tree node exists and is not a draft */\nfunction isPublic(treeNode: TreeNode | null): boolean {\n\tif (!treeNode) return false\n\tconst node = canvasNodeFromValue(treeNode, treeNode.parentid)\n\tif (!node) return false\n\treturn !(withDraft(node) && node.isDraft)\n}\n", "/*\n * Defines the format of the `.framerssg` files, such as `editor-input.framerssg` and `bundle-metadata.framerssg`.\n *\n * For now, the format is plain JSON, but we include a version header at the beginning if we ever need to change it,\n * e.g., if we need to start compressing the JSON, or support binary data.\n *\n * The header is a version string followed by a newline character, so that as long as we stick to plain JSON, the entire\n * file remains easily readable.\n */\n\nconst SSG_DATA_VERSION = 1\n\n/** Browser-friendly. */\nexport function serializeSSGData(json: unknown): BlobPart[] {\n\tconst encoder = new TextEncoder()\n\tconst data = encoder.encode(JSON.stringify(json))\n\tconst header = `${SSG_DATA_VERSION}\\n`\n\treturn [header, data]\n}\n\nexport function parseSSGData<T = unknown>(data: Buffer): T {\n\tconst endOfHeader = data.indexOf(10 /* \\n */)\n\tif (endOfHeader === -1) {\n\t\tthrow new Error(\"Invalid editor input: missing header\")\n\t}\n\tconst version = data.toString(\"utf8\", 0, endOfHeader)\n\tif (version !== String(SSG_DATA_VERSION)) {\n\t\tthrow new Error(`Invalid editor input: unsupported version: ${version}`)\n\t}\n\tconst json = JSON.parse(data.toString(\"utf8\", endOfHeader + 1))\n\treturn json\n}\n", "import type { Locale } from \"./locale.ts\"\nimport type { Rewrite } from \"./rewrite.ts\"\nimport type { Route } from \"./route.ts\"\nimport { serializeSSGData } from \"./ssgData.ts\"\n\nexport type { Route as SSGRoute } from \"./route.ts\"\nexport type { Rewrite as SSGRewrite } from \"./rewrite.ts\"\n\nexport interface EditorInput {\n\tadaptLayoutToTextDirection?: boolean\n\tautomaticLocale: boolean\n\t/** Prefer undefined over an empty array for performance. */\n\tdebugFlags?: DebugFlag[]\n\texperiments: Record<string, string>\n\tlocales: Locale[]\n\tpreOptimizePaths?: string[]\n\trewrites?: Rewrite[]\n\troutes: Route[]\n}\n\nexport const enum DebugFlag {\n\tbundleWithEsbuild = \"bundleWithEsbuild\",\n\tbundleWithRolldown = \"bundleWithRolldown\",\n\t/**\n\t * By default, we render small sites directly in the ssg-sandbox Lambda, while larger sites get split between\n\t * multiple ssg-sandbox-renderer Lambdas. This flag forces even a small site to use the renderer Lambda. This makes\n\t * it easier to test ssg-sandbox-renderer code paths without having to find a large site.\n\t */\n\tforceRendererLambda = \"forceRendererLambda\",\n\tforceSourceMapsOff = \"forceSourceMapsOff\",\n\tforceSourceMapsOn = \"forceSourceMapsOn\",\n\tnoBeautifyStackTraces = \"noBeautifyStackTraces\",\n\tnoMinifyJS = \"noMinifyJS\",\n\tnoBundleJS = \"noBundleJS\",\n\tnoRender = \"noRender\",\n}\n\n/** Used by the Framer web app to serialize the editor input. */\nexport function serializeEditorInput(editorInput: EditorInput): File {\n\treturn new File(serializeSSGData(editorInput), \"editor-input.framerssg\")\n}\n", "import { AnnotationKey, type ExportSpecifier } from \"@framerjs/framer-runtime/crossorigin\"\nimport { type LocalModuleId, ModuleType, ResolvablePromise, emptyArray, getLogger } from \"@framerjs/shared\"\nimport { moduleTypesForSourceNode } from \"code-generation/moduleTypeForSourceNode.ts\"\nimport type { EngineStores } from \"document/EngineStores.ts\"\nimport type { VekterEngineScheduler } from \"document/VekterEngineScheduler.ts\"\nimport type {\n\tCanvasNode,\n\tCanvasTree,\n\tLayoutTemplateNode,\n\tNodeID,\n\tSmartComponentNode,\n\tWebPageNode,\n} from \"document/models/CanvasTree/index.ts\"\nimport { ErrorListNode } from \"document/models/CanvasTree/nodes/ErrorListNode.ts\"\nimport { ErrorNode, ErrorNodeReason, ErrorNodeType } from \"document/models/CanvasTree/nodes/ErrorNode.ts\"\nimport {\n\tisLayoutTemplateNode,\n\tisSmartComponentNode,\n\tisWebPageNode,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isVariableReference } from \"document/models/CanvasTree/traits/VariableReference.ts\"\nimport { hasImageFill } from \"document/models/CanvasTree/traits/WithFill.ts\"\nimport { type CodeGenerationStore, GenerationCondition } from \"document/stores/CodeGenerationStore.ts\"\nimport type { ModulesStore } from \"document/stores/ModulesStore.ts\"\nimport type { ScopeStore } from \"document/stores/ScopeStore.ts\"\nimport type { TreeStore } from \"document/stores/TreeStore.ts\"\nimport { isValidModuleSourceNode } from \"document/utils/moduleSourceNodeHelpers.ts\"\nimport { type DependencyGraph, collectModuleAndItsDependentsRecursively } from \"modules/DependencyGraph.ts\"\nimport type { TypeSlashName } from \"modules/types.ts\"\nimport { getTypeSlashName, splitTypeSlashName } from \"modules/utils.ts\"\n\nconst logger = getLogger(\"regenerateModulesForFitImage\")\n\nconst autoSizeImageModuleTypes: Set<ModuleType> = new Set([\n\tModuleType.Collection,\n\tModuleType.LayoutTemplate,\n\tModuleType.Screen,\n\tModuleType.Canvas,\n])\n\nconst sharedModuleExportIdentifier: ExportSpecifier = \"default\"\n\ninterface ModuleToRegenerate {\n\tlocalId: LocalModuleId\n\tsourceNodeId: NodeID\n\ttype: ModuleType\n}\n\ninterface ModuleWithAutoSizeImageAnnotation extends ModuleToRegenerate {\n\thasAnnotation: boolean\n}\n\n/**\n * Regenerates any required modules for the given nodes to support Fit Image\n * @param stores engine store dependencies\n * @param scheduler engine scheduler\n * @param nodes Nodes involved in the Fit Image change\n */\nexport async function regenerateModulesForFitImage(\n\tstores: Pick<EngineStores, \"treeStore\" | \"codeGenerationStore\" | \"scopeStore\" | \"modulesStore\">,\n\tscheduler: VekterEngineScheduler,\n\tnodes: CanvasNode[],\n): Promise<void> {\n\tconst modulesToRegenerate = getModulesToRegenerateForFitImage({\n\t\t...stores,\n\t\tnodes,\n\t})\n\tif (modulesToRegenerate.length === 0) return\n\n\t// Add error nodes so the modules will be regenerated on publish if they are not regenerated before then\n\tconst listNode = ErrorListNode.ensure(stores.treeStore.tree)\n\tscheduler.processWhenReady(() => {\n\t\tfor (const module of modulesToRegenerate) {\n\t\t\tstores.treeStore.tree.insertNode(\n\t\t\t\tnew ErrorNode({\n\t\t\t\t\ttype: ErrorNodeType.CodeGeneration,\n\t\t\t\t\tscopeId: module.sourceNodeId,\n\t\t\t\t\tsourceNodeId: module.sourceNodeId,\n\t\t\t\t\treason: ErrorNodeReason.FitImageRegenerationRequired,\n\t\t\t\t}),\n\t\t\t\tlistNode.id,\n\t\t\t)\n\t\t}\n\t})\n\n\tconst nodeIds = nodes.map(node => node.id)\n\t// Start regenerating modules proactively when the engine is idle to reduce the chance of the user seeing errors on the canvas before they next publish\n\tfor (const module of modulesToRegenerate) {\n\t\tawait regenerateModuleWhileIdle(scheduler, stores.codeGenerationStore, module, { nodeIds })\n\t}\n}\n\nfunction regenerateModuleWhileIdle(\n\tscheduler: VekterEngineScheduler,\n\tcodeGenerationStore: CodeGenerationStore,\n\tmodule: ModuleToRegenerate,\n\tcontext: { nodeIds: NodeID[] },\n) {\n\tconst promise = new ResolvablePromise<void>()\n\tscheduler.runWhenIdle(async () => {\n\t\ttry {\n\t\t\tawait codeGenerationStore.updateComponent(module.sourceNodeId, GenerationCondition.Forced)\n\t\t} catch (error) {\n\t\t\tlogger.reportError(new Error(\"Failed to regenerate required module for Fit Image\", { cause: error }), {\n\t\t\t\tnodeIds: context.nodeIds,\n\t\t\t\tmoduleId: module.localId,\n\t\t\t})\n\t\t}\n\t\tpromise.resolve()\n\t})\n\treturn promise\n}\n\nexport function getRelatedModulesForFitImage(modulesStore: ModulesStore, treeStore: TreeStore) {\n\tconst modules: ModuleWithAutoSizeImageAnnotation[] = []\n\tfor (const [typeSlashName] of modulesStore.localModules) {\n\t\tconst moduleWithFitImageAnnotationStatus = getModuleWithFitImageAnnotationStatus(\n\t\t\tmodulesStore,\n\t\t\ttreeStore,\n\t\t\ttypeSlashName,\n\t\t\t\"all\",\n\t\t)\n\t\tif (!moduleWithFitImageAnnotationStatus) continue\n\n\t\tmodules.push(moduleWithFitImageAnnotationStatus)\n\t}\n\n\treturn modules\n}\n\nfunction getModuleWithFitImageAnnotationStatus(\n\tmodulesStore: ModulesStore,\n\ttreeStore: TreeStore,\n\tmoduleTypeSlashName: TypeSlashName,\n\tstatus: \"withAnnotation\" | \"withoutAnnotation\" | \"all\",\n): ModuleWithAutoSizeImageAnnotation | undefined {\n\tconst localModule = modulesStore.localModules.get(moduleTypeSlashName)\n\tif (!localModule) return undefined\n\tif (!autoSizeImageModuleTypes.has(localModule.type as ModuleType)) return undefined\n\n\tconst moduleStore = modulesStore.forType(localModule.type as ModuleType)\n\tconst moduleData = moduleStore.getByLocalId(localModule.localId)\n\tif (!moduleData) return undefined\n\tconst annotations = moduleData.annotations(null, sharedModuleExportIdentifier)\n\n\t// This is a hack to avoid counting canvas page screens (also screen/ modules),\n\t// which don't use the FramerAutoSizeImages annotation and would only pollute the\n\t// results. They don't use the FramerCanvasComponentVariantDetails annotation\n\t// either, we use this as an indicator to filter them out.\n\tconst isCanvasPageScreenModule =\n\t\tlocalModule.type === ModuleType.Screen &&\n\t\tannotations &&\n\t\t!annotations[AnnotationKey.FramerCanvasComponentVariantDetails]\n\tif (isCanvasPageScreenModule) return undefined\n\n\t// If the module doesn't contain any assets, also skip.\n\tconst persistedModule = modulesStore.getPersistedModuleByLocalId(localModule.localId)\n\tif (!persistedModule?.hasAssets) return undefined\n\n\tconst sourceNode = treeStore.tree.get(localModule.name)\n\tif (!sourceNode) return undefined\n\tif (!isValidModuleSourceNodeForType(treeStore.tree, localModule.type as ModuleType, sourceNode)) return undefined\n\n\tconst hasAnnotation = Boolean(annotations?.[AnnotationKey.FramerAutoSizeImages])\n\tif (status === \"withAnnotation\" && !hasAnnotation) return undefined\n\tif (status === \"withoutAnnotation\" && hasAnnotation) return undefined\n\n\treturn {\n\t\tlocalId: localModule.localId,\n\t\tsourceNodeId: localModule.name,\n\t\ttype: localModule.type as ModuleType,\n\t\thasAnnotation,\n\t}\n}\n\nfunction getModulesToRegenerateForFitImage({\n\tmodulesStore,\n\ttreeStore,\n\tscopeStore,\n\tnodes,\n}: {\n\tmodulesStore: ModulesStore\n\ttreeStore: TreeStore\n\tscopeStore: ScopeStore\n\tnodes: CanvasNode[]\n}): readonly ModuleToRegenerate[] {\n\tconst activeScope = scopeStore.active\n\n\tif (!isSmartComponentNode(activeScope) && !isLayoutTemplateNode(activeScope) && !isWebPageNode(activeScope)) {\n\t\treturn emptyArray<ModuleToRegenerate>()\n\t}\n\n\t// If we are changing nodes with static fill images then nothing needs to be regenerated beyond the scope of the nodes, which is automatic\n\tconst anyNodeWithVariableFillImage = nodes.some(node => {\n\t\tconst current = node.draftOrCurrent()\n\t\treturn hasImageFill(current) && isVariableReference(current.fillImage)\n\t})\n\tif (!anyNodeWithVariableFillImage) return emptyArray<ModuleToRegenerate>()\n\n\treturn getDependentModulesToRegenerate(modulesStore, treeStore, activeScope)\n}\n\nfunction getDependentModulesToRegenerate(\n\tmodulesStore: ModulesStore,\n\ttreeStore: TreeStore,\n\tactiveScope: SmartComponentNode | LayoutTemplateNode | WebPageNode,\n): ModuleToRegenerate[] {\n\tconst dependencyGraph = modulesStore.getLatestDependencyGraph()\n\tconst scopeModuleType = moduleTypesForSourceNode(activeScope, treeStore.tree)[0]\n\n\tif (!scopeModuleType) {\n\t\treturn []\n\t}\n\n\tconst scopeModuleTypeSlashName = getTypeSlashName({\n\t\ttype: scopeModuleType,\n\t\tname: activeScope.id,\n\t})\n\n\tconst dependentModules = new Set<TypeSlashName>()\n\tcollectModuleAndItsDependentsRecursively(dependencyGraph, scopeModuleTypeSlashName, dependentModules)\n\n\tconst modulesToRegenerate = new Map<TypeSlashName, ModuleToRegenerate>()\n\n\tfor (const moduleTypeSlashName of dependentModules) {\n\t\tif (!isLayoutTemplateNode(activeScope)) {\n\t\t\t// Get any related collections to regenerate, we have to do this even for modules that are not outdated.\n\t\t\t// This is for the case where a collection may be hooked up to a dependent component image variable.\n\t\t\t// Layout templates controls do not accept collection variables so we can skip this step.\n\t\t\taddDependentCollectionsToRegenerate(\n\t\t\t\tmodulesStore,\n\t\t\t\ttreeStore,\n\t\t\t\tdependencyGraph,\n\t\t\t\tmoduleTypeSlashName,\n\t\t\t\tmodulesToRegenerate,\n\t\t\t)\n\t\t}\n\n\t\tif (moduleTypeSlashName === scopeModuleTypeSlashName) continue\n\n\t\tconst relatedModule = getModuleWithFitImageAnnotationStatus(\n\t\t\tmodulesStore,\n\t\t\ttreeStore,\n\t\t\tmoduleTypeSlashName,\n\t\t\t\"withoutAnnotation\",\n\t\t)\n\t\tif (!relatedModule) continue\n\t\tmodulesToRegenerate.set(moduleTypeSlashName, relatedModule)\n\t}\n\n\treturn [...modulesToRegenerate.values()]\n}\n\n/**\n * Adds any collections that the target module depends on to `modulesToRegenerate` if they are outdated.\n */\nfunction addDependentCollectionsToRegenerate(\n\tmodulesStore: ModulesStore,\n\ttreeStore: TreeStore,\n\tdependencyGraph: DependencyGraph,\n\tmoduleTypeSlashName: TypeSlashName,\n\tmodulesToRegenerate: Map<TypeSlashName, ModuleToRegenerate>,\n) {\n\tfor (const dependency of dependencyGraph?.[moduleTypeSlashName]?.dependencies ?? []) {\n\t\tconst [moduleType, moduleName] = splitTypeSlashName(dependency)\n\n\t\t// @see getDependencyCanonicalPath in DependencyGraph.ts, collections are normalised and we need to revert the normalisation\n\t\tif (moduleType !== ModuleType.DraftCollection && moduleType !== ModuleType.Collection) continue\n\n\t\tconst collectionModule = getModuleWithFitImageAnnotationStatus(\n\t\t\tmodulesStore,\n\t\t\ttreeStore,\n\t\t\tgetTypeSlashName({ type: ModuleType.Collection, name: moduleName }),\n\t\t\t\"withoutAnnotation\",\n\t\t)\n\t\tif (collectionModule) {\n\t\t\tmodulesToRegenerate.set(collectionModule.localId, collectionModule)\n\t\t}\n\t}\n}\n\nfunction isValidModuleSourceNodeForType(tree: CanvasTree, type: ModuleType, node: CanvasNode) {\n\tif (!isValidModuleSourceNode(node, tree)) return false\n\n\ttry {\n\t\tconst expectedType = moduleTypesForSourceNode(node, tree)\n\t\treturn expectedType.includes(type)\n\t} catch {\n\t\t// if this errors then it is not valid because there are no module types for this node\n\t\treturn false\n\t}\n}\n", "import { AnnotationKey, type ExportSpecifier } from \"@framerjs/framer-runtime/crossorigin\"\nimport { type LocalModuleId, ModuleType, getLogger } from \"@framerjs/shared\"\nimport type { EngineStores } from \"document/EngineStores.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isWebPageNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { withDraft } from \"document/models/CanvasTree/traits/WithDraft.ts\"\nimport type { CodeGenerationStore } from \"document/stores/CodeGenerationStore.ts\"\nimport type { ModulesStore } from \"document/stores/ModulesStore.ts\"\nimport type { TreeStore } from \"document/stores/TreeStore.ts\"\nimport { isUndefined } from \"utils/typeChecks.ts\"\n\nconst logger = getLogger(\"LayoutFlowEffectRegeneration\")\n\nconst sharedModuleExportIdentifier: ExportSpecifier = \"default\"\n\nlet activeAbortController: AbortController | null = null\n\nexport function interruptLayoutTemplateFlowEffectRegeneration(): void {\n\tif (activeAbortController) {\n\t\tactiveAbortController.abort()\n\t\tactiveAbortController = null\n\t}\n}\n\ninterface WebPageModuleToRegenerate {\n\tlocalId: LocalModuleId\n\tsourceNodeId: NodeID\n}\n\ninterface FlowEffectModuleStats {\n\ttotalModules: number\n\tmodulesToRegenerate: number\n}\n\ninterface FlowEffectModuleAnalysis {\n\tstats: FlowEffectModuleStats\n\tmodulesToRegenerate: WebPageModuleToRegenerate[]\n}\n\nexport interface RegenerationProgress {\n\tcompleted: number\n\ttotal: number\n}\n\n/**\n * Regenerates all webpage modules in the project that don't yet have the\n * FramerLayoutTemplateFlowEffect annotation.\n *\n * @param stores engine store dependencies\n * @param options.limit optional maximum number of modules to regenerate, used in the debug tool\n * @param options.onProgress optional callback invoked after each module is regenerated\n */\nexport async function regenerateModulesForLayoutTemplateFlowEffect(\n\tstores: Pick<EngineStores, \"treeStore\" | \"codeGenerationStore\" | \"modulesStore\">,\n\toptions: {\n\t\tlimit?: number\n\t\tonProgress?: (progress: RegenerationProgress) => void\n\t} = {},\n): Promise<boolean> {\n\t// Supersede any prior regeneration\n\tactiveAbortController?.abort()\n\tactiveAbortController = new AbortController()\n\tconst { signal } = activeAbortController\n\n\ttry {\n\t\tconst { stats, modulesToRegenerate: allModulesToRegenerate } = getWebPageModulesToRegenerate(\n\t\t\tstores.modulesStore,\n\t\t\tstores.treeStore,\n\t\t)\n\n\t\tconst modulesToRegenerate = isUndefined(options.limit)\n\t\t\t? allModulesToRegenerate\n\t\t\t: allModulesToRegenerate.slice(0, options.limit)\n\n\t\tlogger.debug(\"Regenerating WebPage Modules for Flow Effect in Layout Template\", {\n\t\t\t...stats,\n\t\t\tlimited: modulesToRegenerate.length,\n\t\t})\n\n\t\tif (modulesToRegenerate.length === 0) return true\n\n\t\toptions.onProgress?.({ completed: 0, total: modulesToRegenerate.length })\n\n\t\tconst total = modulesToRegenerate.length\n\t\tfor (const [index, module] of modulesToRegenerate.entries()) {\n\t\t\tif (signal.aborted) {\n\t\t\t\tlogger.debug(\"Regeneration interrupted\", {\n\t\t\t\t\tprogress: `${index}/${total}`,\n\t\t\t\t})\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tlogger.debug(\"Regenerating module\", { progress: `${index + 1}/${total}`, sourceNodeId: module.sourceNodeId })\n\n\t\t\tawait regenerateWebPageModule(stores.codeGenerationStore, module)\n\t\t\toptions.onProgress?.({ completed: index + 1, total })\n\t\t}\n\n\t\treturn true\n\t} finally {\n\t\t// Reset abort controller if it's still the active one\n\t\tif (signal === activeAbortController?.signal) {\n\t\t\tactiveAbortController = null\n\t\t}\n\t}\n}\n\nasync function regenerateWebPageModule(codeGenerationStore: CodeGenerationStore, module: WebPageModuleToRegenerate) {\n\ttry {\n\t\tawait codeGenerationStore.forceComponentUpdate(module.sourceNodeId)\n\t} catch (error) {\n\t\tlogger.reportError(\n\t\t\tnew Error(\"Failed to regenerate required module for Layout Template Flow Effect\", { cause: error }),\n\t\t\t{\n\t\t\t\tmoduleId: module.localId,\n\t\t\t},\n\t\t)\n\t}\n}\n\n/**\n * Analyzes all webpage modules and returns both the modules that need\n * regeneration and aggregate stats for the debug UI and tracking.\n */\nexport function getWebPageModulesToRegenerate(\n\tmodulesStore: ModulesStore,\n\ttreeStore: TreeStore,\n): FlowEffectModuleAnalysis {\n\tconst modulesToRegenerate: WebPageModuleToRegenerate[] = []\n\tlet totalModules = 0\n\n\tconst webpageModuleStore = modulesStore.forType(ModuleType.Screen)\n\n\tfor (const [typeSlashName] of modulesStore.localModules) {\n\t\tconst localModule = modulesStore.localModules.get(typeSlashName)\n\t\tif (!localModule || localModule.type !== ModuleType.Screen) continue\n\n\t\tconst moduleData = webpageModuleStore.getByLocalId(localModule.localId)\n\t\tif (!moduleData) continue\n\n\t\tconst sourceNodeId = localModule.name\n\t\tconst sourceNode = treeStore.tree.get(sourceNodeId)\n\t\tif (!sourceNode || !isWebPageNode(sourceNode)) continue\n\n\t\tconst annotations = moduleData.annotations(null, sharedModuleExportIdentifier)\n\t\tif (!annotations || !annotations[AnnotationKey.FramerCanvasComponentVariantDetails]) continue\n\n\t\t// Pages in draft are automatically regenerated when they are undrafted, so we don't need to do\n\t\t// it proactively.\n\t\tif (withDraft(sourceNode) && sourceNode.isDraft) continue\n\n\t\ttotalModules++\n\n\t\tconst hasAnnotation = Boolean(annotations[AnnotationKey.FramerLayoutTemplateFlowEffect])\n\t\tif (hasAnnotation) continue\n\n\t\tmodulesToRegenerate.push({\n\t\t\tlocalId: localModule.localId,\n\t\t\tsourceNodeId,\n\t\t})\n\t}\n\n\treturn {\n\t\tstats: {\n\t\t\ttotalModules,\n\t\t\tmodulesToRegenerate: modulesToRegenerate.length,\n\t\t},\n\t\tmodulesToRegenerate,\n\t}\n}\n", "import { ProjectLicenseType } from \"@framerjs/app-shared\"\nimport { experiments } from \"app/experiments.ts\"\nimport type { ProjectStore } from \"document/stores/ProjectStore.ts\"\nimport { assertNever } from \"library/utils/assert.ts\"\nimport { UpsellAction, UpsellFeature } from \"../../../siteSettings/Plans/Stripe/utils/upsell.ts\"\nimport { BYTES_PER_UNIT, MAX_BANDWIDTH_WITH_ADDONS_GB } from \"../../../siteSettings/Usage/constants.ts\"\n\nexport const enum BandwidthEvaluationMode {\n\t/**\n\t * Use this when evaluating publish blocking. We only consider historical usage\n\t * (previousMonth or twoMonthsAgoMonth), never the current month.\n\t */\n\tPublishBlock = \"publishBlock\",\n\t/** Same calculation with PublishBlock, but only to inform the user without blocking publish */\n\tPublishToast = \"publishToast\",\n\n\t/** Considers the current month usage. */\n\tCurrentMonthOnly = \"currentMonthOnly\",\n}\n\n/** Returns the bandwidth limit and the evaluated usage, or null if the limit hasn't been reached. */\nfunction bandwidthLimitOnPublish(\n\tprojectStore: ProjectStore,\n\tmode: BandwidthEvaluationMode,\n): { limit: number; usage: number } | null {\n\tconst currentLimit = projectStore?.project?.settings.resourceLimits.bandwidthInGB ?? null\n\n\t// Unlimited bandwidth users should never see upsells\n\tif (currentLimit === null) return null\n\n\tconst usageData = projectStore.project?.usage?.bandwidth\n\n\tlet usageBytes = 0\n\tswitch (mode) {\n\t\tcase BandwidthEvaluationMode.PublishToast:\n\t\tcase BandwidthEvaluationMode.PublishBlock: {\n\t\t\t// Gate publish-mode bandwidth blocking behind experiment. When off, don't block.\n\t\t\tif (!experiments.isOn(\"publishBandwidthBlock\")) return null\n\n\t\t\t// For publish, ignore current month; consider previous and two months ago\n\t\t\tconst previousMonth = usageData?.previousMonth ?? 0\n\t\t\tconst twoMonthsAgo = usageData?.twoMonthsAgo ?? 0\n\n\t\t\t// Only enforce when BOTH previous months are over the limit\n\t\t\tconst thresholdBytes = currentLimit * BYTES_PER_UNIT.GB\n\t\t\tconst previousOver = previousMonth > thresholdBytes\n\t\t\tconst twoMonthsAgoOver = twoMonthsAgo > thresholdBytes\n\n\t\t\tif (!(previousOver && twoMonthsAgoOver)) return null\n\n\t\t\t// When enforcing, use the lower of the two months for messaging/upsell\n\t\t\tusageBytes = Math.min(previousMonth, twoMonthsAgo)\n\t\t\tbreak\n\t\t}\n\t\tcase BandwidthEvaluationMode.CurrentMonthOnly:\n\t\t\t// Consider only the current month\n\t\t\tusageBytes = usageData?.currentMonth ?? 0\n\t\t\tbreak\n\t\tdefault:\n\t\t\tassertNever(mode)\n\t}\n\n\tconst usageInGB = usageBytes / BYTES_PER_UNIT.GB\n\treturn usageInGB > currentLimit ? { limit: currentLimit, usage: usageInGB } : null\n}\n\nexport type BandwidthLimitUpsellResult = {\n\tfeature: UpsellFeature.bandwidthInGB\n\tbandwidthLimit: number\n\taction: UpsellAction\n\tbandwidthUsage: number\n}\n\nexport function getBandwidthLimitUpsell({\n\tprojectStore,\n\tevaluationMode,\n}: {\n\tprojectStore: ProjectStore\n\tevaluationMode: BandwidthEvaluationMode\n}): BandwidthLimitUpsellResult | null {\n\tconst bandwidth = bandwidthLimitOnPublish(projectStore, evaluationMode)\n\tif (bandwidth === null) {\n\t\treturn null\n\t}\n\n\tconst shouldBlockPublish = evaluationMode === BandwidthEvaluationMode.PublishBlock\n\tconst { limit: bandwidthLimitInGB, usage: bandwidthUsageInGB } = bandwidth\n\n\tconst isEnterprise = projectStore.projectLicenseType === ProjectLicenseType.EnterpriseSite\n\tconst isFree = projectStore.projectLicenseType === ProjectLicenseType.FreeSite\n\n\t// Don't block publish for free or enterprise accounts\n\tif (shouldBlockPublish && (isFree || isEnterprise)) {\n\t\treturn null\n\t}\n\n\tif (isEnterprise) {\n\t\treturn {\n\t\t\tfeature: UpsellFeature.bandwidthInGB,\n\t\t\tbandwidthLimit: bandwidthLimitInGB,\n\t\t\taction: UpsellAction.Contact,\n\t\t\tbandwidthUsage: bandwidthUsageInGB,\n\t\t}\n\t}\n\n\tconst maximumBandwidthAllowed = projectStore.resourceLimits?.maxBandwidthInGB ?? Infinity\n\tconst canBuyBandwidthAddon = bandwidthUsageInGB <= maximumBandwidthAllowed\n\n\tif (canBuyBandwidthAddon) {\n\t\treturn {\n\t\t\tfeature: UpsellFeature.bandwidthInGB,\n\t\t\tbandwidthLimit: bandwidthLimitInGB,\n\t\t\taction: UpsellAction.AddOn,\n\t\t\tbandwidthUsage: bandwidthUsageInGB,\n\t\t}\n\t}\n\n\tconst shouldUpgradeToSelfServe = bandwidthUsageInGB <= MAX_BANDWIDTH_WITH_ADDONS_GB\n\tif (shouldUpgradeToSelfServe) {\n\t\treturn {\n\t\t\tfeature: UpsellFeature.bandwidthInGB,\n\t\t\tbandwidthLimit: bandwidthLimitInGB,\n\t\t\taction: UpsellAction.Upgrade,\n\t\t\tbandwidthUsage: bandwidthUsageInGB,\n\t\t}\n\t}\n\n\t// Don't block publish for upgrading to Enterprise\n\tif (shouldBlockPublish) return null\n\n\treturn {\n\t\tfeature: UpsellFeature.bandwidthInGB,\n\t\tbandwidthLimit: bandwidthLimitInGB,\n\t\taction: UpsellAction.UpgradeToEnterprise,\n\t\tbandwidthUsage: bandwidthUsageInGB,\n\t}\n}\n", "import type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport type { ProjectStore } from \"document/stores/ProjectStore.ts\"\nimport { getCollectionCount } from \"utils/collectionUtils.ts\"\nimport {\n\ttype UpsellAction,\n\tUpsellFeature,\n\tresolveUpsellAction,\n} from \"../../../siteSettings/Plans/Stripe/utils/upsell.ts\"\nimport { MAX_CMS_COLLECTIONS_ON_SELF_SERVE } from \"../../../siteSettings/Usage/constants.ts\"\n\n/** Returns the CMS collections limit and the current collection count, or null if the limit hasn't been reached. */\nexport function cmsCollectionsLimitOnPublish(\n\tprojectStore: ProjectStore,\n\ttree: CanvasTree,\n): { limit: number; count: number } | null {\n\tlet limit = projectStore.resourceLimits?.cmsCollections ?? null\n\tif (limit === null) return null\n\n\t// On a mini plan, we don't want to block the user from publishing if they have 1 collection\n\t// Because we used to allow this in the past, but the new limit has been set to 0\n\tlimit = Math.max(limit, 1)\n\tconst count = getCollectionCount(tree)\n\treturn count > limit ? { limit, count } : null\n}\n\nexport type CmsCollectionsLimitUpsellResult = {\n\tfeature: UpsellFeature.cmsCollections\n\tcmsCollectionsLimit: number\n\taction: UpsellAction\n\tcmsCollectionsCount: number\n}\n\nexport function getCmsCollectionsLimitUpsell({\n\tisEnterprise,\n\tprojectStore,\n\ttree,\n\tmaxCmsCollectionsLimit,\n}: {\n\tisEnterprise: boolean\n\tprojectStore: ProjectStore\n\ttree: CanvasTree\n\tmaxCmsCollectionsLimit?: number | null\n}): CmsCollectionsLimitUpsellResult | null {\n\tconst collections = cmsCollectionsLimitOnPublish(projectStore, tree)\n\tif (collections === null) return null\n\n\treturn {\n\t\tfeature: UpsellFeature.cmsCollections,\n\t\tcmsCollectionsLimit: collections.limit,\n\t\taction: resolveUpsellAction({\n\t\t\tisEnterprise,\n\t\t\tcount: collections.count,\n\t\t\tmaxLimit: maxCmsCollectionsLimit ?? Infinity,\n\t\t\tselfServeMax: MAX_CMS_COLLECTIONS_ON_SELF_SERVE,\n\t\t}),\n\t\tcmsCollectionsCount: collections.count,\n\t}\n}\n", "import type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport type { ProjectStore } from \"document/stores/ProjectStore.ts\"\nimport { getTotalCollectionItemCount } from \"utils/collectionUtils.ts\"\nimport {\n\ttype UpsellAction,\n\tUpsellFeature,\n\tresolveUpsellAction,\n} from \"../../../siteSettings/Plans/Stripe/utils/upsell.ts\"\nimport { MAX_CMS_ITEMS_ON_SELF_SERVE } from \"../../../siteSettings/Usage/constants.ts\"\n\n/** Returns the CMS Items limit and the current Item count, or null if the limit hasn't been reached. */\nfunction cmsItemsLimitOnPublish(projectStore: ProjectStore, tree: CanvasTree): { limit: number; count: number } | null {\n\tconst limit = projectStore.resourceLimits?.cmsItems ?? null\n\tif (limit === null) return null\n\n\tconst count = getTotalCollectionItemCount(tree)\n\treturn count > limit ? { limit, count } : null\n}\n\nexport type CmsItemsLimitUpsellResult = {\n\tfeature: UpsellFeature.cmsItems\n\tcmsItemsLimit: number\n\taction: UpsellAction\n\tcmsItemsCount: number\n}\n\nexport function getCmsItemsLimitUpsell({\n\tisEnterprise,\n\tprojectStore,\n\ttree,\n\tmaxCmsItemsLimit,\n}: {\n\tisEnterprise: boolean\n\tprojectStore: ProjectStore\n\ttree: CanvasTree\n\tmaxCmsItemsLimit?: number | null\n}): CmsItemsLimitUpsellResult | null {\n\tconst items = cmsItemsLimitOnPublish(projectStore, tree)\n\tif (items === null) return null\n\n\treturn {\n\t\tfeature: UpsellFeature.cmsItems,\n\t\tcmsItemsLimit: items.limit,\n\t\taction: resolveUpsellAction({\n\t\t\tisEnterprise,\n\t\t\tcount: items.count,\n\t\t\tmaxLimit: maxCmsItemsLimit ?? Infinity,\n\t\t\tselfServeMax: MAX_CMS_ITEMS_ON_SELF_SERVE,\n\t\t}),\n\t\tcmsItemsCount: items.count,\n\t}\n}\n", "import { getRawWebPagePath } from \"document/components/utils/getWebPagePath.ts\"\nimport type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport { isWebPageNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { ProjectStore } from \"document/stores/ProjectStore.ts\"\nimport { customNotFoundPagePaths } from \"library/router/customNotFoundPagePaths.ts\"\n\nexport function getWebPageNodeCountWithout404(tree: CanvasTree): number {\n\tconst non404webPages = tree.root.children.filter(node => {\n\t\tif (!isWebPageNode(node)) {\n\t\t\treturn false\n\t\t}\n\t\tconst isAbTestingVariant = !!node.abTestingParentId\n\t\tif (isAbTestingVariant) {\n\t\t\treturn false\n\t\t}\n\n\t\tconst path = getRawWebPagePath(tree, node)\n\t\tif (!path) {\n\t\t\t// Page doesn't have a path, so it can't be a 404 page, so we should count it.\n\t\t\treturn true\n\t\t}\n\n\t\treturn !customNotFoundPagePaths.has(path)\n\t})\n\treturn non404webPages.length\n}\n\nexport function pagesLimitOnPublish(\n\tprojectStore: ProjectStore,\n\ttree: CanvasTree,\n): { limit: number; count: number } | null {\n\tconst limit = projectStore.resourceLimits?.pages ?? null\n\tif (limit === null) return null\n\n\tconst count = getWebPageNodeCountWithout404(tree)\n\treturn count > limit ? { limit, count } : null\n}\n", "import type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport type { ProjectStore } from \"document/stores/ProjectStore.ts\"\nimport {\n\ttype UpsellAction,\n\tUpsellFeature,\n\tresolveUpsellAction,\n} from \"../../../siteSettings/Plans/Stripe/utils/upsell.ts\"\nimport { MAX_PAGES_ON_SELF_SERVE } from \"../../../siteSettings/Usage/constants.ts\"\nimport { pagesLimitOnPublish } from \"./publishMultiPageSiteUpsell.ts\"\n\nexport type PagesLimitUpsellResult = {\n\tfeature: UpsellFeature.pages\n\tpagesLimit: number\n\taction: UpsellAction\n\tpagesCount: number\n}\n\nexport function getPagesLimitUpsell({\n\tisEnterprise,\n\tprojectStore,\n\ttree,\n\tmaxPagesLimit,\n}: {\n\tisEnterprise: boolean\n\tprojectStore: ProjectStore\n\ttree: CanvasTree\n\tmaxPagesLimit?: number | null\n}): PagesLimitUpsellResult | null {\n\tconst pages = pagesLimitOnPublish(projectStore, tree)\n\tif (pages === null) return null\n\n\treturn {\n\t\tfeature: UpsellFeature.pages,\n\t\tpagesLimit: pages.limit,\n\t\taction: resolveUpsellAction({\n\t\t\tisEnterprise,\n\t\t\tcount: pages.count,\n\t\t\tmaxLimit: maxPagesLimit ?? Infinity,\n\t\t\tselfServeMax: MAX_PAGES_ON_SELF_SERVE,\n\t\t}),\n\t\tpagesCount: pages.count,\n\t}\n}\n", "import { assertNever } from \"@framerjs/shared\"\nimport { experimentIsOnOrForceEnabled } from \"app/experiments.ts\"\nimport type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport type { Locale } from \"document/models/CanvasTree/traits/WithLocales.ts\"\nimport { isEmptyRichTextValue } from \"utils/isEmptyRichTextValue.ts\"\nimport { isNullish } from \"utils/typeChecks.ts\"\nimport { ClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport type { LocalizationSource } from \"./getLocalizationSources.ts\"\nimport { isSlugSource } from \"./getLocalizationSources.ts\"\nimport { isIncludedInLocale } from \"./includedLocales.ts\"\n\nexport function canBeBatchTranslated(\n\tactiveLocale: Locale,\n\tsource: LocalizationSource,\n\tframerSiteId: string | undefined,\n\temptyValueBehavior?: \"allowEmptyValue\",\n): boolean {\n\tif (source.aiTranslationDisabled) return false\n\tif (isNullish(source.value)) return false\n\tif (source.value === \"\" && emptyValueBehavior !== \"allowEmptyValue\") return false\n\tif (isEmptyRichTextValue(source.value) && emptyValueBehavior !== \"allowEmptyValue\") return false\n\n\tconst status = source.localizedValueStatuses[activeLocale.id]\n\tif (!status) return false\n\n\tswitch (status) {\n\t\tcase \"new\":\n\t\t\treturn true\n\t\tcase \"needsReview\": {\n\t\t\tconst localizedValue = source.localizedValues[activeLocale.id]\n\t\t\tconst generatedByAI = localizedValue?.generatedByAI === true\n\t\t\t// If something has been translated manually before, we don't want to implicitly start\n\t\t\t// translating it with AI.\n\t\t\tconst localizationAiUpdateExperimentEnabled = experimentIsOnOrForceEnabled(\"localizationAiUpdate\", framerSiteId)\n\t\t\tconst managedByAI = localizationAiUpdateExperimentEnabled && activeLocale.managedByAI\n\t\t\tif (!generatedByAI && !managedByAI) return false\n\n\t\t\t// While a locale is a draft, its fine to re-translate anything.\n\t\t\tif (activeLocale.draft) return true\n\n\t\t\t// Slugs of published pages/collection items are risky to re-translate. You might for\n\t\t\t// example want to setup a redirect.\n\t\t\tif (isSlugSource(source)) {\n\t\t\t\tswitch (source.type) {\n\t\t\t\t\tcase \"slug\":\n\t\t\t\t\t\t// No problem if the item is still a draft.\n\t\t\t\t\t\treturn source.collectionItemIsDraft\n\t\t\t\t\tcase ClassDiscriminator.RouteSegmentNode:\n\t\t\t\t\t\t// We could allow this, but we would have to check that the route segment\n\t\t\t\t\t\t// doesn't contain any pages within its sub tree that are not a draft.\n\t\t\t\t\t\treturn false\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tassertNever(source)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true\n\t\t}\n\t\tcase \"done\":\n\t\tcase \"warning\":\n\t\t\treturn false\n\t\tdefault:\n\t\t\tassertNever(status)\n\t}\n}\n\nexport function canBeBatchTranslatedAndVisibleInLocale(\n\ttree: CanvasTree,\n\tactiveLocale: Locale,\n\tsource: LocalizationSource,\n\tframerSiteId: string | undefined,\n\temptyValueBehavior?: \"allowEmptyValue\",\n): boolean {\n\tif (!canBeBatchTranslated(activeLocale, source, framerSiteId, emptyValueBehavior)) return false\n\n\t// Visibility can be configured on either the source's scope or source node.\n\tconst scopeNode = tree.get(source.scopeId)\n\tif (scopeNode && !isIncludedInLocale(tree, scopeNode, activeLocale.id)) return false\n\n\tconst sourceNode = tree.get(source.nodeId)\n\tif (sourceNode && !isIncludedInLocale(tree, sourceNode, activeLocale.id)) return false\n\n\treturn true\n}\n", "import type { LocalizationSourceGroup } from \"document/components/chrome/localization/getLocalizationSources.ts\"\nimport type { Locale } from \"document/models/CanvasTree/traits/WithLocales.ts\"\n\nexport function isGroupExcludedInLocale(group: LocalizationSourceGroup, activeLocale: Locale): boolean {\n\tif (!group) return false\n\tif (!group.supportsLocaleVisibility) return false\n\tif (!group.includedLocaleIds) return false\n\n\treturn !group.includedLocaleIds.includes(activeLocale.id)\n}\n", "import type { Locale } from \"document/models/CanvasTree/traits/WithLocales.ts\"\nimport { isReadonlyArray } from \"utils/typeChecks.ts\"\nimport {\n\ttype LocalizationSource,\n\ttype LocalizationSourceGroup,\n\twithLocalizationSubGroups,\n} from \"./getLocalizationSources.ts\"\nimport { isGroupExcludedInLocale } from \"./isGroupExcludedInLocale.ts\"\n\nconst exitSymbol = Symbol(\"Exit\")\nconst continueSymbol = Symbol(\"Continue\")\n\ntype Exit = typeof exitSymbol\ntype Continue = typeof continueSymbol\ntype ExitOrContinue = Exit | Continue\n\nfunction forEachLocalizationSourceInGroupWithExit(\n\tgroupOrGroups: LocalizationSourceGroup | readonly LocalizationSourceGroup[],\n\tcallback: (item: LocalizationSource) => ExitOrContinue,\n): ExitOrContinue {\n\tif (isReadonlyArray(groupOrGroups)) {\n\t\tfor (const group of groupOrGroups) {\n\t\t\tconst result = forEachLocalizationSourceInGroupWithExit(group, callback)\n\n\t\t\tif (result === exitSymbol) {\n\t\t\t\treturn exitSymbol\n\t\t\t}\n\t\t}\n\n\t\treturn continueSymbol\n\t}\n\n\tconst group = groupOrGroups\n\n\tfor (const item of group.items) {\n\t\tconst result = callback(item)\n\t\tif (result === exitSymbol) {\n\t\t\treturn exitSymbol\n\t\t}\n\t}\n\n\tif (withLocalizationSubGroups(group)) {\n\t\tfor (const subGroup of group.groups) {\n\t\t\tconst result = forEachLocalizationSourceInGroupWithExit(subGroup, callback)\n\t\t\tif (result === exitSymbol) {\n\t\t\t\treturn exitSymbol\n\t\t\t}\n\t\t}\n\t}\n\n\treturn continueSymbol\n}\n\n/**\n * Recursively iterates over all LocalizationSource items in a LocalizationSourceGroup,\n * including those in any subgroups, and calls the provided callback for each item.\n *\n * @param group - The root LocalizationSourceGroup to traverse.\n * @param callback - Function to call for each LocalizationSource found.\n */\nexport function forEachLocalizationSourceInGroup(\n\tgroupOrGroups: LocalizationSourceGroup | readonly LocalizationSourceGroup[],\n\tcallback: (item: LocalizationSource) => void,\n) {\n\treturn forEachLocalizationSourceInGroupWithExit(groupOrGroups, source => {\n\t\tcallback(source)\n\t\treturn continueSymbol\n\t})\n}\n\n/**\n * Recursively iterates over all LocalizationSource items in a LocalizationSourceGroup,\n * including those in any subgroups, and calls the provided callback for each item.\n *\n * @param group - The root LocalizationSourceGroup to traverse.\n * @param activeLocale - The active locale to check if the group is excluded in.\n * @param callback - Function to call for each LocalizationSource found.\n */\nexport function forEachLocalizationSourceInNonExcludedGroups(\n\tgroupOrGroups: LocalizationSourceGroup | readonly LocalizationSourceGroup[],\n\tactiveLocale: Locale,\n\tcallback: (item: LocalizationSource) => void,\n) {\n\tif (isReadonlyArray(groupOrGroups)) {\n\t\tfor (const group of groupOrGroups) {\n\t\t\tforEachLocalizationSourceInNonExcludedGroups(group, activeLocale, callback)\n\t\t}\n\t\treturn\n\t}\n\n\tconst group = groupOrGroups\n\n\tif (isGroupExcludedInLocale(group, activeLocale)) return\n\n\tfor (const item of group.items) {\n\t\tcallback(item)\n\t}\n\n\tif (withLocalizationSubGroups(group)) {\n\t\tfor (const subGroup of group.groups) {\n\t\t\tforEachLocalizationSourceInNonExcludedGroups(subGroup, activeLocale, callback)\n\t\t}\n\t}\n}\n\n/**\n * Checks if any LocalizationSource items in a LocalizationSourceGroup,\n * including those in any subgroups, match the provided callback.\n *\n * @param group - The root LocalizationSourceGroup to traverse.\n * @param callback - Function to call for each LocalizationSource found.\n */\nexport function someLocalizationSourceInGroup(\n\tgroup: LocalizationSourceGroup,\n\tcallback: (item: LocalizationSource) => boolean,\n): boolean {\n\tconst result = forEachLocalizationSourceInGroupWithExit(group, source => {\n\t\tconst match = callback(source)\n\t\treturn match ? exitSymbol : continueSymbol\n\t})\n\n\treturn result === exitSymbol\n}\n", "import type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { assert } from \"@framerjs/shared\"\nimport type {\n\tLocalizationSource,\n\tLocalizationSourceGroup,\n} from \"document/components/chrome/localization/getLocalizationSources.ts\"\nimport {\n\tgetLocalizationSourceGroups,\n\tisEmptyValue,\n\tisEqualLocalizationGroup,\n\tisEqualLocalizationSource,\n\tisImageSource,\n\twithLocalizationSubGroups,\n} from \"document/components/chrome/localization/getLocalizationSources.ts\"\nimport type { CanvasTree, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport type { Locale, LocaleId } from \"document/models/CanvasTree/traits/WithLocales.ts\"\nimport type { LocalizedValue } from \"document/models/LocalizedValue.ts\"\nimport type { RichTextDocument } from \"document/models/richText/RichTextDocument.ts\"\nimport { isEmptyRichTextValue } from \"utils/isEmptyRichTextValue.ts\"\nimport { isShallowObjectEqual } from \"utils/isShallowEqual.ts\"\nimport { isNumber, isString } from \"utils/typeChecks.ts\"\nimport { canBeBatchTranslated } from \"./canBeBatchTranslated.ts\"\nimport { isGroupExcludedInLocale } from \"./isGroupExcludedInLocale.ts\"\nimport { forEachLocalizationSourceInGroup } from \"./localizationSourceGroupUtils.ts\"\n\ntype MutableCountPerLocale = Record<LocaleId, number>\nexport type CountPerLocale = Readonly<MutableCountPerLocale>\n\ntype Hash = number\ntype KeyPath = string\ntype KeyPaths = ReadonlySet<KeyPath>\n\ntype SourceByKeyPath = ReadonlyMap<KeyPath, LocalizationSource>\ntype KeyPathsByHash = ReadonlyMap<Hash, KeyPaths>\ntype GroupById = ReadonlyMap<NodeID, LocalizationSourceGroup>\n\nexport interface LocalizationSourceState {\n\treadonly tree: CanvasTree\n\treadonly locales: readonly Locale[] | undefined\n\treadonly componentsHash: string\n\treadonly batchTranslatableItemCountPerLocale: CountPerLocale\n\treadonly progressPerLocale: CountPerLocale\n\treadonly translatedWordCountPerLocale: CountPerLocale\n\treadonly totalTranslatedItemCount: number\n\treadonly groups: readonly LocalizationSourceGroup[]\n\treadonly sourceByKeyPath: SourceByKeyPath\n\treadonly groupById: GroupById\n\treadonly keyPathsByHash: KeyPathsByHash\n}\n\nconst noLocalesProgress: CountPerLocale = {}\nconst noTranslatedWordsPerLocale: CountPerLocale = {}\n\nfunction isEmptyLocalizedValue(localizedValue: LocalizedValue<string | RichTextDocument> | undefined): boolean {\n\tif (!localizedValue || localizedValue.value === null) return true\n\tif (localizedValue.type === \"rich-text\") return isEmptyRichTextValue(localizedValue.value)\n\treturn isString(localizedValue.value) ? isEmptyValue(localizedValue.value) : false\n}\n\nexport function isHiddenLocalizationSource(source: LocalizationSource, localeId: LocaleId) {\n\tif (isImageSource(source)) return false\n\n\treturn isEmptyValue(source.value) && isEmptyLocalizedValue(source.localizedValues[localeId])\n}\n\nexport function isTranslatedLocalizationSource(source: LocalizationSource, localeId: LocaleId) {\n\tconst status = source.localizedValueStatuses[localeId]\n\tif (!status || status === \"new\") return false\n\n\tconst localizedValue = source.localizedValues[localeId]\n\tif (!localizedValue) return false\n\n\treturn localizedValue.value !== null\n}\n\nfunction getProgressAndCountsPerLocale(\n\tgroups: readonly LocalizationSourceGroup[],\n\toptionalLocales: readonly Locale[] | undefined,\n\tpreviousState: LocalizationSourceState | undefined,\n\tframerSiteId?: string,\n): Pick<\n\tLocalizationSourceState,\n\t| \"progressPerLocale\"\n\t| \"totalTranslatedItemCount\"\n\t| \"translatedWordCountPerLocale\"\n\t| \"batchTranslatableItemCountPerLocale\"\n> {\n\tif (!optionalLocales || optionalLocales.length === 0) {\n\t\treturn {\n\t\t\tprogressPerLocale: noLocalesProgress,\n\t\t\ttotalTranslatedItemCount: 0,\n\t\t\ttranslatedWordCountPerLocale: noTranslatedWordsPerLocale,\n\t\t\tbatchTranslatableItemCountPerLocale: noTranslatedWordsPerLocale,\n\t\t}\n\t}\n\n\tconst locales = optionalLocales\n\n\tlet totalTranslatedItemCount = 0\n\n\tconst localeIds = locales.map(locale => locale.id)\n\n\tconst finishedItemsPerLocale: MutableCountPerLocale = Object.fromEntries(localeIds.map(id => [id, 0]))\n\tconst itemCountPerLocale = { ...finishedItemsPerLocale }\n\tconst translatedWordCountPerLocale = { ...finishedItemsPerLocale }\n\tconst batchTranslatableItemCountPerLocale = { ...finishedItemsPerLocale }\n\n\tfunction handleGroup(group: LocalizationSourceGroup) {\n\t\tif (withLocalizationSubGroups(group)) {\n\t\t\tfor (const subGroup of group.groups) {\n\t\t\t\thandleGroup(subGroup)\n\t\t\t}\n\t\t}\n\n\t\tfor (const source of group.items) {\n\t\t\tconst statuses = source.localizedValueStatuses\n\t\t\tfor (const locale of locales) {\n\t\t\t\tconst localeId = locale.id\n\n\t\t\t\tif (isGroupExcludedInLocale(group, locale)) continue\n\n\t\t\t\tif (canBeBatchTranslated(locale, source, framerSiteId)) {\n\t\t\t\t\tconst currentLocaleCount = batchTranslatableItemCountPerLocale[locale.id]\n\t\t\t\t\tassert(isNumber(currentLocaleCount))\n\t\t\t\t\tbatchTranslatableItemCountPerLocale[locale.id] = currentLocaleCount + 1\n\t\t\t\t}\n\n\t\t\t\tif (!isHiddenLocalizationSource(source, localeId)) {\n\t\t\t\t\tconst currentItemCount = itemCountPerLocale[localeId]\n\t\t\t\t\tassert(isNumber(currentItemCount))\n\n\t\t\t\t\tconst localizedValue = source.localizedValues[localeId]\n\t\t\t\t\tconst status = statuses[localeId]\n\n\t\t\t\t\t// Images without alt text are `done` without requiring a translation, but\n\t\t\t\t\t// should not impact progress in that case. Same for slugs.\n\t\t\t\t\tconst shouldIgnoreForCount = status === \"done\" && !localizedValue\n\t\t\t\t\tif (shouldIgnoreForCount) continue\n\n\t\t\t\t\titemCountPerLocale[localeId] = currentItemCount + 1\n\n\t\t\t\t\tif (isTranslatedLocalizationSource(source, localeId)) {\n\t\t\t\t\t\ttotalTranslatedItemCount++\n\n\t\t\t\t\t\tconst currentTranslatedWordsPerLocale = translatedWordCountPerLocale[localeId]\n\t\t\t\t\t\tassert(isNumber(currentTranslatedWordsPerLocale))\n\t\t\t\t\t\ttranslatedWordCountPerLocale[localeId] = currentTranslatedWordsPerLocale + source.valueWordCount\n\t\t\t\t\t}\n\n\t\t\t\t\tif (status === \"done\") {\n\t\t\t\t\t\tconst currentFinishedCount = finishedItemsPerLocale[localeId]\n\t\t\t\t\t\tassert(isNumber(currentFinishedCount))\n\n\t\t\t\t\t\tfinishedItemsPerLocale[localeId] = currentFinishedCount + 1\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const group of groups) {\n\t\thandleGroup(group)\n\t}\n\n\tconst progressPerLocale = Object.fromEntries(\n\t\tObject.entries(finishedItemsPerLocale).map(([localeId, count]) => {\n\t\t\tconst itemCount = itemCountPerLocale[localeId]\n\t\t\tassert(isNumber(itemCount))\n\t\t\tconst progress = itemCount === 0 ? 1 : count / itemCount\n\t\t\treturn [localeId, progress]\n\t\t}),\n\t)\n\n\tconst previousProgressPerLocale = previousState?.progressPerLocale\n\n\treturn {\n\t\ttotalTranslatedItemCount,\n\t\ttranslatedWordCountPerLocale,\n\t\tbatchTranslatableItemCountPerLocale,\n\t\tprogressPerLocale:\n\t\t\tpreviousProgressPerLocale && isShallowObjectEqual(previousProgressPerLocale, progressPerLocale)\n\t\t\t\t? previousProgressPerLocale\n\t\t\t\t: progressPerLocale,\n\t}\n}\n\nfunction getGroupById(\n\tgroups: readonly LocalizationSourceGroup[],\n\tresult: Map<NodeID, LocalizationSourceGroup> = new Map(),\n): Map<NodeID, LocalizationSourceGroup> {\n\tfor (const group of groups) {\n\t\tresult.set(group.nodeId, group)\n\n\t\tif (withLocalizationSubGroups(group)) {\n\t\t\tgetGroupById(group.groups, result)\n\t\t}\n\t}\n\n\treturn result\n}\n\nfunction getSourceByKeyPathAndKeyPathsByHash(groups: readonly LocalizationSourceGroup[]): {\n\tsourceByKeyPath: SourceByKeyPath\n\tkeyPathsByHash: KeyPathsByHash\n} {\n\tconst sourceByKeyPath = new Map<KeyPath, LocalizationSource>()\n\tconst keyPathsByHash = new Map<Hash, Set<KeyPath>>()\n\n\tforEachLocalizationSourceInGroup(groups, source => {\n\t\tsourceByKeyPath.set(source.keyPath, source)\n\n\t\tconst keyPaths = keyPathsByHash.get(source.hash) ?? new Set()\n\t\tkeyPaths.add(source.keyPath)\n\t\tkeyPathsByHash.set(source.hash, keyPaths)\n\t})\n\n\treturn { sourceByKeyPath, keyPathsByHash }\n}\n\nfunction reusePreviousSourcesIfUnchanged(\n\tsources: readonly LocalizationSource[],\n\tpreviousSources: readonly LocalizationSource[],\n\tpreviousState: LocalizationSourceState,\n): readonly LocalizationSource[] {\n\tlet hasChanges = sources.length !== previousSources.length\n\tconst withReusedSources = sources.map(source => {\n\t\tconst previousSource = previousState.sourceByKeyPath.get(source.keyPath)\n\t\tif (previousSource && isEqualLocalizationSource(previousSource, source)) {\n\t\t\treturn previousSource\n\t\t}\n\t\thasChanges = true\n\t\treturn source\n\t})\n\n\treturn hasChanges ? withReusedSources : previousSources\n}\n\nfunction reusePreviousSourceGroupsIfUnchanged(\n\tgroups: readonly LocalizationSourceGroup[],\n\tpreviousGroups: readonly LocalizationSourceGroup[] | undefined,\n\tpreviousState: LocalizationSourceState | undefined,\n): readonly LocalizationSourceGroup[] {\n\tif (!previousState || !previousGroups) return groups\n\n\tlet hasChanges = groups.length !== previousGroups.length\n\tconst withReusedGroups = groups.map(group => {\n\t\tconst previousGroup = previousState.groupById.get(group.nodeId)\n\t\tif (!previousGroup) {\n\t\t\thasChanges = true\n\t\t\treturn group\n\t\t}\n\n\t\tconst reusedSources = reusePreviousSourcesIfUnchanged(group.items, previousGroup.items, previousState)\n\n\t\tconst groupWithReusedItems: LocalizationSourceGroup = { ...group, items: reusedSources }\n\n\t\tif (withLocalizationSubGroups(groupWithReusedItems)) {\n\t\t\tassert(withLocalizationSubGroups(previousGroup))\n\t\t\tgroupWithReusedItems.groups = reusePreviousSourceGroupsIfUnchanged(\n\t\t\t\tgroupWithReusedItems.groups,\n\t\t\t\tpreviousGroup.groups,\n\t\t\t\tpreviousState,\n\t\t\t)\n\t\t}\n\n\t\tif (isEqualLocalizationGroup(previousGroup, groupWithReusedItems)) {\n\t\t\treturn previousGroup\n\t\t}\n\n\t\thasChanges = true\n\t\treturn groupWithReusedItems\n\t})\n\n\treturn hasChanges ? withReusedGroups : previousGroups\n}\n\nexport function calculateLocalizationSourceState(\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tcomponentsHash: string,\n\tpreviousState: LocalizationSourceState | undefined,\n\tframerSiteId?: string,\n): LocalizationSourceState {\n\t// We compare trees with .equals, so data only trees can pass the check.\n\tif (previousState && previousState.componentsHash === componentsHash && previousState.tree.equals(tree)) {\n\t\treturn previousState\n\t}\n\n\tconst locales = tree.root.locales\n\n\tconst latestSourceGroups = getLocalizationSourceGroups(\n\t\ttree,\n\t\tcomponentLoader,\n\t\tlocales,\n\t\tcomponentsHash,\n\t\t\"canvasHtmlAsTextContentIfPossible\",\n\t)\n\tconst groups = reusePreviousSourceGroupsIfUnchanged(latestSourceGroups, previousState?.groups, previousState)\n\n\tlet groupById: GroupById\n\tlet sourceByKeyPath: SourceByKeyPath\n\tlet keyPathsByHash: KeyPathsByHash\n\n\tconst groupsUnchanged = previousState?.groups === groups\n\tif (groupsUnchanged) {\n\t\tgroupById = previousState.groupById\n\t\tsourceByKeyPath = previousState.sourceByKeyPath\n\t\tkeyPathsByHash = previousState.keyPathsByHash\n\t} else {\n\t\tgroupById = getGroupById(groups)\n\n\t\tconst sourceByKeyPathAndKeyPathsByHash = getSourceByKeyPathAndKeyPathsByHash(groups)\n\t\tsourceByKeyPath = sourceByKeyPathAndKeyPathsByHash.sourceByKeyPath\n\t\tkeyPathsByHash = sourceByKeyPathAndKeyPathsByHash.keyPathsByHash\n\t}\n\n\tlet progressPerLocale: CountPerLocale\n\tlet totalTranslatedItemCount: number\n\tlet translatedWordCountPerLocale: CountPerLocale\n\tlet batchTranslatableItemCountPerLocale: CountPerLocale\n\n\tif (groupsUnchanged && previousState.locales === locales) {\n\t\tprogressPerLocale = previousState.progressPerLocale\n\t\ttotalTranslatedItemCount = previousState.totalTranslatedItemCount\n\t\ttranslatedWordCountPerLocale = previousState.translatedWordCountPerLocale\n\t\tbatchTranslatableItemCountPerLocale = previousState.batchTranslatableItemCountPerLocale\n\t} else {\n\t\tconst calculatedProgress = getProgressAndCountsPerLocale(groups, locales, previousState, framerSiteId)\n\t\tprogressPerLocale = calculatedProgress.progressPerLocale\n\t\ttotalTranslatedItemCount = calculatedProgress.totalTranslatedItemCount\n\t\ttranslatedWordCountPerLocale = calculatedProgress.translatedWordCountPerLocale\n\t\tbatchTranslatableItemCountPerLocale = calculatedProgress.batchTranslatableItemCountPerLocale\n\t}\n\n\treturn {\n\t\ttree,\n\t\tlocales,\n\t\tcomponentsHash,\n\t\tgroups,\n\t\tgroupById,\n\t\tbatchTranslatableItemCountPerLocale,\n\t\tprogressPerLocale,\n\t\ttotalTranslatedItemCount,\n\t\tsourceByKeyPath,\n\t\tkeyPathsByHash,\n\t\ttranslatedWordCountPerLocale,\n\t}\n}\n", "import { ProjectLicenseType } from \"@framerjs/app-shared\"\nimport { type BaseEngine, useBaseEngine } from \"document/base-engine/BaseEngine.ts\"\nimport { useDeprecatedEngineState } from \"document/useDeprecatedEngineState.ts\"\nimport { isVekterEngine } from \"document/useVekterEngine.ts\"\n\nexport interface TranslationLimits {\n\tmaxTranslatableWords: number\n\tcurrentTranslatedWords: number\n\tcanUseCustomAiInstructions: boolean\n\tcanUseCustomLocaleRegions: boolean\n\tcanAddTranslation: boolean\n\thasWordLimit: boolean\n\tisOverWordLimit: boolean\n}\n\nexport function getTranslationLimits(engine: BaseEngine): TranslationLimits {\n\tconst maxTranslatableWords = engine.stores.projectStore.resourceLimits?.translatableWords ?? Infinity\n\tconst selectedLocaleId = isVekterEngine(engine) ? engine.stores.localizationStore.selectedLocaleId : null\n\tconst currentTranslatedWords: number =\n\t\tselectedLocaleId && isVekterEngine(engine)\n\t\t\t? engine.stores.localizationStore.getTranslatedWordCountForLocale(selectedLocaleId)\n\t\t\t: 0\n\tconst canUseCustomAiInstructions =\n\t\tengine.stores.projectStore.featureFlags?.canUseLocalizationCustomAiInstructions === \"on\"\n\tconst canUseCustomLocaleRegions = engine.stores.projectStore.featureFlags?.canUseCustomLocaleRegions === \"on\"\n\n\tconst projectLicenseType = engine.stores.projectStore.projectLicenseType\n\tconst hasWordLimit = projectLicenseType !== ProjectLicenseType.EnterpriseSite && maxTranslatableWords < Infinity\n\tconst canAddTranslation = currentTranslatedWords < maxTranslatableWords\n\tconst isOverWordLimit = currentTranslatedWords > maxTranslatableWords\n\n\treturn {\n\t\tmaxTranslatableWords,\n\t\tcurrentTranslatedWords,\n\t\tcanAddTranslation,\n\t\thasWordLimit,\n\t\tisOverWordLimit,\n\t\tcanUseCustomAiInstructions,\n\t\tcanUseCustomLocaleRegions,\n\t}\n}\n\nexport function useTranslationLimits(): TranslationLimits {\n\tconst engine = useBaseEngine()\n\tconst changeFlags = isVekterEngine(engine) ? [engine.stores.projectStore, engine.stores.localizationStore] : []\n\treturn useDeprecatedEngineState(changeFlags, () => getTranslationLimits(engine))\n}\n", "import { AddOnLicenseType, ProjectLicenseType, openNewTab } from \"@framerjs/app-shared\"\nimport type { ModalOpenSource } from \"@framerjs/events\"\nimport { assertNever } from \"@framerjs/shared\"\nimport { Dictionary } from \"app/dictionary.ts\"\nimport type { BaseEngine } from \"document/base-engine/BaseEngine.ts\"\nimport {\n\ttype UpsellAction,\n\tUpsellFeature,\n\tresolveUpsellAction,\n} from \"document/components/chrome/siteSettings/Plans/Stripe/utils/upsell.ts\"\nimport { MAX_LOCALES_ON_SELF_SERVE } from \"document/components/chrome/siteSettings/Usage/constants.ts\"\nimport type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport type { Locale } from \"document/models/CanvasTree/traits/WithLocales.ts\"\nimport type { ProjectStore } from \"document/stores/ProjectStore.ts\"\nimport { ModalType } from \"document/utils/ModalType.ts\"\nimport { enterpriseUpsellURL } from \"utils/staticURLs.ts\"\nimport { isTranslatedLocalizationSource } from \"../../../localization/calculateLocalizationSourceState.ts\"\nimport type { LocalizationSource } from \"../../../localization/getLocalizationSources.ts\"\nimport { getTranslationLimits } from \"../../../localization/getTranslationLimits.ts\"\n\nexport function getLocalesCount(tree: CanvasTree, includeDrafts: boolean): number {\n\tif (!tree.root.locales) return 0\n\tif (includeDrafts) return tree.root.locales.length\n\treturn tree.root.locales.filter(locale => locale.draft === false).length\n}\n\n/** Returns the locales limit and the current locale count, or null if the limit hasn't been reached. */\nfunction localesLimitOnPublish(\n\tprojectStore: ProjectStore,\n\ttree: CanvasTree,\n\tincludeDrafts: boolean,\n): { limit: number; count: number } | null {\n\tconst { resourceLimits } = projectStore\n\tconst limit = resourceLimits?.locales ?? null\n\tif (limit === null) return null\n\n\tconst count = getLocalesCount(tree, includeDrafts)\n\treturn count > limit ? { limit, count } : null\n}\n\nexport enum UpsellMode {\n\tPublish = 0,\n\tToast = 1,\n}\n\nexport type LocalesLimitUpsellResult = {\n\tfeature: UpsellFeature.localeAddon\n\tlocalesLimit: number\n\taction: UpsellAction\n\tlocalesCount: number\n}\n\nexport function getLimitForLocalesUpsell({\n\tprojectStore,\n\ttree,\n\tupsellMode,\n}: {\n\tprojectStore: ProjectStore\n\ttree: CanvasTree\n\tupsellMode: UpsellMode\n}): LocalesLimitUpsellResult | null {\n\tconst locales = localesLimitOnPublish(projectStore, tree, upsellMode === UpsellMode.Toast)\n\tif (locales === null) return null\n\n\tconst isEnterprise = projectStore.projectLicenseType === ProjectLicenseType.EnterpriseSite\n\n\treturn {\n\t\tfeature: UpsellFeature.localeAddon,\n\t\tlocalesLimit: locales.limit,\n\t\taction: resolveUpsellAction({\n\t\t\tisEnterprise,\n\t\t\tcount: locales.count,\n\t\t\tmaxLimit: projectStore.resourceLimits?.maxLocales ?? Infinity,\n\t\t\tselfServeMax: MAX_LOCALES_ON_SELF_SERVE,\n\t\t}),\n\t\tlocalesCount: locales.count,\n\t}\n}\n\n/** Shows the translation limit upsell modal, returns true if the modal was shown.\n * This function does not check for the translatable word limit itself.\n */\nexport function showLocalizationTranslationLimitUpsell(engine: BaseEngine, source: ModalOpenSource): boolean {\n\tconst projectLicenseType = engine.stores.projectStore.projectLicenseType\n\tswitch (projectLicenseType) {\n\t\tcase ProjectLicenseType.FreeSite: {\n\t\t\tengine.stores.modalStore.set({\n\t\t\t\ttype: ModalType.UpsellFeature,\n\t\t\t\tsource,\n\t\t\t\tupsellFeature: UpsellFeature.translatableWords,\n\t\t\t\ttitle: \"Upgrade Site\",\n\t\t\t\tdescription:\n\t\t\t\t\t\"Upgrade your site to add more locales with unlimited translations, plus other features like setting a custom AI style.\",\n\t\t\t})\n\t\t\treturn true\n\t\t}\n\t\tcase ProjectLicenseType.MiniSite:\n\t\tcase ProjectLicenseType.BasicSite:\n\t\tcase ProjectLicenseType.ProSite:\n\t\t// It is true that this shouldn't be possible,\n\t\t// but we currently lower down the translatable limit for all plans\n\t\t// in the case of unpaid locales. See getTranslationLimits\n\t\tcase ProjectLicenseType.LaunchSite:\n\t\tcase ProjectLicenseType.ScaleSite:\n\t\tcase ProjectLicenseType.BasicSite2025:\n\t\tcase ProjectLicenseType.ProSite2025:\n\t\tcase ProjectLicenseType.ScaleSite2025: {\n\t\t\t// A user has got a free locale with limited words,\n\t\t\t// force them to purchase a locale add-on\n\t\t\tengine.stores.modalStore.set({\n\t\t\t\ttype: ModalType.Confirmation,\n\t\t\t\tsource,\n\t\t\t\ttitle: \"Upgrade your Locale\",\n\t\t\t\tdescription: \"Buy a locale to unlock unlimited words\",\n\t\t\t\tconfirmLabel: \"Buy Locale\",\n\t\t\t\tcancelLabel: Dictionary.MaybeLater,\n\t\t\t\tavoidDismissOnConfirm: true,\n\t\t\t\tonConfirm: () => {\n\t\t\t\t\tengine.stores.modalStore.set({\n\t\t\t\t\t\ttype: ModalType.AcquireAddonModal,\n\t\t\t\t\t\taddonInfo: {\n\t\t\t\t\t\t\taddonLicenseType: AddOnLicenseType.Locale,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsource,\n\t\t\t\t\t})\n\t\t\t\t},\n\t\t\t})\n\t\t\treturn true\n\t\t}\n\t\tcase ProjectLicenseType.EnterpriseSite: {\n\t\t\t// This should never happen for the enterprise plan, but it can\n\t\t\t// if the locale resource limit override is misconfigured, because\n\t\t\t// we currently lower down the translatable limit for all plans\n\t\t\t// in the case of unpaid locales. See getTranslationLimits\n\t\t\tengine.stores.modalStore.set({\n\t\t\t\ttype: ModalType.Confirmation,\n\t\t\t\tsource,\n\t\t\t\ttitle: \"Upgrade your Locale\",\n\t\t\t\tdescription: \"Please contact us to upgrade your locale and unlock unlimited words.\",\n\t\t\t\tconfirmLabel: Dictionary.ContactUs,\n\t\t\t\tcancelLabel: Dictionary.Cancel,\n\t\t\t\tonConfirm: () => openNewTab(enterpriseUpsellURL),\n\t\t\t})\n\t\t\treturn true\n\t\t}\n\t\tdefault:\n\t\t\tassertNever(projectLicenseType)\n\t}\n}\n\n/** Checks if the translations are over the word limit, shows an upsell.\n * Returns true if the upsell was shown, false otherwise.\n */\nexport function upsellTranslatableWordLimit(engine: BaseEngine, source: ModalOpenSource): boolean {\n\tconst { isOverWordLimit } = getTranslationLimits(engine)\n\n\tif (!isOverWordLimit) return false\n\n\treturn showLocalizationTranslationLimitUpsell(engine, source)\n}\n\n/** Checks if a new translation can be added or if the source has been translated,\n * if not shows an upsell. Returns true if the upsell was shown, false otherwise.\n */\nexport function upsellLocalizationTranslationLimit(\n\tengine: BaseEngine,\n\tsource: LocalizationSource,\n\tactiveLocale: Locale,\n\tmodalSource: ModalOpenSource,\n): boolean {\n\tconst { canAddTranslation } = getTranslationLimits(engine)\n\tconst isTranslated = isTranslatedLocalizationSource(source, activeLocale.id)\n\n\tif (isTranslated || canAddTranslation) return false\n\n\treturn showLocalizationTranslationLimitUpsell(engine, modalSource)\n}\n\n/** Checks if the user can use batch AI translation.\n * Shows an upsell and returns true if the user can use batch AI translation, false otherwise.\n */\nexport function upsellTranslateAll(engine: BaseEngine, source: ModalOpenSource): boolean {\n\tconst canUseBatchAITranslation = engine.stores.projectStore.featureFlags?.canUseBatchAITranslation === \"on\"\n\n\tif (!canUseBatchAITranslation) {\n\t\tengine.stores.modalStore.set({\n\t\t\ttype: ModalType.UpsellFeature,\n\t\t\tupsellFeature: UpsellFeature.canUseBatchAITranslation,\n\t\t\ttitle: \"AI Batch Translations\",\n\t\t\tdescription: \"Upgrade your site to gain access to AI-powered one-click Locale translations.\",\n\t\t\tsource,\n\t\t})\n\t\treturn true\n\t}\n\n\treturn false\n}\n", "import type { ProjectStore } from \"document/stores/ProjectStore.ts\"\nimport type { PublishStore } from \"document/stores/PublishStore.ts\"\n\n/**\n * Returns true if the user has deployed to a custom domain, but should not be able to publish to it anymore.\n * Used to block the \"Publish\" button in the toolbar and show the \"Upgrade your site\" modal.\n */\nexport function shouldUpsellRecoverCustomDomain(projectStore: ProjectStore, publishStore: PublishStore) {\n\tconst canPublishToCustomDomainIsUpsell = projectStore.featureFlags?.canPublishToCustomDomain === \"upsell\"\n\n\treturn Boolean(\n\t\tcanPublishToCustomDomainIsUpsell &&\n\t\tpublishStore.customHostnameDeployment &&\n\t\tpublishStore.customHostname &&\n\t\t!publishStore.isFreeDomain(publishStore.customHostname.hostname),\n\t)\n}\n", "import { ProjectLicenseType } from \"@framerjs/app-shared\"\nimport { UpsellFeature } from \"../../siteSettings/Plans/Stripe/utils/upsell.ts\"\nimport { BandwidthEvaluationMode, getBandwidthLimitUpsell } from \"./utils/bandwidthUpsellModals.tsx\"\nimport type { BandwidthLimitUpsellResult } from \"./utils/bandwidthUpsellModals.tsx\"\nimport { getCmsCollectionsLimitUpsell } from \"./utils/getCmsCollectionsLimitUpsell.tsx\"\nimport type { CmsCollectionsLimitUpsellResult } from \"./utils/getCmsCollectionsLimitUpsell.tsx\"\nimport { getCmsItemsLimitUpsell } from \"./utils/getCmsItemsLimitUpsell.tsx\"\nimport type { CmsItemsLimitUpsellResult } from \"./utils/getCmsItemsLimitUpsell.tsx\"\nimport { getPagesLimitUpsell } from \"./utils/getPagesLimitUpsell.ts\"\nimport type { PagesLimitUpsellResult } from \"./utils/getPagesLimitUpsell.ts\"\nimport { UpsellMode, getLimitForLocalesUpsell } from \"./utils/localizationUpsellModals.tsx\"\nimport type { LocalesLimitUpsellResult } from \"./utils/localizationUpsellModals.tsx\"\nimport { shouldUpsellRecoverCustomDomain } from \"./utils/recoverCustomDomainUpsell.ts\"\n\nimport type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport type { ProjectStore } from \"document/stores/ProjectStore.ts\"\nimport type { PublishStore } from \"document/stores/PublishStore.ts\"\n\ninterface GetUpsellParams {\n\tprojectStore: ProjectStore\n\ttree: CanvasTree\n\tpublishStore: PublishStore\n}\n\ninterface CustomDomainRecoverUpsellResult {\n\tfeature: UpsellFeature.customDomainRecoverUpsell\n}\n\nexport type PublishLimitUpsell =\n\t| PagesLimitUpsellResult\n\t| CmsCollectionsLimitUpsellResult\n\t| CmsItemsLimitUpsellResult\n\t| LocalesLimitUpsellResult\n\t| BandwidthLimitUpsellResult\n\t| CustomDomainRecoverUpsellResult\n\nexport const getPublishBlockingUpsell = (params: GetUpsellParams): PublishLimitUpsell | null => {\n\tconst { projectStore, tree, publishStore } = params\n\tconst project = projectStore.project\n\tconst resourceLimits = projectStore.resourceLimits\n\tconst isEnterprise = project?.license.type === ProjectLicenseType.EnterpriseSite\n\n\treturn (\n\t\tgetCmsCollectionsLimitUpsell({\n\t\t\tisEnterprise,\n\t\t\tprojectStore,\n\t\t\ttree,\n\t\t\tmaxCmsCollectionsLimit: resourceLimits?.maxCmsCollections ?? null,\n\t\t}) ||\n\t\tgetCmsItemsLimitUpsell({\n\t\t\tisEnterprise,\n\t\t\tprojectStore,\n\t\t\ttree,\n\t\t\tmaxCmsItemsLimit: resourceLimits?.maxCmsItems ?? null,\n\t\t}) ||\n\t\tgetPagesLimitUpsell({\n\t\t\tisEnterprise,\n\t\t\tprojectStore,\n\t\t\ttree,\n\t\t\tmaxPagesLimit: resourceLimits?.maxPages ?? null,\n\t\t}) ||\n\t\tgetLimitForLocalesUpsell({ projectStore, tree, upsellMode: UpsellMode.Publish }) ||\n\t\tgetRecoverCustomDomainUpsell({ projectStore, publishStore }) ||\n\t\tgetBandwidthLimitUpsell({\n\t\t\tprojectStore,\n\t\t\tevaluationMode: BandwidthEvaluationMode.PublishBlock,\n\t\t})\n\t)\n}\n\n/** Prioritizes publish blocking upsell detection, but can return one that doesn't block publish as well\n */\nexport const getUpsell = (params: GetUpsellParams): PublishLimitUpsell | null => {\n\tconst { projectStore, tree, publishStore } = params\n\treturn (\n\t\tgetPublishBlockingUpsell({ projectStore, tree, publishStore }) ||\n\t\tgetLimitForLocalesUpsell({\n\t\t\tprojectStore,\n\t\t\ttree,\n\t\t\tupsellMode: UpsellMode.Toast,\n\t\t}) ||\n\t\tgetBandwidthLimitUpsell({\n\t\t\tprojectStore,\n\t\t\tevaluationMode: BandwidthEvaluationMode.PublishToast,\n\t\t})\n\t)\n}\n\nfunction getRecoverCustomDomainUpsell({\n\tprojectStore,\n\tpublishStore,\n}: {\n\tprojectStore: GetUpsellParams[\"projectStore\"]\n\tpublishStore: GetUpsellParams[\"publishStore\"]\n}): CustomDomainRecoverUpsellResult | null {\n\tif (shouldUpsellRecoverCustomDomain(projectStore, publishStore)) {\n\t\treturn { feature: UpsellFeature.customDomainRecoverUpsell }\n\t}\n\n\treturn null\n}\n", "import { openNewTab } from \"@framerjs/app-shared\"\nimport {\n\tdnsRecordsArticleURL,\n\tnewIpAddressesArticleURL,\n\toptimizationSupportArticleURL,\n\tpublishingAcademyLessonURL,\n} from \"utils/staticURLs.ts\"\n\nexport function openOptimizationSupportArticle() {\n\topenNewTab(optimizationSupportArticleURL)\n}\n\nexport function openPublishingSupportArticle() {\n\topenNewTab(publishingAcademyLessonURL)\n}\n\nexport function openDNSRecordsArticle() {\n\topenNewTab(dnsRecordsArticleURL)\n}\n\nexport function openNewIpAddressesArticle() {\n\topenNewTab(newIpAddressesArticleURL)\n}\n", "import { Dictionary } from \"app/dictionary.ts\"\nimport { toast } from \"web/lib/toaster.ts\"\nimport { openPublishingSupportArticle } from \"../../openSupportArticle.ts\"\n\n// It doesn't make sense for these toasts to stack, especially since some of\n// them linger on screen until explicitly dismissed. E.g., if you add a domain,\n// and the remove it, the \"removed\" toast should just replace the \"added, please\n// configure\" toast.\nconst key = \"custom-domain-status\"\n\nexport function toastDomainAdded() {\n\ttoast({\n\t\ttype: \"add\",\n\t\tvariant: \"success\",\n\t\tprimaryText: \"Domain added.\",\n\t\tsecondaryText: \"Set-up DNS to continue.\",\n\t\tkey,\n\t\ticon: \"success\",\n\t\tduration: 8000,\n\t\taction: {\n\t\t\ttitle: Dictionary.LearnMore,\n\t\t\tonClick: openPublishingSupportArticle,\n\t\t},\n\t})\n}\n\nexport function toastFreeDomainConnected() {\n\ttoast({\n\t\ttype: \"add\",\n\t\tvariant: \"success\",\n\t\tprimaryText: \"Domain connected\",\n\t\tsecondaryText: \"successfully.\",\n\t\tkey,\n\t\ticon: \"success\",\n\t})\n}\n\nexport function toastDomainConnected() {\n\ttoast({\n\t\ttype: \"add\",\n\t\tvariant: \"success\",\n\t\tprimaryText: \"Domain connected.\",\n\t\tsecondaryText: \"Changes may take 48h.\",\n\t\tkey,\n\t\ticon: \"success\",\n\t\tduration: Infinity,\n\t})\n}\n\nexport function toastValidateDomainError() {\n\ttoast({\n\t\ttype: \"add\",\n\t\tvariant: \"error\",\n\t\tprimaryText: \"Failed to validate\",\n\t\tsecondaryText: \"your DNS settings.\",\n\t\tkey: \"custom-domain-validation-error\",\n\t\ticon: \"error\",\n\t})\n}\n\nexport function toastDomainStatusConnected() {\n\ttoast({\n\t\ttype: \"add\",\n\t\tvariant: \"success\",\n\t\tprimaryText: \"Your custom domain\",\n\t\tsecondaryText: \"is connected.\",\n\t\tkey,\n\t\ticon: \"success\",\n\t})\n}\n\nexport function toastDomainStatusInvalid() {\n\ttoast({\n\t\ttype: \"add\",\n\t\tvariant: \"error\",\n\t\tprimaryText: \"Issues detected\",\n\t\tsecondaryText: \"with your custom domain.\",\n\t\tkey,\n\t\ticon: \"error\",\n\t})\n}\n\nexport function toastDomainStatusError() {\n\ttoast({\n\t\ttype: \"add\",\n\t\tvariant: \"error\",\n\t\tprimaryText: \"Failed to reload\",\n\t\tsecondaryText: \"your domain status.\",\n\t\tkey,\n\t\ticon: \"error\",\n\t})\n}\n\nexport function toastFreeDomainRemoved() {\n\ttoast({\n\t\ttype: \"add\",\n\t\tvariant: \"success\",\n\t\tprimaryText: \"Domain removed\",\n\t\tsecondaryText: \"successfully.\",\n\t\tkey,\n\t\ticon: \"success\",\n\t})\n}\n\nexport function toastCustomDomainRemoved() {\n\ttoast({\n\t\ttype: \"add\",\n\t\tvariant: \"success\",\n\t\tprimaryText: \"Domain removed.\",\n\t\tsecondaryText: \"Please revert DNS records.\",\n\t\tkey,\n\t\ticon: \"success\",\n\t\tduration: Infinity,\n\t})\n}\n\nexport function toastRemoveDomainError() {\n\ttoast({\n\t\ttype: \"add\",\n\t\tvariant: \"error\",\n\t\tprimaryText: \"Your custom domain\",\n\t\tsecondaryText: \"could not be removed.\",\n\t\tkey,\n\t\ticon: \"error\",\n\t})\n}\n", "import \"SiteSettings.styles_bs16zy.wyw.css\"; export const wrapper = \"wrapper_w1o2ymf0\";\nexport const panelBackgroundColor = \"panelBackgroundColor_p1lp8ih5\";\nexport const scrollContainer = \"scrollContainer_s7mibhy\";\nexport const sidebar = \"sidebar_s11djkat\";\nexport const rowsContainer = \"rowsContainer_ro7whr6\";\nexport const page = \"page_pc9qied\";\nexport const placeholder = \"placeholder_p2d2j3d\";\nexport const description = \"description_d5vgume\";\nexport const divider = \"divider_d1dux9p9\";\nexport const versionsProperties = \"versionsProperties_vu5x1d9\";\nexport const versionsSection = \"versionsSection_v1px74r9\";\nexport const indicatorLabel = \"indicatorLabel_i528q3h\";\nexport const preference = \"preference_psv52of\";\nexport const connectDomainButton = \"connectDomainButton_c1tioh7n\";\nexport const wideContainer = \"wideContainer_w1y6q80l\";\nexport const sectionTitle = \"sectionTitle_s9k09fr\";\nexport const settingTitle = \"settingTitle_s143auyj\";\nexport const previewSettingLabel = \"previewSettingLabel_p10kxaxh\";\nexport const previewProtectedStagingRowMuted = \"previewProtectedStagingRowMuted_p1bf5rks\";\nexport const previewStagingDividerSpacing = \"previewStagingDividerSpacing_pytamor\";\nexport const previewStagingToggleRow = \"previewStagingToggleRow_p1om2cka\";\nexport const previewStagingDescription = \"previewStagingDescription_pub8um7\";\nexport const settingDescription = \"settingDescription_sn9pc25\";\nexport const settingDescriptionSecondary = \"settingDescriptionSecondary_so2uwos\";\nexport const sectionTitleGap = 15;\nexport const columnGap = 30;\nexport const columnGapSmallScreen = 15;\nexport const noShrink = \"noShrink_n1ko75dj\";\nexport const fullWidth = \"fullWidth_f1obgswm\";\nexport const limitedWidth = \"limitedWidth_ldgz59b\";", "import { DeploymentStatus, HostnameStatus } from \"@framerjs/app-shared\"\nimport { Badge, type BadgeProps } from \"@framerjs/fresco\"\nimport { assertNever } from \"@framerjs/shared\"\nimport { useExperimentIsOn } from \"app/experiments.ts\"\nimport { onDemandSSGSupportArticleURL } from \"utils/staticURLs.ts\"\nimport * as styles from \"./SiteSettings.styles.ts\"\n\nexport enum StatusIndicatorEnum {\n\tOptimizing,\n\tOptimized,\n\tError,\n\tPending,\n\tWarning,\n}\n\nexport function getStatusIndicatorLabel(status: StatusIndicatorEnum, onDemandSSGEnabled: boolean): string {\n\tswitch (status) {\n\t\tcase StatusIndicatorEnum.Optimizing:\n\t\t\treturn onDemandSSGEnabled ? \"Pre-Optimizing\" : \"Optimizing\"\n\t\tcase StatusIndicatorEnum.Optimized:\n\t\t\treturn onDemandSSGEnabled ? \"Ready\" : \"Optimized\"\n\t\tcase StatusIndicatorEnum.Error:\n\t\t\treturn \"Error\"\n\t\tcase StatusIndicatorEnum.Warning:\n\t\t\treturn \"Warning\"\n\t\tcase StatusIndicatorEnum.Pending:\n\t\t\treturn \"Pending\"\n\t\tdefault:\n\t\t\tassertNever(status)\n\t}\n}\n\nfunction getVariantForStatus(statusIndicator: StatusIndicatorEnum): BadgeProps[\"variant\"] {\n\tswitch (statusIndicator) {\n\t\tcase StatusIndicatorEnum.Optimized:\n\t\t\treturn undefined\n\t\tcase StatusIndicatorEnum.Error:\n\t\t\treturn \"error\"\n\t\tcase StatusIndicatorEnum.Warning:\n\t\t\treturn \"warning\"\n\t\tcase StatusIndicatorEnum.Pending:\n\t\tcase StatusIndicatorEnum.Optimizing:\n\t\t\treturn \"neutral\"\n\t\tdefault:\n\t\t\tassertNever(statusIndicator)\n\t}\n}\n\nexport function deriveIndicatorStatus(\n\tstatus: DeploymentStatus | HostnameStatus,\n\thasWarnings: boolean,\n): StatusIndicatorEnum {\n\tswitch (status) {\n\t\tcase DeploymentStatus.Pending:\n\t\tcase DeploymentStatus.SpaReady:\n\t\t\treturn StatusIndicatorEnum.Optimizing\n\t\tcase DeploymentStatus.SpaFailed:\n\t\tcase DeploymentStatus.SsgPipelineFailed:\n\t\tcase DeploymentStatus.SsgReadyWithErrors:\n\t\t\treturn StatusIndicatorEnum.Error\n\t\tcase HostnameStatus.InvalidDNS:\n\t\t\treturn StatusIndicatorEnum.Pending\n\t\tcase DeploymentStatus.SsgReady:\n\t\tcase DeploymentStatus.SsgReadyWithWarnings:\n\t\t\treturn hasWarnings ? StatusIndicatorEnum.Warning : StatusIndicatorEnum.Optimized\n\t\tcase HostnameStatus.Active:\n\t\t\treturn StatusIndicatorEnum.Optimized\n\t\tdefault:\n\t\t\tassertNever(status)\n\t}\n}\n\nexport function StatusIndicator({\n\tstatus,\n\thasWarnings = false,\n}: {\n\tstatus?: DeploymentStatus | HostnameStatus\n\thasWarnings?: boolean\n}) {\n\tconst onDemandSSGEnabled = useExperimentIsOn(\"onDemandSSG\")\n\n\tif (!status) return null\n\n\tconst currentStatus = deriveIndicatorStatus(status, hasWarnings)\n\tconst label = getStatusIndicatorLabel(currentStatus, onDemandSSGEnabled)\n\tconst variant = getVariantForStatus(currentStatus)\n\n\treturn (\n\t\t<Badge\n\t\t\tas=\"a\"\n\t\t\t// @ts-ignore This component is not polymorphic enough for ts\n\t\t\thref={onDemandSSGSupportArticleURL}\n\t\t\ttarget=\"__blank\"\n\t\t\taria-label=\"On demand ssg support article\"\n\t\t\tvariant={variant}\n\t\t\tclassName={styles.indicatorLabel}\n\t\t>\n\t\t\t{label}\n\t\t</Badge>\n\t)\n}\n", "import type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport type { ExternalModuleExportIdentifier, ModuleExportIdentifierString } from \"@framerjs/shared\"\nimport { getLogger, isExternalModuleIdentifier, parseModuleIdentifier } from \"@framerjs/shared\"\nimport { waitForLoadingComponentsWithTimeout } from \"code-generation/utils/waitForLoadingComponentsWithTimeout.ts\"\nimport type { ModulesStore } from \"document/stores/ModulesStore.ts\"\nimport { isNull, isUndefined } from \"utils/typeChecks.ts\"\nimport type { CanvasTree } from \"../../CanvasTree.ts\"\nimport { usesModuleRevision } from \"../../traits/WithModuleRevision.ts\"\nimport type { ErrorListNode } from \"../ErrorListNode.ts\"\nimport { ERROR_LIST_NODE_ID } from \"../ErrorListNode.ts\"\nimport type { ErrorNode } from \"../ErrorNode.ts\"\nimport { ErrorNodeReason, legacyErrorReason } from \"../ErrorNode.ts\"\nimport type { NodeID } from \"../NodeID.ts\"\nimport { isCollectionNode, isErrorListNode, isSmartComponentNode, isWebPageNode } from \"./nodeCheck.ts\"\n\nconst log = getLogger(\"ErrorRecovery\")\n\n/**\n * Given a map of sets, make a new map where the keys are the values of the set,\n * and the values are sets of the keys.\n */\nfunction invertMap<S extends string>(map: Map<S, Set<S>>): Map<S, Set<S>> {\n\tconst inverse = new Map<S, Set<S>>()\n\tfor (const [key, set] of map) {\n\t\tset.forEach(valueKey => {\n\t\t\tconst inverseSet = inverse.get(valueKey) ?? new Set()\n\t\t\tinverseSet.add(key)\n\t\t\tinverse.set(valueKey, inverseSet)\n\t\t})\n\t}\n\treturn inverse\n}\n\n/**\n * Before predicting what errors can be recovered, we need to know if there are\n * any external modules that haven't been evaluated. This will impact our ability\n * to predict what errors can be recovered.\n */\nexport function unloadedExternalModuleErrorIdentifiers(\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tadditionalMissingModules?: ExternalModuleExportIdentifier[],\n) {\n\tconst externalModuleIdentifiers: ExternalModuleExportIdentifier[] = additionalMissingModules ?? []\n\tfor (const error of tree.get<ErrorListNode>(ERROR_LIST_NODE_ID)?.children ?? []) {\n\t\tif (!error.moduleIdentifier) continue\n\t\tif (!tree.has(error.nodeId)) continue\n\n\t\tconst identifier = parseModuleIdentifier(error.moduleIdentifier)\n\t\tif (!isExternalModuleIdentifier(identifier)) continue\n\t\texternalModuleIdentifiers.push(identifier)\n\t}\n\n\treturn externalModuleIdentifiers.filter(identifier => !componentLoader.componentForIdentifier(identifier.value))\n}\n\n/**\n * If errors were caused by missing external modules, we need to preload them\n * and wait for them to be evaluated in the sandbox, this will allow our error\n * recovery system to know which external modules are available.\n */\nexport async function preloadMissingExternalModuleErrors(\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tmodulesStore: ModulesStore,\n\tadditionalMissingModules?: ExternalModuleExportIdentifier[],\n) {\n\tconst externalModuleIdentifiers = unloadedExternalModuleErrorIdentifiers(\n\t\ttree,\n\t\tcomponentLoader,\n\t\tadditionalMissingModules,\n\t)\n\n\ttry {\n\t\tawait modulesStore.preloadExternalModules(externalModuleIdentifiers)\n\t} catch {\n\t\t// Swallow this error. We don't care if a module can't be preloaded.\n\t}\n\n\ttry {\n\t\tawait waitForLoadingComponentsWithTimeout(\n\t\t\tcomponentLoader,\n\t\t\texternalModuleIdentifiers.map(identifier => identifier.value),\n\t\t\tmodulesStore,\n\t\t\t1_000,\n\t\t)\n\t} catch {\n\t\t// Swallow this error. We don't care if a module can't be evaluated, it just\n\t\t// means we won't be able to recover from it.\n\t}\n}\n\n/**\n * Use ErrorNodes in the tree, and the state of the component loader to predict\n * if regenerating a module will resolve all errors currently recorded in the\n * tree.\n */\nexport function predictRecoverableOrderedSourceNodes(tree: CanvasTree, componentLoader: ComponentLoader): NodeID[] {\n\tconst errorsBySourceNode: Record<NodeID, ErrorNode[]> = {}\n\n\tconst errors = tree.getNodeWithTrait(ERROR_LIST_NODE_ID, isErrorListNode)?.children\n\tif (!errors || errors.length === 0) return []\n\n\t// Group all errors by the source node.\n\tfor (const error of errors) {\n\t\tif (!error.scopeId || !tree.has(error.scopeId)) continue\n\t\tconst list = errorsBySourceNode[error.scopeId] ?? []\n\t\tlist.push(error)\n\t\terrorsBySourceNode[error.scopeId] = list\n\t}\n\n\t// Map modules that are the cause of errors, to the modules which depend on them for recovery.\n\tconst errorDependentsByDependency = new Map<ModuleExportIdentifierString, Set<ModuleExportIdentifierString>>()\n\n\t// Track module identifiers by the source node id for quick lookup later.\n\tconst identifiersToIds: Record<ModuleExportIdentifierString, NodeID> = {}\n\n\tfor (const sourceNodeId in errorsBySourceNode) {\n\t\tconst sourceNodeErrors = errorsBySourceNode[sourceNodeId]\n\t\tif (!sourceNodeErrors || sourceNodeErrors.length === 0) continue\n\t\t// If the source node is deleted, we can ignore the error.\n\t\tconst sourceNode = tree.get(sourceNodeId)\n\t\tif (!sourceNode) continue\n\n\t\t// Only these nodes map to instances and themselves can depend on other generated modules.\n\t\tif (!isWebPageNode(sourceNode) && !isSmartComponentNode(sourceNode) && !isCollectionNode(sourceNode)) continue\n\n\t\tsourceNodeErrors.forEach(error => {\n\t\t\t// Iterate through the errors for each source node. If the error doesn't\n\t\t\t// have a module identifier, it doesn't depend on another module, so we\n\t\t\t// don't need to build a dependency tree for it.\n\t\t\tif (!error.moduleIdentifier) return\n\t\t\tif (error.reason !== ErrorNodeReason.MissingModule && error.reason !== ErrorNodeReason.CodeError) return\n\n\t\t\tidentifiersToIds[sourceNode.instanceIdentifier] ||= sourceNodeId\n\n\t\t\t// Record that this source node is dependent on the error module.\n\t\t\tconst dependents = errorDependentsByDependency.get(error.moduleIdentifier) ?? new Set()\n\t\t\tdependents.add(sourceNode.instanceIdentifier)\n\t\t\terrorDependentsByDependency.set(error.moduleIdentifier, dependents)\n\t\t})\n\t}\n\n\t// Invert the map of error dependencies to quickly check if recovering a\n\t// module would allow dependents to be recovered.\n\tconst errorDependenciesByDependant = invertMap(errorDependentsByDependency)\n\n\t// Track a list of modules we predict we can recover based on the errors.\n\t// The order of this list is the order we will attempt recovery, so if we\n\t// can only recover a module if another module is also recovered, it should\n\t// come later.\n\tconst mayRecover = new Set<ModuleExportIdentifierString>()\n\n\t// A component is available if it is already in the loader, or if we predict\n\t// it will be available after regenerating.\n\tfunction componentWillBecomeAvailable(identifier: ModuleExportIdentifierString) {\n\t\treturn !!componentLoader.componentForIdentifier(identifier) || mayRecover.has(identifier)\n\t}\n\n\tlet iterations = 0\n\n\twhile (errorDependenciesByDependant.size) {\n\t\t// Assume that iterating through the missing modules won't resolve\n\t\t// anything, and break the loop if so.\n\t\tlet deadlock = true\n\t\tfor (const [errorModuleIdentifier, dependents] of errorDependentsByDependency) {\n\t\t\tconst sourceNodeId = identifiersToIds[errorModuleIdentifier]\n\t\t\tconst treeErrors = sourceNodeId ? (errorsBySourceNode[sourceNodeId] ?? []) : []\n\t\t\tif (\n\t\t\t\ttreeErrors.length\n\t\t\t\t\t? // If the component has tree errors, we can only recover if\n\t\t\t\t\t\t// every error is recoverable based on the current state of the\n\t\t\t\t\t\t// loader and the modules we think we can recover by regenerating.\n\t\t\t\t\t\ttreeErrors.every(error => isRecoverableError(error, componentWillBecomeAvailable, componentLoader, tree))\n\t\t\t\t\t: // Otherwise if there are no errors, we may be able to\n\t\t\t\t\t\t// recover dependents if the component is/will be available.\n\t\t\t\t\t\tcomponentWillBecomeAvailable(errorModuleIdentifier)\n\t\t\t) {\n\t\t\t\t// If the error module had tree errors, and they are all\n\t\t\t\t// recoverable, add the module to the list straight away.\n\t\t\t\tmayRecover.add(errorModuleIdentifier)\n\n\t\t\t\tdependents.forEach(dependent => {\n\t\t\t\t\t// For each dependent that recorded an error during code\n\t\t\t\t\t// generation due to the error module, record that that\n\t\t\t\t\t// module would like be available during regeneration.\n\t\t\t\t\tconst dependencies = errorDependenciesByDependant.get(dependent)\n\t\t\t\t\tif (!dependencies) return\n\n\t\t\t\t\tdependencies.delete(errorModuleIdentifier)\n\n\t\t\t\t\t// If the dependant module no longer has any unavailable\n\t\t\t\t\t// dependencies, we can recover it.\n\t\t\t\t\tif (dependencies.size === 0) {\n\t\t\t\t\t\tmayRecover.add(dependent)\n\t\t\t\t\t\terrorDependenciesByDependant.delete(dependent)\n\t\t\t\t\t\t// If we can recover a module, it's possible we can\n\t\t\t\t\t\t// recover modules that depend on it, so allow another\n\t\t\t\t\t\t// iteration.\n\t\t\t\t\t\tdeadlock = false\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\titerations++\n\n\t\tif (deadlock) break\n\t}\n\n\t// We recorded the module identifiers of the nodes we think we can recover,\n\t// so to regenerate them, we need to map those back to node ids.\n\tconst recoverableSourceNodeIds = new Set<NodeID>()\n\tfor (const identifier of mayRecover) {\n\t\tconst id = identifiersToIds[identifier]\n\t\tif (!id) continue\n\t\trecoverableSourceNodeIds.add(id)\n\t}\n\n\t// Do a final iteration through source nodes with errors that didn't depend\n\t// on missing modules. Perhaps their errors are also recoverable due to\n\t// version changes etc.\n\tfor (const id in errorsBySourceNode) {\n\t\tif (recoverableSourceNodeIds.has(id)) continue\n\t\tconst treeErrors = errorsBySourceNode[id]\n\t\tif (!treeErrors?.length) continue\n\t\tif (treeErrors.every(error => isRecoverableError(error, componentWillBecomeAvailable, componentLoader, tree))) {\n\t\t\trecoverableSourceNodeIds.add(id)\n\t\t}\n\t}\n\n\tconst ids = Array.from(recoverableSourceNodeIds)\n\tlog.debug(\"Predicted generated module recovery\", {\n\t\terrorsBySourceNode,\n\t\tcanRecover: ids,\n\t\titerations,\n\t})\n\n\treturn ids\n}\n\n/**\n * A function that implements heuristics to decide when regenerating a module\n * would resolve all errors.\n */\nfunction isRecoverableError(\n\terror: ErrorNode,\n\tcomponentWillBecomeAvailable: (identifier: ModuleExportIdentifierString) => boolean,\n\tcomponentLoader: ComponentLoader,\n\ttree: CanvasTree,\n): boolean {\n\t// If the node has been deleted, regenerating may remove the error.\n\tconst node = tree.get(error.nodeId)\n\tif (!node) return true\n\n\tswitch (error.reason) {\n\t\tcase ErrorNodeReason.MissingModule:\n\t\t\tif (!error.moduleIdentifier) return false\n\t\t\t// If we created an error because the module was missing (or timed\n\t\t\t// out waiting for it), we can recover if the module is available.\n\t\t\treturn componentWillBecomeAvailable(error.moduleIdentifier)\n\t\tcase ErrorNodeReason.CodeError: {\n\t\t\tif (!error.moduleIdentifier) return false\n\t\t\t// If we created an error because the module had an error, if the\n\t\t\t// module is missing, we can't recover.\n\t\t\tif (!componentWillBecomeAvailable(error.moduleIdentifier)) return false\n\t\t\t// Otherwise we can recover if their is no longer an error in the\n\t\t\t// loader for the module. This will be true if we predict the\n\t\t\t// component will become available, but isn't in the loader at this\n\t\t\t// time. We assume that's good enough.\n\t\t\treturn isNull(componentLoader.errorForIdentifier(error.moduleIdentifier))\n\t\t}\n\t\tcase ErrorNodeReason.FitImageRegenerationRequired:\n\t\tcase ErrorNodeReason.LayoutTemplateFlowEffectRegenerationRequired:\n\t\t\t// The error is only added to ensure the module is regenerated before the next publish, so it is always recoverable\n\t\t\treturn true\n\t\tdefault: {\n\t\t\tif (legacyErrorReason.has(error.reason)) {\n\t\t\t\t// We may not have always tracked moduleIdentifiers in the past.\n\t\t\t\t// Assume that if the identifier is missing we can regenerate\n\t\t\t\t// it.\n\t\t\t\tif (!error.moduleIdentifier) return true\n\t\t\t\treturn componentWillBecomeAvailable(error.moduleIdentifier)\n\t\t\t}\n\t\t\t// Otherwise we don't know how to predict if we can recover, but if\n\t\t\t// the source node has changed since the module was generated, and\n\t\t\t// we haven't regenerated since, we may be able to recover by\n\t\t\t// regenerating it.\n\t\t\tconst sourceNode = tree.get(error.scopeId)\n\t\t\tif (!sourceNode) return false\n\t\t\t// Otherwise if the source node has had any changes that haven't\n\t\t\t// been code-generated, we may be able to recover.\n\t\t\tif (usesModuleRevision(sourceNode, tree)) {\n\t\t\t\treturn !isUndefined(sourceNode.moduleSourceRevisionHint)\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\t}\n}\n", "import type { ToastAction } from \"@framerjs/fresco\"\nimport { Translatable as T } from \"@framerjs/fresco\"\nimport type { ReactNode } from \"react\"\n\ninterface SitePublishedToastText {\n\ttext?: ReactNode\n\tprimaryText?: ReactNode\n\tsecondaryText?: ReactNode\n}\n\nexport function sitePublishedText({ isFirstTimePublish }: { isFirstTimePublish: boolean }): SitePublishedToastText {\n\tif (isFirstTimePublish) {\n\t\treturn {\n\t\t\tprimaryText: <T>Your website</T>,\n\t\t\tsecondaryText: <T>has been published.</T>,\n\t\t}\n\t}\n\n\treturn {\n\t\tprimaryText: <T>Your website</T>,\n\t\tsecondaryText: <T>has been updated.</T>,\n\t}\n}\n\nexport function sitePublishedAction({\n\tdisplayMinimalUI,\n\tisDomainConnected,\n\tisFirstPublish,\n\topenLinkAction,\n\tconnectDomainAction,\n}: {\n\tdisplayMinimalUI: boolean\n\tisDomainConnected: boolean\n\tisFirstPublish: boolean\n\topenLinkAction: ToastAction\n\tconnectDomainAction: ToastAction\n}): ToastAction {\n\tif (displayMinimalUI) {\n\t\treturn openLinkAction\n\t}\n\n\tif (isDomainConnected || !isFirstPublish) {\n\t\treturn openLinkAction\n\t}\n\n\treturn connectDomainAction\n}\n", "import type { ProjectSettingsFeatureFlags, TeamLicenseFeatureFlags } from \"@framerjs/app-config\"\nimport { defaultProjectFeatureFlags } from \"@framerjs/app-config\"\nimport { FeatureSet, createFeatureComponent, useCondition } from \"./FeatureSet.tsx\"\n\n// TODO: These should move to project.settings.featureFlags\n// Once we do, we can stop setting spaceLicenseFeatures in here:\n// https://github.com/framer/FramerStudio/blob/5a43e0303d39795ed05e5e049fbf11b2b00d0ded/src/app/vekter/src/web/pages/project/components/ProjectHandlers.tsx#L320\ntype FeaturesFromTeamLicense = Pick<TeamLicenseFeatureFlags, \"canUseCustomTemplates\">\n\nexport type FeatureName = keyof ProjectSettingsFeatureFlags | keyof FeaturesFromTeamLicense\n\n// Initialize with the values that UI has been dehydrated with.\nexport const features = new FeatureSet<FeatureName>({\n\t...defaultProjectFeatureFlags,\n\t// Default value migrated from:\n\t// https://github.com/framer/FramerStudio/blob/664302a6289e668212404c0aedd989c3c26d023f/src/app/config/src/features.ts#L18\n\tcanUseCustomTemplates: \"upsell\",\n})\n\nexport function useFeatureIsOn(feature: FeatureName): boolean {\n\treturn useCondition(features, feature, variant => variant === \"on\")\n}\n\nexport function useFeatureVariant(feature: FeatureName, desiredVariant: string): boolean {\n\treturn useCondition(features, feature, variant => variant === desiredVariant)\n}\n\nexport const Feature = createFeatureComponent(features)\n", "// Keep in sync with _fonts-sandbox.css\nexport const defaultFontSites = `body, input, textarea, select, button { font-size: 12px; font-family: sans-serif; }`\n", "import { domParser } from \"library/render/utils/dom.ts\"\n\n/**\n * Generate a valid HTML string\n * @important The returned HTML is not sanitized (e.g. can contain <script> tags) and can cause XSS vulnerabilities if used without encoding.\n */\nexport function getParsedHTML(input: string | undefined, tagName: \"head\" | \"body\"): string {\n\tif (input === undefined) return \"\"\n\t/**\n\t * Wrap the input in the element it's supposed to be inserted in,\n\t * to stop the domParser from taking too many liberties with fixing it up.\n\t * E.g. without this, a GTM noscript tag will be moved from the body to the head,\n\t * but the inner iframe will remain in the body.\n\t */\n\tconst newInput = `<${tagName}>${input}</${tagName}>`\n\tconst parsedCustomHTML = domParser(newInput)\n\tconst element = parsedCustomHTML.querySelector(tagName)\n\treturn element instanceof HTMLElement ? element.innerHTML : \"\"\n}\n", "import { getSnippetMarkers } from \"@framerjs/shared/src/custom-code/markers.ts\"\nimport type { CustomCodePlacement } from \"@framerjs/shared/src/custom-code/types.ts\"\nimport type { CustomCodeNode } from \"document/models/CanvasTree/index.ts\"\nimport { assertNever } from \"library/utils/assert.ts\"\nimport { getParsedHTML } from \"./getParsedHTML.ts\"\n\nexport type CustomHTML = Record<CustomCodePlacement, string>\n\nexport function getAllParsedCustomHTML(customCodeNodes: Iterable<CustomCodeNode> | undefined): CustomHTML {\n\tconst result: CustomHTML = {\n\t\theadStart: \"\",\n\t\theadEnd: \"\",\n\t\tbodyEnd: \"\",\n\t\tbodyStart: \"\",\n\t}\n\n\tif (!customCodeNodes) return result\n\n\tfor (const customCode of customCodeNodes) {\n\t\tif (customCode.disabled) continue\n\t\tif (customCode.pageIds && customCode.pageIds.length > 0) continue\n\t\t// The snippets that are loaded on every page visit will be loaded either via SSG or snippets loader\n\t\t// In case of SSG, they will be included in the generated page HTML, and won't be loaded again in the initial render\n\t\t// In case of snippets loader (SPA mode only), they will be loaded in the initial render\n\t\tif (customCode.loadMode !== \"once\") continue\n\n\t\tconst html = customCode.managedByPlugin\n\t\t\t? `<!-- Plugin: ${customCode.managedByPlugin} --> ${customCode.code}`\n\t\t\t: customCode.code\n\n\t\tconst { start, end } = getSnippetMarkers(customCode.id)\n\t\tconst parsedCustomHTML = getParsedCustomHTML(html, customCode.placement)\n\t\tresult[customCode.placement] += `${start}\\n${parsedCustomHTML}\\n${end}\\n`\n\t}\n\n\treturn result\n}\n\nfunction getParsedCustomHTML(html: string, placement: CustomCodePlacement): string {\n\tif (placement === \"headStart\" || placement === \"headEnd\") {\n\t\treturn getParsedHTML(html, \"head\")\n\t}\n\tif (placement === \"bodyStart\" || placement === \"bodyEnd\") {\n\t\treturn getParsedHTML(html, \"body\")\n\t}\n\tassertNever(placement)\n}\n", "import type { FramerEvents } from \"@framerjs/events\"\n\nexport function defaultExportToHTMLMetrics() {\n\t// IMPORTANT: All these metrics will be sent directly into the\n\t// `project_published` event, so make sure to use matching fields here!\n\treturn {\n\t\t// Code generation/engine stats.\n\t\tcmsUpdateMs: 0,\n\t\tcollectRedirectRoutesMs: 0,\n\t\tforceUpdateAutoGeneratedComponentMs: 0,\n\t\tgenerateFontsMs: 0,\n\t\tgetFallbackSearchIndexUrlMs: 0,\n\t\tincompatibleForceUpdateMs: 0,\n\t\tmetadataUpdateMs: 0,\n\t\tmoduleStoreWaitMs: 0,\n\t\tsnapshotConvergeMs: 0,\n\t\tsnapshotConvergeIterations: 0,\n\t\tsmartComponentUpdateMs: 0,\n\t\ttextStylesUpdateMs: 0,\n\t\tupdatePendingGeneratedNodeMs: 0,\n\t\t// AI stats.\n\t\taiGeneratedSitePages: 0,\n\t\t// Various route/page stats.\n\t\tpageCount: 0, // <- For CMS pages, counts every item as one reachable page.\n\t\tpageNodeCount: 0, // Unique web page node count.\n\t\tpageNodeWithLayoutTemplate: 0,\n\t\tuniqueLayoutTemplates: 0,\n\t\tredirectCount: 0,\n\t\tproxyCount: 0,\n\t\trewriteCount: 0,\n\t\trewriteExternalCount: 0,\n\t\trewriteInternalCount: 0,\n\t\theaderCount: 0,\n\t\tabTestCount: 0,\n\t} satisfies Partial<Extract<FramerEvents, { event: \"project_published\" }>>\n}\n\nexport type ExportToHTMLMetrics = ReturnType<typeof defaultExportToHTMLMetrics>\n", "export default \"// src/export/bundled/captureFormsUTMTagsInCookie.ts?bundleSites\\n((queryString) => {\\n  const urlParams = new URLSearchParams(queryString);\\n  const utmTagKeys = [\\\"utm_source\\\", \\\"utm_medium\\\", \\\"utm_campaign\\\", \\\"utm_term\\\", \\\"utm_content\\\", \\\"gclid\\\"];\\n  const utmTags = Array.from(urlParams.entries()).filter(\\n    ([key, _value]) => utmTagKeys.includes(key)\\n  );\\n  if (utmTags.length === 0) return;\\n  try {\\n    const encodedParams = encodeURIComponent(JSON.stringify(Object.fromEntries(utmTags)));\\n    document.cookie = `framerFormsUTMTags=${encodedParams}; path=/`;\\n  } catch (e) {\\n    console.error(\\\"Error capturing UTM tags:\\\", e);\\n  }\\n})(window.location.search);\\n\"", "export default \"// ../../library/src/render/presentation/formatRelativeDate.ts\\nvar formatters = /* @__PURE__ */ new Map();\\nfunction getRelativeTimeFormat(style, numeric, locale) {\\n  const options = { numeric, style };\\n  const args = [locale, options];\\n  const key = JSON.stringify(args);\\n  const existing = formatters.get(key);\\n  if (existing) return existing;\\n  const formatter = new Intl.RelativeTimeFormat(...args);\\n  formatters.set(key, formatter);\\n  return formatter;\\n}\\nfunction formatRelativeDate(targetDate, referenceDate, format, style, numeric, capitalize, locale) {\\n  const unit = getRelativeDateUnit(targetDate, referenceDate, format);\\n  const value = getRelativeDateValue(targetDate, referenceDate, unit);\\n  const formatted = getRelativeTimeFormat(style, numeric, locale).format(value, unit);\\n  if (capitalize) return capitalizeFirstLetter(formatted);\\n  return formatted;\\n}\\nfunction capitalizeFirstLetter(text) {\\n  return text.charAt(0).toUpperCase() + text.slice(1);\\n}\\nfunction getRelativeDateUnit(targetDate, referenceDate, format) {\\n  if (format !== \\\"auto\\\") return format;\\n  const daysDiff = differenceInCalendarDays(targetDate, referenceDate);\\n  if (Math.abs(daysDiff) <= 7) return \\\"day\\\";\\n  const weeksDiff = differenceInCalendarWeeks(targetDate, referenceDate);\\n  if (Math.abs(weeksDiff) <= 4) return \\\"week\\\";\\n  const monthsDiff = differenceInCalendarMonths(targetDate, referenceDate);\\n  if (Math.abs(monthsDiff) <= 12) return \\\"month\\\";\\n  return \\\"year\\\";\\n}\\nvar SECOND = 1e3;\\nvar MINUTE = 6e4;\\nvar HOUR = 36e5;\\nvar DAY = 864e5;\\nvar WEEK = 6048e5;\\nfunction getRelativeDateValue(targetDate, referenceDate, unit) {\\n  const delta = targetDate.getTime() - referenceDate.getTime();\\n  switch (unit) {\\n    case \\\"second\\\":\\n      return Math.trunc(delta / SECOND);\\n    case \\\"minute\\\":\\n      return Math.trunc(delta / MINUTE);\\n    case \\\"hour\\\":\\n      return Math.trunc(delta / HOUR);\\n    case \\\"day\\\":\\n      return differenceInCalendarDays(targetDate, referenceDate);\\n    case \\\"week\\\":\\n      return differenceInCalendarWeeks(targetDate, referenceDate);\\n    case \\\"month\\\":\\n      return differenceInCalendarMonths(targetDate, referenceDate);\\n    case \\\"quarter\\\":\\n      return differenceInCalendarQuarters(targetDate, referenceDate);\\n    case \\\"year\\\":\\n      return differenceInCalendarYears(targetDate, referenceDate);\\n  }\\n  const _ = unit;\\n}\\nfunction getUTCStartOfDay(date) {\\n  const result = new Date(date);\\n  result.setUTCHours(0, 0, 0, 0);\\n  return result;\\n}\\nfunction differenceInCalendarDays(targetDate, referenceDate) {\\n  const targetTimestamp = getUTCStartOfDay(targetDate).getTime();\\n  const referenceTimestamp = getUTCStartOfDay(referenceDate).getTime();\\n  return Math.round((targetTimestamp - referenceTimestamp) / DAY);\\n}\\nfunction getUTCStartOfWeek(date) {\\n  const result = new Date(date);\\n  const day = result.getUTCDay();\\n  const diff = (day < 1 ? 7 : 0) + day - 1;\\n  result.setUTCDate(result.getUTCDate() - diff);\\n  result.setUTCHours(0, 0, 0, 0);\\n  return result;\\n}\\nfunction differenceInCalendarWeeks(targetDate, referenceDate) {\\n  const targetTimestamp = getUTCStartOfWeek(targetDate).getTime();\\n  const referenceTimestamp = getUTCStartOfWeek(referenceDate).getTime();\\n  return Math.round((targetTimestamp - referenceTimestamp) / WEEK);\\n}\\nfunction differenceInCalendarMonths(targetDate, referenceDate) {\\n  const yearsDiff = targetDate.getUTCFullYear() - referenceDate.getUTCFullYear();\\n  const monthsDiff = targetDate.getUTCMonth() - referenceDate.getUTCMonth();\\n  return yearsDiff * 12 + monthsDiff;\\n}\\nfunction getUTCQuarter(date) {\\n  const month = date.getUTCMonth();\\n  return Math.trunc(month / 3);\\n}\\nfunction differenceInCalendarQuarters(targetDate, referenceDate) {\\n  const yearsDiff = targetDate.getUTCFullYear() - referenceDate.getUTCFullYear();\\n  const quartersDiff = getUTCQuarter(targetDate) - getUTCQuarter(referenceDate);\\n  return yearsDiff * 4 + quartersDiff;\\n}\\nfunction differenceInCalendarYears(targetDate, referenceDate) {\\n  return targetDate.getUTCFullYear() - referenceDate.getUTCFullYear();\\n}\\n\\n// src/export/bundled/formatRelativeDate.ts?bundleSites\\nwindow.__framer_formatRelativeDate = formatRelativeDate;\\n\"", "export default \"// ../../library/src/router/forwardQueryParams.ts\\nvar FRAMER_VARIANT_KEY = \\\"framer_variant\\\";\\nfunction forwardQueryParams(queryParamsString, href) {\\n  const startOfHash = href.indexOf(\\\"#\\\");\\n  const hrefWithoutHash = startOfHash === -1 ? href : href.substring(0, startOfHash);\\n  const hash = startOfHash === -1 ? \\\"\\\" : href.substring(startOfHash);\\n  const startOfSearch = hrefWithoutHash.indexOf(\\\"?\\\");\\n  const baseUrl = startOfSearch === -1 ? hrefWithoutHash : hrefWithoutHash.substring(0, startOfSearch);\\n  const searchString = startOfSearch === -1 ? \\\"\\\" : hrefWithoutHash.substring(startOfSearch);\\n  const newSearchParams = new URLSearchParams(searchString);\\n  const currentSearchParams = new URLSearchParams(queryParamsString);\\n  for (const [key, value] of currentSearchParams) {\\n    if (newSearchParams.has(key)) continue;\\n    if (key === FRAMER_VARIANT_KEY) continue;\\n    newSearchParams.append(key, value);\\n  }\\n  const newSearchString = newSearchParams.toString();\\n  if (newSearchString === \\\"\\\") {\\n    return hrefWithoutHash + hash;\\n  }\\n  return baseUrl + \\\"?\\\" + newSearchString + hash;\\n}\\n\\n// src/export/bundled/rewriteLinksWithQueryParams.ts?bundleSites\\nvar internalLinkSelector = 'div#main a[href^=\\\"#\\\"],div#main a[href^=\\\"/\\\"],div#main a[href^=\\\".\\\"]';\\nvar preserveParamsSelector = \\\"div#main a[data-framer-preserve-params]\\\";\\nvar preserveInternalParams = document.currentScript?.hasAttribute(\\\"data-preserve-internal-params\\\");\\nif (window.location.search && !navigator.webdriver && // We only want to rewrite links if the agent is not a bot.\\n!/bot|-google|google-|yandex|ia_archiver|crawl|spider/iu.test(navigator.userAgent)) {\\n  const links = document.querySelectorAll(\\n    preserveInternalParams ? `${internalLinkSelector},${preserveParamsSelector}` : preserveParamsSelector\\n  );\\n  for (const link of links) {\\n    const hrefWithQueryParams = forwardQueryParams(window.location.search, link.href);\\n    link.setAttribute(\\\"href\\\", hrefWithQueryParams);\\n  }\\n}\\n\"", "import type { FeatureValue } from \"@framerjs/app-config\"\nimport type { HeaderRouteNode } from \"document/models/CanvasTree/nodes/HeaderRouteNode.ts\"\nimport type { ValidationResult } from \"./ValidationResult.ts\"\n\n// Matches https://github.com/framer/FramerWebApi/blob/19bd07373dac7066b59e93180f214e716ce5244a/src/lib/sites/validation/routes.ts#L21\nconst maxHeaderValueLength = 1200\n\nconst maxHeaderValueLengthOverrides = {\n\t\"Content-Security-Policy\": 2500,\n}\n\n// Note: \\x09 (tab) is intentionally excluded from this pattern because tab characters are allowed in HTTP header values (RFC 7230).\n// biome-ignore lint/suspicious/noControlCharactersInRegex: Intentional check for control characters\nconst controlCharsPattern = /[\\x00-\\x08\\x0A-\\x1F\\x7F]/u\n\n/**\n * Headers that were once whitelisted but are now disallowed. Used to filter out headers during\n * publishing so that projects with deprecated headers can still be published.\n * These might at some point be allowed for enterprise projects.\n */\nconst deprecatedAddOnHeaders = [\"Expect-CT\", \"NEL\", \"Report-To\", \"X-Permitted-Cross-Domain-Policies\"] as const\nconst deprecatedHeaderKeysSet = new Set(deprecatedAddOnHeaders.map(key => key.toLowerCase()))\nexport const isDeprecatedHeaderKey = (key: string) => deprecatedHeaderKeysSet.has(key.toLowerCase())\n\n// See https://www.notion.so/framer/Advanced-Hosting-Pricing-2a9adf6e8c9680068ef2d823f60c4bd7\nconst customHeadersAllowlist = [\"Permissions-Policy\", \"Referrer-Policy\", \"Strict-Transport-Security\", \"X-Frame-Options\"]\nconst customHeadersAllowlistSet = new Set(customHeadersAllowlist.map(key => key.toLowerCase()))\n\nconst advancedHeadersAllowlist = [\n\t\"Content-Security-Policy\",\n\t\"Content-Security-Policy-Report-Only\",\n\t\"Cross-Origin-Embedder-Policy\",\n\t\"Cross-Origin-Opener-Policy\",\n\t\"Cross-Origin-Resource-Policy\",\n\t\"Feature-Policy\",\n\t\"Reporting-Endpoints\",\n\t\"Server\",\n\t\"X-Content-Type-Options\",\n\t\"X-Robots-Tag\",\n\t\"X-XSS-Protection\",\n]\nconst advancedHeadersAllowlistSet = new Set(advancedHeadersAllowlist.map(key => key.toLowerCase()))\n\ninterface HeaderOption {\n\tkey: string\n\tupsell: boolean\n}\n\nexport const getHeadersAllowlist = (canUseAdvancedHeaders: FeatureValue): HeaderOption[] => {\n\tconst customHeaderOptions = customHeadersAllowlist.map(key => ({\n\t\tkey,\n\t\tupsell: false,\n\t}))\n\tconst advancedHeaderOptions = advancedHeadersAllowlist.map(key => ({\n\t\tkey,\n\t\tupsell: canUseAdvancedHeaders !== \"on\",\n\t}))\n\n\treturn [...customHeaderOptions, ...advancedHeaderOptions]\n}\n\nexport const isHeaderKeyAllowed = (key: string, canUseAdvancedHeaders: FeatureValue) => {\n\tconst normalizedKey = key.trim().toLowerCase()\n\tif (canUseAdvancedHeaders === \"on\") {\n\t\treturn customHeadersAllowlistSet.has(normalizedKey) || advancedHeadersAllowlistSet.has(normalizedKey)\n\t}\n\treturn customHeadersAllowlistSet.has(normalizedKey)\n}\n\nexport function validateHeaderKey(key: string, canUseAdvancedHeaders: FeatureValue): ValidationResult {\n\tkey = key.trim()\n\n\tif (!key) {\n\t\treturn { result: \"empty\" }\n\t}\n\n\tif (!isHeaderKeyAllowed(key, canUseAdvancedHeaders)) {\n\t\treturn { result: \"error\", message: \"This header is not in the allowed list\" }\n\t}\n\n\treturn { result: \"ok\", normalizedValue: key }\n}\n\nexport function validateHeaderValue(key: string, value: string): ValidationResult {\n\tvalue = value.trim()\n\n\tif (!value) {\n\t\treturn { result: \"empty\" }\n\t}\n\n\tconst maxLength =\n\t\tmaxHeaderValueLengthOverrides[key as keyof typeof maxHeaderValueLengthOverrides] ?? maxHeaderValueLength\n\tif (value.length > maxLength) {\n\t\treturn { result: \"error\", message: `The value is too long (max ${maxLength} characters)` }\n\t}\n\n\t// Check for control characters (except tab) which are not allowed in HTTP headers\n\tif (controlCharsPattern.test(value)) {\n\t\treturn { result: \"error\", message: \"Header value contains invalid characters\" }\n\t}\n\n\treturn { result: \"ok\", normalizedValue: value }\n}\n\nexport function validateHeaderUniqueness(\n\tpath: string,\n\tkey: string,\n\texistingHeaderRouteNodes: readonly HeaderRouteNode[],\n\tcurrentHeaderRouteNode?: HeaderRouteNode,\n): ValidationResult<undefined> {\n\tfor (const existing of existingHeaderRouteNodes) {\n\t\t// Skip checking against the header being edited\n\t\tif (currentHeaderRouteNode && existing.id === currentHeaderRouteNode.id) {\n\t\t\tcontinue\n\t\t}\n\n\t\tif (path === existing.path && key.toLocaleLowerCase() === existing.key.toLocaleLowerCase()) {\n\t\t\treturn { result: \"error\", message: \"A rule with this path and header name already exists\" }\n\t\t}\n\t}\n\n\treturn { result: \"ok\", normalizedValue: undefined }\n}\n", "import type { Locale as RouterLocale } from \"library/router/types.ts\"\nimport { isString } from \"utils/typeChecks.ts\"\n\n/**\n * Shared interface for resolved route destinations with locale information\n */\nexport interface ResolvedRouteTo {\n\tlocalePrefix: string\n\tpath: string\n\tfullPath: string\n}\n\n/**\n * Extracts all explicit paths from a list of route nodes.\n * Used to detect when an expanded locale path would conflict with an explicitly defined path.\n *\n * This function returns all explicitly defined paths: \"/\", \"/*\", \"/blog\", \"/blog/*\", \"/de/blog\", \"/en/blog\", etc.\n * It's not exclusive to localized paths: \"/de/blog\", \"/en/blog\", etc.\n */\nexport function getExplicitPaths<T extends { path?: string }>(nodes: readonly T[]): ReadonlySet<string> {\n\tconst explicitPaths = new Set<string>()\n\n\tfor (const node of nodes) {\n\t\tif (isString(node.path)) explicitPaths.add(node.path)\n\t}\n\n\treturn explicitPaths\n}\n\n/**\n * Gets the locale prefix for a given locale (e.g., \"/en\", \"/de\", or \"\" for default)\n */\nexport function getLocalePrefix(locale: RouterLocale | undefined): string {\n\treturn locale?.slug ? `/${locale.slug}` : \"\"\n}\n\n/**\n * Creates a regex group from locale prefixes (e.g., \"(|/en|/de)\")\n */\nexport function createLocaleRegexpGroup(localePrefixes: string[]): string {\n\treturn `(${localePrefixes.join(\"|\")})`\n}\n\n/**\n * Bumps wildcard references in a path by 1 (e.g., \":1\" becomes \":2\")\n * This is used when adding a new regex group to a path, requiring existing\n * wildcard references to be incremented.\n */\nexport function bumpWildcards(path: string): string {\n\treturn path.replaceAll(/:(\\d+)/gu, (_, i: string) => `:${Number(i) + 1}`)\n}\n\n/**\n * Groups routes by their resolved destination path across multiple locales.\n *\n * For each locale:\n * - Creates an expanded path with the locale prefix\n * - Skips if the expanded path is explicitly defined elsewhere\n * - Resolves the route's destination for that locale\n * - Groups routes by their resolved destination path\n *\n * @param allLocales - All available locales to expand to\n * @param routePath - The original route path (e.g., \"/blog\")\n * @param explicitPaths - Set of explicitly defined paths to avoid conflicts\n * @param resolver - Function to resolve the route's destination for a given locale and expanded path\n * @returns Record mapping resolved paths to arrays of ResolvedRouteTo objects\n */\nexport function groupRoutesByResolvedPath(\n\tallLocales: readonly RouterLocale[],\n\troutePath: string,\n\texplicitPaths: ReadonlySet<string>,\n\tresolver: (locale: RouterLocale, expandedPath: string) => ResolvedRouteTo | undefined,\n): Record<string, ResolvedRouteTo[]> {\n\tconst grouped: Record<string, ResolvedRouteTo[]> = {}\n\n\tfor (const locale of allLocales) {\n\t\tconst localePrefix = getLocalePrefix(locale)\n\t\tconst expandedPath = `${localePrefix}${routePath}`\n\t\t// If this is an expanded path, and it already has another explicit route, that takes priority.\n\t\t// localePrefix check here makes sure we don't skip the default locale path (\"/\")\n\t\tif (localePrefix && explicitPaths.has(expandedPath)) continue\n\n\t\tconst resolvedTo = resolver(locale, expandedPath)\n\t\tif (!resolvedTo) continue\n\n\t\tconst resolvedToPath = resolvedTo.path\n\t\tgrouped[resolvedToPath] ??= []\n\t\tgrouped[resolvedToPath].push(resolvedTo)\n\t}\n\n\treturn grouped\n}\n", "import type { FeatureValue } from \"@framerjs/app-config\"\nimport { assert } from \"@framerjs/shared\"\nimport { getNonDefaultLocaleIdForPath } from \"document/components/chrome/siteSettings/Redirects/getNonDefaultLocaleForPath.ts\"\nimport type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport type { HeaderKey, HeaderRouteNode, HeaderValue } from \"document/models/CanvasTree/nodes/HeaderRouteNode.ts\"\nimport { RoutesNode } from \"document/models/CanvasTree/nodes/RoutesNode.ts\"\nimport { getRouterLocales } from \"utils/getRouterLocales.ts\"\nimport {\n\tisDeprecatedHeaderKey,\n\tisHeaderKeyAllowed,\n} from \"web/pages/projects/components/Domains/validation/validateHeader.ts\"\nimport type { GenerateRoutesContext } from \"./exportToHTML.ts\"\nimport { createLocaleRegexpGroup, getExplicitPaths, getLocalePrefix } from \"./routeLocaleExpansion.ts\"\n\ninterface ResolvedHeaderRoute {\n\tpath: string\n\theaders: Record<HeaderKey, HeaderValue>\n}\n\nfunction expandHeaderRouteLocales(\n\ttree: CanvasTree,\n\texplicitPaths: ReadonlySet<string>,\n\tnode: HeaderRouteNode,\n\tcanUseAdvancedHeaders: FeatureValue,\n): ResolvedHeaderRoute[] {\n\tconst result: ResolvedHeaderRoute[] = []\n\tif (!node.path || !node.headers || node.headers.length === 0) return result\n\n\tconst headers: Record<HeaderKey, HeaderValue> = {}\n\tnode.headers.forEach(element => {\n\t\t// If the header key is not allowed and deprecated, skip it. This allows a project with deprecated\n\t\t// headers to still be published without errors. This is a workaround while we don't have a problem UI for this.\n\t\tif (!isHeaderKeyAllowed(element.key, canUseAdvancedHeaders) && isDeprecatedHeaderKey(element.key)) return\n\n\t\theaders[element.key] = element.value\n\t})\n\n\t// Return empty if no allowed headers remain after filtering\n\tif (Object.keys(headers).length === 0) return result\n\n\t// No need to expand if:\n\t// - this header already is for a specific locale\n\t// - there's no locales to expand to\n\t// - the header's configuration prevents expanding\n\tconst pathLocaleVekterId = getNonDefaultLocaleIdForPath(node.path, tree.root.locales)\n\n\tconst allLocales = getRouterLocales(tree, \"includeDrafts\")\n\tconst pathLocale = allLocales.find(({ id }) => id === pathLocaleVekterId)\n\tif (pathLocale || !tree.root.locales?.length || !node.shouldExpandToAllLocales()) {\n\t\tresult.push({ path: node.path, headers })\n\t\treturn result\n\t}\n\n\t// Expand the header into all locales (including default locale)\n\tconst localePrefixes: string[] = []\n\tfor (const locale of allLocales) {\n\t\t// If it's empty it means it's the default locale\n\t\t// Including it so it behaves the same way as redirects\n\t\t// Creates compressed regex groups like: (|/en|/de)/blog\n\t\tconst localePrefix = getLocalePrefix(locale)\n\n\t\tconst expandedPath = `${localePrefix}${node.path}`\n\t\t// If this is an expanded path, and it already has another, explicit header, that takes priority.\n\t\t// localePrefix check here makes sure we don't skip the default locale path (\"/\")\n\t\tif (localePrefix && explicitPaths.has(expandedPath)) continue\n\n\t\tlocalePrefixes.push(localePrefix)\n\t}\n\n\t// Combine locale prefixes into a single regex group if there are multiple\n\tif (localePrefixes.length === 1) {\n\t\tresult.push({ path: `${localePrefixes[0]}${node.path}`, headers })\n\t} else if (localePrefixes.length > 1) {\n\t\t// Combine multiple locale prefixes into a single regex group: (|/es|/pt)/page\n\t\t// Note the first pipe is the root locale, which is always included.\n\t\tconst regexpGroup = createLocaleRegexpGroup(localePrefixes)\n\t\tresult.push({ path: `${regexpGroup}${node.path}`, headers })\n\t}\n\n\treturn result\n}\n\nexport function collectHeaderRoutes(tree: CanvasTree, context: GenerateRoutesContext) {\n\tconst routesNode = RoutesNode.get(tree)\n\tif (!routesNode) {\n\t\treturn\n\t}\n\n\tassert(routesNode.isLoaded(), \"Routes node must be fully loaded when collecting header routes\")\n\n\tconst allHeaderNodes = routesNode.getHeaderRoutes()\n\tconst explicitPaths = getExplicitPaths(allHeaderNodes)\n\n\tfor (const node of allHeaderNodes) {\n\t\tif (!node.path || !node.headers || node.headers.length === 0) continue\n\n\t\tfor (const resolvedHeader of expandHeaderRouteLocales(tree, explicitPaths, node, context.canUseAdvancedHeaders)) {\n\t\t\tcontext.serverRoutes.push({\n\t\t\t\tpath: resolvedHeader.path,\n\t\t\t\thandler: { type: \"header\", headers: resolvedHeader.headers },\n\t\t\t})\n\n\t\t\tcontext.metrics.count(\"headerCount\")\n\n\t\t\t// Track unique header keys for analytics\n\t\t\tfor (const key of Object.keys(resolvedHeader.headers)) {\n\t\t\t\tcontext.headerKeys.add(key)\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport const testing = { expandHeaderRouteLocales, collectHeaderRoutes }\n", "import { assert } from \"@framerjs/shared\"\nimport type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport { RoutesNode } from \"document/models/CanvasTree/nodes/RoutesNode.ts\"\nimport type { GenerateRoutesContext } from \"./exportToHTML.ts\"\n\nexport function collectProxyRoutes(tree: CanvasTree, context: GenerateRoutesContext) {\n\tconst routesNode = RoutesNode.get(tree)\n\tif (!routesNode) {\n\t\treturn\n\t}\n\n\tassert(routesNode.isLoaded(), \"Routes node must be fully loaded when collecting proxy routes\")\n\n\tconst allProxyNodes = routesNode.getProxyRoutes()\n\n\tfor (const node of allProxyNodes) {\n\t\tcontext.serverRoutes.push({\n\t\t\tpath: node.path,\n\t\t\thandler: { type: \"proxy\", targetUrl: node.targetUrl },\n\t\t})\n\t\tcontext.metrics.count(\"proxyCount\")\n\t}\n}\n", "import { assert, isSingleElementArray } from \"@framerjs/shared\"\nimport { getNonDefaultLocaleIdForPath } from \"document/components/chrome/siteSettings/Redirects/getNonDefaultLocaleForPath.ts\"\nimport type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport type { RedirectRouteNode } from \"document/models/CanvasTree/nodes/RedirectRouteNode.ts\"\nimport { RoutesNode } from \"document/models/CanvasTree/nodes/RoutesNode.ts\"\nimport type { LinkToWebPage } from \"document/models/CanvasTree/traits/utils/Link.ts\"\nimport { isLinkToWebPage } from \"document/models/CanvasTree/traits/utils/Link.ts\"\nimport { SlugBehavior, getResolvedLinkToWebPage } from \"document/utils/getResolvedLinkToWebPage.ts\"\nimport type { Locale as RouterLocale } from \"library/router/types.ts\"\nimport { getRouterLocales } from \"utils/getRouterLocales.ts\"\nimport type { GenerateRoutesContext } from \"./exportToHTML.ts\"\nimport {\n\ttype ResolvedRouteTo,\n\tbumpWildcards,\n\tcreateLocaleRegexpGroup,\n\tgetExplicitPaths,\n\tgetLocalePrefix,\n\tgroupRoutesByResolvedPath,\n} from \"./routeLocaleExpansion.ts\"\n\ninterface ResolvedRedirectRoute {\n\tpath: string\n\tto: string\n}\n\nfunction resolveAndExpandRedirects(\n\ttree: CanvasTree,\n\texplicitPaths: ReadonlySet<string>,\n\tredirect: RedirectRouteNode,\n): ResolvedRedirectRoute[] {\n\tconst result: ResolvedRedirectRoute[] = []\n\tif (!redirect.path || !redirect.to) return result\n\n\t// No need to expand if:\n\t// - this redirect already is for a specific locale\n\t// - there's no locales to expand to\n\t// - the redirect's configuration prevents expanding\n\tconst pathLocaleVekterId = getNonDefaultLocaleIdForPath(redirect.path, tree.root.locales)\n\n\t// XXX: Exclude draft locales?\n\t// Would technically be a breaking change though, maybe somebody relies on draft locales also generating redirects.\n\tconst allLocales = getRouterLocales(tree, \"includeDrafts\")\n\tconst pathLocale = allLocales.find(({ id }) => id === pathLocaleVekterId)\n\tif (pathLocale || !tree.root.locales?.length || !redirect.shouldExpandToAllLocales()) {\n\t\tconst resolvedTo = resolveRedirectTo(tree, redirect.path, redirect.to, pathLocale)\n\t\tif (!resolvedTo) return result\n\n\t\tresult.push({ path: redirect.path, to: resolvedTo.fullPath })\n\t\treturn result\n\t}\n\n\tconst redirectTo = redirect.to\n\tconst isRedirectToWebPage = isLinkToWebPage(redirectTo)\n\n\t// Expand the redirect into all locales, and group the ones with an identical resolvedTo.path, so essentially the\n\t// ones without localized path variables.\n\tconst groupedRedirects = groupRoutesByResolvedPath(\n\t\tallLocales,\n\t\tredirect.path,\n\t\texplicitPaths,\n\t\t(locale, expandedPath) => {\n\t\t\treturn resolveRedirectTo(tree, expandedPath, redirectTo, locale)\n\t\t},\n\t)\n\n\t// Combine redirects into one per unique resolvedTo, with the locale prefix handled by a regexp group, e.g.:\n\t//\n\t//     /blog/bonjour-le-monde: [/fr-FR, /fr-BE] => (/fr-FR|/fr-BE)/blog/bonjour-le-monde\n\t//     /blog/hallo-wereld: [/nl-NL, /nl-BE]     => (/nl-NL|/nl-BE)/blog/hallo-wereld\n\tfor (const resolvedToPath in groupedRedirects) {\n\t\tconst resolvedTo = groupedRedirects[resolvedToPath]\n\t\t// It's always defined, but the type checker doesn't know that.\n\t\tif (!resolvedTo) continue\n\n\t\t// If there's only one item in this group, no need to use regexp, just point to it directly.\n\t\tif (isSingleElementArray(resolvedTo)) {\n\t\t\tconst { localePrefix, fullPath } = resolvedTo[0]\n\t\t\tresult.push({\n\t\t\t\tpath: `${localePrefix}${redirect.path}`,\n\t\t\t\tto: fullPath,\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\n\t\tconst localePrefixes = resolvedTo.map(({ localePrefix }) => localePrefix)\n\t\tconst regexpGroup = createLocaleRegexpGroup(localePrefixes)\n\t\tresult.push({\n\t\t\tpath: `${regexpGroup}${redirect.path}`,\n\t\t\t// Static redirects don't get a locale prefix, but may need to have their wildcards bumped.\n\t\t\tto: isRedirectToWebPage ? `:1${resolvedToPath}` : bumpWildcards(resolvedToPath),\n\t\t})\n\t}\n\n\treturn result\n}\n\nfunction resolveRedirectTo(\n\ttree: CanvasTree,\n\tredirectPath: string,\n\tredirectTo: string | LinkToWebPage,\n\tlocale: RouterLocale | undefined,\n): ResolvedRouteTo | undefined {\n\tconst localePrefix = getLocalePrefix(locale)\n\n\tlet resolvedRedirectTo: ResolvedRouteTo\n\tif (isLinkToWebPage(redirectTo)) {\n\t\tconst resolvedTo = getResolvedLinkToWebPage(tree, redirectTo, SlugBehavior.Resolve, locale, undefined, false)\n\t\tif (!resolvedTo) return\n\n\t\tresolvedRedirectTo = {\n\t\t\tlocalePrefix,\n\t\t\tpath: resolvedTo,\n\t\t\tfullPath: `${localePrefix}${resolvedTo}`,\n\t\t}\n\t} else {\n\t\tresolvedRedirectTo = {\n\t\t\tlocalePrefix,\n\t\t\tpath: redirectTo,\n\t\t\t// Static redirects don't get a locale prefix.\n\t\t\t// If this is changed, we should change both redirects and rewrites at the same time.\n\t\t\t// See: https://framer-team.slack.com/archives/C076SFPGPNH/p1761142182383929?thread_ts=1761138056.798419&cid=C076SFPGPNH\n\t\t\tfullPath: redirectTo,\n\t\t}\n\t}\n\n\tif (redirectPath === resolvedRedirectTo.fullPath) return\n\n\treturn resolvedRedirectTo\n}\n\nexport function collectRedirectRoutes(tree: CanvasTree, context: GenerateRoutesContext) {\n\tconst routesNode = RoutesNode.get(tree)\n\tif (!routesNode) {\n\t\treturn\n\t}\n\n\tassert(routesNode.isLoaded(), \"Routes node must be fully loaded when collecting redirect routes\")\n\n\tconst allRedirectNodes = routesNode.getRedirects()\n\tconst explicitPaths = getExplicitPaths(allRedirectNodes)\n\n\tfor (const redirect of allRedirectNodes) {\n\t\tif (!redirect.path || !redirect.to) continue\n\n\t\tfor (const resolvedRedirect of resolveAndExpandRedirects(tree, explicitPaths, redirect)) {\n\t\t\tcontext.serverRoutes.push({\n\t\t\t\tpath: resolvedRedirect.path,\n\t\t\t\thandler: { type: \"redirect\", to: resolvedRedirect.to },\n\t\t\t})\n\t\t\tcontext.metrics.count(\"redirectCount\")\n\t\t}\n\t}\n}\n\nexport const testing = { resolveAndExpandRedirects, collectRedirectRoutes }\n", "import { extractProtocolPrefix, parseURL } from \"@framerjs/app-shared\"\nimport { assert, assertNever, isSingleElementArray } from \"@framerjs/shared\"\nimport { getNonDefaultLocaleIdForPath } from \"document/components/chrome/siteSettings/Redirects/getNonDefaultLocaleForPath.ts\"\nimport type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport type { RewriteRouteNode } from \"document/models/CanvasTree/nodes/RewriteRouteNode.ts\"\nimport { RewriteType } from \"document/models/CanvasTree/nodes/RewriteTypeEnum.ts\"\nimport { RoutesNode } from \"document/models/CanvasTree/nodes/RoutesNode.ts\"\nimport { isValidURL, isValidURLWithoutProtocol } from \"document/utils/domainValidation.ts\"\nimport type { Locale as RouterLocale } from \"library/router/types.ts\"\nimport { getRouterLocales } from \"utils/getRouterLocales.ts\"\nimport type { GenerateRoutesContext } from \"./exportToHTML.ts\"\nimport {\n\ttype ResolvedRouteTo,\n\tbumpWildcards,\n\tcreateLocaleRegexpGroup,\n\tgetExplicitPaths,\n\tgetLocalePrefix,\n\tgroupRoutesByResolvedPath,\n} from \"./routeLocaleExpansion.ts\"\n\ninterface ResolvedRewriteRoute {\n\tpath: string\n\tpathWithoutLocaleGroupPrefixes: string\n\tto: string\n\tlocalePrefixes: string[]\n}\n\nfunction resolveAndExpandRewrites(\n\ttree: CanvasTree,\n\texplicitPaths: ReadonlySet<string>,\n\trewrite: RewriteRouteNode,\n): ResolvedRewriteRoute[] {\n\tconst result: ResolvedRewriteRoute[] = []\n\tif (!rewrite.path || !rewrite.targetUrl) return result\n\n\t// No need to expand if:\n\t// - this rewrite already is for a specific locale\n\t// - there's no locales to expand to\n\t// - the rewrite's configuration prevents expanding\n\tconst pathLocaleVekterId = getNonDefaultLocaleIdForPath(rewrite.path, tree.root.locales)\n\n\tconst allLocales = getRouterLocales(tree, \"includeDrafts\")\n\tconst pathLocale = allLocales.find(({ id }) => id === pathLocaleVekterId)\n\tif (pathLocale || !tree.root.locales?.length || !rewrite.shouldExpandToAllLocales()) {\n\t\tresult.push({\n\t\t\tpath: rewrite.path,\n\t\t\tpathWithoutLocaleGroupPrefixes: rewrite.path,\n\t\t\tto: rewrite.targetUrl,\n\t\t\tlocalePrefixes: [],\n\t\t})\n\t\treturn result\n\t}\n\n\t// Expand the rewrite into all locales, and group the ones with an identical resolvedTo.path\n\t// NOTE: currently, `rewrite.targetUrl` is not resolved because it is a string, not a LinkToWebPage. We want to\n\t// change this though in the future, so leaving the structure similar to redirects in place.\n\tconst groupedRewrites = groupRoutesByResolvedPath(allLocales, rewrite.path, explicitPaths, locale => {\n\t\treturn resolveRewriteTo(locale, rewrite.targetUrl, rewrite.rewriteType)\n\t})\n\n\t// Combine rewrites into one per unique resolvedTo, with the locale prefix handled by a regexp group, e.g.:\n\t//\n\t//     /blog: [/fr-FR, /fr-BE] => (/fr-FR|/fr-BE)/blog\n\t//     /app: [/nl-NL, /nl-BE]  => (/nl-NL|/nl-BE)/app\n\tfor (const resolvedToPath in groupedRewrites) {\n\t\tconst resolvedTo = groupedRewrites[resolvedToPath]\n\t\t// We know it exists because we're looping over it.\n\t\tif (!resolvedTo) continue\n\n\t\t// NOTE: This currently only happens in one specific case:\n\t\t// When all non-default locales are explicitly defined (in explicitPaths), leaving only the\n\t\t// default locale to be expanded. In this case, there's a single element with an empty locale prefix.\n\t\t// Avoiding the empty regexp group in this case.\n\t\t//\n\t\t// In the future, if rewrites resolve differently per locale (similar to how redirects work),\n\t\t// this code path would handle other single-locale cases as well.\n\t\tif (isSingleElementArray(resolvedTo)) {\n\t\t\tconst { localePrefix, fullPath } = resolvedTo[0]\n\t\t\t// fullPath is already built in the resolveRewriteTo function\n\t\t\t// Internal example: /fr/sourcePath => another.framer.site/fr/destinationPath\n\t\t\t// External example: /fr/sourcePath => www.example.com/destinationPath\n\t\t\tresult.push({\n\t\t\t\tpath: `${localePrefix}${rewrite.path}`,\n\t\t\t\tpathWithoutLocaleGroupPrefixes: `${localePrefix}${rewrite.path}`,\n\t\t\t\tto: fullPath,\n\t\t\t\tlocalePrefixes: [],\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\n\t\tconst localePrefixes = resolvedTo.map(({ localePrefix }) => localePrefix)\n\t\tconst regexpGroup = createLocaleRegexpGroup(localePrefixes)\n\n\t\tif (rewrite.rewriteType === RewriteType.External) {\n\t\t\tresult.push({\n\t\t\t\tpath: `${regexpGroup}${rewrite.path}`,\n\t\t\t\tpathWithoutLocaleGroupPrefixes: rewrite.path,\n\t\t\t\tto: resolvedTo[0]?.fullPath ?? \"\",\n\t\t\t\tlocalePrefixes,\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\n\t\t// Example: https://another.framer.site(/fr|/pt)/test\n\t\tconst { hostname } = parseURL(rewrite.targetUrl)\n\t\tconst urlProtocol = extractProtocolPrefix(rewrite.targetUrl)\n\n\t\tresult.push({\n\t\t\tpath: `${regexpGroup}${rewrite.path}`,\n\t\t\tpathWithoutLocaleGroupPrefixes: rewrite.path,\n\t\t\t// Place locale regexp group between domain and path: https://domain.com:1/path\n\t\t\tto: `${urlProtocol}${hostname}:1${bumpWildcards(resolvedToPath)}`,\n\t\t\tlocalePrefixes,\n\t\t})\n\t}\n\n\treturn result\n}\n\n/** Not adding locale prefix to external rewrites and static redirects to maintain consistency with redirects. */\n// See: https://framer-team.slack.com/archives/C076SFPGPNH/p1761142182383929?thread_ts=1761138056.798419&cid=C076SFPGPNH\nfunction resolveRewriteTo(\n\tlocale: RouterLocale | undefined,\n\ttargetUrl: string,\n\trewriteType: RewriteType,\n): ResolvedRouteTo {\n\tconst localePrefix = getLocalePrefix(locale)\n\n\t// NOTE: it has been discussed that in retrospect it would make sense to add the locale prefix even for\n\t// external rewrites and static redirects.\n\t// However it is hard to change redirects due to backwards compatibility, so we decided to maintain consistency\n\t// in rewrites to make it easier for users to understand.\n\t// When/if we change one, we should change both at the same time.\n\tswitch (rewriteType) {\n\t\tcase RewriteType.External: {\n\t\t\treturn {\n\t\t\t\tlocalePrefix,\n\t\t\t\tpath: targetUrl,\n\t\t\t\t// External rewrites don't get a locale prefix\n\t\t\t\t// Same behavior as static redirects.\n\t\t\t\tfullPath: targetUrl,\n\t\t\t}\n\t\t}\n\t\tcase RewriteType.Internal: {\n\t\t\t// If it's a full URL to a Framer project, insert the locale prefix after the domain\n\t\t\t// TODO: resolve a LinkToWebPage to a localized path.\n\t\t\t// @see https://framer-team.slack.com/archives/C076SFPGPNH/p1761218297795219\n\t\t\tconst { hostname, pathname } = parseURL(targetUrl)\n\t\t\tif (!hostname || !pathname) {\n\t\t\t\tthrow new Error(\"Invalid rewrite target URL\")\n\t\t\t}\n\t\t\tconst urlProtocol = extractProtocolPrefix(targetUrl)\n\t\t\tconst fullPathWithLocale = `${localePrefix}${pathname}`\n\n\t\t\treturn {\n\t\t\t\tlocalePrefix,\n\t\t\t\tpath: pathname,\n\t\t\t\tfullPath: `${urlProtocol}${hostname}${fullPathWithLocale}`,\n\t\t\t}\n\t\t}\n\t\tdefault:\n\t\t\tassertNever(rewriteType, \"Unrecognized RewriteRouteNode.type\")\n\t}\n}\n\nexport function collectRewriteRoutes(tree: CanvasTree, context: GenerateRoutesContext, matchPagesFirst: boolean) {\n\tconst routesNode = RoutesNode.get(tree)\n\tif (!routesNode) {\n\t\treturn\n\t}\n\n\tassert(routesNode.isLoaded(), \"Routes node must be fully loaded when collecting rewrite routes\")\n\n\tconst allRewriteNodes = routesNode.getRewriteRoutes()\n\tconst explicitPaths = getExplicitPaths(allRewriteNodes)\n\n\tfor (const rewrite of allRewriteNodes) {\n\t\tif (!rewrite.path || !rewrite.targetUrl) continue\n\t\tif (matchPagesFirst !== !!rewrite.matchPagesFirst) continue\n\n\t\tfor (const resolvedRewrite of resolveAndExpandRewrites(tree, explicitPaths, rewrite)) {\n\t\t\tlet targetUrl = resolvedRewrite.to\n\t\t\tif (isValidURLWithoutProtocol(targetUrl)) {\n\t\t\t\ttargetUrl = `https://${targetUrl}`\n\t\t\t} else if (isValidURL(targetUrl)) {\n\t\t\t\t// Nothing to do, the URL is already valid\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Rewrite target URL is not a valid URL\")\n\t\t\t}\n\n\t\t\tcontext.ssgRewrites.push({\n\t\t\t\truleId: rewrite.id,\n\t\t\t\tpath: resolvedRewrite.pathWithoutLocaleGroupPrefixes,\n\t\t\t\tto: targetUrl,\n\t\t\t\tlocalePrefixes: resolvedRewrite.localePrefixes,\n\t\t\t})\n\n\t\t\tcontext.serverRoutes.push({\n\t\t\t\tpath: resolvedRewrite.path,\n\t\t\t\thandler: { type: \"rewrite\", to: targetUrl, rewriteType: rewrite.rewriteType },\n\t\t\t})\n\n\t\t\tcontext.metrics.count(\"rewriteCount\")\n\t\t\tcontext.metrics.count(\n\t\t\t\trewrite.rewriteType === RewriteType.Internal ? \"rewriteInternalCount\" : \"rewriteExternalCount\",\n\t\t\t)\n\t\t}\n\t}\n}\n\nexport const testing = { resolveAndExpandRewrites, collectRewriteRoutes }\n", "import { REGULAR_FONT_WEIGHT } from \"@framerjs/app-shared\"\nimport type { AssetMap } from \"@framerjs/assets\"\nimport { getServiceMap } from \"@framerjs/framer-environment/domains.ts\"\nimport type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { assert, ModuleType, localModuleIdentifierForStableName } from \"@framerjs/shared\"\nimport { createComponentFontHash } from \"code-generation/utils/createComponentFontHash.ts\"\nimport { flattenComponentFontBundles } from \"code-generation/utils/flattenComponentFonts.ts\"\nimport type { AnyScopeNode, CanvasNode } from \"document/models/CanvasTree/index.ts\"\nimport type { AnyLayoutTemplateNode } from \"document/models/CanvasTree/nodes/LayoutTemplateNode.ts\"\nimport type { AssetStore } from \"document/stores/AssetStore.ts\"\nimport type { ModulesStoreSnapshot } from \"document/stores/ModulesStore.ts\"\nimport type { FontSourceName } from \"library/index.ts\"\nimport { FontSourceNames, fontStore } from \"library/index.ts\"\nimport type { FontCategory, ReadonlyFontVariationAxes } from \"library/render/fonts/types.ts\"\nimport type { ComponentFont } from \"library/utils/addFonts.ts\"\nimport { assertNever } from \"library/utils/assert.ts\"\nimport type { FallbackFontValues } from \"text/sizeAdjustedFallback.ts\"\nimport {\n\tgetCustomOrBuiltInFontFallbackValues,\n\tgetFontshareFallbackValues,\n\tgetFramerFontFallbackValues,\n\tgetGoogleFontFallbackValues,\n\tgetSizeAdjustedFallbackFontFamily,\n\tshouldGenerateSizeAdjustedFallback,\n} from \"text/sizeAdjustedFallback.ts\"\nimport { apiFetcher } from \"web/lib/apiFetcher.ts\"\n\ninterface FontsHTML {\n\tfontCSS: string\n\tfallbackFontFaceRules: Set<string>\n\tlinkTags: string[]\n}\n\ntype GoogleComponentFont = ComponentFont & { source: \"google\" }\ntype NonGoogleComponentFont = ComponentFont & { source: Exclude<FontSourceName, \"google\"> }\nfunction isGoogleComponentFont(font: ComponentFont): font is GoogleComponentFont {\n\treturn font.source === \"google\"\n}\nfunction isNonGoogleComponentFont(font: ComponentFont): font is NonGoogleComponentFont {\n\treturn font.source !== \"google\"\n}\n\nexport async function generateFonts(\n\tcomponentLoader: ComponentLoader,\n\tmodulesSnapshot: ModulesStoreSnapshot,\n\tassetStore: AssetStore,\n\tscreenNodesToExport: (CanvasNode | AnyScopeNode)[],\n\tlayoutTemplates: AnyLayoutTemplateNode[],\n) {\n\tconst screenFonts = getModuleFonts(componentLoader, screenNodesToExport, ModuleType.Screen)\n\tconst layoutTemplateFonts = getModuleFonts(componentLoader, layoutTemplates, ModuleType.LayoutTemplate)\n\tconst { googleFonts, manuallyConstructedGoogleFonts, nonGoogleFonts } = pickFontsToGenerate(\n\t\tmodulesSnapshot,\n\t\tscreenFonts.concat(layoutTemplateFonts),\n\t)\n\n\tconst [googleFontsHTML, manuallyConstructedFontsHTML] = await Promise.all([\n\t\tgetGoogleFontsAPIHTML(googleFonts),\n\t\tgetManuallyConstructedFontsHTML([...manuallyConstructedGoogleFonts, ...nonGoogleFonts], assetStore.assetMap),\n\t])\n\n\t// Note: we\u2019re deduping fallback font face rules in case the project uses\n\t// both Google Inter and Framer Inter (or any other font coming both from\n\t// Google and from other sources).\n\tconst fallbackFontFaceRules = Array.from(\n\t\tnew Set([...googleFontsHTML.fallbackFontFaceRules, ...manuallyConstructedFontsHTML.fallbackFontFaceRules]),\n\t)\n\n\treturn {\n\t\tfontCSS: [googleFontsHTML.fontCSS, manuallyConstructedFontsHTML.fontCSS, ...fallbackFontFaceRules]\n\t\t\t.filter(Boolean)\n\t\t\t.join(\"\\n\"),\n\t\tfontLinkTags: googleFontsHTML.linkTags.concat(manuallyConstructedFontsHTML.linkTags),\n\t}\n}\n\n// Some Google fonts are subsetted in a ton of small parts (~125) which blows up the CSS we include in the HTML.\n// Instead of injecting the CSS, we\u2019ll use a <link> tag to include these.\n// TODO: Make this dynamic so it also works with other / new fonts.\n// See: https://framer-team.slack.com/archives/C01J38GC2SW/p1758284907813679\nconst FORCE_LINKED_FONTS = [\n\t\"M PLUS Rounded 1c\",\n\t\"Noto Sans JP\",\n\t\"Noto Sans\",\n\t\"Noto Serif JP\",\n\t\"Sawarabi Mincho\",\n\t\"Shippori Mincho B1\",\n\t\"Shippori Mincho\",\n\t\"Zen Kaku Gothic Antique\",\n\t\"Zen Kaku Gothic New\",\n]\n\nfunction isForceLinkedFont(fontFamily: string): boolean {\n\treturn FORCE_LINKED_FONTS.includes(fontFamily)\n}\n\nfunction buildGoogleFontFamilyQueryParam(font: ComponentFont): string {\n\tif (font.variationAxes) {\n\t\treturn `family=${getGoogleVariableFont(font.uiFamilyName, font.variationAxes)}`\n\t} else {\n\t\tconst familyParam = `${encodeGoogleFontFamily(font.uiFamilyName)}:ital,wght@${font.style === \"italic\" ? \"1\" : \"0\"},${font.weight || `${REGULAR_FONT_WEIGHT}`}`\n\t\treturn `family=${familyParam}`\n\t}\n}\n\nasync function getGoogleFontsAPIHTML(googleFonts: ComponentFont[]): Promise<FontsHTML> {\n\tif (googleFonts.length === 0) return { fontCSS: \"\", fallbackFontFaceRules: new Set(), linkTags: [] }\n\n\tconst preconnectTag = '<link href=\"https://fonts.gstatic.com\" rel=\"preconnect\" crossorigin>'\n\tconst linkTags: string[] = [preconnectTag]\n\tconst normalGoogleFonts: ComponentFont[] = []\n\n\tfor (const font of googleFonts) {\n\t\tif (isForceLinkedFont(font.uiFamilyName) && !font.variationAxes) {\n\t\t\tconst familyQueryParam = buildGoogleFontFamilyQueryParam(font)\n\t\t\tconst linkTag = `<link media=\"print\" onload=\"this.media=''\" href=\"https://fonts.googleapis.com/css2?${familyQueryParam}&display=swap\" rel=\"stylesheet\">`\n\t\t\tlinkTags.push(linkTag)\n\t\t} else {\n\t\t\tnormalGoogleFonts.push(font)\n\t\t}\n\t}\n\n\tconst swappableFonts: ComponentFont[] = []\n\tconst nonSwappableFonts: ComponentFont[] = []\n\tconst fallbackFontFaceRules = new Set<string>()\n\tfor (const font of normalGoogleFonts) {\n\t\tconst fontFamily = fontStore.google.getFontFamilyByName(font.uiFamilyName)\n\t\tconst fontCategory = fontFamily?.fonts[0]?.category\n\t\tconst isSwappable = shouldGenerateSizeAdjustedFallback(\"google\", font.weight, fontCategory)\n\n\t\tif (!isSwappable) {\n\t\t\tnonSwappableFonts.push(font)\n\t\t\tcontinue\n\t\t}\n\n\t\tconst fallbackValues = await getGoogleFontFallbackValues(font.uiFamilyName)\n\t\tif (!fallbackValues) {\n\t\t\tnonSwappableFonts.push(font)\n\t\t\tcontinue\n\t\t}\n\n\t\tswappableFonts.push(font)\n\n\t\tconst fallbackFontFaceRule = getFallbackFontFaceRule(font.cssFamilyName, fallbackValues)\n\t\tfallbackFontFaceRules.add(fallbackFontFaceRule)\n\t}\n\n\tconst googleCSS = await Promise.all(\n\t\t[swappableFonts, nonSwappableFonts].map(async fonts => {\n\t\t\tif (fonts.length === 0) return \"\"\n\n\t\t\tconst variableQueryParams: string[] = []\n\t\t\tconst staticQueryParams: string[] = []\n\n\t\t\tfor (const font of fonts) {\n\t\t\t\tconst familyQueryParam = buildGoogleFontFamilyQueryParam(font)\n\t\t\t\tif (font.variationAxes) {\n\t\t\t\t\tvariableQueryParams.push(familyQueryParam)\n\t\t\t\t} else {\n\t\t\t\t\tstaticQueryParams.push(familyQueryParam)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst displayParam = `display=${fonts === swappableFonts ? \"swap\" : \"auto\"}`\n\t\t\tif (variableQueryParams.length > 0) variableQueryParams.push(displayParam)\n\t\t\tif (staticQueryParams.length > 0) staticQueryParams.push(displayParam)\n\n\t\t\treturn Promise.all([\n\t\t\t\tfetchGoogleFonts(staticQueryParams),\n\t\t\t\t// We want to suffix the variable font faces received back from\n\t\t\t\t// the API with unique family names. This is to avoid conflicts\n\t\t\t\t// with the static font faces for pages that use both variable\n\t\t\t\t// and static fonts. Otherwise, the font faces added last will\n\t\t\t\t// take be taking priority and result in the page not being\n\t\t\t\t// rendered correctly.\n\t\t\t\tfetchGoogleFonts(variableQueryParams).then(appendVariableToFontFamily),\n\t\t\t]).then(css => css.join(\"\"))\n\t\t}),\n\t).then(cssParts => cssParts.join(\"\"))\n\n\treturn { fontCSS: googleCSS, fallbackFontFaceRules, linkTags }\n}\n\nasync function getManuallyConstructedFontsHTML(fonts: ComponentFont[], assetMap: AssetMap): Promise<FontsHTML> {\n\tconst fontFaceRules = new Set<string>()\n\tconst fallbackFontFaceRules = new Set<string>()\n\tconst linkTags = new Set<string>()\n\n\tconst resolvedFonts = await Promise.all(\n\t\tfonts.map(async font => {\n\t\t\t// Eventually, we should be able to remove redirect resolving, see\n\t\t\t// https://github.com/framer/FramerStudio/pull/18918 for context.\n\t\t\tif (font.url.startsWith(getServiceMap().modulesCDN)) {\n\t\t\t\treturn { ...font, url: await resolveRedirects(font.url) }\n\t\t\t} else {\n\t\t\t\treturn font\n\t\t\t}\n\t\t}),\n\t)\n\n\tfor (const font of resolvedFonts) {\n\t\tconst escapedFontUrl = JSON.stringify(font.url)\n\n\t\tconst shouldHaveFallback = shouldGenerateSizeAdjustedFallback(\n\t\t\tfont.source,\n\t\t\tfont.weight,\n\t\t\tgetFontCategoryForFont(font),\n\t\t)\n\n\t\tlet fallbackValues: FallbackFontValues | undefined\n\t\tif (font.source === FontSourceNames.Google) {\n\t\t\tfallbackValues = await getGoogleFontFallbackValues(font.uiFamilyName)\n\t\t} else if (font.source === FontSourceNames.Fontshare) {\n\t\t\tfallbackValues = await getFontshareFallbackValues(font.uiFamilyName)\n\t\t} else if (font.source === FontSourceNames.Framer) {\n\t\t\tfallbackValues = getFramerFontFallbackValues(font.uiFamilyName)\n\t\t} else if (font.source === FontSourceNames.Custom || font.source === FontSourceNames.BuiltIn) {\n\t\t\tfallbackValues = getCustomOrBuiltInFontFallbackValues(font.uiFamilyName, font.url, assetMap)\n\t\t} else if (font.source === FontSourceNames.Local) {\n\t\t\t// Local fonts shouldn\u2019t be collected by FontCollector\n\t\t\tthrow new Error(\n\t\t\t\t`generateFonts: received a local font (font family: \"${font.uiFamilyName}\"); this should not happen`,\n\t\t\t)\n\t\t} else {\n\t\t\tassertNever(font.source)\n\t\t}\n\n\t\tconst useFontDisplaySwap = shouldHaveFallback && !!fallbackValues\n\n\t\tconst fontFamily = font.cssFamilyName\n\n\t\tconst properties = [`font-family: ${JSON.stringify(fontFamily)}`, `src: url(${escapedFontUrl})`]\n\t\tif (useFontDisplaySwap) properties.push(`font-display: swap`)\n\t\tif (font.style) properties.push(`font-style: ${font.style}`)\n\t\tif (font.weight) properties.push(`font-weight: ${font.weight}`)\n\t\tif (font.stretch) properties.push(`font-stretch: ${font.stretch}`)\n\t\tif (font.unicodeRange) properties.push(`unicode-range: ${font.unicodeRange}`)\n\t\tfontFaceRules.add(`@font-face { ${properties.join(\"; \")} }`)\n\n\t\tif (\n\t\t\tuseFontDisplaySwap &&\n\t\t\t// We have to repeat the `!== undefined` check here because\n\t\t\t// TypeScript can\u2019t infer we checked for it in `useFontDisplaySwap`\n\t\t\tfallbackValues !== undefined\n\t\t) {\n\t\t\tconst fallbackFontFaceRule = getFallbackFontFaceRule(fontFamily, fallbackValues)\n\t\t\tfallbackFontFaceRules.add(fallbackFontFaceRule)\n\t\t}\n\n\t\tif (font.source === \"google\") {\n\t\t\tlinkTags.add('<link href=\"https://fonts.gstatic.com\" rel=\"preconnect\" crossorigin>')\n\t\t}\n\t}\n\n\tconst css = Array.from(fontFaceRules).join(\"\\n\")\n\treturn { fontCSS: css, fallbackFontFaceRules, linkTags: Array.from(linkTags) }\n}\n\nfunction getFontCategoryForFont(font: ComponentFont): FontCategory | undefined {\n\tconst fontSource = font.source\n\tswitch (fontSource) {\n\t\tcase \"google\":\n\t\t\treturn fontStore.google.getFontFamilyByName(font.uiFamilyName)?.fonts[0]?.category\n\t\tcase \"fontshare\":\n\t\t\treturn fontStore.fontshare.getFontFamilyByName(font.uiFamilyName)?.fonts[0]?.category\n\t\tcase \"framer\":\n\t\t\treturn fontStore.framer.getFontFamilyByName(font.uiFamilyName)?.fonts[0]?.category\n\t\tcase \"local\":\n\t\t\treturn fontStore.local.getFontFamilyByName(font.uiFamilyName)?.fonts[0]?.category\n\t\tcase \"builtIn\":\n\t\t\treturn fontStore.builtIn.getFontFamilyByName(font.uiFamilyName)?.fonts[0]?.category\n\t\tcase \"custom\":\n\t\t\treturn fontStore.custom.getFontFamilyByName(font.uiFamilyName)?.fonts[0]?.category\n\t\tdefault:\n\t\t\tassertNever(fontSource)\n\t}\n}\n\nfunction getFallbackFontFaceRule(\n\tfontFamily: string,\n\t{ fallbackFontName, ascentOverride, descentOverride, lineGapOverride, sizeAdjust }: FallbackFontValues,\n): string {\n\tconst properties = [\n\t\t`font-family: ${JSON.stringify(getSizeAdjustedFallbackFontFamily(fontFamily))}`,\n\t\t`src: local(${JSON.stringify(fallbackFontName)})`,\n\t\t`ascent-override: ${ascentOverride}`,\n\t\t`descent-override: ${descentOverride}`,\n\t\t`line-gap-override: ${lineGapOverride}`,\n\t\t`size-adjust: ${sizeAdjust}`,\n\t]\n\treturn `@font-face { ${properties.join(\"; \")} }`\n}\n\nfunction getModuleFonts(\n\tcomponentLoader: ComponentLoader,\n\tnodes: (CanvasNode | AnyScopeNode)[],\n\tmoduleType: ModuleType,\n): ComponentFont[] {\n\treturn nodes.flatMap(node => {\n\t\tconst componentIdentifier = localModuleIdentifierForStableName(moduleType, node.id, \"default\").value\n\t\tconst component = componentLoader.componentForIdentifier(componentIdentifier)\n\n\t\treturn flattenComponentFontBundles(component?.fonts ?? [])\n\t})\n}\n\nfunction resolveFont<T extends ComponentFont>(modulesSnapshot: ModulesStoreSnapshot, font: T): T {\n\t// For local modules, we need to resolve their font asset URL manually\n\t// against the persisted module URL, because the module might be transient\n\t// and thus pointing to a URL that only exists in memory (a blob URL).\n\t// But, we can only do that if the code-generator provided additional\n\t// metadata about the module asset: its unresolved URL, and the identifier\n\t// of the local module the font belongs to.\n\tif (!font.moduleAsset) return font\n\n\tconst persistedModule = modulesSnapshot.getPersistedModuleByLocalIdentifier(font.moduleAsset.localModuleIdentifier)\n\t// If we didn't find the persisted module in our snapshot, then it's\n\t// probably not a local module, and font.url is fine, since external modules\n\t// are never transient.\n\tif (!persistedModule) return font\n\n\treturn {\n\t\t...font,\n\t\turl: new URL(font.moduleAsset.url, persistedModule.moduleURL).href,\n\t}\n}\n\nasync function resolveRedirects(url: string): Promise<string> {\n\ttry {\n\t\tconst response = await fetch(url, {\n\t\t\tmethod: \"HEAD\",\n\t\t\tredirect: \"follow\",\n\t\t})\n\t\treturn response.url\n\t} catch (err) {\n\t\treturn url\n\t}\n}\n\n/**\n * \u201CComposite font\u201D is a font combined of multiple unique font files with the same family,\n * weight, style, and stretch, but different unicode ranges.\n * https://drafts.csswg.org/css-fonts-3/#composite-fonts\n */\nfunction createCompositeFontHash(font: ComponentFont) {\n\treturn createComponentFontHash({ ...font, unicodeRange: undefined })\n}\n\nconst fontPriorityBySource: Record<FontSourceName, number> = {\n\t// Custom fonts are prioritized over all others because they show a clear\n\t// intent (a font uploaded by the user).\n\tcustom: 0,\n\t// Framer fonts are higher-quality than Google fonts (e.g. Framer Inter has\n\t// italics while Google Inter doesn\u2019t).\n\tframer: 1,\n\t// Google fonts are higher-quality than Fontshare fonts because they support\n\t// subsetting.\n\tgoogle: 2,\n\tfontshare: 3,\n\tbuiltIn: 4,\n\t// This font source will never be emitted, but let\u2019s keep it here for\n\t// completeness.\n\tlocal: 5,\n}\n\nexport function pickFontsToGenerate(modulesSnapshot: ModulesStoreSnapshot, screenFonts: ComponentFont[]) {\n\tconst prioritizedFonts = [...screenFonts].sort((a, b) => {\n\t\t// What if our site uses two fonts with the same name and different\n\t\t// sources? Such as Google Roboto and Fontshare Roboto, or Google Inter\n\t\t// and Framer Inter. Instead of emitting two @font-faces with the same\n\t\t// name, let\u2019s prioritize the higher-quality source.\n\t\tif (fontPriorityBySource[a.source] !== fontPriorityBySource[b.source]) {\n\t\t\treturn fontPriorityBySource[a.source] - fontPriorityBySource[b.source]\n\t\t}\n\n\t\t// What if we have both woff2 and ttf/otf fonts within the same source?\n\t\t// Let\u2019s put woff2 first so if there are any ttfs/otfs with the\n\t\t// identical font name/weight/style/etc, we\u2019ll prioritize the woff2.\n\t\t// (This can happen when a user re-uploads a custom .woff2 file on top\n\t\t// of a .ttf/otf one.)\n\t\tconst aIsWoff2 = a.url.endsWith(\".woff2\")\n\t\tconst bIsWoff2 = b.url.endsWith(\".woff2\")\n\t\tif (aIsWoff2 !== bIsWoff2) return aIsWoff2 ? -1 : 1\n\n\t\t// If one font has OpenType features enabled and the other doesn't,\n\t\t// prioritize the one with OpenType. This ensures that if any page on\n\t\t// the site uses OpenType features for a Google font, we load the\n\t\t// complete font file that supports those features.\n\t\tif (a.openType !== b.openType) return a.openType ? -1 : 1\n\n\t\t// We don't care about the order of the rest of the fonts.\n\t\treturn 0\n\t})\n\n\tconst visitedCompositeFonts = new Map<string, ComponentFont>()\n\tconst visitedFonts = new Set<string>()\n\tconst googleFonts: GoogleComponentFont[] = []\n\tconst manuallyConstructedGoogleFonts: GoogleComponentFont[] = []\n\tconst nonGoogleFonts: NonGoogleComponentFont[] = []\n\tfor (const font of prioritizedFonts) {\n\t\t// Ignore this font if it\u2019s already provided by a different source (no\n\t\t// matter the unicode ranges). Thanks to the .sort() above,\n\t\t// higher-quality font URLs will come first.\n\t\tconst compositeFontHash = createCompositeFontHash(font)\n\t\tif (\n\t\t\tvisitedCompositeFonts.has(compositeFontHash) &&\n\t\t\tvisitedCompositeFonts.get(compositeFontHash)!.source !== font.source\n\t\t) {\n\t\t\tcontinue\n\t\t}\n\t\tvisitedCompositeFonts.set(compositeFontHash, font)\n\n\t\t// Ignore this font if the identical font (but perhaps with a different\n\t\t// url) is already available. Thanks to the .sort() above,\n\t\t// higher-quality sources will come first.\n\t\tconst fontHash = createComponentFontHash(font)\n\t\tif (visitedFonts.has(fontHash)) continue\n\t\tvisitedFonts.add(fontHash)\n\n\t\tif (isGoogleComponentFont(font)) {\n\t\t\t// Google Fonts provides subsetted fonts by default for better performance,\n\t\t\t// but these subsets don't include all OpenType layout features (like ligatures\n\t\t\t// or stylistic alternates). For static fonts with OpenType features, we need\n\t\t\t// to manually construct the @font-face using the complete font file. Variable\n\t\t\t// fonts are handled differently - we can use the `capability=VF` query param\n\t\t\t// which includes all layout features while still maintaining subsetting.\n\t\t\tif (font.openType) {\n\t\t\t\tmanuallyConstructedGoogleFonts.push(font)\n\t\t\t} else {\n\t\t\t\tgoogleFonts.push(font)\n\t\t\t}\n\t\t} else {\n\t\t\tassert(isNonGoogleComponentFont(font))\n\t\t\tconst resolvedFont = resolveFont(modulesSnapshot, font)\n\t\t\tnonGoogleFonts.push(resolvedFont)\n\t\t}\n\t}\n\n\treturn { googleFonts, manuallyConstructedGoogleFonts, nonGoogleFonts }\n}\n\nfunction getGoogleVariableFontAxesOptions(variationAxes: ReadonlyFontVariationAxes) {\n\t// Axes should be sorted alphabetically by tag (a, b, c, A, B, C)\n\tconst sortedAxes = [...variationAxes].sort(({ tag: a }, { tag: b }) => {\n\t\tconst aIsLower = a === a.toLowerCase()\n\t\tconst bIsLower = b === b.toLowerCase()\n\n\t\tif (aIsLower && !bIsLower) return -1\n\t\tif (!aIsLower && bIsLower) return 1\n\t\treturn a.localeCompare(b)\n\t})\n\n\tconst tags: string[] = []\n\tconst values: string[] = []\n\n\tfor (const axis of sortedAxes) {\n\t\ttags.push(axis.tag)\n\t\tvalues.push(`${axis.minValue}..${axis.maxValue}`)\n\t}\n\n\treturn { tags, values }\n}\n\nfunction getGoogleVariableFont(\n\tfontFamily: ComponentFont[\"uiFamilyName\"],\n\tvariationAxes: NonNullable<ComponentFont[\"variationAxes\"]>,\n) {\n\tconst { tags, values } = getGoogleVariableFontAxesOptions(variationAxes)\n\treturn `${encodeGoogleFontFamily(fontFamily)}:${tags.join(\",\")}@${values.join(\",\")}`\n}\n\nconst encodeGoogleFontFamily = (family: string) => family.replace(/\\s+/gu, \"+\")\n\n// Regular expression to match font-family declarations\n// This handles both single and double quoted font names, as well as unquoted names\nconst fontFamilyRegex = /font-family:\\s*(['\"]?)([^'\";]+)\\1/g\nfunction appendVariableToFontFamily(fontsCss: string): string {\n\t// Replace each font-family occurrence with the same name + \" Variable\"\n\treturn fontsCss.replace(fontFamilyRegex, (match, quote, fontName) => {\n\t\t// If the quote exists (either ' or \"), use it, otherwise use empty string\n\t\tconst quoteChar = quote || \"\"\n\t\t// Trim the font name and append \" Variable\"\n\t\tconst newFontName = fontName.trim() + \" Variable\"\n\n\t\treturn `font-family: ${quoteChar}${newFontName}${quoteChar}`\n\t})\n}\n\nasync function fetchGoogleFonts(queryParams: string[]): Promise<string> {\n\tif (queryParams.length === 0) return \"\"\n\tconst request = `/web/google-fonts/css?${queryParams.join(\"&\")}`\n\tconst response = await apiFetcher.getRaw(request)\n\tif (response.status !== 200) {\n\t\tthrow new Error(`error fetching Google Fonts CSS: ${response} returned ${response.status}`)\n\t}\n\tif (!response.headers.get(\"content-type\")?.startsWith(\"text/css\")) {\n\t\tthrow new Error(`error fetching Google Fonts CSS: content-type is not text/css`)\n\t}\n\n\treturn response.text()\n}\n\nexport const testing = {\n\tgetGoogleVariableFontAxesOptions,\n\tgetGoogleVariableFont,\n\tencodeGoogleFontFamily,\n\tappendVariableToFontFamily,\n}\n", "import { AnalyticsScopeNode } from \"document/models/CanvasTree/index.ts\"\nimport { isWebPageNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { GenerateRoutesContext } from \"./exportToHTML.ts\"\n\n/**\n * Calculates cumulative distribution start positions for A/B test variants.\n * Returns an array where each element represents the (0-indexed) start position\n * in **parts per million (PPM)** (0\u2013999,999) for the corresponding variant in `variantIds`.\n *\n * E.g. for Control: 10%, Variant A: 20%, Variant B: 70%\n * Returns [100000, 300000] meaning: control 0-99,999, variant A 100,000-299,999, variant B 300,000-999,999\n */\nexport function getAbTestCumulativeDistributions(\n\tcontext: GenerateRoutesContext,\n\tcontrolPageId: string,\n\tvariantIds: readonly string[],\n): number[] | undefined {\n\tconst controlPage = context.tree.get(controlPageId)\n\tif (!isWebPageNode(controlPage)) return undefined\n\n\tconst analyticsScopeNode = AnalyticsScopeNode.get(context.tree)?.loaded\n\tconst funnel = controlPage.getAbTestingFunnel(analyticsScopeNode)\n\tif (!funnel) return undefined\n\n\tconst { distributions } = funnel.getAbVariantDistributionsPpm(context.tree, context.componentLoader)\n\tconst distributionMap = new Map(distributions.map(d => [d.id, d.distributionPercentagePpm ?? 0] as const))\n\n\t// Control PPM determines where variants start\n\tconst controlPpm = distributionMap.get(controlPageId) ?? 0\n\n\t// Build cumulative start positions for each variant (in variantIds order)\n\tlet cumulative = controlPpm\n\tconst cumulativeDistributions: number[] = []\n\tfor (const variantId of variantIds) {\n\t\tcumulativeDistributions.push(cumulative)\n\t\tcumulative += distributionMap.get(variantId) ?? 0\n\t}\n\n\treturn cumulativeDistributions\n}\n", "import md5 from \"md5\"\nimport { basex } from \"../utils/baseX.ts\"\n\n// Generates bundle ID the same way generate-static-site does:\n// https://github.com/framer/FramerInfrastructureFunctions/blob/7ba52e47087de744b7dfbc87fc9ea00e5dc7625f/functions/generate-static-site/src/ssg-service/index.ts#L76-L81\n\n// This is different than in base62.ts because we need to match:\n// https://github.com/framer/FramerInfrastructureFunctions/blob/7ba52e47087de744b7dfbc87fc9ea00e5dc7625f/functions/generate-static-site/src/ssg-service/index.ts#L16\nconst BASE_62_ALPHABET = \"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n\nconst BASE_62_CONVERTER = basex(BASE_62_ALPHABET)\n\nexport function getBundleId(projectId: string): string {\n\tconst projectIdBytes = BASE_62_CONVERTER.decode(projectId)\n\tconst bundleIdBytes = md5(projectIdBytes, { asBytes: true })\n\treturn BASE_62_CONVERTER.encode(bundleIdBytes)\n}\n", "import type {\n\tDeploymentTreeState,\n\tPatchedDeploymentTreeState,\n\tRegularDeploymentTreeState,\n} from \"@framerjs/app-shared/src/Deployments.ts\"\nimport { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport {\n\tassert,\n\ttype ModuleExportIdentifierString,\n\tModuleType,\n\tgetLogger,\n\tisLocalModuleIdentifier,\n\tlocalModuleIdentifierForStableName,\n\tparseModuleIdentifier,\n} from \"@framerjs/shared\"\nimport { isCompatibleWithCurrentApp } from \"code-generation/codeGenVersion.ts\"\nimport type { SafeJS } from \"code-generation/js/serializeJS.ts\"\nimport { BindingCollector } from \"code-generation/utils/BindingCollector.ts\"\nimport { ImportCollector } from \"code-generation/utils/ImportCollector.ts\"\nimport type { MetricsCollector } from \"code-generation/utils/MetricsCollector.ts\"\nimport {\n\tgetMissingComponents,\n\twaitForLoadingComponentsWithTimeout,\n} from \"code-generation/utils/waitForLoadingComponentsWithTimeout.ts\"\nimport type { BaseEngineScheduler } from \"document/base-engine/BaseEngine.ts\"\nimport { CrdtTreeCommitter } from \"document/crdt/sync/CrdtTreeCommitter.ts\"\nimport type { CanvasTree } from \"document/models/CanvasTree/CanvasTree.ts\"\nimport type { TreeUpdater } from \"document/models/CanvasTree/TreeUpdater.ts\"\nimport {\n\ttype CodeComponentNode,\n\ttype NodeID,\n\ttype ShallowSmartComponentNode,\n\tisScopeNode,\n} from \"document/models/CanvasTree/index.ts\"\nimport type { CanvasNode } from \"document/models/CanvasTree/nodes/CanvasNode.ts\"\nimport type { AnyLayoutTemplateNode } from \"document/models/CanvasTree/nodes/LayoutTemplateNode.ts\"\nimport type { AnyWebPageNode, ShallowWebPageNode } from \"document/models/CanvasTree/nodes/WebPageNode.ts\"\nimport {\n\tisCodeComponentNode,\n\tisSmartComponentNode,\n\tisWebPageNode,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { AssetStore } from \"document/stores/AssetStore.ts\"\nimport type { CodeGenerationStore } from \"document/stores/CodeGenerationStore.ts\"\nimport type { ModulesStore, ModulesStoreSnapshot } from \"document/stores/ModulesStore.ts\"\nimport {\n\tgetCanvasPageNodes,\n\tgetWebPageNodesWithCollection,\n\tgetWebPageNodesWithoutCollection,\n} from \"document/stores/ScopeStore.ts\"\nimport type { TreeStore } from \"document/stores/TreeStore.ts\"\nimport { isValidModuleSourceNode, localModuleIdsForSourceNode } from \"document/utils/moduleSourceNodeHelpers.ts\"\nimport type { ExportToHTMLMetrics } from \"./ExportToHTMLMetrics.ts\"\nimport { collectNodesInPrototypeNavigationChain } from \"./collectNodesInPrototypeNavigationChain.ts\"\nimport { exportLayoutTemplates, getAppliedLocalLayoutTemplates } from \"./exportLayoutTemplates.ts\"\n\nconst log = getLogger(\"exportToHTML\")\n\nconst MAX_SYNC_ITERATIONS = 10\n\nexport interface ProjectSnapshotForExport {\n\ttree: CanvasTree\n\ttreeState: DeploymentTreeState\n\tmodulesSnapshot: ModulesStoreSnapshot\n\tcomponentLoaderSnapshot: ComponentLoader\n\tentryScreenNode: AnyWebPageNode\n\tscreenNodesToExport: CanvasNode[]\n\tlayoutTemplateNodesToExport: AnyLayoutTemplateNode[]\n\tlayoutTemplate: { binding: SafeJS; declarations: SafeJS; css: string } | undefined\n\timports: SafeJS[]\n}\n\nexport async function prepareProjectSnapshotForExport({\n\tassetStore,\n\tcodeGenerationStore,\n\tcomponentLoader,\n\tentryScreenNodeIdOverride,\n\tlazyLayoutTemplates,\n\tmetrics,\n\tmodulesStore,\n\tpatchedTreeState,\n\tscheduler,\n\ttreeStore,\n}: {\n\tassetStore: AssetStore\n\tcodeGenerationStore: CodeGenerationStore\n\tcomponentLoader: ComponentLoader\n\tentryScreenNodeIdOverride: NodeID | undefined\n\tlazyLayoutTemplates?: boolean\n\tmetrics: MetricsCollector<keyof ExportToHTMLMetrics>\n\tmodulesStore: ModulesStore\n\tpatchedTreeState?: PatchedDeploymentTreeState\n\tscheduler: BaseEngineScheduler\n\ttreeStore: TreeStore\n}): Promise<ProjectSnapshotForExport> {\n\tlet lastConvergenceState: ConvergenceState | undefined\n\n\tconst convergenceTimer = metrics.time(\"snapshotConvergeMs\")\n\n\tlet iteration = 0\n\twhile (iteration++ < MAX_SYNC_ITERATIONS) {\n\t\t// Tree changes get queued for code-gen in postProcess, so we wait for that to happen.\n\t\tawait new Promise<void>(resolve => {\n\t\t\tscheduler.runBeforeNextFrame(resolve)\n\t\t})\n\n\t\t// ! Begin: code that checks convergence must be sync!\n\t\tconst convergenceState = getConvergenceState({\n\t\t\tcodeGenerationStore,\n\t\t\tcomponentLoader,\n\t\t\tentryScreenNodeIdOverride,\n\t\t\tmodulesStore,\n\t\t\ttree: treeStore.getDataTreeOrLoadedTree(),\n\t\t})\n\t\tlastConvergenceState = convergenceState\n\n\t\tif (convergenceState.isConverged) {\n\t\t\tbreak\n\t\t}\n\t\t// ! End: code that checks convergence must be sync!\n\n\t\tlog.debug(\n\t\t\t\"prepareProjectSnapshotForExport: not converged on iteration\",\n\t\t\titeration,\n\t\t\t\", isCodeGenIdle:\",\n\t\t\tconvergenceState.isCodeGenIdle,\n\t\t\t\", staleNodes:\",\n\t\t\tconvergenceState.staleNodes,\n\t\t\t\", incompatibleNodes:\",\n\t\t\tconvergenceState.incompatibleNodes,\n\t\t\t\", hasPendingModulesTreeData:\",\n\t\t\tconvergenceState.hasPendingModulesTreeData,\n\t\t\t\", hasMissingComponents:\",\n\t\t\tconvergenceState.hasMissingComponents,\n\t\t)\n\n\t\t// First, make sure any pending code-gen is complete.\n\t\tif (!convergenceState.isCodeGenIdle) {\n\t\t\tawait codeGenerationStore.generateAndPersistAllQueuedComponents()\n\t\t}\n\n\t\t// Then, make sure any *remaining* stale and incompatible nodes get force-regenerated.\n\t\tconst staleNodes = computeStaleNodes(codeGenerationStore)\n\t\tconst incompatibleNodes = computeIncompatibleNodes(\n\t\t\tconvergenceState.screenNodesToExport,\n\t\t\ttreeStore.getDataTreeOrLoadedTree(),\n\t\t\tmodulesStore,\n\t\t)\n\t\tawait Promise.all([\n\t\t\t// We want to force-regenerate stale nodes because there are certain cases where a node might be stale, but\n\t\t\t// its revision hints suggest otherwise, which causes code-gen to bail out if not forced.\n\t\t\tPromise.all(staleNodes.map(node => codeGenerationStore.forceComponentUpdate(node.id))),\n\t\t\tPromise.all(\n\t\t\t\tincompatibleNodes.map(async node => {\n\t\t\t\t\tconst timer = metrics.time(\"incompatibleForceUpdateMs\")\n\t\t\t\t\tawait codeGenerationStore.forceComponentUpdate(node.id)\n\t\t\t\t\ttimer.done()\n\t\t\t\t}),\n\t\t\t),\n\t\t])\n\n\t\t// Run these after code-gen, because code-gen will generate new modules that need:\n\t\t// - re-evaluating in the sandbox\n\t\t// - writing to the tree\n\t\tawait Promise.all([\n\t\t\twaitForLoadingComponentsWithTimeout(componentLoader, convergenceState.componentLoaderIdentifiers, modulesStore),\n\t\t\tmodulesStore.writeTreeData(),\n\t\t])\n\t}\n\n\t// ! Begin: code after the loop until we capture the snapshot must be sync!\n\tconvergenceTimer.done()\n\n\tconst snapshot = captureSnapshot({\n\t\tassetStore,\n\t\tcomponentLoader,\n\t\titerations: iteration - 1, // We break at MAX_SYNC_ITERATIONS + 1, so the actual iterations is one less.\n\t\tlastConvergenceState,\n\t\tlazyLayoutTemplates,\n\t\tmetrics,\n\t\tmodulesStore,\n\t\tpatchedTreeState,\n\t\ttree: treeStore.getDataTreeOrLoadedTree(),\n\t\ttreeUpdater: treeStore.timeline,\n\t})\n\t// ! End: code after the loop until we capture the snapshot must be sync!\n\n\treturn snapshot\n}\n\ninterface ConvergenceState {\n\tisConverged: boolean\n\tentryScreenNode: AnyWebPageNode\n\tscreenNodesToExport: CanvasNode[]\n\tlayoutTemplateNodesToExport: AnyLayoutTemplateNode[]\n\tisCodeGenIdle: boolean\n\tstaleNodes: CanvasNode[]\n\tincompatibleNodes: CanvasNode[]\n\thasPendingModulesTreeData: boolean\n\thasMissingComponents: boolean\n\tcomponentLoaderIdentifiers: ModuleExportIdentifierString[]\n}\n\n// This function must be sync!\nfunction getConvergenceState({\n\tcodeGenerationStore,\n\tcomponentLoader,\n\tentryScreenNodeIdOverride,\n\tmodulesStore,\n\ttree,\n}: {\n\tcodeGenerationStore: CodeGenerationStore\n\tcomponentLoader: ComponentLoader\n\tentryScreenNodeIdOverride: NodeID | undefined\n\tmodulesStore: ModulesStore\n\ttree: CanvasTree\n}): ConvergenceState {\n\tconst entryScreenNode = tree.get(entryScreenNodeIdOverride ?? tree.root.homePageNodeId)\n\tassert(entryScreenNode, \"Entry screen node must exist\")\n\tassert(isWebPageNode(entryScreenNode), \"Entry screen node must be a web page node\")\n\n\tconst screenNodesToExport = computeScreenNodesToExport(tree, entryScreenNode, componentLoader)\n\tconst layoutTemplateNodesToExport = getAppliedLocalLayoutTemplates(tree, screenNodesToExport)\n\n\tconst isCodeGenIdle = codeGenerationStore.isIdle()\n\tconst staleNodes = computeStaleNodes(codeGenerationStore)\n\tconst incompatibleNodes = computeIncompatibleNodes(screenNodesToExport, tree, modulesStore)\n\n\tconst hasPendingModulesTreeData = modulesStore.hasPendingTreeData()\n\n\tconst screenIdentifiers = screenNodesToExport.map(\n\t\tnode => localModuleIdentifierForStableName(ModuleType.Screen, node.id, \"default\").value,\n\t)\n\tconst layoutTemplateIdentifiers = layoutTemplateNodesToExport.map(node => node.instanceIdentifier)\n\tconst componentLoaderIdentifiers = [...screenIdentifiers, ...layoutTemplateIdentifiers]\n\tconst missingComponents = getMissingComponents(componentLoaderIdentifiers, componentLoader)\n\tconst hasMissingComponents = missingComponents.length > 0\n\n\tconst isConverged =\n\t\tisCodeGenIdle &&\n\t\tstaleNodes.length === 0 &&\n\t\tincompatibleNodes.length === 0 &&\n\t\t!hasPendingModulesTreeData &&\n\t\t!hasMissingComponents\n\n\treturn {\n\t\tisConverged,\n\t\tentryScreenNode,\n\t\tscreenNodesToExport,\n\t\tlayoutTemplateNodesToExport,\n\t\tisCodeGenIdle,\n\t\tstaleNodes,\n\t\tincompatibleNodes,\n\t\thasPendingModulesTreeData,\n\t\thasMissingComponents,\n\t\tcomponentLoaderIdentifiers,\n\t}\n}\n\n// This function must be sync!\nfunction captureSnapshot({\n\tassetStore,\n\tcomponentLoader,\n\titerations,\n\tlastConvergenceState,\n\tlazyLayoutTemplates,\n\tmetrics,\n\tmodulesStore,\n\tpatchedTreeState,\n\ttree,\n\ttreeUpdater,\n}: {\n\tassetStore: AssetStore\n\tcomponentLoader: ComponentLoader\n\titerations: number\n\tlastConvergenceState: ConvergenceState | undefined\n\tlazyLayoutTemplates: boolean | undefined\n\tmetrics: MetricsCollector<keyof ExportToHTMLMetrics>\n\tmodulesStore: ModulesStore\n\tpatchedTreeState?: PatchedDeploymentTreeState\n\ttree: CanvasTree\n\ttreeUpdater: TreeUpdater\n}): ProjectSnapshotForExport {\n\tassert(\n\t\tlastConvergenceState,\n\t\t\"prepareProjectSnapshotForExport should have at least one loop iteration that sets the convergence state\",\n\t)\n\tconst { entryScreenNode, screenNodesToExport, layoutTemplateNodesToExport } = lastConvergenceState\n\n\tmetrics.count(\"snapshotConvergeIterations\", iterations)\n\n\tif (iterations >= MAX_SYNC_ITERATIONS) {\n\t\tlog.reportError(\"prepareProjectSnapshotForExport: failed to converge after MAX_SYNC_ITERATIONS\", {\n\t\t\tisCodeGenIdle: lastConvergenceState.isCodeGenIdle,\n\t\t\tstaleNodes: lastConvergenceState.staleNodes.length,\n\t\t\tincompatibleNodes: lastConvergenceState.incompatibleNodes.length,\n\t\t\thasPendingModulesTreeData: lastConvergenceState.hasPendingModulesTreeData,\n\t\t\thasMissingComponents: lastConvergenceState.hasMissingComponents,\n\t\t})\n\t\t// Publish anyway, but the tree state may not be an accurate reflection of the published site.\n\t} else {\n\t\tlog.debug(\"prepareProjectSnapshotForExport: converged after\", iterations, \"iterations\")\n\t}\n\n\tconst treeState = getTreeState(treeUpdater, patchedTreeState)\n\n\tconst modulesSnapshot = modulesStore.takeSnapshot()\n\tconst componentLoaderSnapshot = new ComponentLoader(componentLoader)\n\n\tconst { imports, bindings } = prepareImports(componentLoader, modulesStore)\n\n\tconst layoutTemplate = exportLayoutTemplates(\n\t\ttree,\n\t\tcomponentLoader,\n\t\tmodulesStore,\n\t\tassetStore,\n\t\tscreenNodesToExport,\n\t\timports,\n\t\tbindings,\n\t\t{ lazy: lazyLayoutTemplates === true },\n\t)\n\n\treturn {\n\t\ttree,\n\t\ttreeState,\n\t\tmodulesSnapshot,\n\t\tcomponentLoaderSnapshot,\n\t\tentryScreenNode,\n\t\tscreenNodesToExport,\n\t\tlayoutTemplateNodesToExport,\n\t\tlayoutTemplate,\n\t\timports: imports.statements,\n\t}\n}\n\nexport class NoTreeVersionError extends Error {}\n\nfunction getTreeState(\n\ttreeUpdater: TreeUpdater,\n\tpatchedTreeState: PatchedDeploymentTreeState | undefined,\n): DeploymentTreeState {\n\tif (patchedTreeState) {\n\t\treturn patchedTreeState\n\t}\n\tif (!treeUpdater.remoteTreeVersion) {\n\t\tthrow new NoTreeVersionError()\n\t}\n\tconst treeState: RegularDeploymentTreeState = {\n\t\ttreeVersion: treeUpdater.remoteTreeVersion,\n\t}\n\tif (treeUpdater instanceof CrdtTreeCommitter) {\n\t\ttreeState.frontier = treeUpdater.store.manifest.toMaxSeqArray()\n\t}\n\treturn treeState\n}\n\nfunction computeScreenNodesToExport(\n\ttree: CanvasTree,\n\tentryScreenNode: AnyWebPageNode,\n\tcomponentLoader: ComponentLoader,\n): CanvasNode[] {\n\t// Ensure all web pages in the tree are included. They don't need to be\n\t// linked to to be valid publish targets, and may be linked to by draft text\n\t// which we do not collect as part of the chain.\n\tconst anyWebPages: AnyWebPageNode[] = [\n\t\tentryScreenNode,\n\t\t// Static pages go before CMS pages, because that's what our client-side router does, and we want our\n\t\t// server-side router (which just follows the order) to do the same.\n\t\t//\n\t\t// See: https://github.com/framer/company/issues/26015\n\t\t...getWebPageNodesWithoutCollection(tree),\n\t\t...getWebPageNodesWithCollection(tree, true),\n\t]\n\tconst navigableScreens = new Set<CanvasNode | AnyWebPageNode>(anyWebPages)\n\t/**\n\t * @TODO - Don't use all page nodes, just ones linked to by a prototype component in a web page.\n\t */\n\tfor (const node of getCanvasPageNodes(tree)) {\n\t\tconst homeNode = tree.get(node.homeNodeId)\n\t\tif (!homeNode) continue\n\n\t\tcollectNodesInPrototypeNavigationChain(tree, componentLoader, homeNode).forEach(screen =>\n\t\t\tnavigableScreens.add(screen),\n\t\t)\n\t}\n\n\tconst screenNodesToExport = Array.from(navigableScreens)\n\t\t.map(node => {\n\t\t\t// Usually, if a ground node happens to be a CodeComponentNode, we'll\n\t\t\t// generate a simple screen which renders the respective component, for\n\t\t\t// example:\n\t\t\t//\n\t\t\t//     // generated <CodeComponentNode ID>.tsx\n\t\t\t//     import Component from \"... <SmartComponentNode ID>.tsx\"\n\t\t\t//     const Screen = () => (\n\t\t\t//         <Component variable1={xxx} variable2={xxx} />\n\t\t\t//     )\n\t\t\t//\n\t\t\t//     // generated HTML\n\t\t\t//     import Screen from \"...\"\n\t\t\t//     ReactDOM.render(<Screen />)\n\t\t\t//\n\t\t\t// But if the CodeComponentNode is an instance of a responsive screen\n\t\t\t// component (i.e., a SmartComponentNode with variantType: breakpoint),\n\t\t\t// we instead want to use the component's module itself as the screen:\n\t\t\t//\n\t\t\t//     // generated HTML\n\t\t\t//     import ResponsiveScreenComponent from \"... <SmartComponentNode ID>.tsx\"\n\t\t\t//     ReactDOM.render(<ResponsiveScreenComponent />)\n\t\t\t//\n\t\t\t// We achieve this by switching out the CodeComponentNode for the\n\t\t\t// respective SmartComponentNode.\n\t\t\tconst canvasNode = node as CanvasNode\n\t\t\tif (isCodeComponentNode(canvasNode)) {\n\t\t\t\tconst smartComponentOrWebPageNode = getSmartComponentOrWebPageNode(tree, canvasNode, ModuleType.Screen)\n\t\t\t\tif (smartComponentOrWebPageNode) return smartComponentOrWebPageNode.loaded\n\t\t\t}\n\t\t\t// TODO Check and handle shallow/fully loaded scope state\n\t\t\tif (isScopeNode(node, true)) {\n\t\t\t\tassert(node.isLoaded(), \"Node must be loaded to be exported.\")\n\t\t\t\treturn node.loaded\n\t\t\t}\n\t\t\treturn canvasNode\n\t\t})\n\t\t.filter((node): node is CanvasNode => {\n\t\t\tif (!node) return false\n\t\t\tif (!isValidModuleSourceNode(node, tree)) {\n\t\t\t\tlog.error(\n\t\t\t\t\t\"Node\",\n\t\t\t\t\tnode.id,\n\t\t\t\t\t\"was referenced as a navigable screen, but is a\",\n\t\t\t\t\tnode.__class,\n\t\t\t\t\t\"with a\",\n\t\t\t\t\ttree.get(node.parentid)?.__class ?? \"<null>\",\n\t\t\t\t\t\"parent, you may need to update links to fix this.\",\n\t\t\t\t)\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn true\n\t\t})\n\treturn screenNodesToExport\n}\n\nfunction computeStaleNodes(codeGenerationStore: CodeGenerationStore) {\n\treturn codeGenerationStore.nodesWithStaleModules()\n}\n\nfunction computeIncompatibleNodes(screenNodesToExport: CanvasNode[], tree: CanvasTree, modulesStore: ModulesStore) {\n\treturn nodesWithIncompatibleModules(screenNodesToExport, tree, modulesStore)\n}\n\n/**\n * Given a CodeComponentNode pointing to a local module, return its respective\n * SmartComponentNode or WebPageNode.\n *\n * @param moduleType If provided, will bail unless the CodeComponentNode points to a module of that type\n */\nfunction getSmartComponentOrWebPageNode(\n\ttree: CanvasTree,\n\tinstance: CodeComponentNode,\n\tmoduleType?: ModuleType,\n): ShallowSmartComponentNode | ShallowWebPageNode | undefined {\n\tconst moduleIdentifier = parseModuleIdentifier(instance.codeComponentIdentifier)\n\tif (!isLocalModuleIdentifier(moduleIdentifier)) return\n\n\tif (moduleType && moduleIdentifier.type !== moduleType) return\n\n\tconst [, componentNodeId] = moduleIdentifier.localId.split(\"/\")\n\tconst componentNode = tree.get(componentNodeId)\n\tif (!isSmartComponentNode(componentNode) && !isWebPageNode(componentNode)) return\n\n\treturn componentNode\n}\n\nfunction nodesWithIncompatibleModules(nodes: CanvasNode[], tree: CanvasTree, modulesStore: ModulesStore): CanvasNode[] {\n\tconst incompatible: CanvasNode[] = []\n\tfor (const node of nodes) {\n\t\tconst localModuleIds = localModuleIdsForSourceNode(node, tree)\n\t\tconst modules = localModuleIds.map(localId => modulesStore.getPersistedModuleByLocalId(localId))\n\t\tif (modules.some(module => !module || !isCompatibleWithCurrentApp(node, module, tree))) {\n\t\t\tincompatible.push(node)\n\t\t}\n\t}\n\treturn incompatible\n}\n\nfunction prepareImports(componentLoader: ComponentLoader, modulesStore: ModulesStore) {\n\tconst bindings = new BindingCollector()\n\tconst imports = new ImportCollector(undefined, componentLoader, modulesStore, bindings)\n\n\t// Every export always has these imports. We bind them ahead of time to reserve the\n\t// importBinding names.\n\timports.addImport(\"react\", { exportSpecifier: \"*\", importBinding: \"React\" })\n\timports.addImport(\"react-dom\", {\n\t\texportSpecifier: \"createPortal\",\n\t\timportBinding: \"createPortal\",\n\t})\n\timports.addImport(\"react-dom/client\", {\n\t\texportSpecifier: \"*\",\n\t\timportBinding: \"ReactDOM\",\n\t})\n\timports.addImport(\"framer\", {\n\t\texportSpecifier: \"*\",\n\t\timportBinding: \"Framer\",\n\t})\n\n\treturn { imports, bindings }\n}\n", "import type { FeatureValue } from \"@framerjs/app-config\"\nimport {\n\ttype DeploymentTreeState,\n\ttype PatchedDeploymentTreeState,\n\tSearchIndexStatus,\n} from \"@framerjs/app-shared/src/Deployments.ts\"\nimport { createAbsoluteImageAssetURL, parseAssetReference } from \"@framerjs/assets\"\nimport type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport {\n\ttype LocalModuleExportIdentifierString,\n\tModuleType,\n\tassert,\n\temptyArray,\n\tgetServiceMap,\n\tlocalModuleImportMapSpecifier,\n\tparseModuleIdentifier,\n} from \"@framerjs/shared\"\nimport { isModuleType } from \"@framerjs/shared/src/moduleIdentifiers.ts\"\nimport {\n\tbundleDataAttr,\n\tendOfBodyEndMarker,\n\tendOfBodyStartMarker,\n\tendOfHeadEndMarker,\n\tendOfHeadStartMarker,\n\tesModuleShimsDataAttr,\n\thydrateV2DatasetKey,\n\timportMapDataAttr,\n\tmainBundleName,\n\tmainTagId,\n\tsearchIndexFallbackMetaName,\n\tsearchIndexMetaName,\n\tstartOfBodyEndMarker,\n\tstartOfBodyStartMarker,\n\tstartOfHeadEndMarker,\n\tstartOfHeadStartMarker,\n} from \"@framerjs/shared/src/ssg/constants.ts\"\nimport type { SSGRewrite, SSGRoute } from \"@framerjs/shared/src/ssg/editor.ts\"\nimport { experiments } from \"app/experiments.ts\"\nimport { features } from \"app/features.ts\"\nimport { viewportForNode } from \"code-generation/components/generateMetadataModule.ts\"\nimport { snippetsModuleIdentifier } from \"code-generation/components/generateSnippetsModule.ts\"\nimport { js } from \"code-generation/js/js.ts\"\nimport { type SafeJS, SerializableObject, SortBehavior, serializeJS } from \"code-generation/js/serializeJS.ts\"\nimport type { NavigationRoute, NavigationRoutes } from \"code-generation/types.ts\"\nimport { BindingCollector } from \"code-generation/utils/BindingCollector.ts\"\nimport { FileDeclarationCollector } from \"code-generation/utils/DeclarationCollector.ts\"\nimport { MetricsCollector } from \"code-generation/utils/MetricsCollector.ts\"\nimport type { BaseEngineScheduler } from \"document/base-engine/BaseEngine.ts\"\nimport { getIncludedLocales } from \"document/components/chrome/localization/includedLocales.ts\"\nimport { framerStudioVersion } from \"document/components/chrome/statusBar/versions.ts\"\nimport { getRawWebPagePath, getRawWebPagePathLocalized } from \"document/components/utils/getWebPagePath.ts\"\nimport {\n\tAnalyticsScopeNode,\n\ttype CanvasNode,\n\ttype CanvasTree,\n\ttype CustomCodeNode,\n\tCustomCodeScopeNode,\n\ttype NodeID,\n\ttype WebPageNode,\n} from \"document/models/CanvasTree/index.ts\"\nimport { ColorStyleTokenListNode } from \"document/models/CanvasTree/nodes/ColorStyleTokenListNode.ts\"\nimport { FunnelStatus } from \"document/models/CanvasTree/nodes/FunnelNode.ts\"\nimport {\n\ttype LocalizedSegments,\n\ttype ReadonlyWebPageSegmentReferencePathByWebPageId,\n\tgetRouteSegmentRootNode,\n} from \"document/models/CanvasTree/nodes/RouteSegmentRootNode.utils.ts\"\nimport { isWebPageNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isVariableReference } from \"document/models/CanvasTree/traits/VariableReference.ts\"\nimport {\n\ttype WithCollectionDataSource,\n\thasCollectionDataSource,\n} from \"document/models/CanvasTree/traits/WithCollectionDataSource.ts\"\nimport { hasLayoutTemplate } from \"document/models/CanvasTree/traits/WithLayoutTemplate.ts\"\nimport { getWebPageScrollTargets } from \"document/models/CanvasTree/traits/WithScrollTarget.ts\"\nimport type { WebMetadata } from \"document/models/CanvasTree/traits/WithWebMetadata.ts\"\nimport { getExportTokenCSSRules } from \"document/models/CanvasTree/utils/tokens.ts\"\nimport type { AssetStore } from \"document/stores/AssetStore.ts\"\nimport type { CodeGenerationStore } from \"document/stores/CodeGenerationStore.ts\"\nimport type { DebugStore } from \"document/stores/DebugStore.ts\"\nimport type { ModulesStore, ModulesStoreSnapshot } from \"document/stores/ModulesStore.ts\"\nimport type { ProjectStore } from \"document/stores/ProjectStore.ts\"\nimport type { PublishStore, ServerAbTest, ServerRoute } from \"document/stores/PublishStore.ts\"\nimport { getWebPageNodes } from \"document/stores/ScopeStore.ts\"\nimport type { TreeStore } from \"document/stores/TreeStore.ts\"\nimport { localModuleIdsForSourceNode } from \"document/utils/moduleSourceNodeHelpers.ts\"\nimport { listVersionDeployments } from \"document/utils/sitesAPI.ts\"\nimport { FORCE_SHOW_KEY as FORCE_SHOW_EDITOR_BAR_KEY } from \"editorbar/constants.ts\"\nimport { getFramerRelease } from \"environment/getFramerRelease.ts\"\nimport { getTunnelId } from \"environment/getTunnelId.ts\"\nimport { framerAppearAnimationScriptKey, framerCSSMarker } from \"library/index.ts\"\nimport type { LibraryFeatures } from \"library/modules/LibraryFeaturesContext.ts\"\nimport { escapeHTML } from \"library/render/utils/dom.ts\"\nimport { customNotFoundPagePaths } from \"library/router/customNotFoundPagePaths.ts\"\nimport type { Locale as RouterLocale } from \"library/router/types.ts\"\nimport type { PersistedModule } from \"modules/ModulesStorage.ts\"\nimport { extendImportMap, getStaticImportMap, getTailscaleScreenshotImportMap } from \"modules/importMapManager.ts\"\nimport type { ImportMap } from \"modules/types.ts\"\nimport { getTypeSlashName } from \"modules/utils.ts\"\nimport { defaultFontSites } from \"renderer/setDefaultFont.ts\"\nimport { randomBase62 } from \"utils/base62.ts\"\nimport { getSamplePathVariablesForCMSPage } from \"utils/collectionUtils.ts\"\nimport { type CustomHTML, getAllParsedCustomHTML } from \"utils/customHTML.ts\"\nimport {\n\ttype CollectionUtilExport,\n\tcollectCollectionUtilsForReferencedCollections,\n\tgetCollectionUtilForDataIdentifier,\n\tgetCollectionUtilForNode,\n} from \"utils/getCollectionUtilForNode.ts\"\nimport { getRouterLocales } from \"utils/getRouterLocales.ts\"\nimport { join } from \"utils/join.ts\"\nimport { isString } from \"utils/typeChecks.ts\"\nimport { type ExportToHTMLMetrics, defaultExportToHTMLMetrics } from \"./ExportToHTMLMetrics.ts\"\nimport captureFormsUTMTagsInCookieSource from \"./bundled/captureFormsUTMTagsInCookie.ts?bundleSites\"\nimport formatRelativeDateSource from \"./bundled/formatRelativeDate.ts?bundleSites\"\nimport rewriteLinksWithQueryParamsSource from \"./bundled/rewriteLinksWithQueryParams.ts?bundleSites\"\nimport { collectHeaderRoutes } from \"./collectHeaderRoutes.ts\"\nimport type { TokenisedSitePageEffects } from \"./collectPageEffects.ts\"\nimport { collectPageEffectsForPublish } from \"./collectPageEffects.ts\"\nimport { collectProxyRoutes } from \"./collectProxyRoutes.ts\"\nimport { collectRedirectRoutes } from \"./collectRedirectRoutes.ts\"\nimport { collectRewriteRoutes } from \"./collectRewriteRoutes.ts\"\nimport { generateFonts } from \"./generateFonts.ts\"\nimport { getAbTestCumulativeDistributions } from \"./getAbTestCumulativeDistributions.ts\"\nimport { getBundleId } from \"./getBundleId.ts\"\nimport { globalStylesForExport } from \"./globalStylesForExport.ts\"\nimport { type ProjectSnapshotForExport, prepareProjectSnapshotForExport } from \"./prepareProjectSnapshotForExport.ts\"\n\nexport interface GenerateRoutesContext {\n\treadonly tree: CanvasTree\n\treadonly componentLoader: ComponentLoader\n\treadonly modulesSnapshot: ModulesStoreSnapshot\n\treadonly metrics: MetricsCollector<keyof ExportToHTMLMetrics>\n\treadonly projectId: string\n\treadonly canUseAdvancedHeaders: FeatureValue\n\tnavigationRoutes: NavigationRoutes\n\tserverRoutes: ServerRoute[]\n\tlocalizedSegments?: LocalizedSegments\n\twebPageSegmentReferencePathByWebPageId: ReadonlyWebPageSegmentReferencePathByWebPageId | undefined\n\tssgRoutes: SSGRoute[]\n\tssgRewrites: SSGRewrite[]\n\t/** Maps the control page id to the ids of its A/B testing variants */\n\tabTestingVariantIdsByWebPageId: Record<string, string[]>\n\tpageEffects: TokenisedSitePageEffects\n\tpageEffectsDeclarations: FileDeclarationCollector\n\tuniqueLayoutTemplates: Set<LocalModuleExportIdentifierString>\n\theaderKeys: Set<string>\n\toverrides?: GenerateHTMLOverrides\n}\n\n// Specifier should not be changed without also updating SSG!\nconst badgeImportSpecifier = \"__framer-badge\"\n/**\n * To update the badge:\n * 0) Bring this PR https://github.com/framer/FramerStudio/pull/24477 up to date (rebase from master) until\n *    https://github.com/framer/company/issues/33852 is fixed\n * 1) Go to the project https://fix-masks-chrome.beta.framer.com/projects/Made-in-Framer-Badge--kSrabtE7g9E6iCxT1hhx-fhDEr?node=PX9hIOIVM\n * 2) Open the badge (e.g. by double clicking or assets -> project -> badge), make any changes, publish\n * 3) Right click \"badge\" and select \"Copy URL\", open in browser and copy the final URL (after the redirect)\n *\n * Then:\n * 4) Go to Assets -> Update badgeModuleURL & the import URL in the \"SSRBadge.tsx\" code file, save.\n * 5) Publish the page, visit it and copy the code from the \"Generate SSR\" button.\n * 6) Paste the output here.\n */\nconst badgeModuleURL = \"https://framerusercontent.com/modules/kr6mBIQPAjMiv35rQa3A/JqQCEBMftp0u8SBv29R5/PX9hIOIVM.js\"\nconst badgeSSRHTML = `<!--$--><!--$--><!--$--><a class=\"framer-6jWyo framer-n0ccwk framer-v-n0ccwk framer-bmpgw8 __framer-badge\" data-framer-appear-id=\"n0ccwk\" data-framer-name=\"Light\" data-nosnippet=\"true\" style=\"will-change:transform;pointer-events:auto;opacity:0.001;transform:translateY(10px)\" href=\"https://www.framer.com\" rel=\"noopener\" title=\"Create a free website with Framer, the website builder loved by startups, designers and agencies.\"><div class=\"framer-13yxzio\" data-framer-name=\"Backdrop\" style=\"background-color:rgb(255, 255, 255);border-bottom-left-radius:10px;border-bottom-right-radius:10px;border-top-left-radius:10px;border-top-right-radius:10px;box-shadow:0px 0.6021873017743928px 1.5656869846134214px -1.5px rgba(0, 0, 0, 0.17), 0px 2.288533303243457px 5.950186588432988px -3px rgba(0, 0, 0, 0.14), 0px 10px 26px -4.5px rgba(0, 0, 0, 0.02)\"></div><div class=\"framer-19yaanm\" data-framer-name=\"Content\" style=\"transform:translate(-50%, -50%)\"><div class=\"framer-1kflzx5\"><div data-framer-name=\"Logo\" class=\"framer-hcsc7 framer-e50co\" style=\"--1bd4d3i:rgb(0, 0, 0);--otdjsv:rgb(0, 0, 0);transform:translateX(-50%)\"></div></div><!--$--><p style=\"position:absolute;transform:scale(0.001)\">Create a free website with Framer, the website builder loved by startups, designers and agencies.</p><div data-framer-name=\"Text\" class=\"framer-g7oZR framer-1um7t9d\" style=\"--1bd4d3i:rgb(0, 0, 0);--otdjsv:rgb(0, 0, 0)\"></div><!--/$--></div><div class=\"framer-j4ugry\" data-framer-name=\"Bottom\" style=\"mask:linear-gradient(180deg, rgba(0,0,0,0) 65%, rgba(0,0,0,1) 100%) add;-webkit-mask:linear-gradient(180deg, rgba(0,0,0,0) 65%, rgba(0,0,0,1) 100%) add;border-bottom-left-radius:11px;border-bottom-right-radius:11px;border-top-left-radius:11px;border-top-right-radius:11px;box-shadow:inset 0px 0px 0px 1px rgb(0, 0, 0);opacity:0.06\"></div><div class=\"framer-jnuwbw\" data-framer-name=\"Border\" style=\"border-bottom-left-radius:11px;border-bottom-right-radius:11px;border-top-left-radius:11px;border-top-right-radius:11px;box-shadow:inset 0px 0px 0px 1px rgb(0, 0, 0);opacity:0.04\"></div></a><!--/$--><!--/$--><!--/$-->`\n\nfunction isIgnoredModule(typeSlashName: string, module: PersistedModule, overrides?: GenerateHTMLOverrides) {\n\t// Draft collections should not be included in the public import map\n\tif (module.type === ModuleType.DraftCollection) return true\n\n\tif (!overrides) return false\n\n\tif (module.type === ModuleType.WebPageMetadata) {\n\t\treturn (\n\t\t\ttypeSlashName !==\n\t\t\tgetTypeSlashName({\n\t\t\t\ttype: ModuleType.WebPageMetadata,\n\t\t\t\tname: overrides.initialRoute?.routeId,\n\t\t\t})\n\t\t)\n\t}\n\n\tassert(isModuleType(module.type), \"Module type is not valid\")\n\n\treturn overrides.importMapModuleTypeFilter(module.type)\n}\n\nexport function createLocalModuleImportMap(\n\tmodulesSnapshot: ModulesStoreSnapshot,\n\toverrides?: GenerateHTMLOverrides,\n): ImportMap {\n\tconst importMap: ImportMap = { imports: {} }\n\t// Create an entry for every local module in ModulesStore. We ignore the\n\t// LocalModulesListNode as it is not guaranteed to be up-to-date as it can\n\t// be impacted by tree disconnections etc. and at this time is only really\n\t// meant to drive the version of modules for version history.\n\tfor (const typeSlashName of modulesSnapshot.localModuleKeys) {\n\t\tconst module = modulesSnapshot.getModuleWithTypeSlashName(typeSlashName)\n\t\tif (!module) continue\n\n\t\tif (isIgnoredModule(typeSlashName, module, overrides)) continue\n\n\t\tassert(isString(module.files.module), \"Must have a module file name to build a local module import map specifier.\")\n\n\t\timportMap.imports[localModuleImportMapSpecifier(module.localId, module.files.module)] = module.moduleURL\n\t}\n\n\treturn importMap\n}\n\ntype CollectionUtils = Record<string, SafeJS>\n\nfunction createCollectionUtils(tree: CanvasTree, modulesSnapshot: ModulesStoreSnapshot): CollectionUtils {\n\tconst collectionUtils: CollectionUtils = {}\n\n\tconst addCollectionUtil = (collectionUtil: CollectionUtilExport) => {\n\t\t// When updating the implementation, keep in mind `CollectionUtilsCache`\n\t\t// in library rely on the collection utils.\n\t\tcollectionUtils[collectionUtil.collectionId] = js.joinLines(\n\t\t\tjs`async () => (await import(${collectionUtil.moduleURL}))?.[${collectionUtil.exportIdentifier}]`,\n\t\t)\n\t}\n\n\tfor (const node of getWebPageNodes(tree)) {\n\t\tif (node.dataIdentifier) {\n\t\t\tconst collectionUtil = getCollectionUtilForDataIdentifier(modulesSnapshot, node.dataIdentifier)\n\n\t\t\tif (collectionUtil) {\n\t\t\t\taddCollectionUtil(collectionUtil)\n\t\t\t}\n\t\t}\n\n\t\tcollectCollectionUtilsForReferencedCollections(modulesSnapshot, node, addCollectionUtil)\n\t}\n\n\treturn collectionUtils\n}\n\ntype EditorBarBlockedReason = \"feature-flag\"\n\ninterface GenerateHTMLOverrides {\n\tentryScreenNodeId: NodeID\n\timportMapModuleTypeFilter: (type: ModuleType) => boolean\n\tinitialRoute: { routeId: string; localeId?: string; pathVariables?: Record<string, string> }\n\tsearchIndexURL: string\n\tsearchIndexFallbackURL: string\n\t/**\n\t * When true, the generated HTML will not load the Framer on-page editor bar.\n\t * Used for contexts like agent screenshots where the editor bar UI (and its\n\t * sandboxed iframe) must not appear in the rendered page.\n\t */\n\tdisableEditorBar?: boolean\n\t/**\n\t * When true, layout templates are emitted as lazy (Framer.lazy) imports\n\t * instead of eager static imports.\n\t * Used for contexts like agent screenshots where we do not need fast navigations.\n\t */\n\tlazyLayoutTemplates?: boolean\n}\n\ninterface GenerateHTMLResult {\n\thtml: string\n\tserverRoutes: ServerRoute[]\n\tssgRoutes: SSGRoute[]\n\tssgRewrites: SSGRewrite[]\n\tlocales: readonly RouterLocale[]\n\tmetrics: ExportToHTMLMetrics\n\ttreeState: DeploymentTreeState\n\theaderKeys: string[]\n\tsearchIndexUrl: string\n\tlocalizedSegments?: LocalizedSegments\n}\n\nexport async function generateHTML({\n\tcomponentLoader,\n\tmodulesStore,\n\tcodeGenerationStore,\n\tdebugStore,\n\ttreeStore,\n\tpublishStore,\n\tprojectStore,\n\tassetStore,\n\tframerSiteId,\n\toverrides,\n\tscheduler,\n\tpatchedTreeState,\n}: {\n\tcomponentLoader: ComponentLoader\n\tmodulesStore: ModulesStore\n\tcodeGenerationStore: CodeGenerationStore\n\tdebugStore: DebugStore\n\ttreeStore: TreeStore\n\tpublishStore: PublishStore\n\tprojectStore: ProjectStore\n\tassetStore: AssetStore\n\tframerSiteId?: string\n\toverrides?: GenerateHTMLOverrides\n\tscheduler: BaseEngineScheduler\n\tpatchedTreeState?: PatchedDeploymentTreeState\n}): Promise<GenerateHTMLResult> {\n\tconst metrics = new MetricsCollector(defaultExportToHTMLMetrics())\n\n\t// This might need to do a network request, so we kick this off early.\n\tconst getFallbackSearchIndexUrlPromise = metrics.timed(\"getFallbackSearchIndexUrlMs\", () =>\n\t\tgetFallbackSearchIndexUrl(publishStore, projectStore, treeStore),\n\t)\n\n\tconst projectSnapshotForExport = await prepareProjectSnapshotForExport({\n\t\tassetStore,\n\t\tcodeGenerationStore,\n\t\tcomponentLoader,\n\t\tentryScreenNodeIdOverride: overrides?.entryScreenNodeId,\n\t\tlazyLayoutTemplates: overrides?.lazyLayoutTemplates,\n\t\tmetrics,\n\t\tmodulesStore,\n\t\tpatchedTreeState,\n\t\tscheduler,\n\t\ttreeStore,\n\t})\n\n\treturn generateHTMLFromSnapshot({\n\t\tprojectSnapshotForExport,\n\t\tdebugStore,\n\t\tpublishStore,\n\t\tprojectStore,\n\t\tassetStore,\n\t\tframerSiteId,\n\t\toverrides,\n\t\tmetrics,\n\t\tgetFallbackSearchIndexUrlPromise,\n\t})\n}\n\nasync function generateHTMLFromSnapshot({\n\tprojectSnapshotForExport,\n\tdebugStore,\n\tpublishStore,\n\tprojectStore,\n\tassetStore,\n\tframerSiteId,\n\toverrides,\n\tmetrics,\n\tgetFallbackSearchIndexUrlPromise,\n}: {\n\tprojectSnapshotForExport: ProjectSnapshotForExport\n\tdebugStore: DebugStore\n\tpublishStore: PublishStore\n\tprojectStore: ProjectStore\n\tassetStore: AssetStore\n\tframerSiteId?: string\n\toverrides?: GenerateHTMLOverrides\n\tmetrics: MetricsCollector<keyof ExportToHTMLMetrics>\n\tgetFallbackSearchIndexUrlPromise: Promise<string | undefined>\n}): Promise<GenerateHTMLResult> {\n\tconst {\n\t\ttree,\n\t\ttreeState,\n\t\tmodulesSnapshot,\n\t\tcomponentLoaderSnapshot,\n\t\tentryScreenNode,\n\t\tscreenNodesToExport,\n\t\tlayoutTemplateNodesToExport,\n\t\tlayoutTemplate,\n\t\timports,\n\t} = projectSnapshotForExport\n\n\tconst screenModules = screenNodesToExport.map(node => {\n\t\t// TODO Check and handle shallow/fully loaded scope state\n\t\tassert(node, \"Node must be loaded to be exported.\")\n\t\tconst [module, metadataModule] = localModuleIdsForSourceNode(node, tree).map(localId =>\n\t\t\tmodulesSnapshot.getPersistedModuleByLocalId(localId),\n\t\t)\n\n\t\tassert(module, \"Module must exist as it was asserted in the previous loop.\")\n\n\t\treturn {\n\t\t\tmodule,\n\t\t\tmetadataModule,\n\t\t}\n\t})\n\n\tconst context: GenerateRoutesContext = {\n\t\tcomponentLoader: componentLoaderSnapshot,\n\t\ttree,\n\t\tmodulesSnapshot,\n\t\tmetrics,\n\t\tprojectId: projectStore.projectId,\n\t\tcanUseAdvancedHeaders: projectStore.featureFlags?.canUseAdvancedHeaders ?? \"off\",\n\t\tnavigationRoutes: {},\n\t\tserverRoutes: [],\n\t\twebPageSegmentReferencePathByWebPageId: undefined,\n\t\tssgRoutes: [],\n\t\tssgRewrites: [],\n\t\tabTestingVariantIdsByWebPageId: {},\n\t\tpageEffects: {\n\t\t\tglobal: tree.root.globalPageEffect,\n\t\t\troutes: {},\n\t\t},\n\t\tpageEffectsDeclarations: new FileDeclarationCollector(new BindingCollector()),\n\t\tuniqueLayoutTemplates: new Set(),\n\t\theaderKeys: new Set(),\n\t}\n\t// header routes are the first routes, since they should be applied to all types of requests.\n\tcollectHeaderRoutes(tree, context)\n\n\t// proxy routes go before pages, redirects and rewrite routes, as settings should override conflicting routes.\n\t// note: our client-side router is not aware of proxy routes.\n\tcollectProxyRoutes(tree, context)\n\n\t// Redirect routes go before page routes, otherwise redirect for CMS pages\n\t// (/blog/post1 => /blog/post2) would not work (since /blog/:slug page route\n\t// would catch them first).\n\t//\n\t// Note that this creates an edge case: since our client-side router is not\n\t// aware of redirects, you might get conflicting behaviors:\n\t//\n\t// - you have a /help page and a /help => /support redirect\n\t// - you visit /help page directly, and you get redirected by the\n\t//   server-side router\n\t// - you visit any other page first and then click a /help link, and you get\n\t//   the /help page (client-side routing)\n\t// - you refresh the /help page, and you get redirected\n\t//\n\t// But this isn't as bad as redirects for CMS pages not working, and we can\n\t// fix it by teaching the client-side router about redirects.\n\t{\n\t\tconst timer = metrics.time(\"collectRedirectRoutesMs\")\n\t\tcollectRedirectRoutes(tree, context)\n\t\ttimer.done()\n\t}\n\n\t// Match before pages rewrite routes go before page routes, but after redirects.\n\tcollectRewriteRoutes(tree, context, false)\n\n\tif (tree.root.translatePagePaths === \"yes\") {\n\t\tgenerateLocalizedSegments(context)\n\t}\n\n\tconst snippetsModule = debugStore.debuggingOfPublishedSites.disableCustomCode\n\t\t? undefined\n\t\t: modulesSnapshot.getPersistedModuleByLocalId(snippetsModuleIdentifier.localId)\n\n\t// Page routes go last.\n\tfor (const { module, metadataModule } of screenModules) {\n\t\tgenerateRouteForModule(context, module, metadataModule, snippetsModule, overrides)\n\t}\n\n\t// Match after pages rewrite routes go after page routes.\n\tcollectRewriteRoutes(tree, context, true)\n\n\tlet sitesImportMap: ImportMap = getStaticImportMap(\n\t\tdebugStore.debuggingOfPublishedSites.reactBuild,\n\t\tdebugStore.debuggingOfPublishedSites.reactVersionOverride,\n\t\tdebugStore.debuggingOfPublishedSites.schedulerVersionOverride,\n\t)\n\n\t// Start the server with `TAILSCALE_URL` local tunnel in order to serve local dev assets to the screenshot agent\n\tconst tailscaleScreenshotImportMap = getTailscaleScreenshotImportMap()\n\tif (tailscaleScreenshotImportMap) {\n\t\tsitesImportMap = extendImportMap(sitesImportMap, tailscaleScreenshotImportMap, \"source-wins\")\n\t}\n\n\t// Webpages use a local module import map to avoid frequent updates when\n\t// local dependencies change. Fill the import map with all local modules to\n\t// ensure that any import map entry to any local module can be resolved.\n\tsitesImportMap = extendImportMap(sitesImportMap, createLocalModuleImportMap(modulesSnapshot, overrides))\n\n\t// If there is an import map for user added packages (Instant NPM) merge\n\t// it with the default one.\n\tconst userImportMapContent = modulesSnapshot.dependenciesModule?.importMapContent\n\tif (userImportMapContent) {\n\t\tconst userImportMap: ImportMap = JSON.parse(userImportMapContent)\n\t\tif (userImportMap.imports) {\n\t\t\tsitesImportMap = extendImportMap(sitesImportMap, userImportMap)\n\t\t}\n\t}\n\n\tconst customNotFoundPageModuleURL = getCustomNotFoundPageModuleURL(context.ssgRoutes)\n\tlet notFoundPageImportSpecifier: string\n\tif (!customNotFoundPageModuleURL) {\n\t\tnotFoundPageImportSpecifier = defaultNotFoundPageImportSpecifier\n\t\t// The only reason we import the default not found page via the import\n\t\t// map is so that SSG can pick it up and include it in the bundle.\n\t\tsitesImportMap = extendImportMap(sitesImportMap, {\n\t\t\timports: { [notFoundPageImportSpecifier]: defaultNotFoundPageModuleURL },\n\t\t})\n\t} else {\n\t\t// Custom not found page is already part of the site's routes, so it'll\n\t\t// get bundled without us having to add it to the import map.\n\t\tnotFoundPageImportSpecifier = customNotFoundPageModuleURL\n\t}\n\n\tconst showBadge = publishStore.hasBadge()\n\tif (showBadge) {\n\t\t// The only reason we import the badge via the import map is so that SSG\n\t\t// can pick it up and include it in the bundle.\n\t\tsitesImportMap = extendImportMap(sitesImportMap, {\n\t\t\timports: { [badgeImportSpecifier]: badgeModuleURL },\n\t\t})\n\t}\n\n\tconst fontsTimer = metrics.time(\"generateFontsMs\")\n\tconst { fontCSS, fontLinkTags } = await generateFonts(\n\t\tcomponentLoaderSnapshot,\n\t\tmodulesSnapshot,\n\t\tassetStore,\n\t\tscreenNodesToExport,\n\t\tlayoutTemplateNodesToExport,\n\t)\n\tfontsTimer.done()\n\n\tconst webMetadata = tree.root.webMetadata\n\t// WebMetadata stores asset references, which we need to resolve against the\n\t// base module URL into absolute URLs.\n\tconst resolvedFaviconURL = webMetadata?.favicon && resolveModuleImage(webMetadata.favicon)\n\tconst resolvedFaviconDarkURL = webMetadata?.faviconDark && resolveModuleImage(webMetadata.faviconDark)\n\n\tconst resolvedAppleTouchIconURL = webMetadata?.appleTouchIcon && resolveModuleImage(webMetadata.appleTouchIcon)\n\n\tassert(!isVariableReference(webMetadata?.socialImage), \"RootNode social image should never be a variable reference\")\n\tlet resolvedSocialImageURL = webMetadata?.socialImage && resolveModuleImage(webMetadata.socialImage)\n\t// We used to use the home page's social image for the site-wide social\n\t// image, let's keep doing that for backward compatibility.\n\tif (!resolvedSocialImageURL && entryScreenNode.webMetadata && isString(entryScreenNode.webMetadata.socialImage)) {\n\t\tresolvedSocialImageURL = resolveModuleImage(entryScreenNode.webMetadata.socialImage)\n\t}\n\tconst resolvedWebMetadata = {\n\t\t...webMetadata,\n\t\tresolvedFaviconURL,\n\t\tresolvedFaviconDarkURL,\n\t\tresolvedSocialImageURL,\n\t\tresolvedAppleTouchIconURL,\n\t}\n\n\tconst fallbackSearchIndexUrl = await getFallbackSearchIndexUrlPromise\n\tconst { metaTags, searchIndexUrl } = generateMetaTags(\n\t\tresolvedWebMetadata,\n\t\tprojectStore.projectId,\n\t\toverrides?.searchIndexFallbackURL ?? fallbackSearchIndexUrl,\n\t\toverrides?.searchIndexURL,\n\t)\n\n\tlet customCodeNodes: Iterable<CustomCodeNode> = []\n\tconst customCodeScope = CustomCodeScopeNode.get(tree)\n\tif (customCodeScope) {\n\t\tconst loadedScope = await customCodeScope.load()\n\t\tif (loadedScope) {\n\t\t\tcustomCodeNodes = loadedScope.children\n\t\t}\n\t}\n\n\tconst customHTML = generateValidCustomHTML(customCodeNodes, debugStore)\n\n\t// We do not want any draft locales to be included in the exported site\n\tconst locales = getRouterLocales(tree, \"excludeDrafts\")\n\n\tconst collectionUtils = createCollectionUtils(tree, modulesSnapshot)\n\n\t// Configure Library behavior for the site.\n\tconst libraryFeatures: LibraryFeatures = {\n\t\teditorBarDisableFrameAncestorsSecurity: experiments.isOn(\"editorBarDisableFrameAncestorsSecurity\"),\n\t\tmotionDivToDiv: experiments.isOn(\"motionDivToDiv\"),\n\t\tyieldOnTap: experiments.isOn(\"yieldOnTap\"),\n\t\tsynchronousNavigationOnDesktop: experiments.isOn(\"synchronousNavigationOnDesktop\"),\n\t\tonPageMoveTool: experiments.isOn(\"onPageMoveTool\"),\n\t\tonPageLocalizationSupport: experiments.isOn(\"onPageLocalizationSupport\"),\n\t\tautobahnNavigation: experiments.isOn(\"autobahnNavigation\"),\n\t\tdisableCustomCode: debugStore.debuggingOfPublishedSites.disableCustomCode,\n\t}\n\n\t// Enable capture of UTM tags in cookie.\n\t// We have to check the license type, because the metadata setting alone\n\t// does not guarantee the feature eligibility. It could be copied over\n\t// from another project when it was remixed.\n\tconst captureFormsUTMTagsInCookie =\n\t\tBoolean(resolvedWebMetadata.enableFormsUTMTracking) && features.isOn(\"canUseUTMTracking\")\n\n\tlet editorBarBlockedReason: EditorBarBlockedReason | undefined\n\tif (projectStore.featureFlags?.blockEditorBar === \"on\") {\n\t\teditorBarBlockedReason = \"feature-flag\"\n\t}\n\n\tconst disableEditorBar = overrides?.disableEditorBar === true\n\n\tconst templateArgs: CreateFromTemplateArguments = {\n\t\timports,\n\t\ttokenCSS: getExportTokenCSSRules(ColorStyleTokenListNode.getAllTokenNodes(tree)).join(\"\\n\"),\n\t\tfontCSS,\n\t\tfontLinkTags,\n\t\timportMap: JSON.stringify(sitesImportMap),\n\t\tnavigationRoutes: context.navigationRoutes,\n\t\tviewport: await viewportForNode(entryScreenNode),\n\t\tframerSiteId,\n\t\tcustomHTML,\n\t\tmetaTags,\n\t\tlanguage: resolvedWebMetadata.language,\n\t\treducedMotion: resolvedWebMetadata.reducedMotion,\n\t\tshowBadge,\n\t\tnotFoundPageImportSpecifier,\n\t\tlocales,\n\t\tpageEffects: context.pageEffects,\n\t\tpageEffectsDeclarations: context.pageEffectsDeclarations,\n\t\tautomaticLocaleEnabled: resolvedWebMetadata.automaticLocale,\n\t\tcollectionUtils,\n\t\tlibraryFeatures,\n\t\tpreserveQueryParams: resolvedWebMetadata.preserveQueryParams,\n\t\tadaptLayoutToTextDirection: tree.root.adaptLayoutToTextDirection,\n\t\tenableImproveInpDuringHydration: experiments.isOn(\"improveInpDuringHydration\"),\n\t\tcaptureFormsUTMTagsInCookie,\n\t\tenableStepByStepInit: debugStore.debuggingOfPublishedSites.stepByStepInit,\n\t\tlayoutTemplate,\n\t\teditorBarBlockedReason,\n\t\tdisableEditorBar,\n\t\tsiteCanonicalURL: publishStore.canonicalURL.url,\n\t\tinitialRouteOverride: overrides?.initialRoute,\n\t\tsnippetsModuleURL: snippetsModule?.moduleURL,\n\t}\n\n\tconst html = createHTMLFromTemplate(templateArgs)\n\n\tmetrics.count(\"uniqueLayoutTemplates\", context.uniqueLayoutTemplates.size)\n\n\t// Enrich server routes with AB testing variants\n\tfor (const { handler } of context.serverRoutes) {\n\t\tif (handler.type !== \"page\") continue\n\n\t\tif (handler.abTest) {\n\t\t\t// Only attach variantIds if there is a linked A/B test.\n\t\t\t// It is possible that the test is concluded, in which case we might have kept\n\t\t\t// the variants, but we don't want to serve them until the new A/B test is started.\n\t\t\tconst variantIds = context.abTestingVariantIdsByWebPageId[handler.pageId] || emptyArray()\n\t\t\tif (variantIds.length > 0) {\n\t\t\t\thandler.abTest.variantIds = variantIds\n\t\t\t\tmetrics.count(\"abTestCount\")\n\n\t\t\t\t// Add cumulative distributions (PPM) from the funnel\n\t\t\t\tconst distributions = getAbTestCumulativeDistributions(context, handler.pageId, variantIds)\n\t\t\t\tif (distributions) {\n\t\t\t\t\thandler.abTest.distributionsPpm = distributions\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Cannot publish an A/B test without variants.\n\t\t\t\thandler.abTest = undefined\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\thtml,\n\t\tserverRoutes: context.serverRoutes,\n\t\tlocalizedSegments: context.localizedSegments,\n\t\tssgRoutes: context.ssgRoutes,\n\t\tssgRewrites: context.ssgRewrites,\n\t\tlocales,\n\t\tmetrics: metrics.get(),\n\t\ttreeState,\n\t\theaderKeys: [...context.headerKeys].sort(),\n\t\tsearchIndexUrl,\n\t}\n}\n\nconst badgeStyles = `\n\t\t@supports (z-index: calc(infinity)) {\n\t\t\t#__framer-badge-container {\n\t\t\t\t--infinity: infinity;\n\t\t\t}\n\t\t}\n\n\t\t#__framer-badge-container {\n\t\t\tposition: fixed;\n\t\t\tbottom: 0;\n\t\t\tpadding: 20px;\n\t\t\twidth: 100%;\n\t\t\tdisplay: flex;\n\t\t\tjustify-content: flex-end;\n\t\t\tpointer-events: none;\n\t\t\tz-index: calc(var(--infinity, 2147483647));\n\t\t}`\n\ninterface CreateFromTemplateArguments {\n\treadonly imports: SafeJS[]\n\treadonly tokenCSS: string\n\treadonly fontCSS: string\n\treadonly fontLinkTags: string[]\n\treadonly importMap: string\n\treadonly navigationRoutes: NavigationRoutes\n\treadonly viewport: string\n\treadonly framerSiteId?: string\n\treadonly customHTML: CustomHTML\n\treadonly metaTags: string\n\treadonly language?: string\n\treadonly reducedMotion?: boolean\n\treadonly showBadge: boolean\n\treadonly notFoundPageImportSpecifier: string\n\treadonly locales: readonly RouterLocale[]\n\treadonly pageEffects?: TokenisedSitePageEffects\n\treadonly pageEffectsDeclarations: FileDeclarationCollector\n\treadonly automaticLocaleEnabled?: boolean\n\treadonly collectionUtils: CollectionUtils | undefined\n\treadonly libraryFeatures: LibraryFeatures\n\treadonly preserveQueryParams?: boolean\n\treadonly enableImproveInpDuringHydration: boolean\n\treadonly adaptLayoutToTextDirection: boolean\n\treadonly captureFormsUTMTagsInCookie: boolean\n\treadonly enableStepByStepInit: boolean\n\treadonly layoutTemplate?: { binding: SafeJS; declarations: SafeJS; css: string }\n\treadonly editorBarBlockedReason: EditorBarBlockedReason | undefined\n\treadonly disableEditorBar: boolean\n\treadonly siteCanonicalURL?: string\n\treadonly initialRouteOverride?: { routeId: string; localeId?: string; pathVariables?: Record<string, string> }\n\treadonly snippetsModuleURL?: string\n}\n\nfunction wrapWithIIFE(script: string) {\n\treturn `!function(){${script}}()`\n}\n\nfunction createHTMLFromTemplate({\n\timports,\n\ttokenCSS,\n\tfontCSS,\n\tfontLinkTags,\n\timportMap,\n\tnavigationRoutes,\n\tviewport,\n\tframerSiteId,\n\tcustomHTML,\n\tmetaTags,\n\tlanguage,\n\treducedMotion,\n\tshowBadge,\n\tnotFoundPageImportSpecifier,\n\tlocales,\n\tpageEffects,\n\tpageEffectsDeclarations,\n\tcollectionUtils,\n\tlibraryFeatures,\n\tpreserveQueryParams,\n\tadaptLayoutToTextDirection,\n\tenableImproveInpDuringHydration,\n\tcaptureFormsUTMTagsInCookie,\n\tenableStepByStepInit,\n\tlayoutTemplate,\n\teditorBarBlockedReason,\n\tdisableEditorBar,\n\tsiteCanonicalURL,\n\tinitialRouteOverride,\n\tsnippetsModuleURL,\n}: CreateFromTemplateArguments): string {\n\tconst trackingScript = framerSiteId\n\t\t? `<script async src=\"${getServiceMap().events}/script?v=2\" data-fid=\"${framerSiteId}\" data-no-nt></script>`\n\t\t: \"\"\n\n\tconst { headStart, headEnd, bodyStart, bodyEnd } = customHTML\n\n\tconst formatRelativeDateScript = `<script data-relative-date-script=\"global\">${wrapWithIIFE(formatRelativeDateSource)}</script>`\n\n\t/**\n\t * @important When adding scripts here, make sure that the file content itself is wrapped in an IIFE, or wrap it here.\n\t * Otherwise, all variables/functions from scripts will be defined in a global context and might override each other.\n\t */\n\tconst preserveQueryParamsScript = `<script ${preserveQueryParams ? \"data-preserve-internal-params\" : \"\"}>${wrapWithIIFE(rewriteLinksWithQueryParamsSource)}</script>`\n\n\tconst captureFormsUTMTagsInCookieScript = captureFormsUTMTagsInCookie\n\t\t? `<script>${captureFormsUTMTagsInCookieSource}</script>` // the source itself is wrapped in an IIFE, so we don't need to wrap it here\n\t\t: \"\"\n\n\t// Will preload On-Page Editing for returning users, and not the rest of the visitors.\n\tconst onPageEditingPreloadScript =\n\t\tframerSiteId && !disableEditorBar\n\t\t\t? `<script>try{if(localStorage.getItem(\"${FORCE_SHOW_EDITOR_BAR_KEY}\")){const n=document.createElement(\"link\");n.rel = \"modulepreload\";n.href=\"${getEditorBarInitUrl()}\";document.head.appendChild(n)}}catch(e){}</script>`\n\t\t\t: \"\"\n\n\tlet editorBarLoader: string | undefined\n\n\tif (disableEditorBar) {\n\t\teditorBarLoader = \"undefined\"\n\t} else if (editorBarBlockedReason === \"feature-flag\") {\n\t\t// language=JavaScript\n\t\teditorBarLoader = /* js */ `\n\t\t\t(() => {\n\t\t\t\tconsole.log(\"[Framer On-Page Editing] Unavailable because it was disabled by Framer customer support\")\n\t\t\t})()\n\t\t`\n\t} else {\n\t\t// language=JavaScript\n\t\teditorBarLoader = /* js */ `\n\t\t\ttypeof window !== \"undefined\" ? (() => {\n\t\t\t\tif (isBot) {\n\t\t\t\t\tconsole.log(\"[Framer On-Page Editing] Unavailable because navigator is bot\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\treturn Framer.lazy(async () => {\n\t\t\t\t\tconst dependencies = {\n\t\t\t\t\t\t__version: 3,\n\t\t\t\t\t\tframer: {\n\t\t\t\t\t\t\tuseCurrentRoute: Framer.useCurrentRoute,\n\t\t\t\t\t\t\tuseLocaleInfo: Framer.useLocaleInfo,\n\t\t\t\t\t\t\tuseRouter: Framer.useRouter,\n\t\t\t\t\t\t},\n\t\t\t\t\t\treact: {\n\t\t\t\t\t\t\tcreateElement: React.createElement,\n\t\t\t\t\t\t\tFragment: React.Fragment,\n\t\t\t\t\t\t\tmemo: React.memo,\n\t\t\t\t\t\t\tuseCallback: React.useCallback,\n\t\t\t\t\t\t\tuseEffect: React.useEffect,\n\t\t\t\t\t\t\tuseRef: React.useRef,\n\t\t\t\t\t\t\tuseState: React.useState,\n\t\t\t\t\t\t\tuseLayoutEffect: React.useLayoutEffect,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"react-dom\": { createPortal },\n\t\t\t\t\t}\n\n\t\t\t\t\twindow.__framer_editorBarDependencies = dependencies\n\n\t\t\t\t\tconst { createEditorBar } = await import(\"${getEditorBarInitUrl()}\")\n\t\t\t\t\treturn {\n\t\t\t\t\t\tdefault: createEditorBar(),\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})() : undefined\n\t\t`\n\t}\n\n\t// This script fragment must be placed inside `main` as it depends on the `routeId` and `localeId` variables.\n\t// The `collectionItemId` variable logic is heavily based on the one defined in the `library/src/Router.tsx` file\n\t// Has to be called after patchRoutesForABTesting, because it needs A/B testing params\n\tconst analyticsPageviewScript = /* js */ `\nif (typeof window !== \"undefined\") {\n\tvoid (async () => {\n\t\tconst route = routes[routeId]\n\n\t\tconst defaultLocaleId = \"default\"\n\t\tconst framerLocale = locales.find(({ id }) => !localeId ? id === defaultLocaleId : id === localeId).code\n\n\t\tlet collectionItemId = routeData?.collectionItemId ?? null\n\t\tif (collectionItemId === null && route?.collectionId && collectionUtils) {\n\t\t\t  const utils = await collectionUtils[route.collectionId]?.()\n\t\t\t  const [slug] = Object.values(pathVariables)\n\t\t\t  if (utils && typeof slug === \"string\") {\n\t\t\t\t  collectionItemId = (await utils.getRecordIdBySlug(slug, framerLocale || undefined)) ?? null\n\t\t\t  }\n\t\t}\n\n\t\tconst resolvedDateTimeOptions = Intl.DateTimeFormat().resolvedOptions()\n\t\tconst timezone = resolvedDateTimeOptions.timeZone\n\t\tconst locale = resolvedDateTimeOptions.locale\n\n\t\t// wait for the page to be activated before sending the pageview event\n\t\t// https://developer.chrome.com/docs/web-platform/prerender-pages#impact-on-analytics\n\t\tawait new Promise((resolve) => {\n\t\t\tif (document.prerendering) {\n\t\t\t\tdocument.addEventListener(\"prerenderingchange\", resolve, { once: true })\n\t\t\t} else {\n\t\t\t\tresolve()\n\t\t\t}\n\t\t})\n\n\t\twindow.__framer_events.push([\n\t\t\t\"published_site_pageview\",\n\t\t\t{\n\t\t\t\tframerSiteId: framerSiteId ?? null,\n\t\t\t\tversion: 2,\n\t\t\t\troutePath: route?.path || \"/\",\n\t\t\t\tcollectionItemId,\n\t\t\t\tframerLocale: framerLocale || null,\n\t\t\t\twebPageId: route?.abTestingVariantId ?? routeId,\n\t\t\t\tabTestId: route?.abTestId,\n\t\t\t\treferrer: document.referrer || null,\n\t\t\t\turl: window.location.href,\n\t\t\t\thostname: window.location.hostname || null,\n\t\t\t\tpathname: window.location.pathname || null,\n\t\t\t\thash: window.location.hash || null,\n\t\t\t\tsearch: window.location.search || null,\n\t\t\t\ttimezone,\n\t\t\t\tlocale,\n\t\t\t},\n\t\t\t\"eager\"\n\t\t])\n\n\t\t// Yield to avoid blocking the main thread with the user code\n\t\tawait Framer.yieldToMain({ priority: \"background\", ensureContinueBeforeUnload: true, continueAfter: \"paint\" })\n\n\t\tdocument.dispatchEvent(new CustomEvent(\"framer:pageview\", {\n\t\t\tdetail: { framerLocale: framerLocale || null }\n\t\t}))\n\t})()\n}\n`\n\n\tconst loadSnippets = snippetsModuleURL ? `new Framer.LazyValue(() => import(\"${snippetsModuleURL}\"))` : \"undefined\"\n\n\treturn /* html */ `<!doctype html>\n<!-- Made in Framer \u00B7 framer.com \u2728 -->\n<!-- Published ${getFormattedPublishDate()} -->\n<html${language ? ` lang=\"${language}\"` : \"\"}${experiments.isOn(\"redirectLondonTimezone\") && language === \"en\" ? ` data-redirect-timezone=\"1\"` : \"\"}>\n<head>\n\t<meta charset=\"utf-8\">\n\t<script type=\"importmap\" ${importMapDataAttr}>${importMap}</script>\n\t<script async src=\"https://ga.jspm.io/npm:es-module-shims@1.6.3/dist/es-module-shims.js\" crossorigin=\"anonymous\" ${esModuleShimsDataAttr}></script>\n\t${onPageEditingPreloadScript}\n\t${headStart}\n\t<meta name=\"viewport\" content=\"${viewport}\">\n\t<meta name=\"generator\" content=\"Framer ${framerStudioVersion}\">\n\t${metaTags}\n\t<style ${framerCSSMarker}>\n\t\t${globalStylesForExport.trimStart()}\n\t\t${defaultFontSites}\n\t\t${tokenCSS}\n\t\t${showBadge ? badgeStyles : \"\"}\n\t\t${layoutTemplate?.css ?? \"\"}\n\t</style>\n\t<style data-framer-font-css>${fontCSS}</style>\n\t${fontLinkTags.join(\"\\n    \")}\n\t${headEnd}\n</head>\n<body>\n\t${trackingScript}\n\t${bodyStart}\n\t${formatRelativeDateScript}\n\t<div id=\"${mainTagId}\"></div>\n\t${preserveQueryParamsScript}\n\t${captureFormsUTMTagsInCookieScript}\n\t${showBadge ? `<div id=\"__framer-badge-container\">${badgeSSRHTML}</div>` : \"\"}\n\t<script ${framerAppearAnimationScriptKey}=\"${reducedMotion ? \"reduce\" : \"no-preference\"}\"></script>\n\t<script>typeof document<\"u\"&&(window.process={...window.process,env:{...window.process?.env,NODE_ENV:\"production\"}});</script>\n\t<script type=\"module\" async ${bundleDataAttr}=\"${mainBundleName}\">\n\t\t${js.linesFrom(imports)}\n\n\t\tconst routes = ${serializeJS(new SerializableObject(navigationRoutes, SortBehavior.Unsorted))}\n\n\t\tconst locales = ${serializeJS(locales)}\n\t\tconst collectionUtils = ${collectionUtils ? serializeJS(new SerializableObject(collectionUtils)) : js`undefined`}\n\t\tconst framerSiteId = \"${framerSiteId}\"\n\t\t${layoutTemplate?.declarations ?? \"\"}\n\n\t\tconst isBrowser = typeof document !== \"undefined\"\n\t\tconst isBot = isBrowser && /bot|-google|google-|yandex|ia_archiver|crawl|spider/iu.test(navigator.userAgent)\n\n\t\texport async function getPageRoot({ routeId, pathVariables, localeId, collectionItemId }) {\n\t\t\tconst rootPreload = routes[routeId].page.preload()\n\n\t\t\tconst content = React.createElement(\n\t\t\t\tFramer.PageRoot,\n\t\t\t\t{\n\t\t\t\t\tisWebsite: true,\n\t\t\t\t\tenvironment: \"site\",\n\t\t\t\t\trouteId,\n\t\t\t\t\tpathVariables,\n\t\t\t\t\troutes,\n\t\t\t\t\tcollectionUtils,\n\t\t\t\t\tframerSiteId,\n\t\t\t\t\tnotFoundPage: Framer.lazy(() => import(\"${notFoundPageImportSpecifier}\")),\n\t\t\t\t\tisReducedMotion: ${serializeJS(reducedMotion)},\n\t\t\t\t\tlocaleId,\n\t\t\t\t\tlocales,\n\t\t\t\t\tpreserveQueryParams: ${serializeJS(preserveQueryParams)},\n\t\t\t\t\tsiteCanonicalURL: ${serializeJS(siteCanonicalURL)},\n\t\t\t\t\tEditorBar: ${editorBarLoader},\n\t\t\t\t\tadaptLayoutToTextDirection: ${serializeJS(adaptLayoutToTextDirection)},\n\t\t\t\t\t${layoutTemplate ? `LayoutTemplate: ${layoutTemplate.binding},` : \"\"}\n\t\t\t\t\tloadSnippetsModule: ${loadSnippets},\n\t\t\t\t\tinitialCollectionItemId: collectionItemId,\n\t\t\t\t}\n\t\t\t)\n\n\t\t\tconst contentWithFeaturesContext = React.createElement(\n\t\t\t\tFramer.LibraryFeaturesProvider,\n\t\t\t\t{\n\t\t\t\t\tchildren: content,\n\t\t\t\t\tvalue: ${serializeJS(libraryFeatures)}\n\t\t\t\t}\n\t\t\t)\n\n\t\t\tconst contentWithGracefullyDegradingErrorBoundary = React.createElement(Framer.GracefullyDegradingErrorBoundary, {\n\t\t\t\tchildren: contentWithFeaturesContext\n\t\t\t})\n\n\t\t\t${serializeJS(js.joinLines(...pageEffectsDeclarations.list()))}\n\t\t\tconst page = React.createElement(Framer.PageEffectsProvider, {\n\t\t\t\tchildren: contentWithGracefullyDegradingErrorBoundary,\n\t\t\t\tvalue: ${serializeJS(pageEffects)}\n\t\t\t})\n\n\t\t\t// We don't want the initial render to immediately have to suspend.\n\t\t\tawait rootPreload\n\t\t\treturn page\n\t\t}\n\n\t\tif (isBrowser) {\n\t\t\twindow.__framer_importFromPackage = (packageAndFilename, exportIdentifier) => () => {\n\t\t\t\treturn React.createElement(Framer.ErrorPlaceholder, { error: 'Package component not supported: \"' + exportIdentifier + '\" in \"' + packageAndFilename + '\"' })\n\t\t\t}\n\n\t\t\t${experiments.isOn(\"cmsDatabase\") ? \"window.__framer_executeServerDatabaseQuery = Framer.executeServerDatabaseQuery\" : \"\"}\n\t\t\twindow.__framer_events = window.__framer_events || []\n\n\t\t\t// Initialize lazy modules cache for hydration\n\t\t\tFramer.initLazyModulesCache()\n\n\t\t\t// Fallback support for stack gaps\n\t\t\tFramer.installFlexboxGapWorkaroundIfNeeded()\n\n\t\t\tconst container = document.getElementById(\"main\")\n\t\t\t// We know that #main is parsed before this script, so we don't need to wait for DOMContentLoaded or similar events.\n\t\t\tif (\"${hydrateV2DatasetKey}\" in container.dataset) main(true, container)\n\t\t\telse main(false, container)\n\t\t}\n\n\t\tfunction track() {\n\t\t\tif (!isBrowser) return\n\t\t\twindow.__framer_events.push(arguments)\n\t\t}\n\n\t\tasync function main(shouldHydrate, container) {\n\t\t\tfunction handleError(error, errorInfo, recoverable = true) {\n\t\t\t\tif (error.caught || window.__framer_hadFatalError) return // we already logged it\n\n\t\t\t\tconst componentStack = errorInfo?.componentStack\n\t\t\t\tif (recoverable) {\n\t\t\t\t\tconsole.warn(\"Caught a recoverable error. The site is still functional, but might have some UI flickering or degraded page load performance. If you are the author of this website, update external components and check recently added custom code or code overrides to fix the following server/client mismatches:\\\\n\", error, componentStack)\n\t\t\t\t\t// we only want to collect 1%, because this can be quite noisy (floods the data pipeline)\n\t\t\t\t\tif (Math.random() > 0.01) return\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\"Caught a fatal error. Please report the following to the Framer team via https://www.framer.com/contact/:\\\\n\", error, componentStack)\n\t\t\t\t}\n\t\t\t\ttrack(recoverable ? \"published_site_load_recoverable_error\" : \"published_site_load_error\", {\n\t\t\t\t\tmessage: String(error),\n\t\t\t\t\tcomponentStack, // componentStack is more useful\n\t\t\t\t\tstack: componentStack ? undefined : error instanceof Error && typeof error.stack === \"string\" ? error.stack : null,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tlet routeId, localeId, pathVariables, breakpoints, routeData\n\t\t\t\tif (shouldHydrate) {\n\t\t\t\t\trouteData = JSON.parse(container.dataset[\"${hydrateV2DatasetKey}\"])\n\t\t\t\t\trouteId = routeData.routeId\n\t\t\t\t\tlocaleId = routeData.localeId\n\t\t\t\t\tpathVariables = routeData.pathVariables\n\t\t\t\t\tbreakpoints = routeData.breakpoints\n\n\t\t\t\t\trouteId = Framer.patchRoutesForABTesting(routes, routeId) // Prioritize optimized route id to avoid flickering in browsers not supporting the server-timing header (Safari older than 16.4)\n\t\t\t\t} else {\n\t\t\t\t\tFramer.patchRoutesForABTesting(routes, undefined) // This must happen before inferInitialRouteFromPath\n\n\t\t\t\t\t${\n\t\t\t\t\t\tinitialRouteOverride\n\t\t\t\t\t\t\t? /* JS */ `\n\t\t\t\t\tconst initialOverride = ${serializeJS(initialRouteOverride)}\n\t\t\t\t\trouteId = initialOverride.routeId\n\t\t\t\t\tlocaleId = initialOverride.localeId\n\t\t\t\t\tpathVariables = initialOverride.pathVariables\n\t\t\t\t\t`\n\t\t\t\t\t\t\t: /* JS */ `\n\t\t\t\t\tconst serverRouteExperimentEnabled = ${experiments.isOn(\"serverTimingRoute\")}\n\t\t\t\t\tconst serverRoute = serverRouteExperimentEnabled && performance.getEntriesByType(\"navigation\")[0]?.serverTiming?.find(e => e.name === \"route\")?.description\n\t\t\t\t\tif (serverRoute) {\n\t\t\t\t\t\tconst routeData = new URLSearchParams(serverRoute)\n\t\t\t\t\t\trouteId = routeData.get(\"id\")\n\t\t\t\t\t\tlocaleId = routeData.get(\"locale\")\n\t\t\t\t\t\tfor (const [key, value] of routeData.entries()) {\n\t\t\t\t\t\t\tif (!key.startsWith(\"var.\")) continue\n\t\t\t\t\t\t\tpathVariables ??= {}\n\t\t\t\t\t\t\tpathVariables[key.slice(4)] = value\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (!routeId || !localeId) {\n\t\t\t\t\t\tconst routeData = Framer.inferInitialRouteFromPath(routes, decodeURIComponent(location.pathname), true, locales)\n\t\t\t\t\t\trouteId = routeData.routeId\n\t\t\t\t\t\tlocaleId = routeData.localeId\n\t\t\t\t\t\tpathVariables = routeData.pathVariables\n\t\t\t\t\t}\n\t\t\t\t\t`\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst pagePromise = getPageRoot({\n\t\t\t\t\trouteId,\n\t\t\t\t\tlocaleId,\n\t\t\t\t\tpathVariables,\n\t\t\t\t\tcollectionItemId: routeData?.collectionItemId,\n\t\t\t\t})\n\n\t\t\t\t${analyticsPageviewScript}\n\n\t\t\t\tconst page = await pagePromise\n\t\t\t\tif (shouldHydrate) {\n\t\t\t\t\t${enableStepByStepInit ? `await waitForApproval(\"rewriting breakpoints\")` : \"\"}\n\n\t\t\t\t\tFramer.withPerformanceMarks(\"framer-rewrite-breakpoints\", () => {\n\t\t\t\t\t\tFramer.removeHiddenBreakpointLayersV2(breakpoints)\n\t\t\t\t\t\twindow.__framer_onRewriteBreakpoints?.(breakpoints)\n\t\t\t\t\t})\n\n\t\t\t\t\t${enableStepByStepInit ? `const hydrationSettings = await waitForApproval(\"hydration\", [\"disableConcurrency\"])` : \"\"}\n\n\t\t\t\t\tconst startTransition = ${enableStepByStepInit ? `hydrationSettings.disableConcurrency ? cb => cb() : React.startTransition` : `isBot ? cb => cb() : React.startTransition`}\n\t\t\t\t\tstartTransition(() => {\n\t\t\t\t\t\tFramer.markHydrationStart()\n\t\t\t\t\t\tif (${serializeJS(enableImproveInpDuringHydration)}) Framer.turnOffReactEventHandling()\n\t\t\t\t\t\tReactDOM.hydrateRoot(container, page, { onRecoverableError: handleError })\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\t${enableStepByStepInit ? `await waitForApproval(\"initial render\")` : \"\"}\n\t\t\t\t\tReactDOM.createRoot(container, { onRecoverableError: handleError }).render(page)\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\thandleError(error, undefined, false)\n\t\t\t\tthrow error\n\t\t\t}\n\t\t}\n\n\t\t${\n\t\t\tenableStepByStepInit\n\t\t\t\t? /* JS */ `\n\t\tfunction waitForApproval(stepName, supportedFlags) {\n\t\t\treturn new Promise((resolve) => {\n\t\t\t\tlet message = \"! [Step-by-step init] Please call proceed() to continue to the next step: \" + stepName\n\t\t\t\tif (supportedFlags) message += \". You can also pass the following settings for the next step: proceed({ \" + supportedFlags.map(flag => flag + \": ...\").join(\", \") + \" })\"\n\t\t\t\tconsole.log(message)\n\t\t\t\twindow.proceed = (options = {}) => {\n\t\t\t\t\tconsole.log(\"[Step-by-step init] Proceeding to the next step: \" + stepName)\n\t\t\t\t\tresolve(options)\n\t\t\t\t\twindow.proceed = null\n\t\t\t\t}\n\t\t\t})\n\t\t}`\n\t\t\t\t: \"\"\n\t\t}\n\n\t\t${\n\t\t\t// Always make sure this is called *before* the call to `hydrateRoot`, see: https://framer-team.slack.com/archives/C051TFHTQGM/p1724427123461469\n\t\t\tshowBadge\n\t\t\t\t? /* JS */ `\n\t\t;(function () {\n\t\t\tif (!isBrowser) return\n\n\t\t\tReact.startTransition(() => {\n\t\t\t\tReactDOM.hydrateRoot(\n\t\t\t\t\tdocument.getElementById(\"__framer-badge-container\"),\n\t\t\t\t\tReact.createElement(React.Suspense, {}, React.createElement(React.lazy(() => import(\"${badgeImportSpecifier}\"))))\n\t\t\t\t)\n\t\t\t})\n\t\t})()`\n\t\t\t\t: \"\"\n\t\t}\n\t</script>\n\t${bodyEnd}\n</body>\n</html>\n`\n}\n\ntype ResolvedWebMetadata = Omit<WebMetadata, \"favicon\" | \"faviconDark\" | \"socialImage\" | \"appleTouchIcon\"> & {\n\tresolvedFaviconURL?: string\n\tresolvedFaviconDarkURL?: string\n\tresolvedSocialImageURL?: string\n\tresolvedAppleTouchIconURL?: string\n}\n\nfunction generateGoogleAnalyticsScript(trackingId: string): string {\n\treturn `\n\t<!-- Global site tag (gtag.js) - Google Analytics -->\n\t<script async src=\"https://www.googletagmanager.com/gtag/js?id=${trackingId}\"></script>\n\t<script>\n\t  window.dataLayer = window.dataLayer || [];\n\t  function gtag(){window.dataLayer.push(arguments);}\n\t  gtag('js', new Date());\n\t  gtag('config', '${trackingId}');\n\t</script>`\n}\n\nexport const darkFaviconDefault = \"https://framerusercontent.com/sites/icons/default-favicon-dark.v1.png\"\nexport const lightFaviconDefault = \"https://framerusercontent.com/sites/icons/default-favicon-light.v1.png\"\nexport const appleTouchIconDefault = \"https://framerusercontent.com/sites/icons/default-touch-icon.v3.png\"\n\nfunction generateMetaTags(\n\tmetadata: ResolvedWebMetadata,\n\tprojectId: string,\n\tfallbackSearchIndexUrl: string | undefined,\n\tsearchIndexURLOverride: string | undefined,\n) {\n\tconst {\n\t\ttitle,\n\t\tdescription,\n\t\tgoogleAnalyticsTrackingId,\n\t\tresolvedFaviconURL,\n\t\tresolvedFaviconDarkURL,\n\t\tresolvedSocialImageURL,\n\t\tresolvedAppleTouchIconURL,\n\t\toptOutOfHTMLPlugin,\n\t} = metadata\n\tconst escapedTitle = isString(title) ? escapeHTML(title) : \"\"\n\tconst escapedDescription = isString(description) ? escapeHTML(description) : \"\"\n\n\tconst titleTag = `<title>${escapedTitle}</title>`\n\tconst descriptionTag = `<meta name=\"description\" content=\"${escapedDescription}\" />`\n\n\t// This tag is used by the Search component on sites to access the search-index we generate during SSG.\n\t//\n\t// We generate the path during publish rather than during SSG so that unoptimized pages can also access the index\n\t// as soon as it's available.\n\tconst searchIndexUrl = searchIndexURLOverride ?? generateSearchIndexUrl(projectId)\n\tconst searchIndexTags = [`<meta name=\"${searchIndexMetaName}\" content=\"${searchIndexUrl}\">`]\n\tif (fallbackSearchIndexUrl) {\n\t\tsearchIndexTags.push(`<meta name=\"${searchIndexFallbackMetaName}\" content=\"${fallbackSearchIndexUrl}\">`)\n\t}\n\n\tconst htmlPluginTag = optOutOfHTMLPlugin ? `<meta name=\"framer-html-plugin\" content=\"disable\">` : \"\"\n\n\tconst metaImagesTags: string[] = []\n\tconst faviconLightLinkTag = `<link href=\"${resolvedFaviconURL ?? resolvedFaviconDarkURL ?? lightFaviconDefault}\" rel=\"icon\" media=\"(prefers-color-scheme: light)\">`\n\tconst faviconDarkLinkTag = `<link href=\"${resolvedFaviconDarkURL ?? resolvedFaviconURL ?? darkFaviconDefault}\" rel=\"icon\" media=\"(prefers-color-scheme: dark)\">`\n\tmetaImagesTags.push(faviconLightLinkTag)\n\tmetaImagesTags.push(faviconDarkLinkTag)\n\n\t// We don't want to add the apple touch icon if the favicon is present\n\t// because for any existing sites, the favicon will be used instead. For\n\t// new sites that don't have a favicon, we want to use the apple touch\n\t// icon.\n\tconst hasFavicon = isString(resolvedFaviconURL) || isString(resolvedFaviconDarkURL)\n\tconst touchIconFallbackURL = hasFavicon ? undefined : appleTouchIconDefault\n\tconst touchIconURL = resolvedAppleTouchIconURL ?? touchIconFallbackURL\n\tif (touchIconURL) metaImagesTags.push(`<link rel=\"apple-touch-icon\" href=\"${touchIconURL}\"/>`)\n\n\tconst tags = [\n\t\ttitleTag,\n\t\tdescriptionTag,\n\t\t...searchIndexTags,\n\t\thtmlPluginTag,\n\t\t...metaImagesTags,\n\t\t`<!-- Open Graph / Facebook -->`,\n\t\t`<meta property=\"og:type\" content=\"website\">`,\n\t\t`<meta property=\"og:title\" content=\"${escapedTitle}\">`,\n\t\t`<meta property=\"og:description\" content=\"${escapedDescription}\">`,\n\t\tresolvedSocialImageURL && `<meta property=\"og:image\" content=\"${resolvedSocialImageURL}\">`,\n\t\t`<!-- Twitter -->`,\n\t\t`<meta name=\"twitter:card\" content=\"summary_large_image\">`,\n\t\t`<meta name=\"twitter:title\" content=\"${escapedTitle}\">`,\n\t\t`<meta name=\"twitter:description\" content=\"${escapedDescription}\">`,\n\t\tresolvedSocialImageURL && `<meta name=\"twitter:image\" content=\"${resolvedSocialImageURL}\">`,\n\t\tgoogleAnalyticsTrackingId && generateGoogleAnalyticsScript(googleAnalyticsTrackingId),\n\t]\n\treturn { metaTags: join(tags, \"\\n    \"), searchIndexUrl }\n}\n\nfunction generateSearchIndexUrl(projectId: string): string {\n\tconst serviceMap = getServiceMap()\n\tconst bundleId = getBundleId(projectId)\n\tconst hash = randomBase62(12)\n\tconst filename = `searchIndex-${hash}.json`\n\treturn `${serviceMap.userContent}/sites/${bundleId}/${filename}`\n}\n\nconst deploymentsListLimit = 10\n\nasync function getFallbackSearchIndexUrl(\n\tpublishStore: PublishStore,\n\tprojectStore: ProjectStore,\n\ttreeStore: TreeStore,\n): Promise<string | undefined> {\n\tconst lastDeployment = treeStore.isOnMainBranch()\n\t\t? publishStore.defaultHostnameDeployment\n\t\t: publishStore.branchHostnameDeployment\n\tif (lastDeployment?.searchIndexStatus === SearchIndexStatus.Ready && lastDeployment.searchIndexUrl) {\n\t\treturn lastDeployment.searchIndexUrl\n\t}\n\n\tconst pastDeployments = await listVersionDeployments(\n\t\tprojectStore.projectId,\n\t\tdeploymentsListLimit,\n\t\tundefined,\n\t\ttreeStore.branchId,\n\t)\n\tfor (const deployment of pastDeployments.deployments) {\n\t\tif (deployment.searchIndexStatus === SearchIndexStatus.Ready && deployment.searchIndexUrl) {\n\t\t\treturn deployment.searchIndexUrl\n\t\t}\n\t}\n}\n\nfunction resolveModuleImage(assetReference: string | undefined): string | undefined {\n\tif (!assetReference) return undefined\n\tconst parsedAssetReference = parseAssetReference(assetReference)\n\tif (!parsedAssetReference) return undefined\n\treturn createAbsoluteImageAssetURL(parsedAssetReference.identifier)\n}\n\n/**\n * IMPORTANT: The comment that is added at the end of each code snippet will be the string that\n * gets replaced with page specific custom code when server side generating.\n * If you are updating it please ensure that the metadata modules are still being code generated correctly similar to this code.\n */\nfunction generateValidCustomHTML(\n\tcustomCodeNodes: Iterable<CustomCodeNode> | undefined,\n\tdebugStore: DebugStore,\n): CustomHTML {\n\tif (debugStore.debuggingOfPublishedSites.disableCustomCode) {\n\t\treturn {\n\t\t\theadStart: `${startOfHeadStartMarker}${endOfHeadStartMarker}`,\n\t\t\theadEnd: `${startOfHeadEndMarker}${endOfHeadEndMarker}`,\n\t\t\tbodyStart: `${startOfBodyStartMarker}${endOfBodyStartMarker}`,\n\t\t\tbodyEnd: `${startOfBodyEndMarker}${endOfBodyEndMarker}`,\n\t\t}\n\t}\n\n\tconst allCustomHTML = getAllParsedCustomHTML(customCodeNodes)\n\n\treturn {\n\t\theadStart: `${startOfHeadStartMarker}\\n    ${allCustomHTML.headStart}\\n    ${endOfHeadStartMarker}`,\n\t\theadEnd: `${startOfHeadEndMarker}\\n    ${allCustomHTML.headEnd}\\n    ${endOfHeadEndMarker}`,\n\t\tbodyStart: `${startOfBodyStartMarker}\\n    ${allCustomHTML.bodyStart}\\n    ${endOfBodyStartMarker}`,\n\t\tbodyEnd: `${startOfBodyEndMarker}\\n    ${allCustomHTML.bodyEnd}\\n    ${endOfBodyEndMarker}`,\n\t}\n}\n\n// Specifier should not be changed without also updating SSG!\nconst defaultNotFoundPageImportSpecifier = \"__framer-not-found-page\"\n\n// Source:\n// https://framer.com/projects/Sites-404-Page--bbF6EOvwW2XyMSfcme4r-aFUrm?view=code:codeFile/Y7MOIQ_\nconst defaultNotFoundPageModuleURL = \"https://framer.com/m/framer/SitesNotFoundPage.js@1.4.0\"\n\n/** Returns a module URL of the custom 404 page, if the project has one. */\nfunction getCustomNotFoundPageModuleURL(routes: SSGRoute[]): string | undefined {\n\tconst customNotFoundRoute = routes.find(({ path }) => path && customNotFoundPagePaths.has(path))\n\treturn customNotFoundRoute?.moduleUrl\n}\n\ninterface RouteValues {\n\trouteId: string\n\tnavigation: NavigationRoute\n\t// Only web pages generate Server and SSG routes.\n\tserver?: ServerRoute\n\tssg?: SSGRoute\n}\n\nfunction getDefaultRouteValues(module: PersistedModule): RouteValues {\n\treturn {\n\t\trouteId: module.name,\n\t\tnavigation: {\n\t\t\t// Create a reference to a lazily-imported React component.\n\t\t\t//\n\t\t\t// With a little help from our Router, and with proper\n\t\t\t// RoutesProvider setup, this will allow any component to\n\t\t\t// render/navigate to a screen without directly importing it:\n\t\t\t//\n\t\t\t//     const { getRoute } = useRouter()\n\t\t\t//     const { page } = getRoute(targetId)\n\t\t\t//\n\t\t\t// These lazy references can be prefetched after the component that\n\t\t\t// links to these targets mounts, ensuring that users don't have to\n\t\t\t// wait while the next screen's source is fetched.\n\t\t\tpage: js`Framer.lazy(() => import(${module.moduleURL}))`,\n\t\t},\n\t}\n}\n\nfunction generateRouteForModule(\n\tcontext: GenerateRoutesContext,\n\tmodule: PersistedModule,\n\tmetadataModule: PersistedModule | undefined,\n\tsnippetsModule: PersistedModule | undefined,\n\toverrides?: GenerateHTMLOverrides,\n) {\n\tconst node = context.tree.get(module.name)\n\n\tlet route: RouteValues\n\tif (isWebPageNode(node)) {\n\t\t// TODO Check and handle shallow/fully loaded scope state\n\t\tif (!node.isLoaded()) return\n\t\t// We don't publish draft web pages.\n\t\tif (node.isDraft) {\n\t\t\treturn\n\t\t}\n\n\t\tif (node.abTestingParentId) {\n\t\t\t// A/B testing variant page should not be published if the control page is a draft,\n\t\t\t// or it doesn't exist (the latter should be impossible, but we check for it anyway)\n\t\t\tconst controlPage = context.tree.get(node.abTestingParentId)\n\t\t\tif (!isWebPageNode(controlPage) || controlPage.isDraft) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// It should also not be published if there is no started A/B testing funnel\n\t\t\tconst analyticsScopeNode = AnalyticsScopeNode.get(context.tree)?.loaded\n\t\t\tif (node.getAbTestingFunnel(analyticsScopeNode)?.status !== FunnelStatus.Started) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tcontext.metrics.count(\"pageNodeCount\")\n\t\tif (hasLayoutTemplate(node)) {\n\t\t\tcontext.uniqueLayoutTemplates.add(node.layoutTemplateIdentifier)\n\t\t\tcontext.metrics.count(\"pageNodeWithLayoutTemplate\")\n\t\t}\n\n\t\tassert(metadataModule, \"Web page must have a metadata module\")\n\n\t\troute = generateRouteForWebPageNode(context, module, metadataModule, snippetsModule, node, overrides?.initialRoute)\n\t\tcontext.navigationRoutes[route.routeId] = route.navigation\n\n\t\tcollectPageEffectsForPublish(context.pageEffects, node, context.pageEffectsDeclarations)\n\t} else {\n\t\troute = getDefaultRouteValues(module)\n\t\tcontext.navigationRoutes[route.routeId] = route.navigation\n\t}\n\n\tif (route.server) {\n\t\tcontext.serverRoutes.push(route.server)\n\t}\n\tif (route.ssg) {\n\t\tcontext.ssgRoutes.push(route.ssg)\n\t}\n}\n\nfunction generateRouteForWebPageNode(\n\tcontext: GenerateRoutesContext,\n\tmodule: PersistedModule,\n\tmetadataModule: PersistedModule,\n\tsnippetsModule: PersistedModule | undefined,\n\tnode: WebPageNode,\n\tinitialRouteOverride?: { routeId: string; localeId?: string; pathVariables?: Record<string, string> },\n): RouteValues {\n\tconst route = getDefaultRouteValues(module)\n\tconst path = getRawWebPagePath(context.tree, node)\n\t// When creating an export for screenshots, we don't want the hash of the HTML to change when\n\t// the save ids of unrelated routes change.\n\tif (initialRouteOverride && route.routeId !== initialRouteOverride.routeId) {\n\t\troute.navigation.page = js`Framer.lazy(() => {})`\n\t}\n\n\troute.navigation.path = path\n\n\tconst pathLocalized =\n\t\tcontext.tree.root.translatePagePaths === \"yes\" ? getRawWebPagePathLocalized(context.tree, node) : undefined\n\tif (pathLocalized) {\n\t\troute.navigation.pathLocalized = pathLocalized\n\t}\n\n\troute.navigation.elements = getWebPageScrollTargets(node)\n\troute.navigation.includedLocales = getIncludedLocales(context.tree, node)\n\n\t// Used while patching the routes for abTesting\n\troute.navigation.abTestingParentId = node.abTestingParentId\n\n\t// We store the collectionId on the Route object so that we can use it to\n\t// Resolve hash slugs that link to a collection item in a list\n\tconst collectionUtil = getCollectionUtilForNode(context.modulesSnapshot, node)\n\tif (collectionUtil) {\n\t\troute.navigation.collectionId = collectionUtil.collectionId\n\t}\n\n\tif (node.dataIdentifier) {\n\t\tconst dataDefinition = context.componentLoader.dataForIdentifier(node.dataIdentifier)\n\t\tconst itemToSlug = dataDefinition?.itemToSlug ?? {}\n\t\tconst pageCount = Object.keys(itemToSlug).length\n\t\tcontext.metrics.count(\"pageCount\", pageCount)\n\t} else {\n\t\tcontext.metrics.count(\"pageCount\")\n\t}\n\n\tif (path) {\n\t\tconst includedLocales = getIncludedLocales(context.tree, node)\n\t\tif (node.abTestingParentId) {\n\t\t\t// Build a mapping from  control page ID to page IDs of A/B testing variants\n\t\t\tconst variants =\n\t\t\t\tcontext.abTestingVariantIdsByWebPageId[node.abTestingParentId] ||\n\t\t\t\t(context.abTestingVariantIdsByWebPageId[node.abTestingParentId] = [])\n\t\t\tvariants.push(route.routeId)\n\t\t} else {\n\t\t\t// Only the control page should get its own server route. Its\n\t\t\t// `route.server.handler.variantIds` is later set to the ids of A/B testing\n\t\t\t// variant web pages using the above mapping\n\t\t\t// Only the started A/B testing funnels are published\n\t\t\tconst analyticsScopeNode = AnalyticsScopeNode.get(context.tree)?.loaded\n\t\t\tconst abTestingFunnel = node.getAbTestingFunnel(analyticsScopeNode)\n\t\t\tconst abTestId = abTestingFunnel?.status === FunnelStatus.Started ? abTestingFunnel.id : undefined\n\n\t\t\tlet abTest: ServerAbTest | undefined\n\t\t\tif (abTestId) {\n\t\t\t\tconst samplePathVariables = hasCollectionDataSource(node)\n\t\t\t\t\t? getSamplePathVariablesForCMSPage(context.tree, node)\n\t\t\t\t\t: undefined\n\t\t\t\tabTest = {\n\t\t\t\t\tid: abTestId,\n\t\t\t\t\tvariantIds: [], // will be filled later\n\t\t\t\t\tsamplePathVariables,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\troute.server = {\n\t\t\t\tpath,\n\t\t\t\tincludedLocales,\n\t\t\t\thandler: {\n\t\t\t\t\ttype: \"page\",\n\t\t\t\t\tabTest,\n\t\t\t\t\tpageId: route.routeId,\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tif (context.tree.root.translatePagePaths === \"yes\") {\n\t\t\t\tassert(\n\t\t\t\t\tcontext.webPageSegmentReferencePathByWebPageId,\n\t\t\t\t\t\"webPageSegmentReferencePathByWebPageId must be generated when creating the localized segments\",\n\t\t\t\t)\n\n\t\t\t\tconst webPageSegmentReferencePath = context.webPageSegmentReferencePathByWebPageId.get(node.id)\n\t\t\t\tif (webPageSegmentReferencePath) {\n\t\t\t\t\troute.server.path = webPageSegmentReferencePath\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\troute.ssg = {\n\t\t\trouteId: route.routeId,\n\t\t\tabTestingParentId: route.navigation.abTestingParentId,\n\t\t\tpath,\n\t\t\tpathLocalized,\n\t\t\tincludedLocales,\n\t\t\tmoduleUrl: module.moduleURL,\n\t\t\tmetadataUrl: metadataModule.moduleURL,\n\t\t\tsnippetsUrl: snippetsModule?.moduleURL,\n\t\t\tdataUrl: getDataModuleURL(node, context.modulesSnapshot),\n\t\t}\n\t}\n\n\treturn route\n}\n\nfunction getDataModuleURL(\n\tnode: CanvasNode & WithCollectionDataSource,\n\tmodulesSnapshot: ModulesStoreSnapshot,\n): string | undefined {\n\tif (!node.dataIdentifier) return\n\n\tconst parsedDataIdentifier = parseModuleIdentifier(node.dataIdentifier)\n\n\tif (parsedDataIdentifier.kind === \"externalModuleExport\") return parsedDataIdentifier.importSpecifier\n\n\tassert(parsedDataIdentifier.kind === \"localModuleExport\")\n\n\tconst dataModule = modulesSnapshot.getPersistedModuleByLocalId(parsedDataIdentifier.localId)\n\tif (!dataModule) throw new Error(`Missing data module ${node.dataIdentifier} for screen ${node.id}`)\n\treturn dataModule.moduleURL\n}\n\nfunction getEditorBarInitUrl() {\n\tconst serviceMap = getServiceMap()\n\tconst releaseChannel = getEditorBarReleaseChannel()\n\n\tconst pathPrefix = releaseChannel === \"stable\" ? \"\" : `/${releaseChannel}`\n\tconst url = new URL(`/edit${pathPrefix}/init.mjs`, serviceMap.app)\n\n\tconst tunnelId = getTunnelId()\n\tif (tunnelId) {\n\t\turl.searchParams.set(\"tunnel\", tunnelId)\n\t}\n\n\treturn url.href\n}\n\nfunction getEditorBarReleaseChannel() {\n\tconst release = getFramerRelease(window)\n\treturn release?.channel ?? \"stable\"\n}\n\nfunction generateLocalizedSegments(context: GenerateRoutesContext) {\n\tconst { localizedSegments, webPageSegmentReferencePathByWebPageId } = getRouteSegmentRootNode(\n\t\tcontext.tree,\n\t).getWebPageIdToSegmentReferencePath(context.tree)\n\n\tcontext.localizedSegments = localizedSegments\n\tcontext.webPageSegmentReferencePathByWebPageId = webPageSegmentReferencePathByWebPageId\n}\n\nfunction getFormattedPublishDate(): string {\n\treturn (\n\t\tnew Intl.DateTimeFormat(\"en-US\", { dateStyle: \"medium\", timeStyle: \"short\", timeZone: \"UTC\" }).format(new Date()) +\n\t\t\" UTC\"\n\t)\n}\n", "import type { ExperimentName } from \"@framerjs/app-config\"\nimport type {\n\tDeployment,\n\tEnrichedHostnameWithDeployment,\n\tHostname,\n\tServerDeployment,\n\tVersionDeployment,\n} from \"@framerjs/app-shared\"\nimport {\n\tApiError,\n\tDeploymentStatus,\n\tDeploymentStrategy,\n\tHostnameStatus,\n\tHostnameType,\n\tHostnameVariant,\n\tmapDeployment,\n\topenNewTab,\n} from \"@framerjs/app-shared\"\nimport type {\n\tBranchHostname,\n\tBranchHostnameWithDeployment,\n\tCustomHostname,\n\tDefaultHostname,\n\tDeploymentTreeState,\n\tPatchedDeploymentTreeState,\n\tProtectedStagingValue,\n} from \"@framerjs/app-shared/src/Deployments.ts\"\nimport { MAIN_BRANCH_ID } from \"@framerjs/crdtree2\"\nimport type { ComponentLoader, DataDefinition } from \"@framerjs/framer-runtime\"\nimport { isErrorDefinition } from \"@framerjs/framer-runtime\"\nimport type { ToastAction } from \"@framerjs/fresco\"\nimport type {\n\tExternalModuleExportIdentifier,\n\tExternalModuleExportIdentifierString,\n\tLocalModuleExportIdentifierString,\n\tModuleExportIdentifierString,\n\tModuleIdentifier,\n} from \"@framerjs/shared\"\nimport {\n\tassert,\n\tModuleType,\n\tReportTag,\n\tResolvablePromise,\n\tassertNever,\n\tgetLogger,\n\thostInfo,\n\tisEmptyObject,\n\tisExternalModuleIdentifier,\n\tisLocalModuleIdentifier,\n\tisModuleExportIdentifier,\n\tisModuleIdentifier,\n\tparseModuleIdentifier,\n\tunhandledError,\n} from \"@framerjs/shared\"\nimport { DebugFlag, type SSGRoute, serializeEditorInput } from \"@framerjs/shared/src/ssg/editor.ts\"\nimport type { Rewrite } from \"@framerjs/shared/src/ssg/rewrite.ts\"\nimport * as Sentry from \"@sentry/browser\"\nimport type { Config } from \"app/FeatureSet.tsx\"\nimport { Dictionary } from \"app/dictionary.ts\"\nimport { experiments } from \"app/experiments.ts\"\nimport { MetricsInteractionViews } from \"app/metrics.ts\"\nimport { listHostnames } from \"document/base-engine/BaseHostnameStore.ts\"\nimport { fetchTopField } from \"document/components/chrome/analytics/utils/fetchUtils.ts\"\nimport { getDayRelativeToToday } from \"document/components/chrome/analytics/utils/getDayRelativeToToday.ts\"\nimport { getRelatedModulesForFitImage } from \"document/components/chrome/properties/utils/regenerateModulesForFitImage.ts\"\nimport { getWebPageModulesToRegenerate } from \"document/components/chrome/properties/utils/regenerateModulesForLayoutTemplateFlowEffect.ts\"\nimport { getPublishBlockingUpsell } from \"document/components/chrome/shared/UpsellModal/getUpsell.tsx\"\nimport {\n\ttoastCustomDomainRemoved,\n\ttoastDomainAdded,\n\ttoastDomainConnected,\n\ttoastFreeDomainConnected,\n\ttoastFreeDomainRemoved,\n\ttoastRemoveDomainError,\n} from \"document/components/chrome/siteSettings/Domains/CustomDomain/customDomainToasts.ts\"\nimport { StatusIndicatorEnum, deriveIndicatorStatus } from \"document/components/chrome/siteSettings/StatusIndicator.tsx\"\nimport { isFramerModule } from \"document/components/utils/defaultComponents.ts\"\nimport { FALLBACK_PATH, getRawWebPagePath } from \"document/components/utils/getWebPagePath.ts\"\nimport { pagePathLabel } from \"document/components/utils/pathToName.ts\"\nimport { getPluginManifestFromModuleIdentifier } from \"document/components/utils/plugins.ts\"\nimport { CONTENT_MANAGEMENT_ID } from \"document/models/CanvasTree/nodes/ContentManagementNode.ts\"\nimport type { ErrorListNode } from \"document/models/CanvasTree/nodes/ErrorListNode.ts\"\nimport { ERROR_LIST_NODE_ID } from \"document/models/CanvasTree/nodes/ErrorListNode.ts\"\nimport type { ErrorNode } from \"document/models/CanvasTree/nodes/ErrorNode.ts\"\nimport { ErrorNodeReason, ErrorNodeType, legacyErrorReason } from \"document/models/CanvasTree/nodes/ErrorNode.ts\"\nimport type { HeaderKey, HeaderValue } from \"document/models/CanvasTree/nodes/HeaderRouteNode.ts\"\nimport type { PresetsListNode } from \"document/models/CanvasTree/nodes/PresetsListNode.ts\"\nimport type { RewriteType } from \"document/models/CanvasTree/nodes/RewriteTypeEnum.ts\"\nimport type { LocalizedSegments } from \"document/models/CanvasTree/nodes/RouteSegmentRootNode.utils.ts\"\nimport { RoutesNode } from \"document/models/CanvasTree/nodes/RoutesNode.ts\"\nimport { allVariantsAreHidden } from \"document/models/CanvasTree/nodes/TemplateHelper.ts\"\nimport type { AnyWebPageNode, ShallowWebPageNode, WebPageNode } from \"document/models/CanvasTree/nodes/WebPageNode.ts\"\nimport { type StylePresetNode, isStylePresetNode } from \"document/models/CanvasTree/nodes/utils/isStylePresetNode.ts\"\nimport {\n\tisCodeComponentNode,\n\tisCollectionNode,\n\tisCustomCodeScopeNode,\n\tisDataRepeater,\n\tisDesignPageNode,\n\tisErrorListNode,\n\tisExternalModuleNode,\n\tisPresetsListNode,\n\tisSmartComponentNode,\n\tisWebPageNode,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport {\n\tpredictRecoverableOrderedSourceNodes,\n\tpreloadMissingExternalModuleErrors,\n} from \"document/models/CanvasTree/nodes/utils/predictRecoverableModules.ts\"\nimport { getSmartComponentOrWebPageForCodeComponent } from \"document/models/CanvasTree/nodes/utils/smartComponentInstanceHelpers.ts\"\nimport { hasCodeOverride } from \"document/models/CanvasTree/traits/WithCodeOverride.ts\"\nimport { withCodeOverridesExperiment } from \"document/models/CanvasTree/traits/WithCodeOverrides.ts\"\nimport { hasCollectionDataSource } from \"document/models/CanvasTree/traits/WithCollectionDataSource.ts\"\nimport type { IncludedLocales } from \"document/models/CanvasTree/traits/WithLocaleConfig.ts\"\nimport { defaultLocaleId } from \"document/models/CanvasTree/traits/WithLocales.ts\"\nimport { usesModuleRevision } from \"document/models/CanvasTree/traits/WithModuleRevision.ts\"\nimport { isReplica } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport { withQueryParam } from \"document/models/CanvasTree/traits/WithVariables.ts\"\nimport { isReplicaVariantOrReplicaVariantChild } from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport {\n\tcalculateModuleRevision,\n\tcalculateRouteRevision,\n} from \"document/models/CanvasTree/traits/utils/calculateModuleRevision.ts\"\nimport {\n\tisStylableCodeComponent,\n\tstylableCodeComponents,\n} from \"document/models/CanvasTree/traits/utils/hardCodedCodeComponentIdentifierChecks.ts\"\nimport { getNodeError } from \"document/models/CanvasTree/utils/getNodeError.ts\"\nimport type { AssetStore } from \"document/stores/AssetStore.ts\"\nimport type { ChromeStore } from \"document/stores/ChromeStore.ts\"\nimport type { LoadedExternalModulesStore } from \"document/stores/LoadedExternalModulesStore.ts\"\nimport type { ModulesStore } from \"document/stores/ModulesStore.ts\"\nimport type { PluginStore } from \"document/stores/PluginStore.ts\"\nimport type { ScopeStore } from \"document/stores/ScopeStore.ts\"\nimport type { SelectionStore } from \"document/stores/SelectionStore.ts\"\nimport type { ShaderFallbackImageStore } from \"document/stores/ShaderFallbackImageStore.ts\"\nimport { ModalType } from \"document/utils/ModalType.ts\"\nimport { sitePublishedAction, sitePublishedText } from \"document/utils/publishToastUtils.tsx\"\nimport { type ListVersionDeploymentsResponse, listVersionDeployments } from \"document/utils/sitesAPI.ts\"\nimport { getFramerRelease } from \"environment/getFramerRelease.ts\"\nimport { environment } from \"environment/index.ts\"\nimport { generateHTML } from \"export/exportToHTML.ts\"\nimport { NoTreeVersionError } from \"export/prepareProjectSnapshotForExport.ts\"\nimport { customNotFoundPagePaths } from \"library/router/customNotFoundPagePaths.ts\"\nimport type { Locale as RouterLocale } from \"library/router/types.ts\"\nimport { WaitForLoadingComponentsError } from \"modules/waitForComponentLoaderToCatchUp.ts\"\nimport pluralize from \"pluralize\"\nimport type { ReactNode } from \"react\"\nimport type { ProjectChangeScope, Socket } from \"socket/types.ts\"\nimport { randomBase62 } from \"utils/base62.ts\"\nimport { getCollectionCount } from \"utils/collectionUtils.ts\"\nimport { fetchWithRetry } from \"utils/fetch.ts\"\nimport { getCollectionForIdentifier } from \"utils/getCollectionForIdentifier.ts\"\nimport { isShallowObjectEqual } from \"utils/isShallowEqual.ts\"\nimport { sha256 } from \"utils/sha256.ts\"\nimport { isNull, isNumber, isObject, isString, isUndefined } from \"utils/typeChecks.ts\"\nimport { apiFetcher } from \"web/lib/apiFetcher.ts\"\nimport { isConnectionError } from \"web/lib/isConnectionError.ts\"\nimport { getMultiplayerServiceURL } from \"web/lib/multiplayerService.ts\"\nimport { toast } from \"web/lib/toaster.ts\"\nimport { ErrorArea, UIInteraction, record } from \"web/lib/tracker.ts\"\nimport { xRequestedByHeader } from \"web/lib/xRequestedByHeader.ts\"\nimport { serialiseChanges } from \"web/pages/project/components/PublishPopover/utils/changeSummary.ts\"\nimport type { ExtendedPermissions } from \"web/pages/project/permissions/projectPermissions.ts\"\nimport {\n\tChangeStatus,\n\tChangeType,\n\ttype ProjectChange,\n\tcomputePatchedChanges,\n\tgetNodeChange,\n\tgetRemovedChange,\n\tsortedChangesFromGroups,\n} from \"web/pages/project/projectChanges.ts\"\nimport { EngineStore } from \"../EngineStore.ts\"\nimport type {\n\tAnyCustomCodeScopeNode,\n\tAnySmartComponentNode,\n\tCanvasTree,\n\tCollectionNode,\n\tNodeID,\n\tScopeNode,\n\tSmartComponentNode,\n} from \"../models/CanvasTree/index.ts\"\nimport { CanvasNode, isScopeNode } from \"../models/CanvasTree/index.ts\"\nimport { type CodeGenerationStore, GenerationCondition } from \"./CodeGenerationStore.ts\"\nimport type { DebugStore } from \"./DebugStore.ts\"\nimport type { ModalStore } from \"./ModalStore.ts\"\nimport { PasswordPolicy } from \"./Password.ts\"\nimport { type PopoverStore, PopoverType } from \"./PopoverStore.ts\"\nimport type { ProjectStore } from \"./ProjectStore.ts\"\nimport { PublishStatus } from \"./PublishStatus.ts\"\nimport { type SiteSettingsStore, SiteSettingsTabNames } from \"./SiteSettingsStore.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\nimport { parseFormErrorReason } from \"./formErrorReason.ts\"\n\nconst log = getLogger(\"PublishStore\")\n\nconst toastTrackingPage = \"publish-success-toast\"\n\nfunction createOpenLinkToastAction(url: string): ToastAction {\n\treturn {\n\t\ttitle: \"Open Link\",\n\t\tonClick: () => {\n\t\t\trecord(\"ui_interaction\", {\n\t\t\t\tpage: toastTrackingPage,\n\t\t\t\tid: UIInteraction.openPublishedLink,\n\t\t\t})\n\t\t\topenNewTab(url)\n\t\t},\n\t}\n}\n\nfunction createConnectDomainAction(siteSettingsStore: SiteSettingsStore): ToastAction {\n\treturn {\n\t\ttitle: \"Add Domain\",\n\t\tonClick: () => {\n\t\t\trecord(\"ui_interaction\", {\n\t\t\t\tpage: toastTrackingPage,\n\t\t\t\tid: UIInteraction.openSiteSettingsDomains,\n\t\t\t})\n\t\t\tsiteSettingsStore.setActiveTab({ tab: SiteSettingsTabNames.domains }).catch(unhandledError)\n\t\t},\n\t}\n}\n\nexport const STALE_MODULE_ERROR_REASON = \"stale\"\n\ninterface PublishRevisions {\n\tchanges: ProjectChange[]\n\tnextRevisions: Record<NodeID, number | null>\n\tnextPaths: Record<NodeID, string>\n\tcount: number | null\n}\n\nconst SERVER_ROUTES_VERSION = 9\n\ntype ServerLocale = Omit<RouterLocale, \"textDirection\" | \"fallback\"> & {\n\ttextDirection?: never\n\tfallback?: ServerLocale\n}\n\nfunction routerLocaleToServerLocale(locale: RouterLocale): ServerLocale {\n\tconst { textDirection, fallback, ...rest } = locale\n\n\tconst serverLocale: ServerLocale = rest\n\n\tif (fallback) {\n\t\tserverLocale.fallback = routerLocaleToServerLocale(fallback)\n\t}\n\n\treturn serverLocale\n}\n\ninterface ServerRoutesMap {\n\tversion: typeof SERVER_ROUTES_VERSION\n\troutes: ServerRoute[]\n\tlocales: readonly ServerLocale[]\n\tlocalizedSegments?: LocalizedSegments\n}\n\nexport interface ServerAbTest {\n\tid: string\n\tvariantIds: readonly string[]\n\t/**\n\t * Cumulative distribution start positions for each variant in \"parts per million\" (0\u2013999,999).\n\t * Array is in the same order as `variantIds` (excludes control).\n\t * Each value represents the start of that variant's range.\n\t * E.g. [100000, 300000] means: control 0-99,999, variant[0] 100,000-299,999, variant[1] 300,000-999,999\n\t */\n\tdistributionsPpm?: readonly number[]\n\t/**\n\t * For CMS pages, this includes concrete values for path variables.\n\t * This is used to construct the path for taking screenshots\n\t * of A/B test variants.\n\t *\n\t * The value is consumed in FramerWebApi and dropped from the\n\t * DynamoDB payload.\n\t */\n\tsamplePathVariables?: Record<string, string>\n}\n\nexport interface ServerRoute {\n\tpath: string\n\t// This is optional to be consistent with the web API. Also publish routes\n\t// are used for redirects which currently don't support included locales.\n\tincludedLocales?: IncludedLocales\n\thandler:\n\t\t| {\n\t\t\t\ttype: \"page\"\n\t\t\t\tpageId: string\n\t\t\t\tabTest?: ServerAbTest\n\t\t  }\n\t\t| {\n\t\t\t\ttype: \"redirect\"\n\t\t\t\tto: string\n\t\t\t\tcode?: number\n\t\t  }\n\t\t| {\n\t\t\t\ttype: \"proxy\"\n\t\t\t\ttargetUrl: string\n\t\t  }\n\t\t| {\n\t\t\t\ttype: \"rewrite\"\n\t\t\t\tto: string\n\t\t\t\trewriteType: RewriteType\n\t\t  }\n\t\t| {\n\t\t\t\ttype: \"header\"\n\t\t\t\theaders: {\n\t\t\t\t\t[key: HeaderKey]: HeaderValue\n\t\t\t\t}\n\t\t  }\n}\n\ntype CanonicalURL =\n\t| { type: \"default\"; url?: string }\n\t| { type: \"custom\"; url: string }\n\t| { type: \"rewrite\"; url?: string }\n\nexport interface DomainConnectDiscoveryResult {\n\tproviderId: string\n\tproviderName: string\n\tproviderDisplayName?: string\n\twidth?: number\n\theight?: number\n\n\tapplyURL: string\n}\n\nexport enum DnsRecordsType {\n\tA = \"A\",\n\tAAAA = \"AAAA\",\n\tCNAME = \"CNAME\",\n\tCAA = \"CAA\",\n}\n\ninterface DnsRecordValidation {\n\tvalue: string\n\ttype: DnsRecordsType\n\tisValid: boolean\n\treason?: InvalidDNSReason\n}\n\ninterface DnsCaaConflict {\n\tname: string\n\tvalue: string\n\tisInRoot: boolean\n}\n\nexport interface ValidatedCustomHostname extends CustomHostname {\n\tisApex: boolean\n\trequiredAddresses: string[]\n\tinvalidDnsReason: InvalidDNSReason | null\n\tdomainConnect: DomainConnectDiscoveryResult | null\n\tprefix: string\n\thasDeprecatedAddresses?: boolean // TODO: Remove this when the transition to new IPs is complete\n\trequiredRecords: DnsRecordValidation[]\n\tconflictRecords: DnsRecordValidation[]\n\tcaaConflicts: DnsCaaConflict[]\n}\n\nconst enum InvalidDNSReason {\n\tExtraRecords = \"extra_records\",\n\tMissingRequiredRecords = \"missing_required_records\",\n\tDuplicatePrefix = \"duplicate_prefix\",\n\tInvalidCaa = \"invalid_caa\",\n}\n\ninterface PublishResponse {\n\tdeployment: ServerDeployment\n\thostnames: Hostname[]\n}\n\nexport interface PublishResult {\n\tdeployment: ServerDeployment\n\thostnames: Hostname[]\n}\n\ninterface PublishFailureResult {\n\terror: string\n}\n\nconst key = \"error\" satisfies keyof PublishFailureResult\nexport function isPublishError(value: unknown): value is PublishFailureResult {\n\treturn isObject(value) && !isNull(value) && key in value && isString(value.error)\n}\n\ninterface UpdateCustomDomainResult {\n\tok: boolean\n\terrorMessage?: string\n}\n\nasync function publish({\n\tprojectId,\n\thtml,\n\tserverRoutes,\n\tssgRoutes,\n\tssgRewrites,\n\tlocales,\n\ttreeState,\n\tcanonicalURL,\n\tdebugFlags,\n\tserializedExperiments,\n\tadaptLayoutToTextDirection,\n\tautomaticLocale,\n\tchangeSummary,\n\tsearchIndexUrl,\n\tpreOptimizePaths,\n\tlocalizedSegments,\n\tdetached,\n\tbranchId,\n}: {\n\tprojectId: string\n\thtml: string\n\tserverRoutes: ServerRoute[]\n\tssgRoutes: SSGRoute[]\n\tssgRewrites: Rewrite[]\n\tlocales: readonly RouterLocale[]\n\ttreeState: DeploymentTreeState\n\tcanonicalURL: CanonicalURL\n\tdebugFlags: DebugFlag[] | undefined\n\tserializedExperiments: Config<ExperimentName>\n\tadaptLayoutToTextDirection: boolean\n\tautomaticLocale: boolean\n\tchangeSummary?: string\n\tsearchIndexUrl: string\n\tpreOptimizePaths: string[]\n\tlocalizedSegments?: LocalizedSegments\n\t/**\n\t * Detached deployments don't update the hostnames, other than creating a version hostname for that deployment.\n\t */\n\tdetached: boolean\n\tbranchId: string\n}): Promise<PublishResponse> {\n\tconst body = new FormData()\n\tbody.set(\"projectId\", projectId)\n\tbody.set(\"html\", html)\n\tconst serverRoutesMap: ServerRoutesMap = {\n\t\tversion: SERVER_ROUTES_VERSION,\n\t\troutes: serverRoutes,\n\t\tlocales: locales.map(routerLocaleToServerLocale),\n\t\tlocalizedSegments,\n\t}\n\tbody.set(\"routes\", JSON.stringify(serverRoutesMap))\n\tif (treeState.treeVersion !== undefined) {\n\t\tbody.set(\"treeVersion\", String(treeState.treeVersion))\n\t}\n\tif (!experiments.is(\"patching\", \"off\")) {\n\t\t// Patching is still highly experimental, and we might still change our mind about the\n\t\t// treeState, so let's not store it by default just yet.\n\t\tbody.set(\"treeState\", JSON.stringify(treeState))\n\t}\n\tbody.set(\"canonicalUrl\", JSON.stringify(canonicalURL))\n\tbody.set(\"searchIndexUrl\", searchIndexUrl)\n\tif (changeSummary) {\n\t\tbody.set(\"changeSummary\", changeSummary)\n\t}\n\n\tconst { buildId, channel } = getBuildInfo()\n\tbody.set(\"buildId\", buildId)\n\tbody.set(\"channel\", channel)\n\n\tconst ssgEditorInput = serializeEditorInput({\n\t\tadaptLayoutToTextDirection,\n\t\tautomaticLocale,\n\t\tdebugFlags,\n\t\texperiments: serializedExperiments,\n\t\tlocales: [...locales],\n\t\tpreOptimizePaths: experiments.isOn(\"onDemandSSG\") ? preOptimizePaths : undefined,\n\t\trewrites: ssgRewrites,\n\t\troutes: ssgRoutes,\n\t})\n\tbody.set(\"ssgEditorInput\", ssgEditorInput)\n\n\tif (branchId !== MAIN_BRANCH_ID) {\n\t\tbody.set(\"branchId\", branchId)\n\t}\n\n\t// We do not pass the multipart/form-data content type here, because it will be\n\t// filled in by the browser and contain the multipart boundary\n\tconst response = await apiFetcher.postRaw(\n\t\tdetached ? \"/web/v1/sites/publish?detached=true\" : \"/web/v1/sites/publish\",\n\t\tbody,\n\t\tundefined,\n\t)\n\treturn response.json()\n}\n\nfunction getBuildInfo() {\n\tconst buildId = process.env.BUILD_ID\n\tassert(buildId, \"BUILD_ID must be set\")\n\n\tconst release = getFramerRelease(window)\n\tassert(release, \"release channel must be known\")\n\tlet channel = release.channel\n\tif (release.override === \"preview\") {\n\t\tchannel += `+preview@${buildId}`\n\t}\n\n\treturn { buildId, channel }\n}\n\nasync function unpublish(projectId: string): Promise<void> {\n\treturn apiFetcher.post(\"/web/v1/sites/unpublish\", { projectId })\n}\n\ninterface CreateCustomDomainResponse {\n\tprojectId: string\n\thostnames: Hostname[]\n}\n\nasync function postCustomDomain(params: { projectId: string; domain: string }): Promise<CreateCustomDomainResponse> {\n\treturn apiFetcher.post(\"/web/v1/sites/hostnames/custom\", params)\n}\n\ninterface ValidateCustomDomainResponse {\n\thostnames: ValidatedCustomHostname[]\n}\n\nexport async function validateCustomDomain(\n\tparams: { projectId: string },\n\tsignal?: AbortSignal,\n): Promise<ValidateCustomDomainResponse> {\n\tconst response: ValidateCustomDomainResponse = await apiFetcher.post(\n\t\t`/web/v1/sites/hostnames/custom/projects/${params.projectId}/validate`,\n\t\tparams,\n\t\tsignal,\n\t)\n\n\t// Filter out redirect domains that shouldn't be there, e.g.,\n\t// www.blog.mysite.com. Or more formally, `www` redirects that point to\n\t// non-apex domains.\n\t//\n\t// - www.mysite.com => mysite.com - bueno\n\t// - mysite.com => www.mysite.com - bueno\n\t// - www.blog.mysite.com => blog.mysite.com - no bueno\n\t//\n\t// Eventually, we will simply stop creating these on the backend, and clean\n\t// up the existing ones, and then we'll be able to remove this code.\n\tconst { hostnames } = response\n\tconst nonApex = Object.fromEntries(hostnames.filter(h => !h.isApex).map(h => [h.hostname, true]))\n\tconst isWWWRedirectToNonApex = (h: ValidatedCustomHostname) =>\n\t\th.hostname.startsWith(\"www.\") && h.redirect && nonApex[h.redirect]\n\treturn { hostnames: hostnames.filter(h => !isWWWRedirectToNonApex(h)) }\n}\n\ninterface CheckDomainAvailabilityResponse {\n\tisAvailable: boolean\n\ttype: string\n}\n\nasync function checkDomainAvailability(domain: string): Promise<CheckDomainAvailabilityResponse> {\n\treturn apiFetcher.post(`/web/v1/sites/hostnames/available`, { domain })\n}\n\nasync function removeCustomDomain(params: { projectId: string; domain: string }): Promise<void> {\n\treturn apiFetcher.delete(\"/web/v1/sites/hostnames/custom\", params)\n}\n\nasync function updateCustomHostname(params: {\n\tprojectId: string\n\tdomain: string\n\tdeploymentId: string\n}): Promise<EnrichedHostnameWithDeployment> {\n\treturn apiFetcher.put(\"/web/v1/sites/hostnames/custom\", params)\n}\n\nfunction computeLocalizedSegmentsMetrics(localizedSegments: LocalizedSegments | undefined): {\n\tlocalizedSegmentsBytes: number\n\tlocalizedSegmentsCount: number\n} {\n\tif (!localizedSegments) return { localizedSegmentsBytes: 0, localizedSegmentsCount: 0 }\n\n\tconst { [defaultLocaleId]: _, ...segments } = localizedSegments\n\n\tif (isEmptyObject(segments)) return { localizedSegmentsBytes: 0, localizedSegmentsCount: 0 }\n\n\tconst localizedSegmentsBytes = new TextEncoder().encode(JSON.stringify(segments)).length\n\n\tlet localizedSegmentsCount = 0\n\tfor (const localeSegments of Object.values(segments)) {\n\t\tlocalizedSegmentsCount += Object.keys(localeSegments).length\n\t}\n\n\treturn {\n\t\tlocalizedSegmentsBytes,\n\t\tlocalizedSegmentsCount,\n\t}\n}\n\nexport interface DeploymentSettings {\n\tdeploymentStrategy: DeploymentStrategy\n\tprotectedStaging?: ProtectedStagingValue\n}\n\ninterface ProjectSettings {\n\tdeploymentSettings: DeploymentSettings\n\tpasswordSettings: {\n\t\tpasswordPolicy: PasswordPolicy\n\t\tpasswordValue?: string\n\t}\n}\n\nexport async function getProjectSettings(\n\tprojectId: string,\n\tsignal?: AbortSignal,\n): Promise<{ settings: ProjectSettings }> {\n\treturn apiFetcher.get(`/web/v1/sites/projects/${projectId}/settings`, undefined, signal)\n}\n\nasync function updateProjectSettings(\n\tprojectId: string,\n\tprojectSettings: Partial<ProjectSettings>,\n): Promise<{ settings: ProjectSettings }> {\n\treturn apiFetcher.put(`/web/v1/sites/projects/${projectId}/settings`, projectSettings)\n}\n\ninterface DeploymentIssue {\n\trouteId: string | null\n\tseverity: string\n\t// Legacy deployment issues don't have type and data, but have a pre-formatted Markdown message instead.\n\ttype?: string\n\tdata?: Record<string, unknown>\n\tmessage?: string\n}\n\nexport interface GetDeploymentIssuesResponse {\n\tissues: DeploymentIssue[]\n\thasMoreIssues: boolean\n}\n\nasync function getDeploymentIssues(projectId: string, deploymentId: string): Promise<GetDeploymentIssuesResponse> {\n\treturn apiFetcher.get(`/web/v1/sites/deployments/${projectId}/${deploymentId}/issues`)\n}\n\nasync function getBranchHostname(projectId: string, branchId: string): Promise<BranchHostnameWithDeployment> {\n\treturn apiFetcher.get(`/web/v1/sites/hostnames/${projectId}/branch/${branchId}`)\n}\n\n/**\n * For the given list of hostnames, fetches their deployment issues if needed.\n *\n * De-duplicates the requests if multiple hostnames point to the same deployment.\n *\n * Returns a list of deployment issues for each corresponding hostname.\n */\nasync function getDeploymentIssuesIfNeeded(\n\tprojectId: string,\n\thostnames: {\n\t\tnewDeployment: Deployment | undefined\n\t\tcurrentDeploymentIssues: GetDeploymentIssuesResponse | undefined\n\t}[],\n) {\n\tconst requests: { [deploymentId: string]: Promise<GetDeploymentIssuesResponse> } = {}\n\tconst result = new Array<Promise<GetDeploymentIssuesResponse | undefined>>(hostnames.length)\n\n\tfor (let i = 0; i < hostnames.length; i++) {\n\t\t// biome-ignore lint/style/noNonNullAssertion: loop\n\t\tconst { newDeployment, currentDeploymentIssues } = hostnames[i]!\n\n\t\tresult[i] = Promise.resolve(currentDeploymentIssues)\n\n\t\tif (!newDeployment) continue\n\n\t\t// We expect no issues on a fresh publish, and we want publishing to feel snappy, so let's avoid a request.\n\t\tif (newDeployment.status === DeploymentStatus.SpaReady) {\n\t\t\tresult[i] = Promise.resolve(undefined)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Deployments in the ready status and without warnings means there are no issues, so we can avoid a request.\n\t\t// The \"without warnings\" check is for routes < v8, when there was no SsgReadyWithWarnings, and warnings were\n\t\t// instead part of SsgReady.\n\t\tif (newDeployment.status === DeploymentStatus.SsgReady && !newDeployment.hasWarnings) {\n\t\t\tresult[i] = Promise.resolve(undefined)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Start a new request, or attach to the existing one.\n\t\tlet request = requests[newDeployment.id]\n\t\tif (!request) {\n\t\t\trequest = getDeploymentIssues(projectId, newDeployment.id)\n\t\t\trequests[newDeployment.id] = request\n\t\t}\n\n\t\tresult[i] = request\n\t}\n\n\treturn Promise.all(result)\n}\n\nasync function* listVersionDeploymentsStream(projectId: string, limit?: number, branchId?: string) {\n\tlet cursor: string | undefined = undefined\n\tlet hasNextPage: boolean = true\n\tlet deployments: VersionDeployment[] = []\n\n\twhile (hasNextPage) {\n\t\tconst response: ListVersionDeploymentsResponse = await listVersionDeployments(projectId, limit, cursor, branchId)\n\t\tcursor = response.cursor\n\t\thasNextPage = response.hasNextPage\n\t\tdeployments = response.deployments.map(mapDeployment)\n\n\t\tif (hasNextPage) yield deployments\n\t}\n\n\t// Last deployments should be returned rather than yielded. That way, the\n\t// final iterator result is { value: <deployments[]>, done: true } and\n\t// the UI can act accordingly.\n\treturn deployments\n}\n\ntype EnrichedHostnameWithDeploymentAndDeploymentId = EnrichedHostnameWithDeployment & {\n\tdeploymentId: string\n}\n\nexport async function listFreeDomains(): Promise<{ freeDomains: string[] }> {\n\treturn apiFetcher.get(\"/web/v1/sites/domains/free\")\n}\n\nenum PollingType {\n\tHostnames = 0,\n\tVersions = 1,\n}\n\nconst INITIAL_POLL_INTERVAL = 1_000 // 1 second for first 10s\nconst MODERATE_POLL_INTERVAL = 5_000 // 5 seconds for next 50s\nconst SLOW_POLL_INTERVAL = 60_000 // 1 minute for remaining time\nconst MAX_POLL_ATTEMPTS = 39 // Stop after ~20 minutes (10s + 50s + 19min = 20min)\n\nexport function isDeploymentOptimizing(status: DeploymentStatus | undefined): boolean {\n\treturn Boolean(status && deriveIndicatorStatus(status, false) === StatusIndicatorEnum.Optimizing)\n}\n\nexport function hasDeploymentErrorsOrInProgress(status: DeploymentStatus | undefined): boolean {\n\treturn (\n\t\tstatus === DeploymentStatus.SpaReady || // SSG in progress\n\t\tstatus === DeploymentStatus.SsgPipelineFailed ||\n\t\tstatus === DeploymentStatus.SsgReadyWithErrors\n\t)\n}\n\nexport type PublishErrorUIType = \"component\" | \"code-override\" | \"cms\" | \"form\" | \"code-generation\" | \"unknown\"\n\nconst missingExportRegex = /^The requested module '[^']*' does not provide an export named '(?<exportName>[^']+)'$/u\n/**\n * When named exports are renamed, the containing module will throw a syntax error like:\n *\n * ```plaintext\n * The requested module 'blob:https://project-bwpzetmjykoykh3ht6oq.framercanvas.com/635d85b0-d18a-4dad-b60a-cc8b70ad9e26' does not provide an export named 'UTMFormComponent'\n * ```\n *\n * This function returns the name of the missing export.\n */\nfunction getMissingExportName(error: string | undefined): string | undefined {\n\tif (!error) return undefined\n\tconst match = missingExportRegex.exec(error)\n\treturn match?.groups?.exportName\n}\n\nfunction errorTypeForNode(\n\ttree: CanvasTree,\n\tnode: ErrorNode,\n\tincludeShallowScopeErrors: boolean,\n): PublishErrorUIType | undefined {\n\t// Ignore legacy errors that can't be recovered.\n\tif (legacyErrorReason.has(node.reason) && !node.moduleIdentifier) {\n\t\treturn undefined\n\t}\n\tif (node.moduleIdentifier) {\n\t\tconst source = tree.get(node.nodeId)\n\t\tif (!source) {\n\t\t\tconst scope = tree.getNodeWithTrait(node.scopeId, isScopeNode)\n\t\t\tif (scope && !scope.isLoaded()) {\n\t\t\t\treturn includeShallowScopeErrors ? \"component\" : undefined\n\t\t\t}\n\t\t\tassert(source, \"Publish Errors: An error node should correspond to a node in the tree.\")\n\t\t}\n\t\tif (hasCodeOverride(source) && source.codeOverrideIdentifier === node.moduleIdentifier) {\n\t\t\treturn \"code-override\"\n\t\t}\n\t\tif (isDataRepeater(source) && source.dataIdentifier === node.moduleIdentifier) {\n\t\t\treturn \"cms\"\n\t\t}\n\t\tif (isCodeComponentNode(source) && source.codeComponentIdentifier === node.moduleIdentifier) {\n\t\t\treturn \"component\"\n\t\t}\n\t\t// In the case where the identifier is not used by any of our known sources, ignore this error.\n\t\treturn undefined\n\t}\n\tif (node.type === ErrorNodeType.Form) return \"form\"\n\treturn \"code-generation\"\n}\n\nexport interface PublishError {\n\tnodeId: NodeID\n\ttype: PublishErrorUIType\n\tscopeId: NodeID\n\treason: string | ErrorNodeReason | undefined\n\tmoduleIdentifier: string | undefined\n\texportName?: string\n}\n\nconst NON_BLOCKING_FORM_ERROR_REASONS = new Set([\"email_not_verified\"])\n\nexport function isUnverifiedEmailFormError(rawReason: string | ErrorNodeReason | undefined): boolean {\n\tconst { destinationType, reason } = parseFormErrorReason(rawReason)\n\treturn destinationType === \"verifiedEmail\" && NON_BLOCKING_FORM_ERROR_REASONS.has(reason)\n}\n\nfunction isNonBlockingPublishError(error: PublishError): boolean {\n\treturn error.type === \"form\" && isUnverifiedEmailFormError(error.reason)\n}\n\nexport function hasBlockingPublishErrors(errors: readonly PublishError[] | undefined): boolean {\n\treturn !!errors && errors.some(error => !isNonBlockingPublishError(error))\n}\n\nfunction addErrorsForMissingModulesInScope(\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tscope: SmartComponentNode | WebPageNode,\n\terrors: PublishError[],\n\tmissingExternalModules: Set<ExternalModuleExportIdentifierString> | undefined,\n\tcodeComponentIdentifiers: Set<string | undefined>,\n\tmissingExportNames: Map<string, string>,\n\t/**\n\t * Track visited scopes so we don't infinitely recurse in case someone has\n\t * added an instance of a smart component in the same scope as the smart\n\t * component.\n\t */\n\tvisitedScopes: Set<NodeID>,\n): void {\n\t// To check for missing instances, walk the scope of the primary variant\n\t// looking for code component nodes with identifiers that aren't in the\n\t// component loader. The primary variant contains all nodes in all variants,\n\t// they just might not all be visible.\n\tfor (const { node, skipChildren } of scope.walkWithSkipChildren()) {\n\t\tif (isScopeNode(node)) continue\n\n\t\t// Skip replicas, the primary variant will include all nodes.\n\t\tif (isReplica(node)) {\n\t\t\tskipChildren()\n\t\t\tcontinue\n\t\t}\n\n\t\t// When all variants of the node are hidden, it and it's descendants\n\t\t// won't be included in generated code, so are unlikely to be the reason\n\t\t// that the module for this scope has an error.\n\t\tif (allVariantsAreHidden(tree, scope, node)) {\n\t\t\tskipChildren()\n\t\t\tcontinue\n\t\t}\n\n\t\t// If the layer has a missing code override, assume that is a cause of\n\t\t// an error.\n\t\tif (hasCodeOverride(node) && !componentLoader.componentForIdentifier(node.codeOverrideIdentifier)) {\n\t\t\tcodeComponentIdentifiers.add(node.codeOverrideIdentifier)\n\t\t\terrors.push({\n\t\t\t\ttype: \"code-override\",\n\t\t\t\tnodeId: node.id,\n\t\t\t\tscopeId: scope.id,\n\t\t\t\treason: ErrorNodeReason.MissingModule,\n\t\t\t\tmoduleIdentifier: isModuleIdentifier(node.codeOverrideIdentifier) ? node.codeOverrideIdentifier : undefined,\n\t\t\t})\n\t\t}\n\n\t\tif (\n\t\t\t!isCodeComponentNode(node) ||\n\t\t\t!isModuleExportIdentifier(node.codeComponentIdentifier) ||\n\t\t\t// If we have already checked this component, we don't need to check it again.\n\t\t\tcodeComponentIdentifiers.has(node.codeComponentIdentifier)\n\t\t) {\n\t\t\tcontinue\n\t\t}\n\n\t\tconst exists = componentLoader.componentForIdentifier(node.codeComponentIdentifier)\n\t\tconst error = componentLoader.errorForIdentifier(node.codeComponentIdentifier)\n\n\t\t// If the component is in the loader and doesn't have an error it's\n\t\t// unlikely to be causing the containing webpage to fail to evaluate.\n\t\tif (exists && isNull(error)) continue\n\n\t\t// If we encounter a missing external module, we don't know if it's\n\t\t// actually missing, or if it's just not loaded yet if it has never been\n\t\t// rendered on the canvas in this session.\n\t\tif (\n\t\t\tmissingExternalModules &&\n\t\t\t!exists &&\n\t\t\tisNull(error) &&\n\t\t\tisModuleExportIdentifier(node.codeComponentIdentifier) &&\n\t\t\tisExternalModuleIdentifier(node.codeComponentIdentifier)\n\t\t) {\n\t\t\tmissingExternalModules.add(node.codeComponentIdentifier)\n\t\t\tcontinue\n\t\t}\n\n\t\tconst localSmartComponent = getSmartComponentOrWebPageForCodeComponent(tree, node)\n\n\t\tif (\n\t\t\tisSmartComponentNode(localSmartComponent) &&\n\t\t\tlocalSmartComponent.isLoaded() &&\n\t\t\t!visitedScopes.has(localSmartComponent.id)\n\t\t) {\n\t\t\tvisitedScopes.add(localSmartComponent.id)\n\t\t\t// If the node is a local smart component, it's not very helpful to\n\t\t\t// just flag that it's missing or erroring, instead we can recurse\n\t\t\t// down into the actual smart component layers and try to find the\n\t\t\t// reason.\n\t\t\tconst smartComponentErrors: PublishError[] = []\n\t\t\taddErrorsForMissingModulesInScope(\n\t\t\t\ttree,\n\t\t\t\tcomponentLoader,\n\t\t\t\tlocalSmartComponent,\n\t\t\t\tsmartComponentErrors,\n\t\t\t\tmissingExternalModules,\n\t\t\t\tcodeComponentIdentifiers,\n\t\t\t\tmissingExportNames,\n\t\t\t\tvisitedScopes,\n\t\t\t)\n\t\t\t// If we find errors inside the smart component, they are likely the\n\t\t\t// source, so we track them and ignore this component.\n\t\t\tif (smartComponentErrors.length > 0) {\n\t\t\t\terrors.push(...smartComponentErrors)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tcodeComponentIdentifiers.add(node.codeComponentIdentifier)\n\n\t\tconst exportName =\n\t\t\tgetMissingExportName(error?.error) ?? parseModuleIdentifier(node.codeComponentIdentifier)?.exportSpecifier\n\n\t\t// If the error is a missing export, we should only record it once per component it is\n\t\t// exported from. This ensures that `Button` exported from 2 files is recorded twice.\n\t\tif (isString(error?.error) && isString(exportName)) {\n\t\t\tconst existingErrorExport = missingExportNames.get(error.error)\n\t\t\tif (existingErrorExport === exportName) return\n\t\t\tmissingExportNames.set(error.error, exportName)\n\t\t}\n\n\t\t// Otherwise there is likely something wrong with this component,\n\t\t// perhaps an override violates the rule of hooks, or the component is\n\t\t// missing in the component loader.\n\t\terrors.push({\n\t\t\ttype: \"component\",\n\t\t\tnodeId: node.id,\n\t\t\tscopeId: scope.id,\n\t\t\treason: error ? ErrorNodeReason.CodeError : ErrorNodeReason.MissingModule,\n\t\t\tmoduleIdentifier: node.codeComponentIdentifier,\n\t\t\texportName,\n\t\t})\n\t}\n}\n\ninterface RoutesSizeErrorStats {\n\tpageCount: number\n\tredirectCount: number\n\trewriteCount: number\n\theaderCount: number\n}\n\nexport interface RecoveryProgress {\n\tphase: \"regeneration\" | \"persistence\"\n\ttotal: number\n\tcompleted: number\n}\n\nconst metadataLengthErrorRegex = /^\"(.+)\\.(.+?)\" length must be less than or equal/u\nconst routesTotalSizeErrorRegex = /\"routes\" total size may not exceed (\\d+)/u\n/**\n * Matches the server-side MAX_SITE_PUBLISH_MULTER_FIELD_SIZE multer \"Field value too long\" error when a form field\n * exceeds the configured field-size limit (25MB by default).\n * */\nconst fieldValueTooLongErrorRegex = /^Field value too long$/u\n\ninterface Publish400ErrorMapping {\n\tmessage: string\n\tneedsErrorRefInToast: boolean\n\ttoastSecondaryText?: string\n}\n\nexport function buildRoutesSizeErrorMessage(stats: RoutesSizeErrorStats | undefined): string {\n\tconst base = \"Too many routes\"\n\n\tif (!stats) return base\n\n\tconst parts: string[] = []\n\tparts.push(`${stats.pageCount} Page routes`)\n\n\tif (stats.redirectCount) parts.push(`${stats.redirectCount} Redirects`)\n\tif (stats.rewriteCount) parts.push(`${stats.rewriteCount} Rewrites`)\n\tif (stats.headerCount) parts.push(`${stats.headerCount} Headers`)\n\n\treturn `${base} (${parts.join(\", \")})`\n}\n\n/**\n * Maps a 400-status API error message to a user-facing publish error. Returns\n * `undefined` when the message doesn't match any known pattern, so the caller\n * can fall through to a generic message.\n */\nexport function mapPublish400ErrorMessage(\n\terrorMessage: string,\n\troutesSizeStats: RoutesSizeErrorStats | undefined,\n): Publish400ErrorMapping | undefined {\n\tconst metadataMatch = errorMessage.match(metadataLengthErrorRegex)\n\tif (metadataMatch) {\n\t\tconst [, path, field] = metadataMatch\n\t\tconst pageTitle = path ? pagePathLabel(path) : undefined\n\t\treturn {\n\t\t\tmessage: `Failed to publish as the ${field} for ${pageTitle} is too long. Please adjust in your settings.`,\n\t\t\tneedsErrorRefInToast: true,\n\t\t}\n\t}\n\n\tif (routesTotalSizeErrorRegex.test(errorMessage)) {\n\t\treturn {\n\t\t\tmessage: buildRoutesSizeErrorMessage(routesSizeStats),\n\t\t\tneedsErrorRefInToast: false,\n\t\t}\n\t}\n\n\tif (fieldValueTooLongErrorRegex.test(errorMessage)) {\n\t\treturn {\n\t\t\tmessage: \"Failed to publish.\",\n\t\t\ttoastSecondaryText: \"Project too large, try reducing the number of pages, redirects, or rewrites.\",\n\t\t\tneedsErrorRefInToast: false,\n\t\t}\n\t}\n\n\treturn undefined\n}\n\ninterface PublishStatsAccumulator {\n\tusedCollections: Set<ModuleExportIdentifierString>\n\tcodeComponentInstanceCount: number\n\tdeprecatedCodeComponentInstanceCount: number\n\tusedLocalCodeComponents: Set<LocalModuleExportIdentifierString>\n\tusedExternalCodeComponents: Set<ExternalModuleExportIdentifierString>\n\tusedOverrides: Set<string>\n\tusedWorkshopGeneratedComponents: Set<string>\n\tlayersWithOverrides: number\n\tlocalCodeFileIdentifiers: Map<LocalModuleExportIdentifierString, ModuleIdentifier>\n\tpendingExternal: Map<\n\t\tExternalModuleExportIdentifierString,\n\t\t{ identifier: ExternalModuleExportIdentifier; count: number }\n\t>\n}\n\nexport class PublishStore extends EngineStore {\n\tprivate _didInitialize = false\n\t// FIXME: the two ! below are actually incorrect: the _projectId and _socket properties are not initialized\n\t// until initialize() is called. However, too much code assumes that they are initialized and not undefined.\n\t// One way to fix this would be to turn them into getters that throw if they are not initialized,\n\t// but we would have to take the performance implications of that into account\n\tprivate _projectId!: string\n\tprivate _socket!: Socket\n\n\tprivate _publishStatus: PublishStatus = PublishStatus.Unknown\n\tprivate _deploymentSettings: DeploymentSettings | undefined\n\tprivate _passwordPolicy: PasswordPolicy | undefined\n\tprivate _passwordValue: string | undefined\n\tprivate _freeDomains: string[] = []\n\n\tprivate _defaultHostname: DefaultHostname | undefined\n\tprivate _customHostname: CustomHostname | undefined\n\tprivate _branchHostname: BranchHostname | undefined\n\t#previousBranchId: string | undefined\n\t#loadingBranchPublishContextId: string | undefined\n\tprivate _defaultHostnameDeployment: Deployment | undefined\n\tprivate _customHostnameDeployment: Deployment | undefined\n\tprivate _branchHostnameDeployment: Deployment | undefined\n\tprivate _defaultHostnameDeploymentIssues: GetDeploymentIssuesResponse | undefined\n\tprivate _customHostnameDeploymentIssues: GetDeploymentIssuesResponse | undefined\n\n\tprivate _recoveryProgress: RecoveryProgress | undefined\n\n\tcustomHostnameValidationResult: ValidatedCustomHostname[] = []\n\n\tprivate _versions: VersionDeployment[] = []\n\tprivate _versionsStream: AsyncGenerator<VersionDeployment[], VersionDeployment[]> | undefined\n\tprivate _didLoadInitialVersionDeployments = false\n\tprivate _canLoadMoreVersionDeployments = true\n\tprivate _latestPublishSuccessToastKey: string | undefined\n\n\tconstructor(\n\t\tprivate readonly componentLoader: ComponentLoader,\n\t\tprivate readonly treeStore: TreeStore,\n\t\tprivate readonly projectStore: ProjectStore,\n\t\tprivate readonly codeGenerationStore: CodeGenerationStore,\n\t\tprivate readonly modulesStore: ModulesStore,\n\t\tprivate readonly pluginStore: PluginStore,\n\t\tprivate readonly siteSettingsStore: SiteSettingsStore,\n\t\tprivate readonly popoverStore: PopoverStore,\n\t\tprivate readonly debugStore: DebugStore,\n\t\tprivate readonly chromeStore: ChromeStore,\n\t\tprivate readonly scopeStore: ScopeStore,\n\t\tprivate readonly selectionStore: SelectionStore,\n\t\tprivate readonly shaderFallbackImageStore: ShaderFallbackImageStore,\n\t\tprivate readonly loadedExternalModulesStore: LoadedExternalModulesStore,\n\t\tprivate readonly assetStore: AssetStore,\n\t\tprivate readonly modalStore: ModalStore,\n\t\tprivate readonly getActiveWebPageURL: (hostname: string) => string,\n\t\tprivate readonly isViewOnly: (permission: keyof ExtendedPermissions) => boolean,\n\t\tprivate abortSignal?: AbortSignal,\n\t) {\n\t\tsuper()\n\t}\n\n\tprivate async confirmPublishWithDisabledForms(): Promise<boolean> {\n\t\treturn new Promise(resolve => {\n\t\t\tlet didResolve = false\n\t\t\tconst settle = (value: boolean) => {\n\t\t\t\tif (didResolve) return\n\t\t\t\tdidResolve = true\n\t\t\t\tresolve(value)\n\t\t\t}\n\n\t\t\tthis.modalStore.push({\n\t\t\t\ttype: ModalType.Confirmation,\n\t\t\t\ttitle: \"Publish with disabled forms?\",\n\t\t\t\tdescription:\n\t\t\t\t\t\"Some of your forms contain unverified email addresses. They will not receive any submissions until they are verified.\",\n\t\t\t\tconfirmLabel: Dictionary.Publish,\n\t\t\t\tcancelLabel: Dictionary.Cancel,\n\t\t\t\tsource: \"automatic\",\n\t\t\t\thasBackdrop: true,\n\t\t\t\tonConfirm: () => settle(true),\n\t\t\t\tonCancel: () => settle(false),\n\t\t\t\tonDismiss: () => settle(false),\n\t\t\t})\n\t\t})\n\t}\n\n\tasync initialize(projectId: string, socket: Socket) {\n\t\tif (this._didInitialize) return\n\t\tthis._didInitialize = true\n\n\t\tthis._socket = socket\n\t\tthis._projectId = projectId\n\n\t\tthis.fetchMostVisitedPaths()\n\t\tconst mostVisitedPathsIntervalId = setInterval(\n\t\t\t() => this.fetchMostVisitedPaths(),\n\t\t\tPublishStore.mostVisitedPathsRefreshInterval,\n\t\t)\n\t\tthis.abortSignal?.addEventListener(\"abort\", () => {\n\t\t\tclearInterval(mostVisitedPathsIntervalId)\n\t\t\tthis.stopPolling(PollingType.Hostnames)\n\t\t\tthis.stopPolling(PollingType.Versions)\n\t\t})\n\t\tthis.abortSignal = undefined\n\n\t\tawait Promise.allSettled([\n\t\t\tthis.loadHostnames().then(() => this.validateCustomDomain()),\n\t\t\tthis.loadProjectSettings(),\n\t\t\tthis.loadFreeDomains(),\n\t\t])\n\t}\n\n\tinitializeFromStore(source: PublishStore) {\n\t\tif (this._didInitialize) return\n\t\tthis._didInitialize = true\n\n\t\tthis._socket = source._socket\n\t\tthis._projectId = source._projectId\n\n\t\t// This is a one-time shallow copy. PublishStore properties are replaced rather\n\t\t// than mutated in place, so reusing the current references here is safe.\n\n\t\t// fetchMostVisitedPaths\n\t\tthis._mostVisitedPaths = source._mostVisitedPaths\n\t\t// loadHostnames\n\t\tthis._publishStatus = source._publishStatus\n\t\tthis._defaultHostname = source._defaultHostname\n\t\tthis._customHostname = source._customHostname\n\t\tthis._branchHostname = source._branchHostname\n\t\tthis._defaultHostnameDeployment = source._defaultHostnameDeployment\n\t\tthis._customHostnameDeployment = source._customHostnameDeployment\n\t\tthis._branchHostnameDeployment = source._branchHostnameDeployment\n\t\tthis._defaultHostnameDeploymentIssues = source._defaultHostnameDeploymentIssues\n\t\tthis._customHostnameDeploymentIssues = source._customHostnameDeploymentIssues\n\t\t// validateCustomDomain\n\t\tthis.customHostnameValidationResult = source.customHostnameValidationResult\n\t\t// loadProjectSettings\n\t\tthis._deploymentSettings = source._deploymentSettings\n\t\tthis._passwordPolicy = source._passwordPolicy\n\t\tthis._passwordValue = source._passwordValue\n\t\t// loadFreeDomains\n\t\tthis._freeDomains = source._freeDomains\n\n\t\tthis.#previousBranchId = undefined\n\t}\n\n\tprivate async updateState(\n\t\thostnames: EnrichedHostnameWithDeploymentAndDeploymentId[],\n\t\tcustomHostnameValidationResult?: ValidatedCustomHostname[],\n\t) {\n\t\tconst branchId = this.treeStore.branchId\n\n\t\tlet {\n\t\t\t_defaultHostname: nextDefaultHostname,\n\t\t\t_customHostname: nextCustomHostname,\n\t\t\t_branchHostname: nextBranchHostname,\n\t\t\t_defaultHostnameDeployment: nextDefaultHostnameDeployment,\n\t\t\t_customHostnameDeployment: nextCustomHostnameDeployment,\n\t\t\t_branchHostnameDeployment: nextBranchHostnameDeployment,\n\t\t} = this\n\n\t\tfor (const { deployment, ...wronglyTypedHostname } of hostnames) {\n\t\t\t// FIXME: We need to clean up our types to get a correct type here.\n\t\t\tconst hostname = wronglyTypedHostname as Hostname\n\t\t\tswitch (hostname.type) {\n\t\t\t\tcase HostnameType.Default:\n\t\t\t\t\tnextDefaultHostname = hostname\n\t\t\t\t\tnextDefaultHostnameDeployment = {\n\t\t\t\t\t\t...deployment,\n\t\t\t\t\t\tprojectId: hostname.projectId,\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\n\t\t\t\tcase HostnameType.Custom:\n\t\t\t\t\tif (hostname.redirect) break\n\t\t\t\t\tnextCustomHostname = hostname\n\t\t\t\t\tnextCustomHostnameDeployment = {\n\t\t\t\t\t\t...deployment,\n\t\t\t\t\t\tprojectId: hostname.projectId,\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\n\t\t\t\tcase HostnameType.Branch:\n\t\t\t\t\tnextBranchHostname = hostname\n\t\t\t\t\tnextBranchHostnameDeployment = {\n\t\t\t\t\t\t...deployment,\n\t\t\t\t\t\tprojectId: hostname.projectId,\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tconst [nextDefaultHostnameIssues, nextCustomHostnameIssues] = await getDeploymentIssuesIfNeeded(this._projectId, [\n\t\t\t{\n\t\t\t\tnewDeployment: nextDefaultHostnameDeployment,\n\t\t\t\tcurrentDeploymentIssues: this._defaultHostnameDeploymentIssues,\n\t\t\t},\n\t\t\t{\n\t\t\t\tnewDeployment: nextCustomHostnameDeployment,\n\t\t\t\tcurrentDeploymentIssues: this._customHostnameDeploymentIssues,\n\t\t\t},\n\t\t])\n\n\t\t// NO AWAITS BELOW THIS LINE PLEASE, the state updates should be atomic so everything re-renders at once.\n\n\t\tconst branchChanged = branchId !== this.treeStore.branchId\n\n\t\tconst previousDefaultPublishStatus = this._defaultHostname?.isPublished\n\t\t\t? PublishStatus.Published\n\t\t\t: PublishStatus.Unpublished\n\t\tconst nextDefaultPublishStatus = nextDefaultHostname?.isPublished\n\t\t\t? PublishStatus.Published\n\t\t\t: PublishStatus.Unpublished\n\n\t\tif (this._defaultHostname !== undefined) {\n\t\t\tthis.notifyPublishStateChange(previousDefaultPublishStatus, nextDefaultPublishStatus, hostnames)\n\t\t}\n\n\t\tthis._defaultHostname = nextDefaultHostname\n\t\tthis._customHostname = nextCustomHostname\n\t\tthis._defaultHostnameDeployment = nextDefaultHostnameDeployment\n\t\tthis._customHostnameDeployment = nextCustomHostnameDeployment\n\t\tif (!branchChanged) {\n\t\t\t// We only update the branch hostname if the branch hasn't changed\n\t\t\t// during the async operations above.\n\t\t\tthis._branchHostname = nextBranchHostname\n\t\t\tthis._branchHostnameDeployment = nextBranchHostnameDeployment\n\t\t}\n\t\tthis._defaultHostnameDeploymentIssues = nextDefaultHostnameIssues\n\t\tthis._customHostnameDeploymentIssues = nextCustomHostnameIssues\n\n\t\tif (customHostnameValidationResult) {\n\t\t\tthis.customHostnameValidationResult = customHostnameValidationResult\n\t\t}\n\n\t\tconst isDefaultHostnameOptimizing = isDeploymentOptimizing(this._defaultHostnameDeployment?.status)\n\t\tconst isBranchHostnameOptimizing = isDeploymentOptimizing(this._branchHostnameDeployment?.status)\n\t\tthis.togglePolling(PollingType.Hostnames, isDefaultHostnameOptimizing || isBranchHostnameOptimizing)\n\n\t\tif (this._publishStatus !== PublishStatus.Publishing) {\n\t\t\tthis.syncPublishStatus()\n\t\t}\n\t}\n\n\tprivate clearActiveBranch(): void {\n\t\tthis._branchHostname = undefined\n\t\tthis._branchHostnameDeployment = undefined\n\t}\n\n\tprivate async loadBranchPublishContext(): Promise<void> {\n\t\tconst branchId = this.treeStore.branchId\n\n\t\tthis.clearActiveBranch()\n\t\tif (this.treeStore.isOnMainBranch()) {\n\t\t\tthis.#loadingBranchPublishContextId = undefined\n\t\t\tthis.syncPublishStatus()\n\t\t\treturn\n\t\t}\n\n\t\t// The branch publish context is always fetched live on branch switches.\n\t\t// Keep status Unknown until hostname and deployment are loaded together.\n\t\tthis._publishStatus = PublishStatus.Unknown\n\n\t\tif (this.#loadingBranchPublishContextId === branchId) return\n\t\tthis.#loadingBranchPublishContextId = branchId\n\n\t\tlet shouldSyncPublishStatus = false\n\t\ttry {\n\t\t\tconst hostname = await getBranchHostname(this._projectId, branchId)\n\t\t\tconst { deployment, ...branchHostname } = hostname\n\t\t\tif (this.treeStore.branchId !== branchId || this.#loadingBranchPublishContextId !== branchId) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis._branchHostname = branchHostname\n\t\t\tassert(deployment, `Expected branch hostname ${branchId} to include deployment`)\n\t\t\tthis._branchHostnameDeployment = {\n\t\t\t\t...mapDeployment(deployment as unknown as ServerDeployment),\n\t\t\t\tprojectId: hostname.projectId,\n\t\t\t}\n\t\t\tshouldSyncPublishStatus = true\n\t\t} catch (err) {\n\t\t\tif (err instanceof ApiError && err.status === 404) {\n\t\t\t\tif (this.treeStore.branchId === branchId && this.#loadingBranchPublishContextId === branchId) {\n\t\t\t\t\tthis.clearActiveBranch()\n\t\t\t\t\tshouldSyncPublishStatus = true\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlog.error(\"getBranchHostname failed\", err)\n\t\t\t}\n\t\t} finally {\n\t\t\tif (this.#loadingBranchPublishContextId === branchId) {\n\t\t\t\tthis.#loadingBranchPublishContextId = undefined\n\t\t\t}\n\t\t\tif (shouldSyncPublishStatus && this.treeStore.branchId === branchId) {\n\t\t\t\tthis.syncPublishStatus()\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Derives `_publishStatus` from the hostname for the active timeline branch. */\n\tprivate syncPublishStatus(): void {\n\t\tif (this._publishStatus === PublishStatus.Publishing) {\n\t\t\treturn\n\t\t}\n\n\t\tconst nextPublishStatus = this.treeStore.isOnMainBranch()\n\t\t\t? this._defaultHostname?.isPublished\n\t\t\t\t? PublishStatus.Published\n\t\t\t\t: PublishStatus.Unpublished\n\t\t\t: this._branchHostname?.isPublished\n\t\t\t\t? PublishStatus.Published\n\t\t\t\t: PublishStatus.Unpublished\n\n\t\t// Local publish sets Published directly after updateState; only external hostname syncs go through here.\n\t\tif (this._publishStatus === PublishStatus.Unpublished && nextPublishStatus === PublishStatus.Published) {\n\t\t\tthis.#suppressNextPublishPopover = true\n\t\t}\n\n\t\tthis._publishStatus = nextPublishStatus\n\t}\n\n\tpostProcess(): void {\n\t\tconst branchId = this.treeStore.branchId\n\t\tif (this.#previousBranchId === branchId) return\n\t\tthis.#previousBranchId = branchId\n\t\tthis.resetVersions()\n\t\tvoid this.loadBranchPublishContext()\n\t}\n\n\tprivate isDocumentLoaded = false\n\n\tdocumentDidLoad() {\n\t\tthis.isDocumentLoaded = true\n\t}\n\n\tasync loadProjectSettings(): Promise<void> {\n\t\tconst {\n\t\t\tsettings: { passwordSettings, deploymentSettings },\n\t\t} = await getProjectSettings(this._projectId)\n\t\tthis._deploymentSettings = deploymentSettings\n\t\tthis._passwordPolicy = passwordSettings.passwordPolicy\n\t\tthis._passwordValue = passwordSettings.passwordValue\n\t}\n\n\t/**\n\t * Returns a paginated list of version deployments for the *current* branch.\n\t * @param limit - The maximum number of versions to return.\n\t * @returns A promise that resolves when the versions have been loaded.\n\t */\n\tasync loadVersions(limit?: number): Promise<void> {\n\t\tawait this.loadProjectSettings()\n\n\t\tif (!this._versionsStream) {\n\t\t\tthis._versionsStream = listVersionDeploymentsStream(this._projectId, limit, this.treeStore.branchId)\n\t\t}\n\n\t\tconst branchId = this.treeStore.branchId\n\t\tconst { value: versions, done } = await this._versionsStream.next()\n\n\t\tif (branchId !== this.treeStore.branchId) {\n\t\t\t// In case the user changed branches while the versions were being fetched, we don't want to update the state\n\t\t\treturn\n\t\t}\n\n\t\tthis._didLoadInitialVersionDeployments = true\n\t\tthis._canLoadMoreVersionDeployments = !done\n\n\t\t// AsyncIterator types aren't 100% safe:\n\t\t//\n\t\t// > After a terminating value has been yielded additional calls to\n\t\t// > next() should continue to return {done: true}\n\t\t//\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#iterators\n\t\t//\n\t\t// In other words, if somebody keeps calling next() after the iterator\n\t\t// has already emitted return value, the value will be undefined.\n\t\t//\n\t\t// For now, let's handle this gracefully and bail, but in general this\n\t\t// smells more like a programming error, and we should fix the Versions\n\t\t// and Analytics tabs racing with each other when managing the loading\n\t\t// of the versions data via useEffect mount/unmount.\n\t\tif (!versions) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.versions = [...this.versions, ...versions]\n\t}\n\n\t/**\n\t * Refreshes the currently-loaded `this.versions` from the API, but\n\t * otherwise doesn't alter the list of versions, i.e., it won't add/remove\n\t * anything to/from the list.\n\t *\n\t * Mostly useful for refreshing the \"Optimizing\" status of the\n\t * currently-loaded versions.\n\t *\n\t * Note: at this time, it'll only do this for the first page of versions.\n\t * It's an implementation shortcut, because it's unlikely that you'll have\n\t * more than one loaded page of versions that are still optimizing, and it\n\t * saves us from multi-page requests.\n\t */\n\tasync refreshVersions(): Promise<void> {\n\t\tif (this.versions.length === 0) {\n\t\t\treturn\n\t\t}\n\n\t\tconst response = await listVersionDeployments(this._projectId, undefined, undefined, this.treeStore.branchId)\n\n\t\tconst newVersions: VersionDeployment[] = []\n\t\tlet anyStatusChanged = false\n\t\tfor (const version of this.versions) {\n\t\t\tconst deploymentWithVersion = response.deployments.find(freshVersion => freshVersion.id === version.id)\n\t\t\tconst newVersion = deploymentWithVersion ? mapDeployment(deploymentWithVersion) : version\n\t\t\tnewVersions.push(newVersion)\n\n\t\t\tanyStatusChanged ||= newVersion.status !== version.status\n\t\t}\n\n\t\t// Optimization: at this time, we only expect the status to change\n\t\t// between API calls, so if none have changed, let's spare ourselves\n\t\t// a re-render.\n\t\tif (!anyStatusChanged) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.versions = newVersions\n\t}\n\n\tresetVersions() {\n\t\tthis._versionsStream = undefined\n\t\tthis._didLoadInitialVersionDeployments = false\n\t\tthis._canLoadMoreVersionDeployments = true\n\t\tthis.versions = []\n\t}\n\n\tget versions(): VersionDeployment[] {\n\t\treturn this._versions\n\t}\n\n\tset versions(versions: VersionDeployment[]) {\n\t\tif (versions.length === 0) {\n\t\t\tthis._versions = versions\n\t\t} else {\n\t\t\t// Make sure we store unique version deployments\n\t\t\tthis._versions = [...new Map(versions.map(version => [version.id, version])).values()]\n\t\t}\n\n\t\tconst isAnyVersionOptimizing = this._versions.some(version => isDeploymentOptimizing(version.status))\n\t\tthis.togglePolling(PollingType.Versions, isAnyVersionOptimizing)\n\t}\n\n\tget canLoadMoreVersionDeployments(): boolean {\n\t\treturn this._canLoadMoreVersionDeployments\n\t}\n\n\tget didLoadInitialVersionDeployments(): boolean {\n\t\treturn this._didLoadInitialVersionDeployments\n\t}\n\n\tpublic async loadHostnames(): Promise<EnrichedHostnameWithDeploymentAndDeploymentId[]> {\n\t\tconst branchId = this.treeStore.branchId\n\t\tconst { hostnames } = await listHostnames(this._projectId, branchId)\n\t\tconst enrichedHostnames = hostnames.map(\n\t\t\t(hostname): EnrichedHostnameWithDeploymentAndDeploymentId => ({\n\t\t\t\t...hostname,\n\t\t\t\tdeployment: mapDeployment(hostname.deployment),\n\t\t\t\tdeploymentId: hostname.deployment.id,\n\t\t\t}),\n\t\t)\n\n\t\t// Ignore stale responses from a previously active branch\n\t\tif (branchId === this.treeStore.branchId) {\n\t\t\tawait this.updateState(enrichedHostnames)\n\t\t}\n\t\treturn enrichedHostnames\n\t}\n\n\tprivate async loadFreeDomains(): Promise<void> {\n\t\tconst { freeDomains } = await listFreeDomains()\n\t\tthis._freeDomains = freeDomains\n\t}\n\n\tget publishStatus(): PublishStatus {\n\t\treturn this._publishStatus\n\t}\n\n\tget recoveryProgress(): RecoveryProgress | undefined {\n\t\treturn this._recoveryProgress\n\t}\n\n\tget defaultHostname(): DefaultHostname | undefined {\n\t\treturn this._defaultHostname\n\t}\n\n\tget branchHostname(): BranchHostname | undefined {\n\t\treturn this._branchHostname\n\t}\n\n\tget defaultHostnameDeployment(): Deployment | undefined {\n\t\treturn this._defaultHostnameDeployment\n\t}\n\n\tget defaultHostnameDeploymentIssues(): GetDeploymentIssuesResponse | undefined {\n\t\treturn this._defaultHostnameDeploymentIssues\n\t}\n\n\tget customHostname(): CustomHostname | undefined {\n\t\treturn this._customHostname\n\t}\n\n\tget customHostnameDeployment(): Deployment | undefined {\n\t\treturn this._customHostnameDeployment\n\t}\n\n\tget branchHostnameDeployment(): Deployment | undefined {\n\t\treturn this._branchHostnameDeployment\n\t}\n\n\tget customHostnameDeploymentIssues(): GetDeploymentIssuesResponse | undefined {\n\t\treturn this._customHostnameDeploymentIssues\n\t}\n\n\tget defaultCanonicalURL(): string | undefined {\n\t\tconst defaultCanonicalHostname = this.customHostname?.hostname ?? this.defaultHostname?.hostname\n\t\tif (defaultCanonicalHostname) {\n\t\t\treturn \"https://\" + defaultCanonicalHostname\n\t\t}\n\n\t\treturn undefined\n\t}\n\n\t#previousCanonicalURL: CanonicalURL | undefined\n\t#suppressNextPublishPopover = false\n\n\tget canonicalURL(): CanonicalURL {\n\t\tconst rootWebMetadata = this.treeStore.tree.root.webMetadata\n\t\tconst canUseCustomCanonicalUrl = this.projectStore.project?.settings.featureFlags.canUseCustomCanonicalUrl === \"on\"\n\t\tconst canUseRewriteCanonicalUrl =\n\t\t\tthis.projectStore.project?.settings.featureFlags.canUseRewriteCanonicalUrl === \"on\"\n\t\tlet canonicalURL: CanonicalURL | undefined\n\n\t\tif (\n\t\t\tcanUseRewriteCanonicalUrl &&\n\t\t\trootWebMetadata?.canonicalURL === \"rewrite\" &&\n\t\t\trootWebMetadata.rewriteCanonicalHostname &&\n\t\t\trootWebMetadata.rewriteCanonicalPath\n\t\t) {\n\t\t\tconst hostname = rootWebMetadata.rewriteCanonicalHostname\n\t\t\tconst path = rootWebMetadata.rewriteCanonicalPath\n\t\t\tassert(hostname, \"Empty rewrite canonical hostname\")\n\t\t\tassert(path, \"Empty rewrite canonical path\")\n\t\t\tcanonicalURL = {\n\t\t\t\ttype: \"rewrite\",\n\t\t\t\turl: `https://${hostname}${path}`,\n\t\t\t}\n\t\t} else if (\n\t\t\tcanUseCustomCanonicalUrl &&\n\t\t\trootWebMetadata?.canonicalURL === \"custom\" &&\n\t\t\trootWebMetadata.customCanonicalURL\n\t\t) {\n\t\t\tcanonicalURL = {\n\t\t\t\ttype: \"custom\",\n\t\t\t\turl: rootWebMetadata.customCanonicalURL,\n\t\t\t}\n\t\t} else {\n\t\t\tcanonicalURL = { type: \"default\", url: this.defaultCanonicalURL }\n\t\t}\n\n\t\tif (this.#previousCanonicalURL && isShallowObjectEqual(this.#previousCanonicalURL, canonicalURL)) {\n\t\t\treturn this.#previousCanonicalURL\n\t\t}\n\n\t\tthis.#previousCanonicalURL = canonicalURL\n\t\treturn canonicalURL\n\t}\n\n\tprivate getPermissionRequiredForPublish({\n\t\tpublishToProduction = false,\n\t}: { publishToProduction?: boolean } = {}): keyof ExtendedPermissions {\n\t\tif (publishToProduction) return \"canPublish\"\n\n\t\tconst hasCustomDomain = this.customHostname && this.customHostnameDeployment\n\t\tconst stagingEnabled = this.deploymentStrategy === DeploymentStrategy.Manual\n\t\treturn hasCustomDomain && stagingEnabled ? \"canPublishToStaging\" : \"canPublish\"\n\t}\n\n\tpublic hasPublishPermission({ publishToProduction = false }: { publishToProduction?: boolean } = {}): boolean {\n\t\treturn !this.isViewOnly(this.getPermissionRequiredForPublish({ publishToProduction }))\n\t}\n\n\tcanPublish(): boolean {\n\t\t// Never allow publishing when the document is view-only or user has no permissions\n\t\tif (!this.hasPublishPermission()) {\n\t\t\treturn false\n\t\t}\n\n\t\tif (\n\t\t\tgetPublishBlockingUpsell({\n\t\t\t\tprojectStore: this.projectStore,\n\t\t\t\ttree: this.treeStore.tree,\n\t\t\t\tpublishStore: this,\n\t\t\t})\n\t\t) {\n\t\t\treturn false\n\t\t}\n\n\t\treturn this.readyToPublish\n\t}\n\n\tpublic shouldShowPublishSheetOnPublish(previousPublishStatus: PublishStatus): boolean {\n\t\tconst hasJustPublished =\n\t\t\tpreviousPublishStatus === PublishStatus.Unpublished && this.publishStatus === PublishStatus.Published\n\t\tif (!hasJustPublished) return false\n\t\tif (!this.#suppressNextPublishPopover) return true\n\t\tthis.#suppressNextPublishPopover = false\n\t\treturn false\n\t}\n\n\tget readyToPublish(): boolean {\n\t\tif (!this.isDocumentLoaded) return false\n\t\treturn (\n\t\t\t(this.getHomeNode() !== null && this.publishStatus === PublishStatus.Published) ||\n\t\t\tthis.publishStatus !== PublishStatus.Unknown\n\t\t)\n\t}\n\n\t/** True while the branch hostname/deployment is being fetched after a branch switch. */\n\tget isLoadingBranchPublishContext(): boolean {\n\t\treturn this.#loadingBranchPublishContextId !== undefined\n\t}\n\n\tget freeDomains(): string[] {\n\t\treturn this._freeDomains\n\t}\n\n\tisFreeDomain(domain: string): boolean {\n\t\treturn this.freeDomains.some(freeDomain => domain.endsWith(`.${freeDomain}`))\n\t}\n\n\tget passwordValue(): string | undefined {\n\t\treturn this._passwordValue\n\t}\n\n\tget passwordPolicy(): PasswordPolicy {\n\t\treturn this._passwordPolicy || PasswordPolicy.Off\n\t}\n\n\tget deploymentStrategy(): DeploymentStrategy | undefined {\n\t\treturn this._deploymentSettings?.deploymentStrategy\n\t}\n\n\tget deploymentSettings(): DeploymentSettings | undefined {\n\t\treturn this._deploymentSettings\n\t}\n\n\thasBadge() {\n\t\t// Always show it for drafts (Which are still used when projects are created via the tutorial).\n\t\t//\n\t\t// TODO: Change this in the backend, then remove this branch:\n\t\t// https://github.com/framer/FramerWebApi/blob/46545512bc74deaa04d84d183da1def6bb38edcc/src/lib/projects/getProjectsSettings.ts#L61\n\t\tif (this.projectStore.isDraft) {\n\t\t\treturn true\n\t\t}\n\n\t\t// Else, check the project settings\n\t\treturn this.projectStore.project?.settings.featureFlags.showBannerOnPublishedSite === \"on\"\n\t}\n\n\tasync updateProjectSettings(update: Partial<ProjectSettings>): Promise<void> {\n\t\tconst oldDeploymentSettings = this._deploymentSettings\n\t\tconst oldPasswordPolicy = this._passwordPolicy\n\n\t\ttry {\n\t\t\t// Optimistic UI update.\n\t\t\tif (update.deploymentSettings) {\n\t\t\t\tthis._deploymentSettings = update.deploymentSettings\n\t\t\t}\n\t\t\tif (update.passwordSettings?.passwordPolicy) {\n\t\t\t\tthis._passwordPolicy = update.passwordSettings.passwordPolicy\n\t\t\t}\n\n\t\t\tconst {\n\t\t\t\tsettings: { deploymentSettings, passwordSettings },\n\t\t\t} = await updateProjectSettings(this._projectId, update)\n\t\t\tthis._deploymentSettings = deploymentSettings\n\t\t\tthis._passwordPolicy = passwordSettings.passwordPolicy\n\n\t\t\tif (update.passwordSettings?.passwordPolicy) {\n\t\t\t\tconst enabled = update.passwordSettings.passwordPolicy !== PasswordPolicy.Off\n\t\t\t\ttoast({\n\t\t\t\t\ttype: \"add\",\n\t\t\t\t\tvariant: \"success\",\n\t\t\t\t\tkey: \"toggle-password\",\n\t\t\t\t\tprimaryText: enabled ? \"Password added\" : \"Password removed\",\n\t\t\t\t\tsecondaryText: enabled ? \"to the website.\" : \"from the website.\",\n\t\t\t\t\ticon: \"success\",\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tif (passwordSettings.passwordPolicy !== PasswordPolicy.Off) {\n\t\t\t\tthis._passwordValue = passwordSettings.passwordValue\n\t\t\t}\n\n\t\t\tthis.notifyProjectChange(\"settings\")\n\t\t} catch {\n\t\t\tif (update.deploymentSettings) {\n\t\t\t\tthis._deploymentSettings = oldDeploymentSettings\n\t\t\t}\n\t\t\tif (update.passwordSettings?.passwordPolicy) {\n\t\t\t\tthis._passwordPolicy = oldPasswordPolicy\n\t\t\t\tconst wantedToEnable = update.passwordSettings.passwordPolicy !== PasswordPolicy.Off\n\t\t\t\ttoast({\n\t\t\t\t\ttype: \"add\",\n\t\t\t\t\tvariant: \"error\",\n\t\t\t\t\tkey: \"toggle-password\",\n\t\t\t\t\tprimaryText: wantedToEnable ? \"Failed to add password\" : \"Failed to remove password\",\n\t\t\t\t\tsecondaryText: wantedToEnable ? \"to the website.\" : \"from the website.\",\n\t\t\t\t\ticon: \"error\",\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate isExternalUpdate({\n\t\tnextDefaultHostnameDeploymentId,\n\t\tcurrentDefaultHostnameDeploymentId,\n\t\tnextBranchHostnameDeploymentId,\n\t\tcurrentBranchHostnameDeploymentId,\n\t}: {\n\t\tnextDefaultHostnameDeploymentId: string | null\n\t\tcurrentDefaultHostnameDeploymentId: string | null\n\t\tnextBranchHostnameDeploymentId: string | null\n\t\tcurrentBranchHostnameDeploymentId: string | null\n\t}): boolean {\n\t\tif (this.treeStore.isOnMainBranch()) {\n\t\t\treturn Boolean(\n\t\t\t\tnextDefaultHostnameDeploymentId &&\n\t\t\t\tcurrentDefaultHostnameDeploymentId &&\n\t\t\t\tnextDefaultHostnameDeploymentId !== currentDefaultHostnameDeploymentId,\n\t\t\t)\n\t\t}\n\n\t\treturn Boolean(\n\t\t\tnextBranchHostnameDeploymentId &&\n\t\t\tcurrentBranchHostnameDeploymentId &&\n\t\t\tnextBranchHostnameDeploymentId !== currentBranchHostnameDeploymentId,\n\t\t)\n\t}\n\n\tprivate notifyPublishStateChange(\n\t\tpreviousDefaultPublishStatus: PublishStatus,\n\t\tnextDefaultPublishStatus: PublishStatus,\n\t\tnextHostnames: EnrichedHostnameWithDeployment[],\n\t): void {\n\t\tif (\n\t\t\tpreviousDefaultPublishStatus === PublishStatus.Published &&\n\t\t\tnextDefaultPublishStatus === PublishStatus.Unpublished\n\t\t) {\n\t\t\t// External unpublish, show toast\n\t\t\ttoast({\n\t\t\t\ticon: \"success\",\n\t\t\t\tvariant: \"success\",\n\t\t\t\tkey: \"unpublish-success\",\n\t\t\t\tprimaryText: \"A collaborator\",\n\t\t\t\tsecondaryText: \"unpublished this project.\",\n\t\t\t\ttype: \"add\",\n\t\t\t})\n\t\t\t// On the off chance the site gets unpublished while setting a password,\n\t\t\t// reset it to the previous value.\n\t\t\tthis._passwordValue = this.passwordValue\n\t\t\treturn\n\t\t}\n\n\t\tconst nextDefaultHostnameWithDeployment = nextHostnames.find(hostname => hostname.type === HostnameType.Default)\n\t\tconst nextDefaultHostnameDeploymentId = nextDefaultHostnameWithDeployment?.deployment.id ?? null\n\t\tconst currentDefaultHostnameDeploymentId = this._defaultHostname?.deploymentId ?? null\n\t\tconst nextBranchHostnameWithDeployment = nextHostnames.find(\n\t\t\thostname => hostname.type === HostnameType.Branch && hostname.branchId === this.treeStore.branchId,\n\t\t)\n\t\tconst nextBranchHostnameDeploymentId = nextBranchHostnameWithDeployment?.deployment.id ?? null\n\t\tconst currentBranchHostnameDeploymentId = this._branchHostname?.deploymentId ?? null\n\t\tconst isExternalUpdate = this.isExternalUpdate({\n\t\t\tnextDefaultHostnameDeploymentId,\n\t\t\tcurrentDefaultHostnameDeploymentId,\n\t\t\tnextBranchHostnameDeploymentId,\n\t\t\tcurrentBranchHostnameDeploymentId,\n\t\t})\n\n\t\tif (\n\t\t\t(previousDefaultPublishStatus === PublishStatus.Unpublished &&\n\t\t\t\tnextDefaultPublishStatus === PublishStatus.Published) ||\n\t\t\tisExternalUpdate\n\t\t) {\n\t\t\t// External publish, show toast.\n\t\t\t// Pre-compute the URL so the onClick closure captures a string\n\t\t\t// instead of `this` (whose driver \u2192 scheduler chain would be retained).\n\t\t\tconst toastHostname = this.externalPublishToastHostname(nextHostnames)\n\t\t\tconst openLinkURL = toastHostname ? this.getActiveWebPageURL(toastHostname) : undefined\n\t\t\tconst action: ToastAction | undefined = openLinkURL ? createOpenLinkToastAction(openLinkURL) : undefined\n\n\t\t\tthis.showPublishSuccessToast({\n\t\t\t\tprimaryText: \"A collaborator\",\n\t\t\t\tsecondaryText: \"published this project.\",\n\t\t\t\taction,\n\t\t\t})\n\t\t}\n\t}\n\n\tprivate externalPublishToastHostname(nextHostnames: EnrichedHostnameWithDeployment[]): string | undefined {\n\t\tif (!this.treeStore.isOnMainBranch()) {\n\t\t\tconst branchHostname = nextHostnames.find(\n\t\t\t\thostname => hostname.type === HostnameType.Branch && hostname.branchId === this.treeStore.branchId,\n\t\t\t)\n\t\t\treturn branchHostname?.hostname ?? this._branchHostname?.hostname\n\t\t}\n\n\t\treturn nextHostnames.find(hostname => hostname.type === HostnameType.Default)?.hostname\n\t}\n\n\tprivate showPublishSuccessToast({\n\t\ttext,\n\t\tprimaryText,\n\t\tsecondaryText,\n\t\taction,\n\t\tduration,\n\t}: {\n\t\ttext?: ReactNode\n\t\tprimaryText?: ReactNode\n\t\tsecondaryText?: ReactNode\n\t\taction?: ToastAction\n\t\tduration?: number\n\t}) {\n\t\t// Remove the previous publish toast if it exists to force a new one to animate in.\n\t\tif (this._latestPublishSuccessToastKey) {\n\t\t\ttoast({ type: \"remove\", key: this._latestPublishSuccessToastKey })\n\t\t}\n\t\tconst publishToastKey = `publish-success-${randomBase62(8)}`\n\t\tthis._latestPublishSuccessToastKey = publishToastKey\n\t\ttoast({\n\t\t\ttype: \"add\",\n\t\t\tvariant: \"success\",\n\t\t\ttext,\n\t\t\tprimaryText,\n\t\t\tsecondaryText,\n\t\t\tkey: publishToastKey,\n\t\t\ticon: \"success\",\n\t\t\taction,\n\t\t\tduration,\n\t\t})\n\t}\n\n\tgetHomeNode(): ShallowWebPageNode | null {\n\t\tconst tree = this.treeStore.getDataTreeOrPartialTree()\n\t\tconst rootNode = tree.root\n\t\tif (!rootNode.homePageNodeId) return null\n\t\tconst homePage = tree.getNode(rootNode.homePageNodeId)\n\t\treturn isWebPageNode(homePage) ? homePage : null\n\t}\n\n\tgetErrors(options?: {\n\t\tmissingExternalModules?: Set<ExternalModuleExportIdentifierString>\n\t\tincludeShallowScopeErrors?: boolean\n\t\tincludeStaleModules?: boolean\n\t}): PublishError[] {\n\t\tconst { missingExternalModules, includeShallowScopeErrors = false } = options ?? {}\n\t\tconst seenNodeIds = new Set<NodeID | undefined>()\n\t\tconst errors: PublishError[] = []\n\t\t// We may encounter multiple webpages or smart components that all are\n\t\t// missing the same module. In that case we just want to show the first\n\t\t// smart component or webpage that is missing it, rather than overwhelming\n\t\t// customers with duplicate errors.\n\t\tconst seenModuleIdentifiers = new Set<string | undefined>()\n\t\tconst missingExportNames = new Map<string, string>()\n\n\t\t// First, iterate through the errors in the component loader. This may\n\t\t// include errors that were or were not caught during code-generation, but\n\t\t// may still result in a code-generated module failing to evaluate. For\n\t\t// example, a code component or an override can have it's export renamed or\n\t\t// deleted after code-generation completes, resulting in a broken webpage or\n\t\t// smart component. This doesn't account for missing modules. If those\n\t\t// weren't caught during code-generation, they won't effect publishing.\n\t\tfor (const entity of this.componentLoader.getAllEntities()) {\n\t\t\tif (!isErrorDefinition(entity)) continue\n\n\t\t\tconst parsed = parseModuleIdentifier(entity.identifier)\n\t\t\tif (!isLocalModuleIdentifier(parsed) || parsed.type !== ModuleType.Screen) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst scope = this.treeStore.tree.get(parsed.localIdName)\n\t\t\tif (!isWebPageNode(scope)) continue\n\n\t\t\tconst missingModulesInWebPage: PublishError[] = []\n\n\t\t\tconst isLoadedScope = scope.isLoaded()\n\t\t\tif (isLoadedScope) {\n\t\t\t\taddErrorsForMissingModulesInScope(\n\t\t\t\t\tthis.treeStore.tree,\n\t\t\t\t\tthis.componentLoader,\n\t\t\t\t\tscope,\n\t\t\t\t\tmissingModulesInWebPage,\n\t\t\t\t\tmissingExternalModules,\n\t\t\t\t\tseenModuleIdentifiers,\n\t\t\t\t\tmissingExportNames,\n\t\t\t\t\tnew Set([scope.id]),\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tif (missingModulesInWebPage.length > 0) {\n\t\t\t\t// If we detected any descendant errors, those are probably the\n\t\t\t\t// reason the webpage isn't evaluating.\n\t\t\t\terrors.push(...missingModulesInWebPage)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst exportName = getMissingExportName(entity?.error)\n\t\t\tif (isString(exportName)) {\n\t\t\t\tconst existingErrorExport = missingExportNames.get(entity.error)\n\t\t\t\tif (existingErrorExport === exportName) continue\n\t\t\t\tmissingExportNames.set(entity.error, exportName)\n\t\t\t}\n\n\t\t\t// Otherwise there is an error in the webpage.\n\t\t\terrors.push({\n\t\t\t\ttype: isString(exportName) ? \"component\" : \"unknown\",\n\t\t\t\t// @todo: use `unsafeGetBaseVariantId` once it's available\n\t\t\t\tnodeId: isLoadedScope ? scope.baseVariantId : scope.id,\n\t\t\t\tscopeId: scope.id,\n\t\t\t\treason: ErrorNodeReason.CodeError,\n\t\t\t\tmoduleIdentifier: scope.instanceIdentifier,\n\t\t\t\texportName,\n\t\t\t})\n\t\t}\n\n\t\t// Next, iterate through the errors recorded to the tree. These will be\n\t\t// errors encountered during code-generation, or when changing form\n\t\t// destinations. They may result in errors in the component loader too, so\n\t\t// we must track the identifier so we don't add the same errors twice.\n\t\tthis.treeStore.tree.get<ErrorListNode>(ERROR_LIST_NODE_ID)?.children?.forEach(node => {\n\t\t\tif (seenNodeIds.has(node.nodeId) || seenModuleIdentifiers.has(node.moduleIdentifier)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!node.nodeId || !node.scopeId || this.treeStore.tree.root.id === node.scopeId) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// It's not possible to show errors when we don't know the collection.\n\t\t\t// This filters out errors that were incorrectly recorded in the past.\n\t\t\t// We could choose to migrate these out in the future.\n\t\t\tif (node.scopeId === CONTENT_MANAGEMENT_ID && isUndefined(node.sourceNodeId)) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Don't show errors for deleted nodes.\n\t\t\tconst scope = this.treeStore.tree.get(node.scopeId)\n\t\t\tif (!scope) return\n\n\t\t\tconst isInLoadedScope = isScopeNode(scope) && scope.isLoaded()\n\t\t\tif (!isInLoadedScope && !includeShallowScopeErrors) return\n\t\t\tif (isInLoadedScope && !this.treeStore.tree.has(node.nodeId)) return\n\t\t\t// Ignore errors for nodes that are no longer in the original source node.\n\t\t\tif (isInLoadedScope && this.treeStore.treeIndex.getScopeIdFor(node.nodeId) !== node.scopeId) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Skip errors that can't be categorized.\n\t\t\tconst type = errorTypeForNode(this.treeStore.tree, node, includeShallowScopeErrors)\n\t\t\tif (isUndefined(type)) return\n\n\t\t\t// Provide a more specific export name if possible. We don't skip duplicate export names\n\t\t\t// because we don't know if they are missing from the same module.\n\t\t\tconst exportName = isModuleExportIdentifier(node.moduleIdentifier)\n\t\t\t\t? parseModuleIdentifier(node.moduleIdentifier)?.exportSpecifier\n\t\t\t\t: undefined\n\n\t\t\terrors.push({\n\t\t\t\ttype,\n\t\t\t\tnodeId: node.nodeId,\n\t\t\t\tscopeId: node.scopeId,\n\t\t\t\treason: node.reason,\n\t\t\t\tmoduleIdentifier: node.moduleIdentifier,\n\t\t\t\texportName: exportName !== \"default\" ? exportName : undefined,\n\t\t\t})\n\n\t\t\t// Only record a module or node as seen if it is included in the list.\n\t\t\tseenModuleIdentifiers.add(node.moduleIdentifier)\n\t\t\tseenNodeIds.add(node.nodeId)\n\t\t})\n\n\t\tif (!options?.includeStaleModules || !experiments.isOn(\"publishStaleModuleErrors\")) return errors\n\n\t\t// Finally, add errors for any out of date modules.\n\t\t//\n\t\t// Only check this if we have already done a pass where we update all\n\t\t// stale modules if we can. The remaining nodes here should be nodes\n\t\t// that are throwing during serialization/compilation and can't be\n\t\t// persisted.\n\t\tfor (const node of this.getNodesWithStaleModulesForPublish({\n\t\t\tignoreHint: true,\n\t\t})) {\n\t\t\tif (\n\t\t\t\tseenNodeIds.has(node.id) ||\n\t\t\t\t(hasInstanceIdentifier(node) && seenModuleIdentifiers.has(node.instanceIdentifier))\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\terrors.push({\n\t\t\t\ttype: \"code-generation\",\n\t\t\t\tnodeId: node.id,\n\t\t\t\tscopeId: node.id,\n\t\t\t\treason: STALE_MODULE_ERROR_REASON,\n\t\t\t\tmoduleIdentifier: hasInstanceIdentifier(node) ? node.instanceIdentifier : undefined,\n\t\t\t})\n\t\t}\n\n\t\treturn errors\n\t}\n\n\t#lastPublishRevisions: Record<number, PublishRevisions> = {}\n\n\t/**\n\t * Get the current moduleSourceRevision of every node that calculates its\n\t * own revision, compare that to the revisions of these nodes during the\n\t * last publish, ensuring that any pending revisions are synchronously\n\t * calculated. This allows us to know the exact number of changed modules\n\t * without awaiting code-generation.\n\t */\n\tgetPublishRevisions(): PublishRevisions {\n\t\t// If the tree hasn't changed, reuse the last result.\n\t\tconst lastResult = this.#lastPublishRevisions[this.treeStore.timeline.remoteTreeVersion]\n\t\tif (lastResult) return lastResult\n\t\tthis.#lastPublishRevisions = {}\n\n\t\tconst tree = this.treeStore.getDataTreeOrPartialTree()\n\n\t\tconst currentRevisionNodes = this.codeGenerationStore.revisionNodes(tree)\n\t\tconst hasPreviousRevisions = !isUndefined(tree.root.publishRevisions)\n\t\tconst previousRevisions = tree.root.publishRevisions || {}\n\t\tconst previousPaths = tree.root.publishPaths || {}\n\t\tconst nextRevisions: Record<NodeID, number | null> = {}\n\t\tconst nextPaths: Record<NodeID, string> = {}\n\n\t\tconst added = new Set<NodeID>()\n\t\tconst changes = new Set<NodeID>()\n\t\tconst start = performance.now()\n\t\tconst deleted = new Set<string>(Object.keys(previousRevisions))\n\n\t\tconst pendingChanges = new Set<NodeID>()\n\n\t\tfor (const node of currentRevisionNodes) {\n\t\t\t// @TODO - Temporarily skip these since we don't show changes from\n\t\t\t// the diffs for them. In the future we should show changes for\n\t\t\t// these node types.\n\t\t\tif (isStylePresetNode(node) || isPresetsListNode(node) || isCollectionNode(node)) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (deleted.has(node.id)) deleted.delete(node.id)\n\t\t\tnextRevisions[node.id] = node.moduleSourceRevision ?? null\n\t\t\tif (isWebPageNode(node)) {\n\t\t\t\tnextPaths[node.id] = getRawWebPagePath(tree, node) ?? FALLBACK_PATH\n\t\t\t}\n\n\t\t\tconst previousRevision = previousRevisions[node.id]\n\t\t\tif (node.id in previousRevisions) {\n\t\t\t\tif (node.moduleSourceRevisionHint !== node.moduleSourceRevisionCommittedHint) {\n\t\t\t\t\tpendingChanges.add(node.id)\n\t\t\t\t} else if (\n\t\t\t\t\t(isNumber(node.moduleSourceRevision) && previousRevision !== node.moduleSourceRevision) ||\n\t\t\t\t\tpreviousPaths[node.id] !== nextPaths[node.id]\n\t\t\t\t) {\n\t\t\t\t\tchanges.add(node.id)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tadded.add(node.id)\n\t\t\t}\n\t\t}\n\n\t\tconst routesNode = RoutesNode.get(this.treeStore.tree)\n\t\tconst proxies = routesNode?.loaded?.getProxyRoutes() ?? []\n\n\t\tfor (const node of proxies) {\n\t\t\tif (deleted.has(node.id)) deleted.delete(node.id)\n\t\t\tconst revision = calculateRouteRevision(node)\n\t\t\tnextRevisions[node.id] = revision ?? null\n\t\t\tconst previousRevision = previousRevisions[node.id]\n\t\t\tif (node.id in previousRevisions) {\n\t\t\t\tif (isNumber(previousRevision) && previousRevision !== revision) {\n\t\t\t\t\tchanges.add(node.id)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tadded.add(node.id)\n\t\t\t}\n\t\t}\n\n\t\tfor (const id of pendingChanges) {\n\t\t\tconst node = tree.get(id)\n\t\t\tassert(node && usesModuleRevision(node, tree), \"Pending changes should use module revision.\")\n\t\t\tif (isScopeNode(node) && !node.isLoaded()) continue\n\t\t\tconst nextRevision = (nextRevisions[id] = calculateModuleRevision(node, tree) ?? null)\n\t\t\tif (previousRevisions[id] !== nextRevision) changes.add(id)\n\t\t}\n\n\t\t// The order of these defines the order of the output.\n\t\tconst groups: Record<ChangeType, ProjectChange[]> = {\n\t\t\t[ChangeType.LayoutTemplate]: [],\n\t\t\t[ChangeType.WebPage]: [],\n\t\t\t[ChangeType.SmartComponent]: [],\n\t\t\t[ChangeType.CollectionItem]: [],\n\t\t\t[ChangeType.ProxyRoute]: [],\n\t\t}\n\n\t\tfor (const id of changes) {\n\t\t\tconst node = tree.get(id)\n\t\t\tif (!node) continue\n\t\t\tconst change = getNodeChange(node, ChangeStatus.Updated, tree, this.componentLoader)\n\t\t\tif (!change) continue\n\t\t\tgroups[change.type].push(change)\n\t\t}\n\n\t\tfor (const id of added) {\n\t\t\tconst node = tree.get(id)\n\t\t\tif (!node) continue\n\t\t\tconst change = getNodeChange(node, ChangeStatus.Added, tree, this.componentLoader)\n\t\t\tif (!change) continue\n\n\t\t\tgroups[change.type].push(change)\n\t\t}\n\n\t\tfor (const id of deleted) {\n\t\t\tconst change = getRemovedChange(id, tree, this.componentLoader, previousPaths[id])\n\t\t\tif (!change) continue\n\n\t\t\tgroups[change.type].push(change)\n\t\t}\n\n\t\tconst allChanges = sortedChangesFromGroups(groups)\n\n\t\tlog.debug(\"Calculated changelog in\", performance.now() - start, \"ms\", {\n\t\t\tchanges,\n\t\t\tadded,\n\t\t\tdeleted,\n\t\t\tpending: pendingChanges,\n\t\t\tnextRevisions,\n\t\t})\n\n\t\treturn (this.#lastPublishRevisions[this.treeStore.timeline.remoteTreeVersion] = {\n\t\t\tchanges: allChanges,\n\t\t\tnextRevisions,\n\t\t\tnextPaths,\n\t\t\tcount: hasPreviousRevisions ? allChanges.length : null,\n\t\t})\n\t}\n\n\tprivate getPublishChanges({ patchedNodeIds }: { patchedNodeIds: readonly string[] | undefined }) {\n\t\tlet publishRevisions: PublishRevisions | undefined\n\t\tlet changes: ProjectChange[] | undefined\n\t\tif (!patchedNodeIds) {\n\t\t\t// After creating the html, once all modules are up to date, get the\n\t\t\t// module source revisions of all nodes that support them. After a\n\t\t\t// successful publish, we store these in the tree. This allows us to\n\t\t\t// tell what nodes have changed since the last publish.\n\t\t\tpublishRevisions = this.getPublishRevisions()\n\t\t\tchanges = publishRevisions.changes\n\t\t} else {\n\t\t\tchanges = computePatchedChanges(patchedNodeIds, this.treeStore.tree, this.componentLoader)\n\t\t}\n\n\t\tlet changeSummary: string | undefined\n\t\tif (changes) {\n\t\t\ttry {\n\t\t\t\tchangeSummary = serialiseChanges(changes)\n\t\t\t} catch (error) {\n\t\t\t\tlog.reportError(error)\n\t\t\t}\n\t\t}\n\n\t\treturn { publishRevisions, changeSummary }\n\t}\n\n\t#recoveryPromise: Promise<PublishError[]> | undefined\n\t#recoveryMetrics = {\n\t\tprePublishLoadShallowScopesMs: 0,\n\t\tprePublishCatchUpWebPagesMs: 0,\n\t\tprePublishRecoverModulesMs: 0,\n\t\tprePublishPreloadExternalModulesMs: 0,\n\t}\n\n\t/**\n\t * A subset of nodes that are critical to publishing that must be guaranteed to be up to date\n\t * before publishing.\n\t *\n\t * @TODO - Consider removing the filter here and considering all out of date nodes that are part\n\t * of the dependency graph of a site.\n\t */\n\tgetNodesWithStaleModulesForPublish(options?: { ignoreHint?: boolean }) {\n\t\treturn this.codeGenerationStore.nodesWithStaleModules(node => {\n\t\t\treturn (\n\t\t\t\tisWebPageNode(node) ||\n\t\t\t\tisSmartComponentNode(node) ||\n\t\t\t\tisCollectionNode(node) ||\n\t\t\t\tisPresetsListNode(node) ||\n\t\t\t\tisStylePresetNode(node) ||\n\t\t\t\tisCustomCodeScopeNode(node)\n\t\t\t)\n\t\t}, options)\n\t}\n\n\t/**\n\t * When the publish popover is opened, we want to eagerly prepare for\n\t * publishing. That includes 2 steps:\n\t * 1. Make sure any out of date web pages are caught up. In the future this\n\t *    should probably be all generated modules, not just web pages.\n\t * 2. If there are errors for generated modules, predict if any are\n\t *    recoverable by regenerating, and try to regenerate.\n\t *\n\t * Finally we can show errors in the publish popover that a customer will\n\t * need to resolve before publishing.\n\t */\n\tasync prepareForPublishing(\n\t\toutOfDateWebPagesAndComponents: (\n\t\t\t| AnyWebPageNode\n\t\t\t| AnySmartComponentNode\n\t\t\t| CollectionNode\n\t\t\t| StylePresetNode\n\t\t\t| PresetsListNode\n\t\t\t| AnyCustomCodeScopeNode\n\t\t)[] = this.getNodesWithStaleModulesForPublish(),\n\t\tpredictedRecoverableSourceNodeIds?: NodeID[],\n\t\tmissingExternalModules?: ExternalModuleExportIdentifierString[],\n\t) {\n\t\t// If we are already performing a recovery, return the promise for that recovery.\n\t\tif (this.#recoveryPromise) return this.#recoveryPromise\n\n\t\tconst promise = new ResolvablePromise<PublishError[]>()\n\t\tthis.#recoveryPromise = promise\n\n\t\tconst loader = this.treeStore.tree.getService(\"loader\")\n\t\tif (loader && !this.treeStore.getDataTree()) {\n\t\t\tconst shallowScopes = loader.numberOfScopesToLoad()\n\t\t\tif (shallowScopes) {\n\t\t\t\tconst startTime = performance.now()\n\t\t\t\tloader.prioritizeLoadingAllData({\n\t\t\t\t\toperationInBackground: true,\n\t\t\t\t\toperationName: \"prepare_for_publish\",\n\t\t\t\t})\n\t\t\t\tawait loader.afterAllDataLoaded()\n\t\t\t\tconst durationMs = Math.round(performance.now() - startTime)\n\t\t\t\tthis.#recoveryMetrics.prePublishLoadShallowScopesMs += durationMs\n\t\t\t\trecord(\"load_shallow_scopes_before_publish\", {\n\t\t\t\t\tdurationMs,\n\t\t\t\t\tshallowScopes,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst { codeGenerationStore, modulesStore, treeStore } = this\n\n\t\t// Wait for modules to be initialized.\n\t\tawait modulesStore.whenInitialized()\n\n\t\tlet shaderFallbackUpdatedScopeIds = new Set<NodeID>()\n\t\ttry {\n\t\t\tshaderFallbackUpdatedScopeIds = await this.shaderFallbackImageStore.ensureFallbackImagesUpToDate()\n\t\t} catch (error) {\n\t\t\tlog.warn(\"Failed to generate shader fallback images before publish\", error)\n\t\t}\n\n\t\t{\n\t\t\tconst start = performance.now()\n\n\t\t\t// Fallback image writes bypass module revision hints, so explicitly\n\t\t\t// regenerate the affected source modules before publishing.\n\t\t\tif (shaderFallbackUpdatedScopeIds.size > 0) {\n\t\t\t\tawait Promise.all(\n\t\t\t\t\t[...shaderFallbackUpdatedScopeIds].map(scopeId =>\n\t\t\t\t\t\tcodeGenerationStore.forceComponentUpdate(scopeId).catch(unhandledError),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t}\n\n\t\t\t// Wait for all nodes to be generated.\n\t\t\tawait codeGenerationStore.generateAndUpdateQueuedComponents()\n\n\t\t\t// Ensure any missing modules are generated at least once before updating existing\n\t\t\t// modules.\n\t\t\tawait codeGenerationStore.ensureDependencyModulesExist()\n\n\t\t\t// Update out of date web page and smart components if they have\n\t\t\t// changed.\n\t\t\tawait Promise.all(\n\t\t\t\toutOfDateWebPagesAndComponents.map(node =>\n\t\t\t\t\tcodeGenerationStore.updateComponent(node.id, GenerationCondition.Changed).catch(unhandledError),\n\t\t\t\t),\n\t\t\t)\n\n\t\t\t// Ensure the ErrorListNode is up to date after updating webpages.\n\t\t\tawait codeGenerationStore.persistence.process()\n\n\t\t\tconst durationMs = Math.round(performance.now() - start)\n\t\t\tthis.#recoveryMetrics.prePublishCatchUpWebPagesMs += durationMs\n\t\t\trecord(\"catch_up_modules_before_publish\", {\n\t\t\t\tdurationMs,\n\t\t\t\toutOfDateWebPages: outOfDateWebPagesAndComponents.length,\n\t\t\t})\n\t\t}\n\n\t\tconst tree = treeStore.getDataTreeOrLoadedTree()\n\n\t\t// Ensure any missing external modules are evaluated before predicting\n\t\t// recoverable errors.\n\t\t{\n\t\t\tconst start = performance.now()\n\t\t\tawait preloadMissingExternalModuleErrors(\n\t\t\t\ttree,\n\t\t\t\tthis.componentLoader,\n\t\t\t\tmodulesStore,\n\t\t\t\tmissingExternalModules?.map(id => parseModuleIdentifier(id)),\n\t\t\t)\n\t\t\tconst durationMs = Math.round(performance.now() - start)\n\t\t\tthis.#recoveryMetrics.prePublishPreloadExternalModulesMs += durationMs\n\t\t\trecord(\"preload_external_modules_before_publish\", { durationMs })\n\t\t}\n\n\t\t// We won't have predicted the recoverable modules if we couldn't do it\n\t\t// synchronously in the publish sheet's initial render. In that case, we\n\t\t// can predict them now having done the async work earlier in this\n\t\t// method.\n\t\tconst recoveryStart = performance.now()\n\t\tpredictedRecoverableSourceNodeIds ??= predictRecoverableOrderedSourceNodes(tree, this.componentLoader)\n\n\t\tif (!predictedRecoverableSourceNodeIds?.length) {\n\t\t\tconst errors = this.getErrors({ includeStaleModules: true })\n\t\t\tpromise.resolve(errors)\n\t\t\tthis.#recoveryPromise = undefined\n\t\t\treturn errors\n\t\t}\n\n\t\t// Try to recover from all errors in order. The predicted order allows\n\t\t// dependencies that failed to be evaluated to be regenerated first so\n\t\t// that dependents can read them in the component loader when they\n\t\t// themselves are regenerated.\n\t\tif (experiments.isOn(\"publishingRecoveryProgress\")) {\n\t\t\tthis._recoveryProgress = { phase: \"regeneration\", total: predictedRecoverableSourceNodeIds.length, completed: 0 }\n\n\t\t\tfor (const nodeId of predictedRecoverableSourceNodeIds) {\n\t\t\t\tawait codeGenerationStore.updateComponent(nodeId, GenerationCondition.Forced)\n\t\t\t\tthis._recoveryProgress = {\n\t\t\t\t\tphase: \"regeneration\",\n\t\t\t\t\ttotal: this._recoveryProgress.total,\n\t\t\t\t\tcompleted: this._recoveryProgress.completed + 1,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst persistenceQueueSize = codeGenerationStore.persistence.size\n\t\t\tif (persistenceQueueSize > 0) {\n\t\t\t\tthis._recoveryProgress = { phase: \"persistence\", total: persistenceQueueSize, completed: 0 }\n\t\t\t\tawait codeGenerationStore.persistence.processWithProgress((completed, total) => {\n\t\t\t\t\tthis._recoveryProgress = { phase: \"persistence\", total, completed }\n\t\t\t\t})\n\t\t\t}\n\t\t\tthis._recoveryProgress = undefined\n\t\t} else {\n\t\t\t// Previous flow without progress\n\t\t\tfor (const nodeId of predictedRecoverableSourceNodeIds) {\n\t\t\t\tawait codeGenerationStore.updateComponent(nodeId, GenerationCondition.Forced)\n\t\t\t}\n\t\t\tawait codeGenerationStore.persistence.process()\n\t\t}\n\n\t\t// Ensure recovery didn't create any new errors.\n\t\tconst errors = this.getErrors({ includeStaleModules: true })\n\t\tpromise.resolve(errors)\n\t\tthis.#recoveryPromise = undefined\n\n\t\t// Figure out which modules were actually recovered for the purposes of\n\t\t// tracking, for instance if our prediction heuristics were wrong.\n\t\tconst actualRecoverableModules = new Set<NodeID>(predictedRecoverableSourceNodeIds)\n\t\tconst unrecoverableModules = new Set<NodeID>()\n\t\tfor (const node of tree.getNodeWithTrait(ERROR_LIST_NODE_ID, isErrorListNode)?.children ?? []) {\n\t\t\tif (!node.scopeId) continue\n\t\t\tunrecoverableModules.add(node.scopeId)\n\t\t\tactualRecoverableModules.delete(node.scopeId)\n\t\t}\n\n\t\tconst durationMs = Math.round(performance.now() - recoveryStart)\n\t\tthis.#recoveryMetrics.prePublishRecoverModulesMs += durationMs\n\t\trecord(\"recover_modules_before_publish\", {\n\t\t\tdurationMs,\n\t\t\tpredictedRecoverableModules: predictedRecoverableSourceNodeIds.length,\n\t\t\tunrecoverableModules: unrecoverableModules.size,\n\t\t\tactualRecoverableModules: actualRecoverableModules.size,\n\t\t})\n\n\t\treturn errors\n\t}\n\n\tpublic async publish({\n\t\tpatched,\n\t\tsuppressPublishPopoverOnError = false,\n\t\tsuppressPublishPopover = false,\n\t}: {\n\t\tpatched?: {\n\t\t\ttreeState: PatchedDeploymentTreeState\n\t\t\tnodeIds: readonly string[]\n\t\t}\n\t\tsuppressPublishPopoverOnError?: boolean\n\t\tsuppressPublishPopover?: boolean\n\t} = {}): Promise<PublishResult | PublishFailureResult> {\n\t\tif (!this.canPublish()) {\n\t\t\tSentry.addBreadcrumb({\n\t\t\t\tmessage: \"Publish aborted: canPublish() returned false\",\n\t\t\t\tlevel: \"warning\",\n\t\t\t\tdata: {\n\t\t\t\t\tisDocumentLoaded: this.isDocumentLoaded,\n\t\t\t\t\tpublishStatus: this._publishStatus,\n\t\t\t\t\thasHomeNode: this.getHomeNode() !== null,\n\t\t\t\t},\n\t\t\t})\n\t\t\treturn { error: \"Publishing is currently unavailable.\" }\n\t\t}\n\n\t\tconst detached = patched !== undefined\n\n\t\tconst {\n\t\t\ttreeStore,\n\t\t\tpluginStore,\n\t\t\tsiteSettingsStore,\n\t\t\tpopoverStore,\n\t\t\tdebugStore,\n\t\t\tchromeStore,\n\t\t\tscopeStore,\n\t\t\tselectionStore,\n\t\t} = this\n\n\t\tconst branchId = treeStore.branchId\n\n\t\tif (siteSettingsStore.hasUnsavedChanges && !window.confirm(\"Unsaved changes will not be published\")) {\n\t\t\tSentry.addBreadcrumb({ message: \"Publish aborted: user declined unsaved changes confirmation\", level: \"warning\" })\n\t\t\treturn { error: \"Unsaved site settings were not confirmed for publish.\" }\n\t\t}\n\n\t\tconst publishStartTime = performance.now()\n\n\t\tconst projectId = this._projectId\n\t\tconst prevStatus = this._publishStatus\n\t\tthis._publishStatus = PublishStatus.Publishing\n\t\tlet hasNonBlockingFormErrors = false\n\n\t\t/**\n\t\t * @TODO - This is only necessary because the publish sheet won't render\n\t\t * unless these values are set. We should allow rendering the sheet\n\t\t * without these values so we can prevent a bad initial publish and show\n\t\t * errors in the sheet, see PublishPopover.tsx.\n\t\t */\n\t\tconst hasFirstPublish = this.defaultHostname && this.defaultHostnameDeployment && this.deploymentStrategy\n\t\tif (hasFirstPublish) {\n\t\t\tconst publishErrors = await this.prepareForPublishing()\n\t\t\tconst blockingPublishErrors = publishErrors?.filter(error => !isNonBlockingPublishError(error)) ?? []\n\t\t\thasNonBlockingFormErrors = publishErrors && publishErrors.length > blockingPublishErrors.length\n\t\t\tif (blockingPublishErrors.length !== 0) {\n\t\t\t\tSentry.addBreadcrumb({\n\t\t\t\t\tmessage: \"Publish aborted: blocking publish errors\",\n\t\t\t\t\tlevel: \"warning\",\n\t\t\t\t\tdata: { count: blockingPublishErrors.length },\n\t\t\t\t})\n\t\t\t\tif (!suppressPublishPopoverOnError && !suppressPublishPopover) {\n\t\t\t\t\t// eslint-disable-next-line require-atomic-updates\n\t\t\t\t\tpopoverStore.active = PopoverType.Publish\n\t\t\t\t}\n\t\t\t\tthis._publishStatus = prevStatus\n\t\t\t\treturn {\n\t\t\t\t\terror: `Publishing blocked by ${blockingPublishErrors.length} blocking ${pluralize(\"error\", blockingPublishErrors.length)}.`,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (hasNonBlockingFormErrors) {\n\t\t\tif (environment.isApiPlugin) {\n\t\t\t\tSentry.addBreadcrumb({ message: \"Publish: skipping non-blocking form errors confirmation\", level: \"info\" })\n\t\t\t} else {\n\t\t\t\tconst shouldPublish = await this.confirmPublishWithDisabledForms()\n\t\t\t\tif (!shouldPublish) {\n\t\t\t\t\tSentry.addBreadcrumb({\n\t\t\t\t\t\tmessage: \"Publish aborted: user declined disabled forms confirmation\",\n\t\t\t\t\t\tlevel: \"warning\",\n\t\t\t\t\t})\n\t\t\t\t\tthis._publishStatus = prevStatus\n\t\t\t\t\treturn { error: \"Publishing cancelled because unverified form recipients were not confirmed.\" }\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst loader = treeStore.tree.getService(\"loader\")\n\t\tlet shallowScopesCount: number | undefined\n\t\tlet shallowScopesLoadingMs: number | undefined\n\t\tif (loader && !treeStore.getDataTree()) {\n\t\t\tconst startTime = performance.now()\n\t\t\tshallowScopesCount = loader.numberOfScopesToLoad()\n\t\t\tloader.prioritizeLoadingAllData({\n\t\t\t\toperationInBackground: true,\n\t\t\t\toperationName: \"load_shallow_scopes_during_publish\",\n\t\t\t})\n\t\t\tawait loader.afterAllDataLoaded()\n\t\t\tshallowScopesLoadingMs = performance.now() - startTime\n\t\t}\n\n\t\tconst homeNode = this.getHomeNode()?.loaded\n\t\tif (!(homeNode instanceof CanvasNode)) {\n\t\t\ttoast({\n\t\t\t\ttype: \"add\",\n\t\t\t\tvariant: \"error\",\n\t\t\t\tprimaryText: \"Project has no pages.\",\n\t\t\t\tsecondaryText: \"Create one first.\",\n\t\t\t\tkey: \"no-web-pages\",\n\t\t\t\ticon: \"error\",\n\t\t\t\tduration: 5000,\n\t\t\t})\n\t\t\tSentry.addBreadcrumb({ message: \"Publish aborted: project has no pages\", level: \"warning\" })\n\t\t\tthis._publishStatus = prevStatus\n\t\t\treturn { error: \"Project has no pages.\" }\n\t\t}\n\n\t\tlet metricsForError: RoutesSizeErrorStats | undefined\n\n\t\ttry {\n\t\t\tconst framerSiteId = await sha256(projectId)\n\n\t\t\tconst {\n\t\t\t\thtml,\n\t\t\t\tserverRoutes,\n\t\t\t\tlocalizedSegments,\n\t\t\t\tssgRoutes,\n\t\t\t\tssgRewrites,\n\t\t\t\tlocales,\n\t\t\t\tmetrics,\n\t\t\t\ttreeState,\n\t\t\t\theaderKeys,\n\t\t\t\tsearchIndexUrl,\n\t\t\t} = await generateHTML({\n\t\t\t\tcomponentLoader: this.componentLoader,\n\t\t\t\tmodulesStore: this.modulesStore,\n\t\t\t\tcodeGenerationStore: this.codeGenerationStore,\n\t\t\t\tdebugStore,\n\t\t\t\ttreeStore,\n\t\t\t\tpublishStore: this,\n\t\t\t\tprojectStore: this.projectStore,\n\t\t\t\tassetStore: this.assetStore,\n\t\t\t\tframerSiteId,\n\t\t\t\tscheduler: this.scheduler,\n\t\t\t\tpatchedTreeState: patched?.treeState,\n\t\t\t})\n\n\t\t\tmetricsForError = {\n\t\t\t\tpageCount: metrics.pageCount,\n\t\t\t\tredirectCount: metrics.redirectCount,\n\t\t\t\trewriteCount: metrics.rewriteCount,\n\t\t\t\theaderCount: metrics.headerCount,\n\t\t\t}\n\n\t\t\tconst { publishRevisions, changeSummary } = this.getPublishChanges({ patchedNodeIds: patched?.nodeIds })\n\n\t\t\tconst preOptimizePaths = new Set(this._mostVisitedPaths)\n\t\t\t// Dummy hostname, because we only care about the pathname.\n\t\t\t// TODO: Refactor (split) getActiveWebPageURL into getURL + getPathname?\n\t\t\tconst currentPagePath = new URL(this.getActiveWebPageURL(\"example.com\")).pathname\n\t\t\tpreOptimizePaths.add(currentPagePath)\n\n\t\t\t// SPA doesn't support 404 on non-CMS pages, so we need to pre-optimize the 404 page.\n\t\t\tfor (const path of customNotFoundPagePaths) {\n\t\t\t\tpreOptimizePaths.add(path)\n\t\t\t}\n\n\t\t\tconst { deployment, hostnames } = await publish({\n\t\t\t\tprojectId,\n\t\t\t\thtml,\n\t\t\t\tserverRoutes,\n\t\t\t\tlocalizedSegments,\n\t\t\t\tssgRoutes,\n\t\t\t\tssgRewrites,\n\t\t\t\tlocales,\n\t\t\t\ttreeState,\n\t\t\t\tcanonicalURL: this.canonicalURL,\n\t\t\t\tdebugFlags: getDebugFlags(debugStore),\n\t\t\t\tserializedExperiments: experiments.serialize(),\n\t\t\t\tadaptLayoutToTextDirection: treeStore.tree.root.adaptLayoutToTextDirection,\n\t\t\t\tautomaticLocale: treeStore.tree.root.webMetadata?.automaticLocale ?? false,\n\t\t\t\tchangeSummary,\n\t\t\t\tsearchIndexUrl,\n\t\t\t\tpreOptimizePaths: Array.from(preOptimizePaths).filter(Boolean),\n\t\t\t\tdetached,\n\t\t\t\tbranchId,\n\t\t\t})\n\n\t\t\t// Detached deployment doesn't update the hostnames, while publish\n\t\t\t// revisions stored on the root are only pertinent to the default hostname.\n\t\t\tif (!detached && publishRevisions) {\n\t\t\t\tthis.scheduler.scheduleDocumentUpdateIgnoringUndo(() => {\n\t\t\t\t\ttreeStore.tree.root.set({\n\t\t\t\t\t\tpublishRevisions: publishRevisions.nextRevisions,\n\t\t\t\t\t\tpublishPaths: publishRevisions.nextPaths,\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Trigger a tree snapshot. Makes it easier to make duplicates of\n\t\t\t// the project as it was (close to) when published, but is not a\n\t\t\t// required step, so errors are ignored and we don\u2019t wait for it.\n\t\t\t//\n\t\t\t// For patched deployments, we already store a snapshot during the\n\t\t\t// patching process: document-patched-${patched.treeState.patchedSnapshotId}.crdt\n\t\t\tif (!patched) {\n\t\t\t\tconst path = `/projects/${projectId}/tree/latest`\n\t\t\t\t// TODO: Remove the conditional once we've fully migrated to FramerMultiplayerService\n\t\t\t\tconst url = this.treeStore.isMPSSocket ? getMultiplayerServiceURL(path) : path\n\t\t\t\tvoid fetchWithRetry(url, {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tcredentials: \"include\",\n\t\t\t\t\theaders: xRequestedByHeader,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Detached deployment doesn't update the hostnames.\n\t\t\tif (!detached) {\n\t\t\t\tif (\n\t\t\t\t\tprevStatus === PublishStatus.Unpublished &&\n\t\t\t\t\tthis.customHostname?.isPublished === false &&\n\t\t\t\t\tthis.deploymentStrategy === DeploymentStrategy.Manual\n\t\t\t\t) {\n\t\t\t\t\t// In the scenario where the user has:\n\t\t\t\t\t// - added their custom domain;\n\t\t\t\t\t// - pinned it to a specific version;\n\t\t\t\t\t// - unpublished their project;\n\t\t\t\t\t// - publishes again;\n\t\t\t\t\t// We ensure we get the correct timestamps by re-fetching the hostnames.\n\t\t\t\t\t//\n\t\t\t\t\t// The actual publish endpoint returns a single deployment (= latest), which is wrong in this case.\n\t\t\t\t\tawait this.loadHostnames()\n\t\t\t\t} else {\n\t\t\t\t\t// Only update the state of the hostname(s) that have the new deployment.\n\t\t\t\t\tconst mappedDeployment = mapDeployment(deployment)\n\t\t\t\t\tconst updatedHostnames = hostnames\n\t\t\t\t\t\t.filter(hostname => hostname.deploymentId === deployment.id)\n\t\t\t\t\t\t.map(hostname => ({ ...hostname, deployment: mappedDeployment, projectId }))\n\t\t\t\t\tawait this.updateState(updatedHostnames)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Reset versions.\n\t\t\tthis.resetVersions()\n\n\t\t\tconst domainConnected =\n\t\t\t\tthis.deploymentStrategy === DeploymentStrategy.AlwaysLatest && Boolean(this.customHostname?.isPublished)\n\t\t\tconst publishedToHostname = this.resolvePublishedHostname({ detached, branchId, domainConnected, hostnames })\n\n\t\t\tif (!detached) {\n\t\t\t\tconst openLinkURL = this.getActiveWebPageURL(publishedToHostname)\n\n\t\t\t\tconst openLinkAction = createOpenLinkToastAction(openLinkURL)\n\t\t\t\tconst connectDomainAction = createConnectDomainAction(siteSettingsStore)\n\n\t\t\t\tconst toastText = sitePublishedText({\n\t\t\t\t\tisFirstTimePublish: prevStatus !== PublishStatus.Published,\n\t\t\t\t})\n\t\t\t\tconst toastAction = sitePublishedAction({\n\t\t\t\t\tdisplayMinimalUI: chromeStore.displayMinimalUI,\n\t\t\t\t\tisDomainConnected: domainConnected,\n\t\t\t\t\tisFirstPublish: prevStatus !== PublishStatus.Published,\n\t\t\t\t\topenLinkAction,\n\t\t\t\t\tconnectDomainAction,\n\t\t\t\t})\n\n\t\t\t\tthis.showPublishSuccessToast({\n\t\t\t\t\t...toastText,\n\t\t\t\t\taction: toastAction,\n\t\t\t\t\tduration: 5000,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tif (suppressPublishPopover && prevStatus === PublishStatus.Unpublished) {\n\t\t\t\tthis.#suppressNextPublishPopover = true\n\t\t\t}\n\n\t\t\tthis._publishStatus = PublishStatus.Published\n\t\t\tthis.notifyProjectChange(\"sites\")\n\n\t\t\t// Find all collections so we can see how many of them are in use.\n\t\t\tconst allCollections = new Map(\n\t\t\t\tthis.componentLoader\n\t\t\t\t\t.getData()\n\t\t\t\t\t.filter((definition): definition is DataDefinition => {\n\t\t\t\t\t\tconst { identifier } = definition\n\t\t\t\t\t\tif (isLocalModuleIdentifier(identifier) && !getCollectionForIdentifier(this.treeStore.tree, identifier)) {\n\t\t\t\t\t\t\t// TODO: If the collection doesn't exist in the\n\t\t\t\t\t\t\t// tree, we assume that it's a deleted collection.\n\t\t\t\t\t\t\t// We have to support code-based collections as\n\t\t\t\t\t\t\t// well. For this we need to delete local modules\n\t\t\t\t\t\t\t// when the collection node is deleted / vacuum\n\t\t\t\t\t\t\t// deleted generated modules regularly.\n\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true\n\t\t\t\t\t})\n\t\t\t\t\t.map(d => [d.identifier, d]),\n\t\t\t)\n\n\t\t\t// Code related metrics.\n\t\t\t//\n\t\t\t// TODO: We should also count unique (non-Framer) Instant NPM\n\t\t\t// dependencies used by all the code modules.\n\t\t\t// Note: usedOverrides can include legacy code identifiers (for now).\n\t\t\t// localCodeFileIdentifiers / pendingExternal are intermediate state\n\t\t\t// for the fastWalk branch; the legacy branch leaves them empty.\n\t\t\tconst acc = {\n\t\t\t\tusedCollections: new Set<ModuleExportIdentifierString>(),\n\t\t\t\tcodeComponentInstanceCount: 0,\n\t\t\t\tdeprecatedCodeComponentInstanceCount: 0,\n\t\t\t\tusedLocalCodeComponents: new Set<LocalModuleExportIdentifierString>(),\n\t\t\t\tusedExternalCodeComponents: new Set<ExternalModuleExportIdentifierString>(),\n\t\t\t\tusedOverrides: new Set<string>(),\n\t\t\t\tusedWorkshopGeneratedComponents: new Set<string>(),\n\t\t\t\tlayersWithOverrides: 0,\n\t\t\t\tlocalCodeFileIdentifiers: new Map<LocalModuleExportIdentifierString, ModuleIdentifier>(),\n\t\t\t\tpendingExternal: new Map<\n\t\t\t\t\tExternalModuleExportIdentifierString,\n\t\t\t\t\t{ identifier: ExternalModuleExportIdentifier; count: number }\n\t\t\t\t>(),\n\t\t\t}\n\t\t\tlet designPageCount = 0\n\t\t\tlet urlVariableCount = 0\n\n\t\t\tconst tree = treeStore.getDataTreeOrLoadedTree()\n\t\t\t// Walk the tree to collect statistics about collection & code use.\n\t\t\t// TODO: This should use tree indexes.\n\t\t\t// FIXME: should we skip counting if the scope is a draft?\n\t\t\tfor (const scopeNode of tree.root.children.filter<ScopeNode>(isScopeNode)) {\n\t\t\t\tif (isDesignPageNode(scopeNode)) {\n\t\t\t\t\tdesignPageCount++\n\t\t\t\t}\n\t\t\t\tif (isWebPageNode(scopeNode)) {\n\t\t\t\t\turlVariableCount += scopeNode.variables.filter(withQueryParam).length\n\t\t\t\t}\n\t\t\t\tassert(scopeNode.isLoaded(), \"Scope node not loaded\")\n\t\t\t\tif (!isSmartComponentNode(scopeNode) && !isWebPageNode(scopeNode)) {\n\t\t\t\t\t// Only check web pages and Smart Components (because they\n\t\t\t\t\t// can contain uses we wouldn't encounter on web pages).\n\t\t\t\t\t//\n\t\t\t\t\t// TODO: We should skip unused Smart Components.\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// Use fastWalk only where it's needed: data-only tree on a crdt project.\n\t\t\t\t// TODO: remove this gate (and the walk() branch) once dataOnlyTree is fully rolled out.\n\t\t\t\tif (experiments.isOn(\"dataOnlyTree\") && this.treeStore.mode === \"crdt\") {\n\t\t\t\t\tthis.collectPublishStatsCrdt(scopeNode, acc)\n\t\t\t\t} else {\n\t\t\t\t\tthis.collectPublishStatsLegacy(scopeNode, acc)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst workshopPluginManifest = pluginStore.getWorkshopManifest()\n\t\t\tfor (const [value, identifier] of acc.localCodeFileIdentifiers) {\n\t\t\t\tconst pluginManifest = getPluginManifestFromModuleIdentifier(\n\t\t\t\t\tthis.treeStore,\n\t\t\t\t\tthis.modulesStore,\n\t\t\t\t\tthis.pluginStore,\n\t\t\t\t\tidentifier,\n\t\t\t\t)\n\t\t\t\tif (pluginManifest?.id === workshopPluginManifest?.id) {\n\t\t\t\t\tacc.usedWorkshopGeneratedComponents.add(value)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const [value, { identifier, count }] of acc.pendingExternal) {\n\t\t\t\tif (isExternalCodeFileModuleIdentifier(this.treeStore, identifier)) {\n\t\t\t\t\tacc.codeComponentInstanceCount += count\n\t\t\t\t\tacc.usedExternalCodeComponents.add(value)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Calculate missing/unused collections using the data collected above.\n\t\t\tconst unusedCollections = new Set(allCollections.keys())\n\t\t\tlet collectionUsedRecordCount = 0\n\t\t\tlet collectionMissingCount = 0\n\t\t\tacc.usedCollections.forEach(identifier => {\n\t\t\t\tunusedCollections.delete(identifier)\n\t\t\t\tconst dataDefinition = allCollections.get(identifier)\n\t\t\t\tconst itemToSlug = dataDefinition?.itemToSlug ?? {}\n\t\t\t\tcollectionUsedRecordCount += Object.keys(itemToSlug).length\n\t\t\t\tif (!allCollections.has(identifier)) collectionMissingCount++\n\t\t\t})\n\n\t\t\t// Count the number of code components by Framer so we can infer third-party usage.\n\t\t\tlet officialExternalCodeComponents = 0\n\t\t\tfor (const identifierString of acc.usedExternalCodeComponents) {\n\t\t\t\tconst identifier = parseModuleIdentifier(identifierString)\n\t\t\t\tif (isFramerModule(this.treeStore.tree, identifier)) {\n\t\t\t\t\t// This one will include a check if the component was\n\t\t\t\t\t// published under \"framer/*\" namespace, so it should also\n\t\t\t\t\t// include the ones from\n\t\t\t\t\t// `insertSidebar/dataSources/items/*`, but we should\n\t\t\t\t\t// improve this tracking.\n\t\t\t\t\tofficialExternalCodeComponents++\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// We ascertain that the page is using search if there's a search component in the tree.\n\t\t\tconst hasSearch = treeStore.treeIndex.searchComponentNodeIds.size > 0\n\n\t\t\trecord(\"project_published\", {\n\t\t\t\tdeployId: deployment.id,\n\t\t\t\thostname: publishedToHostname,\n\t\t\t\trouteCount: Object.keys(serverRoutes).length,\n\t\t\t\tframerSiteId,\n\t\t\t\ttreeVersion: treeState.treeVersion,\n\t\t\t\thasBadge: this.hasBadge(),\n\t\t\t\thasSearch,\n\t\t\t\tadditionalLocaleCount: locales.length - 1,\n\t\t\t\t...computeLocalizedSegmentsMetrics(localizedSegments),\n\t\t\t\tcollectionTotalCount: getCollectionCount(this.treeStore.tree),\n\t\t\t\tcollectionUnusedCount: unusedCollections.size,\n\t\t\t\tcollectionUsedCount: acc.usedCollections.size,\n\t\t\t\tcollectionUsedRecordCount,\n\t\t\t\tcollectionMissingCount,\n\t\t\t\tdesignPageCount,\n\t\t\t\tpublishDurationMs: Math.round(performance.now() - publishStartTime),\n\t\t\t\tcodeComponentInstanceCount: acc.codeComponentInstanceCount,\n\t\t\t\tuniqueLocalCodeComponents: acc.usedLocalCodeComponents.size,\n\t\t\t\tuniqueExternalCodeComponents: acc.usedExternalCodeComponents.size,\n\t\t\t\tofficialExternalCodeComponents,\n\t\t\t\tformCount: treeStore.treeIndex.formContainerNodeIds.size,\n\t\t\t\tshaderCount: treeStore.treeIndex.shaderNodeIds.size,\n\t\t\t\turlVariableCount,\n\t\t\t\tlayersWithOverrides: acc.layersWithOverrides,\n\t\t\t\tuniqueOverrides: acc.usedOverrides.size,\n\t\t\t\tautomaticLocale: treeStore.tree.root.webMetadata?.automaticLocale ?? false,\n\t\t\t\tworkshopGeneratedComponents: acc.usedWorkshopGeneratedComponents.size,\n\t\t\t\t...metrics,\n\t\t\t\theaderKeys,\n\t\t\t\t...this.#recoveryMetrics,\n\t\t\t\tshallowScopesCount,\n\t\t\t\tshallowScopesLoadingMs,\n\t\t\t})\n\n\t\t\ttrackAutoImageModuleAnnotations(this.modulesStore, this.treeStore)\n\t\t\ttrackFlowEffectModuleAnnotations(this.modulesStore, this.treeStore)\n\n\t\t\trecord(\"publish_deprecated_code_component\", {\n\t\t\t\ttotal: treeStore.treeIndex.deprecatedCodeComponentNodeIds.size,\n\t\t\t\tinWebPageOrSmartComponent: acc.deprecatedCodeComponentInstanceCount,\n\t\t\t})\n\n\t\t\t// Reset the prepublish metrics.\n\t\t\tthis.#recoveryMetrics = {\n\t\t\t\tprePublishLoadShallowScopesMs: 0,\n\t\t\t\tprePublishCatchUpWebPagesMs: 0,\n\t\t\t\tprePublishRecoverModulesMs: 0,\n\t\t\t\tprePublishPreloadExternalModulesMs: 0,\n\t\t\t}\n\n\t\t\t// Update UI right away if necessary.\n\t\t\tif (this._customHostname && this._deploymentSettings?.deploymentStrategy === DeploymentStrategy.AlwaysLatest) {\n\t\t\t\tthis._customHostnameDeployment = mapDeployment(deployment)\n\t\t\t\trecord(\"custom_domain_version_set\", {\n\t\t\t\t\tdeployId: deployment.id,\n\t\t\t\t\tdeployStatus: deployment.status,\n\t\t\t\t\thostname: this._customHostname.hostname,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn { deployment, hostnames }\n\t\t} catch (error) {\n\t\t\tlet needsErrorRefInToast = true\n\t\t\tconst errorIsConnectionError = isConnectionError(error)\n\n\t\t\tconst errorRef = randomBase62(5)\n\t\t\tlog.reportError(\n\t\t\t\terror,\n\t\t\t\t{ isConnectionError: errorIsConnectionError },\n\t\t\t\t{ [ReportTag.ErrorRef]: errorRef },\n\t\t\t\t!errorIsConnectionError,\n\t\t\t)\n\t\t\tlet reportingErrorMessage = \"\" // Will populate with either the user facing message or the error message at the end of this catch block\n\n\t\t\tlet message = \"Something went wrong while publishing, please try again\"\n\t\t\tlet secondaryText: string | undefined = undefined\n\t\t\tlet action: ToastAction | undefined\n\n\t\t\t// There used to be a time when we didn't validate page metadata's\n\t\t\t// length, which means there might be projects out there that fail\n\t\t\t// to publish because of that. Let's try to detect this, and provide\n\t\t\t// a more specific error message.\n\t\t\t//\n\t\t\t// Eventually, we should be able to remove this, because all new\n\t\t\t// edits to page metadata should be validated on the frontend.\n\t\t\tif (error instanceof ApiError && error.status === 400) {\n\t\t\t\tconst mapping = mapPublish400ErrorMessage(error.message, metricsForError)\n\t\t\t\tif (mapping) {\n\t\t\t\t\tmessage = mapping.message\n\t\t\t\t\tsecondaryText = mapping.toastSecondaryText\n\t\t\t\t\treportingErrorMessage = mapping.toastSecondaryText\n\t\t\t\t\t\t? `${mapping.message} ${mapping.toastSecondaryText}`\n\t\t\t\t\t\t: mapping.message\n\t\t\t\t\tneedsErrorRefInToast = mapping.needsErrorRefInToast\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (error instanceof NoTreeVersionError) {\n\t\t\t\tneedsErrorRefInToast = false\n\t\t\t\tmessage = reportingErrorMessage = \"Cannot publish when disconnected\"\n\t\t\t\tsecondaryText = undefined\n\t\t\t}\n\n\t\t\tif (errorIsConnectionError) {\n\t\t\t\tmessage = reportingErrorMessage = \"Network error while publishing, please check your connection and try again\"\n\t\t\t\tsecondaryText = undefined\n\t\t\t}\n\n\t\t\tif (error instanceof WaitForLoadingComponentsError) {\n\t\t\t\tsecondaryText = undefined\n\t\t\t\tif (error.wasTimeout) {\n\t\t\t\t\treportingErrorMessage = \"Failed to publish because there was a timeout processing updates\"\n\t\t\t\t\tmessage = \"Failed to publish because there was a timeout processing updates, please try again\"\n\t\t\t\t}\n\n\t\t\t\t// Only show a detailed message for the first error! (In most cases there will be only one)\n\t\t\t\tconst identifier = error.missing[0]\n\t\t\t\tconst moduleIdentifier = parseModuleIdentifier(identifier)\n\t\t\t\tif (identifier && isLocalModuleIdentifier(moduleIdentifier)) {\n\t\t\t\t\tconst isError = new Set(error.error).has(identifier)\n\t\t\t\t\tconst { type, localIdName: nodeId } = moduleIdentifier\n\t\t\t\t\tconst reviewAction = {\n\t\t\t\t\t\ttitle: Dictionary.Review,\n\t\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\t\trecord(\"ui_interaction\", {\n\t\t\t\t\t\t\t\tpage: MetricsInteractionViews.TOAST,\n\t\t\t\t\t\t\t\tid: \"review-publish-error\",\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tthis.scheduler.processWhenReady(() => {\n\t\t\t\t\t\t\t\tconst node = treeStore.tree.get(nodeId)\n\t\t\t\t\t\t\t\tif (!node) return\n\t\t\t\t\t\t\t\tscopeStore.selectByNode(nodeId)\n\t\t\t\t\t\t\t\tconst errorNodes: string[] = []\n\t\t\t\t\t\t\t\tfor (const n of node.walk()) {\n\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\tgetNodeError(\n\t\t\t\t\t\t\t\t\t\t\tn,\n\t\t\t\t\t\t\t\t\t\t\tthis.componentLoader,\n\t\t\t\t\t\t\t\t\t\t\tthis.treeStore.tree,\n\t\t\t\t\t\t\t\t\t\t\tthis.loadedExternalModulesStore,\n\t\t\t\t\t\t\t\t\t\t\tthis.modulesStore,\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\terrorNodes.push(n.id)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tselectionStore.set(errorNodes)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t\tswitch (type) {\n\t\t\t\t\t\tcase ModuleType.Screen: {\n\t\t\t\t\t\t\treportingErrorMessage = `Error on a page: ${error.message}`\n\t\t\t\t\t\t\tmessage = \"Failed to publish because there is an error on a page\"\n\t\t\t\t\t\t\taction = reviewAction\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase ModuleType.Canvas: {\n\t\t\t\t\t\t\tmessage = reportingErrorMessage = \"Failed to publish because there is an error in a component\"\n\t\t\t\t\t\t\taction = reviewAction\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase ModuleType.Prototype: {\n\t\t\t\t\t\t\tmessage = reportingErrorMessage = \"Failed to publish because there is an error in a prototype\"\n\t\t\t\t\t\t\taction = reviewAction\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\t// Improve the message reported to pulse with the type.\n\t\t\t\t\t\t\treportingErrorMessage = `${message} - ${type}`\n\t\t\t\t\t\t\t// Show the generic error without action\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\trecord(\"publish_local_module_component_timeout\", {\n\t\t\t\t\t\tmoduleType: type,\n\t\t\t\t\t\tisError,\n\t\t\t\t\t\ttotalMissing: error.missing.length,\n\t\t\t\t\t})\n\t\t\t\t} else if (isExternalModuleIdentifier(moduleIdentifier)) {\n\t\t\t\t\treportingErrorMessage = `${message} - external`\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (errorIsConnectionError) {\n\t\t\t\trecord(\"connection_error\", { where: log.id, message })\n\t\t\t} else {\n\t\t\t\treportingErrorMessage ||= (error instanceof Error && error.message) || message\n\t\t\t\trecord(\"application_error\", {\n\t\t\t\t\tarea: ErrorArea.publish,\n\t\t\t\t\tmessage: reportingErrorMessage,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\ttoast({\n\t\t\t\ttype: \"add\",\n\t\t\t\tvariant: \"error\",\n\t\t\t\tprimaryText: message,\n\t\t\t\tsecondaryText: needsErrorRefInToast ? `(ref: ${errorRef}).` : secondaryText,\n\t\t\t\tkey: \"publish-error\",\n\t\t\t\ticon: \"error\",\n\t\t\t\tduration: 5000,\n\t\t\t\taction,\n\t\t\t})\n\t\t\tthis._publishStatus = prevStatus\n\n\t\t\treturn { error: reportingErrorMessage || message }\n\t\t}\n\t}\n\n\tprivate collectPublishStatsCrdt(scopeNode: ScopeNode, acc: PublishStatsAccumulator): void {\n\t\t// Full tree walk - using fastWalk to offset the performance impact\n\t\t// when publishing with a partially loaded tree (aka. via DataTree)\n\t\tfor (const accessor of scopeNode.fastWalk()) {\n\t\t\tif (accessor.get(\"replicaInfo\") && accessor.get(\"isVariant\")) {\n\t\t\t\taccessor.skipChildren = true\n\t\t\t\t// Don't log module related stats for nodes in variants.\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (accessor.__class === \"CodeComponentNode\") {\n\t\t\t\t// Note: CodeComponentNode is used for all module-based\n\t\t\t\t// components, not just code components.\n\t\t\t\tconst codeComponentIdentifier = accessor.get(\"codeComponentIdentifier\") as string | undefined\n\t\t\t\tif (codeComponentIdentifier) {\n\t\t\t\t\tconst identifier = parseModuleIdentifier(codeComponentIdentifier)\n\t\t\t\t\tif (identifier?.kind === \"localModuleExport\" && identifier.type === \"codeFile\") {\n\t\t\t\t\t\tacc.codeComponentInstanceCount++\n\t\t\t\t\t\tacc.usedLocalCodeComponents.add(identifier.value)\n\t\t\t\t\t\tacc.localCodeFileIdentifiers.set(identifier.value, identifier)\n\t\t\t\t\t} else if (identifier?.kind === \"externalModuleExport\") {\n\t\t\t\t\t\tconst existing = acc.pendingExternal.get(identifier.value)\n\t\t\t\t\t\tif (existing) existing.count++\n\t\t\t\t\t\telse acc.pendingExternal.set(identifier.value, { identifier, count: 1 })\n\t\t\t\t\t}\n\t\t\t\t\tif (stylableCodeComponents.has(codeComponentIdentifier)) {\n\t\t\t\t\t\tacc.deprecatedCodeComponentInstanceCount++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst codeOverrideEnabled = accessor.get(\"codeOverrideEnabled\")\n\t\t\tconst codeOverrideIdentifier = accessor.get(\"codeOverrideIdentifier\")\n\t\t\tif (codeOverrideEnabled && isString(codeOverrideIdentifier)) {\n\t\t\t\tacc.layersWithOverrides++\n\t\t\t\tacc.usedOverrides.add(codeOverrideIdentifier)\n\t\t\t}\n\n\t\t\tconst codeOverrides = accessor.get(\"codeOverrides\") as Array<{ identifier: string }> | undefined\n\t\t\tif (codeOverrides && codeOverrides.length > 0) {\n\t\t\t\tacc.layersWithOverrides++\n\t\t\t\tfor (const override of codeOverrides) {\n\t\t\t\t\tacc.usedOverrides.add(override.identifier)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst dataIdentifier = accessor.get(\"dataIdentifier\")\n\t\t\tif (dataIdentifier) {\n\t\t\t\tacc.usedCollections.add(dataIdentifier as ModuleExportIdentifierString)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate collectPublishStatsLegacy(scopeNode: ScopeNode, acc: PublishStatsAccumulator): void {\n\t\tconst workshopPluginManifest = this.pluginStore.getWorkshopManifest()\n\t\tfor (const node of scopeNode.walk()) {\n\t\t\tif (isReplicaVariantOrReplicaVariantChild(node)) {\n\t\t\t\t// Don't log module related stats for nodes in variants.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (isCodeComponentNode(node)) {\n\t\t\t\t// Note: CodeComponentNode is used for all module-based\n\t\t\t\t// components, not just code components.\n\t\t\t\tconst identifier = parseModuleIdentifier(node.codeComponentIdentifier)\n\t\t\t\tif (identifier?.kind === \"localModuleExport\" && identifier.type === \"codeFile\") {\n\t\t\t\t\tacc.codeComponentInstanceCount++\n\t\t\t\t\tacc.usedLocalCodeComponents.add(identifier.value)\n\t\t\t\t\tconst pluginManifest = getPluginManifestFromModuleIdentifier(\n\t\t\t\t\t\tthis.treeStore,\n\t\t\t\t\t\tthis.modulesStore,\n\t\t\t\t\t\tthis.pluginStore,\n\t\t\t\t\t\tidentifier,\n\t\t\t\t\t)\n\t\t\t\t\tif (pluginManifest?.id === workshopPluginManifest?.id) {\n\t\t\t\t\t\tacc.usedWorkshopGeneratedComponents.add(identifier.value)\n\t\t\t\t\t}\n\t\t\t\t} else if (isExternalCodeFileModuleIdentifier(this.treeStore, identifier)) {\n\t\t\t\t\tacc.codeComponentInstanceCount++\n\t\t\t\t\tacc.usedExternalCodeComponents.add(identifier.value)\n\t\t\t\t}\n\t\t\t\tif (isStylableCodeComponent(node)) {\n\t\t\t\t\tacc.deprecatedCodeComponentInstanceCount++\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (hasCodeOverride(node)) {\n\t\t\t\tacc.layersWithOverrides++\n\t\t\t\tacc.usedOverrides.add(node.codeOverrideIdentifier)\n\t\t\t}\n\t\t\tif (withCodeOverridesExperiment(node) && node.codeOverrides && node.codeOverrides.length > 0) {\n\t\t\t\tacc.layersWithOverrides++\n\t\t\t\tfor (const override of node.codeOverrides) {\n\t\t\t\t\tacc.usedOverrides.add(override.identifier)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (hasCollectionDataSource(node)) {\n\t\t\t\tacc.usedCollections.add(node.dataIdentifier)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate resolvePublishedHostname({\n\t\tdetached,\n\t\tbranchId,\n\t\tdomainConnected,\n\t\thostnames,\n\t}: {\n\t\tdetached: boolean\n\t\tbranchId: string\n\t\tdomainConnected: boolean\n\t\thostnames: Hostname[]\n\t}): string {\n\t\tif (detached) {\n\t\t\tconst versionHostname = hostnames.find(h => h.type === HostnameType.Version)\n\t\t\tassert(versionHostname, \"Version hostname not found for detached publish\")\n\t\t\treturn versionHostname.hostname\n\t\t} else if (branchId !== MAIN_BRANCH_ID) {\n\t\t\tconst branchHostname = hostnames.find(h => h.type === HostnameType.Branch && h.branchId === branchId)\n\t\t\tassert(branchHostname, \"Branch hostname not found\")\n\t\t\treturn branchHostname.hostname\n\t\t}\n\n\t\tconst defaultHostname = this.defaultHostname\n\t\tassert(defaultHostname, \"Default hostname not found\")\n\n\t\treturn this.customHostname && domainConnected ? this.customHostname.hostname : defaultHostname.hostname\n\t}\n\n\tpublic async unpublish() {\n\t\tif (!this.defaultHostname) return\n\t\tconst projectId = this._projectId\n\n\t\ttry {\n\t\t\tawait unpublish(projectId)\n\t\t\trecord(\"project_unpublished\", {\n\t\t\t\thostname: this.defaultHostname.hostname,\n\t\t\t})\n\t\t\tthis.resetVersions()\n\t\t\tawait this.loadHostnames()\n\t\t\tthis.notifyProjectChange(\"sites\")\n\n\t\t\ttoast({\n\t\t\t\ttype: \"add\",\n\t\t\t\tvariant: \"success\",\n\t\t\t\tprimaryText: \"Your project\",\n\t\t\t\tsecondaryText: \"has been unpublished.\",\n\t\t\t\tkey: \"unpublish-success\",\n\t\t\t\ticon: \"success\",\n\t\t\t})\n\t\t} catch (error) {\n\t\t\tlog.reportError(error)\n\n\t\t\ttoast({\n\t\t\t\ttype: \"add\",\n\t\t\t\tvariant: \"error\",\n\t\t\t\tprimaryText: \"Failed to unpublish\",\n\t\t\t\tsecondaryText: \"your project.\",\n\t\t\t\tkey: \"unpublish-error\",\n\t\t\t\ticon: \"error\",\n\t\t\t})\n\t\t}\n\t}\n\n\tpublic isCustomDomainAvailable = async (domain: string) => {\n\t\tconst response = await checkDomainAvailability(domain)\n\t\treturn response.isAvailable\n\t}\n\n\tpublic addCustomDomain = async (domain: string, variant?: HostnameVariant) => {\n\t\tif (!this._defaultHostnameDeployment) return\n\n\t\t// Error handling is done at the UI layer.\n\t\tconst projectId = this._projectId\n\t\tconst { hostnames: createdHostnames } = await postCustomDomain({\n\t\t\tprojectId,\n\t\t\tdomain,\n\t\t})\n\n\t\t// Also immediately trigger validation.\n\t\t//\n\t\t// TODO: On the backend, start returning the new validation data, isApex\n\t\t// and invalidDnsReason, when creating the custom domain. Then we won't\n\t\t// need this second request.\n\t\tconst { hostnames: validatedHostnames } = await validateCustomDomain({\n\t\t\tprojectId,\n\t\t})\n\n\t\tconst hostnames: Hostname[] = [...createdHostnames, ...validatedHostnames]\n\n\t\t// Set the custom hostname deployment to the default hostname deployment.\n\t\t// TODO: Don't assume local client knows the exact state of the server.\n\t\tassert(this._defaultHostnameDeployment, \"missing default hostname deployment\")\n\t\tconst enrichedHostnamesWithDeployment: EnrichedHostnameWithDeploymentAndDeploymentId[] = []\n\t\tfor (const hostname of hostnames) {\n\t\t\tif (hostname.deploymentId !== this._defaultHostnameDeployment.id) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tenrichedHostnamesWithDeployment.push({\n\t\t\t\t...hostname,\n\t\t\t\tdeployment: this._defaultHostnameDeployment,\n\t\t\t\tprojectId,\n\t\t\t})\n\t\t}\n\n\t\tawait this.updateState(enrichedHostnamesWithDeployment, validatedHostnames)\n\n\t\tassert(this._customHostname, `Custom hostname not found`)\n\t\trecord(\"custom_domain_added\", {\n\t\t\tdeployId: this._customHostname.deploymentId,\n\t\t\thostname: this._customHostname.hostname,\n\t\t\tvariant,\n\t\t})\n\n\t\tif (variant === HostnameVariant.Free) {\n\t\t\ttoastFreeDomainConnected()\n\t\t} else if (this._customHostname.status === HostnameStatus.Active) {\n\t\t\ttoastDomainConnected()\n\t\t} else {\n\t\t\ttoastDomainAdded()\n\t\t}\n\t}\n\n\tpublic async validateCustomDomain() {\n\t\tconst deployment = this._customHostnameDeployment\n\t\tif (!deployment) return\n\n\t\tconst projectId = this._projectId\n\t\tconst { hostnames } = await validateCustomDomain({ projectId })\n\n\t\tconst enrichedHostnames = hostnames.map((hostname): EnrichedHostnameWithDeploymentAndDeploymentId => {\n\t\t\treturn { ...hostname, deployment, projectId }\n\t\t})\n\t\tawait this.updateState(enrichedHostnames, hostnames)\n\t}\n\n\tpublic async removeCustomDomain(domain: string) {\n\t\tconst projectId = this._projectId\n\t\tif (!this.customHostname) return\n\n\t\ttry {\n\t\t\tawait removeCustomDomain({ projectId, domain })\n\t\t\trecord(\"custom_domain_removed\", {\n\t\t\t\thostname: this.customHostname.hostname,\n\t\t\t})\n\t\t\tthis._customHostname = undefined\n\t\t\tthis._customHostnameDeployment = undefined\n\t\t\tthis._customHostnameDeploymentIssues = undefined\n\t\t\tthis.customHostnameValidationResult = []\n\n\t\t\tif (this.isFreeDomain(domain)) {\n\t\t\t\ttoastFreeDomainRemoved()\n\t\t\t} else {\n\t\t\t\ttoastCustomDomainRemoved()\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlog.reportError(error)\n\t\t\ttoastRemoveDomainError()\n\t\t}\n\t}\n\n\tpublic async updateCustomDomain(deployment: VersionDeployment): Promise<UpdateCustomDomainResult> {\n\t\tconst projectId = this._projectId\n\t\tconst domain = this.customHostname?.hostname\n\n\t\tif (!domain || !this._customHostnameDeployment) {\n\t\t\treturn { ok: false, errorMessage: \"Custom domain is not configured.\" }\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await updateCustomHostname({\n\t\t\t\tprojectId,\n\t\t\t\tdomain,\n\t\t\t\tdeploymentId: deployment.id,\n\t\t\t})\n\t\t\tconst enrichedHostnameWithDeployment: EnrichedHostnameWithDeploymentAndDeploymentId = {\n\t\t\t\t...response,\n\t\t\t\tdeploymentId: deployment.id,\n\t\t\t}\n\t\t\tawait this.updateState([enrichedHostnameWithDeployment])\n\n\t\t\t// Refresh the hostnames after deploying\n\t\t\t// this is needed to get the updated `abTestIds`\n\t\t\tvoid this.loadHostnames()\n\t\t\tthis.notifyProjectChange(\"sites\")\n\n\t\t\trecord(\"custom_domain_version_set\", {\n\t\t\t\tdeployId: deployment.id,\n\t\t\t\tdeployStatus: deployment.status,\n\t\t\t\thostname: domain,\n\t\t\t})\n\n\t\t\ttoast({\n\t\t\t\ttype: \"add\",\n\t\t\t\tvariant: \"success\",\n\t\t\t\tprimaryText: \"Published\",\n\t\t\t\tsecondaryText: \"to your custom domain.\",\n\t\t\t\tkey: \"published-custom-domain-success\",\n\t\t\t\ticon: \"success\",\n\t\t\t})\n\n\t\t\treturn { ok: true }\n\t\t} catch (error) {\n\t\t\tconst message = \"Failed to publish to custom domain.\"\n\t\t\tconst errorMessage = error instanceof Error && error.message ? error.message : message\n\t\t\tlog.reportError(error)\n\t\t\trecord(\"application_error\", { area: ErrorArea.publish, message })\n\n\t\t\ttoast({\n\t\t\t\ttype: \"add\",\n\t\t\t\tvariant: \"error\",\n\t\t\t\tprimaryText: \"Failed to publish\",\n\t\t\t\tsecondaryText: \"to custom domain.\",\n\t\t\t\tkey: \"published-custom-domain-error\",\n\t\t\t\ticon: \"error\",\n\t\t\t})\n\n\t\t\treturn { ok: false, errorMessage }\n\t\t}\n\t}\n\n\tprivate notifyProjectChange(scope: ProjectChangeScope) {\n\t\tthis._socket.send({ type: \"notifyProjectChange\", value: { scope } })\n\t}\n\n\t/**\n\t * Timeout ID and attempt count when polling is enabled, undefined otherwise.\n\t */\n\t#polling: Record<PollingType, { timeoutId: number; attempt: number } | undefined> = {\n\t\t[PollingType.Hostnames]: undefined,\n\t\t[PollingType.Versions]: undefined,\n\t}\n\n\t/**\n\t * Calculate poll interval with simple 3-phase strategy.\n\t * Attempts 1-10: 1s intervals (first 10 seconds)\n\t * Attempts 11-20: 5s intervals (next 50 seconds, total 1 minute)\n\t * Attempts 21-39: 60s intervals (remaining 19 minutes, total 20 minutes)\n\t */\n\tprivate calculatePollInterval(attempt: number): number {\n\t\tif (attempt <= 10) {\n\t\t\treturn INITIAL_POLL_INTERVAL // 1s for first 10s\n\t\t}\n\n\t\tif (attempt <= 20) {\n\t\t\treturn MODERATE_POLL_INTERVAL // 5s for next 50s\n\t\t}\n\n\t\treturn SLOW_POLL_INTERVAL // 60s for remaining time\n\t}\n\n\tprivate poll(type: PollingType) {\n\t\tconst polling = this.#polling[type]\n\t\tif (!polling) return\n\n\t\tconst { timeoutId, attempt } = polling\n\n\t\t// If we've exceeded the maximum number of attempts, stop polling.\n\t\tif (attempt >= MAX_POLL_ATTEMPTS) {\n\t\t\tlog.debug(\n\t\t\t\t`Stopping polling for ${PollingType[type]}: ${timeoutId} after ${MAX_POLL_ATTEMPTS} attempts (20 minutes)`,\n\t\t\t)\n\t\t\tthis.stopPolling(type)\n\t\t\treturn\n\t\t}\n\n\t\tpolling.attempt++\n\n\t\tlet promise: Promise<unknown> | undefined\n\t\tif (type === PollingType.Hostnames) {\n\t\t\tpromise = this.loadHostnames()\n\t\t} else if (type === PollingType.Versions) {\n\t\t\tpromise = this.refreshVersions()\n\t\t} else {\n\t\t\tassertNever(type)\n\t\t}\n\n\t\tpromise.then(\n\t\t\t() => {\n\t\t\t\tif (!this.#polling[type]) return\n\t\t\t\t// Polling is still enabled, so let's schedule another run.\n\t\t\t\tconst interval = this.calculatePollInterval(this.#polling[type].attempt)\n\t\t\t\tlog.debug(\n\t\t\t\t\t`Scheduling next poll for ${PollingType[type]} for the ${this.#polling[type].attempt}th time, with interval: ${interval}ms`,\n\t\t\t\t)\n\n\t\t\t\tthis.#polling[type].timeoutId = window.setTimeout(() => this.poll(type), interval)\n\t\t\t},\n\t\t\terror => {\n\t\t\t\tlog.error(\"Error polling\", type, error)\n\t\t\t\tthis.stopPolling(type)\n\t\t\t},\n\t\t)\n\t}\n\n\tprivate togglePolling(type: PollingType, enabled: boolean) {\n\t\tif (enabled) {\n\t\t\tthis.startPolling(type)\n\t\t} else {\n\t\t\tthis.stopPolling(type)\n\t\t}\n\t}\n\n\tprivate startPolling(type: PollingType) {\n\t\t// Optimization doesn't work in local dev environments, so there's no sense polling, it only clutters your web\n\t\t// inspector's Network tab and Docker logs.\n\t\tif (hostInfo.isLocal) return\n\n\t\tif (this.#polling[type]) return\n\n\t\t// Don't poll right away. Chance is we started polling because we just\n\t\t// noticed that a deployment is optimizing, so it doesn't make sense to\n\t\t// check again right away. Instead, schedule the first poll to happen\n\t\t// after the initial interval.\n\t\tthis.#polling[type] = { timeoutId: window.setTimeout(() => this.poll(type), INITIAL_POLL_INTERVAL), attempt: 0 }\n\t}\n\n\tprivate stopPolling(type: PollingType) {\n\t\tclearTimeout(this.#polling[type]?.timeoutId)\n\t\tthis.#polling[type] = undefined\n\t}\n\n\tprivate _optimizationIssuesWindowDeployment: VersionDeployment | null = null\n\tprivate _optimizationIssuesWindowDeploymentIssues: GetDeploymentIssuesResponse | null = null\n\n\topenOptimizationIssuesWindow(deployment: VersionDeployment) {\n\t\tthis._optimizationIssuesWindowDeployment = deployment\n\t\tvoid getDeploymentIssues(this._projectId, deployment.id).then(response => {\n\t\t\t// If the window is still open, and still on the same deployment, update the issues.\n\t\t\tif (this._optimizationIssuesWindowDeployment?.id === deployment.id) {\n\t\t\t\tthis._optimizationIssuesWindowDeploymentIssues = response\n\t\t\t}\n\t\t})\n\t}\n\n\tcloseOptimizationIssuesWindow() {\n\t\tthis._optimizationIssuesWindowDeployment = null\n\t\tthis._optimizationIssuesWindowDeploymentIssues = null\n\t}\n\n\tget optimizationIssuesWindowDeployment(): VersionDeployment | null {\n\t\treturn this._optimizationIssuesWindowDeployment\n\t}\n\n\tget optimizationIssuesWindowDeploymentIssues(): GetDeploymentIssuesResponse | null {\n\t\treturn this._optimizationIssuesWindowDeploymentIssues\n\t}\n\n\t/** Refresh daily, mostly for users that never close their Framer tabs. */\n\tprivate static mostVisitedPathsRefreshInterval = 24 * 60 * 60 * 1000\n\tprivate static mostVisitedPathsLimit = 20\n\n\tprivate _mostVisitedPaths: string[] = []\n\n\tprivate fetchMostVisitedPaths() {\n\t\tfetchTopField(\n\t\t\tthis._projectId,\n\t\t\t\"pathname\",\n\t\t\t{\n\t\t\t\tfromDay: getDayRelativeToToday(-30),\n\t\t\t\ttoDay: getDayRelativeToToday(0),\n\t\t\t},\n\t\t\tnew AbortController().signal,\n\t\t\tPublishStore.mostVisitedPathsLimit,\n\t\t)\n\t\t\t.then(response => {\n\t\t\t\tthis._mostVisitedPaths = (response.pathname ?? []).map(item => item.value)\n\t\t\t})\n\t\t\t.catch(error => {\n\t\t\t\tlog.warn(\"Failed to fetch most visited paths\", error)\n\t\t\t})\n\t}\n\n\ttesting = {\n\t\tsetCustomHostname: (customHostname: CustomHostname) => {\n\t\t\tthis._customHostname = customHostname\n\t\t},\n\t\tsetCustomHostnameDeployment: (customHostnameDeployment: Deployment) => {\n\t\t\tthis._customHostnameDeployment = customHostnameDeployment\n\t\t},\n\t\tsetDefaultHostname: (defaultHostname: DefaultHostname) => {\n\t\t\tthis._defaultHostname = defaultHostname\n\t\t},\n\t\tsetDeploymentSettings: (deploymentSettings: DeploymentSettings) => {\n\t\t\tthis._deploymentSettings = deploymentSettings\n\t\t},\n\t}\n}\n\nfunction isExternalCodeFileModuleIdentifier(\n\ttreeStore: TreeStore,\n\tidentifier: ModuleIdentifier | undefined,\n): identifier is ExternalModuleExportIdentifier {\n\tif (identifier?.kind !== \"externalModuleExport\") return false\n\tconst moduleNode = treeStore.tree.get(identifier.moduleId)\n\tif (!isExternalModuleNode(moduleNode)) return false\n\treturn moduleNode.type === \"codeFile\"\n}\n\n/**\n * Track the prevalence of `FramerAutoSizeImages` annotation on modules in the project so we\n * can judge the number of modules that will need to be regenerated.\n */\nfunction trackAutoImageModuleAnnotations(modulesStore: ModulesStore, treeStore: TreeStore) {\n\ttry {\n\t\tconst result = {\n\t\t\twithAnnotationLocal: new Set(),\n\t\t\twithoutAnnotationLocal: new Set(),\n\t\t}\n\n\t\tconst modules = getRelatedModulesForFitImage(modulesStore, treeStore)\n\t\tfor (const module of modules) {\n\t\t\tif (module.hasAnnotation) {\n\t\t\t\tresult.withAnnotationLocal.add(module.localId)\n\t\t\t} else {\n\t\t\t\tresult.withoutAnnotationLocal.add(module.localId)\n\t\t\t}\n\t\t}\n\n\t\tlog.debug(\"Track auto size image module annotations result:\", result)\n\t\trecord(\"publish_image_annotation\", {\n\t\t\twithAnnotationLocal: result.withAnnotationLocal.size,\n\t\t\twithoutAnnotationLocal: result.withoutAnnotationLocal.size,\n\t\t})\n\t} catch (error) {\n\t\tlog.reportError(error)\n\t}\n}\n\nfunction trackFlowEffectModuleAnnotations(modulesStore: ModulesStore, treeStore: TreeStore) {\n\ttry {\n\t\tconst { stats } = getWebPageModulesToRegenerate(modulesStore, treeStore)\n\t\tconst withAnnotationLocal = stats.totalModules - stats.modulesToRegenerate\n\t\tconst withoutAnnotationLocal = stats.modulesToRegenerate\n\n\t\tlog.debug(\"Track flow effect module annotations result:\", {\n\t\t\twithAnnotationLocal,\n\t\t\twithoutAnnotationLocal,\n\t\t})\n\t\trecord(\"publish_flow_effect_annotation\", {\n\t\t\twithAnnotationLocal,\n\t\t\twithoutAnnotationLocal,\n\t\t})\n\t} catch (error) {\n\t\tlog.reportError(error)\n\t}\n}\n\nfunction hasInstanceIdentifier<T extends CanvasNode>(\n\tnode: T,\n): node is T & { instanceIdentifier: ModuleExportIdentifierString } {\n\treturn (\n\t\t\"instanceIdentifier\" in node &&\n\t\tisString(node.instanceIdentifier) &&\n\t\tisModuleExportIdentifier(node.instanceIdentifier)\n\t)\n}\n\nfunction getDebugFlags(debugStore: DebugStore): DebugFlag[] | undefined {\n\tconst flags: DebugFlag[] = []\n\tif (!debugStore.debuggingOfPublishedSites.minification) {\n\t\tflags.push(DebugFlag.noMinifyJS)\n\t}\n\tif (!debugStore.debuggingOfPublishedSites.bundling) {\n\t\tflags.push(DebugFlag.noBundleJS)\n\t}\n\tif (debugStore.debuggingOfPublishedSites.forceRendererLambda) {\n\t\tflags.push(DebugFlag.forceRendererLambda)\n\t}\n\treturn flags.length > 0 ? flags : undefined\n}\n", "import { assert } from \"library/utils/assert.ts\"\nimport { ChangeStatus, ChangeType, type ProjectChange } from \"web/pages/project/projectChanges.ts\"\n\ntype Change = Omit<ProjectChange, \"nodeId\" | \"userIds\">\n\nexport const changeTypeStrToInt = {\n\t[ChangeType.WebPage]: 0,\n\t[ChangeType.SmartComponent]: 1,\n\t[ChangeType.LayoutTemplate]: 2,\n\t[ChangeType.CollectionItem]: 3,\n\t[ChangeType.ProxyRoute]: 4,\n} as const\n\nconst changeTypeIntToStr = reverseMap(changeTypeStrToInt)\ntype ChangeTypeInt = (typeof changeTypeStrToInt)[keyof typeof changeTypeStrToInt]\n\ntype NormalisedScopeNameList = Partial<Record<ChangeTypeInt, string[]>>\ntype NormalisedSummaryForStatus = NormalisedScopeNameList & { t: number }\ntype NormalisedSummary = Record<ChangeStatus, NormalisedSummaryForStatus> & { v: 1 }\n\n/**\n * We are limited to 1000 chars to store a change summary,\n * therefore we count all the changes by type, but the scope details\n * are only captured if we stay under the 1000 chars threshold.\n */\nexport const JSON_TRUE_MAX_LENGTH = 1000\n\nexport function serialiseChanges(changes: Change[]): string {\n\tconst normalised = normalise(changes)\n\tconst stringified = JSON.stringify(normalised)\n\tassert(\n\t\tstringified.length <= JSON_TRUE_MAX_LENGTH,\n\t\t`Serialised changes are over the limit of ${JSON_TRUE_MAX_LENGTH} chars.`,\n\t)\n\n\treturn stringified\n}\n\nconst TOTALS_BUFFER = 6 // allocate enough space for `t`s to grow to 3 digits\nconst JSON_MAX_LENGTH = JSON_TRUE_MAX_LENGTH - TOTALS_BUFFER\nconst JSON_SCOPE_LENGTH = 7 // ,'0':[]\n\nfunction addingNameStrLength(names: string[], name: string) {\n\tconst needsComma = names.length > 0\n\treturn name.length + 2 + (needsComma ? 1 : 0)\n}\n\nexport function changeSummaryBase(): NormalisedSummary {\n\treturn {\n\t\tv: 1, // Schema version\n\t\t[ChangeStatus.Updated]: {\n\t\t\tt: 0,\n\t\t},\n\t\t[ChangeStatus.Added]: {\n\t\t\tt: 0,\n\t\t},\n\t\t[ChangeStatus.Removed]: {\n\t\t\tt: 0,\n\t\t},\n\t}\n}\n\nfunction normalise(changes: Change[]): NormalisedSummary {\n\tconst summary = changeSummaryBase()\n\tlet currStrLength = JSON.stringify(summary).length\n\n\tfor (const { status, type, name } of changes) {\n\t\tsummary[status].t += 1\n\n\t\tconst scope = changeTypeStrToInt[type]\n\n\t\tif (!summary[status][scope]) {\n\t\t\tconst nextStrLength = currStrLength + JSON_SCOPE_LENGTH\n\t\t\tif (nextStrLength > JSON_MAX_LENGTH) continue\n\t\t\tsummary[status][scope] = []\n\t\t\tcurrStrLength = nextStrLength\n\t\t}\n\n\t\tconst nextStrLength = currStrLength + addingNameStrLength(summary[status][scope], name)\n\t\tif (nextStrLength > JSON_MAX_LENGTH) continue\n\t\tsummary[status][scope].push(name)\n\t\tcurrStrLength = nextStrLength\n\t}\n\n\treturn summary\n}\n\nfunction reverseMap<T extends Record<any, any>>(obj: T): { [K in keyof T as `${T[K] & (string | number)}`]: K } {\n\treturn Object.fromEntries(Object.entries(obj).map(([key, value]) => [value, key]))\n}\n\ntype NormalisedSummaryPartial = Record<ChangeStatus, Partial<Record<ChangeTypeInt, unknown>> & { t: number }> & {\n\tv: 1\n}\n\nconst statuses = Object.values(ChangeStatus).filter(v => typeof v !== \"string\")\n\nexport function parseChanges(serialisedChanges: string) {\n\tconst result = {\n\t\tchanges: [] as Change[],\n\t\ttotalChanges: 0,\n\t}\n\n\tconst maybeSummary = JSON.parse(serialisedChanges) as unknown\n\tassertIsObject(maybeSummary)\n\tassertIsValidSchemaVersion(maybeSummary)\n\tassertsIsNormalisedSummaryPartial(maybeSummary)\n\n\tconst scopes = Object.values(changeTypeStrToInt)\n\tfor (const status of statuses) {\n\t\tif (status in maybeSummary && maybeSummary[status]) {\n\t\t\tconst summaryForStatus = maybeSummary[status]\n\t\t\tresult.totalChanges += summaryForStatus.t\n\n\t\t\tfor (const scope of scopes) {\n\t\t\t\tif (scope in summaryForStatus && summaryForStatus[scope]) {\n\t\t\t\t\tconst scopeSummary = summaryForStatus[scope]\n\t\t\t\t\tassertIsNameList(scopeSummary)\n\n\t\t\t\t\tfor (const scopeName of scopeSummary) {\n\t\t\t\t\t\tresult.changes.push({\n\t\t\t\t\t\t\tname: scopeName,\n\t\t\t\t\t\t\ttype: changeTypeIntToStr[scope],\n\t\t\t\t\t\t\tstatus,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result\n}\n\nfunction assertIsObject(obj: unknown): asserts obj is object {\n\tif (typeof obj !== \"object\" || obj === null) {\n\t\tthrow new Error(\"Invalid schema: JSON is not an object\")\n\t}\n}\n\nfunction assertIsValidSchemaVersion(obj: object): asserts obj is {\n\tv: 1\n} {\n\tif (!(\"v\" in obj) || obj.v !== 1) {\n\t\tthrow new Error(\"Invalid schema: Incorrect version\")\n\t}\n}\n\nfunction assertsIsNormalisedSummaryPartial(obj: Record<string, unknown>): asserts obj is NormalisedSummaryPartial {\n\tfor (const status of statuses) {\n\t\tif (!(status in obj)) {\n\t\t\tthrow new Error(`Invalid schema: missing status \"${status}\"`)\n\t\t}\n\n\t\tconst statusObj = obj[status]\n\t\tif (typeof statusObj !== \"object\" || statusObj === null) {\n\t\t\tthrow new Error(`Invalid schema: status \"${status}\" is not an object`)\n\t\t}\n\n\t\tif (!(\"t\" in statusObj) || typeof statusObj.t !== \"number\") {\n\t\t\tthrow new Error(`Invalid schema: status \"${status}\" has invalid \"t\" property`)\n\t\t}\n\t}\n}\n\nfunction assertIsNameList(list: unknown): asserts list is string[] {\n\tif (!Array.isArray(list) || list.some(i => typeof i !== \"string\")) {\n\t\tthrow new Error(\"Invalid schema: scope value is not a list of names\")\n\t}\n}\n", "import type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { assert, unhandledError } from \"@framerjs/shared\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type { UpsellFeature } from \"document/components/chrome/siteSettings/Plans/Stripe/utils/upsell.ts\"\nimport type { UsageType } from \"document/components/chrome/siteSettings/Usage/types.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isScopeNode } from \"document/models/CanvasTree/index.ts\"\nimport type { WebMetadata } from \"document/models/CanvasTree/traits/WithWebMetadata.ts\"\nimport { getMetadataWarningMessages } from \"document/models/CanvasTree/traits/WithWebMetadata.ts\"\nimport type { LinkToWebPage } from \"document/models/CanvasTree/traits/utils/Link.ts\"\nimport type { NullableRecord } from \"document/models/CanvasTree/traits/utils/NullablePartialRecord.ts\"\nimport { ActiveMainView } from \"document/utils/ActiveEditorType.ts\"\nimport { ModalType } from \"document/utils/ModalType.ts\"\nimport { isNonNull } from \"utils/typeChecks.ts\"\nimport { Pages } from \"web/lib/tracker.ts\"\nimport type { ChromeStore } from \"./ChromeStore.ts\"\nimport type { ModalStore } from \"./ModalStore.ts\"\nimport type { ScopeStore } from \"./ScopeStore.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\n\nexport enum SiteSettingsTabNames {\n\tproject = \"project\",\n\tdomains = \"domains\",\n\tredirects = \"redirects\",\n\tversions = \"versions\",\n\tplans = \"plans\",\n\tpage = \"page\",\n\tforms = \"forms\",\n\tusage = \"usage\",\n\tcustomCode = \"customCode\",\n}\nexport type SiteSettingsTab =\n\t| { tab: SiteSettingsTabNames.project }\n\t| { tab: SiteSettingsTabNames.domains }\n\t| { tab: SiteSettingsTabNames.redirects }\n\t| {\n\t\t\ttab: SiteSettingsTabNames.versions\n\t\t\t/**\n\t\t\t * Allows pre-selecting a version.\n\t\t\t *\n\t\t\t * Known limitation: will only work if the version is one of the latest DEPLOYMENTS_LIST_LIMIT versions.\n\t\t\t */\n\t\t\tid?: string\n\t\t\t/**\n\t\t\t * Used for deep linking to version issues, will open the optimization issues window on mount.\n\t\t\t */\n\t\t\tshowDeploymentIssues?: boolean\n\t  }\n\t| {\n\t\t\ttab: SiteSettingsTabNames.plans\n\t\t\tupsellFeature?: UpsellFeature\n\t  }\n\t| { tab: SiteSettingsTabNames.page; id: NodeID }\n\t| { tab: SiteSettingsTabNames.forms }\n\t| { tab: SiteSettingsTabNames.usage; usageType: UsageType }\n\t| { tab: SiteSettingsTabNames.customCode; pageId?: NodeID }\n\n/**\n * Used to automatically emit ui_impression tracking events when the user\n * navigates to the given tab. Use `null` to explicitly opt a tab out of this,\n * for example, if you don't want to track a particular tab, or if you want to\n * do some custom tracking.\n */\nexport const siteSettingsImpressionTrackingPages: Record<SiteSettingsTabNames, Pages | null> = {\n\t[SiteSettingsTabNames.project]: Pages.siteSettingsProject,\n\t[SiteSettingsTabNames.domains]: Pages.siteSettingsDomains,\n\t[SiteSettingsTabNames.redirects]: Pages.siteSettingsRedirects,\n\t[SiteSettingsTabNames.versions]: Pages.siteSettingsVersions,\n\t[SiteSettingsTabNames.plans]: Pages.siteSettingsPlans,\n\t[SiteSettingsTabNames.forms]: Pages.siteSettingsForms,\n\t[SiteSettingsTabNames.page]: null,\n\t[SiteSettingsTabNames.usage]: Pages.siteSettingsUsage,\n\t[SiteSettingsTabNames.customCode]: Pages.siteSettingsCustomCode,\n}\n\nexport function isSiteSettingsTabName(value: string): value is SiteSettingsTabNames {\n\treturn value in SiteSettingsTabNames\n}\n\nconst metaDataWithoutChanges: NullableRecord<WebMetadata> = {\n\ttitle: null,\n\tdescription: null,\n\tfavicon: null,\n\tfaviconDark: null,\n\tsocialImage: null,\n\tappleTouchIcon: null,\n\tgoogleAnalyticsTrackingId: null,\n\treducedMotion: null,\n\tnoIndex: null,\n\tnoIndexSite: null,\n\tlanguage: null,\n\tlanguageTitle: null,\n\tadaptLayoutToTextDirection: null,\n\tcanonicalURL: null,\n\tcustomCanonicalURL: null,\n\trewriteCanonicalHostname: null,\n\trewriteCanonicalPath: null,\n\toptOutOfHTMLPlugin: null,\n\tautomaticLocale: null,\n\tpreserveQueryParams: null,\n\tenableFormsUTMTracking: null,\n\ttranslatePagePaths: null,\n\ttranslatePagePathsWithAI: null,\n}\nObject.freeze(metaDataWithoutChanges)\n\ninterface Redirect {\n\tfrom: string\n\tto: string | LinkToWebPage\n}\n\nexport const newRedirect = Symbol.for(\"newRedirect\")\n\nexport class SiteSettingsStore extends EngineStore {\n\tconstructor(\n\t\tprivate readonly componentLoader: ComponentLoader,\n\t\tprivate readonly chromeStore: ChromeStore,\n\t\tprivate readonly modalStore: ModalStore,\n\t\tprivate readonly scopeStore: ScopeStore,\n\t\tprivate readonly treeStore: TreeStore,\n\t) {\n\t\tsuper()\n\t}\n\n\tprivate _active: SiteSettingsTab | null = null\n\n\tget active(): SiteSettingsTab | null {\n\t\treturn this._active\n\t}\n\n\tasync setActiveTab(nextTab: SiteSettingsTab | null) {\n\t\tif (this.chromeStore.displayMinimalUI) return\n\n\t\tconst switchTab = async () => {\n\t\t\tif (this.hasUnsavedChanges) {\n\t\t\t\tconst action = await new Promise<\"discard\" | \"cancel\" | \"save\">(resolve => {\n\t\t\t\t\tthis.modalStore.set({\n\t\t\t\t\t\ttype: ModalType.UnsavedChanges,\n\t\t\t\t\t\tdescription: \"You are about to close a settings tab with unsaved changes.\",\n\t\t\t\t\t\tonConfirm: resolve,\n\t\t\t\t\t\tsource: \"settings\",\n\t\t\t\t\t})\n\t\t\t\t})\n\n\t\t\t\tthis.modalStore.dismiss()\n\n\t\t\t\tswitch (action) {\n\t\t\t\t\tcase \"discard\":\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase \"cancel\":\n\t\t\t\t\t\treturn\n\t\t\t\t\tcase \"save\":\n\t\t\t\t\t\tthrow Error(\"Unsaved changes modal for site settings, save not implemented\")\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.redirectsSearchTerm = \"\"\n\t\t\tthis.clearUnsavedChanges()\n\t\t\tthis._active = nextTab\n\t\t\tthis.chromeStore.onChangeSiteSettingsVisible(Boolean(nextTab))\n\t\t}\n\n\t\tif (nextTab?.tab === SiteSettingsTabNames.page) {\n\t\t\t// If the scope we are switching to hasn't loaded yet, request it to be loaded soon\n\t\t\tconst node = this.treeStore.tree.get(nextTab.id)\n\t\t\tif (isScopeNode(node) && !node.isLoaded()) void node.load()\n\t\t}\n\n\t\treturn switchTab()\n\t}\n\n\tget isOpen(): boolean {\n\t\treturn this.chromeStore.mainView === ActiveMainView.SiteSettings\n\t}\n\n\topen = () => {\n\t\tif (this.isOpen) return\n\n\t\tconst webPage = this.scopeStore.getTopMostWebPageNode()\n\t\tconst home = this.scopeStore.getFirstWebPageNode()\n\n\t\t// If there\u2019s a selected page and it\u2019s not the homepage, open the page settings\n\t\tif (webPage && webPage.id !== home?.id) {\n\t\t\tthis.setActiveTab({ tab: SiteSettingsTabNames.page, id: webPage.id }).catch(unhandledError)\n\t\t} else {\n\t\t\tthis.setActiveTab({ tab: SiteSettingsTabNames.project }).catch(unhandledError)\n\t\t}\n\t}\n\n\tclose = () => {\n\t\tthis.setActiveTab(null).catch(unhandledError)\n\t}\n\n\ttoggle = () => {\n\t\tif (this.isOpen) {\n\t\t\tthis.close()\n\t\t} else {\n\t\t\tthis.open()\n\t\t}\n\t}\n\n\tgetIsRedirectsVisible(): boolean {\n\t\treturn this.isOpen && this.active?.tab === SiteSettingsTabNames.redirects\n\t}\n\n\t// Metadata changes\n\t// Null means that the value hasn't been changed\n\tmetadataChanges: Readonly<NullableRecord<WebMetadata>> = metaDataWithoutChanges\n\tpagePath: string | null = null\n\n\tupdateMetadataValue<K extends keyof WebMetadata>(key: K, value: WebMetadata[K] | null) {\n\t\tthis.metadataChanges = { ...this.metadataChanges, [key]: value }\n\t}\n\n\tgetMetadataUpdate(): { metadata: WebMetadata | null; pagePath: string | null } {\n\t\t// If the title is an empty string (deleted), unset the page title to undefined,\n\t\t// so that it will pick up the site title or the node name as a fallback.\n\t\tconst metadata: WebMetadata = {}\n\t\tfor (const untypedKey in this.metadataChanges) {\n\t\t\tconst key = untypedKey as keyof typeof this.metadataChanges\n\t\t\tconst value = this.metadataChanges[key]\n\t\t\tif (value !== null) metadata[key] = value as typeof value & undefined\n\t\t}\n\n\t\tconst { hasWarnings, warningMessages } = getMetadataWarningMessages(this.componentLoader, {\n\t\t\ttitle: metadata.title,\n\t\t\tdescription: metadata.description,\n\t\t\tpagePath: this.pagePath ?? undefined,\n\t\t})\n\t\tassert(!hasWarnings, warningMessages)\n\n\t\treturn {\n\t\t\tmetadata: Object.keys(metadata).length === 0 ? null : metadata,\n\t\t\tpagePath: this.pagePath,\n\t\t}\n\t}\n\n\tget hasMetadataChanges(): boolean {\n\t\tif (this.pagePath !== null) return true\n\t\treturn Object.values(this.metadataChanges).some(isNonNull)\n\t}\n\n\tclearMetadataChanges(): void {\n\t\tthis.metadataChanges = metaDataWithoutChanges\n\t\tthis.pagePath = null\n\t}\n\n\t// Canonical URL changes\n\tcustomCanonicalURLChanges?: string\n\n\tget hasCanonicalURLChanges(): boolean {\n\t\treturn this.customCanonicalURLChanges !== undefined\n\t}\n\n\tclearCanonicalURLChanges(): void {\n\t\tthis.customCanonicalURLChanges = undefined\n\t}\n\n\t// Rewrite canonical URL changes\n\trewriteCanonicalHostnameChanges?: string\n\trewriteCanonicalPathChanges?: string\n\n\tget hasRewriteCanonicalHostnameChanges(): boolean {\n\t\treturn this.rewriteCanonicalHostnameChanges !== undefined\n\t}\n\n\tget hasRewriteCanonicalPathChanges(): boolean {\n\t\treturn this.rewriteCanonicalPathChanges !== undefined\n\t}\n\n\tclearRewriteCanonicalHostnameChanges(): void {\n\t\tthis.rewriteCanonicalHostnameChanges = undefined\n\t}\n\n\tclearRewriteCanonicalPathChanges(): void {\n\t\tthis.rewriteCanonicalPathChanges = undefined\n\t}\n\n\t/**\n\t * Redirects changes\n\t *\n\t * This holds the state of redirects that the user is working on\n\t * (creating/editing), before they get persisted to the document.\n\t *\n\t * Since we allow editing multiple redirects at the same time, we use an\n\t * object keyed by the redirect ID. And for the redirect being created, we\n\t * use the `newRedirect` symbol.\n\t *\n\t * The values are \"diffs\" (think \"unsaved changes\" or \"drafts\") between the\n\t * persisted redirect, and the user input, e.g.:\n\t *\n\t *     { \"a5lg74J0p\": { from: \"/blog\" } }\n\t *\n\t * ... means that the user edited a5lg74J0p's \"from\" value to \"/blog\" (but\n\t * hasn't saved it yet), and they didn't touch the \"to\" value. While:\n\t *\n\t *     { [newRedirect]: { from: \"/blog\" } }\n\t *\n\t * ... would mean that the user started working on a new redirect, and set\n\t * its \"from\" to \"/blog\", but hasn't set the \"to\" yet.\n\t *\n\t * We also take special care to ensure we'll never have empty \"diffs\" in\n\t * here, and instead just remove it from the object.\n\t */\n\tredirectsChanges: Readonly<Record<string | symbol, Readonly<Partial<Redirect>>>> = {}\n\n\tupdateRedirectDraft(key: string | symbol, update: Partial<Redirect>) {\n\t\tconst updated = { ...this.redirectsChanges[key], ...update }\n\n\t\tif (Object.keys(updated).length > 0) {\n\t\t\tthis.redirectsChanges = { ...this.redirectsChanges, [key]: updated }\n\t\t} else {\n\t\t\tthis.clearRedirectDraft(key)\n\t\t}\n\t}\n\n\t/**\n\t * Clears a prop from a draft.\n\t *\n\t * Think e.g. user starting changing a redirect's \"from\" value from \"/foo\"\n\t * to \"/bar\", but then changed it back to \"/foo\". In this case, you'll want\n\t * to clear the \"from\" prop from the draft.\n\t */\n\tclearRedirectDraftProp(key: string | symbol, prop: keyof Redirect) {\n\t\tconst redirect = this.redirectsChanges[key]\n\t\tif (!redirect) return\n\n\t\tconst { [prop]: _, ...updated } = redirect\n\n\t\tif (Object.keys(updated).length > 0) {\n\t\t\tthis.redirectsChanges = { ...this.redirectsChanges, [key]: updated }\n\t\t} else {\n\t\t\tthis.clearRedirectDraft(key)\n\t\t}\n\t}\n\n\t/**\n\t * Clears (removes) and entire draft.\n\t *\n\t * Think e.g. user canceled editing a redirect.\n\t */\n\tclearRedirectDraft(key: string | symbol) {\n\t\tconst { [key]: _, ...redirectsWithoutKey } = this.redirectsChanges\n\t\tthis.redirectsChanges = redirectsWithoutKey\n\t}\n\n\tget hasRedirectsChanges(): boolean {\n\t\t// Object.keys doesn't include symbols, so we need to use\n\t\t// Reflect.ownKeys to account for the `newRedirect` drafts.\n\t\treturn Reflect.ownKeys(this.redirectsChanges).length > 0\n\t}\n\n\tclearRedirectsChanges() {\n\t\tthis.redirectsChanges = {}\n\t}\n\n\t// Unsaved changes\n\tget hasUnsavedChanges(): boolean {\n\t\treturn this.hasMetadataChanges || this.hasRedirectsChanges || this.hasCanonicalURLChanges\n\t}\n\n\tclearUnsavedChanges(): void {\n\t\tthis.clearMetadataChanges()\n\n\t\tthis.clearRedirectsChanges()\n\t\tthis.clearCanonicalURLChanges()\n\t}\n\n\t// Redirects search state\n\tredirectsSearchTerm: string = \"\"\n}\n", "import { toast } from \"web/lib/toaster.ts\"\n\ntype LimitErrorCode = \"upsell\" | \"max-allowed-reached\"\n\n/**\n * A custom error class for limit errors.\n *\n * This error is used to indicate that a user has either reached a limit, or doesn't have\n * permission to edit a resource.\n */\nexport class LimitError extends Error {\n\treadonly code: LimitErrorCode\n\n\tconstructor(message: string, code: LimitErrorCode) {\n\t\tsuper(message)\n\t\tthis.name = \"LimitError\"\n\t\tthis.code = code\n\t}\n}\n\n/**\n * Wraps a function in a try/catch block and shows a toast if the error is a LimitError.\n */\nexport function handleLimitError(fn: () => void) {\n\ttry {\n\t\tfn()\n\t} catch (error) {\n\t\tif (!(error instanceof LimitError)) throw error\n\t\ttoast({\n\t\t\ttype: \"add\",\n\t\t\tkey: error.code,\n\t\t\ttext: error.message,\n\t\t\tvariant: \"error\",\n\t\t})\n\t}\n}\n"],
  "mappings": "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",
  "names": ["md5", "ChangeStatus", "logger", "sharedModuleExportIdentifier", "assertNever", "group", "statuses", "log", "key", "import_jsx_runtime", "assertNever", "key", "key", "assertNever", "md5", "log", "assert", "nextStrLength", "key", "SiteSettingsTabNames", "key", "log", "key", "PollingType", "log", "durationMs", "errors", "pluralize"]
}
