@aglyn/aglyn 1.0.0-beta.143

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (963) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +11 -0
  3. package/package.json +66 -0
  4. package/src/index.d.ts +25 -0
  5. package/src/index.js +26 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/aglyn.d.ts +31 -0
  8. package/src/lib/aglyn.js +114 -0
  9. package/src/lib/aglyn.js.map +1 -0
  10. package/src/lib/app-utils/abuse-report.d.ts +193 -0
  11. package/src/lib/app-utils/abuse-report.js +321 -0
  12. package/src/lib/app-utils/abuse-report.js.map +1 -0
  13. package/src/lib/app-utils/accept-negotiation.d.ts +129 -0
  14. package/src/lib/app-utils/accept-negotiation.js +266 -0
  15. package/src/lib/app-utils/accept-negotiation.js.map +1 -0
  16. package/src/lib/app-utils/account-emails.d.ts +263 -0
  17. package/src/lib/app-utils/account-emails.js +264 -0
  18. package/src/lib/app-utils/account-emails.js.map +1 -0
  19. package/src/lib/app-utils/actions.d.ts +717 -0
  20. package/src/lib/app-utils/actions.js +1031 -0
  21. package/src/lib/app-utils/actions.js.map +1 -0
  22. package/src/lib/app-utils/activity-presenter.d.ts +152 -0
  23. package/src/lib/app-utils/activity-presenter.js +326 -0
  24. package/src/lib/app-utils/activity-presenter.js.map +1 -0
  25. package/src/lib/app-utils/advertising-tag-mounts.d.ts +133 -0
  26. package/src/lib/app-utils/advertising-tag-mounts.js +118 -0
  27. package/src/lib/app-utils/advertising-tag-mounts.js.map +1 -0
  28. package/src/lib/app-utils/advertising-tags.d.ts +307 -0
  29. package/src/lib/app-utils/advertising-tags.js +525 -0
  30. package/src/lib/app-utils/advertising-tags.js.map +1 -0
  31. package/src/lib/app-utils/agent-api-catalog.d.ts +94 -0
  32. package/src/lib/app-utils/agent-api-catalog.js +106 -0
  33. package/src/lib/app-utils/agent-api-catalog.js.map +1 -0
  34. package/src/lib/app-utils/agent-openapi.d.ts +103 -0
  35. package/src/lib/app-utils/agent-openapi.js +1128 -0
  36. package/src/lib/app-utils/agent-openapi.js.map +1 -0
  37. package/src/lib/app-utils/analytics-beacon.d.ts +154 -0
  38. package/src/lib/app-utils/analytics-beacon.js +152 -0
  39. package/src/lib/app-utils/analytics-beacon.js.map +1 -0
  40. package/src/lib/app-utils/analytics-environment.d.ts +133 -0
  41. package/src/lib/app-utils/analytics-environment.js +152 -0
  42. package/src/lib/app-utils/analytics-environment.js.map +1 -0
  43. package/src/lib/app-utils/analytics-events.d.ts +744 -0
  44. package/src/lib/app-utils/analytics-events.js +650 -0
  45. package/src/lib/app-utils/analytics-events.js.map +1 -0
  46. package/src/lib/app-utils/analytics-link-clicks.d.ts +102 -0
  47. package/src/lib/app-utils/analytics-link-clicks.js +267 -0
  48. package/src/lib/app-utils/analytics-link-clicks.js.map +1 -0
  49. package/src/lib/app-utils/analytics-path-key.d.ts +46 -0
  50. package/src/lib/app-utils/analytics-path-key.js +46 -0
  51. package/src/lib/app-utils/analytics-path-key.js.map +1 -0
  52. package/src/lib/app-utils/api-adapter.d.ts +47 -0
  53. package/src/lib/app-utils/api-adapter.js +367 -0
  54. package/src/lib/app-utils/api-adapter.js.map +1 -0
  55. package/src/lib/app-utils/api-idempotency.d.ts +169 -0
  56. package/src/lib/app-utils/api-idempotency.js +213 -0
  57. package/src/lib/app-utils/api-idempotency.js.map +1 -0
  58. package/src/lib/app-utils/api-plugins.d.ts +210 -0
  59. package/src/lib/app-utils/api-plugins.js +221 -0
  60. package/src/lib/app-utils/api-plugins.js.map +1 -0
  61. package/src/lib/app-utils/assist-credits.d.ts +482 -0
  62. package/src/lib/app-utils/assist-credits.js +509 -0
  63. package/src/lib/app-utils/assist-credits.js.map +1 -0
  64. package/src/lib/app-utils/attribution-attribute.d.ts +34 -0
  65. package/src/lib/app-utils/attribution-attribute.js +34 -0
  66. package/src/lib/app-utils/attribution-attribute.js.map +1 -0
  67. package/src/lib/app-utils/attribution-guard.d.ts +130 -0
  68. package/src/lib/app-utils/attribution-guard.js +410 -0
  69. package/src/lib/app-utils/attribution-guard.js.map +1 -0
  70. package/src/lib/app-utils/author-css.d.ts +123 -0
  71. package/src/lib/app-utils/author-css.js +275 -0
  72. package/src/lib/app-utils/author-css.js.map +1 -0
  73. package/src/lib/app-utils/author-html-markdown.d.ts +31 -0
  74. package/src/lib/app-utils/author-html-markdown.js +497 -0
  75. package/src/lib/app-utils/author-html-markdown.js.map +1 -0
  76. package/src/lib/app-utils/author-html.d.ts +135 -0
  77. package/src/lib/app-utils/author-html.js +1037 -0
  78. package/src/lib/app-utils/author-html.js.map +1 -0
  79. package/src/lib/app-utils/automation-placeholders.d.ts +72 -0
  80. package/src/lib/app-utils/automation-placeholders.js +207 -0
  81. package/src/lib/app-utils/automation-placeholders.js.map +1 -0
  82. package/src/lib/app-utils/bandwidth-cap.d.ts +183 -0
  83. package/src/lib/app-utils/bandwidth-cap.js +193 -0
  84. package/src/lib/app-utils/bandwidth-cap.js.map +1 -0
  85. package/src/lib/app-utils/binding-token-catalog.d.ts +82 -0
  86. package/src/lib/app-utils/binding-token-catalog.js +293 -0
  87. package/src/lib/app-utils/binding-token-catalog.js.map +1 -0
  88. package/src/lib/app-utils/binding-tokens.d.ts +157 -0
  89. package/src/lib/app-utils/binding-tokens.js +251 -0
  90. package/src/lib/app-utils/binding-tokens.js.map +1 -0
  91. package/src/lib/app-utils/breadcrumb-json-ld.d.ts +57 -0
  92. package/src/lib/app-utils/breadcrumb-json-ld.js +67 -0
  93. package/src/lib/app-utils/breadcrumb-json-ld.js.map +1 -0
  94. package/src/lib/app-utils/campaign-attribution.d.ts +117 -0
  95. package/src/lib/app-utils/campaign-attribution.js +162 -0
  96. package/src/lib/app-utils/campaign-attribution.js.map +1 -0
  97. package/src/lib/app-utils/campaign-forwarding.d.ts +220 -0
  98. package/src/lib/app-utils/campaign-forwarding.js +332 -0
  99. package/src/lib/app-utils/campaign-forwarding.js.map +1 -0
  100. package/src/lib/app-utils/campaign-membership.d.ts +109 -0
  101. package/src/lib/app-utils/campaign-membership.js +176 -0
  102. package/src/lib/app-utils/campaign-membership.js.map +1 -0
  103. package/src/lib/app-utils/campaign-touch.d.ts +206 -0
  104. package/src/lib/app-utils/campaign-touch.js +326 -0
  105. package/src/lib/app-utils/campaign-touch.js.map +1 -0
  106. package/src/lib/app-utils/child-contract-compose.d.ts +28 -0
  107. package/src/lib/app-utils/child-contract-compose.js +140 -0
  108. package/src/lib/app-utils/child-contract-compose.js.map +1 -0
  109. package/src/lib/app-utils/child-contract.d.ts +129 -0
  110. package/src/lib/app-utils/child-contract.js +153 -0
  111. package/src/lib/app-utils/child-contract.js.map +1 -0
  112. package/src/lib/app-utils/collection-delete.d.ts +113 -0
  113. package/src/lib/app-utils/collection-delete.js +120 -0
  114. package/src/lib/app-utils/collection-delete.js.map +1 -0
  115. package/src/lib/app-utils/collection-entries.d.ts +833 -0
  116. package/src/lib/app-utils/collection-entries.js +1285 -0
  117. package/src/lib/app-utils/collection-entries.js.map +1 -0
  118. package/src/lib/app-utils/collection-entry-date.d.ts +129 -0
  119. package/src/lib/app-utils/collection-entry-date.js +183 -0
  120. package/src/lib/app-utils/collection-entry-date.js.map +1 -0
  121. package/src/lib/app-utils/collection-kind.d.ts +55 -0
  122. package/src/lib/app-utils/collection-kind.js +69 -0
  123. package/src/lib/app-utils/collection-kind.js.map +1 -0
  124. package/src/lib/app-utils/collection-slug.d.ts +79 -0
  125. package/src/lib/app-utils/collection-slug.js +70 -0
  126. package/src/lib/app-utils/collection-slug.js.map +1 -0
  127. package/src/lib/app-utils/compose-layout-nodes.d.ts +147 -0
  128. package/src/lib/app-utils/compose-layout-nodes.js +261 -0
  129. package/src/lib/app-utils/compose-layout-nodes.js.map +1 -0
  130. package/src/lib/app-utils/compose-layout-props.d.ts +71 -0
  131. package/src/lib/app-utils/compose-layout-props.js +61 -0
  132. package/src/lib/app-utils/compose-layout-props.js.map +1 -0
  133. package/src/lib/app-utils/compose-reusable-components.d.ts +504 -0
  134. package/src/lib/app-utils/compose-reusable-components.js +1366 -0
  135. package/src/lib/app-utils/compose-reusable-components.js.map +1 -0
  136. package/src/lib/app-utils/compress.d.ts +35 -0
  137. package/src/lib/app-utils/compress.js +38 -0
  138. package/src/lib/app-utils/compress.js.map +1 -0
  139. package/src/lib/app-utils/consent-banner-ui.d.ts +226 -0
  140. package/src/lib/app-utils/consent-banner-ui.js +583 -0
  141. package/src/lib/app-utils/consent-banner-ui.js.map +1 -0
  142. package/src/lib/app-utils/consent-groups.d.ts +189 -0
  143. package/src/lib/app-utils/consent-groups.js +219 -0
  144. package/src/lib/app-utils/consent-groups.js.map +1 -0
  145. package/src/lib/app-utils/consent-preferences-dialog.d.ts +58 -0
  146. package/src/lib/app-utils/consent-preferences-dialog.js +106 -0
  147. package/src/lib/app-utils/consent-preferences-dialog.js.map +1 -0
  148. package/src/lib/app-utils/console-record-links.d.ts +163 -0
  149. package/src/lib/app-utils/console-record-links.js +178 -0
  150. package/src/lib/app-utils/console-record-links.js.map +1 -0
  151. package/src/lib/app-utils/console-routes.d.ts +658 -0
  152. package/src/lib/app-utils/console-routes.js +489 -0
  153. package/src/lib/app-utils/console-routes.js.map +1 -0
  154. package/src/lib/app-utils/console-widget-slot-context.d.ts +46 -0
  155. package/src/lib/app-utils/console-widget-slot-context.js +23 -0
  156. package/src/lib/app-utils/console-widget-slot-context.js.map +1 -0
  157. package/src/lib/app-utils/contact-custom-fields.d.ts +191 -0
  158. package/src/lib/app-utils/contact-custom-fields.js +349 -0
  159. package/src/lib/app-utils/contact-custom-fields.js.map +1 -0
  160. package/src/lib/app-utils/contact-holder.d.ts +52 -0
  161. package/src/lib/app-utils/contact-holder.js +98 -0
  162. package/src/lib/app-utils/contact-holder.js.map +1 -0
  163. package/src/lib/app-utils/contact-merge.d.ts +136 -0
  164. package/src/lib/app-utils/contact-merge.js +379 -0
  165. package/src/lib/app-utils/contact-merge.js.map +1 -0
  166. package/src/lib/app-utils/contacts.d.ts +554 -0
  167. package/src/lib/app-utils/contacts.js +401 -0
  168. package/src/lib/app-utils/contacts.js.map +1 -0
  169. package/src/lib/app-utils/content-author-profile.d.ts +68 -0
  170. package/src/lib/app-utils/content-author-profile.js +118 -0
  171. package/src/lib/app-utils/content-author-profile.js.map +1 -0
  172. package/src/lib/app-utils/content-authors.d.ts +662 -0
  173. package/src/lib/app-utils/content-authors.js +771 -0
  174. package/src/lib/app-utils/content-authors.js.map +1 -0
  175. package/src/lib/app-utils/content-schema-type.d.ts +81 -0
  176. package/src/lib/app-utils/content-schema-type.js +87 -0
  177. package/src/lib/app-utils/content-schema-type.js.map +1 -0
  178. package/src/lib/app-utils/contexts.d.ts +35 -0
  179. package/src/lib/app-utils/contexts.js +35 -0
  180. package/src/lib/app-utils/contexts.js.map +1 -0
  181. package/src/lib/app-utils/create-resource-uid.d.ts +18 -0
  182. package/src/lib/app-utils/create-resource-uid.js +23 -0
  183. package/src/lib/app-utils/create-resource-uid.js.map +1 -0
  184. package/src/lib/app-utils/crm-booking.d.ts +75 -0
  185. package/src/lib/app-utils/crm-booking.js +133 -0
  186. package/src/lib/app-utils/crm-booking.js.map +1 -0
  187. package/src/lib/app-utils/crm-csv.d.ts +232 -0
  188. package/src/lib/app-utils/crm-csv.js +432 -0
  189. package/src/lib/app-utils/crm-csv.js.map +1 -0
  190. package/src/lib/app-utils/crm-digest.d.ts +179 -0
  191. package/src/lib/app-utils/crm-digest.js +271 -0
  192. package/src/lib/app-utils/crm-digest.js.map +1 -0
  193. package/src/lib/app-utils/crm-email-templates.d.ts +172 -0
  194. package/src/lib/app-utils/crm-email-templates.js +382 -0
  195. package/src/lib/app-utils/crm-email-templates.js.map +1 -0
  196. package/src/lib/app-utils/crm-inbound.d.ts +245 -0
  197. package/src/lib/app-utils/crm-inbound.js +407 -0
  198. package/src/lib/app-utils/crm-inbound.js.map +1 -0
  199. package/src/lib/app-utils/crm-kinds.d.ts +73 -0
  200. package/src/lib/app-utils/crm-kinds.js +92 -0
  201. package/src/lib/app-utils/crm-kinds.js.map +1 -0
  202. package/src/lib/app-utils/crm-next-activity.d.ts +107 -0
  203. package/src/lib/app-utils/crm-next-activity.js +140 -0
  204. package/src/lib/app-utils/crm-next-activity.js.map +1 -0
  205. package/src/lib/app-utils/crm-reports.d.ts +479 -0
  206. package/src/lib/app-utils/crm-reports.js +680 -0
  207. package/src/lib/app-utils/crm-reports.js.map +1 -0
  208. package/src/lib/app-utils/crm-task-reminders.d.ts +129 -0
  209. package/src/lib/app-utils/crm-task-reminders.js +139 -0
  210. package/src/lib/app-utils/crm-task-reminders.js.map +1 -0
  211. package/src/lib/app-utils/crm.d.ts +1546 -0
  212. package/src/lib/app-utils/crm.js +1814 -0
  213. package/src/lib/app-utils/crm.js.map +1 -0
  214. package/src/lib/app-utils/csp-report.d.ts +84 -0
  215. package/src/lib/app-utils/csp-report.js +177 -0
  216. package/src/lib/app-utils/csp-report.js.map +1 -0
  217. package/src/lib/app-utils/csv-import.d.ts +192 -0
  218. package/src/lib/app-utils/csv-import.js +279 -0
  219. package/src/lib/app-utils/csv-import.js.map +1 -0
  220. package/src/lib/app-utils/dataset-csv.d.ts +109 -0
  221. package/src/lib/app-utils/dataset-csv.js +235 -0
  222. package/src/lib/app-utils/dataset-csv.js.map +1 -0
  223. package/src/lib/app-utils/dataset-models.d.ts +194 -0
  224. package/src/lib/app-utils/dataset-models.js +409 -0
  225. package/src/lib/app-utils/dataset-models.js.map +1 -0
  226. package/src/lib/app-utils/dataset-query.d.ts +57 -0
  227. package/src/lib/app-utils/dataset-query.js +126 -0
  228. package/src/lib/app-utils/dataset-query.js.map +1 -0
  229. package/src/lib/app-utils/datasets.d.ts +136 -0
  230. package/src/lib/app-utils/datasets.js +177 -0
  231. package/src/lib/app-utils/datasets.js.map +1 -0
  232. package/src/lib/app-utils/decompress.d.ts +36 -0
  233. package/src/lib/app-utils/decompress.js +32 -0
  234. package/src/lib/app-utils/decompress.js.map +1 -0
  235. package/src/lib/app-utils/dedicated-sending-domain.d.ts +47 -0
  236. package/src/lib/app-utils/dedicated-sending-domain.js +114 -0
  237. package/src/lib/app-utils/dedicated-sending-domain.js.map +1 -0
  238. package/src/lib/app-utils/deferred-image.d.ts +86 -0
  239. package/src/lib/app-utils/deferred-image.js +83 -0
  240. package/src/lib/app-utils/deferred-image.js.map +1 -0
  241. package/src/lib/app-utils/definition-canvas-tree.d.ts +61 -0
  242. package/src/lib/app-utils/definition-canvas-tree.js +126 -0
  243. package/src/lib/app-utils/definition-canvas-tree.js.map +1 -0
  244. package/src/lib/app-utils/deployment-shape.d.ts +167 -0
  245. package/src/lib/app-utils/deployment-shape.js +238 -0
  246. package/src/lib/app-utils/deployment-shape.js.map +1 -0
  247. package/src/lib/app-utils/detect-template-placeholders.d.ts +30 -0
  248. package/src/lib/app-utils/detect-template-placeholders.js +53 -0
  249. package/src/lib/app-utils/detect-template-placeholders.js.map +1 -0
  250. package/src/lib/app-utils/dmca-counter-notice.d.ts +185 -0
  251. package/src/lib/app-utils/dmca-counter-notice.js +277 -0
  252. package/src/lib/app-utils/dmca-counter-notice.js.map +1 -0
  253. package/src/lib/app-utils/docs-deflection.d.ts +156 -0
  254. package/src/lib/app-utils/docs-deflection.js +547 -0
  255. package/src/lib/app-utils/docs-deflection.js.map +1 -0
  256. package/src/lib/app-utils/docs-help.d.ts +57 -0
  257. package/src/lib/app-utils/docs-help.generated.d.ts +303 -0
  258. package/src/lib/app-utils/docs-help.generated.js +867 -0
  259. package/src/lib/app-utils/docs-help.generated.js.map +1 -0
  260. package/src/lib/app-utils/docs-help.js +46 -0
  261. package/src/lib/app-utils/docs-help.js.map +1 -0
  262. package/src/lib/app-utils/docs-index.generated.d.ts +29 -0
  263. package/src/lib/app-utils/docs-index.generated.js +8388 -0
  264. package/src/lib/app-utils/docs-index.generated.js.map +1 -0
  265. package/src/lib/app-utils/docs-retrieval.d.ts +67 -0
  266. package/src/lib/app-utils/docs-retrieval.js +188 -0
  267. package/src/lib/app-utils/docs-retrieval.js.map +1 -0
  268. package/src/lib/app-utils/document-landmark.d.ts +50 -0
  269. package/src/lib/app-utils/document-landmark.js +100 -0
  270. package/src/lib/app-utils/document-landmark.js.map +1 -0
  271. package/src/lib/app-utils/duplicate-resource.d.ts +101 -0
  272. package/src/lib/app-utils/duplicate-resource.js +206 -0
  273. package/src/lib/app-utils/duplicate-resource.js.map +1 -0
  274. package/src/lib/app-utils/dynamic-list-rule.d.ts +471 -0
  275. package/src/lib/app-utils/dynamic-list-rule.js +914 -0
  276. package/src/lib/app-utils/dynamic-list-rule.js.map +1 -0
  277. package/src/lib/app-utils/element-animation.d.ts +200 -0
  278. package/src/lib/app-utils/element-animation.js +233 -0
  279. package/src/lib/app-utils/element-animation.js.map +1 -0
  280. package/src/lib/app-utils/element-hidden-style.d.ts +46 -0
  281. package/src/lib/app-utils/element-hidden-style.js +48 -0
  282. package/src/lib/app-utils/element-hidden-style.js.map +1 -0
  283. package/src/lib/app-utils/element-ui.d.ts +243 -0
  284. package/src/lib/app-utils/element-ui.js +459 -0
  285. package/src/lib/app-utils/element-ui.js.map +1 -0
  286. package/src/lib/app-utils/email-starter-policy.d.ts +160 -0
  287. package/src/lib/app-utils/email-starter-policy.js +327 -0
  288. package/src/lib/app-utils/email-starter-policy.js.map +1 -0
  289. package/src/lib/app-utils/email-topics.d.ts +310 -0
  290. package/src/lib/app-utils/email-topics.js +336 -0
  291. package/src/lib/app-utils/email-topics.js.map +1 -0
  292. package/src/lib/app-utils/enabled-plugins-context.d.ts +100 -0
  293. package/src/lib/app-utils/enabled-plugins-context.js +113 -0
  294. package/src/lib/app-utils/enabled-plugins-context.js.map +1 -0
  295. package/src/lib/app-utils/ensure-canvas-root.d.ts +38 -0
  296. package/src/lib/app-utils/ensure-canvas-root.js +61 -0
  297. package/src/lib/app-utils/ensure-canvas-root.js.map +1 -0
  298. package/src/lib/app-utils/entity-picker-context.d.ts +199 -0
  299. package/src/lib/app-utils/entity-picker-context.js +93 -0
  300. package/src/lib/app-utils/entity-picker-context.js.map +1 -0
  301. package/src/lib/app-utils/error-beacon.d.ts +107 -0
  302. package/src/lib/app-utils/error-beacon.js +296 -0
  303. package/src/lib/app-utils/error-beacon.js.map +1 -0
  304. package/src/lib/app-utils/expand-repeatables.d.ts +172 -0
  305. package/src/lib/app-utils/expand-repeatables.js +299 -0
  306. package/src/lib/app-utils/expand-repeatables.js.map +1 -0
  307. package/src/lib/app-utils/foreign-script.d.ts +82 -0
  308. package/src/lib/app-utils/foreign-script.js +102 -0
  309. package/src/lib/app-utils/foreign-script.js.map +1 -0
  310. package/src/lib/app-utils/form-abuse-ceiling.d.ts +146 -0
  311. package/src/lib/app-utils/form-abuse-ceiling.js +158 -0
  312. package/src/lib/app-utils/form-abuse-ceiling.js.map +1 -0
  313. package/src/lib/app-utils/form-contract.d.ts +198 -0
  314. package/src/lib/app-utils/form-contract.js +282 -0
  315. package/src/lib/app-utils/form-contract.js.map +1 -0
  316. package/src/lib/app-utils/form-dataset-binding.d.ts +50 -0
  317. package/src/lib/app-utils/form-dataset-binding.js +74 -0
  318. package/src/lib/app-utils/form-dataset-binding.js.map +1 -0
  319. package/src/lib/app-utils/forms.d.ts +727 -0
  320. package/src/lib/app-utils/forms.js +777 -0
  321. package/src/lib/app-utils/forms.js.map +1 -0
  322. package/src/lib/app-utils/functions.d.ts +188 -0
  323. package/src/lib/app-utils/functions.js +529 -0
  324. package/src/lib/app-utils/functions.js.map +1 -0
  325. package/src/lib/app-utils/guarded-version-save.d.ts +91 -0
  326. package/src/lib/app-utils/guarded-version-save.js +131 -0
  327. package/src/lib/app-utils/guarded-version-save.js.map +1 -0
  328. package/src/lib/app-utils/health-report.d.ts +1766 -0
  329. package/src/lib/app-utils/health-report.js +2072 -0
  330. package/src/lib/app-utils/health-report.js.map +1 -0
  331. package/src/lib/app-utils/host-naming.d.ts +135 -0
  332. package/src/lib/app-utils/host-naming.js +188 -0
  333. package/src/lib/app-utils/host-naming.js.map +1 -0
  334. package/src/lib/app-utils/host-permissions.d.ts +76 -0
  335. package/src/lib/app-utils/host-permissions.js +119 -0
  336. package/src/lib/app-utils/host-permissions.js.map +1 -0
  337. package/src/lib/app-utils/host-tokens.d.ts +228 -0
  338. package/src/lib/app-utils/host-tokens.js +304 -0
  339. package/src/lib/app-utils/host-tokens.js.map +1 -0
  340. package/src/lib/app-utils/idp-profile.d.ts +83 -0
  341. package/src/lib/app-utils/idp-profile.js +268 -0
  342. package/src/lib/app-utils/idp-profile.js.map +1 -0
  343. package/src/lib/app-utils/image-upload-types.d.ts +49 -0
  344. package/src/lib/app-utils/image-upload-types.js +86 -0
  345. package/src/lib/app-utils/image-upload-types.js.map +1 -0
  346. package/src/lib/app-utils/index.d.ts +18 -0
  347. package/src/lib/app-utils/index.js +23 -0
  348. package/src/lib/app-utils/index.js.map +1 -0
  349. package/src/lib/app-utils/internal-traffic.d.ts +197 -0
  350. package/src/lib/app-utils/internal-traffic.js +288 -0
  351. package/src/lib/app-utils/internal-traffic.js.map +1 -0
  352. package/src/lib/app-utils/lineal-order.d.ts +62 -0
  353. package/src/lib/app-utils/lineal-order.js +65 -0
  354. package/src/lib/app-utils/lineal-order.js.map +1 -0
  355. package/src/lib/app-utils/link-references.d.ts +36 -0
  356. package/src/lib/app-utils/link-references.js +89 -0
  357. package/src/lib/app-utils/link-references.js.map +1 -0
  358. package/src/lib/app-utils/link-target-search-context.d.ts +123 -0
  359. package/src/lib/app-utils/link-target-search-context.js +221 -0
  360. package/src/lib/app-utils/link-target-search-context.js.map +1 -0
  361. package/src/lib/app-utils/list-assignment-policy.d.ts +169 -0
  362. package/src/lib/app-utils/list-assignment-policy.js +170 -0
  363. package/src/lib/app-utils/list-assignment-policy.js.map +1 -0
  364. package/src/lib/app-utils/list-import.d.ts +158 -0
  365. package/src/lib/app-utils/list-import.js +332 -0
  366. package/src/lib/app-utils/list-import.js.map +1 -0
  367. package/src/lib/app-utils/llms-txt.d.ts +104 -0
  368. package/src/lib/app-utils/llms-txt.js +144 -0
  369. package/src/lib/app-utils/llms-txt.js.map +1 -0
  370. package/src/lib/app-utils/local-storage-budget.d.ts +75 -0
  371. package/src/lib/app-utils/local-storage-budget.js +153 -0
  372. package/src/lib/app-utils/local-storage-budget.js.map +1 -0
  373. package/src/lib/app-utils/lockdown.d.ts +698 -0
  374. package/src/lib/app-utils/lockdown.js +929 -0
  375. package/src/lib/app-utils/lockdown.js.map +1 -0
  376. package/src/lib/app-utils/margin-utilization.d.ts +267 -0
  377. package/src/lib/app-utils/margin-utilization.js +351 -0
  378. package/src/lib/app-utils/margin-utilization.js.map +1 -0
  379. package/src/lib/app-utils/markdown-lite.d.ts +297 -0
  380. package/src/lib/app-utils/markdown-lite.js +705 -0
  381. package/src/lib/app-utils/markdown-lite.js.map +1 -0
  382. package/src/lib/app-utils/marketing-consent.d.ts +704 -0
  383. package/src/lib/app-utils/marketing-consent.js +783 -0
  384. package/src/lib/app-utils/marketing-consent.js.map +1 -0
  385. package/src/lib/app-utils/marketplace-listing-visibility.d.ts +120 -0
  386. package/src/lib/app-utils/marketplace-listing-visibility.js +139 -0
  387. package/src/lib/app-utils/marketplace-listing-visibility.js.map +1 -0
  388. package/src/lib/app-utils/marketplace-overrides.d.ts +271 -0
  389. package/src/lib/app-utils/marketplace-overrides.js +462 -0
  390. package/src/lib/app-utils/marketplace-overrides.js.map +1 -0
  391. package/src/lib/app-utils/marketplace-provenance.d.ts +150 -0
  392. package/src/lib/app-utils/marketplace-provenance.js +136 -0
  393. package/src/lib/app-utils/marketplace-provenance.js.map +1 -0
  394. package/src/lib/app-utils/marketplace-theme.d.ts +237 -0
  395. package/src/lib/app-utils/marketplace-theme.js +525 -0
  396. package/src/lib/app-utils/marketplace-theme.js.map +1 -0
  397. package/src/lib/app-utils/marketplace-update-state.d.ts +119 -0
  398. package/src/lib/app-utils/marketplace-update-state.js +132 -0
  399. package/src/lib/app-utils/marketplace-update-state.js.map +1 -0
  400. package/src/lib/app-utils/marketplace-verification.d.ts +95 -0
  401. package/src/lib/app-utils/marketplace-verification.js +81 -0
  402. package/src/lib/app-utils/marketplace-verification.js.map +1 -0
  403. package/src/lib/app-utils/measure-node-map.d.ts +76 -0
  404. package/src/lib/app-utils/measure-node-map.js +111 -0
  405. package/src/lib/app-utils/measure-node-map.js.map +1 -0
  406. package/src/lib/app-utils/media-alt.d.ts +55 -0
  407. package/src/lib/app-utils/media-alt.js +58 -0
  408. package/src/lib/app-utils/media-alt.js.map +1 -0
  409. package/src/lib/app-utils/media-asset-facts.d.ts +125 -0
  410. package/src/lib/app-utils/media-asset-facts.js +467 -0
  411. package/src/lib/app-utils/media-asset-facts.js.map +1 -0
  412. package/src/lib/app-utils/media-cdn-scope.d.ts +65 -0
  413. package/src/lib/app-utils/media-cdn-scope.js +75 -0
  414. package/src/lib/app-utils/media-cdn-scope.js.map +1 -0
  415. package/src/lib/app-utils/media-folders.d.ts +161 -0
  416. package/src/lib/app-utils/media-folders.js +230 -0
  417. package/src/lib/app-utils/media-folders.js.map +1 -0
  418. package/src/lib/app-utils/media-metadata.d.ts +277 -0
  419. package/src/lib/app-utils/media-metadata.js +388 -0
  420. package/src/lib/app-utils/media-metadata.js.map +1 -0
  421. package/src/lib/app-utils/media-picker-context.d.ts +93 -0
  422. package/src/lib/app-utils/media-picker-context.js +26 -0
  423. package/src/lib/app-utils/media-picker-context.js.map +1 -0
  424. package/src/lib/app-utils/media-quarantine.d.ts +247 -0
  425. package/src/lib/app-utils/media-quarantine.js +323 -0
  426. package/src/lib/app-utils/media-quarantine.js.map +1 -0
  427. package/src/lib/app-utils/media-ref.d.ts +661 -0
  428. package/src/lib/app-utils/media-ref.js +1055 -0
  429. package/src/lib/app-utils/media-ref.js.map +1 -0
  430. package/src/lib/app-utils/media-takedown-reach.d.ts +126 -0
  431. package/src/lib/app-utils/media-takedown-reach.js +143 -0
  432. package/src/lib/app-utils/media-takedown-reach.js.map +1 -0
  433. package/src/lib/app-utils/member-email-aliases.d.ts +180 -0
  434. package/src/lib/app-utils/member-email-aliases.js +217 -0
  435. package/src/lib/app-utils/member-email-aliases.js.map +1 -0
  436. package/src/lib/app-utils/merge-node-sx.d.ts +47 -0
  437. package/src/lib/app-utils/merge-node-sx.js +123 -0
  438. package/src/lib/app-utils/merge-node-sx.js.map +1 -0
  439. package/src/lib/app-utils/name-match.d.ts +155 -0
  440. package/src/lib/app-utils/name-match.js +175 -0
  441. package/src/lib/app-utils/name-match.js.map +1 -0
  442. package/src/lib/app-utils/name-search.d.ts +117 -0
  443. package/src/lib/app-utils/name-search.js +145 -0
  444. package/src/lib/app-utils/name-search.js.map +1 -0
  445. package/src/lib/app-utils/node-capabilities.d.ts +85 -0
  446. package/src/lib/app-utils/node-capabilities.js +88 -0
  447. package/src/lib/app-utils/node-capabilities.js.map +1 -0
  448. package/src/lib/app-utils/node-definition-sanitizer.d.ts +164 -0
  449. package/src/lib/app-utils/node-definition-sanitizer.js +402 -0
  450. package/src/lib/app-utils/node-definition-sanitizer.js.map +1 -0
  451. package/src/lib/app-utils/node-identity.d.ts +47 -0
  452. package/src/lib/app-utils/node-identity.js +50 -0
  453. package/src/lib/app-utils/node-identity.js.map +1 -0
  454. package/src/lib/app-utils/node-interactions.d.ts +102 -0
  455. package/src/lib/app-utils/node-interactions.js +192 -0
  456. package/src/lib/app-utils/node-interactions.js.map +1 -0
  457. package/src/lib/app-utils/node-url-policy.d.ts +54 -0
  458. package/src/lib/app-utils/node-url-policy.js +72 -0
  459. package/src/lib/app-utils/node-url-policy.js.map +1 -0
  460. package/src/lib/app-utils/notifications.d.ts +71 -0
  461. package/src/lib/app-utils/notifications.js +101 -0
  462. package/src/lib/app-utils/notifications.js.map +1 -0
  463. package/src/lib/app-utils/onboarding-deep-link.d.ts +120 -0
  464. package/src/lib/app-utils/onboarding-deep-link.js +142 -0
  465. package/src/lib/app-utils/onboarding-deep-link.js.map +1 -0
  466. package/src/lib/app-utils/operator-identity.d.ts +207 -0
  467. package/src/lib/app-utils/operator-identity.js +186 -0
  468. package/src/lib/app-utils/operator-identity.js.map +1 -0
  469. package/src/lib/app-utils/org-billing-doc.d.ts +231 -0
  470. package/src/lib/app-utils/org-billing-doc.js +238 -0
  471. package/src/lib/app-utils/org-billing-doc.js.map +1 -0
  472. package/src/lib/app-utils/org-override-reason.d.ts +100 -0
  473. package/src/lib/app-utils/org-override-reason.js +116 -0
  474. package/src/lib/app-utils/org-override-reason.js.map +1 -0
  475. package/src/lib/app-utils/org-permissions.d.ts +194 -0
  476. package/src/lib/app-utils/org-permissions.js +357 -0
  477. package/src/lib/app-utils/org-permissions.js.map +1 -0
  478. package/src/lib/app-utils/org-roles.d.ts +72 -0
  479. package/src/lib/app-utils/org-roles.js +131 -0
  480. package/src/lib/app-utils/org-roles.js.map +1 -0
  481. package/src/lib/app-utils/organizations.d.ts +407 -0
  482. package/src/lib/app-utils/organizations.js +511 -0
  483. package/src/lib/app-utils/organizations.js.map +1 -0
  484. package/src/lib/app-utils/page-header-actions-context.d.ts +83 -0
  485. package/src/lib/app-utils/page-header-actions-context.js +58 -0
  486. package/src/lib/app-utils/page-header-actions-context.js.map +1 -0
  487. package/src/lib/app-utils/page-header-record-context.d.ts +80 -0
  488. package/src/lib/app-utils/page-header-record-context.js +64 -0
  489. package/src/lib/app-utils/page-header-record-context.js.map +1 -0
  490. package/src/lib/app-utils/page-markdown.d.ts +103 -0
  491. package/src/lib/app-utils/page-markdown.js +385 -0
  492. package/src/lib/app-utils/page-markdown.js.map +1 -0
  493. package/src/lib/app-utils/paid-media-source.d.ts +90 -0
  494. package/src/lib/app-utils/paid-media-source.js +184 -0
  495. package/src/lib/app-utils/paid-media-source.js.map +1 -0
  496. package/src/lib/app-utils/palette-sx.d.ts +34 -0
  497. package/src/lib/app-utils/palette-sx.js +150 -0
  498. package/src/lib/app-utils/palette-sx.js.map +1 -0
  499. package/src/lib/app-utils/password-policy.d.ts +47 -0
  500. package/src/lib/app-utils/password-policy.js +46 -0
  501. package/src/lib/app-utils/password-policy.js.map +1 -0
  502. package/src/lib/app-utils/payments-configured.d.ts +84 -0
  503. package/src/lib/app-utils/payments-configured.js +88 -0
  504. package/src/lib/app-utils/payments-configured.js.map +1 -0
  505. package/src/lib/app-utils/person-erasure.d.ts +126 -0
  506. package/src/lib/app-utils/person-erasure.js +121 -0
  507. package/src/lib/app-utils/person-erasure.js.map +1 -0
  508. package/src/lib/app-utils/person-key.d.ts +32 -0
  509. package/src/lib/app-utils/person-key.js +62 -0
  510. package/src/lib/app-utils/person-key.js.map +1 -0
  511. package/src/lib/app-utils/plan-entitlements.d.ts +2756 -0
  512. package/src/lib/app-utils/plan-entitlements.js +4085 -0
  513. package/src/lib/app-utils/plan-entitlements.js.map +1 -0
  514. package/src/lib/app-utils/platform-ad-conversions.d.ts +122 -0
  515. package/src/lib/app-utils/platform-ad-conversions.js +174 -0
  516. package/src/lib/app-utils/platform-ad-conversions.js.map +1 -0
  517. package/src/lib/app-utils/platform-advertising-tags.d.ts +139 -0
  518. package/src/lib/app-utils/platform-advertising-tags.js +203 -0
  519. package/src/lib/app-utils/platform-advertising-tags.js.map +1 -0
  520. package/src/lib/app-utils/platform-brand.d.ts +151 -0
  521. package/src/lib/app-utils/platform-brand.js +175 -0
  522. package/src/lib/app-utils/platform-brand.js.map +1 -0
  523. package/src/lib/app-utils/platform-consent-default.d.ts +142 -0
  524. package/src/lib/app-utils/platform-consent-default.js +295 -0
  525. package/src/lib/app-utils/platform-consent-default.js.map +1 -0
  526. package/src/lib/app-utils/platform-marketing-consent.d.ts +151 -0
  527. package/src/lib/app-utils/platform-marketing-consent.js +182 -0
  528. package/src/lib/app-utils/platform-marketing-consent.js.map +1 -0
  529. package/src/lib/app-utils/platform-marketing-host.d.ts +33 -0
  530. package/src/lib/app-utils/platform-marketing-host.js +97 -0
  531. package/src/lib/app-utils/platform-marketing-host.js.map +1 -0
  532. package/src/lib/app-utils/platform-visitor-consent.d.ts +252 -0
  533. package/src/lib/app-utils/platform-visitor-consent.js +533 -0
  534. package/src/lib/app-utils/platform-visitor-consent.js.map +1 -0
  535. package/src/lib/app-utils/plugin-api-cross-origin.d.ts +61 -0
  536. package/src/lib/app-utils/plugin-api-cross-origin.js +202 -0
  537. package/src/lib/app-utils/plugin-api-cross-origin.js.map +1 -0
  538. package/src/lib/app-utils/plugin-api-rate-limit.d.ts +192 -0
  539. package/src/lib/app-utils/plugin-api-rate-limit.js +270 -0
  540. package/src/lib/app-utils/plugin-api-rate-limit.js.map +1 -0
  541. package/src/lib/app-utils/plugin-artifact-path.d.ts +32 -0
  542. package/src/lib/app-utils/plugin-artifact-path.js +33 -0
  543. package/src/lib/app-utils/plugin-artifact-path.js.map +1 -0
  544. package/src/lib/app-utils/plugin-bundle-checks.d.ts +148 -0
  545. package/src/lib/app-utils/plugin-bundle-checks.js +989 -0
  546. package/src/lib/app-utils/plugin-bundle-checks.js.map +1 -0
  547. package/src/lib/app-utils/plugin-manifest.d.ts +516 -0
  548. package/src/lib/app-utils/plugin-manifest.js +687 -0
  549. package/src/lib/app-utils/plugin-manifest.js.map +1 -0
  550. package/src/lib/app-utils/published-legal-pages.d.ts +71 -0
  551. package/src/lib/app-utils/published-legal-pages.js +90 -0
  552. package/src/lib/app-utils/published-legal-pages.js.map +1 -0
  553. package/src/lib/app-utils/publisher-agreement.d.ts +254 -0
  554. package/src/lib/app-utils/publisher-agreement.js +274 -0
  555. package/src/lib/app-utils/publisher-agreement.js.map +1 -0
  556. package/src/lib/app-utils/publisher-attestation.d.ts +99 -0
  557. package/src/lib/app-utils/publisher-attestation.js +158 -0
  558. package/src/lib/app-utils/publisher-attestation.js.map +1 -0
  559. package/src/lib/app-utils/recipient-email-render.d.ts +216 -0
  560. package/src/lib/app-utils/recipient-email-render.js +221 -0
  561. package/src/lib/app-utils/recipient-email-render.js.map +1 -0
  562. package/src/lib/app-utils/redispatch-caught-error.d.ts +38 -0
  563. package/src/lib/app-utils/redispatch-caught-error.js +46 -0
  564. package/src/lib/app-utils/redispatch-caught-error.js.map +1 -0
  565. package/src/lib/app-utils/registering-plugin.d.ts +19 -0
  566. package/src/lib/app-utils/registering-plugin.js +38 -0
  567. package/src/lib/app-utils/registering-plugin.js.map +1 -0
  568. package/src/lib/app-utils/release-flags.d.ts +283 -0
  569. package/src/lib/app-utils/release-flags.js +518 -0
  570. package/src/lib/app-utils/release-flags.js.map +1 -0
  571. package/src/lib/app-utils/repair-canvas-nodes.d.ts +130 -0
  572. package/src/lib/app-utils/repair-canvas-nodes.js +298 -0
  573. package/src/lib/app-utils/repair-canvas-nodes.js.map +1 -0
  574. package/src/lib/app-utils/repeat-infringer.d.ts +166 -0
  575. package/src/lib/app-utils/repeat-infringer.js +188 -0
  576. package/src/lib/app-utils/repeat-infringer.js.map +1 -0
  577. package/src/lib/app-utils/repeat-sources.d.ts +115 -0
  578. package/src/lib/app-utils/repeat-sources.js +86 -0
  579. package/src/lib/app-utils/repeat-sources.js.map +1 -0
  580. package/src/lib/app-utils/request-geo.d.ts +114 -0
  581. package/src/lib/app-utils/request-geo.js +247 -0
  582. package/src/lib/app-utils/request-geo.js.map +1 -0
  583. package/src/lib/app-utils/request-ip.d.ts +213 -0
  584. package/src/lib/app-utils/request-ip.js +344 -0
  585. package/src/lib/app-utils/request-ip.js.map +1 -0
  586. package/src/lib/app-utils/resolve-named-tokens.d.ts +26 -0
  587. package/src/lib/app-utils/resolve-named-tokens.js +59 -0
  588. package/src/lib/app-utils/resolve-named-tokens.js.map +1 -0
  589. package/src/lib/app-utils/responsive-typography-sx.d.ts +77 -0
  590. package/src/lib/app-utils/responsive-typography-sx.js +122 -0
  591. package/src/lib/app-utils/responsive-typography-sx.js.map +1 -0
  592. package/src/lib/app-utils/reusable-component-keys.d.ts +135 -0
  593. package/src/lib/app-utils/reusable-component-keys.js +140 -0
  594. package/src/lib/app-utils/reusable-component-keys.js.map +1 -0
  595. package/src/lib/app-utils/reusable-prop-values.d.ts +199 -0
  596. package/src/lib/app-utils/reusable-prop-values.js +494 -0
  597. package/src/lib/app-utils/reusable-prop-values.js.map +1 -0
  598. package/src/lib/app-utils/safe-json-ld.d.ts +29 -0
  599. package/src/lib/app-utils/safe-json-ld.js +37 -0
  600. package/src/lib/app-utils/safe-json-ld.js.map +1 -0
  601. package/src/lib/app-utils/sanitize-svg.d.ts +55 -0
  602. package/src/lib/app-utils/sanitize-svg.js +460 -0
  603. package/src/lib/app-utils/sanitize-svg.js.map +1 -0
  604. package/src/lib/app-utils/scheme-sx.d.ts +84 -0
  605. package/src/lib/app-utils/scheme-sx.js +148 -0
  606. package/src/lib/app-utils/scheme-sx.js.map +1 -0
  607. package/src/lib/app-utils/scope-tokens.d.ts +249 -0
  608. package/src/lib/app-utils/scope-tokens.js +331 -0
  609. package/src/lib/app-utils/scope-tokens.js.map +1 -0
  610. package/src/lib/app-utils/screen-link-context-value.d.ts +57 -0
  611. package/src/lib/app-utils/screen-link-context-value.js +43 -0
  612. package/src/lib/app-utils/screen-link-context-value.js.map +1 -0
  613. package/src/lib/app-utils/screen-link-context.d.ts +185 -0
  614. package/src/lib/app-utils/screen-link-context.js +304 -0
  615. package/src/lib/app-utils/screen-link-context.js.map +1 -0
  616. package/src/lib/app-utils/screen-link-value.d.ts +269 -0
  617. package/src/lib/app-utils/screen-link-value.js +384 -0
  618. package/src/lib/app-utils/screen-link-value.js.map +1 -0
  619. package/src/lib/app-utils/screen-route.d.ts +669 -0
  620. package/src/lib/app-utils/screen-route.js +751 -0
  621. package/src/lib/app-utils/screen-route.js.map +1 -0
  622. package/src/lib/app-utils/screen-seo-fields.d.ts +37 -0
  623. package/src/lib/app-utils/screen-seo-fields.js +42 -0
  624. package/src/lib/app-utils/screen-seo-fields.js.map +1 -0
  625. package/src/lib/app-utils/search-indexing.d.ts +162 -0
  626. package/src/lib/app-utils/search-indexing.js +207 -0
  627. package/src/lib/app-utils/search-indexing.js.map +1 -0
  628. package/src/lib/app-utils/seo-listing-fields.d.ts +70 -0
  629. package/src/lib/app-utils/seo-listing-fields.js +75 -0
  630. package/src/lib/app-utils/seo-listing-fields.js.map +1 -0
  631. package/src/lib/app-utils/seo-locale.d.ts +119 -0
  632. package/src/lib/app-utils/seo-locale.js +133 -0
  633. package/src/lib/app-utils/seo-locale.js.map +1 -0
  634. package/src/lib/app-utils/seo-title-variables.d.ts +149 -0
  635. package/src/lib/app-utils/seo-title-variables.js +190 -0
  636. package/src/lib/app-utils/seo-title-variables.js.map +1 -0
  637. package/src/lib/app-utils/seo-title.d.ts +70 -0
  638. package/src/lib/app-utils/seo-title.js +117 -0
  639. package/src/lib/app-utils/seo-title.js.map +1 -0
  640. package/src/lib/app-utils/server.d.ts +174 -0
  641. package/src/lib/app-utils/server.js +314 -0
  642. package/src/lib/app-utils/server.js.map +1 -0
  643. package/src/lib/app-utils/site-context.d.ts +106 -0
  644. package/src/lib/app-utils/site-context.js +100 -0
  645. package/src/lib/app-utils/site-context.js.map +1 -0
  646. package/src/lib/app-utils/sitemap.d.ts +117 -0
  647. package/src/lib/app-utils/sitemap.js +183 -0
  648. package/src/lib/app-utils/sitemap.js.map +1 -0
  649. package/src/lib/app-utils/social-image.d.ts +112 -0
  650. package/src/lib/app-utils/social-image.js +191 -0
  651. package/src/lib/app-utils/social-image.js.map +1 -0
  652. package/src/lib/app-utils/starter-templates.d.ts +99 -0
  653. package/src/lib/app-utils/starter-templates.js +579 -0
  654. package/src/lib/app-utils/starter-templates.js.map +1 -0
  655. package/src/lib/app-utils/stored-nodes.d.ts +120 -0
  656. package/src/lib/app-utils/stored-nodes.js +174 -0
  657. package/src/lib/app-utils/stored-nodes.js.map +1 -0
  658. package/src/lib/app-utils/strip-undefined.d.ts +59 -0
  659. package/src/lib/app-utils/strip-undefined.js +95 -0
  660. package/src/lib/app-utils/strip-undefined.js.map +1 -0
  661. package/src/lib/app-utils/stripe-deployment-mode.d.ts +47 -0
  662. package/src/lib/app-utils/stripe-deployment-mode.js +70 -0
  663. package/src/lib/app-utils/stripe-deployment-mode.js.map +1 -0
  664. package/src/lib/app-utils/support-tiers.d.ts +108 -0
  665. package/src/lib/app-utils/support-tiers.js +201 -0
  666. package/src/lib/app-utils/support-tiers.js.map +1 -0
  667. package/src/lib/app-utils/timezone-geo-hint.d.ts +36 -0
  668. package/src/lib/app-utils/timezone-geo-hint.js +180 -0
  669. package/src/lib/app-utils/timezone-geo-hint.js.map +1 -0
  670. package/src/lib/app-utils/upload-cors.d.ts +155 -0
  671. package/src/lib/app-utils/upload-cors.js +254 -0
  672. package/src/lib/app-utils/upload-cors.js.map +1 -0
  673. package/src/lib/app-utils/upload-inspection.d.ts +159 -0
  674. package/src/lib/app-utils/upload-inspection.js +539 -0
  675. package/src/lib/app-utils/upload-inspection.js.map +1 -0
  676. package/src/lib/app-utils/url-slug.d.ts +40 -0
  677. package/src/lib/app-utils/url-slug.js +42 -0
  678. package/src/lib/app-utils/url-slug.js.map +1 -0
  679. package/src/lib/app-utils/usage-budget.d.ts +429 -0
  680. package/src/lib/app-utils/usage-budget.js +421 -0
  681. package/src/lib/app-utils/usage-budget.js.map +1 -0
  682. package/src/lib/app-utils/variables.d.ts +96 -0
  683. package/src/lib/app-utils/variables.js +233 -0
  684. package/src/lib/app-utils/variables.js.map +1 -0
  685. package/src/lib/app-utils/video-asset-facts.d.ts +61 -0
  686. package/src/lib/app-utils/video-asset-facts.js +70 -0
  687. package/src/lib/app-utils/video-asset-facts.js.map +1 -0
  688. package/src/lib/app-utils/video-object.d.ts +89 -0
  689. package/src/lib/app-utils/video-object.js +245 -0
  690. package/src/lib/app-utils/video-object.js.map +1 -0
  691. package/src/lib/app-utils/visitor-consent.d.ts +757 -0
  692. package/src/lib/app-utils/visitor-consent.js +981 -0
  693. package/src/lib/app-utils/visitor-consent.js.map +1 -0
  694. package/src/lib/app-utils/visitor-record-ceiling.d.ts +223 -0
  695. package/src/lib/app-utils/visitor-record-ceiling.js +215 -0
  696. package/src/lib/app-utils/visitor-record-ceiling.js.map +1 -0
  697. package/src/lib/app-utils/web-vitals-rum.d.ts +53 -0
  698. package/src/lib/app-utils/web-vitals-rum.js +278 -0
  699. package/src/lib/app-utils/web-vitals-rum.js.map +1 -0
  700. package/src/lib/app-utils/webhook-delivery.d.ts +324 -0
  701. package/src/lib/app-utils/webhook-delivery.js +413 -0
  702. package/src/lib/app-utils/webhook-delivery.js.map +1 -0
  703. package/src/lib/app-utils/where-used.d.ts +57 -0
  704. package/src/lib/app-utils/where-used.js +59 -0
  705. package/src/lib/app-utils/where-used.js.map +1 -0
  706. package/src/lib/app-utils/wistia-embed.d.ts +86 -0
  707. package/src/lib/app-utils/wistia-embed.js +119 -0
  708. package/src/lib/app-utils/wistia-embed.js.map +1 -0
  709. package/src/lib/app-utils/workflows.d.ts +136 -0
  710. package/src/lib/app-utils/workflows.js +346 -0
  711. package/src/lib/app-utils/workflows.js.map +1 -0
  712. package/src/lib/canvas-manager/canvas-manager-tree.d.ts +109 -0
  713. package/src/lib/canvas-manager/canvas-manager-tree.js +139 -0
  714. package/src/lib/canvas-manager/canvas-manager-tree.js.map +1 -0
  715. package/src/lib/canvas-manager/canvas-manager.d.ts +549 -0
  716. package/src/lib/canvas-manager/canvas-manager.js +1311 -0
  717. package/src/lib/canvas-manager/canvas-manager.js.map +1 -0
  718. package/src/lib/canvas-manager/index.d.ts +20 -0
  719. package/src/lib/canvas-manager/index.js +21 -0
  720. package/src/lib/canvas-manager/index.js.map +1 -0
  721. package/src/lib/canvas-manager/stores/index.d.ts +17 -0
  722. package/src/lib/canvas-manager/stores/index.js +18 -0
  723. package/src/lib/canvas-manager/stores/index.js.map +1 -0
  724. package/src/lib/canvas-manager/stores/node.store.d.ts +30 -0
  725. package/src/lib/canvas-manager/stores/node.store.js +45 -0
  726. package/src/lib/canvas-manager/stores/node.store.js.map +1 -0
  727. package/src/lib/components-manager/components-manager.d.ts +56 -0
  728. package/src/lib/components-manager/components-manager.js +191 -0
  729. package/src/lib/components-manager/components-manager.js.map +1 -0
  730. package/src/lib/components-manager/index.d.ts +18 -0
  731. package/src/lib/components-manager/index.js +19 -0
  732. package/src/lib/components-manager/index.js.map +1 -0
  733. package/src/lib/emit-manager/emit-manager.d.ts +56 -0
  734. package/src/lib/emit-manager/emit-manager.js +60 -0
  735. package/src/lib/emit-manager/emit-manager.js.map +1 -0
  736. package/src/lib/emit-manager/index.d.ts +18 -0
  737. package/src/lib/emit-manager/index.js +19 -0
  738. package/src/lib/emit-manager/index.js.map +1 -0
  739. package/src/lib/foundation/constants/_internal.d.ts +18 -0
  740. package/src/lib/foundation/constants/_internal.js +62 -0
  741. package/src/lib/foundation/constants/_internal.js.map +1 -0
  742. package/src/lib/foundation/constants/app.d.ts +23 -0
  743. package/src/lib/foundation/constants/app.js +25 -0
  744. package/src/lib/foundation/constants/app.js.map +1 -0
  745. package/src/lib/foundation/constants/canvas.d.ts +18 -0
  746. package/src/lib/foundation/constants/canvas.js +18 -0
  747. package/src/lib/foundation/constants/canvas.js.map +1 -0
  748. package/src/lib/foundation/constants/components.d.ts +54 -0
  749. package/src/lib/foundation/constants/components.js +61 -0
  750. package/src/lib/foundation/constants/components.js.map +1 -0
  751. package/src/lib/foundation/constants/shared.d.ts +50 -0
  752. package/src/lib/foundation/constants/shared.js +49 -0
  753. package/src/lib/foundation/constants/shared.js.map +1 -0
  754. package/src/lib/foundation/constants/symbol.d.ts +63 -0
  755. package/src/lib/foundation/constants/symbol.js +75 -0
  756. package/src/lib/foundation/constants/symbol.js.map +1 -0
  757. package/src/lib/foundation/definitions/components.types.d.ts +372 -0
  758. package/src/lib/foundation/definitions/components.types.js +180 -0
  759. package/src/lib/foundation/definitions/components.types.js.map +1 -0
  760. package/src/lib/foundation/definitions/contact.types.d.ts +73 -0
  761. package/src/lib/foundation/definitions/contact.types.js +107 -0
  762. package/src/lib/foundation/definitions/contact.types.js.map +1 -0
  763. package/src/lib/foundation/definitions/host-content-collections.d.ts +137 -0
  764. package/src/lib/foundation/definitions/host-content-collections.js +219 -0
  765. package/src/lib/foundation/definitions/host-content-collections.js.map +1 -0
  766. package/src/lib/foundation/definitions/org-billing.types.d.ts +1361 -0
  767. package/src/lib/foundation/definitions/org-billing.types.js +77 -0
  768. package/src/lib/foundation/definitions/org-billing.types.js.map +1 -0
  769. package/src/lib/foundation/definitions/organization.types.d.ts +307 -0
  770. package/src/lib/foundation/definitions/organization.types.js +42 -0
  771. package/src/lib/foundation/definitions/organization.types.js.map +1 -0
  772. package/src/lib/foundation/definitions/platform.types.d.ts +1326 -0
  773. package/src/lib/foundation/definitions/platform.types.js +124 -0
  774. package/src/lib/foundation/definitions/platform.types.js.map +1 -0
  775. package/src/lib/foundation/definitions/property-kinds.d.ts +189 -0
  776. package/src/lib/foundation/definitions/property-kinds.js +565 -0
  777. package/src/lib/foundation/definitions/property-kinds.js.map +1 -0
  778. package/src/lib/foundation/definitions/shared.d.ts +23 -0
  779. package/src/lib/foundation/definitions/shared.js +18 -0
  780. package/src/lib/foundation/definitions/shared.js.map +1 -0
  781. package/src/lib/foundation/definitions/write-deny-coverage.util.d.ts +249 -0
  782. package/src/lib/foundation/definitions/write-deny-coverage.util.js +499 -0
  783. package/src/lib/foundation/definitions/write-deny-coverage.util.js.map +1 -0
  784. package/src/lib/foundation/index.d.ts +32 -0
  785. package/src/lib/foundation/index.js +67 -0
  786. package/src/lib/foundation/index.js.map +1 -0
  787. package/src/lib/lifecycle.d.ts +24 -0
  788. package/src/lib/lifecycle.js +39 -0
  789. package/src/lib/lifecycle.js.map +1 -0
  790. package/src/lib/mst/common.d.ts +17 -0
  791. package/src/lib/mst/common.js +23 -0
  792. package/src/lib/mst/common.js.map +1 -0
  793. package/src/lib/mst/index.d.ts +19 -0
  794. package/src/lib/mst/index.js +20 -0
  795. package/src/lib/mst/index.js.map +1 -0
  796. package/src/lib/mst/json.d.ts +22 -0
  797. package/src/lib/mst/json.js +23 -0
  798. package/src/lib/mst/json.js.map +1 -0
  799. package/src/lib/mst/types.d.ts +20 -0
  800. package/src/lib/mst/types.js +18 -0
  801. package/src/lib/mst/types.js.map +1 -0
  802. package/src/lib/plugin-manager/billing-webhook-hooks.d.ts +77 -0
  803. package/src/lib/plugin-manager/billing-webhook-hooks.js +55 -0
  804. package/src/lib/plugin-manager/billing-webhook-hooks.js.map +1 -0
  805. package/src/lib/plugin-manager/commerce-zone-props.d.ts +172 -0
  806. package/src/lib/plugin-manager/commerce-zone-props.js +31 -0
  807. package/src/lib/plugin-manager/commerce-zone-props.js.map +1 -0
  808. package/src/lib/plugin-manager/custom-fields.d.ts +60 -0
  809. package/src/lib/plugin-manager/custom-fields.js +39 -0
  810. package/src/lib/plugin-manager/custom-fields.js.map +1 -0
  811. package/src/lib/plugin-manager/editor-sessions.d.ts +109 -0
  812. package/src/lib/plugin-manager/editor-sessions.js +137 -0
  813. package/src/lib/plugin-manager/editor-sessions.js.map +1 -0
  814. package/src/lib/plugin-manager/enabled-plugins.d.ts +438 -0
  815. package/src/lib/plugin-manager/enabled-plugins.js +403 -0
  816. package/src/lib/plugin-manager/enabled-plugins.js.map +1 -0
  817. package/src/lib/plugin-manager/feature-plugins.d.ts +1314 -0
  818. package/src/lib/plugin-manager/feature-plugins.js +609 -0
  819. package/src/lib/plugin-manager/feature-plugins.js.map +1 -0
  820. package/src/lib/plugin-manager/first-party-plugins.generated.d.ts +11 -0
  821. package/src/lib/plugin-manager/first-party-plugins.generated.js +149 -0
  822. package/src/lib/plugin-manager/first-party-plugins.generated.js.map +1 -0
  823. package/src/lib/plugin-manager/index.d.ts +42 -0
  824. package/src/lib/plugin-manager/index.js +46 -0
  825. package/src/lib/plugin-manager/index.js.map +1 -0
  826. package/src/lib/plugin-manager/install-presets.d.ts +93 -0
  827. package/src/lib/plugin-manager/install-presets.js +86 -0
  828. package/src/lib/plugin-manager/install-presets.js.map +1 -0
  829. package/src/lib/plugin-manager/media-delivery-provider.d.ts +124 -0
  830. package/src/lib/plugin-manager/media-delivery-provider.js +53 -0
  831. package/src/lib/plugin-manager/media-delivery-provider.js.map +1 -0
  832. package/src/lib/plugin-manager/order-fulfilment.d.ts +142 -0
  833. package/src/lib/plugin-manager/order-fulfilment.js +104 -0
  834. package/src/lib/plugin-manager/order-fulfilment.js.map +1 -0
  835. package/src/lib/plugin-manager/plugin-activity-actions.d.ts +122 -0
  836. package/src/lib/plugin-manager/plugin-activity-actions.js +140 -0
  837. package/src/lib/plugin-manager/plugin-activity-actions.js.map +1 -0
  838. package/src/lib/plugin-manager/plugin-bridge.d.ts +98 -0
  839. package/src/lib/plugin-manager/plugin-bridge.js +154 -0
  840. package/src/lib/plugin-manager/plugin-bridge.js.map +1 -0
  841. package/src/lib/plugin-manager/plugin-config.d.ts +148 -0
  842. package/src/lib/plugin-manager/plugin-config.js +228 -0
  843. package/src/lib/plugin-manager/plugin-config.js.map +1 -0
  844. package/src/lib/plugin-manager/plugin-console-crons.d.ts +139 -0
  845. package/src/lib/plugin-manager/plugin-console-crons.js +177 -0
  846. package/src/lib/plugin-manager/plugin-console-crons.js.map +1 -0
  847. package/src/lib/plugin-manager/plugin-contact-capture.d.ts +220 -0
  848. package/src/lib/plugin-manager/plugin-contact-capture.js +89 -0
  849. package/src/lib/plugin-manager/plugin-contact-capture.js.map +1 -0
  850. package/src/lib/plugin-manager/plugin-contributions.d.ts +244 -0
  851. package/src/lib/plugin-manager/plugin-contributions.js +283 -0
  852. package/src/lib/plugin-manager/plugin-contributions.js.map +1 -0
  853. package/src/lib/plugin-manager/plugin-entitlement-keys.d.ts +169 -0
  854. package/src/lib/plugin-manager/plugin-entitlement-keys.js +84 -0
  855. package/src/lib/plugin-manager/plugin-entitlement-keys.js.map +1 -0
  856. package/src/lib/plugin-manager/plugin-entitlements.d.ts +181 -0
  857. package/src/lib/plugin-manager/plugin-entitlements.js +188 -0
  858. package/src/lib/plugin-manager/plugin-entitlements.js.map +1 -0
  859. package/src/lib/plugin-manager/plugin-events.d.ts +145 -0
  860. package/src/lib/plugin-manager/plugin-events.js +79 -0
  861. package/src/lib/plugin-manager/plugin-events.js.map +1 -0
  862. package/src/lib/plugin-manager/plugin-figures.d.ts +251 -0
  863. package/src/lib/plugin-manager/plugin-figures.js +252 -0
  864. package/src/lib/plugin-manager/plugin-figures.js.map +1 -0
  865. package/src/lib/plugin-manager/plugin-host-collections.d.ts +146 -0
  866. package/src/lib/plugin-manager/plugin-host-collections.js +116 -0
  867. package/src/lib/plugin-manager/plugin-host-collections.js.map +1 -0
  868. package/src/lib/plugin-manager/plugin-jobs.d.ts +130 -0
  869. package/src/lib/plugin-manager/plugin-jobs.js +182 -0
  870. package/src/lib/plugin-manager/plugin-jobs.js.map +1 -0
  871. package/src/lib/plugin-manager/plugin-loader.d.ts +86 -0
  872. package/src/lib/plugin-manager/plugin-loader.js +223 -0
  873. package/src/lib/plugin-manager/plugin-loader.js.map +1 -0
  874. package/src/lib/plugin-manager/plugin-manager.d.ts +95 -0
  875. package/src/lib/plugin-manager/plugin-manager.js +343 -0
  876. package/src/lib/plugin-manager/plugin-manager.js.map +1 -0
  877. package/src/lib/plugin-manager/plugin-metered-lines.d.ts +97 -0
  878. package/src/lib/plugin-manager/plugin-metered-lines.js +123 -0
  879. package/src/lib/plugin-manager/plugin-metered-lines.js.map +1 -0
  880. package/src/lib/plugin-manager/plugin-org-erasure.d.ts +52 -0
  881. package/src/lib/plugin-manager/plugin-org-erasure.js +100 -0
  882. package/src/lib/plugin-manager/plugin-org-erasure.js.map +1 -0
  883. package/src/lib/plugin-manager/plugin-permissions.d.ts +69 -0
  884. package/src/lib/plugin-manager/plugin-permissions.js +77 -0
  885. package/src/lib/plugin-manager/plugin-permissions.js.map +1 -0
  886. package/src/lib/plugin-manager/plugin-person-erasure.d.ts +58 -0
  887. package/src/lib/plugin-manager/plugin-person-erasure.js +109 -0
  888. package/src/lib/plugin-manager/plugin-person-erasure.js.map +1 -0
  889. package/src/lib/plugin-manager/plugin-record-cards.d.ts +99 -0
  890. package/src/lib/plugin-manager/plugin-record-cards.js +59 -0
  891. package/src/lib/plugin-manager/plugin-record-cards.js.map +1 -0
  892. package/src/lib/plugin-manager/plugin-record-facts.d.ts +111 -0
  893. package/src/lib/plugin-manager/plugin-record-facts.js +51 -0
  894. package/src/lib/plugin-manager/plugin-record-facts.js.map +1 -0
  895. package/src/lib/plugin-manager/plugin-record-routes.d.ts +129 -0
  896. package/src/lib/plugin-manager/plugin-record-routes.js +93 -0
  897. package/src/lib/plugin-manager/plugin-record-routes.js.map +1 -0
  898. package/src/lib/plugin-manager/plugin-record-timeline.d.ts +147 -0
  899. package/src/lib/plugin-manager/plugin-record-timeline.js +39 -0
  900. package/src/lib/plugin-manager/plugin-record-timeline.js.map +1 -0
  901. package/src/lib/plugin-manager/plugin-resource-drafts.d.ts +137 -0
  902. package/src/lib/plugin-manager/plugin-resource-drafts.js +51 -0
  903. package/src/lib/plugin-manager/plugin-resource-drafts.js.map +1 -0
  904. package/src/lib/plugin-manager/plugin-services.d.ts +94 -0
  905. package/src/lib/plugin-manager/plugin-services.js +153 -0
  906. package/src/lib/plugin-manager/plugin-services.js.map +1 -0
  907. package/src/lib/plugin-manager/plugin-styles-ui.d.ts +71 -0
  908. package/src/lib/plugin-manager/plugin-styles-ui.js +80 -0
  909. package/src/lib/plugin-manager/plugin-styles-ui.js.map +1 -0
  910. package/src/lib/plugin-manager/plugin-styles.d.ts +176 -0
  911. package/src/lib/plugin-manager/plugin-styles.js +186 -0
  912. package/src/lib/plugin-manager/plugin-styles.js.map +1 -0
  913. package/src/lib/plugin-manager/plugin-subprocessors.d.ts +135 -0
  914. package/src/lib/plugin-manager/plugin-subprocessors.js +129 -0
  915. package/src/lib/plugin-manager/plugin-subprocessors.js.map +1 -0
  916. package/src/lib/plugin-manager/plugin-tax-profile.d.ts +84 -0
  917. package/src/lib/plugin-manager/plugin-tax-profile.js +39 -0
  918. package/src/lib/plugin-manager/plugin-tax-profile.js.map +1 -0
  919. package/src/lib/plugin-manager/plugin-user-erasure.d.ts +53 -0
  920. package/src/lib/plugin-manager/plugin-user-erasure.js +84 -0
  921. package/src/lib/plugin-manager/plugin-user-erasure.js.map +1 -0
  922. package/src/lib/plugin-manager/plugin-zones.d.ts +121 -0
  923. package/src/lib/plugin-manager/plugin-zones.js +74 -0
  924. package/src/lib/plugin-manager/plugin-zones.js.map +1 -0
  925. package/src/lib/plugin-manager/realm-plugins.d.ts +112 -0
  926. package/src/lib/plugin-manager/realm-plugins.js +196 -0
  927. package/src/lib/plugin-manager/realm-plugins.js.map +1 -0
  928. package/src/lib/plugin-manager/realm-server.d.ts +54 -0
  929. package/src/lib/plugin-manager/realm-server.js +88 -0
  930. package/src/lib/plugin-manager/realm-server.js.map +1 -0
  931. package/src/lib/plugin-manager/record-zone-props.d.ts +126 -0
  932. package/src/lib/plugin-manager/record-zone-props.js +31 -0
  933. package/src/lib/plugin-manager/record-zone-props.js.map +1 -0
  934. package/src/lib/plugin-manager/site-page-hooks.d.ts +102 -0
  935. package/src/lib/plugin-manager/site-page-hooks.js +114 -0
  936. package/src/lib/plugin-manager/site-page-hooks.js.map +1 -0
  937. package/src/lib/plugin-manager/site-runtime.d.ts +57 -0
  938. package/src/lib/plugin-manager/site-runtime.js +25 -0
  939. package/src/lib/plugin-manager/site-runtime.js.map +1 -0
  940. package/src/lib/plugin-manager/usage-alert-contributors.d.ts +115 -0
  941. package/src/lib/plugin-manager/usage-alert-contributors.js +106 -0
  942. package/src/lib/plugin-manager/usage-alert-contributors.js.map +1 -0
  943. package/src/lib/types/ast.d.ts +199 -0
  944. package/src/lib/types/ast.js +20 -0
  945. package/src/lib/types/ast.js.map +1 -0
  946. package/src/lib/types/index.d.ts +20 -0
  947. package/src/lib/types/index.js +21 -0
  948. package/src/lib/types/index.js.map +1 -0
  949. package/src/lib/types/nodes.d.ts +608 -0
  950. package/src/lib/types/nodes.js +28 -0
  951. package/src/lib/types/nodes.js.map +1 -0
  952. package/src/lib/types/routing.d.ts +17 -0
  953. package/src/lib/types/routing.js +18 -0
  954. package/src/lib/types/routing.js.map +1 -0
  955. package/src/lib/types/screen.d.ts +23 -0
  956. package/src/lib/types/screen.js +18 -0
  957. package/src/lib/types/screen.js.map +1 -0
  958. package/src/lib/utils.d.ts +25 -0
  959. package/src/lib/utils.js +42 -0
  960. package/src/lib/utils.js.map +1 -0
  961. package/src/server.d.ts +37 -0
  962. package/src/server.js +55 -0
  963. package/src/server.js.map +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/visitor-consent.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Visitor tracking consent (AGL-1498): the single answer to \"may this\n * tracking feature run for this visitor?\", shared by every surface that has\n * to agree about it — the tenant's GA injection, the consent banner, the\n * marketing runtime's visitor id, the console card that configures it, and\n * the console preview's region simulator.\n *\n * The model, and the honesty bar it was built against:\n *\n * - **Strictly necessary — no consent asked, none required.** The cart cookie\n * (`aglyn_cart_{hostId}`, commerce checkout), the member session\n * (`aglyn_member_{hostId}`, memberships sign-in), the `aglyn-tenant-host`\n * preview-host override, popup/announcement dismissal stamps (local-only,\n * never transmitted, and blocking them would show MORE popups), the\n * first-party pageview beacon (cookieless, stores no visitor identifier —\n * AGL-82), and the stored consent choice itself.\n * - **Consent-gated: `advertising`** (AGL-1649) — GA4's `ad_storage`,\n * `ad_user_data` and `ad_personalization`. OFF for every site unless the\n * host turns the question on, and granted only by an explicit visitor yes\n * to that specific category: never by the implied default, never by a\n * record written before the category existed, never by any refusal status.\n * A host who needs Ads storage previously had one workaround — switch the\n * whole tool off and run their own CMP — which is why this exists.\n * - **Consent-gated: `analytics`.** Today that is the customer-configured\n * Google Analytics tag — a third-party identifier-setting script — plus\n * the CROSS-VISIT persistence of the `aglyn:visitor` experiment id (the id\n * never leaves the browser, but an indefinite-lifetime identifier is\n * disproportionate without a basis; without one it degrades to\n * sessionStorage, so variants stay stable within the visit).\n *\n * **Two postures, resolved per visitor** (the Squarespace shape, host-chosen):\n *\n * - **`opt-in`** — prior consent: nothing gated loads until an explicit\n * accept. Applied in regions whose law requires prior consent (EU/EEA/UK),\n * whenever the visitor's region is UNKNOWN, and everywhere when the host\n * picks `strict` mode. Unknown-geo falls to opt-in deliberately: the\n * asymmetry is a few lost analytics events on rare headerless visits\n * versus pre-consent tracking of an EU visitor.\n * - **`opt-out`** — implied consent: gated features are live from first\n * paint, no banner and no notice; the visitor's recorded state is\n * `implied`, and the always-present \"Your Privacy Choices\" control is the\n * opt-out surface. Applied outside prior-consent regions when the host\n * mode is `geo`.\n *\n * **GPC (Global Privacy Control)** is honored as an automatic opt-out in\n * both postures: a visitor whose browser sends it is recorded `gpc-opt-out`\n * and never tracked, unless they later explicitly accept (the signal is a\n * default; a specific, informed choice overrides it).\n *\n * Enforcement is AT THE SOURCE and MODE-INDEPENDENT: whenever the verdict is\n * \"no\", the GA script never loads — not load-then-suppress — and the gate\n * does not care WHY consent is absent. Because tenant pages are ISR-cached,\n * both the posture and the verdict are evaluated client-side only — the\n * cached HTML never varies by region or consent state.\n */\n\n/** The host fields this module reads; keeps callers free of the full doc. */\nexport interface VisitorConsentHost {\n analytics?: {\n gaMeasurementId?: string\n /** GTM container (AGL-2486) — gated exactly as the GA id is. */\n gtmContainerId?: string\n } | null\n consent?: {\n /**\n * Host opt-out of the whole tool (AGL-1498). PERSISTED NAME. `true`\n * means the host runs their own consent solution (or accepts the\n * exposure): no banner, no privacy-choices control, and gated features\n * load for every visitor. Absent means the tool is active.\n */\n disabled?: boolean\n /**\n * The host's consent posture (AGL-1498). PERSISTED NAME.\n * - `'geo'` — geo-conditional: implied consent (tracking on, opt-out\n * offered) outside prior-consent regions; a prior-consent banner in\n * EU/EEA/UK and wherever the region is unknown.\n * - `'strict'` — opt-in everywhere: every visitor gets the banner.\n * Absent behaves as `'geo'` — the field practice (Squarespace) and the\n * posture the console preselects; recorded here so nobody discovers it\n * by surprise.\n */\n mode?: 'geo' | 'strict'\n /**\n * Host opt-in to ASKING about advertising storage (AGL-1649). PERSISTED\n * NAME. Absent or `false` — the default for every site that exists — means\n * the visitor is asked about analytics only and the three advertising\n * signals stay denied, which is where AGL-1622 put them.\n *\n * `true` adds a SECOND question to the banner and the privacy-choices\n * panel. It does not grant anything by itself: it creates the opportunity\n * for a visitor to say yes, which is the thing a host previously could not\n * obtain without switching the whole tool off and running their own CMP.\n *\n * Strictly `=== true`, like {@link isConsentToolDisabled}: a truthy string\n * out of a hand-edited host document must not turn a consent category on.\n */\n advertising?: boolean\n } | null\n}\n\n/** The host's configured posture; absent means `'geo'`. */\nexport type HostConsentMode = 'geo' | 'strict'\n\n/** The per-visitor resolved posture. */\nexport type VisitorConsentPosture = 'opt-in' | 'opt-out'\n\n/**\n * Consent-gated feature categories.\n *\n * `advertising` (AGL-1649) is gated ONLY where the host opted in — see\n * {@link hostAsksAboutAdvertising}. The stored shape is keyed by category, so\n * this extended rather than migrated, and a record written before it existed\n * reads as \"never asked\", never as a grant.\n */\nexport type VisitorConsentCategory = 'analytics' | 'advertising'\n\n/**\n * A visitor's recorded consent state. The five are DISTINCT on purpose:\n * \"how many visitors are tracked\" (and any future regulator question) needs\n * to distinguish a visitor who clicked Accept from one who was defaulted in.\n *\n * - `implied` — opt-out posture, no action taken: tracking is on.\n * - `accepted` — explicit yes (either posture): tracking is on.\n * - `declined` — explicit no to a prior-consent banner: tracking is off.\n * - `opted-out` — explicit opt-out from the implied default: tracking off.\n * - `gpc-opt-out` — the browser's GPC signal, honored: tracking off.\n */\nexport type VisitorConsentStatus =\n | 'implied'\n | 'accepted'\n | 'declined'\n | 'opted-out'\n | 'gpc-opt-out'\n\nconst CONSENT_STATUSES: ReadonlySet<string> = new Set([\n 'implied',\n 'accepted',\n 'declined',\n 'opted-out',\n 'gpc-opt-out',\n])\n\n/** The statuses that are a visitor's own click, not a default or a signal. */\nexport function isExplicitConsentStatus(\n status: VisitorConsentStatus | null | undefined,\n): boolean {\n return (\n status === 'accepted' || status === 'declined' || status === 'opted-out'\n )\n}\n\n/**\n * Which refusal a \"no\" is, for a visitor in this state.\n *\n * `opted-out` when they were defaulted in, `declined` when they were asked\n * first. The GATE does not care — both refuse — but the RECORD does: \"how many\n * visitors were tracked before they said no\" is a question only these two\n * answers separate, and it is a question a regulator can ask.\n *\n * Lives here rather than in either surface that needs it. Both the consent\n * overlay and the console's own module were deriving it, and a rule with two\n * derivations is a rule that eventually means two different things.\n */\nexport function refusalStatusFor(\n stored: { status?: VisitorConsentStatus } | null | undefined,\n posture: VisitorConsentPosture | null | undefined,\n): VisitorConsentStatus {\n return stored?.status === 'implied' || posture === 'opt-out'\n ? 'opted-out'\n : 'declined'\n}\n\n/** Whether a status grants the analytics category. */\nexport function analyticsGrantedByStatus(\n status: VisitorConsentStatus,\n): boolean {\n return status === 'accepted' || status === 'implied'\n}\n\n/**\n * Whether a status can carry an advertising grant at all (AGL-1649; widened by\n * AGL-2402, narrowed back on 2026-08-24, widened again on 2026-08-25).\n *\n * The SAME status set as {@link analyticsGrantedByStatus}, and the agreement is\n * deliberate: `implied` grants both. Being defaulted in where the law permits a\n * default is one posture, applied to both categories, and the visitor's opt-out\n * surface is the same one.\n *\n * ## Why it moved three times, because the next person will move it again\n *\n * AGL-2402 (`a410d8785`) first made `implied` qualify, on the reasoning that\n * the rule is safe by GEOGRAPHY: an `implied` record can only ever be written\n * in the OPT-OUT posture, because {@link resolveConsentPosture} puts the EU 27,\n * the EEA/EFTA three, the UK, Gibraltar, the EU outermost regions AND any\n * visitor whose region cannot be determined into opt-in, where\n * `decideVisitorConsent` records no default at all. That half was always sound\n * and is still asserted in `visitor-consent-advertising.spec.ts`.\n *\n * The half that failed was DISCLOSURE. That commit stated the published Cookie\n * Policy had been updated first; read against the live page on 2026-08-24 it\n * said two different things — its \"Marketing / advertising\" paragraph described\n * the opt-out posture, while the per-cookie table said `_gac`, `_gcl_au`,\n * `_fbp` and `_fbc` were \"set only where you have allowed advertising cookies\"\n * and \"Your choices\" repeated it. A policy that says both cannot authorise the\n * wider behaviour, so the code was narrowed to the strictest thing it said.\n *\n * On 2026-08-25 the master moved for real, in the right order: those five\n * opt-in-only sentences were rewritten in the Cookie Policy gdoc, and only then\n * did this function follow. The Privacy Policy needed nothing — it already said\n * *\"With your consent, we do 'share' … for cross-context behavioral\n * advertising\"*, named Google and Meta, and described the EU/UK-ask-first vs.\n * elsewhere-from-first-visit split. The flat \"we do not sell or share\" denial\n * that the narrowing reasoned from was a paraphrase in `docs/ANALYTICS.md`, not\n * a sentence in the document.\n *\n * ⛔ Re-narrowing is a POLICY act, not a code change. Move the published\n * masters first and let this follow — never the other way round. Nine surfaces\n * describe this rule to a human and `consent-advertising-copy-drift.spec.ts`\n * fails on all of them the moment the two disagree.\n *\n * A `true` here is necessary, never sufficient: the host must ALSO have opted\n * into asking (see {@link hostAsksAboutAdvertising}), and a refusal — declined,\n * opted out, or a GPC signal — outranks the default everywhere.\n */\nexport function advertisingGrantedByStatus(\n status: VisitorConsentStatus,\n): boolean {\n // Fails CLOSED: an exact match against the granting statuses, so any\n // unknown, absent or future status answers `false`. `strictNullChecks` is\n // off repo-wide, which means `status` can be `null`/`undefined` at runtime\n // despite the type — an equality test denies those, an exclusion list\n // (`status !== 'declined' && …`) would have granted them.\n //\n // `implied` GRANTS from 2026-08-25, and the policy went first (the call,\n // executed in that order). `decideVisitorConsent` only ever writes `implied`\n // in the OPT-OUT posture — `resolveConsentPosture` keeps the EU 27, the\n // EEA/EFTA three, the UK, Gibraltar, the EU outermost regions AND any visitor\n // whose region cannot be determined in opt-in, where no default is recorded at\n // all — so this widens advertising to the rest of the world only, and the\n // geographic guarantee `visitor-consent-advertising.spec.ts` asserts is\n // untouched. `gpc-opt-out` and `declined` still answer `false`.\n //\n // The disclosure this rests on is now consistent in BOTH masters, which is\n // what the 2026-08-24 narrowing was waiting for: the Privacy Policy already\n // said *\"With your consent, we do 'share' … Where the law requires us to ask\n // first — the EU, the UK, and anywhere we cannot determine your region — it\n // does not load until you accept. Elsewhere it runs from your first visit\"*,\n // and the Cookie Policy's two remaining opt-in-only sentences (the ×4\n // per-cookie note and the \"Your choices\" bullet) were rewritten to match it\n // the same day. Re-narrow this ONLY by moving the policies back first.\n return status === 'accepted' || status === 'implied'\n}\n\n/**\n * Strict GA measurement-id check (AGL-138) — the id lands inside an inline\n * script, so the format gate is load-bearing, not cosmetic.\n */\nexport const GA_MEASUREMENT_ID_PATTERN = /^G-[A-Z0-9]{4,16}$/\n\n/**\n * The shape a Meta pixel id has, shared by the LOADER and the console field.\n *\n * Declared HERE and not in `advertising-tags.ts`, which the console may not\n * import: `advertising-tag-gate.spec` case (f) fails any console file that\n * reaches for that module, because it is what mounts a vendor's script. A\n * format string is not a vendor, so it lives with the other id patterns and\n * the loader imports it from here.\n *\n * One pattern, because two would be a form that accepts an id the loader then\n * refuses — the tag never mounts and the operator is left looking at a saved\n * field and no pixel.\n */\nexport const META_PIXEL_ID_PATTERN = /^[0-9]{8,20}$/\n\n/**\n * A Google Ads conversion id — `AW-` and digits.\n *\n * Distinct from `GA_MEASUREMENT_ID_PATTERN` (`G-…`) on purpose: they are\n * different products with different ids, and a form that accepted either in\n * either field would load an analytics id into an ads tag and report nothing.\n */\nexport const GOOGLE_ADS_ID_PATTERN = /^AW-[0-9]{6,16}$/\n\n/**\n * A LinkedIn Insight partner id — numeric, and short.\n *\n * Bounded well under the Meta band rather than sharing it: a partner id is six\n * or seven digits today, and a pattern loose enough to accept a Meta pixel id\n * would let a mis-paste into the wrong field validate and then load a tag that\n * matches nothing.\n */\nexport const LINKEDIN_PARTNER_ID_PATTERN = /^[0-9]{4,10}$/\n\n/** The configured GA id when it is well-formed, else null. */\nexport function resolveGaMeasurementId(\n host: VisitorConsentHost | null | undefined,\n): string | null {\n const candidate = String(host?.analytics?.gaMeasurementId ?? '')\n return GA_MEASUREMENT_ID_PATTERN.test(candidate) ? candidate : null\n}\n\n/**\n * A Google Tag Manager container id — `GTM-` and 5–10 upper-case\n * alphanumerics.\n *\n * Format-checked for the same reason the GA id is: it lands inside an INLINE\n * SCRIPT on a published page, so anything that is not this shape must never\n * reach it (AGL-138).\n */\nexport const GTM_CONTAINER_ID_PATTERN = /^GTM-[A-Z0-9]{5,10}$/\n\n/** The configured GTM container when it is well-formed, else null. */\nexport function resolveGtmContainerId(\n host: VisitorConsentHost | null | undefined,\n): string | null {\n const candidate = String(host?.analytics?.gtmContainerId ?? '')\n return GTM_CONTAINER_ID_PATTERN.test(candidate) ? candidate : null\n}\n\n/**\n * Whether the site loads ANY Google tag — a GA property, a GTM container, or\n * both (AGL-2486).\n *\n * The one predicate both consent questions are asked through, because the\n * alternative is two places that each remember only one of the two. A site\n * with a container and no GA id is a site that tracks: it was the shape that\n * would have had `consentGatedCategories` return `[]`, no banner rendered, and\n * the container loading ungated — which for GTM is worse than for GA, since a\n * container is exactly the thing that can carry advertising tags.\n */\nexport function hostHasGoogleTag(\n host: VisitorConsentHost | null | undefined,\n): boolean {\n return !!resolveGaMeasurementId(host) || !!resolveGtmContainerId(host)\n}\n\n/** Host opt-out of the tool. Absent means ACTIVE — the safe default. */\nexport function isConsentToolDisabled(\n host: VisitorConsentHost | null | undefined,\n): boolean {\n return host?.consent?.disabled === true\n}\n\n/** The host's posture choice; anything but `'strict'` reads as `'geo'`. */\nexport function resolveHostConsentMode(\n host: VisitorConsentHost | null | undefined,\n): HostConsentMode {\n return host?.consent?.mode === 'strict' ? 'strict' : 'geo'\n}\n\n/**\n * The gated categories this site actually uses. Empty means there is\n * nothing to consent to and no consent UI renders — a banner with no\n * question behind it is decoration that trains visitors to click banners.\n */\nexport function consentGatedCategories(\n host: VisitorConsentHost | null | undefined,\n): VisitorConsentCategory[] {\n // A GTM CONTAINER counts (AGL-2486). Read as `resolveGaMeasurementId` alone,\n // a site running only a container had no gated category, so no banner\n // rendered and the container loaded ungated — see `hostHasGoogleTag`.\n if (!hostHasGoogleTag(host)) return []\n return hostAsksAboutAdvertising(host)\n ? ['analytics', 'advertising']\n : ['analytics']\n}\n\n/**\n * Whether this site asks its visitors about advertising storage (AGL-1649).\n *\n * Two conditions, both required. The host has to have opted in — the flag is\n * off for every site that exists and stays off unless someone turns it on —\n * and the site has to actually have an analytics tag, because advertising\n * storage here is GA4's `ad_storage` and there is nothing to ask about\n * without one. A banner with no question behind it is decoration (AGL-1498).\n */\nexport function hostAsksAboutAdvertising(\n host: VisitorConsentHost | null | undefined,\n): boolean {\n // Either tag qualifies (AGL-2486): `ad_storage` is what a GA property reads\n // and what a GTM container's advertising tags read, and a container is the\n // likelier of the two to carry them.\n return host?.consent?.advertising === true && hostHasGoogleTag(host)\n}\n\n/**\n * Whether the published site runs the consent machinery at all: the tool is\n * active AND the site uses at least one gated feature.\n */\nexport function hostConsentRequired(\n host: VisitorConsentHost | null | undefined,\n): boolean {\n return !isConsentToolDisabled(host) && consentGatedCategories(host).length > 0\n}\n\n/**\n * Regions whose law requires PRIOR consent for non-essential\n * cookies/identifiers (ePrivacy and its UK retention): the EU 27, the three\n * EEA/EFTA states, the UK, Gibraltar (UK GDPR extends there), and the EU\n * outermost regions that carry their own ISO codes. ISO 3166-1 alpha-2,\n * matching `x-vercel-ip-country`.\n *\n * Deliberately NOT a \"privacy-law countries\" list: plenty of laws (CCPA,\n * LGPD, PIPEDA) regulate tracking on an opt-out basis, which is exactly what\n * the opt-out posture plus GPC provides. This set is only the prior-consent\n * boundary.\n */\nexport const PRIOR_CONSENT_COUNTRY_CODES: ReadonlySet<string> = new Set([\n // EU 27\n 'AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR',\n 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK',\n 'SI', 'ES', 'SE',\n // EEA / EFTA\n 'IS', 'LI', 'NO',\n // UK and Gibraltar\n 'GB', 'GI',\n // EU outermost regions with their own ISO codes (legally EU territory)\n 'AX', 'GF', 'GP', 'MQ', 'RE', 'YT',\n])\n\n/**\n * The per-visitor posture. Client-evaluated (ISR forbids varying the HTML),\n * from the country the region endpoint reports.\n *\n * Unknown region (`null`) falls to `opt-in` — the ONE place this feature\n * does not maximize tracking, because the asymmetry is lopsided: a few lost\n * analytics events on rare headerless visits, versus pre-consent tracking\n * of an EU visitor, which \"track as soon as we legally can\" excludes by its\n * own terms.\n */\nexport function resolveConsentPosture(\n host: VisitorConsentHost | null | undefined,\n country: string | null | undefined,\n): VisitorConsentPosture {\n if (resolveHostConsentMode(host) === 'strict') return 'opt-in'\n if (!country) return 'opt-in'\n return PRIOR_CONSENT_COUNTRY_CODES.has(country.toUpperCase())\n ? 'opt-in'\n : 'opt-out'\n}\n\n/**\n * Whether this browser sends Global Privacy Control. Read live at decision\n * time — the signal is the user agent's, not ours to cache.\n */\nexport function hasGlobalPrivacyControl(): boolean {\n return (\n typeof navigator !== 'undefined' &&\n (navigator as { globalPrivacyControl?: unknown }).globalPrivacyControl ===\n true\n )\n}\n\n/**\n * A visitor's stored consent record. Versioned so a future category\n * addition can distinguish \"declined analytics\" from \"was never asked about\n * marketing\".\n */\nexport interface StoredVisitorConsent {\n v: 1\n /** Epoch ms of the decision (or of the implied default's recording). */\n at: number\n status: VisitorConsentStatus\n /** The category grant, derived from `status` at store time. */\n analytics: boolean\n /**\n * The advertising grant (AGL-1649). ABSENT on every record written before\n * the category existed, and absent reads as `false` — \"was never asked\"\n * is not \"said yes\". Reading it the other way would hand Google a basis\n * for every visitor who ever clicked Allow on an analytics-only banner.\n *\n * Carried by an explicit accept, and — since 2026-08-25 — by the opt-out\n * posture's implied default, on a site whose host turned the question on.\n * Never by a refusal: declined, opted out and GPC all deny it everywhere.\n * See {@link advertisingGrantedByStatus} for the order the policy and the\n * code move in.\n */\n advertising?: boolean\n /** ISO country at decision time, when known — the `implied,us` shape. */\n country?: string | null\n}\n\n/**\n * Keyed by hostId, not a bare name: preview deployments and localhost serve\n * many hosts from one origin, and one site's \"yes\" must never leak to\n * another's.\n */\nexport const VISITOR_CONSENT_STORAGE_PREFIX = 'aglyn:consent:'\n\n/** The marketing runtime's cross-visit experiment id (`site-runtime.tsx`). */\nexport const VISITOR_ID_STORAGE_KEY = 'aglyn:visitor'\n\n/** Fired on `window` whenever {@link storeVisitorConsent} records a state. */\nexport const VISITOR_CONSENT_CHANGED_EVENT = 'aglyn:consent:changed'\n\n/**\n * Fired on `window` to open the privacy-choices panel — the change-your-mind\n * path, in BOTH directions. Sites can also link any element to\n * `#aglyn-consent`; the banner listens for those clicks.\n */\nexport const VISITOR_CONSENT_OPEN_EVENT = 'aglyn:consent:open'\n\nexport function visitorConsentStorageKey(hostId: string): string {\n return `${VISITOR_CONSENT_STORAGE_PREFIX}${hostId}`\n}\n\n/**\n * Cookie-name PREFIXES the analytics grant is answerable for (AGL-1606).\n *\n * A prefix sweep rather than a name list, because the names are derived and\n * configuration-dependent: `_ga` is joined by `_ga_<measurement id without the\n * `G-`>` per property, by `_gac_<id>` when Google Ads linking is on, and by\n * `_gid` where the legacy daily id is still issued. Hardcoding the two names a\n * given site happens to carry today is precisely how a withdrawal leaves an\n * identifier behind on the next site. `_ga` subsumes `_ga`, `_ga_*` and\n * `_gac_*`; `_gid` is the only Google analytics cookie that does not start\n * with it.\n */\nexport const ANALYTICS_COOKIE_PREFIXES: readonly string[] = ['_ga', '_gid']\n\n/**\n * Cookie-name PREFIXES the ADVERTISING grant is answerable for (AGL-2486).\n *\n * These are Google's, and they are separate from the analytics list above for\n * a reason that is not tidiness: an advertising-only withdrawal must sweep\n * them while analytics keeps running. Folding them into\n * {@link ANALYTICS_COOKIE_PREFIXES} would have swept them on ANALYTICS\n * withdrawal and still not on the case that motivates this — leaving the same\n * hole, narrower — besides filing a conversion-linker cookie under a category\n * it does not belong to.\n *\n * `_gcl_*` is the conversion linker, written by gtag once `ad_storage` is\n * granted, and it is the one that started this: it does not begin with `_ga`,\n * so nothing swept it, on any path.\n *\n * ONE PREFIX, deliberately. `_gac_*` (Google Ads linking) was in this list\n * briefly and is not, because it is written under the ANALYTICS grant and is\n * already swept by the `_ga` prefix. Listing it here made every\n * analytics-only GRANT delete it — on a site that never asks the advertising\n * question `stored.advertising` is always false, so the sweep ran on the way\n * IN — which broke \"cleanup is the withdrawal path only\" (AGL-1606). Sweeping\n * wider is not free when a category nobody was asked about owns the trigger.\n *\n * PRECISION MATTERS, because {@link clearCookiesWithPrefixes} is `startsWith`.\n * `_gcl` cannot reach `_ga`, `_ga_<id>`, `_gac_<id>` or `_gid` — those are\n * analytics and MUST survive an advertising-only withdrawal.\n */\nexport const ADVERTISING_COOKIE_PREFIXES: readonly string[] = ['_gcl']\n\n/**\n * Expire the advertising identifiers, on the same domain ladder as the\n * analytics sweep (AGL-2486).\n *\n * Deleting a cookie that was never set is a no-op; failing to delete one that\n * was is the defect — so this runs on every non-granting store rather than\n * only on a transition observed to be a withdrawal, which the record cannot\n * reliably tell us anyway.\n */\nexport function clearAdvertisingCookies(hostname?: string | null): string[] {\n return clearCookiesWithPrefixes(ADVERTISING_COOKIE_PREFIXES, hostname)\n}\n\n/**\n * Multi-label public suffixes: names under which registrations happen, so the\n * label to their left is the registrable one. A short list rather than the\n * Public Suffix List — the same trade `console-domains.ts` makes, and the\n * failure mode is mild in both directions: an unlisted suffix costs one\n * over-broad `domain=` write that the browser silently refuses (cookies cannot\n * be set on a public suffix), never a deletion on someone else's domain.\n */\nconst MULTI_LABEL_PUBLIC_SUFFIXES: ReadonlySet<string> = new Set([\n 'co.uk', 'org.uk', 'me.uk', 'ac.uk', 'gov.uk',\n 'com.au', 'net.au', 'org.au',\n 'co.nz', 'co.za',\n 'co.jp', 'ne.jp', 'or.jp',\n 'com.br', 'com.mx', 'com.cn', 'com.tr',\n 'co.in', 'co.kr', 'com.sg', 'com.hk',\n])\n\nfunction normalizeCookieHostname(hostname: string | null | undefined): string {\n return String(hostname ?? '')\n .trim()\n .toLowerCase()\n .replace(/\\.+$/, '')\n}\n\n/**\n * The registrable domain of a hostname — the highest name a cookie may be\n * written at — or `null` when there is none.\n *\n * This is the fiddly half of the cleanup. GA's `cookie_domain: 'auto'` walks\n * UP from the hostname and writes at the highest domain the browser accepts,\n * which is the registrable domain with a leading dot: a visit to\n * `www.shop.acme.co.uk` leaves `_ga` on `.acme.co.uk`, not on the exact host.\n * A deletion aimed at the exact hostname therefore silently no-ops — it writes\n * a second, host-scoped, already-expired cookie and leaves the real one alone.\n *\n * `null` for a single-label host (`localhost`) and for IP literals: those take\n * host-only cookies, which the undecorated deletion already covers.\n */\nexport function registrableCookieDomain(\n hostname: string | null | undefined,\n): string | null {\n // Named `name`, not `host`: `host.foo` inside app-utils is what the\n // AGL-1361 write-deny sweep reads as a host-document field, and a local\n // string's `.split`/`.includes` would land in it as phantom fields.\n const name = normalizeCookieHostname(hostname)\n if (!name) return null\n // IPv6 literal (bracketed or bare) and IPv4 literal: host-only cookies.\n if (name.startsWith('[') || name.includes(':')) return null\n if (/^\\d+(\\.\\d+){3}$/.test(name)) return null\n const labels = name.split('.')\n if (labels.length < 2 || labels.some((label) => !label)) return null\n const lastTwo = labels.slice(-2).join('.')\n if (MULTI_LABEL_PUBLIC_SUFFIXES.has(lastTwo)) {\n // `acme.co.uk` is registrable; `co.uk` on its own is not a domain at all.\n return labels.length > 2 ? labels.slice(-3).join('.') : null\n }\n return lastTwo\n}\n\n/**\n * Every `domain=` value a cookie deletion has to try, most specific first and\n * stopping at the registrable domain.\n *\n * The whole ladder rather than the registrable domain alone because\n * `cookie_domain` is configurable: a host that pins it to `shop.acme.com`\n * leaves the cookie one rung below where `auto` would. Walking the rungs costs\n * a handful of no-op writes and removes the guess.\n *\n * Empty when there is no registrable domain — the host-only deletion that\n * {@link clearAnalyticsCookies} always performs is the complete answer there.\n */\nexport function analyticsCookieDomains(\n hostname: string | null | undefined,\n): string[] {\n const name = normalizeCookieHostname(hostname)\n const registrable = registrableCookieDomain(name)\n if (!registrable) return []\n const domains: string[] = []\n let current = name\n for (;;) {\n domains.push(`.${current}`)\n if (current === registrable) break\n const cut = current.indexOf('.')\n if (cut < 0) break\n current = current.slice(cut + 1)\n }\n return domains\n}\n\n/**\n * Expire every analytics cookie this browser is carrying, at the host itself\n * and at every domain up to the registrable one. Returns the names it acted\n * on, which is what makes the cleanup assertable.\n *\n * Best-effort by construction: a cookie written at a path other than `/` is\n * not reachable this way, and `document.cookie` cannot report which domain a\n * cookie came from — hence the ladder. Neither limit applies to the cookies GA\n * actually writes (path `/`, registrable domain).\n */\nexport function clearAnalyticsCookies(\n hostname?: string | null,\n): string[] {\n return clearCookiesWithPrefixes(ANALYTICS_COOKIE_PREFIXES, hostname)\n}\n\n/**\n * The same sweep for an ARBITRARY prefix set — the generalisation\n * {@link clearAnalyticsCookies} now delegates to.\n *\n * Extracted rather than copied because the hard part is not the prefix match,\n * it is {@link analyticsCookieDomains}: the ladder from the exact hostname up\n * to the registrable domain, which exists because a tag written with an `auto`\n * cookie domain leaves its identifier one or more rungs ABOVE the host. A\n * second vendor's sweep re-derived by hand would get that wrong the first time\n * and pass its own test, because a deletion aimed at the wrong domain silently\n * no-ops — it writes an already-expired host-scoped cookie and reports success.\n * One implementation, one ladder, one place to fix.\n *\n * Meta's `_fbp`/`_fbc` are written exactly like `_ga`: path `/`, registrable\n * domain, first-party. Nothing here is Google-specific and nothing here is\n * Meta-specific.\n */\nexport function clearCookiesWithPrefixes(\n prefixes: readonly string[],\n hostname?: string | null,\n): string[] {\n if (typeof document === 'undefined') return []\n // An empty prefix set would match EVERY cookie via `''.startsWith`, which\n // would delete the cart, the member session and the consent record itself.\n // A caller with nothing to sweep gets nothing swept.\n if (!prefixes || prefixes.length === 0) return []\n try {\n const names = new Set<string>()\n for (const pair of String(document.cookie ?? '').split(';')) {\n const name = pair.split('=')[0].trim()\n if (name && prefixes.some((p) => !!p && name.startsWith(p))) {\n names.add(name)\n }\n }\n if (names.size === 0) return []\n const domains = analyticsCookieDomains(\n hostname ??\n (typeof window !== 'undefined' ? window.location?.hostname : ''),\n )\n for (const name of names) {\n const expired = `${name}=; Max-Age=0; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`\n document.cookie = expired\n for (const domain of domains) {\n document.cookie = `${expired}; domain=${domain}`\n }\n }\n return [...names]\n } catch {\n // Cookies disabled or a hostile `document.cookie`: the gate still keeps\n // the script out, which is the load-bearing half.\n return []\n }\n}\n\n/**\n * The `window` flag `gtag.js` consults before every hit: with\n * `window['ga-disable-G-XXXX'] === true` the tag for that property sends\n * nothing and writes nothing. Google's own documented opt-out mechanism, and\n * the one that works on a tag which never received a consent-mode default\n * (AGL-1608) — a case that still exists after AGL-1622, because a tag arriving\n * through GTM or a host's own CMP is not one this module declared for.\n */\nexport const GA_DISABLE_FLAG_PREFIX = 'ga-disable-'\n\n/** A single consent-mode signal value. */\nexport type AnalyticsConsentSignal = 'granted' | 'denied'\n\n/**\n * The consent-mode signal set this tool is answerable for.\n *\n * `ad_storage` and friends are typed as the literal `'denied'`, not as\n * {@link AnalyticsConsentSignal}: the tool asks a visitor about analytics and\n * nothing else, so there is no advertising basis on file to grant, in either\n * direction. Widening them is a change the type has to be edited to allow.\n */\nexport interface AnalyticsConsentSignals {\n analytics_storage: AnalyticsConsentSignal\n ad_storage: 'denied'\n ad_user_data: 'denied'\n ad_personalization: 'denied'\n}\n\n/**\n * The consent-mode payload for a given analytics grant — ONE source, so the\n * `default` declared before the tag loads (AGL-1622) and the `update` sent on a\n * mid-pageview withdrawal (AGL-1608) can never drift apart. Two hand-written\n * literals that disagree is how a tag ends up believing a state the visitor\n * never chose.\n */\nexport function analyticsConsentSignals(\n granted: boolean,\n): AnalyticsConsentSignals {\n return {\n analytics_storage: granted ? 'granted' : 'denied',\n ad_storage: 'denied',\n ad_user_data: 'denied',\n ad_personalization: 'denied',\n }\n}\n\n/** The four signals when advertising is in play (AGL-1649). */\nexport interface VisitorConsentSignals {\n analytics_storage: AnalyticsConsentSignal\n ad_storage: AnalyticsConsentSignal\n ad_user_data: AnalyticsConsentSignal\n ad_personalization: AnalyticsConsentSignal\n}\n\n/**\n * The consent-mode payload for a pair of category grants (AGL-1649).\n *\n * A SEPARATE function from {@link analyticsConsentSignals} rather than a\n * widening of it, deliberately. AGL-1649 says not to widen those three\n * literals, and the reason survives this change: a caller that only knows\n * about analytics should be unable to express a grant it has no answer for.\n * Reaching an advertising grant now requires calling something else and\n * passing it, which is a thing a reviewer can see in a diff.\n *\n * Advertising is clamped to analytics. `ad_storage: 'granted'` with\n * `analytics_storage: 'denied'` is not a state this tool can reach honestly —\n * every refusal path (declined, opted out, GPC) withdraws both together — so\n * the clamp makes the impossible state unrepresentable rather than merely\n * unreached.\n */\nexport function consentModeSignals(grants: {\n analytics: boolean\n advertising: boolean\n}): VisitorConsentSignals {\n const analytics = grants.analytics === true\n const advertising = analytics && grants.advertising === true\n const ads: AnalyticsConsentSignal = advertising ? 'granted' : 'denied'\n return {\n analytics_storage: analytics ? 'granted' : 'denied',\n ad_storage: ads,\n ad_user_data: ads,\n ad_personalization: ads,\n }\n}\n\n/**\n * Whether advertising storage may run for this visitor on this site.\n *\n * THREE independent conditions, and all of them are load-bearing:\n *\n * 1. The host asks about advertising at all. A record that says yes is\n * ignored on a site that never turned the category on — which covers a\n * host switching it back off, and covers a stale record generally.\n * 2. The record's status can carry a grant — an explicit accept, and nothing\n * else (see {@link advertisingGrantedByStatus}). An `implied` default\n * cannot, and every refusal status refuses.\n * 3. The record actually says yes to this category.\n *\n * Absent, unreadable or legacy records all answer `false`, which is the same\n * answer they gave before the category existed.\n */\nexport function advertisingGrantedByRecord(\n host: VisitorConsentHost | null | undefined,\n stored: StoredVisitorConsent | null | undefined,\n): boolean {\n if (!hostAsksAboutAdvertising(host)) return false\n if (!stored) return false\n if (!advertisingGrantedByStatus(stored.status)) return false\n return stored.advertising === true\n}\n\n/**\n * The consent-mode `default` declaration that goes in front of the tag\n * (AGL-1622), for injection into the same inline block that creates\n * `dataLayer` and calls `gtag('config', …)`.\n *\n * ## What this is, and — load-bearing — what it is NOT\n *\n * It is NOT a licence to load the tag earlier. It is emitted INSIDE the block\n * that only renders when the AGL-1498 gate has already said yes, so it is\n * reached only on a pageview where analytics is granted. On every gated\n * pageview — an EU/UK/EEA visitor with no explicit accept, an unknown region, a\n * declined or opted-out visitor, a GPC browser — nothing here renders, no\n * request goes to `googletagmanager.com`, and this constant is never evaluated\n * into the page. \"The script never LOADS, rather than load-then-suppress\" is a\n * stated AGL-1498 property and it is intact everywhere the gate applies;\n * `consent-mode-default.spec.tsx` fails if that ever stops being true.\n *\n * the decision, 2026-08-14: load-then-restrict is approved for the UNITED\n * STATES, where the implied-consent posture already permits the load and the\n * restriction signals act on a tag that is legitimately resident. EU and UK\n * keep the prior-consent gate exactly as it is, because loading an analytics\n * tag before consent is the specific thing prior-consent law prohibits. So the\n * consent-mode mechanism is strictly ADDITIVE to the gate, never a replacement\n * for it.\n *\n * What declaring it actually buys, given the tag is granted by the time it is\n * read:\n *\n * - The advertising signals are denied FROM THE FIRST HIT. Without a default,\n * a freshly loaded tag runs with `ad_storage` unrestricted and only becomes\n * denied if the visitor happens to withdraw and change their mind again\n * (AGL-1608's `update`). The load-time state now matches the tool's actual\n * scope instead of being wider than it.\n * - A later `update` is a transition from a declared state rather than a tag's\n * first-ever consent signal, which is the shape GA4's consent-mode reporting\n * and any third-party CMP alongside ours both expect.\n *\n * The value is a literal, built from {@link analyticsConsentSignals} — no\n * interpolated input reaches it, which matters because it lands inside an\n * inline script (the AGL-138 concern).\n */\nexport const GA_CONSENT_DEFAULT_SNIPPET = `gtag('consent', 'default', ${JSON.stringify(\n analyticsConsentSignals(true),\n)});`\n\n/**\n * The same declaration for a visitor who granted ADVERTISING too (AGL-1649).\n *\n * A second CONSTANT rather than a parameterised builder, for the reason the\n * first one is a constant: it lands inside an inline script (the AGL-138\n * concern), and a constant cannot interpolate anything. Both values are\n * literals fixed at module load; the only thing the caller chooses is which\n * of the two to emit.\n *\n * Reached only where {@link advertisingGrantedByRecord} says yes — host\n * opted in, explicit accept, explicit yes to this category — which is\n * evaluated client-side after hydration, like every other part of this gate.\n * The ISR property is unaffected: the cached HTML contains neither snippet,\n * because the whole block is inside the client-side `analyticsAllowed`\n * condition.\n *\n * Declaring the grant as the DEFAULT rather than sending a later `update` is\n * what keeps the tag's first hit correct. An update would arrive after\n * `config`, so the session's first pageview — usually the entire session for\n * a marketing visit — would carry the denied state the visitor did not\n * choose.\n */\nexport const GA_CONSENT_DEFAULT_WITH_ADS_SNIPPET = `gtag('consent', 'default', ${JSON.stringify(\n consentModeSignals({ analytics: true, advertising: true }),\n)});`\n\n/**\n * Consent-mode URL passthrough for the platform's own tag (AGL-2548).\n *\n * The advertising signals in {@link GA_CONSENT_DEFAULT_SNIPPET} are denied, so\n * on `aglyn.com` gtag writes no `_gcl_aw` cookie and the `gclid` an ad click\n * arrives with lives only in that first URL. The conversions it should be\n * credited for fire one hop later, on the console, where the posture grants\n * advertising storage outside the prior-consent regions — and without this\n * declaration the click id never makes that hop. The console reports a\n * conversion with no click behind it, and Google Ads counts nothing.\n *\n * `url_passthrough` is Google's mechanism for exactly this state: while\n * `ad_storage` is denied, gtag appends the click identifiers to links into the\n * cross-domain-linked hosts as URL parameters instead of setting a cookie. The\n * receiving tag reads them under its own consent state. Nothing is stored on\n * the denying surface, so the marketing site's opt-in advertising posture is\n * unchanged; the click id simply survives the link it was always meant to\n * survive.\n *\n * `ads_data_redaction` is the companion Google documents alongside it: with\n * `ad_storage` denied, the ad click identifiers are stripped from the hits this\n * tag sends and its network requests go to a cookieless endpoint. Declared\n * together so a denied visitor is measured with less, not merely differently.\n *\n * Both are `set` calls, so they must precede `gtag('config', …)` in the same\n * inline block — a `set` applies to hits processed after it, and the session's\n * first pageview is the one carrying the click.\n *\n * PLATFORM ID ONLY. A customer's tag is configured with their id and their\n * consent posture; how their ad click ids travel is theirs to decide, and a\n * passthrough declared on their behalf would rewrite links on their site.\n */\nexport const GA_CLICK_ID_PASSTHROUGH_SNIPPET =\n \"gtag('set', 'url_passthrough', true);\" +\n \"gtag('set', 'ads_data_redaction', true);\"\n\n/**\n * The measurement ids whose tag is actually RESIDENT in this page.\n *\n * Discovered from the page rather than taken from the host document on\n * purpose: what has to be silenced is whatever gtag.js is currently loaded and\n * configured for, which is not always what the host record configures — a tag\n * can arrive through GTM, and a stale `<script>` from earlier in the pageview\n * is exactly the thing this function exists to find.\n *\n * Ids are format-checked before they are used, because each one becomes a\n * `window` property name.\n */\nexport function residentGaMeasurementIds(): string[] {\n if (typeof document === 'undefined') return []\n const ids = new Set<string>()\n try {\n const loaded = document.querySelectorAll(\n 'script[src*=\"googletagmanager.com/gtag/js\"]',\n )\n for (const element of Array.from(loaded)) {\n const src = String((element as HTMLScriptElement).src ?? '')\n const match = /[?&]id=([^&]*)/.exec(src)\n const id = match ? decodeURIComponent(match[1]) : ''\n if (GA_MEASUREMENT_ID_PATTERN.test(id)) ids.add(id)\n }\n } catch {\n // A hostile or absent DOM: the dataLayer pass below still applies.\n }\n try {\n const layer = (window as unknown as Record<string, unknown>)?.dataLayer\n for (const entry of Array.from((layer ?? []) as ArrayLike<unknown>)) {\n // `arguments` objects, not arrays — gtag pushes its own call sites.\n const args = Array.from((entry ?? []) as ArrayLike<unknown>)\n if (args[0] !== 'config') continue\n const id = String(args[1] ?? '')\n if (GA_MEASUREMENT_ID_PATTERN.test(id)) ids.add(id)\n }\n } catch {\n // No dataLayer, or one that is not iterable: the script pass stands.\n }\n return [...ids]\n}\n\n/**\n * Make every resident GA tag agree with the consent state, and return the ids\n * it acted on.\n *\n * ## Why deleting the cookies is not enough (AGL-1608)\n *\n * The AGL-1498 gate stops the script from LOADING, which is the right\n * enforcement for a fresh pageview and the wrong tool for a visitor who\n * withdraws mid-pageview: `gtag.js` has already executed, and React unmounting\n * the `<script>` element does not unload it. `window.gtag` stays live, GA4\n * enhanced measurement fires on its own (scroll depth, outbound click, file\n * download), and the tag re-writes `_ga_<id>` AFTER\n * {@link clearAnalyticsCookies} has deleted it. Reproduced on aglyn.com: an\n * opt-out, a hand-run sweep to zero cookies, then one scroll to the footer\n * brought `_ga_YW5PG16YTM` back.\n *\n * Two signals, because they fail differently and neither is guaranteed:\n * the `ga-disable-<id>` window flag silences a tag that never received a\n * consent-mode default, and the `consent`/`update` call reaches a tag that\n * arrived through GTM with its own id this function never saw.\n *\n * ## What this deliberately does NOT do\n *\n * It never touches the gate. Both signals act only on a tag that is already\n * resident — which, by construction, only exists after a grant. AGL-1622 later\n * added a consent-mode DEFAULT ({@link GA_CONSENT_DEFAULT_SNIPPET}), but inside\n * the gated block and therefore only on a pageview the gate already allowed:\n * load-then-restrict is additive to \"the script never LOADS\", not a\n * replacement for it, and the prior-consent regions are unaffected.\n *\n * Symmetric on purpose: a visitor who opts out and changes their mind in the\n * same pageview would otherwise stay silently unmeasured until they navigated,\n * because the re-rendered `<Script>` cannot re-execute an already-loaded tag.\n * The re-grant restores whatever the CALLER passes — analytics alone on a site\n * that never asks the advertising question (`advertising` defaults to false),\n * and both categories where the visitor's record grants both (AGL-1649). The\n * clamp in {@link consentModeSignals} still makes ads-without-analytics\n * unrepresentable, so a withdrawal can never restore advertising alone.\n */\nexport function setResidentAnalyticsTags(\n granted: boolean,\n advertising = false,\n): string[] {\n if (typeof window === 'undefined') return []\n const ids = residentGaMeasurementIds()\n const scope = window as unknown as Record<string, unknown>\n for (const id of ids) {\n scope[`${GA_DISABLE_FLAG_PREFIX}${id}`] = !granted\n }\n try {\n const send = scope.gtag\n if (typeof send === 'function') {\n // The same payload builder the load-time `default` is made from\n // (AGL-1622), so the two declarations cannot drift.\n ;(send as (...args: unknown[]) => void)(\n 'consent',\n 'update',\n consentModeSignals({ analytics: granted, advertising }),\n )\n }\n } catch {\n // A tag that throws on its own consent call is one we cannot silence;\n // the flag above and the cookie sweep still stand.\n }\n return ids\n}\n\n/**\n * The stored record, or null when there is none (never resolved, storage\n * unavailable, or an unrecognized shape — treated alike: not yet decided).\n */\nexport function readStoredVisitorConsent(\n hostId: string | null | undefined,\n): StoredVisitorConsent | null {\n if (!hostId || typeof window === 'undefined') return null\n try {\n const raw = window.localStorage.getItem(visitorConsentStorageKey(hostId))\n if (!raw) return null\n const parsed = JSON.parse(raw)\n if (\n parsed?.v !== 1 ||\n typeof parsed.status !== 'string' ||\n !CONSENT_STATUSES.has(parsed.status)\n ) {\n return null\n }\n const status = parsed.status as VisitorConsentStatus\n return {\n v: 1,\n at: typeof parsed.at === 'number' ? parsed.at : 0,\n status,\n // Derived, never trusted from storage: a hand-edited record must not\n // grant what its status does not.\n analytics: analyticsGrantedByStatus(status),\n // Same discipline for advertising (AGL-1649), plus one more clause:\n // the key has to be PRESENT and true. Absent is a record written\n // before the category existed — never asked, which is not a yes.\n advertising:\n advertisingGrantedByStatus(status) && parsed.advertising === true,\n country: typeof parsed.country === 'string' ? parsed.country : null,\n }\n } catch {\n // No storage (privacy mode) or corrupt JSON — the visitor is simply\n // undecided, which is the safe reading.\n return null\n }\n}\n\n/**\n * Record a consent state and make the page agree with it immediately.\n *\n * Storing the record is itself strictly-necessary storage (it is how a \"no\"\n * is remembered), so it is exempt from the consent it records. Any\n * non-granting state also REMOVES the identifiers the grant allowed —\n * the persistent `aglyn:visitor` id AND the GA cookies\n * ({@link clearAnalyticsCookies}): opting out cleans up, it does not merely\n * stop adding (AGL-1606) — and SILENCES the tag that is already running\n * ({@link setResidentAnalyticsTags}), without which the cleanup un-does itself\n * within the same pageview (AGL-1608). Listeners hear about it via\n * {@link VISITOR_CONSENT_CHANGED_EVENT} so the GA gate and the runtime react\n * without a reload.\n *\n * The two cleanups are deliberately in SEPARATE try blocks: private mode\n * throws on `localStorage` while cookies still work, and a withdrawal must\n * not lose the cookie sweep to that.\n */\nexport function storeVisitorConsent(\n hostId: string,\n state: {\n status: VisitorConsentStatus\n country?: string | null\n /**\n * The visitor's answer to the advertising question (AGL-1649). Omitted\n * by every caller that does not ask one, and omitted means NO.\n */\n advertising?: boolean\n },\n): StoredVisitorConsent {\n const stored: StoredVisitorConsent = {\n v: 1,\n at: Date.now(),\n status: state.status,\n analytics: analyticsGrantedByStatus(state.status),\n // Derived at store time exactly as `analytics` is, so a caller cannot\n // persist a grant the status does not support — a refusal always writes\n // `false` here even if the panel's checkbox was left ticked.\n advertising:\n advertisingGrantedByStatus(state.status) && state.advertising === true,\n country: state.country ?? null,\n }\n if (typeof window !== 'undefined') {\n try {\n window.localStorage.setItem(\n visitorConsentStorageKey(hostId),\n JSON.stringify(stored),\n )\n if (!stored.analytics) {\n window.localStorage.removeItem(VISITOR_ID_STORAGE_KEY)\n }\n } catch {\n // Private mode: the state holds for this page via the event below,\n // and is re-derived next visit — the safe failure.\n }\n // Silence the RESIDENT tag before sweeping, never after (AGL-1608): the\n // gate only keeps the script from LOADING, so a mid-pageview withdrawal\n // leaves gtag.js live and it re-writes `_ga_<id>` on its next enhanced\n // measurement event. Sweeping first would delete three cookies and\n // immediately get one back.\n setResidentAnalyticsTags(stored.analytics, stored.advertising === true)\n if (!stored.analytics) {\n clearAnalyticsCookies()\n }\n // The advertising half, and it belongs HERE rather than only in\n // `revokeAdvertisingTags` (AGL-2486). That function sweeps a vendor whose\n // marked script elements are in the document, and it is installed only on\n // our own marketing host — so on a CUSTOMER site, where the advertising\n // question is equally available, withdrawing advertising ran no sweep at\n // all. `_gcl_au` is written by the GA tag `site-analytics.tsx` mounts, not\n // by a script this module marked, so no element-scoped teardown was ever\n // going to reach it on any surface.\n //\n // This path is the one every site shares: it is where a decision becomes a\n // record. Unconditional on the grant being absent, for the reason in\n // `clearAdvertisingCookies` — a delete of something never set costs\n // nothing, a missed delete is the defect.\n if (!stored.advertising) {\n clearAdvertisingCookies()\n }\n try {\n window.dispatchEvent(new CustomEvent(VISITOR_CONSENT_CHANGED_EVENT))\n } catch {\n // A dispatch failure only delays consumers until the next read.\n }\n }\n return stored\n}\n\n/**\n * The GA gate's whole verdict: may the analytics category run for this\n * visitor, on this site, right now?\n *\n * - Consent machinery not required (no gated features, or host opted out of\n * the tool) → yes.\n * - Required and the recorded state grants analytics (`accepted` or\n * `implied`) → yes.\n * - Required and anything else — declined, opted out, GPC, or NOT YET\n * RESOLVED → no. Undecided is not a maybe: the script stays out until a\n * state that grants it exists. The gate never asks WHY consent is absent,\n * which is what keeps it posture-independent.\n */\nexport function isAnalyticsAllowed(\n host: VisitorConsentHost | null | undefined,\n stored: StoredVisitorConsent | null,\n): boolean {\n if (!hostConsentRequired(host)) return true\n return stored?.analytics === true\n}\n\n/**\n * Where the marketing runtime may keep its experiment visitor id.\n *\n * `local` — the id persists across visits. `session` — the id lives in\n * sessionStorage: variants stay stable within the visit and the identifier\n * dies with the tab. The downgrade applies while the consent machinery is\n * active for this site and analytics is not granted; the id itself never\n * leaves the browser either way (the experiment beacons are aggregate — no\n * visitor id on the wire).\n */\nexport function resolveVisitorIdPersistence(\n host: VisitorConsentHost | null | undefined,\n stored: StoredVisitorConsent | null,\n): 'local' | 'session' {\n return isAnalyticsAllowed(host, stored) ? 'local' : 'session'\n}\n"],"names":["CONSENT_STATUSES","Set","isExplicitConsentStatus","status","refusalStatusFor","stored","posture","analyticsGrantedByStatus","advertisingGrantedByStatus","GA_MEASUREMENT_ID_PATTERN","META_PIXEL_ID_PATTERN","GOOGLE_ADS_ID_PATTERN","LINKEDIN_PARTNER_ID_PATTERN","resolveGaMeasurementId","host","candidate","String","analytics","gaMeasurementId","test","GTM_CONTAINER_ID_PATTERN","resolveGtmContainerId","gtmContainerId","hostHasGoogleTag","isConsentToolDisabled","consent","disabled","resolveHostConsentMode","mode","consentGatedCategories","hostAsksAboutAdvertising","advertising","hostConsentRequired","length","PRIOR_CONSENT_COUNTRY_CODES","resolveConsentPosture","country","has","toUpperCase","hasGlobalPrivacyControl","navigator","globalPrivacyControl","VISITOR_CONSENT_STORAGE_PREFIX","VISITOR_ID_STORAGE_KEY","VISITOR_CONSENT_CHANGED_EVENT","VISITOR_CONSENT_OPEN_EVENT","visitorConsentStorageKey","hostId","ANALYTICS_COOKIE_PREFIXES","ADVERTISING_COOKIE_PREFIXES","clearAdvertisingCookies","hostname","clearCookiesWithPrefixes","MULTI_LABEL_PUBLIC_SUFFIXES","normalizeCookieHostname","trim","toLowerCase","replace","registrableCookieDomain","name","startsWith","includes","labels","split","some","label","lastTwo","slice","join","analyticsCookieDomains","registrable","domains","current","push","cut","indexOf","clearAnalyticsCookies","prefixes","document","window","names","pair","cookie","p","add","size","location","expired","domain","GA_DISABLE_FLAG_PREFIX","analyticsConsentSignals","granted","analytics_storage","ad_storage","ad_user_data","ad_personalization","consentModeSignals","grants","ads","advertisingGrantedByRecord","GA_CONSENT_DEFAULT_SNIPPET","JSON","stringify","GA_CONSENT_DEFAULT_WITH_ADS_SNIPPET","GA_CLICK_ID_PASSTHROUGH_SNIPPET","residentGaMeasurementIds","ids","loaded","querySelectorAll","element","Array","from","src","match","exec","id","decodeURIComponent","layer","dataLayer","entry","args","setResidentAnalyticsTags","scope","send","gtag","readStoredVisitorConsent","raw","localStorage","getItem","parsed","parse","v","at","storeVisitorConsent","state","Date","now","setItem","removeItem","dispatchEvent","CustomEvent","isAnalyticsAllowed","resolveVisitorIdPersistence"],"mappings":"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"}
@@ -0,0 +1,223 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * Flat platform ceilings on the two host subcollections an ANONYMOUS VISITOR
19
+ * can create documents in (AGL-1529).
20
+ *
21
+ * ## What this is
22
+ *
23
+ * A platform-wide ceiling, and deliberately NOT a plan dimension — so
24
+ * "unlimited member accounts on every plan" stays true, because an abuse
25
+ * control is not something we sell. The same instrument is already in place
26
+ * twice: AGL-1655 for forms and AGL-2155 for bandwidth.
27
+ *
28
+ * ## Why it is not a plan dimension, and must never become one
29
+ *
30
+ * AGL-889 decided member accounts are UNLIMITED on every plan as a PRICING
31
+ * matter, and `/pricing` says so. A cap that varied by plan would make that
32
+ * sentence false the moment it shipped. So there is no `OrgEntitlements` key
33
+ * here, no `PLAN_ENTITLEMENTS` row, no band and nothing to re-price: every
34
+ * plan, free through enterprise, gets the same number, and the number exists
35
+ * only to answer the question `checkFormSubmissionAbuseCeiling`'s docblock
36
+ * poses — *"is this still a customer's traffic at all?"* A plan gate asks
37
+ * whether the customer bought this; this asks whether a customer is involved.
38
+ *
39
+ * ## The hole this closes
40
+ *
41
+ * `hosts/{hostId}/siteMembers` and `hosts/{hostId}/leads` were bounded by
42
+ * NOTHING. Both are written on behalf of anonymous visitors on a public site
43
+ * (`membershipRegisterHandler`, the two bookings lead paths), and the only
44
+ * bound was `visitorWriteRateLimitRefusal` — keyed on (host, IP), fails soft,
45
+ * and bounds the RATE rather than the TOTAL. That is verbatim the sentence
46
+ * AGL-2265 used as its reason for adding the free-workspace ceiling, and the
47
+ * shape AGL-2266 closed for `actions` and `entries`: unbounded Firestore
48
+ * documents behind a $0 subscription.
49
+ *
50
+ * ## Why the shape here is the FLAT family, not the MULTIPLE family
51
+ *
52
+ * The two ceilings named as precedent — `FORM_ABUSE_CEILING_*` and
53
+ * `BANDWIDTH_ABUSE_CEILING_*` — are both `max(floor, included × 10)`. They
54
+ * can be, because forms and bandwidth each have an *included band* on the
55
+ * price list to multiply. Members and leads have no included band by
56
+ * construction (that is the whole point of AGL-889), so there is nothing to
57
+ * multiply and a multiple would have to invent a plan dimension to have an
58
+ * operand — the exact thing the decision forbids.
59
+ *
60
+ * The repo already has the family for that case, and those same docblocks
61
+ * point at it: `WEBHOOK_MAX_PER_HOST` (AGL-1360), `NON_PAGE_SCREEN_MAX_PER_HOST`
62
+ * (AGL-1399), `ACTIONS_MAX_PER_HOST` / `ENTRIES_MAX_PER_COLLECTION` (AGL-2266),
63
+ * `AUTHORS_MAX_PER_HOST` (AGL-2486) — *"a flat PLATFORM cap with no
64
+ * `OrgEntitlements` key, no variation by plan, and nothing on the price list
65
+ * to explain."* So the two named precedents supply the POSTURE (containment,
66
+ * not capacity; a trip is an incident, not a quota; the refusal must be
67
+ * visible to the host and opaque to the visitor) and the flat family supplies
68
+ * the SHAPE. They do not disagree; they answer different halves.
69
+ *
70
+ * ## A TOTAL, not a monthly count — the one place the posture differs
71
+ *
72
+ * `FORM_ABUSE_CEILING` and `BANDWIDTH_ABUSE_CEILING` both count a month and
73
+ * therefore self-clear at the month boundary with nobody doing anything. These
74
+ * count LIVE DOCUMENTS, which do not. The refusal counters below are still
75
+ * month-keyed — that is a rate of refusals, and it is what the owner's notice
76
+ * reports — but the ceiling itself is cleared by deleting members or leads (or
77
+ * by support raising it), and the owner's notice must not promise a date. A
78
+ * notice that said "accepting again on 1 September" would be a promise the
79
+ * platform does not keep.
80
+ */
81
+ /**
82
+ * How many member accounts one site may hold (AGL-1529). the figure.
83
+ *
84
+ * Sized to the busiest plausible membership site rather than to today's data,
85
+ * which is the only property a flat ceiling needs. A site member is a human
86
+ * who chose a password on ONE site; 50,000 of them is a large membership
87
+ * roster — larger than anything on the platform and larger than anything the
88
+ * beta will produce — while a script wants millions and reaches this in an
89
+ * afternoon. Every account past it is refused, none is billed, and none of
90
+ * it changes what any plan includes.
91
+ *
92
+ * Counted as LIVE documents, so removing a member in the inbox frees the
93
+ * slot. Counting tombstones would be AGL-1173's bug one collection over.
94
+ */
95
+ export declare const SITE_MEMBERS_MAX_PER_HOST = 50000;
96
+ /**
97
+ * How many lead records one site may hold (AGL-1529).
98
+ *
99
+ * **Deliberately NOT the same number as {@link SITE_MEMBERS_MAX_PER_HOST}**,
100
+ * and the reason changed when leads were deduped.
101
+ *
102
+ * A lead used to be APPEND-ONLY, keyed by nothing: every sign-up wrote one
103
+ * and so did every booking, so one returning customer legitimately produced
104
+ * many rows. 4× was sized to keep the MEMBER ceiling the binding one on the
105
+ * path they share, rather than refusing a record on a site doing nothing
106
+ * wrong. Since `docs/specs/reusable-forms.md` §4 a lead is one document per
107
+ * person per host, keyed on `personKey`, so leads and members now count the
108
+ * same population and that arithmetic no longer applies.
109
+ *
110
+ * **The number stays where it is.** Lowering it because the collection stopped
111
+ * growing per event would convert a safety margin into a plan limit, which
112
+ * `docs/DECISION_LOG.md` forbids — the 2026-08-23 entry made this ceiling a
113
+ * flat platform abuse control precisely so "unlimited leads on every plan"
114
+ * stays literally true. What the headroom now buys is a ceiling that is very
115
+ * unlikely to trip at all, which is the right shape for a control that
116
+ * refuses a person: 200,000 lead rows at ~200 bytes is ~40 MB, which is a
117
+ * number, and unbounded is not.
118
+ *
119
+ * ⚠️ It must stay ABOVE {@link SITE_MEMBERS_MAX_PER_HOST}. A site member is
120
+ * also a lead, so an equal or lower lead ceiling would refuse the side effect
121
+ * of a sign-up the member ceiling had just allowed.
122
+ */
123
+ export declare const LEADS_MAX_PER_HOST = 200000;
124
+ /**
125
+ * Refusal code carried by the sign-up 429 (AGL-1529).
126
+ *
127
+ * The dispatcher's per-(host, IP) rate limiter answers 429 too, so the STATUS
128
+ * discriminates nothing — this code is the whole discriminator, and one means
129
+ * "slow down" while the other means "this site is not taking new accounts".
130
+ * Shared rather than restated so producer and consumer cannot drift, exactly
131
+ * as `FORM_ABUSE_CEILING_CODE` is.
132
+ */
133
+ export declare const SITE_MEMBER_CEILING_CODE = "site-member-ceiling";
134
+ /**
135
+ * The visitor's sentence, under the three rules `FORM_UNAVAILABLE_MESSAGE`
136
+ * established (AGL-1666) and for the identical reason: the person reading it
137
+ * is a stranger to the site and NOT our customer.
138
+ *
139
+ * 1. **It does not blame them.** They filled the form in correctly. Nothing
140
+ * about their address, their password or their retry is the reason.
141
+ * 2. **It does not explain.** "Unusual volume", "this site is at its member
142
+ * limit", or anything naming Aglyn, tells a stranger something about the
143
+ * site owner's account that the owner never chose to publish — and names
144
+ * a platform the visitor did not come here to hear about.
145
+ * 3. **It does not sound successful.** It says, in as many words, that the
146
+ * account was not created, so nobody walks away believing they have one
147
+ * and waiting for an email that is never coming.
148
+ */
149
+ export declare const SITE_MEMBER_UNAVAILABLE_MESSAGE: string;
150
+ /** The verdict every enforcement point below asks for. */
151
+ export interface VisitorRecordCeilingResult {
152
+ /** True once the live document count has REACHED the ceiling. */
153
+ exceeded: boolean;
154
+ /** The ceiling that was compared against. Always a finite integer. */
155
+ ceiling: number;
156
+ /** The count that was compared, floored at 0. */
157
+ used: number;
158
+ }
159
+ /**
160
+ * Is this site at a flat visitor-record ceiling?
161
+ *
162
+ * The ceiling is an explicit argument rather than read from a table, so the
163
+ * suite can re-drive the SAME usage against a ceiling one higher and require
164
+ * it to succeed — the causation leg of `free-tier-caps-refuse.spec.ts`, which
165
+ * is the only thing that distinguishes "refused by THIS cap" from "refuses
166
+ * everything". No production caller passes anything but the two constants
167
+ * above; {@link checkSiteMemberCeiling} and {@link checkLeadCeiling} bind them.
168
+ *
169
+ * `strictNullChecks` is OFF repo-wide, so both inputs are normalised rather
170
+ * than trusted, and the two directions are deliberately NOT symmetric:
171
+ *
172
+ * - `used` folds a missing/NaN count to 0, matching `checkBandwidthAbuseCeiling`.
173
+ * An unreadable count must not refuse a site; the count is read inside a
174
+ * transaction that throws rather than returning nothing, so this is a
175
+ * belt, not a path.
176
+ * - `ceiling` folds a missing/NaN ceiling to 0, and a ceiling of 0 REFUSES
177
+ * EVERYTHING. `0` is a legitimate ceiling meaning "none allowed" and must
178
+ * never read as unlimited — the `if (!count)` trap this repo keeps being
179
+ * bitten by, in the argument that decides the refusal.
180
+ */
181
+ export declare function checkVisitorRecordCeiling(used: number, ceiling: number): VisitorRecordCeilingResult;
182
+ /** {@link checkVisitorRecordCeiling} bound to {@link SITE_MEMBERS_MAX_PER_HOST}. */
183
+ export declare function checkSiteMemberCeiling(used: number): VisitorRecordCeilingResult;
184
+ /** {@link checkVisitorRecordCeiling} bound to {@link LEADS_MAX_PER_HOST}. */
185
+ export declare function checkLeadCeiling(used: number): VisitorRecordCeilingResult;
186
+ /** Which collection a trip belongs to — the counter id and the notice differ. */
187
+ export type VisitorRecordKind = 'siteMembers' | 'leads';
188
+ /**
189
+ * `hosts/{hostId}/counters/{…}` — the durable, client-unwritable record of a
190
+ * trip, in the same counters-document shape `formSubmissionsRefused` uses
191
+ * (AGL-1367/1655). Named through a function so the writer in
192
+ * `@aglyn/tenant-data-admin` and the reader in the inbox console page cannot
193
+ * spell it two different ways.
194
+ */
195
+ export declare function visitorRecordRefusedCounterId(kind: VisitorRecordKind): string;
196
+ /** What the site's owner is shown. Shaped like `FormsPausedOwnerNotice`. */
197
+ export interface VisitorRecordsPausedNotice {
198
+ title: string;
199
+ /** What happened, how many, and what actually clears it. */
200
+ message: string;
201
+ }
202
+ /**
203
+ * The owner's notice — the half deliberately withheld from the visitor.
204
+ *
205
+ * Two `{title, message}` lines rather than `LockdownRefusalNotice`'s three:
206
+ * there is **no `until`**, and its absence is the point. The form and
207
+ * bandwidth ceilings count a month and genuinely do lift on the 1st, so their
208
+ * notices name a date. This ceiling counts live documents, so no date lifts
209
+ * it — deleting records does, or support raising it does. Borrowing the third
210
+ * line for symmetry would print a date that means nothing.
211
+ *
212
+ * Returns `null` below one refusal, the same rule as
213
+ * `formSubmissionsPausedNotice` and for the same reason: the counter document
214
+ * persists from its first trip forever, and "0 refused" on every later month
215
+ * trains the owner to ignore the row that will one day be real.
216
+ */
217
+ export declare function visitorRecordsPausedNotice(input: {
218
+ kind: VisitorRecordKind;
219
+ /** Refusals recorded for the month being displayed. */
220
+ refused: number;
221
+ /** The ceiling that was crossed, from the counter document. */
222
+ ceiling?: number;
223
+ }): VisitorRecordsPausedNotice | null;
@@ -0,0 +1,215 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ /**
17
+ * Flat platform ceilings on the two host subcollections an ANONYMOUS VISITOR
18
+ * can create documents in (AGL-1529).
19
+ *
20
+ * ## What this is
21
+ *
22
+ * A platform-wide ceiling, and deliberately NOT a plan dimension — so
23
+ * "unlimited member accounts on every plan" stays true, because an abuse
24
+ * control is not something we sell. The same instrument is already in place
25
+ * twice: AGL-1655 for forms and AGL-2155 for bandwidth.
26
+ *
27
+ * ## Why it is not a plan dimension, and must never become one
28
+ *
29
+ * AGL-889 decided member accounts are UNLIMITED on every plan as a PRICING
30
+ * matter, and `/pricing` says so. A cap that varied by plan would make that
31
+ * sentence false the moment it shipped. So there is no `OrgEntitlements` key
32
+ * here, no `PLAN_ENTITLEMENTS` row, no band and nothing to re-price: every
33
+ * plan, free through enterprise, gets the same number, and the number exists
34
+ * only to answer the question `checkFormSubmissionAbuseCeiling`'s docblock
35
+ * poses — *"is this still a customer's traffic at all?"* A plan gate asks
36
+ * whether the customer bought this; this asks whether a customer is involved.
37
+ *
38
+ * ## The hole this closes
39
+ *
40
+ * `hosts/{hostId}/siteMembers` and `hosts/{hostId}/leads` were bounded by
41
+ * NOTHING. Both are written on behalf of anonymous visitors on a public site
42
+ * (`membershipRegisterHandler`, the two bookings lead paths), and the only
43
+ * bound was `visitorWriteRateLimitRefusal` — keyed on (host, IP), fails soft,
44
+ * and bounds the RATE rather than the TOTAL. That is verbatim the sentence
45
+ * AGL-2265 used as its reason for adding the free-workspace ceiling, and the
46
+ * shape AGL-2266 closed for `actions` and `entries`: unbounded Firestore
47
+ * documents behind a $0 subscription.
48
+ *
49
+ * ## Why the shape here is the FLAT family, not the MULTIPLE family
50
+ *
51
+ * The two ceilings named as precedent — `FORM_ABUSE_CEILING_*` and
52
+ * `BANDWIDTH_ABUSE_CEILING_*` — are both `max(floor, included × 10)`. They
53
+ * can be, because forms and bandwidth each have an *included band* on the
54
+ * price list to multiply. Members and leads have no included band by
55
+ * construction (that is the whole point of AGL-889), so there is nothing to
56
+ * multiply and a multiple would have to invent a plan dimension to have an
57
+ * operand — the exact thing the decision forbids.
58
+ *
59
+ * The repo already has the family for that case, and those same docblocks
60
+ * point at it: `WEBHOOK_MAX_PER_HOST` (AGL-1360), `NON_PAGE_SCREEN_MAX_PER_HOST`
61
+ * (AGL-1399), `ACTIONS_MAX_PER_HOST` / `ENTRIES_MAX_PER_COLLECTION` (AGL-2266),
62
+ * `AUTHORS_MAX_PER_HOST` (AGL-2486) — *"a flat PLATFORM cap with no
63
+ * `OrgEntitlements` key, no variation by plan, and nothing on the price list
64
+ * to explain."* So the two named precedents supply the POSTURE (containment,
65
+ * not capacity; a trip is an incident, not a quota; the refusal must be
66
+ * visible to the host and opaque to the visitor) and the flat family supplies
67
+ * the SHAPE. They do not disagree; they answer different halves.
68
+ *
69
+ * ## A TOTAL, not a monthly count — the one place the posture differs
70
+ *
71
+ * `FORM_ABUSE_CEILING` and `BANDWIDTH_ABUSE_CEILING` both count a month and
72
+ * therefore self-clear at the month boundary with nobody doing anything. These
73
+ * count LIVE DOCUMENTS, which do not. The refusal counters below are still
74
+ * month-keyed — that is a rate of refusals, and it is what the owner's notice
75
+ * reports — but the ceiling itself is cleared by deleting members or leads (or
76
+ * by support raising it), and the owner's notice must not promise a date. A
77
+ * notice that said "accepting again on 1 September" would be a promise the
78
+ * platform does not keep.
79
+ */ /**
80
+ * How many member accounts one site may hold (AGL-1529). the figure.
81
+ *
82
+ * Sized to the busiest plausible membership site rather than to today's data,
83
+ * which is the only property a flat ceiling needs. A site member is a human
84
+ * who chose a password on ONE site; 50,000 of them is a large membership
85
+ * roster — larger than anything on the platform and larger than anything the
86
+ * beta will produce — while a script wants millions and reaches this in an
87
+ * afternoon. Every account past it is refused, none is billed, and none of
88
+ * it changes what any plan includes.
89
+ *
90
+ * Counted as LIVE documents, so removing a member in the inbox frees the
91
+ * slot. Counting tombstones would be AGL-1173's bug one collection over.
92
+ */ export const SITE_MEMBERS_MAX_PER_HOST = 50000;
93
+ /**
94
+ * How many lead records one site may hold (AGL-1529).
95
+ *
96
+ * **Deliberately NOT the same number as {@link SITE_MEMBERS_MAX_PER_HOST}**,
97
+ * and the reason changed when leads were deduped.
98
+ *
99
+ * A lead used to be APPEND-ONLY, keyed by nothing: every sign-up wrote one
100
+ * and so did every booking, so one returning customer legitimately produced
101
+ * many rows. 4× was sized to keep the MEMBER ceiling the binding one on the
102
+ * path they share, rather than refusing a record on a site doing nothing
103
+ * wrong. Since `docs/specs/reusable-forms.md` §4 a lead is one document per
104
+ * person per host, keyed on `personKey`, so leads and members now count the
105
+ * same population and that arithmetic no longer applies.
106
+ *
107
+ * **The number stays where it is.** Lowering it because the collection stopped
108
+ * growing per event would convert a safety margin into a plan limit, which
109
+ * `docs/DECISION_LOG.md` forbids — the 2026-08-23 entry made this ceiling a
110
+ * flat platform abuse control precisely so "unlimited leads on every plan"
111
+ * stays literally true. What the headroom now buys is a ceiling that is very
112
+ * unlikely to trip at all, which is the right shape for a control that
113
+ * refuses a person: 200,000 lead rows at ~200 bytes is ~40 MB, which is a
114
+ * number, and unbounded is not.
115
+ *
116
+ * ⚠️ It must stay ABOVE {@link SITE_MEMBERS_MAX_PER_HOST}. A site member is
117
+ * also a lead, so an equal or lower lead ceiling would refuse the side effect
118
+ * of a sign-up the member ceiling had just allowed.
119
+ */ export const LEADS_MAX_PER_HOST = 200000;
120
+ /**
121
+ * Refusal code carried by the sign-up 429 (AGL-1529).
122
+ *
123
+ * The dispatcher's per-(host, IP) rate limiter answers 429 too, so the STATUS
124
+ * discriminates nothing — this code is the whole discriminator, and one means
125
+ * "slow down" while the other means "this site is not taking new accounts".
126
+ * Shared rather than restated so producer and consumer cannot drift, exactly
127
+ * as `FORM_ABUSE_CEILING_CODE` is.
128
+ */ export const SITE_MEMBER_CEILING_CODE = 'site-member-ceiling';
129
+ /**
130
+ * The visitor's sentence, under the three rules `FORM_UNAVAILABLE_MESSAGE`
131
+ * established (AGL-1666) and for the identical reason: the person reading it
132
+ * is a stranger to the site and NOT our customer.
133
+ *
134
+ * 1. **It does not blame them.** They filled the form in correctly. Nothing
135
+ * about their address, their password or their retry is the reason.
136
+ * 2. **It does not explain.** "Unusual volume", "this site is at its member
137
+ * limit", or anything naming Aglyn, tells a stranger something about the
138
+ * site owner's account that the owner never chose to publish — and names
139
+ * a platform the visitor did not come here to hear about.
140
+ * 3. **It does not sound successful.** It says, in as many words, that the
141
+ * account was not created, so nobody walks away believing they have one
142
+ * and waiting for an email that is never coming.
143
+ */ export const SITE_MEMBER_UNAVAILABLE_MESSAGE = 'This site isn’t accepting new accounts right now, so your account was ' + 'not created. Please try again later.';
144
+ /**
145
+ * Is this site at a flat visitor-record ceiling?
146
+ *
147
+ * The ceiling is an explicit argument rather than read from a table, so the
148
+ * suite can re-drive the SAME usage against a ceiling one higher and require
149
+ * it to succeed — the causation leg of `free-tier-caps-refuse.spec.ts`, which
150
+ * is the only thing that distinguishes "refused by THIS cap" from "refuses
151
+ * everything". No production caller passes anything but the two constants
152
+ * above; {@link checkSiteMemberCeiling} and {@link checkLeadCeiling} bind them.
153
+ *
154
+ * `strictNullChecks` is OFF repo-wide, so both inputs are normalised rather
155
+ * than trusted, and the two directions are deliberately NOT symmetric:
156
+ *
157
+ * - `used` folds a missing/NaN count to 0, matching `checkBandwidthAbuseCeiling`.
158
+ * An unreadable count must not refuse a site; the count is read inside a
159
+ * transaction that throws rather than returning nothing, so this is a
160
+ * belt, not a path.
161
+ * - `ceiling` folds a missing/NaN ceiling to 0, and a ceiling of 0 REFUSES
162
+ * EVERYTHING. `0` is a legitimate ceiling meaning "none allowed" and must
163
+ * never read as unlimited — the `if (!count)` trap this repo keeps being
164
+ * bitten by, in the argument that decides the refusal.
165
+ */ export function checkVisitorRecordCeiling(used, ceiling) {
166
+ const resolvedCeiling = Math.max(0, Math.floor(Number(ceiling) || 0));
167
+ const resolvedUsed = Math.max(0, Math.floor(Number(used) || 0));
168
+ return {
169
+ exceeded: resolvedUsed >= resolvedCeiling,
170
+ ceiling: resolvedCeiling,
171
+ used: resolvedUsed
172
+ };
173
+ }
174
+ /** {@link checkVisitorRecordCeiling} bound to {@link SITE_MEMBERS_MAX_PER_HOST}. */ export function checkSiteMemberCeiling(used) {
175
+ return checkVisitorRecordCeiling(used, SITE_MEMBERS_MAX_PER_HOST);
176
+ }
177
+ /** {@link checkVisitorRecordCeiling} bound to {@link LEADS_MAX_PER_HOST}. */ export function checkLeadCeiling(used) {
178
+ return checkVisitorRecordCeiling(used, LEADS_MAX_PER_HOST);
179
+ }
180
+ /**
181
+ * `hosts/{hostId}/counters/{…}` — the durable, client-unwritable record of a
182
+ * trip, in the same counters-document shape `formSubmissionsRefused` uses
183
+ * (AGL-1367/1655). Named through a function so the writer in
184
+ * `@aglyn/tenant-data-admin` and the reader in the inbox console page cannot
185
+ * spell it two different ways.
186
+ */ export function visitorRecordRefusedCounterId(kind) {
187
+ return kind === 'leads' ? 'leadsRefused' : 'siteMembersRefused';
188
+ }
189
+ /**
190
+ * The owner's notice — the half deliberately withheld from the visitor.
191
+ *
192
+ * Two `{title, message}` lines rather than `LockdownRefusalNotice`'s three:
193
+ * there is **no `until`**, and its absence is the point. The form and
194
+ * bandwidth ceilings count a month and genuinely do lift on the 1st, so their
195
+ * notices name a date. This ceiling counts live documents, so no date lifts
196
+ * it — deleting records does, or support raising it does. Borrowing the third
197
+ * line for symmetry would print a date that means nothing.
198
+ *
199
+ * Returns `null` below one refusal, the same rule as
200
+ * `formSubmissionsPausedNotice` and for the same reason: the counter document
201
+ * persists from its first trip forever, and "0 refused" on every later month
202
+ * trains the owner to ignore the row that will one day be real.
203
+ */ export function visitorRecordsPausedNotice(input) {
204
+ const refused = Math.floor(Number(input.refused) || 0);
205
+ if (refused < 1) return null;
206
+ const ceiling = typeof input.ceiling === 'number' && Number.isFinite(input.ceiling) ? Math.floor(input.ceiling) : undefined;
207
+ const leads = input.kind === 'leads';
208
+ const noun = leads ? 'lead' : 'sign-up';
209
+ return {
210
+ title: leads ? 'Lead capture is paused' : 'New member sign-ups are paused',
211
+ message: `${refused.toLocaleString()} ${noun}${refused === 1 ? '' : 's'} on ` + `this site ${refused === 1 ? 'has' : 'have'} been refused this month` + (ceiling ? ` after it reached ${ceiling.toLocaleString()} ` + `${leads ? 'leads' : 'member accounts'}` : '') + '. Refused records are not stored and are not billed. This is a ' + 'platform safety limit, not part of your plan — every plan includes ' + `unlimited ${leads ? 'leads' : 'member accounts'}. Removing ` + `${leads ? 'leads' : 'members'} below the limit starts acceptance ` + 'again immediately; if this is real traffic, contact support and we ' + 'will raise it.'
212
+ };
213
+ }
214
+
215
+ //# sourceMappingURL=visitor-record-ceiling.js.map