@aglyn/aglyn 1.0.0-beta.221 → 1.0.0-beta.222
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.
- package/package.json +15 -11
- package/src/lib/app-utils/agent-openapi.js +1 -1
- package/src/lib/app-utils/agent-openapi.js.map +1 -1
- package/src/lib/app-utils/analytics-events.d.ts +3 -2
- package/src/lib/app-utils/analytics-events.js +3 -2
- package/src/lib/app-utils/analytics-events.js.map +1 -1
- package/src/lib/app-utils/api-plugins.d.ts +30 -0
- package/src/lib/app-utils/api-plugins.js +24 -1
- package/src/lib/app-utils/api-plugins.js.map +1 -1
- package/src/lib/app-utils/author-html.d.ts +1 -1
- package/src/lib/app-utils/author-html.js.map +1 -1
- package/src/lib/app-utils/bandwidth-cap.d.ts +12 -1
- package/src/lib/app-utils/bandwidth-cap.js +17 -1
- package/src/lib/app-utils/bandwidth-cap.js.map +1 -1
- package/src/lib/app-utils/compose-reusable-components.d.ts +19 -0
- package/src/lib/app-utils/compose-reusable-components.js +116 -26
- package/src/lib/app-utils/compose-reusable-components.js.map +1 -1
- package/src/lib/app-utils/console-routes.d.ts +4 -0
- package/src/lib/app-utils/console-routes.js +3 -0
- package/src/lib/app-utils/console-routes.js.map +1 -1
- package/src/lib/app-utils/contacts.d.ts +71 -0
- package/src/lib/app-utils/contacts.js +55 -0
- package/src/lib/app-utils/contacts.js.map +1 -1
- package/src/lib/app-utils/contexts.d.ts +1 -0
- package/src/lib/app-utils/contexts.js +1 -0
- package/src/lib/app-utils/contexts.js.map +1 -1
- package/src/lib/app-utils/crm-email-templates.js +21 -4
- package/src/lib/app-utils/crm-email-templates.js.map +1 -1
- package/src/lib/app-utils/crm-kinds.d.ts +2 -0
- package/src/lib/app-utils/crm-kinds.js +1 -0
- package/src/lib/app-utils/crm-kinds.js.map +1 -1
- package/src/lib/app-utils/crm.d.ts +1199 -67
- package/src/lib/app-utils/crm.js +1951 -310
- package/src/lib/app-utils/crm.js.map +1 -1
- package/src/lib/app-utils/csv-import.d.ts +10 -38
- package/src/lib/app-utils/csv-import.js +17 -42
- package/src/lib/app-utils/csv-import.js.map +1 -1
- package/src/lib/app-utils/csv.d.ts +32 -11
- package/src/lib/app-utils/csv.js +43 -5
- package/src/lib/app-utils/csv.js.map +1 -1
- package/src/lib/app-utils/default-site.d.ts +116 -0
- package/src/lib/app-utils/default-site.js +1024 -0
- package/src/lib/app-utils/default-site.js.map +1 -0
- package/src/lib/app-utils/docs-help.generated.d.ts +22 -22
- package/src/lib/app-utils/docs-help.generated.js +44 -10
- package/src/lib/app-utils/docs-help.generated.js.map +1 -1
- package/src/lib/app-utils/docs-index.generated.js +738 -150
- package/src/lib/app-utils/docs-index.generated.js.map +1 -1
- package/src/lib/app-utils/draft-placeholders.d.ts +76 -0
- package/src/lib/app-utils/draft-placeholders.js +115 -0
- package/src/lib/app-utils/draft-placeholders.js.map +1 -0
- package/src/lib/app-utils/entity-picker-context.d.ts +19 -15
- package/src/lib/app-utils/entity-picker-context.js +4 -4
- package/src/lib/app-utils/entity-picker-context.js.map +1 -1
- package/src/lib/app-utils/expand-repeatables.d.ts +66 -10
- package/src/lib/app-utils/expand-repeatables.js +88 -14
- package/src/lib/app-utils/expand-repeatables.js.map +1 -1
- package/src/lib/app-utils/forms.d.ts +33 -22
- package/src/lib/app-utils/forms.js +47 -28
- package/src/lib/app-utils/forms.js.map +1 -1
- package/src/lib/app-utils/full-use-cost.d.ts +277 -0
- package/src/lib/app-utils/full-use-cost.js +421 -0
- package/src/lib/app-utils/full-use-cost.js.map +1 -0
- package/src/lib/app-utils/health-report.js +11 -0
- package/src/lib/app-utils/health-report.js.map +1 -1
- package/src/lib/app-utils/llms-txt.d.ts +20 -0
- package/src/lib/app-utils/llms-txt.js +7 -1
- package/src/lib/app-utils/llms-txt.js.map +1 -1
- package/src/lib/app-utils/media-asset-facts.d.ts +16 -1
- package/src/lib/app-utils/media-asset-facts.js +40 -13
- package/src/lib/app-utils/media-asset-facts.js.map +1 -1
- package/src/lib/app-utils/media-bandwidth.d.ts +52 -0
- package/src/lib/app-utils/media-bandwidth.js +94 -0
- package/src/lib/app-utils/media-bandwidth.js.map +1 -0
- package/src/lib/app-utils/media-ref.d.ts +241 -33
- package/src/lib/app-utils/media-ref.js +324 -43
- package/src/lib/app-utils/media-ref.js.map +1 -1
- package/src/lib/app-utils/media-src.d.ts +8 -8
- package/src/lib/app-utils/media-src.js +27 -11
- package/src/lib/app-utils/media-src.js.map +1 -1
- package/src/lib/app-utils/media-takedown-reach.d.ts +4 -1
- package/src/lib/app-utils/media-takedown-reach.js +6 -3
- package/src/lib/app-utils/media-takedown-reach.js.map +1 -1
- package/src/lib/app-utils/notifications.d.ts +1 -1
- package/src/lib/app-utils/notifications.js +2 -0
- package/src/lib/app-utils/notifications.js.map +1 -1
- package/src/lib/app-utils/organizations.d.ts +51 -2
- package/src/lib/app-utils/organizations.js +56 -3
- package/src/lib/app-utils/organizations.js.map +1 -1
- package/src/lib/app-utils/page-record-sources.d.ts +87 -0
- package/src/lib/app-utils/page-record-sources.js +53 -0
- package/src/lib/app-utils/page-record-sources.js.map +1 -0
- package/src/lib/app-utils/paid-media-source.d.ts +3 -7
- package/src/lib/app-utils/paid-media-source.js +5 -19
- package/src/lib/app-utils/paid-media-source.js.map +1 -1
- package/src/lib/app-utils/person-erasure.d.ts +5 -2
- package/src/lib/app-utils/person-erasure.js.map +1 -1
- package/src/lib/app-utils/picklists.d.ts +187 -0
- package/src/lib/app-utils/picklists.js +320 -0
- package/src/lib/app-utils/picklists.js.map +1 -0
- package/src/lib/app-utils/plan-entitlements.d.ts +220 -50
- package/src/lib/app-utils/plan-entitlements.js +309 -115
- package/src/lib/app-utils/plan-entitlements.js.map +1 -1
- package/src/lib/app-utils/realm-host-surface.generated.js +2 -0
- package/src/lib/app-utils/realm-host-surface.generated.js.map +1 -1
- package/src/lib/app-utils/release-flags.d.ts +1 -1
- package/src/lib/app-utils/release-flags.js +11 -0
- package/src/lib/app-utils/release-flags.js.map +1 -1
- package/src/lib/app-utils/rendered-widths.d.ts +121 -0
- package/src/lib/app-utils/rendered-widths.js +211 -0
- package/src/lib/app-utils/rendered-widths.js.map +1 -0
- package/src/lib/app-utils/repeat-sources.d.ts +2 -1
- package/src/lib/app-utils/repeat-sources.js.map +1 -1
- package/src/lib/app-utils/screen-route.d.ts +154 -36
- package/src/lib/app-utils/screen-route.js +185 -40
- package/src/lib/app-utils/screen-route.js.map +1 -1
- package/src/lib/app-utils/seo-audit.d.ts +11 -1
- package/src/lib/app-utils/seo-audit.js +33 -13
- package/src/lib/app-utils/seo-audit.js.map +1 -1
- package/src/lib/app-utils/seo-keywords.d.ts +11 -0
- package/src/lib/app-utils/seo-keywords.js +19 -5
- package/src/lib/app-utils/seo-keywords.js.map +1 -1
- package/src/lib/app-utils/seo-page-facts.d.ts +47 -4
- package/src/lib/app-utils/seo-page-facts.js +136 -31
- package/src/lib/app-utils/seo-page-facts.js.map +1 -1
- package/src/lib/app-utils/seo-site-scan.d.ts +42 -4
- package/src/lib/app-utils/seo-site-scan.js +113 -12
- package/src/lib/app-utils/seo-site-scan.js.map +1 -1
- package/src/lib/app-utils/server.d.ts +5 -4
- package/src/lib/app-utils/server.js +14 -5
- package/src/lib/app-utils/server.js.map +1 -1
- package/src/lib/app-utils/site-icon-set.d.ts +195 -0
- package/src/lib/app-utils/site-icon-set.js +351 -0
- package/src/lib/app-utils/site-icon-set.js.map +1 -0
- package/src/lib/app-utils/site-interactions.d.ts +101 -4
- package/src/lib/app-utils/site-interactions.js +120 -4
- package/src/lib/app-utils/site-interactions.js.map +1 -1
- package/src/lib/app-utils/starter-template-nodes.d.ts +7 -0
- package/src/lib/app-utils/starter-template-nodes.js +3 -0
- package/src/lib/app-utils/starter-template-nodes.js.map +1 -1
- package/src/lib/app-utils/starter-templates.d.ts +5 -19
- package/src/lib/app-utils/starter-templates.js +5 -49
- package/src/lib/app-utils/starter-templates.js.map +1 -1
- package/src/lib/app-utils/transfer-launcher-context.d.ts +136 -0
- package/src/lib/app-utils/transfer-launcher-context.js +23 -0
- package/src/lib/app-utils/transfer-launcher-context.js.map +1 -0
- package/src/lib/app-utils/transfer-resume-import.d.ts +39 -0
- package/src/lib/app-utils/transfer-resume-import.js +128 -0
- package/src/lib/app-utils/transfer-resume-import.js.map +1 -0
- package/src/lib/app-utils/upgrade-proposal.d.ts +66 -0
- package/src/lib/app-utils/upgrade-proposal.js +95 -0
- package/src/lib/app-utils/upgrade-proposal.js.map +1 -0
- package/src/lib/app-utils/utc-month.d.ts +33 -0
- package/src/lib/app-utils/utc-month.js +35 -0
- package/src/lib/app-utils/utc-month.js.map +1 -0
- package/src/lib/app-utils/visitor-record-ceiling.d.ts +4 -4
- package/src/lib/app-utils/visitor-record-ceiling.js +4 -4
- package/src/lib/app-utils/visitor-record-ceiling.js.map +1 -1
- package/src/lib/app-utils/wire-nodes.d.ts +39 -19
- package/src/lib/app-utils/wire-nodes.js +120 -34
- package/src/lib/app-utils/wire-nodes.js.map +1 -1
- package/src/lib/data-transfer/access.d.ts +74 -0
- package/src/lib/data-transfer/access.js +93 -0
- package/src/lib/data-transfer/access.js.map +1 -0
- package/src/lib/data-transfer/derive.d.ts +246 -0
- package/src/lib/data-transfer/derive.js +1007 -0
- package/src/lib/data-transfer/derive.js.map +1 -0
- package/src/lib/data-transfer/export-file.d.ts +46 -0
- package/src/lib/data-transfer/export-file.js +146 -0
- package/src/lib/data-transfer/export-file.js.map +1 -0
- package/src/lib/data-transfer/field-catalog.d.ts +134 -0
- package/src/lib/data-transfer/field-catalog.js +278 -0
- package/src/lib/data-transfer/field-catalog.js.map +1 -0
- package/src/lib/data-transfer/header-match.d.ts +129 -0
- package/src/lib/data-transfer/header-match.js +367 -0
- package/src/lib/data-transfer/header-match.js.map +1 -0
- package/src/lib/data-transfer/index.d.ts +34 -0
- package/src/lib/data-transfer/index.js +40 -0
- package/src/lib/data-transfer/index.js.map +1 -0
- package/src/lib/data-transfer/job.d.ts +190 -0
- package/src/lib/data-transfer/job.js +229 -0
- package/src/lib/data-transfer/job.js.map +1 -0
- package/src/lib/data-transfer/lookup.d.ts +45 -0
- package/src/lib/data-transfer/lookup.js +71 -0
- package/src/lib/data-transfer/lookup.js.map +1 -0
- package/src/lib/data-transfer/match.d.ts +99 -0
- package/src/lib/data-transfer/match.js +244 -0
- package/src/lib/data-transfer/match.js.map +1 -0
- package/src/lib/data-transfer/package-plan.d.ts +205 -0
- package/src/lib/data-transfer/package-plan.js +475 -0
- package/src/lib/data-transfer/package-plan.js.map +1 -0
- package/src/lib/data-transfer/package.d.ts +181 -0
- package/src/lib/data-transfer/package.js +426 -0
- package/src/lib/data-transfer/package.js.map +1 -0
- package/src/lib/data-transfer/picklist-map.d.ts +139 -0
- package/src/lib/data-transfer/picklist-map.js +271 -0
- package/src/lib/data-transfer/picklist-map.js.map +1 -0
- package/src/lib/data-transfer/plan.d.ts +176 -0
- package/src/lib/data-transfer/plan.js +451 -0
- package/src/lib/data-transfer/plan.js.map +1 -0
- package/src/lib/data-transfer/policy.d.ts +170 -0
- package/src/lib/data-transfer/policy.js +378 -0
- package/src/lib/data-transfer/policy.js.map +1 -0
- package/src/lib/data-transfer/resource.d.ts +211 -0
- package/src/lib/data-transfer/resource.js +241 -0
- package/src/lib/data-transfer/resource.js.map +1 -0
- package/src/lib/data-transfer/review.d.ts +70 -0
- package/src/lib/data-transfer/review.js +233 -0
- package/src/lib/data-transfer/review.js.map +1 -0
- package/src/lib/data-transfer/similarity.d.ts +40 -0
- package/src/lib/data-transfer/similarity.js +106 -0
- package/src/lib/data-transfer/similarity.js.map +1 -0
- package/src/lib/data-transfer/site-package.d.ts +365 -0
- package/src/lib/data-transfer/site-package.js +1077 -0
- package/src/lib/data-transfer/site-package.js.map +1 -0
- package/src/lib/data-transfer/source.d.ts +74 -0
- package/src/lib/data-transfer/source.js +293 -0
- package/src/lib/data-transfer/source.js.map +1 -0
- package/src/lib/data-transfer/transfer-api.d.ts +898 -0
- package/src/lib/data-transfer/transfer-api.js +107 -0
- package/src/lib/data-transfer/transfer-api.js.map +1 -0
- package/src/lib/foundation/definitions/org-billing.types.d.ts +31 -0
- package/src/lib/foundation/definitions/org-billing.types.js.map +1 -1
- package/src/lib/foundation/definitions/organization.types.d.ts +42 -1
- package/src/lib/foundation/definitions/organization.types.js.map +1 -1
- package/src/lib/foundation/definitions/platform.types.d.ts +6 -4
- package/src/lib/foundation/definitions/platform.types.js.map +1 -1
- package/src/lib/foundation/index.d.ts +1 -1
- package/src/lib/foundation/index.js.map +1 -1
- package/src/lib/plugin-manager/feature-plugins.d.ts +91 -2
- package/src/lib/plugin-manager/feature-plugins.js +48 -3
- package/src/lib/plugin-manager/feature-plugins.js.map +1 -1
- package/src/lib/plugin-manager/first-party-plugins.generated.d.ts +50 -0
- package/src/lib/plugin-manager/first-party-plugins.generated.js +1129 -28
- package/src/lib/plugin-manager/first-party-plugins.generated.js.map +1 -1
- package/src/lib/plugin-manager/index.d.ts +0 -1
- package/src/lib/plugin-manager/index.js +0 -1
- package/src/lib/plugin-manager/index.js.map +1 -1
- package/src/lib/plugin-manager/interaction-recipes.d.ts +142 -0
- package/src/lib/plugin-manager/interaction-recipes.js +104 -0
- package/src/lib/plugin-manager/interaction-recipes.js.map +1 -0
- package/src/lib/plugin-manager/interaction-step-checks.d.ts +66 -0
- package/src/lib/plugin-manager/interaction-step-checks.js +86 -0
- package/src/lib/plugin-manager/interaction-step-checks.js.map +1 -0
- package/src/lib/plugin-manager/plugin-artifact-types.d.ts +235 -0
- package/src/lib/plugin-manager/plugin-artifact-types.js +99 -0
- package/src/lib/plugin-manager/plugin-artifact-types.js.map +1 -0
- package/src/lib/plugin-manager/plugin-contact-capture.d.ts +8 -0
- package/src/lib/plugin-manager/plugin-contact-capture.js.map +1 -1
- package/src/lib/plugin-manager/plugin-conversion-credit.d.ts +216 -0
- package/src/lib/plugin-manager/plugin-conversion-credit.js +91 -0
- package/src/lib/plugin-manager/plugin-conversion-credit.js.map +1 -0
- package/src/lib/plugin-manager/plugin-entity-pickers.d.ts +83 -0
- package/src/lib/plugin-manager/plugin-entity-pickers.js +87 -0
- package/src/lib/plugin-manager/plugin-entity-pickers.js.map +1 -0
- package/src/lib/plugin-manager/plugin-host-resources.d.ts +6 -0
- package/src/lib/plugin-manager/plugin-host-resources.js +6 -1
- package/src/lib/plugin-manager/plugin-host-resources.js.map +1 -1
- package/src/lib/plugin-manager/plugin-intake-gates.d.ts +75 -0
- package/src/lib/plugin-manager/plugin-intake-gates.js +49 -0
- package/src/lib/plugin-manager/plugin-intake-gates.js.map +1 -0
- package/src/lib/plugin-manager/plugin-jobs.d.ts +5 -5
- package/src/lib/plugin-manager/plugin-jobs.js +7 -7
- package/src/lib/plugin-manager/plugin-jobs.js.map +1 -1
- package/src/lib/plugin-manager/plugin-live-paths.d.ts +70 -0
- package/src/lib/plugin-manager/plugin-live-paths.js +66 -0
- package/src/lib/plugin-manager/plugin-live-paths.js.map +1 -0
- package/src/lib/plugin-manager/plugin-org-erasure.d.ts +3 -2
- package/src/lib/plugin-manager/plugin-org-erasure.js +30 -5
- package/src/lib/plugin-manager/plugin-org-erasure.js.map +1 -1
- package/src/lib/plugin-manager/plugin-person-erasure.d.ts +68 -9
- package/src/lib/plugin-manager/plugin-person-erasure.js +196 -51
- package/src/lib/plugin-manager/plugin-person-erasure.js.map +1 -1
- package/src/lib/plugin-manager/plugin-person-records.d.ts +275 -0
- package/src/lib/plugin-manager/plugin-person-records.js +107 -0
- package/src/lib/plugin-manager/plugin-person-records.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-counts.d.ts +76 -0
- package/src/lib/plugin-manager/plugin-record-counts.js +49 -0
- package/src/lib/plugin-manager/plugin-record-counts.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-email-state.d.ts +26 -0
- package/src/lib/plugin-manager/plugin-record-email-state.js +16 -0
- package/src/lib/plugin-manager/plugin-record-email-state.js.map +1 -1
- package/src/lib/plugin-manager/plugin-record-index.d.ts +10 -0
- package/src/lib/plugin-manager/plugin-record-index.js.map +1 -1
- package/src/lib/plugin-manager/plugin-record-lists.d.ts +86 -6
- package/src/lib/plugin-manager/plugin-record-lists.js +42 -5
- package/src/lib/plugin-manager/plugin-record-lists.js.map +1 -1
- package/src/lib/plugin-manager/plugin-record-origin.d.ts +79 -0
- package/src/lib/plugin-manager/plugin-record-origin.js +46 -0
- package/src/lib/plugin-manager/plugin-record-origin.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-pages.d.ts +37 -0
- package/src/lib/plugin-manager/plugin-record-pages.js +52 -0
- package/src/lib/plugin-manager/plugin-record-pages.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-timeline.d.ts +60 -0
- package/src/lib/plugin-manager/plugin-record-timeline.js +16 -0
- package/src/lib/plugin-manager/plugin-record-timeline.js.map +1 -1
- package/src/lib/plugin-manager/plugin-resource-drafts.d.ts +5 -5
- package/src/lib/plugin-manager/plugin-resource-drafts.js.map +1 -1
- package/src/lib/plugin-manager/plugin-revocations.d.ts +64 -0
- package/src/lib/plugin-manager/plugin-revocations.js +47 -0
- package/src/lib/plugin-manager/plugin-revocations.js.map +1 -0
- package/src/lib/plugin-manager/plugin-send-tallies.d.ts +69 -0
- package/src/lib/plugin-manager/plugin-send-tallies.js +45 -0
- package/src/lib/plugin-manager/plugin-send-tallies.js.map +1 -0
- package/src/lib/plugin-manager/plugin-site-bundle.d.ts +40 -0
- package/src/lib/plugin-manager/plugin-site-bundle.js +4 -0
- package/src/lib/plugin-manager/plugin-site-bundle.js.map +1 -1
- package/src/lib/plugin-manager/plugin-site-export.d.ts +57 -1
- package/src/lib/plugin-manager/plugin-site-export.js +23 -10
- package/src/lib/plugin-manager/plugin-site-export.js.map +1 -1
- package/src/lib/plugin-manager/plugin-sitemap-readers.d.ts +146 -0
- package/src/lib/plugin-manager/plugin-sitemap-readers.js +110 -0
- package/src/lib/plugin-manager/plugin-sitemap-readers.js.map +1 -0
- package/src/lib/plugin-manager/plugin-transfer-resources.d.ts +714 -0
- package/src/lib/plugin-manager/plugin-transfer-resources.js +443 -0
- package/src/lib/plugin-manager/plugin-transfer-resources.js.map +1 -0
- package/src/lib/plugin-manager/plugin-usage-axes.d.ts +54 -5
- package/src/lib/plugin-manager/plugin-usage-axes.js +11 -3
- package/src/lib/plugin-manager/plugin-usage-axes.js.map +1 -1
- package/src/lib/plugin-manager/plugin-user-erasure.js +9 -1
- package/src/lib/plugin-manager/plugin-user-erasure.js.map +1 -1
- package/src/lib/plugin-manager/plugin-visitor-doors.d.ts +104 -0
- package/src/lib/plugin-manager/plugin-visitor-doors.js +108 -0
- package/src/lib/plugin-manager/plugin-visitor-doors.js.map +1 -0
- package/src/lib/plugin-manager/realm-host-aglyn.generated.js +2 -0
- package/src/lib/plugin-manager/realm-host-aglyn.generated.js.map +1 -1
- package/src/lib/plugin-manager/repeat-rows.d.ts +5 -6
- package/src/lib/plugin-manager/repeat-rows.js.map +1 -1
- package/src/lib/app-utils/actions.d.ts +0 -310
- package/src/lib/app-utils/actions.js +0 -506
- package/src/lib/app-utils/actions.js.map +0 -1
- package/src/lib/app-utils/automation-placeholders.d.ts +0 -72
- package/src/lib/app-utils/automation-placeholders.js +0 -207
- package/src/lib/app-utils/automation-placeholders.js.map +0 -1
- package/src/lib/app-utils/dataset-models.d.ts +0 -339
- package/src/lib/app-utils/dataset-models.js +0 -722
- package/src/lib/app-utils/dataset-models.js.map +0 -1
- package/src/lib/app-utils/datasets.d.ts +0 -171
- package/src/lib/app-utils/datasets.js +0 -227
- package/src/lib/app-utils/datasets.js.map +0 -1
- package/src/lib/app-utils/form-abuse-ceiling.d.ts +0 -146
- package/src/lib/app-utils/form-abuse-ceiling.js +0 -158
- package/src/lib/app-utils/form-abuse-ceiling.js.map +0 -1
- package/src/lib/plugin-manager/order-fulfilment.d.ts +0 -142
- package/src/lib/plugin-manager/order-fulfilment.js +0 -104
- package/src/lib/plugin-manager/order-fulfilment.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/compose-reusable-components.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// By path: the naming rule alone, without the icon catalog's loader beside it.\nimport { iconPathPropName } from '@aglyn/shared-data-mdi/utils/icon-path-prop-name'\nimport type {\n AglynNodeSchema,\n NodeId,\n ReusableComponentIcon,\n ReusableComponentProp,\n} from '../foundation'\nimport {\n type ReusablePropValueClass,\n reusablePropValueClass,\n} from '../foundation/definitions/property-kinds'\nimport {\n COMPONENT_NODE_ID_PREFIX,\n COMPONENT_PROP_TOKEN_PREFIX,\n INSTANCE_CARRIED_NODE_FIELDS,\n INSTANCE_CARRIED_PROPS,\n NODE_HIDE_IF_PROP,\n NODE_HIDE_UNLESS_PROP,\n REUSABLE_INSTANCE_COMPONENT_ID,\n REUSABLE_INSTANCE_PROP_VALUES_KEY,\n STYLE_OVERRIDES_ROOT_KEY,\n} from './reusable-component-keys'\nimport {\n REPEAT_DIRECTIVE_PROPS,\n REPEAT_SELF_PROP,\n repeatKey,\n withoutRepeatDirective,\n} from './expand-repeatables'\nimport { FORM_COMPONENT_ID, FORM_ID_PROP } from './forms'\nimport { mergeNodeSx } from './merge-node-sx'\nimport {\n hasUrlScheme,\n isSafeNodeUrl,\n NODE_URL_PROPS,\n type NodeUrlProp,\n} from './node-url-policy'\nimport {\n readInstanceIconValue,\n readYesNoValue,\n resolveReusablePropValues,\n} from './reusable-prop-values'\nimport { resolveNamedTokens } from './resolve-named-tokens'\n\nexport * from './reusable-component-keys'\nexport * from './reusable-prop-values'\n\nconst isStyleRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.keys(value).length > 0\n\n/**\n * Space-separated class lists joined in order, each name once, or `undefined`\n * when no list holds a name. A value that is not a string contributes nothing.\n */\nfunction joinClassNames(...lists: unknown[]): string | undefined {\n const names = lists\n .filter((list): list is string => typeof list === 'string')\n .flatMap((list) => list.split(/\\s+/))\n .filter(Boolean)\n return names.length ? [...new Set(names)].join(' ') : undefined\n}\n\n/**\n * Whether a node is a placed form that names a form entity — the second kind\n * of node that stands for a tree stored on another document (see\n * {@link PlacementKind}). A `form` node with no `formId` is an ordinary form\n * whose fields are its own children, and has no override layer.\n *\n * The ref test matches the graft's own resolution rule (a non-empty string),\n * so the editor and the renderer agree about which forms are placements.\n */\nexport function isPlacedFormNode(\n node: { componentId?: string; props?: unknown } | undefined | null,\n): boolean {\n if (node?.componentId !== FORM_COMPONENT_ID) return false\n const formId = (node.props as Record<string, unknown> | undefined)?.[\n FORM_ID_PROP\n ]\n return typeof formId === 'string' && formId !== ''\n}\n\n/**\n * Whether a node is a placement that GRAFTS a definition — a reusable\n * component instance or a placed form — and therefore carries the two\n * per-placement override layers (`styleOverrides`, `attrOverrides`, AGL-3285).\n *\n * One predicate for both kinds on purpose: the graft already expands them in\n * one pass, and an override layer that one kind honoured and the other\n * silently ignored would be the canvas/Preview/tenant disagreement this file\n * exists to prevent.\n */\nexport function isDefinitionPlacement(\n node: { componentId?: string; props?: unknown } | undefined | null,\n): boolean {\n return (\n node?.componentId === REUSABLE_INSTANCE_COMPONENT_ID ||\n isPlacedFormNode(node)\n )\n}\n\n/**\n * The tree a placement grafts, from whichever map its kind reads — the\n * component definitions for an instance, the published form designs for a\n * placed form — or `undefined` when it is not a placement or its ref resolves\n * to nothing (AGL-3285). The editor panels use it to offer the same targets\n * the graft will consult.\n */\nexport function placementDefinitionFor<\n N extends AglynNodeSchema = AglynNodeSchema,\n>(\n node: { componentId?: string; props?: unknown } | undefined | null,\n sources: {\n definitions?: Record<string, ReusableComponentTree<N> | undefined>\n formDesigns?: Record<\n string,\n Pick<ReusableComponentTree<N>, 'rootId' | 'nodes'> | undefined\n >\n },\n): Pick<ReusableComponentTree<N>, 'rootId' | 'nodes'> | undefined {\n const props = node?.props as Record<string, unknown> | undefined\n if (node?.componentId === REUSABLE_INSTANCE_COMPONENT_ID) {\n const refId = props?.['refId']\n return typeof refId === 'string' && refId\n ? sources.definitions?.[refId]\n : undefined\n }\n if (isPlacedFormNode(node)) {\n const design = sources.formDesigns?.[props?.[FORM_ID_PROP] as string]\n // The graft's resolution rule: a design whose root is not among its own\n // nodes grafts nothing, so it offers nothing to override either.\n return design?.rootId && design.nodes?.[design.rootId] ? design : undefined\n }\n return undefined\n}\n\n/**\n * Every per-instance style override an instance node carries, keyed the way\n * it is stored (AGL-1332): {@link STYLE_OVERRIDES_ROOT_KEY} for the\n * component root, and a DEFINITION-internal node id for each overridden\n * leaf. Empty for a node that is not a placement ({@link\n * isDefinitionPlacement}: an instance or a placed form) or carries none.\n *\n * Keyed on the definition's own id, never the grafted `cmp__…` id: the\n * graft id is DERIVED from the instance id, so keying on it would break the\n * moment a subtree was duplicated or an instance re-keyed, and two\n * instances of one component could not share the same authoring vocabulary.\n * Entries that are not a non-empty plain object are dropped here rather\n * than at each call site — a `null`, a string, or a cleared `{}` must read\n * as \"no override\" identically in the graft, in detach and in the panel.\n *\n * Deliberately here rather than in a render surface: this file owns what\n * an instance node looks like, and the graft below is the ONE place the\n * overrides are applied — canvas, Preview and tenant SSR all call\n * {@link composeReusableComponentNodes}, so they cannot disagree about\n * what an override means.\n */\nexport function getInstanceStyleOverrides(\n node:\n | { componentId?: string; props?: unknown; styleOverrides?: unknown }\n | undefined\n | null,\n): Record<string, Record<string, unknown>> {\n if (!isDefinitionPlacement(node)) return {}\n const overrides = node?.styleOverrides as Record<string, unknown> | undefined\n if (!isStyleRecord(overrides)) return {}\n const clean: Record<string, Record<string, unknown>> = {}\n for (const [key, value] of Object.entries(overrides)) {\n if (key && isStyleRecord(value)) clean[key] = value\n }\n return clean\n}\n\n/**\n * The sx-shaped ROOT style override carried by an instance node, or\n * `undefined` when the node is not an instance or carries none — the\n * AGL-1306 half of {@link getInstanceStyleOverrides}.\n */\nexport function getInstanceRootStyleOverride(\n node:\n | { componentId?: string; props?: unknown; styleOverrides?: unknown }\n | undefined\n | null,\n): Record<string, unknown> | undefined {\n return getInstanceStyleOverrides(node)[STYLE_OVERRIDES_ROOT_KEY]\n}\n\n/**\n * The `{ sx }` patch one definition node takes from an instance's\n * overrides, or `undefined` when none applies (AGL-1332).\n *\n * Two layers, coarse first: the root slice when this node IS the\n * definition root, then the node's own definition-id slice. Both go\n * through `mergeNodeSx`, so a per-leaf override gets exactly the cascade\n * semantics the root one already had — a `{ md: … }` slice keeps the\n * base's narrower widths, an `@scheme dark` slice merges key-by-key, and\n * a plain property replaces only the leaf it names.\n *\n * A key naming a node the definition no longer has is simply never\n * consulted: this runs per definition node, so a component edited after\n * the override was written degrades to the component's own styling rather\n * than throwing on a page nobody has opened since.\n *\n * Returned as a patch object rather than a value so the caller can spread\n * nothing at all — writing `sx: undefined` onto a node that never had one\n * would materialize the key on every grafted leaf.\n */\nfunction instanceSxPatch(\n baseSx: unknown,\n overrides: Record<string, Record<string, unknown>>,\n defId: NodeId,\n rootId: NodeId | undefined,\n): { sx: unknown } | undefined {\n // The root is addressed by the constant, so a definition node whose id\n // merely happens to BE `root` without being the root gets nothing from\n // the root slice — the alternative is styling an arbitrary leaf from the\n // panel's root target.\n const rootSlice =\n defId === rootId ? overrides[STYLE_OVERRIDES_ROOT_KEY] : undefined\n const leafSlice =\n defId === STYLE_OVERRIDES_ROOT_KEY ? undefined : overrides[defId]\n if (!rootSlice && !leafSlice) return undefined\n let sx = baseSx\n if (rootSlice) sx = mergeNodeSx(sx, rootSlice)\n if (leafSlice) sx = mergeNodeSx(sx, leafSlice)\n return { sx }\n}\n\n/**\n * Props on a grafted definition node that an instance override must never\n * address (AGL-1899).\n *\n * `sx` has its own override layer one field up, and honouring it here would\n * leave two writers racing for one rendered value with no rule to say which\n * wins — the Styles panel would show an instance as clean while the\n * Attributes panel silently repainted it.\n */\nconst ATTR_OVERRIDE_REFUSED_PROPS = new Set(['sx'])\n\n/**\n * Props a placed form's attribute overrides must never address, on any node\n * of its design (AGL-3285).\n *\n * A form is edited once and every page placing it follows — that is the\n * whole point of the form entity. Its submission list, its dataset columns,\n * its consent tick and its routing are all keyed to what the ENTITY declares,\n * so a page that renamed a field, retyped it, made it optional, rewrote its\n * choices or re-pointed where the form sends would file answers the form's\n * own schema does not describe, from one page only, with nothing on the\n * Forms page saying so. Per page, a form may LOOK different; it may not\n * collect something different.\n *\n * - The form node's identity and submission config: `formId`, `formName`,\n * `datasetId`, `datasetName`, and the after-submit outcome\n * (`afterSubmit`, `redirectScreenId`, `redirectUrl`, `revealNodeId`).\n * - Each field's contract: `fieldName` (the submission key),\n * `datasetFieldId`, `fieldType`, `options` (a ticked option's TEXT is the\n * posted value, and the consent check reads it) and `required`.\n * - Element attributes a browser submission reads directly: `name`, `type`\n * (a submit button made a plain button no longer submits), `value`,\n * `action`, `method`, and `disabled` (a disabled input is not posted).\n * - The hide directives: a hidden field is pruned from the page, so its\n * value is never sent.\n *\n * Label, placeholder, help text, the submit label and success message, and\n * everything about styling stay overridable.\n */\nexport const PLACED_FORM_REFUSED_ATTR_PROPS: ReadonlySet<string> = new Set([\n FORM_ID_PROP,\n 'formName',\n 'datasetId',\n 'datasetName',\n 'afterSubmit',\n 'redirectScreenId',\n 'redirectUrl',\n 'revealNodeId',\n 'fieldName',\n 'datasetFieldId',\n 'fieldType',\n 'options',\n 'required',\n 'name',\n 'type',\n 'value',\n 'action',\n 'method',\n 'disabled',\n NODE_HIDE_IF_PROP,\n NODE_HIDE_UNLESS_PROP,\n])\n\n/**\n * Whether `prop` may never be an attribute override on this placement — `sx`\n * on every placement, plus {@link PLACED_FORM_REFUSED_ATTR_PROPS} on a placed\n * form. The render layer and the editor's writer both ask this, so a refused\n * prop can neither be offered nor take effect.\n */\nexport function isAttrOverrideRefused(\n placement: { componentId?: string; props?: unknown } | undefined | null,\n prop: string,\n): boolean {\n if (ATTR_OVERRIDE_REFUSED_PROPS.has(prop)) return true\n return isPlacedFormNode(placement) && PLACED_FORM_REFUSED_ATTR_PROPS.has(prop)\n}\n\n/**\n * Every per-instance ATTRIBUTE override an instance node carries, keyed the\n * way {@link getInstanceStyleOverrides} keys styles — `root` for the\n * definition root, a definition-internal node id for anything else\n * (AGL-1899).\n *\n * Refused props are dropped HERE rather than at the write site, so a slice\n * that reached storage before a refusal existed (or by any path that did not\n * go through the panel) still cannot take effect.\n */\nexport function getInstanceAttrOverrides(\n node:\n | { componentId?: string; props?: unknown; attrOverrides?: unknown }\n | undefined\n | null,\n): Record<string, Record<string, unknown>> {\n if (!isDefinitionPlacement(node)) return {}\n const overrides = node?.attrOverrides as Record<string, unknown> | undefined\n if (!isStyleRecord(overrides)) return {}\n const clean: Record<string, Record<string, unknown>> = {}\n for (const [key, value] of Object.entries(overrides)) {\n if (!key || !isStyleRecord(value)) continue\n const slice: Record<string, unknown> = {}\n for (const [prop, propValue] of Object.entries(value)) {\n if (isAttrOverrideRefused(node, prop)) continue\n slice[prop] = propValue\n }\n if (Object.keys(slice).length > 0) clean[key] = slice\n }\n return clean\n}\n\n/**\n * The `{ props }` patch one definition node takes from an instance's\n * attribute overrides, or `undefined` when none applies (AGL-1899).\n *\n * Layered coarse-first exactly like {@link instanceSxPatch} — the root slice\n * when this node IS the definition root, then the node's own id slice — so\n * the two override kinds stay one authoring model rather than two.\n *\n * The merge is one level deep, replacing only the props each slice NAMES.\n * That keeps a component free to add a prop later and still have every\n * existing instance pick up the new default, and it is deliberately not the\n * cascade `mergeNodeSx` performs: an sx object's nested records are\n * selectors (`@scheme dark`, breakpoints) that genuinely compose, while a\n * prop value is one value. Deep-merging two prop objects that merely look\n * alike would hand the renderer a third thing neither the component nor the\n * page asked for.\n */\nfunction instancePropsPatch(\n baseProps: unknown,\n overrides: Record<string, Record<string, unknown>>,\n defId: NodeId,\n rootId: NodeId | undefined,\n): { props: Record<string, unknown> } | undefined {\n const rootSlice =\n defId === rootId ? overrides[STYLE_OVERRIDES_ROOT_KEY] : undefined\n const leafSlice =\n defId === STYLE_OVERRIDES_ROOT_KEY ? undefined : overrides[defId]\n if (!rootSlice && !leafSlice) return undefined\n return {\n props: {\n ...((baseProps as Record<string, unknown> | undefined) ?? {}),\n ...(rootSlice ?? {}),\n ...(leafSlice ?? {}),\n },\n }\n}\n\n/** One styleable target inside an instance — see {@link listInstanceStyleTargets}. */\nexport interface InstanceStyleTarget {\n /** The `styleOverrides` key this target reads and writes. */\n key: string\n /** The definition-internal node id it styles. */\n componentInternalId: NodeId\n /** 0 for the component root, +1 per level down — the picker indents by it. */\n depth: number\n /** The definition node's `componentId`, so a picker can label it. */\n componentId?: string\n /** The definition node's own `name`, when the component author set one. */\n name?: string\n /** True for the component root (the AGL-1306 target). */\n isRoot: boolean\n}\n\n/**\n * The styleable targets inside one component definition, in tree order\n * (root first, then depth-first through each node's `nodes`) — what the\n * Styles panel offers when a component instance is selected (AGL-1332).\n *\n * Beside the graft on purpose: the panel must write the SAME keys the\n * graft reads, and a second walker that disagreed would offer authors\n * targets no renderer consults. Cycle-safe and unreachable-safe: a node\n * the root cannot reach is not offered, because the graft would never\n * render it either.\n */\nexport function listInstanceStyleTargets(\n definition:\n | Pick<ReusableComponentTree<any>, 'rootId' | 'nodes'>\n | null\n | undefined,\n): InstanceStyleTarget[] {\n const rootId = definition?.rootId\n const nodes = definition?.nodes\n if (!rootId || !nodes?.[rootId]) return []\n const targets: InstanceStyleTarget[] = []\n const seen = new Set<NodeId>()\n const walk = (id: NodeId, depth: number) => {\n const node = nodes[id]\n // `seen` is what bounds the walk: a definition that referenced an\n // ancestor would otherwise recurse until the stack gave out.\n if (!node || seen.has(id)) return\n seen.add(id)\n const isRoot = id === rootId\n targets.push({\n key: isRoot ? STYLE_OVERRIDES_ROOT_KEY : id,\n componentInternalId: id,\n depth,\n componentId: (node as { componentId?: string }).componentId,\n name: (node as { name?: string }).name,\n isRoot,\n })\n const children = (node as { nodes?: unknown }).nodes\n if (!Array.isArray(children)) return\n for (const childId of children as NodeId[]) {\n if (typeof childId === 'string') walk(childId, depth + 1)\n }\n }\n walk(rootId, 0)\n return targets\n}\n\n/**\n * Definitions may nest instances of other definitions; expansion runs in\n * passes capped here so a self-referencing definition can't recurse forever.\n *\n * Exported for the one reader that has to agree with it: a loader fetching\n * only the definitions a document references (`load-referenced-components`)\n * follows nesting exactly this deep, so it never reads a level the graft\n * would not expand, and never stops short of one it would.\n */\nexport const MAX_COMPONENT_DEPTH = 5\n\ntype NormalizedNodes<N extends AglynNodeSchema> = Record<NodeId, N>\n\n/** Stored shape of a host-level reusable component definition's tree. */\nexport interface ReusableComponentTree<\n N extends AglynNodeSchema = AglynNodeSchema,\n> {\n rootId: NodeId\n nodes: NormalizedNodes<N>\n /** Props this definition declares (AGL-1247); absent = unparameterised. */\n props?: ReusableComponentProp[]\n /**\n * The definition's chosen icon (AGL-1193), carried so every editor surface\n * that draws an instance can reach it without a second read. Nothing in\n * the graft below touches it — an instance's icon is editor chrome, and\n * the published page renders the definition's own nodes.\n */\n icon?: ReusableComponentIcon\n}\n\nfunction instancePrefix(instanceId: NodeId) {\n return `${COMPONENT_NODE_ID_PREFIX}${instanceId}__`\n}\n\n/**\n * One kind of node that STANDS FOR a tree stored on another document, and\n * where that tree comes from.\n *\n * A reusable-component instance was the first such node; a placed form is the\n * second (`componentId: 'form'`, `props.formId` → `hosts/{hostId}/forms/{id}`,\n * whose published `rootId`/`nodes` are the fields the page renders). They are\n * one mechanism described twice, so they run through one expansion rather than\n * two passes that would have to agree about id namespacing, depth bounding and\n * cycle safety — and, more sharply, could not see each other: a form placed\n * inside a shared component only exists after the component graft, and a\n * reusable instance inside a form design only exists after the form graft.\n * Passing both kinds to {@link composeReusableComponentNodes} expands each\n * against the other, in either nesting order, within the same depth bound.\n */\nexport interface PlacementKind<N extends AglynNodeSchema = AglynNodeSchema> {\n /** The `componentId` a node must carry to be expanded by this kind. */\n componentId: string\n /** The prop naming the document whose tree is grafted. */\n refProp: string\n /** Resolvable trees, keyed by the id `refProp` holds. */\n definitionsById:\n | Record<string, ReusableComponentTree<N> | undefined>\n | undefined\n /**\n * Whether a resolved graft DISCARDS what the placement node already held.\n *\n * Off for reusable instances, which never hold anything: the editor refuses\n * a drop into them (`flags.dropping: DISABLED`), so replacing the child list\n * with the grafted root is the whole of what the graft has to do.\n *\n * On for placed forms, which do — a form node accepts fields, and every form\n * on the site was built that way before the form entity existed. Those\n * inline fields are the node's OWN content, so they cannot merely be\n * unlinked: left in the map they would still be walked by every later\n * compose stage, still ship in the page payload, and still answer to any\n * scan that reads `formField` nodes out of a flat map. The subtree is\n * dropped with the child list, exactly as `detachInstanceSubtree` drops what\n * it replaces.\n *\n * ⚠️ This is the one thing here that can take content off a page that\n * renders today, so it is deliberately gated on the graft RESOLVING: a\n * placement whose document is missing, unpublished, or holds no design is\n * left untouched, inline children and all. See\n * {@link composeReusableComponentNodes}.\n */\n replacesAuthoredChildren?: boolean\n}\n\n/**\n * The declared-prop name a stored value references when it is EXACTLY one\n * `{{prop.<name>}}` token (whitespace inside the braces tolerated, matching\n * `resolveNamedTokens`' grammar), else `null`.\n *\n * Exact-match on purpose: a value that merely CONTAINS a token\n * (`\"Hi {{prop.name}}!\"`) is only partially prop-fed, so an inline edit of\n * the rendered text could not be decomposed back into a prop value — those\n * leaves stay component-owned (AGL-1304).\n */\nexport function matchComponentPropToken(value: unknown): string | null {\n if (typeof value !== 'string') return null\n const match =\n /^\\s*\\{\\{\\s*prop\\.([A-Za-z_][A-Za-z0-9_]*)\\s*\\}\\}\\s*$/.exec(value)\n return match ? match[1] : null\n}\n\n/** What feeds a grafted instance leaf — see {@link resolveInstanceLeafBinding}. */\nexport interface InstanceLeafBinding {\n /** The definition-internal node id the grafted leaf was copied from. */\n componentInternalId: NodeId\n /**\n * The declared prop whose value feeds the leaf's `contentProp`, or `null`\n * when the leaf's content is the component's own (not prop-fed).\n */\n boundProp: string | null\n}\n\n/**\n * Maps a grafted node id back to its component-internal source and the\n * declared prop (if any) feeding one of its content props (AGL-1304).\n *\n * The graft's provenance is its id scheme — `cmp__{instanceId}__{defId}`\n * (see {@link composeReusableComponentNodes}) — and this is the ONE reader\n * of that scheme, deliberately beside the writer: the canvas double-click\n * hit-test uses it today, and AGL-1306 phase 2 (inner-node style overrides)\n * and AGL-1303 phase 3 (in-place focus mode) need the same inverse mapping.\n *\n * Returns `null` when the id was not grafted from THIS instance, or when\n * the internal id is unknown to the definition — which includes leaves of a\n * NESTED instance's graft (prefixes stack per pass), whose props are fed by\n * the outer definition's own instance node, not by this one.\n *\n * `boundProp` is non-null only when the definition node's `contentProp`\n * (default `children`; pass `src` for image leaves) is exactly one\n * `{{prop.*}}` token naming a DECLARED prop — an undeclared token never\n * substitutes, so an override written for it would silently do nothing.\n *\n * Pure: no canvas, no DOM, inputs never mutated.\n */\nexport function resolveInstanceLeafBinding(\n graftedId: NodeId | null | undefined,\n instanceId: NodeId | null | undefined,\n definition:\n | Pick<ReusableComponentTree, 'nodes' | 'props'>\n | null\n | undefined,\n contentProp = 'children',\n rootId?: NodeId | null,\n): InstanceLeafBinding | null {\n if (!graftedId || !instanceId) return null\n const prefix = instancePrefix(instanceId)\n // The definition's ROOT carries the instance's own id, not a prefixed one\n // — the two are one element (AGL-2521). Without this the root is the one\n // leaf the double-click cannot reach, so a component whose root IS its text\n // stops being inline-editable through its placements.\n if (graftedId === instanceId) {\n const rootInternalId =\n rootId ??\n Object.keys(definition?.nodes ?? {}).find(\n (id) => !(definition?.nodes as Record<string, { parentId?: unknown }>)?.[id]?.parentId,\n )\n if (!rootInternalId) return null\n return resolveInstanceLeafBinding(\n `${prefix}${rootInternalId}`,\n instanceId,\n definition,\n contentProp,\n )\n }\n if (!graftedId.startsWith(prefix)) return null\n const componentInternalId = graftedId.slice(prefix.length)\n if (!componentInternalId) return null\n const defNode = definition?.nodes?.[componentInternalId]\n if (!defNode) return null\n const raw = (defNode.props as Record<string, unknown> | undefined)?.[\n contentProp\n ]\n const name = matchComponentPropToken(raw)\n const declared =\n name != null && (definition?.props ?? []).some((prop) => prop?.name === name)\n return { componentInternalId, boundProp: declared ? name : null }\n}\n\n/** An instance's own values, keyed by declared prop name (AGL-1247). */\nfunction instancePropValues(\n instanceProps: unknown,\n): Record<string, unknown> | undefined {\n const values = (instanceProps as Record<string, unknown> | undefined)?.[\n REUSABLE_INSTANCE_PROP_VALUES_KEY\n ]\n return values && typeof values === 'object' && !Array.isArray(values)\n ? (values as Record<string, unknown>)\n : undefined\n}\n\n/**\n * The text an instance currently renders for a declared prop: its override\n * when set, else the prop's `defaultValue`, else `''`. `''` counts as unset,\n * as it does in the graft — clearing an override restores the component's own\n * copy, so the inline editor and the graft agree about what the author is\n * looking at.\n */\nexport function getInstanceEffectivePropText(\n instanceProps: unknown,\n declared: ReusableComponentProp[] | undefined | null,\n propName: string,\n): string {\n return (\n resolveReusablePropValues(declared, instancePropValues(instanceProps))\n .tokens[`${COMPONENT_PROP_TOKEN_PREFIX}${propName}`] ?? ''\n )\n}\n\n/** A value a field bound to a property has nothing to receive from. */\nfunction isNothingToGive(value: unknown): boolean {\n return (\n value === undefined ||\n value === null ||\n value === '' ||\n (Array.isArray(value) && value.length === 0) ||\n matchComponentPropToken(value) != null\n )\n}\n\n/** A copy a field can own: a list is copied, so no two fields share one. */\nfunction ownValue(value: unknown): unknown {\n return Array.isArray(value) ? [...value] : value\n}\n\n/**\n * What a field bound to exactly one property token receives, by the value\n * class of that property — or `undefined` to remove the prop.\n *\n * `known` is the property's value when the caller resolved one, and\n * `substituted` the text its token became; a caller that resolved nothing\n * (a component editor drawing raw tokens) is read from the text alone.\n */\nfunction typedBindingValue(\n valueClass: ReusablePropValueClass,\n known: { value: unknown } | undefined,\n substituted: unknown,\n): unknown {\n const value = known ? known.value : substituted\n switch (valueClass) {\n case 'boolean':\n return readYesNoValue(value) === true\n case 'number': {\n if (isNothingToGive(value)) return undefined\n if (typeof value === 'number') return value\n const numeric = Number(value)\n return Number.isFinite(numeric) ? numeric : substituted\n }\n case 'icon':\n return isNothingToGive(value)\n ? undefined\n : (readInstanceIconValue(value)?.iconId ?? undefined)\n default:\n return isNothingToGive(value) ? undefined : ownValue(value)\n }\n}\n\n/**\n * The declared-prop substitution for a set of nodes, with each binding handed\n * to the element as the value its property's kind holds (AGL-2871, AGL-2893).\n *\n * The substitution itself is textual — every token becomes text and\n * `resolveNamedTokens` splices it into string props. That is right for copy\n * and wrong for the fields that do not hold copy. So a prop whose stored value\n * is EXACTLY one token naming a declared prop is finished by that prop's value\n * class (`reusablePropValueClass`):\n *\n * - `boolean` (Yes / no, a single Checkbox) — a real `true` or `false`, read\n * through {@link readYesNoValue}, because an element reading `lightbox`\n * takes the string `'false'` for a yes. Nothing to read is a no.\n * - `number` (Number, Slider) — a real number when the value is one, because an\n * element passing `size` to MUI turns `'32'` into `font-size: 32`, which no\n * browser applies. Nothing set is removed; text that is not a number is left\n * as it was authored.\n * - `icon` — the picked icon's id, with its path written into the field's\n * companion (`iconId` → `iconPath`, the rule `iconPathPropName` states)\n * from `iconPaths`. The path is what a published page draws, since it never\n * loads the icon catalog; and it is written or removed on every pass,\n * because a path left over from the component's own icon would be drawn in\n * place of the page's. Nothing picked removes both.\n * - `value` (every other kind: a Choice, a Color, a Size, a Date, a list of\n * answers, an entity) — the value exactly as the property holds it, from\n * `values`, so a list stays a list and a theme multiple stays a number.\n * Nothing set is removed, so the element keeps its own default: a\n * dropdown's empty value is not one of its options, and an element handed\n * `variant: ''` draws neither the component's variant nor its own.\n * - `text` (Text, Long text, Image, Link) — the substituted text.\n *\n * \"Nothing chosen\" includes a binding still holding its token after\n * substitution — a component editor drawing a prop that has no default —\n * which is then drawn exactly as a page that sets nothing renders it.\n *\n * The same finishing reaches a nested placement: a component placed inside\n * this definition, whose own `propValues` hand one of this definition's\n * properties on by its exact token, receives the value typed — a list, a\n * number, an icon with its path — and nothing at all where there is nothing to\n * give, so its own default applies.\n *\n * Exact match only, for the reason {@link matchComponentPropToken} gives: a\n * value that merely contains a token is text with a value inside it, and it\n * stays text. An undeclared name is never typed either — it never substitutes,\n * so there is no value to read.\n *\n * Top-level props only, and never an element's text content (`children`). The\n * binding a panel field offers writes that field's own prop; a token nested in\n * an item list is content the component spelled out, and text is text\n * whatever kind of property fills it — so both keep the textual treatment.\n *\n * An `href` or `src` a token fed is then held to the address rule — see\n * {@link holdPropFedAddresses}.\n *\n * Inputs are never mutated, and a map with no typed binding and no refused\n * address comes back exactly as the substitution left it.\n */\nexport function resolveComponentPropTokens<\n N extends AglynNodeSchema = AglynNodeSchema,\n>(\n nodes: NormalizedNodes<N>,\n declared: ReusableComponentProp[] | undefined | null,\n tokens: Record<string, string> | null | undefined,\n iconPaths?: Record<string, string> | null,\n values?: Record<string, unknown> | null,\n): NormalizedNodes<N> {\n const substituted = resolveNamedTokens(nodes, tokens)\n const typedProps = new Map<string, ReusablePropValueClass>()\n for (const prop of declared ?? []) {\n if (!prop?.name) continue\n const valueClass = reusablePropValueClass(prop)\n if (valueClass !== 'text') typedProps.set(prop.name, valueClass)\n }\n if (!typedProps.size) return holdPropFedAddresses(nodes, substituted)\n const knownValue = (name: string) =>\n values ? { value: values[name] } : undefined\n let typed: NormalizedNodes<N> | undefined\n for (const [id, node] of Object.entries(nodes ?? {})) {\n const raw = node?.props as Record<string, unknown> | undefined\n if (!raw || typeof raw !== 'object') continue\n let props: Record<string, unknown> | undefined\n const own = () =>\n (props = props ?? {\n ...(substituted[id]?.props as Record<string, unknown> | undefined),\n })\n for (const [key, value] of Object.entries(raw)) {\n if (key === 'children') continue\n const name = matchComponentPropToken(value)\n const valueClass = name ? typedProps.get(name) : undefined\n if (!name || !valueClass) continue\n const next = own()\n const finished = typedBindingValue(\n valueClass,\n knownValue(name),\n next[key],\n )\n if (finished === undefined) delete next[key]\n else next[key] = finished\n if (valueClass !== 'icon') continue\n const pathKey = iconPathPropName(key)\n if (pathKey === key) continue\n const path = finished === undefined ? undefined : iconPaths?.[name]\n if (path) next[pathKey] = path\n else delete next[pathKey]\n }\n const nested =\n node?.componentId === REUSABLE_INSTANCE_COMPONENT_ID\n ? instancePropValues(raw)\n : undefined\n if (nested) {\n let forwarded: Record<string, unknown> | undefined\n for (const [key, value] of Object.entries(nested)) {\n const name = matchComponentPropToken(value)\n const valueClass = name ? typedProps.get(name) : undefined\n if (!name || !valueClass) continue\n forwarded = forwarded ?? {\n ...instancePropValues(own()),\n }\n const known = knownValue(name)\n const given = known ? known.value : forwarded[key]\n if (isNothingToGive(given)) {\n delete forwarded[key]\n continue\n }\n if (valueClass === 'icon') {\n const icon = readInstanceIconValue(given)\n const path = iconPaths?.[name]\n forwarded[key] = icon\n ? { ...icon, ...(path && !icon.iconPath ? { iconPath: path } : {}) }\n : undefined\n if (!forwarded[key]) delete forwarded[key]\n continue\n }\n forwarded[key] = typedBindingValue(valueClass, { value: given }, given)\n }\n if (forwarded) own()[REUSABLE_INSTANCE_PROP_VALUES_KEY] = forwarded\n }\n if (!props) continue\n typed = typed ?? { ...substituted }\n typed[id] = { ...substituted[id], props } as N\n }\n return holdPropFedAddresses(nodes, typed ?? substituted)\n}\n\n/** A `{{prop.*}}` token's opening, escaped for a pattern. */\nconst PROP_TOKEN_SOURCE = `\\\\{\\\\{\\\\s*${COMPONENT_PROP_TOKEN_PREFIX.replace(\n /[.*+?^${}()|[\\]\\\\]/g,\n '\\\\$&',\n)}`\n\n/** Where a `{{prop.*}}` token opens, anywhere inside a value. */\nconst PROP_TOKEN_OPENING = new RegExp(PROP_TOKEN_SOURCE)\n\n/**\n * The bindings that open a value and that a later compose stage resolves — a\n * host token, a site variable — but not a property token, which this stage\n * resolves or never will.\n */\nconst LATER_BINDINGS_OPENING = new RegExp(\n `^(?:\\\\{\\\\{(?!${PROP_TOKEN_SOURCE.slice('\\\\{\\\\{'.length)})[^{}]*\\\\}\\\\}\\\\s*)+`,\n)\n\n/**\n * Whether a property-fed value may stay in an address prop once the\n * substitution has made it.\n *\n * The address rule, with the site's own references admitted — a screen or\n * collection link, a media-library pick — since this is the site that resolves\n * them. One exception: a value that opens with a binding a later stage\n * resolves (`{{host.url}}/about`) has no scheme until then, so the binding is\n * left to supply one and what follows it is judged as though the binding came\n * to nothing — which is what an unknown host token does — so a scheme cannot\n * be smuggled in behind it.\n */\nfunction isRenderableAddress(prop: NodeUrlProp, value: unknown): boolean {\n if (typeof value !== 'string') return false\n const address = value.trim()\n if (isSafeNodeUrl(prop, address, { siteReferences: true })) return true\n const opening = LATER_BINDINGS_OPENING.exec(address)\n if (!opening) return false\n const rest = address.slice(opening[0].length)\n return (\n rest === '' ||\n isSafeNodeUrl(prop, rest, { siteReferences: true }) ||\n !hasUrlScheme(rest)\n )\n}\n\n/**\n * `resolved` with every `href` and `src` that a `{{prop.*}}` token fed held to\n * the address rule, and removed where it fails it (AGL-2933).\n *\n * A published node's own address is held to that rule when it is published,\n * and a property's default when its declaration is — but a property's value\n * is set by whichever page places the component, or screen inside the layout,\n * long after either, and this is where it becomes the prop an element spreads\n * onto the DOM. Canvas, Preview, detach and the tenant all arrive here, so a\n * `javascript:` or `data:` value set on a property reaches none of them.\n *\n * It judges the whole value the substitution made (see\n * {@link isRenderableAddress}), so a token behind a literal scheme\n * (`https://example.com/{{prop.path}}`) stays a path on that site, and two\n * values that spell a scheme between them are refused together. A value still\n * holding its property token — an undeclared name, or the component editor's\n * raw-token view — is no address either, and a linking element reads it as\n * none.\n *\n * Only the prop goes: a button with no address is still a button. `raw` is\n * the map before substitution, which is what says a token fed the value;\n * neither map is mutated.\n */\nfunction holdPropFedAddresses<N extends AglynNodeSchema>(\n raw: NormalizedNodes<N>,\n resolved: NormalizedNodes<N>,\n): NormalizedNodes<N> {\n let held: NormalizedNodes<N> | undefined\n for (const [id, node] of Object.entries(raw ?? {})) {\n const authored = node?.props as Record<string, unknown> | undefined\n if (!authored || typeof authored !== 'object') continue\n let props: Record<string, unknown> | undefined\n for (const key of NODE_URL_PROPS) {\n const source = authored[key]\n if (typeof source !== 'string' || !PROP_TOKEN_OPENING.test(source)) continue\n const current = (\n props ?? (resolved[id]?.props as Record<string, unknown> | undefined)\n )?.[key]\n if (current === undefined || isRenderableAddress(key, current)) continue\n props = props ?? {\n ...(resolved[id]?.props as Record<string, unknown> | undefined),\n }\n delete props[key]\n }\n if (!props) continue\n held = held ?? { ...resolved }\n held[id] = { ...resolved[id], props } as N\n }\n return held ?? resolved\n}\n\n/**\n * A definition's declared props resolved over a set of its nodes for one page,\n * then the parts that page hides pruned (AGL-1314) — the single sequence the\n * component graft, detach and a composed layout all run.\n *\n * `values` is the page's own map, and `rootId` the node the prune never\n * removes. Visibility directives are evaluated on the result, never before:\n * they read `{{prop.*}}` like everything else, so pruning ahead of\n * substitution would see a token instead of the value and hide whatever the\n * definition merely MENTIONED.\n */\nexport function applyDeclaredProps<N extends AglynNodeSchema = AglynNodeSchema>(\n nodes: NormalizedNodes<N>,\n declared: ReusableComponentProp[] | undefined | null,\n values: Readonly<Record<string, unknown>> | null | undefined,\n rootId: NodeId,\n): NormalizedNodes<N> {\n const resolved = resolveReusablePropValues(declared, values)\n return pruneHiddenNodes(\n resolveComponentPropTokens(\n nodes,\n declared,\n resolved.tokens,\n resolved.iconPaths,\n resolved.values,\n ),\n rootId,\n )\n}\n\n/**\n * Whether a node's props ask for it to be dropped (AGL-1314) — see\n * {@link NODE_HIDE_IF_PROP} and {@link NODE_HIDE_UNLESS_PROP}.\n *\n * Evaluated on SUBSTITUTED props, so callers must run this after the\n * declared-prop tokens have resolved; against a raw definition node every\n * directive is still a token and reads as \"no opinion\" by design, which is\n * what keeps the component editor showing the parts a page will hide.\n */\nexport function isNodeHiddenByDirective(props: unknown): boolean {\n if (!props || typeof props !== 'object' || Array.isArray(props)) return false\n const bag = props as Record<string, unknown>\n if (readYesNoValue(bag[NODE_HIDE_IF_PROP]) === true) return true\n return readYesNoValue(bag[NODE_HIDE_UNLESS_PROP]) === false\n}\n\nfunction hasVisibilityDirective(props: unknown): boolean {\n if (!props || typeof props !== 'object' || Array.isArray(props)) return false\n const bag = props as Record<string, unknown>\n return NODE_HIDE_IF_PROP in bag || NODE_HIDE_UNLESS_PROP in bag\n}\n\n/**\n * The node minus its visibility directives — they are compose-time\n * instructions, and `Leaf` spreads whatever survives onto the component,\n * so leaving them would put `hideif=\"…\"` on the DOM of every node that\n * declared one and stayed.\n */\nfunction withoutVisibilityDirectives<N extends AglynNodeSchema>(node: N): N {\n if (!hasVisibilityDirective(node?.props)) return node\n const props = { ...(node.props as Record<string, unknown>) }\n delete props[NODE_HIDE_IF_PROP]\n delete props[NODE_HIDE_UNLESS_PROP]\n return { ...node, props: props as N['props'] }\n}\n\n/**\n * Drops every node under `rootId` whose props ask to be hidden, along with\n * its whole subtree and its entry in its parent's child list, and strips\n * the directives off everything that survives (AGL-1314).\n *\n * Structural rather than a `display: none`: an instance can already hide a\n * leaf with a per-leaf style override (AGL-1332), but that still ships the\n * markup, still fetches the image, still leaves the grid column, and still\n * leaves the control in the tab order. \"This page has no mockup\" is a\n * statement about the tree, so it is made in the tree.\n *\n * `rootId` itself is never dropped. The graft below wires the instance\n * node's single child to the definition root by id, so a self-hiding root\n * would leave a dangling reference; a component that should not appear at\n * all is a decision for the page that placed it, not for the definition.\n *\n * Returns the input unchanged when no node carries a directive, so the\n * overwhelmingly common case costs one scan and allocates nothing.\n */\nexport function pruneHiddenNodes<N extends AglynNodeSchema = AglynNodeSchema>(\n nodes: NormalizedNodes<N>,\n rootId: NodeId,\n): NormalizedNodes<N> {\n if (!nodes) return nodes\n let sawDirective = false\n for (const node of Object.values(nodes)) {\n if (hasVisibilityDirective(node?.props)) {\n sawDirective = true\n break\n }\n }\n if (!sawDirective) return nodes\n\n const hidden = new Set<NodeId>()\n const seen = new Set<NodeId>()\n const walk = (id: NodeId) => {\n const node = nodes[id]\n // `seen` bounds the walk: a definition that referenced an ancestor\n // would otherwise recurse until the stack gave out.\n if (!node || seen.has(id)) return\n seen.add(id)\n const children = Array.isArray(node.nodes) ? (node.nodes as NodeId[]) : []\n for (const childId of children) {\n if (typeof childId !== 'string' || !nodes[childId]) continue\n if (isNodeHiddenByDirective(nodes[childId]?.props)) {\n hidden.add(childId)\n for (const descendant of collectDescendantIds(nodes, childId)) {\n hidden.add(descendant)\n }\n continue\n }\n walk(childId)\n }\n }\n walk(rootId)\n\n const next: NormalizedNodes<N> = {}\n for (const [id, node] of Object.entries(nodes)) {\n if (hidden.has(id)) continue\n const kept = withoutVisibilityDirectives(node as N)\n const children = Array.isArray(kept?.nodes) ? (kept.nodes as NodeId[]) : null\n const survivors =\n children && children.some((childId) => hidden.has(childId as NodeId))\n ? children.filter((childId) => !hidden.has(childId as NodeId))\n : null\n next[id] = survivors ? ({ ...kept, nodes: survivors } as N) : kept\n }\n return next\n}\n\n/**\n * Expands reusable-component instance nodes (componentId\n * {@link REUSABLE_INSTANCE_COMPONENT_ID}, `props.refId` → definition id) by\n * grafting the referenced definition's subtree under each instance:\n *\n * - Grafted node ids are namespaced per instance (`cmp__{instanceId}__…`).\n * - The instance node keeps its identity (selection/attributes target) and\n * gains the grafted root as its only child.\n * - Unresolvable refIds leave the instance untouched — a deleted definition\n * must never take a published screen down.\n * - Definitions may contain instances of other definitions; expansion\n * repeats up to {@link MAX_COMPONENT_DEPTH} passes, which also bounds\n * accidental self-reference.\n * - A definition's declared props (AGL-1247) resolve per instance as the\n * subtree is grafted: `{{prop.name}}` tokens take that instance's\n * override, falling back to the prop's default. This is what lets one\n * hero serve eleven pages instead of being copied onto each.\n * - A grafted node asking to be hidden ({@link NODE_HIDE_IF_PROP} /\n * {@link NODE_HIDE_UNLESS_PROP}, AGL-1314) is pruned with its subtree —\n * which is how one hero renders with a mockup on `/product` and without\n * one on `/press`.\n * - Inputs are never mutated.\n *\n * `morePlacements` adds further node kinds that stand for a stored tree — a\n * placed form is the second one ({@link PlacementKind}) — expanded in the same\n * passes as instances, so the two nest inside each other in either order.\n *\n * ⛔ **A placement is expanded only when its tree RESOLVES**, meaning the\n * document is in the map AND carries a `rootId` its `nodes` actually hold. An\n * unresolvable one is left exactly as authored. That is what makes the\n * child-replacing kind safe to introduce on a live site: a form bound to an\n * entity that has never been published still renders the fields drawn on the\n * page, and the graft can only ever swap a page's copy of a form for the\n * entity's own.\n */\nexport function composeReusableComponentNodes<\n N extends AglynNodeSchema = AglynNodeSchema,\n>(\n nodes: NormalizedNodes<N>,\n definitionsById:\n | Record<string, ReusableComponentTree<N> | undefined>\n | undefined,\n morePlacements?: readonly PlacementKind<N>[],\n): NormalizedNodes<N> {\n const placements: PlacementKind<N>[] = [\n {\n componentId: REUSABLE_INSTANCE_COMPONENT_ID,\n refProp: 'refId',\n definitionsById,\n },\n ...(morePlacements ?? []),\n ].filter((placement) => placement.definitionsById)\n if (!placements.length) return nodes\n\n /**\n * The kind and tree this node stands for, or `undefined` when it stands for\n * nothing resolvable.\n *\n * The `nodes[rootId]` check is the resolution rule stated once: a document\n * whose root is not among its own nodes has no design to graft, and wiring\n * the placement's only child to an id nothing holds would blank it on the\n * page while reading, downstream, as already expanded.\n */\n const resolvePlacement = (node: N | undefined) => {\n for (const placement of placements) {\n if (node?.componentId !== placement.componentId) continue\n const refId = (node.props as any)?.[placement.refProp]\n if (typeof refId !== 'string' || !refId) continue\n const definition = placement.definitionsById?.[refId]\n if (!definition?.rootId || !definition.nodes?.[definition.rootId]) continue\n return { placement, definition }\n }\n return undefined\n }\n\n /** Expanded by an earlier pass — its children already carry its prefix. */\n const alreadyGrafted = (id: NodeId, node: N) => {\n const childIds = Array.isArray(node.nodes) ? (node.nodes as NodeId[]) : []\n return childIds.some(\n (childId) =>\n typeof childId === 'string' && childId.startsWith(instancePrefix(id)),\n )\n }\n\n let composed: NormalizedNodes<N> = nodes\n\n /*\n * WHAT A RESOLVED FORM REPLACES, DROPPED BEFORE ANYTHING IS GRAFTED.\n *\n * Ahead of the passes rather than inside them so the drop is decided against\n * the authored tree alone. Inside a pass it would race the expansions\n * running beside it: an inline field that was itself a component instance\n * could be grafted in the same pass that discards it, and its grafted\n * subtree — keyed off ids this walk never sees — would survive its own\n * parent as unreachable nodes on a published page.\n */\n const doomed = new Set<NodeId>()\n const emptied: NodeId[] = []\n for (const [id, node] of Object.entries(nodes)) {\n if (!node || !resolvePlacement(node)?.placement.replacesAuthoredChildren) {\n continue\n }\n if (alreadyGrafted(id, node)) continue\n const descendants = collectDescendantIds(nodes, id)\n if (!descendants.size) continue\n for (const descendantId of descendants) doomed.add(descendantId)\n emptied.push(id)\n }\n if (doomed.size) {\n const pruned: NormalizedNodes<N> = {}\n for (const [id, node] of Object.entries(nodes)) {\n if (!doomed.has(id)) pruned[id] = node as N\n }\n for (const id of emptied) {\n // A replaced form nested in another replaced form's authored children is\n // gone with it, so there is nothing left here to empty.\n if (pruned[id]) pruned[id] = { ...pruned[id], nodes: [] }\n }\n composed = pruned\n }\n\n /**\n * Which definition each graft brought in, keyed by the id prefix its nodes\n * carry — the ancestry a node cannot expand into again.\n *\n * `alreadyGrafted` bounds an instance against ITSELF: once a node's children\n * carry its prefix, that node is done. It cannot see the other shape, where\n * a definition's own subtree contains a FRESH instance naming the same\n * definition. Each pass mints a new instance id, so that node looks new to\n * every check there was, and the graft ran again on its own output until\n * {@link MAX_COMPONENT_DEPTH} stopped it.\n *\n * A depth cap is the right backstop for a reusable component, where\n * self-reference is an authoring mistake. It is the wrong bound for a FORM:\n * `checkFormContract` REQUIRES a form design's tree to contain a `form` node\n * naming that same form, so a placed form does not merely risk grafting into\n * itself — it always does, to the cap, every render. Six nested `<form>`\n * elements is invalid HTML, so the server parser drops the inner ones and\n * the client tree then disagrees with the server tree, which is a hydration\n * failure on a public page.\n *\n * Keyed by prefix because the prefix chain IS the ancestry: a node grafted\n * inside instance X has an id beginning with X's prefix, and one nested two\n * deep begins with both. Testing `startsWith` against a definition already\n * open above therefore asks exactly the right question — \"is this the same\n * definition, inside its own expansion?\" — while leaving a genuinely\n * different form placed inside a form free to expand.\n */\n const graftedAncestry: Array<{ prefix: string; refId: string }> = []\n\n /**\n * The definition id a node points at, and the placement that claims it.\n *\n * Scoped to placements that REPLACE authored children. That is what a form\n * does and what a reusable-component instance does not, and the difference\n * is the whole reason this guard is narrow: for a component, a definition\n * naming itself is an authoring mistake whose documented behaviour is a\n * depth-bounded expansion, and collapsing it here would change a semantic\n * this fix has no business touching. For a placement that replaces children,\n * the instance and the definition's root denote the same thing.\n */\n const replacingRefOf = (\n node: N | undefined,\n ): { refId: string; placement: PlacementKind<N> } | null => {\n for (const placement of placements) {\n if (!placement.replacesAuthoredChildren) continue\n // `componentId` sits on the NODE and the ref on its props, matching\n // `resolvePlacement` exactly — a predicate that drifted from that one\n // would not fail loudly, it would simply never match and leave the guard\n // switched off.\n if (node?.componentId !== placement.componentId) continue\n const refId = (node.props as any)?.[placement.refProp]\n if (typeof refId === 'string' && refId) return { refId, placement }\n }\n return null\n }\n\n /** Just the id, for the two call sites that do not need the placement. */\n const refIdOf = (node: N | undefined): string | null =>\n replacingRefOf(node)?.refId ?? null\n\n /**\n * Is this node an instance of a definition already open above it?\n *\n * Left completely untouched when so — not pruned, not emptied. An unexpanded\n * form node renders its own authored children, which is the same thing an\n * unresolvable ref does, and matches the rule that a missing definition must\n * never take a published page down.\n */\n const withinOwnExpansion = (id: NodeId, node: N): boolean => {\n const refId = refIdOf(node)\n if (!refId) return false\n return graftedAncestry.some(\n (entry) => entry.refId === refId && id.startsWith(entry.prefix),\n )\n }\n\n for (let depth = 0; depth < MAX_COMPONENT_DEPTH; depth++) {\n const pending = Object.entries(composed).filter(\n ([id, node]) =>\n Boolean(resolvePlacement(node)) &&\n !alreadyGrafted(id, node) &&\n !withinOwnExpansion(id, node),\n )\n if (!pending.length) break\n\n const next: NormalizedNodes<N> = { ...composed }\n for (const [instanceId, instanceNode] of pending) {\n const definition = (\n resolvePlacement(instanceNode) as {\n definition: ReusableComponentTree<N>\n }\n ).definition\n const prefix = instancePrefix(instanceId)\n // Recorded BEFORE the subtree is written, so the nodes this graft is\n // about to produce are already inside its ancestry when the next pass\n // considers them.\n const grafting = refIdOf(instanceNode)\n if (grafting) graftedAncestry.push({ prefix, refId: grafting })\n const prefixId = (id: NodeId) => `${prefix}${id}`\n // Style overrides (AGL-1306 root, AGL-1332 per leaf): merged over\n // each definition node's own sx as this instance's copy is grafted —\n // per-instance scope exists only here, exactly like the declared-prop\n // substitution below. Merging into the graft (rather than a renderer\n // patch) is what gives canvas/Preview/tenant parity for free, and\n // reading the definition's CURRENT nodes each pass is why an override\n // can never pin the instance to an old component version.\n //\n // Per-leaf is not a nicety: a component's text leaves usually set\n // their OWN colour, so a root-level `color` never reaches them and an\n // instance given a white background renders white-on-white (AGL-1318).\n //\n // A placed form carries the same two layers (AGL-3285), so one page can\n // restyle a field's label without editing the form for every page.\n const styleOverrides = getInstanceStyleOverrides(\n instanceNode as { componentId?: string; styleOverrides?: unknown },\n )\n // Attribute overrides (AGL-1899) ride the same graft for the same\n // reason: this is the one point where per-instance scope exists, so\n // merging here is what makes canvas, Preview and tenant SSR agree\n // without any of them knowing an override happened.\n //\n // Applied to the props BEFORE `resolveNamedTokens` below, which is\n // what lets an override be written in `{{prop.*}}`/`{{var:id}}` and\n // still resolve, and what makes an override on a bound prop beat the\n // component's own binding — the more specific placement wins.\n const attrOverrides = getInstanceAttrOverrides(\n instanceNode as { componentId?: string; attrOverrides?: unknown },\n )\n\n const grafted: NormalizedNodes<N> = {}\n for (const [defId, defNode] of Object.entries(definition.nodes)) {\n if (!defNode) continue\n grafted[prefixId(defId)] = {\n ...defNode,\n $id: prefixId(defNode.$id ?? defId),\n parentId:\n defId === definition.rootId\n ? instanceId\n : defNode.parentId != null\n ? prefixId(defNode.parentId)\n : defNode.parentId,\n ...(Array.isArray(defNode.nodes) && {\n nodes: (defNode.nodes as NodeId[]).map((childId) =>\n typeof childId === 'string' ? prefixId(childId) : childId,\n ),\n }),\n ...((instanceSxPatch(\n defNode.sx,\n styleOverrides,\n defId,\n definition.rootId,\n ) ?? {}) as any),\n ...((instancePropsPatch(\n defNode.props,\n attrOverrides,\n defId,\n definition.rootId,\n ) ?? {}) as any),\n }\n }\n // Declared props (AGL-1247) substitute HERE, on this instance's copy\n // of the subtree — the only point in the pipeline where per-instance\n // scope exists, since after the merge every grafted node is just\n // another entry in one flat map.\n //\n // The value lands in a real string prop and compose runs graft →\n // repeatables → `resolveNodesBindings`, so a `{{var:id}}` typed into\n // an override still resolves downstream for free. A field bound to a\n // prop that is not text is finished by that prop's kind instead — see\n // `resolveComponentPropTokens` — and the parts this page hides are\n // pruned from the result (`applyDeclaredProps`).\n Object.assign(\n next,\n applyDeclaredProps(\n grafted,\n definition.props,\n instancePropValues(instanceNode.props),\n prefixId(definition.rootId),\n ),\n )\n /*\n * A definition whose ROOT names the definition itself is grafted\n * UNWRAPPED — its root's children attach to the instance, and the\n * duplicate root is dropped.\n *\n * Bounding the recursion above stops the runaway, but one graft of a\n * self-naming design still produces two of the same element nested: the\n * placed node, and the design's root inside it. For a form that is a\n * `<form>` inside a `<form>`, which is invalid HTML — the server parser\n * drops the inner one, the client keeps it, and the two trees disagree.\n * Six of them or two, the page still fails to hydrate.\n *\n * Unwrapping is not a special case bolted on for forms: the instance and\n * the definition's root denote THE SAME THING here, and rendering both\n * was always the duplicate. `checkFormContract` is what makes a form\n * design always take this shape, so for forms this branch is the normal\n * path rather than the exception.\n *\n * The instance keeps its own props: it is the node the page authored,\n * carrying the id everything else resolves against.\n */\n const graftedRootId = prefixId(definition.rootId)\n const definitionRoot = definition.nodes[definition.rootId] as N | undefined\n const rootNamesItself =\n Boolean(grafting) && refIdOf(definitionRoot) === grafting\n const graftedRoot = next[graftedRootId]\n if (rootNamesItself && graftedRoot) {\n const adopted = Array.isArray(graftedRoot.nodes)\n ? (graftedRoot.nodes as NodeId[])\n : []\n for (const childId of adopted) {\n if (next[childId]) {\n next[childId] = { ...next[childId], parentId: instanceId }\n }\n }\n delete next[graftedRootId]\n /*\n * The root's own override slices land on the instance, because the\n * instance IS the root here (AGL-3285). The grafted root carried them\n * and has just been dropped; without this a placed form's `root`\n * target would save and never render. Same precedence as the merge\n * branch below: the slice first, the placement's own `sx` over it.\n */\n const rootSx = styleOverrides[STYLE_OVERRIDES_ROOT_KEY]\n const rootAttrs = attrOverrides[STYLE_OVERRIDES_ROOT_KEY]\n const unwrappedSx = rootSx\n ? mergeNodeSx(rootSx, instanceNode.sx)\n : undefined\n next[instanceId] = {\n ...instanceNode,\n ...(unwrappedSx === undefined ? {} : { sx: unwrappedSx as N['sx'] }),\n ...(rootAttrs\n ? {\n props: {\n ...((instanceNode.props as object | undefined) ?? {}),\n ...rootAttrs,\n },\n }\n : {}),\n nodes: adopted,\n }\n } else if (graftedRoot) {\n /*\n * THE INSTANCE AND THE DEFINITION'S ROOT ARE ONE ELEMENT (AGL-2521).\n *\n * The graft used to keep both — the instance as a container with the\n * definition's root inside it — so every placement published a `div`\n * the author never drew. On `aglyn.com` that was four of them on the\n * home page, one per placement, each sitting between a landmark and\n * its parent and breaking any direct-child selector the layout wrote.\n *\n * So the root TAKES THE INSTANCE'S PLACE: same id, same parent, same\n * slot in the parent's child list. Its own grafted id disappears and\n * its children keep theirs, which is what leaves the `cmp__{instance}\n * __{defId}` scheme — and everything reading it, from per-leaf\n * overrides to {@link resolveInstanceLeafBinding} — untouched.\n *\n * Keeping the INSTANCE'S id rather than the root's is the half that\n * matters: interactions, animations and analytics are all keyed to the\n * node the page authored, and a swap to the prefixed id would silently\n * drop every one of them.\n *\n * What the instance contributed as an element comes with it. Its `sx`\n * merges OVER the root's, because a placement styling its component is\n * the more specific of the two. Its universal directives — hide,\n * animate — move across for the same reason: they were authored\n * against \"this placement\", which is now this element. What stays\n * behind is the bookkeeping that only ever addressed the wrapper:\n * `refId`, `name`, the declared-prop values and the override slices,\n * all of them already consumed by the graft above.\n */\n /*\n * Interactions come from BOTH nodes, root's first.\n *\n * They are keyed to the element by node id, and after the merge one\n * element answers to two authors: the component, which wrote the\n * choreography its internals rely on, and the placement, which wrote\n * whatever this page wants on top. Keeping only one side silently\n * drops the other's — and because the instance keeps its own id, the\n * side that would go missing is the page's, on the very node whose id\n * it is.\n *\n * Root's run first for the reason the host actions do in\n * `getClientAutomations`: the more general enrolls before the more\n * specific, which is the order a page is read in.\n *\n * `interactions` is declared on `NodeSchema`, one layer above the\n * `AglynNodeSchema` this function is generic over, so both are read\n * off the node rather than through the type.\n */\n const interactionsOf = (node: unknown): readonly unknown[] => {\n const value = (node as { interactions?: unknown })?.interactions\n return Array.isArray(value) ? value : []\n }\n const mergedInteractions = [\n ...interactionsOf(graftedRoot),\n ...interactionsOf(instanceNode),\n ]\n const carried: Record<string, unknown> = {}\n for (const key of INSTANCE_CARRIED_PROPS) {\n const value = (instanceNode.props as Record<string, unknown>)?.[key]\n if (value !== undefined) carried[key] = value\n }\n /*\n * A placement's repeat moves across too, and the element repeats\n * ITSELF (AGL-3111).\n *\n * It is the other universal directive authored against \"this\n * placement\": the page asked for one copy of the component per record.\n * After the merge that component is an element whose children are the\n * component's own, which would read as the item template, so the scope\n * is stated rather than left to the child list. The placement's repeat\n * replaces one on the component's root rather than mixing with it —\n * repeats do not nest, and a filter meant for the root's rows applied\n * to the placement's would be neither author's.\n */\n const repeatsPlacement = repeatKey(instanceNode) !== ''\n if (repeatsPlacement) {\n for (const key of REPEAT_DIRECTIVE_PROPS) {\n const value = (instanceNode.props as Record<string, unknown>)?.[key]\n if (value !== undefined) carried[key] = value\n }\n carried[REPEAT_SELF_PROP] = true\n }\n const rootProps = repeatsPlacement\n ? withoutRepeatDirective(graftedRoot).props\n : graftedRoot.props\n /*\n * Classes from BOTH nodes, the component root's first.\n *\n * A class names the element for the site's stylesheet and for the\n * runtime: ⋮ ▸ Start hidden writes `aglyn-hidden` into the placement's\n * `props.className`, and the show/hide steps toggle that class on the\n * element answering to the placement's id, which after the merge is\n * this one. Keeping either list alone drops the other author's names,\n * so the two are joined, each name once, in `props` and on the node.\n */\n const propsClassName = joinClassNames(\n (graftedRoot.props as Record<string, unknown> | undefined)?.[\n 'className'\n ],\n (instanceNode.props as Record<string, unknown> | undefined)?.[\n 'className'\n ],\n )\n if (propsClassName) carried['className'] = propsClassName\n const nodeClassName = joinClassNames(\n (graftedRoot as { className?: unknown }).className,\n (instanceNode as { className?: unknown }).className,\n )\n // The override slices and the reference are DOCUMENT state living on\n // the node beside `sx`, not props — the renderer never spreads them at\n // an element — so they ride along rather than being consumed and\n // dropped. A composed map that is saved back must still carry what the\n // author set on this placement (AGL-1306/AGL-1899), and a re-compose\n // is a no-op because the merged node no longer answers to\n // `reusableInstance`.\n const documentState: Record<string, unknown> = {}\n for (const key of INSTANCE_CARRIED_NODE_FIELDS) {\n const value = (instanceNode as Record<string, unknown>)[key]\n if (value !== undefined) documentState[key] = value\n }\n const mergedSx = mergeNodeSx(graftedRoot.sx, instanceNode.sx)\n const merged = {\n ...graftedRoot,\n $id: instanceId,\n parentId: instanceNode.parentId,\n ...documentState,\n ...(mergedSx === undefined ? {} : { sx: mergedSx as N['sx'] }),\n // Only when there is something to say: materializing an empty\n // `props` on a node that had none is a visible difference to\n // everything that asks whether a node was authored with any.\n ...(rootProps !== undefined || Object.keys(carried).length\n ? { props: { ...(rootProps as object), ...carried } }\n : {}),\n ...(nodeClassName ? { className: nodeClassName } : {}),\n // Absent rather than empty, like `props` above: a node the author\n // gave no choreography is one that carries no such key anywhere\n // else in the pipeline.\n ...(mergedInteractions.length\n ? { interactions: mergedInteractions }\n : {}),\n /*\n * The eye on the placement's hierarchy row hides the element the\n * placement became.\n *\n * Either author may hide it: the component, on its own root, which\n * arrives with the spread above, or the page, on the placement. Only\n * a hiding flag is carried, never a showing one: `false` and absent\n * mean the same thing on a node, so a placement whose eye was never\n * touched cannot bring back a root the component hid. Read off the\n * node for the reason `interactions` is: `hidden` is declared on\n * `NodeSchema`, above the type this function is generic over.\n */\n ...((instanceNode as { hidden?: unknown }).hidden\n ? { hidden: true }\n : {}),\n } as N\n for (const childId of Array.isArray(merged.nodes)\n ? (merged.nodes as NodeId[])\n : []) {\n if (next[childId]) {\n next[childId] = { ...next[childId], parentId: instanceId }\n }\n }\n delete next[graftedRootId]\n next[instanceId] = merged\n } else {\n /*\n * The root was pruned by its own visibility directive, so there is\n * nothing to take the instance's place. The instance stays as an empty\n * container rather than vanishing: its own hide directive has not been\n * evaluated yet, and removing a node the later passes still expect to\n * walk would strand its parent's child list.\n */\n next[instanceId] = {\n ...instanceNode,\n nodes: [],\n }\n }\n }\n composed = next\n }\n return composed\n}\n\n/**\n * Ids of every descendant of `rootId` reachable through `nodes` arrays —\n * the root itself excluded, unknown and repeated ids skipped, so a cycle\n * cannot hang the walk.\n *\n * Child lists are the only edges followed, never `parentId`. That is the\n * published renderer's own reach from the document root, which is why\n * `pageVideoObjects` asks this which Video nodes a page draws (AGL-2957).\n */\nexport function collectDescendantIds<N extends AglynNodeSchema>(\n nodes: NormalizedNodes<N>,\n rootId: NodeId,\n): Set<NodeId> {\n const found = new Set<NodeId>()\n const root = nodes?.[rootId]\n const queue: NodeId[] = Array.isArray(root?.nodes)\n ? [...(root.nodes as NodeId[])]\n : []\n while (queue.length) {\n const id = queue.shift() as NodeId\n if (found.has(id) || id === rootId || !nodes[id]) continue\n found.add(id)\n const children = nodes[id]?.nodes\n if (Array.isArray(children)) queue.push(...(children as NodeId[]))\n }\n return found\n}\n\n/**\n * Materializes the instance at `instanceId` into a plain, freely editable\n * copy of what it was RENDERING (AGL-1314) — what \"Detach from component\"\n * does, and the inverse of {@link replaceSubtreeWithInstance}.\n *\n * Deliberately here, beside the graft, because \"what the instance rendered\"\n * is a question only {@link composeReusableComponentNodes} can answer. The\n * console used to copy `definition.nodes` verbatim, which is the whole bug:\n * the definition's leaves hold `{{prop.headline}}` TOKENS, not text, so a\n * detached hero rendered its own markers and the author's copy was gone.\n * A second, simpler materializer will always drift from the renderer —\n * so this one runs the renderer's own steps:\n *\n * - Declared props (AGL-1247) resolve through {@link applyDeclaredProps},\n * exactly as the graft does: the instance's override, else the\n * definition's default. Every string prop is walked,\n * so an image's `src` bakes to the bound media for free — the token is\n * substituted by name, not by which prop happens to hold it.\n * - The style overrides (AGL-1306 root, AGL-1332 per leaf) merge over the\n * matching definition node's own sx, so the copy keeps the look the page\n * was showing rather than snapping back to the component's base styling.\n * Every node is patched, not just the root: an instance re-coloured to a\n * white band with black copy must detach as a white band with black copy.\n * - Ids are FRESH (`createId`), never the `cmp__…` graft namespace: a\n * detached copy is an ordinary subtree, and leaving graft ids behind\n * would collide the next time an instance of the same definition\n * expanded here. Only the root keeps the instance's id, so the parent's\n * child list, the undo stack and the selection all stay valid.\n * - Anything hanging under the instance (a pre-grafted layout-chrome\n * subtree, AGL-1218) is dropped with it; the copy replaces the whole\n * thing.\n *\n * A missing instance, a node that is not an instance, or a definition\n * without a resolvable root returns `nodes` UNCHANGED — detach must never\n * be the thing that empties a screen. Inputs are never mutated.\n */\nexport function detachInstanceSubtree<\n N extends AglynNodeSchema = AglynNodeSchema,\n>(\n nodes: NormalizedNodes<N>,\n instanceId: NodeId,\n definition:\n | Pick<ReusableComponentTree<N>, 'rootId' | 'nodes' | 'props'>\n | null\n | undefined,\n createId: () => NodeId,\n): NormalizedNodes<N> {\n const instanceNode = nodes?.[instanceId]\n if (instanceNode?.componentId !== REUSABLE_INSTANCE_COMPONENT_ID) {\n return nodes\n }\n const rootId = definition?.rootId\n if (!rootId || !definition?.nodes?.[rootId]) return nodes\n\n // Fresh ids for everything but the root, which inherits the instance's.\n // `createId` is injected so this stays pure (and specs stay readable);\n // the loop re-rolls rather than trusting uniqueness, because a collision\n // here would silently overwrite an unrelated node on the page.\n const taken = new Set<NodeId>(Object.keys(nodes))\n const idMap: Record<NodeId, NodeId> = { [rootId]: instanceId }\n for (const defId of Object.keys(definition.nodes)) {\n if (idMap[defId] != null) continue\n let fresh = createId()\n for (\n let attempt = 0;\n (!fresh || taken.has(fresh)) && attempt < 10;\n attempt++\n ) {\n fresh = createId()\n }\n taken.add(fresh)\n idMap[defId] = fresh\n }\n\n const styleOverrides = getInstanceStyleOverrides(\n instanceNode as { componentId?: string; styleOverrides?: unknown },\n )\n const attrOverrides = getInstanceAttrOverrides(\n instanceNode as { componentId?: string; attrOverrides?: unknown },\n )\n const copied: NormalizedNodes<N> = {}\n for (const [defId, defNode] of Object.entries(definition.nodes)) {\n if (!defNode) continue\n const newId = idMap[defId]\n copied[newId] = {\n ...defNode,\n $id: newId,\n parentId:\n defId === rootId\n ? (instanceNode.parentId ?? null)\n : defNode.parentId != null\n ? (idMap[defNode.parentId] ?? null)\n : (defNode.parentId ?? null),\n ...(Array.isArray(defNode.nodes) && {\n nodes: (defNode.nodes as NodeId[]).map((childId) =>\n typeof childId === 'string' ? (idMap[childId] ?? childId) : childId,\n ),\n }),\n // The SAME patch the graft applies, node for node (AGL-1332) — the\n // detached copy has to look identical to what the page was showing,\n // and a per-leaf override baked only at the root would repaint every\n // headline the moment an author detached.\n ...((instanceSxPatch(defNode.sx, styleOverrides, defId, rootId) ??\n {}) as any),\n // Attribute overrides bake in for the same reason (AGL-1899): a\n // detached copy that reverted to the component's own `variant` would\n // change under the author at the moment they asked for a fork.\n ...((instancePropsPatch(defNode.props, attrOverrides, defId, rootId) ??\n {}) as any),\n }\n }\n\n const doomed = collectDescendantIds(nodes, instanceId)\n const next: NormalizedNodes<N> = {}\n for (const [id, node] of Object.entries(nodes)) {\n if (id === instanceId || doomed.has(id)) continue\n next[id] = node as N\n }\n // Detach must materialize what the instance was RENDERING, so the parts\n // this page hid (AGL-1314) are absent from the copy too — a detached hero\n // that grew its mockup back is the same class of bug as one that rendered\n // `{{prop.headline}}`.\n return Object.assign(\n next,\n applyDeclaredProps(\n copied,\n definition.props,\n instancePropValues(instanceNode.props),\n instanceId,\n ),\n )\n}\n\n/**\n * The definition a subtree becomes when it is promoted (AGL-2908): the\n * element at `rootId` and everything under it, as a component document's own\n * `nodes` map.\n *\n * The other half of \"Save as reusable component\", beside\n * {@link replaceSubtreeWithInstance}: this one says what the new document\n * holds, that one says what the promoting document keeps. Both are here so\n * neither can drift from what the graft expects to read back.\n *\n * - The promoted root's `parentId` is dropped. In its old document it hung\n * from a section; in its own it IS the document, and a definition whose\n * root still points at a parent it no longer has grafts nothing.\n * - Editor-only fields go: `componentSchema` is the palette's own object and\n * `resolvedProps` is a render of the props beside them, so storing either\n * writes a snapshot of the editor into a document the renderer reads.\n * - Unknown `rootId` gives an empty map, and the input is never mutated.\n *\n * Child lists are the only edges followed, so an element the subtree does not\n * reach is not carried along even if it claims the root as its parent.\n */\nexport function reusableComponentDefinitionFrom<\n N extends AglynNodeSchema = AglynNodeSchema,\n>(nodes: NormalizedNodes<N>, rootId: NodeId): NormalizedNodes<N> {\n const root = nodes?.[rootId]\n if (!root) return {}\n const definition: NormalizedNodes<N> = {}\n for (const id of [rootId, ...collectDescendantIds(nodes, rootId)]) {\n const node = nodes[id]\n if (!node) continue\n const {\n componentSchema: _schema,\n resolvedProps: _resolved,\n ...stored\n } = node as N & { componentSchema?: unknown; resolvedProps?: unknown }\n definition[id] = (id === rootId ? { ...stored, parentId: null } : stored) as N\n }\n return definition\n}\n\n/**\n * Replaces the subtree rooted at `rootId` with an instance of `definitionId`\n * (AGL-1193) — what \"Save as reusable component\" does to the tree it was\n * promoted from.\n *\n * Without this the promoting document keeps an inline *copy*: the one place\n * guaranteed never to track the component it created, silently. Deliberately\n * in this file so the swap and {@link composeReusableComponentNodes} cannot\n * drift about what an instance node looks like.\n *\n * - The instance keeps the promoted root's `$id` and `parentId`, so the\n * parent's child list, the undo stack and the current selection all stay\n * valid — the mirror of the detach path, which reuses the instance id.\n * - Every descendant is dropped; its content now lives in the definition.\n * - `displayName` rides along as a prop purely so the editor placeholder can\n * name what it stands for (definitions are not grafted into the canvas).\n * - Unknown `rootId` is a no-op, and the input is never mutated.\n */\nexport function replaceSubtreeWithInstance<\n N extends AglynNodeSchema = AglynNodeSchema,\n>(\n nodes: NormalizedNodes<N>,\n rootId: NodeId,\n definitionId: string,\n displayName?: string,\n): NormalizedNodes<N> {\n const root = nodes?.[rootId]\n if (!root || !definitionId) return nodes\n\n // Descendants only — the root is replaced, not removed.\n const doomed = collectDescendantIds(nodes, rootId)\n\n const next: NormalizedNodes<N> = {}\n for (const [id, node] of Object.entries(nodes)) {\n if (!doomed.has(id)) next[id] = node as N\n }\n next[rootId] = {\n $id: rootId,\n parentId: root.parentId ?? null,\n componentId: REUSABLE_INSTANCE_COMPONENT_ID,\n pluginId: 'mui',\n props: {\n refId: definitionId,\n ...(displayName && { name: displayName }),\n },\n nodes: [],\n } as unknown as N\n return next\n}\n\n/**\n * The icon path an instance node should be drawn with (AGL-1193), or\n * `undefined` when the node is not an instance, its definition is unknown,\n * or that definition chose no icon — every one of which means \"fall back to\n * the component schema's own glyph\".\n *\n * The visual half of `getNodeLabelShort`: an instance stands for one\n * specific component, so a hierarchy of promoted sections drawn with one\n * repeated package glyph tells the author nothing. Unlike the label, the\n * icon is NOT denormalized onto the instance — it is read live off the\n * definition, so changing a component's icon updates every instance already\n * placed instead of only the ones inserted afterwards.\n *\n * Deliberately here rather than in the canvas manager: this file owns what\n * an instance node looks like, and a second reader that disagreed would draw\n * definition icons on nodes the graft does not treat as instances.\n *\n * Returns only the stored `iconPath`. Resolving `iconId` would need the\n * ~2.9 MB icon catalog, which render surfaces never load — and the lookup\n * that \"helpfully\" substitutes a default is what made every icon a \"help\"\n * glyph in AGL-1212.\n */\nexport function resolveInstanceIconPath(\n node:\n | { componentId?: string; props?: unknown }\n | undefined\n | null,\n definitionsById:\n | Record<string, { icon?: ReusableComponentIcon } | undefined>\n | undefined\n | null,\n): string | undefined {\n if (!node || !definitionsById) return undefined\n if (node.componentId !== REUSABLE_INSTANCE_COMPONENT_ID) return undefined\n const refId = (node.props as { refId?: unknown } | undefined)?.refId\n if (typeof refId !== 'string' || !refId) return undefined\n return definitionsById[refId]?.icon?.iconPath || undefined\n}\n\n/**\n * Whether a node map contains an instance of `definitionId` (AGL-703).\n *\n * The inverse of the graft above, and deliberately in the same file: a\n * \"Used by\" card that disagreed with {@link composeReusableComponentNodes}\n * about what counts as a reference would report \"used nowhere\" for\n * something the renderer does expand, which is an invitation to delete it.\n *\n * Scans ONLY direct instances. Callers wanting transitive usage must scan\n * definitions too — a definition may nest instances of other definitions,\n * so \"used by no screen\" does not mean \"used by nothing\".\n */\nexport function nodesReferenceComponent(\n nodes: Record<string, AglynNodeSchema | undefined> | undefined | null,\n definitionId: string,\n): boolean {\n if (!nodes || !definitionId) return false\n return Object.values(nodes).some(\n (node) =>\n node?.componentId === REUSABLE_INSTANCE_COMPONENT_ID &&\n (node.props as { refId?: unknown } | undefined)?.refId === definitionId,\n )\n}\n\n/**\n * Every definition id a node map renders, DIRECTLY or through another\n * definition (AGL-1898).\n *\n * {@link nodesReferenceComponent} answers the same question for one id and\n * scans direct instances only — its own doc says a caller wanting transitive\n * usage \"must scan definitions too\". This is that scan, kept beside the\n * graft for the same reason: a caller that disagreed with\n * {@link composeReusableComponentNodes} about what a document references\n * would be wrong about exactly the nested case the canvas draws.\n *\n * Why it exists here rather than at a call site. A screen's canvas re-grafts\n * when the host's definitions map changes, which is the whole of AGL-1898's\n * phase-2 transport — but that map changes whenever ANY component in the\n * host is published, most of them not on this page. Deciding whether a\n * change is this document's business needs the transitive set, because the\n * usual shared component is reached through a nav or a card rather than\n * placed on the screen itself.\n *\n * - Unresolvable ids are INCLUDED. A screen referencing a definition that is\n * unpublished, deleted, or simply not in the map yet still references it;\n * a caller filtering to \"what can expand\" can intersect with its own map,\n * whereas an id dropped here cannot be recovered.\n * - Cycles terminate: an id already collected is never re-walked, which\n * bounds a self-referencing definition the same way\n * {@link MAX_COMPONENT_DEPTH} bounds the graft.\n * - Traversal is over the definition's stored `nodes`, NOT a composed tree,\n * so it costs nothing and cannot be thrown off by grafted ids.\n */\nexport function collectReferencedComponentIds(\n nodes: Record<string, AglynNodeSchema | undefined> | undefined | null,\n definitionsById?:\n | Record<string, { nodes?: unknown } | undefined>\n | undefined\n | null,\n): Set<string> {\n const found = new Set<string>()\n const directRefIds = (\n source: Record<string, AglynNodeSchema | undefined> | undefined | null,\n ) => {\n const ids: string[] = []\n for (const node of Object.values(source ?? {})) {\n if (node?.componentId !== REUSABLE_INSTANCE_COMPONENT_ID) continue\n const refId = (node.props as { refId?: unknown } | undefined)?.refId\n if (typeof refId === 'string' && refId) ids.push(refId)\n }\n return ids\n }\n\n const queue = directRefIds(nodes)\n while (queue.length) {\n const refId = queue.shift() as string\n if (found.has(refId)) continue\n found.add(refId)\n const definition = definitionsById?.[refId]\n if (!definition?.nodes) continue\n queue.push(\n ...directRefIds(\n definition.nodes as Record<string, AglynNodeSchema | undefined>,\n ),\n )\n }\n return found\n}\n\nexport default composeReusableComponentNodes\n"],"names":["iconPathPropName","reusablePropValueClass","COMPONENT_NODE_ID_PREFIX","COMPONENT_PROP_TOKEN_PREFIX","INSTANCE_CARRIED_NODE_FIELDS","INSTANCE_CARRIED_PROPS","NODE_HIDE_IF_PROP","NODE_HIDE_UNLESS_PROP","REUSABLE_INSTANCE_COMPONENT_ID","REUSABLE_INSTANCE_PROP_VALUES_KEY","STYLE_OVERRIDES_ROOT_KEY","REPEAT_DIRECTIVE_PROPS","REPEAT_SELF_PROP","repeatKey","withoutRepeatDirective","FORM_COMPONENT_ID","FORM_ID_PROP","mergeNodeSx","hasUrlScheme","isSafeNodeUrl","NODE_URL_PROPS","readInstanceIconValue","readYesNoValue","resolveReusablePropValues","resolveNamedTokens","isStyleRecord","value","Array","isArray","Object","keys","length","joinClassNames","lists","names","filter","list","flatMap","split","Boolean","Set","join","undefined","isPlacedFormNode","node","componentId","formId","props","isDefinitionPlacement","placementDefinitionFor","sources","refId","definitions","design","formDesigns","rootId","nodes","getInstanceStyleOverrides","overrides","styleOverrides","clean","key","entries","getInstanceRootStyleOverride","instanceSxPatch","baseSx","defId","rootSlice","leafSlice","sx","ATTR_OVERRIDE_REFUSED_PROPS","PLACED_FORM_REFUSED_ATTR_PROPS","isAttrOverrideRefused","placement","prop","has","getInstanceAttrOverrides","attrOverrides","slice","propValue","instancePropsPatch","baseProps","listInstanceStyleTargets","definition","targets","seen","walk","id","depth","add","isRoot","push","componentInternalId","name","children","childId","MAX_COMPONENT_DEPTH","instancePrefix","instanceId","matchComponentPropToken","match","exec","resolveInstanceLeafBinding","graftedId","contentProp","defNode","prefix","rootInternalId","find","parentId","startsWith","raw","declared","some","boundProp","instancePropValues","instanceProps","values","getInstanceEffectivePropText","propName","tokens","isNothingToGive","ownValue","typedBindingValue","valueClass","known","substituted","numeric","Number","isFinite","iconId","resolveComponentPropTokens","iconPaths","typedProps","Map","set","size","holdPropFedAddresses","knownValue","typed","own","get","next","finished","pathKey","path","nested","forwarded","given","icon","iconPath","PROP_TOKEN_SOURCE","replace","PROP_TOKEN_OPENING","RegExp","LATER_BINDINGS_OPENING","isRenderableAddress","address","trim","siteReferences","opening","rest","resolved","held","authored","source","test","current","applyDeclaredProps","pruneHiddenNodes","isNodeHiddenByDirective","bag","hasVisibilityDirective","withoutVisibilityDirectives","sawDirective","hidden","descendant","collectDescendantIds","kept","survivors","composeReusableComponentNodes","definitionsById","morePlacements","placements","refProp","resolvePlacement","alreadyGrafted","childIds","composed","doomed","emptied","replacesAuthoredChildren","descendants","descendantId","pruned","graftedAncestry","replacingRefOf","refIdOf","withinOwnExpansion","entry","pending","instanceNode","grafting","prefixId","grafted","$id","map","assign","graftedRootId","definitionRoot","rootNamesItself","graftedRoot","adopted","rootSx","rootAttrs","unwrappedSx","interactionsOf","interactions","mergedInteractions","carried","repeatsPlacement","rootProps","propsClassName","nodeClassName","className","documentState","mergedSx","merged","found","root","queue","shift","detachInstanceSubtree","createId","taken","idMap","fresh","attempt","copied","newId","reusableComponentDefinitionFrom","componentSchema","_schema","resolvedProps","_resolved","stored","replaceSubtreeWithInstance","definitionId","displayName","pluginId","resolveInstanceIconPath","nodesReferenceComponent","collectReferencedComponentIds","directRefIds","ids"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/compose-reusable-components.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// By path: the naming rule alone, without the icon catalog's loader beside it.\nimport { iconPathPropName } from '@aglyn/shared-data-mdi/utils/icon-path-prop-name'\nimport type {\n AglynNodeSchema,\n NodeId,\n ReusableComponentIcon,\n ReusableComponentProp,\n} from '../foundation'\nimport {\n type ReusablePropValueClass,\n reusablePropValueClass,\n} from '../foundation/definitions/property-kinds'\nimport {\n COMPONENT_NODE_ID_PREFIX,\n COMPONENT_PROP_TOKEN_PREFIX,\n INSTANCE_CARRIED_NODE_FIELDS,\n INSTANCE_CARRIED_PROPS,\n NODE_HIDE_IF_PROP,\n NODE_HIDE_UNLESS_PROP,\n REUSABLE_INSTANCE_COMPONENT_ID,\n REUSABLE_INSTANCE_PROP_VALUES_KEY,\n STYLE_OVERRIDES_ROOT_KEY,\n} from './reusable-component-keys'\nimport {\n REPEAT_DIRECTIVE_PROPS,\n REPEAT_SELF_PROP,\n repeatKey,\n withoutRepeatDirective,\n} from './expand-repeatables'\nimport { FORM_COMPONENT_ID, FORM_ID_PROP } from './forms'\n\n/** The Form's after-submit reveal target: a node id (`form.tsx`). */\nconst FORM_REVEAL_NODE_PROP = 'revealNodeId'\nimport { mergeNodeSx } from './merge-node-sx'\nimport {\n hasUrlScheme,\n isSafeNodeUrl,\n NODE_URL_PROPS,\n type NodeUrlProp,\n} from './node-url-policy'\nimport {\n readInstanceIconValue,\n readYesNoValue,\n resolveReusablePropValues,\n} from './reusable-prop-values'\nimport { resolveNamedTokens } from './resolve-named-tokens'\n\nexport * from './reusable-component-keys'\nexport * from './reusable-prop-values'\n\nconst isStyleRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.keys(value).length > 0\n\n/**\n * Space-separated class lists joined in order, each name once, or `undefined`\n * when no list holds a name. A value that is not a string contributes nothing.\n */\nfunction joinClassNames(...lists: unknown[]): string | undefined {\n const names = lists\n .filter((list): list is string => typeof list === 'string')\n .flatMap((list) => list.split(/\\s+/))\n .filter(Boolean)\n return names.length ? [...new Set(names)].join(' ') : undefined\n}\n\n/**\n * A node's interactions, read off the node rather than through the type:\n * `interactions` is declared on `NodeSchema`, one layer above the\n * `AglynNodeSchema` the graft is generic over.\n */\nfunction interactionsOf(node: unknown): readonly unknown[] {\n const value = (node as { interactions?: unknown })?.interactions\n return Array.isArray(value) ? value : []\n}\n\n/**\n * Whether a placement says something about this prop. `undefined`, `null` and\n * `''` say nothing: the attributes panel writes an emptied field as absent\n * (AGL-1191), and a document saved before it did carries the empty string. A\n * `false` or a `0` is a real setting and is kept.\n */\nfunction isSetOnPlacement(value: unknown): boolean {\n return value !== undefined && value !== null && value !== ''\n}\n\n/**\n * The props a placement whose design root names the design itself (a placed\n * form) renders with, or `undefined` when neither side has any (AGL-3494).\n *\n * The design root's own props are the base — the saved form's submit label,\n * success message and settings, edited once for every page. The placement's\n * own props go over them ONE PROP AT A TIME, and only the ones it actually\n * sets ({@link isSetOnPlacement}), so a page that left the label alone shows\n * the form's, and a page that wrote one keeps it. The placement's `root`\n * attribute slice (AGL-3285), already merged into `rootProps` by the graft, is\n * laid over last so it beats the placement's own props, as it always has.\n *\n * Classes are joined rather than replaced, the design root's first, for the\n * reason the instance merge joins them: the show/hide steps toggle a class on\n * the element, and either author may have named one.\n *\n * Exported for the spec that pins the merge; the graft is its only caller.\n */\nexport function placementPropsOverRoot(\n rootProps: unknown,\n placementProps: unknown,\n rootAttrs?: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n const base = (rootProps as Record<string, unknown> | undefined) ?? undefined\n const own = (placementProps as Record<string, unknown> | undefined) ?? {}\n if (base === undefined && placementProps === undefined && !rootAttrs) {\n return undefined\n }\n const merged: Record<string, unknown> = { ...(base ?? {}) }\n for (const [key, value] of Object.entries(own)) {\n // A placement's empty value never masks the form's — but where the form\n // says nothing either, the placement's own shape is kept as it was.\n if (isSetOnPlacement(value) || !(key in merged)) merged[key] = value\n }\n const className = joinClassNames(base?.['className'], own['className'])\n if (className) merged['className'] = className\n if (rootAttrs) Object.assign(merged, rootAttrs)\n return merged\n}\n\n/**\n * The design root's props with an after-submit reveal target that names one of\n * the design's own nodes pointed at that node's grafted id (AGL-3494).\n *\n * A form's own besigner can only pick a reveal target from the form's design,\n * so the stored id is a design id, and every design node is renamed by the\n * graft (`cmp__{instance}__{id}`). Left as stored, the reveal would look for an\n * element no page has. The root itself is unwrapped onto the placement, so a\n * reveal of the root names the placement's id.\n */\nfunction revealTargetInPlacement(\n rootProps: unknown,\n definition: { rootId: NodeId; nodes: Record<NodeId, unknown> },\n prefixId: (id: NodeId) => string,\n instanceId: NodeId,\n): unknown {\n const props = rootProps as Record<string, unknown> | undefined\n const target = props?.[FORM_REVEAL_NODE_PROP]\n if (typeof target !== 'string' || !definition.nodes[target]) return rootProps\n return {\n ...props,\n [FORM_REVEAL_NODE_PROP]:\n target === definition.rootId ? instanceId : prefixId(target),\n }\n}\n\n/**\n * Whether a node is a placed form that names a form entity — the second kind\n * of node that stands for a tree stored on another document (see\n * {@link PlacementKind}). A `form` node with no `formId` is an ordinary form\n * whose fields are its own children, and has no override layer.\n *\n * The ref test matches the graft's own resolution rule (a non-empty string),\n * so the editor and the renderer agree about which forms are placements.\n */\nexport function isPlacedFormNode(\n node: { componentId?: string; props?: unknown } | undefined | null,\n): boolean {\n if (node?.componentId !== FORM_COMPONENT_ID) return false\n const formId = (node.props as Record<string, unknown> | undefined)?.[\n FORM_ID_PROP\n ]\n return typeof formId === 'string' && formId !== ''\n}\n\n/**\n * Whether a node is a placement that GRAFTS a definition — a reusable\n * component instance or a placed form — and therefore carries the two\n * per-placement override layers (`styleOverrides`, `attrOverrides`, AGL-3285).\n *\n * One predicate for both kinds on purpose: the graft already expands them in\n * one pass, and an override layer that one kind honoured and the other\n * silently ignored would be the canvas/Preview/tenant disagreement this file\n * exists to prevent.\n */\nexport function isDefinitionPlacement(\n node: { componentId?: string; props?: unknown } | undefined | null,\n): boolean {\n return (\n node?.componentId === REUSABLE_INSTANCE_COMPONENT_ID ||\n isPlacedFormNode(node)\n )\n}\n\n/**\n * The tree a placement grafts, from whichever map its kind reads — the\n * component definitions for an instance, the published form designs for a\n * placed form — or `undefined` when it is not a placement or its ref resolves\n * to nothing (AGL-3285). The editor panels use it to offer the same targets\n * the graft will consult.\n */\nexport function placementDefinitionFor<\n N extends AglynNodeSchema = AglynNodeSchema,\n>(\n node: { componentId?: string; props?: unknown } | undefined | null,\n sources: {\n definitions?: Record<string, ReusableComponentTree<N> | undefined>\n formDesigns?: Record<\n string,\n Pick<ReusableComponentTree<N>, 'rootId' | 'nodes'> | undefined\n >\n },\n): Pick<ReusableComponentTree<N>, 'rootId' | 'nodes'> | undefined {\n const props = node?.props as Record<string, unknown> | undefined\n if (node?.componentId === REUSABLE_INSTANCE_COMPONENT_ID) {\n const refId = props?.['refId']\n return typeof refId === 'string' && refId\n ? sources.definitions?.[refId]\n : undefined\n }\n if (isPlacedFormNode(node)) {\n const design = sources.formDesigns?.[props?.[FORM_ID_PROP] as string]\n // The graft's resolution rule: a design whose root is not among its own\n // nodes grafts nothing, so it offers nothing to override either.\n return design?.rootId && design.nodes?.[design.rootId] ? design : undefined\n }\n return undefined\n}\n\n/**\n * Every per-instance style override an instance node carries, keyed the way\n * it is stored (AGL-1332): {@link STYLE_OVERRIDES_ROOT_KEY} for the\n * component root, and a DEFINITION-internal node id for each overridden\n * leaf. Empty for a node that is not a placement ({@link\n * isDefinitionPlacement}: an instance or a placed form) or carries none.\n *\n * Keyed on the definition's own id, never the grafted `cmp__…` id: the\n * graft id is DERIVED from the instance id, so keying on it would break the\n * moment a subtree was duplicated or an instance re-keyed, and two\n * instances of one component could not share the same authoring vocabulary.\n * Entries that are not a non-empty plain object are dropped here rather\n * than at each call site — a `null`, a string, or a cleared `{}` must read\n * as \"no override\" identically in the graft, in detach and in the panel.\n *\n * Deliberately here rather than in a render surface: this file owns what\n * an instance node looks like, and the graft below is the ONE place the\n * overrides are applied — canvas, Preview and tenant SSR all call\n * {@link composeReusableComponentNodes}, so they cannot disagree about\n * what an override means.\n */\nexport function getInstanceStyleOverrides(\n node:\n | { componentId?: string; props?: unknown; styleOverrides?: unknown }\n | undefined\n | null,\n): Record<string, Record<string, unknown>> {\n if (!isDefinitionPlacement(node)) return {}\n const overrides = node?.styleOverrides as Record<string, unknown> | undefined\n if (!isStyleRecord(overrides)) return {}\n const clean: Record<string, Record<string, unknown>> = {}\n for (const [key, value] of Object.entries(overrides)) {\n if (key && isStyleRecord(value)) clean[key] = value\n }\n return clean\n}\n\n/**\n * The sx-shaped ROOT style override carried by an instance node, or\n * `undefined` when the node is not an instance or carries none — the\n * AGL-1306 half of {@link getInstanceStyleOverrides}.\n */\nexport function getInstanceRootStyleOverride(\n node:\n | { componentId?: string; props?: unknown; styleOverrides?: unknown }\n | undefined\n | null,\n): Record<string, unknown> | undefined {\n return getInstanceStyleOverrides(node)[STYLE_OVERRIDES_ROOT_KEY]\n}\n\n/**\n * The `{ sx }` patch one definition node takes from an instance's\n * overrides, or `undefined` when none applies (AGL-1332).\n *\n * Two layers, coarse first: the root slice when this node IS the\n * definition root, then the node's own definition-id slice. Both go\n * through `mergeNodeSx`, so a per-leaf override gets exactly the cascade\n * semantics the root one already had — a `{ md: … }` slice keeps the\n * base's narrower widths, an `@scheme dark` slice merges key-by-key, and\n * a plain property replaces only the leaf it names.\n *\n * A key naming a node the definition no longer has is simply never\n * consulted: this runs per definition node, so a component edited after\n * the override was written degrades to the component's own styling rather\n * than throwing on a page nobody has opened since.\n *\n * Returned as a patch object rather than a value so the caller can spread\n * nothing at all — writing `sx: undefined` onto a node that never had one\n * would materialize the key on every grafted leaf.\n */\nfunction instanceSxPatch(\n baseSx: unknown,\n overrides: Record<string, Record<string, unknown>>,\n defId: NodeId,\n rootId: NodeId | undefined,\n): { sx: unknown } | undefined {\n // The root is addressed by the constant, so a definition node whose id\n // merely happens to BE `root` without being the root gets nothing from\n // the root slice — the alternative is styling an arbitrary leaf from the\n // panel's root target.\n const rootSlice =\n defId === rootId ? overrides[STYLE_OVERRIDES_ROOT_KEY] : undefined\n const leafSlice =\n defId === STYLE_OVERRIDES_ROOT_KEY ? undefined : overrides[defId]\n if (!rootSlice && !leafSlice) return undefined\n let sx = baseSx\n if (rootSlice) sx = mergeNodeSx(sx, rootSlice)\n if (leafSlice) sx = mergeNodeSx(sx, leafSlice)\n return { sx }\n}\n\n/**\n * Props on a grafted definition node that an instance override must never\n * address (AGL-1899).\n *\n * `sx` has its own override layer one field up, and honouring it here would\n * leave two writers racing for one rendered value with no rule to say which\n * wins — the Styles panel would show an instance as clean while the\n * Attributes panel silently repainted it.\n */\nconst ATTR_OVERRIDE_REFUSED_PROPS = new Set(['sx'])\n\n/**\n * Props a placed form's attribute overrides must never address, on any node\n * of its design (AGL-3285).\n *\n * A form is edited once and every page placing it follows — that is the\n * whole point of the form entity. Its submission list, its dataset columns,\n * its consent tick and its routing are all keyed to what the ENTITY declares,\n * so a page that renamed a field, retyped it, made it optional, rewrote its\n * choices or re-pointed where the form sends would file answers the form's\n * own schema does not describe, from one page only, with nothing on the\n * Forms page saying so. Per page, a form may LOOK different; it may not\n * collect something different.\n *\n * - The form node's identity and submission config: `formId`, `formName`,\n * `datasetId`, `datasetName`, and the after-submit outcome\n * (`afterSubmit`, `redirectScreenId`, `redirectUrl`, `revealNodeId`).\n * - Each field's contract: `fieldName` (the submission key),\n * `datasetFieldId`, `fieldType`, `options` (a ticked option's TEXT is the\n * posted value, and the consent check reads it) and `required`.\n * - Element attributes a browser submission reads directly: `name`, `type`\n * (a submit button made a plain button no longer submits), `value`,\n * `action`, `method`, and `disabled` (a disabled input is not posted).\n * - The hide directives: a hidden field is pruned from the page, so its\n * value is never sent.\n *\n * Label, placeholder, help text, the submit label and success message, and\n * everything about styling stay overridable.\n */\nexport const PLACED_FORM_REFUSED_ATTR_PROPS: ReadonlySet<string> = new Set([\n FORM_ID_PROP,\n 'formName',\n 'datasetId',\n 'datasetName',\n 'afterSubmit',\n 'redirectScreenId',\n 'redirectUrl',\n 'revealNodeId',\n 'fieldName',\n 'datasetFieldId',\n 'fieldType',\n 'options',\n 'required',\n 'name',\n 'type',\n 'value',\n 'action',\n 'method',\n 'disabled',\n NODE_HIDE_IF_PROP,\n NODE_HIDE_UNLESS_PROP,\n])\n\n/**\n * Whether `prop` may never be an attribute override on this placement — `sx`\n * on every placement, plus {@link PLACED_FORM_REFUSED_ATTR_PROPS} on a placed\n * form. The render layer and the editor's writer both ask this, so a refused\n * prop can neither be offered nor take effect.\n */\nexport function isAttrOverrideRefused(\n placement: { componentId?: string; props?: unknown } | undefined | null,\n prop: string,\n): boolean {\n if (ATTR_OVERRIDE_REFUSED_PROPS.has(prop)) return true\n return isPlacedFormNode(placement) && PLACED_FORM_REFUSED_ATTR_PROPS.has(prop)\n}\n\n/**\n * Every per-instance ATTRIBUTE override an instance node carries, keyed the\n * way {@link getInstanceStyleOverrides} keys styles — `root` for the\n * definition root, a definition-internal node id for anything else\n * (AGL-1899).\n *\n * Refused props are dropped HERE rather than at the write site, so a slice\n * that reached storage before a refusal existed (or by any path that did not\n * go through the panel) still cannot take effect.\n */\nexport function getInstanceAttrOverrides(\n node:\n | { componentId?: string; props?: unknown; attrOverrides?: unknown }\n | undefined\n | null,\n): Record<string, Record<string, unknown>> {\n if (!isDefinitionPlacement(node)) return {}\n const overrides = node?.attrOverrides as Record<string, unknown> | undefined\n if (!isStyleRecord(overrides)) return {}\n const clean: Record<string, Record<string, unknown>> = {}\n for (const [key, value] of Object.entries(overrides)) {\n if (!key || !isStyleRecord(value)) continue\n const slice: Record<string, unknown> = {}\n for (const [prop, propValue] of Object.entries(value)) {\n if (isAttrOverrideRefused(node, prop)) continue\n slice[prop] = propValue\n }\n if (Object.keys(slice).length > 0) clean[key] = slice\n }\n return clean\n}\n\n/**\n * The `{ props }` patch one definition node takes from an instance's\n * attribute overrides, or `undefined` when none applies (AGL-1899).\n *\n * Layered coarse-first exactly like {@link instanceSxPatch} — the root slice\n * when this node IS the definition root, then the node's own id slice — so\n * the two override kinds stay one authoring model rather than two.\n *\n * The merge is one level deep, replacing only the props each slice NAMES.\n * That keeps a component free to add a prop later and still have every\n * existing instance pick up the new default, and it is deliberately not the\n * cascade `mergeNodeSx` performs: an sx object's nested records are\n * selectors (`@scheme dark`, breakpoints) that genuinely compose, while a\n * prop value is one value. Deep-merging two prop objects that merely look\n * alike would hand the renderer a third thing neither the component nor the\n * page asked for.\n */\nfunction instancePropsPatch(\n baseProps: unknown,\n overrides: Record<string, Record<string, unknown>>,\n defId: NodeId,\n rootId: NodeId | undefined,\n): { props: Record<string, unknown> } | undefined {\n const rootSlice =\n defId === rootId ? overrides[STYLE_OVERRIDES_ROOT_KEY] : undefined\n const leafSlice =\n defId === STYLE_OVERRIDES_ROOT_KEY ? undefined : overrides[defId]\n if (!rootSlice && !leafSlice) return undefined\n return {\n props: {\n ...((baseProps as Record<string, unknown> | undefined) ?? {}),\n ...(rootSlice ?? {}),\n ...(leafSlice ?? {}),\n },\n }\n}\n\n/** One styleable target inside an instance — see {@link listInstanceStyleTargets}. */\nexport interface InstanceStyleTarget {\n /** The `styleOverrides` key this target reads and writes. */\n key: string\n /** The definition-internal node id it styles. */\n componentInternalId: NodeId\n /** 0 for the component root, +1 per level down — the picker indents by it. */\n depth: number\n /** The definition node's `componentId`, so a picker can label it. */\n componentId?: string\n /** The definition node's own `name`, when the component author set one. */\n name?: string\n /** True for the component root (the AGL-1306 target). */\n isRoot: boolean\n}\n\n/**\n * The styleable targets inside one component definition, in tree order\n * (root first, then depth-first through each node's `nodes`) — what the\n * Styles panel offers when a component instance is selected (AGL-1332).\n *\n * Beside the graft on purpose: the panel must write the SAME keys the\n * graft reads, and a second walker that disagreed would offer authors\n * targets no renderer consults. Cycle-safe and unreachable-safe: a node\n * the root cannot reach is not offered, because the graft would never\n * render it either.\n */\nexport function listInstanceStyleTargets(\n definition:\n | Pick<ReusableComponentTree<any>, 'rootId' | 'nodes'>\n | null\n | undefined,\n): InstanceStyleTarget[] {\n const rootId = definition?.rootId\n const nodes = definition?.nodes\n if (!rootId || !nodes?.[rootId]) return []\n const targets: InstanceStyleTarget[] = []\n const seen = new Set<NodeId>()\n const walk = (id: NodeId, depth: number) => {\n const node = nodes[id]\n // `seen` is what bounds the walk: a definition that referenced an\n // ancestor would otherwise recurse until the stack gave out.\n if (!node || seen.has(id)) return\n seen.add(id)\n const isRoot = id === rootId\n targets.push({\n key: isRoot ? STYLE_OVERRIDES_ROOT_KEY : id,\n componentInternalId: id,\n depth,\n componentId: (node as { componentId?: string }).componentId,\n name: (node as { name?: string }).name,\n isRoot,\n })\n const children = (node as { nodes?: unknown }).nodes\n if (!Array.isArray(children)) return\n for (const childId of children as NodeId[]) {\n if (typeof childId === 'string') walk(childId, depth + 1)\n }\n }\n walk(rootId, 0)\n return targets\n}\n\n/**\n * Definitions may nest instances of other definitions; expansion runs in\n * passes capped here so a self-referencing definition can't recurse forever.\n *\n * Exported for the one reader that has to agree with it: a loader fetching\n * only the definitions a document references (`load-referenced-components`)\n * follows nesting exactly this deep, so it never reads a level the graft\n * would not expand, and never stops short of one it would.\n */\nexport const MAX_COMPONENT_DEPTH = 5\n\ntype NormalizedNodes<N extends AglynNodeSchema> = Record<NodeId, N>\n\n/** Stored shape of a host-level reusable component definition's tree. */\nexport interface ReusableComponentTree<\n N extends AglynNodeSchema = AglynNodeSchema,\n> {\n rootId: NodeId\n nodes: NormalizedNodes<N>\n /** Props this definition declares (AGL-1247); absent = unparameterised. */\n props?: ReusableComponentProp[]\n /**\n * The definition's chosen icon (AGL-1193), carried so every editor surface\n * that draws an instance can reach it without a second read. Nothing in\n * the graft below touches it — an instance's icon is editor chrome, and\n * the published page renders the definition's own nodes.\n */\n icon?: ReusableComponentIcon\n}\n\nfunction instancePrefix(instanceId: NodeId) {\n return `${COMPONENT_NODE_ID_PREFIX}${instanceId}__`\n}\n\n/**\n * One kind of node that STANDS FOR a tree stored on another document, and\n * where that tree comes from.\n *\n * A reusable-component instance was the first such node; a placed form is the\n * second (`componentId: 'form'`, `props.formId` → `hosts/{hostId}/forms/{id}`,\n * whose published `rootId`/`nodes` are the fields the page renders). They are\n * one mechanism described twice, so they run through one expansion rather than\n * two passes that would have to agree about id namespacing, depth bounding and\n * cycle safety — and, more sharply, could not see each other: a form placed\n * inside a shared component only exists after the component graft, and a\n * reusable instance inside a form design only exists after the form graft.\n * Passing both kinds to {@link composeReusableComponentNodes} expands each\n * against the other, in either nesting order, within the same depth bound.\n */\nexport interface PlacementKind<N extends AglynNodeSchema = AglynNodeSchema> {\n /** The `componentId` a node must carry to be expanded by this kind. */\n componentId: string\n /** The prop naming the document whose tree is grafted. */\n refProp: string\n /** Resolvable trees, keyed by the id `refProp` holds. */\n definitionsById:\n | Record<string, ReusableComponentTree<N> | undefined>\n | undefined\n /**\n * Whether a resolved graft DISCARDS what the placement node already held.\n *\n * Off for reusable instances, which never hold anything: the editor refuses\n * a drop into them (`flags.dropping: DISABLED`), so replacing the child list\n * with the grafted root is the whole of what the graft has to do.\n *\n * On for placed forms, which do — a form node accepts fields, and every form\n * on the site was built that way before the form entity existed. Those\n * inline fields are the node's OWN content, so they cannot merely be\n * unlinked: left in the map they would still be walked by every later\n * compose stage, still ship in the page payload, and still answer to any\n * scan that reads `formField` nodes out of a flat map. The subtree is\n * dropped with the child list, exactly as `detachInstanceSubtree` drops what\n * it replaces.\n *\n * ⚠️ This is the one thing here that can take content off a page that\n * renders today, so it is deliberately gated on the graft RESOLVING: a\n * placement whose document is missing, unpublished, or holds no design is\n * left untouched, inline children and all. See\n * {@link composeReusableComponentNodes}.\n */\n replacesAuthoredChildren?: boolean\n}\n\n/**\n * The declared-prop name a stored value references when it is EXACTLY one\n * `{{prop.<name>}}` token (whitespace inside the braces tolerated, matching\n * `resolveNamedTokens`' grammar), else `null`.\n *\n * Exact-match on purpose: a value that merely CONTAINS a token\n * (`\"Hi {{prop.name}}!\"`) is only partially prop-fed, so an inline edit of\n * the rendered text could not be decomposed back into a prop value — those\n * leaves stay component-owned (AGL-1304).\n */\nexport function matchComponentPropToken(value: unknown): string | null {\n if (typeof value !== 'string') return null\n const match =\n /^\\s*\\{\\{\\s*prop\\.([A-Za-z_][A-Za-z0-9_]*)\\s*\\}\\}\\s*$/.exec(value)\n return match ? match[1] : null\n}\n\n/** What feeds a grafted instance leaf — see {@link resolveInstanceLeafBinding}. */\nexport interface InstanceLeafBinding {\n /** The definition-internal node id the grafted leaf was copied from. */\n componentInternalId: NodeId\n /**\n * The declared prop whose value feeds the leaf's `contentProp`, or `null`\n * when the leaf's content is the component's own (not prop-fed).\n */\n boundProp: string | null\n}\n\n/**\n * Maps a grafted node id back to its component-internal source and the\n * declared prop (if any) feeding one of its content props (AGL-1304).\n *\n * The graft's provenance is its id scheme — `cmp__{instanceId}__{defId}`\n * (see {@link composeReusableComponentNodes}) — and this is the ONE reader\n * of that scheme, deliberately beside the writer: the canvas double-click\n * hit-test uses it today, and AGL-1306 phase 2 (inner-node style overrides)\n * and AGL-1303 phase 3 (in-place focus mode) need the same inverse mapping.\n *\n * Returns `null` when the id was not grafted from THIS instance, or when\n * the internal id is unknown to the definition — which includes leaves of a\n * NESTED instance's graft (prefixes stack per pass), whose props are fed by\n * the outer definition's own instance node, not by this one.\n *\n * `boundProp` is non-null only when the definition node's `contentProp`\n * (default `children`; pass `src` for image leaves) is exactly one\n * `{{prop.*}}` token naming a DECLARED prop — an undeclared token never\n * substitutes, so an override written for it would silently do nothing.\n *\n * Pure: no canvas, no DOM, inputs never mutated.\n */\nexport function resolveInstanceLeafBinding(\n graftedId: NodeId | null | undefined,\n instanceId: NodeId | null | undefined,\n definition:\n | Pick<ReusableComponentTree, 'nodes' | 'props'>\n | null\n | undefined,\n contentProp = 'children',\n rootId?: NodeId | null,\n): InstanceLeafBinding | null {\n if (!graftedId || !instanceId) return null\n const prefix = instancePrefix(instanceId)\n // The definition's ROOT carries the instance's own id, not a prefixed one\n // — the two are one element (AGL-2521). Without this the root is the one\n // leaf the double-click cannot reach, so a component whose root IS its text\n // stops being inline-editable through its placements.\n if (graftedId === instanceId) {\n const rootInternalId =\n rootId ??\n Object.keys(definition?.nodes ?? {}).find(\n (id) => !(definition?.nodes as Record<string, { parentId?: unknown }>)?.[id]?.parentId,\n )\n if (!rootInternalId) return null\n return resolveInstanceLeafBinding(\n `${prefix}${rootInternalId}`,\n instanceId,\n definition,\n contentProp,\n )\n }\n if (!graftedId.startsWith(prefix)) return null\n const componentInternalId = graftedId.slice(prefix.length)\n if (!componentInternalId) return null\n const defNode = definition?.nodes?.[componentInternalId]\n if (!defNode) return null\n const raw = (defNode.props as Record<string, unknown> | undefined)?.[\n contentProp\n ]\n const name = matchComponentPropToken(raw)\n const declared =\n name != null && (definition?.props ?? []).some((prop) => prop?.name === name)\n return { componentInternalId, boundProp: declared ? name : null }\n}\n\n/** An instance's own values, keyed by declared prop name (AGL-1247). */\nfunction instancePropValues(\n instanceProps: unknown,\n): Record<string, unknown> | undefined {\n const values = (instanceProps as Record<string, unknown> | undefined)?.[\n REUSABLE_INSTANCE_PROP_VALUES_KEY\n ]\n return values && typeof values === 'object' && !Array.isArray(values)\n ? (values as Record<string, unknown>)\n : undefined\n}\n\n/**\n * The text an instance currently renders for a declared prop: its override\n * when set, else the prop's `defaultValue`, else `''`. `''` counts as unset,\n * as it does in the graft — clearing an override restores the component's own\n * copy, so the inline editor and the graft agree about what the author is\n * looking at.\n */\nexport function getInstanceEffectivePropText(\n instanceProps: unknown,\n declared: ReusableComponentProp[] | undefined | null,\n propName: string,\n): string {\n return (\n resolveReusablePropValues(declared, instancePropValues(instanceProps))\n .tokens[`${COMPONENT_PROP_TOKEN_PREFIX}${propName}`] ?? ''\n )\n}\n\n/** A value a field bound to a property has nothing to receive from. */\nfunction isNothingToGive(value: unknown): boolean {\n return (\n value === undefined ||\n value === null ||\n value === '' ||\n (Array.isArray(value) && value.length === 0) ||\n matchComponentPropToken(value) != null\n )\n}\n\n/** A copy a field can own: a list is copied, so no two fields share one. */\nfunction ownValue(value: unknown): unknown {\n return Array.isArray(value) ? [...value] : value\n}\n\n/**\n * What a field bound to exactly one property token receives, by the value\n * class of that property — or `undefined` to remove the prop.\n *\n * `known` is the property's value when the caller resolved one, and\n * `substituted` the text its token became; a caller that resolved nothing\n * (a component editor drawing raw tokens) is read from the text alone.\n */\nfunction typedBindingValue(\n valueClass: ReusablePropValueClass,\n known: { value: unknown } | undefined,\n substituted: unknown,\n): unknown {\n const value = known ? known.value : substituted\n switch (valueClass) {\n case 'boolean':\n return readYesNoValue(value) === true\n case 'number': {\n if (isNothingToGive(value)) return undefined\n if (typeof value === 'number') return value\n const numeric = Number(value)\n return Number.isFinite(numeric) ? numeric : substituted\n }\n case 'icon':\n return isNothingToGive(value)\n ? undefined\n : (readInstanceIconValue(value)?.iconId ?? undefined)\n default:\n return isNothingToGive(value) ? undefined : ownValue(value)\n }\n}\n\n/**\n * The declared-prop substitution for a set of nodes, with each binding handed\n * to the element as the value its property's kind holds (AGL-2871, AGL-2893).\n *\n * The substitution itself is textual — every token becomes text and\n * `resolveNamedTokens` splices it into string props. That is right for copy\n * and wrong for the fields that do not hold copy. So a prop whose stored value\n * is EXACTLY one token naming a declared prop is finished by that prop's value\n * class (`reusablePropValueClass`):\n *\n * - `boolean` (Yes / no, a single Checkbox) — a real `true` or `false`, read\n * through {@link readYesNoValue}, because an element reading `lightbox`\n * takes the string `'false'` for a yes. Nothing to read is a no.\n * - `number` (Number, Slider) — a real number when the value is one, because an\n * element passing `size` to MUI turns `'32'` into `font-size: 32`, which no\n * browser applies. Nothing set is removed; text that is not a number is left\n * as it was authored.\n * - `icon` — the picked icon's id, with its path written into the field's\n * companion (`iconId` → `iconPath`, the rule `iconPathPropName` states)\n * from `iconPaths`. The path is what a published page draws, since it never\n * loads the icon catalog; and it is written or removed on every pass,\n * because a path left over from the component's own icon would be drawn in\n * place of the page's. Nothing picked removes both.\n * - `value` (every other kind: a Choice, a Color, a Size, a Date, a list of\n * answers, an entity) — the value exactly as the property holds it, from\n * `values`, so a list stays a list and a theme multiple stays a number.\n * Nothing set is removed, so the element keeps its own default: a\n * dropdown's empty value is not one of its options, and an element handed\n * `variant: ''` draws neither the component's variant nor its own.\n * - `text` (Text, Long text, Image, Link) — the substituted text.\n *\n * \"Nothing chosen\" includes a binding still holding its token after\n * substitution — a component editor drawing a prop that has no default —\n * which is then drawn exactly as a page that sets nothing renders it.\n *\n * The same finishing reaches a nested placement: a component placed inside\n * this definition, whose own `propValues` hand one of this definition's\n * properties on by its exact token, receives the value typed — a list, a\n * number, an icon with its path — and nothing at all where there is nothing to\n * give, so its own default applies.\n *\n * Exact match only, for the reason {@link matchComponentPropToken} gives: a\n * value that merely contains a token is text with a value inside it, and it\n * stays text. An undeclared name is never typed either — it never substitutes,\n * so there is no value to read.\n *\n * Top-level props only, and never an element's text content (`children`). The\n * binding a panel field offers writes that field's own prop; a token nested in\n * an item list is content the component spelled out, and text is text\n * whatever kind of property fills it — so both keep the textual treatment.\n *\n * An `href` or `src` a token fed is then held to the address rule — see\n * {@link holdPropFedAddresses}.\n *\n * Inputs are never mutated, and a map with no typed binding and no refused\n * address comes back exactly as the substitution left it.\n */\nexport function resolveComponentPropTokens<\n N extends AglynNodeSchema = AglynNodeSchema,\n>(\n nodes: NormalizedNodes<N>,\n declared: ReusableComponentProp[] | undefined | null,\n tokens: Record<string, string> | null | undefined,\n iconPaths?: Record<string, string> | null,\n values?: Record<string, unknown> | null,\n): NormalizedNodes<N> {\n const substituted = resolveNamedTokens(nodes, tokens)\n const typedProps = new Map<string, ReusablePropValueClass>()\n for (const prop of declared ?? []) {\n if (!prop?.name) continue\n const valueClass = reusablePropValueClass(prop)\n if (valueClass !== 'text') typedProps.set(prop.name, valueClass)\n }\n if (!typedProps.size) return holdPropFedAddresses(nodes, substituted)\n const knownValue = (name: string) =>\n values ? { value: values[name] } : undefined\n let typed: NormalizedNodes<N> | undefined\n for (const [id, node] of Object.entries(nodes ?? {})) {\n const raw = node?.props as Record<string, unknown> | undefined\n if (!raw || typeof raw !== 'object') continue\n let props: Record<string, unknown> | undefined\n const own = () =>\n (props = props ?? {\n ...(substituted[id]?.props as Record<string, unknown> | undefined),\n })\n for (const [key, value] of Object.entries(raw)) {\n if (key === 'children') continue\n const name = matchComponentPropToken(value)\n const valueClass = name ? typedProps.get(name) : undefined\n if (!name || !valueClass) continue\n const next = own()\n const finished = typedBindingValue(\n valueClass,\n knownValue(name),\n next[key],\n )\n if (finished === undefined) delete next[key]\n else next[key] = finished\n if (valueClass !== 'icon') continue\n const pathKey = iconPathPropName(key)\n if (pathKey === key) continue\n const path = finished === undefined ? undefined : iconPaths?.[name]\n if (path) next[pathKey] = path\n else delete next[pathKey]\n }\n const nested =\n node?.componentId === REUSABLE_INSTANCE_COMPONENT_ID\n ? instancePropValues(raw)\n : undefined\n if (nested) {\n let forwarded: Record<string, unknown> | undefined\n for (const [key, value] of Object.entries(nested)) {\n const name = matchComponentPropToken(value)\n const valueClass = name ? typedProps.get(name) : undefined\n if (!name || !valueClass) continue\n forwarded = forwarded ?? {\n ...instancePropValues(own()),\n }\n const known = knownValue(name)\n const given = known ? known.value : forwarded[key]\n if (isNothingToGive(given)) {\n delete forwarded[key]\n continue\n }\n if (valueClass === 'icon') {\n const icon = readInstanceIconValue(given)\n const path = iconPaths?.[name]\n forwarded[key] = icon\n ? { ...icon, ...(path && !icon.iconPath ? { iconPath: path } : {}) }\n : undefined\n if (!forwarded[key]) delete forwarded[key]\n continue\n }\n forwarded[key] = typedBindingValue(valueClass, { value: given }, given)\n }\n if (forwarded) own()[REUSABLE_INSTANCE_PROP_VALUES_KEY] = forwarded\n }\n if (!props) continue\n typed = typed ?? { ...substituted }\n typed[id] = { ...substituted[id], props } as N\n }\n return holdPropFedAddresses(nodes, typed ?? substituted)\n}\n\n/** A `{{prop.*}}` token's opening, escaped for a pattern. */\nconst PROP_TOKEN_SOURCE = `\\\\{\\\\{\\\\s*${COMPONENT_PROP_TOKEN_PREFIX.replace(\n /[.*+?^${}()|[\\]\\\\]/g,\n '\\\\$&',\n)}`\n\n/** Where a `{{prop.*}}` token opens, anywhere inside a value. */\nconst PROP_TOKEN_OPENING = new RegExp(PROP_TOKEN_SOURCE)\n\n/**\n * The bindings that open a value and that a later compose stage resolves — a\n * host token, a site variable — but not a property token, which this stage\n * resolves or never will.\n */\nconst LATER_BINDINGS_OPENING = new RegExp(\n `^(?:\\\\{\\\\{(?!${PROP_TOKEN_SOURCE.slice('\\\\{\\\\{'.length)})[^{}]*\\\\}\\\\}\\\\s*)+`,\n)\n\n/**\n * Whether a property-fed value may stay in an address prop once the\n * substitution has made it.\n *\n * The address rule, with the site's own references admitted — a screen or\n * collection link, a media-library pick — since this is the site that resolves\n * them. One exception: a value that opens with a binding a later stage\n * resolves (`{{host.url}}/about`) has no scheme until then, so the binding is\n * left to supply one and what follows it is judged as though the binding came\n * to nothing — which is what an unknown host token does — so a scheme cannot\n * be smuggled in behind it.\n */\nfunction isRenderableAddress(prop: NodeUrlProp, value: unknown): boolean {\n if (typeof value !== 'string') return false\n const address = value.trim()\n if (isSafeNodeUrl(prop, address, { siteReferences: true })) return true\n const opening = LATER_BINDINGS_OPENING.exec(address)\n if (!opening) return false\n const rest = address.slice(opening[0].length)\n return (\n rest === '' ||\n isSafeNodeUrl(prop, rest, { siteReferences: true }) ||\n !hasUrlScheme(rest)\n )\n}\n\n/**\n * `resolved` with every `href` and `src` that a `{{prop.*}}` token fed held to\n * the address rule, and removed where it fails it (AGL-2933).\n *\n * A published node's own address is held to that rule when it is published,\n * and a property's default when its declaration is — but a property's value\n * is set by whichever page places the component, or screen inside the layout,\n * long after either, and this is where it becomes the prop an element spreads\n * onto the DOM. Canvas, Preview, detach and the tenant all arrive here, so a\n * `javascript:` or `data:` value set on a property reaches none of them.\n *\n * It judges the whole value the substitution made (see\n * {@link isRenderableAddress}), so a token behind a literal scheme\n * (`https://example.com/{{prop.path}}`) stays a path on that site, and two\n * values that spell a scheme between them are refused together. A value still\n * holding its property token — an undeclared name, or the component editor's\n * raw-token view — is no address either, and a linking element reads it as\n * none.\n *\n * Only the prop goes: a button with no address is still a button. `raw` is\n * the map before substitution, which is what says a token fed the value;\n * neither map is mutated.\n */\nfunction holdPropFedAddresses<N extends AglynNodeSchema>(\n raw: NormalizedNodes<N>,\n resolved: NormalizedNodes<N>,\n): NormalizedNodes<N> {\n let held: NormalizedNodes<N> | undefined\n for (const [id, node] of Object.entries(raw ?? {})) {\n const authored = node?.props as Record<string, unknown> | undefined\n if (!authored || typeof authored !== 'object') continue\n let props: Record<string, unknown> | undefined\n for (const key of NODE_URL_PROPS) {\n const source = authored[key]\n if (typeof source !== 'string' || !PROP_TOKEN_OPENING.test(source)) continue\n const current = (\n props ?? (resolved[id]?.props as Record<string, unknown> | undefined)\n )?.[key]\n if (current === undefined || isRenderableAddress(key, current)) continue\n props = props ?? {\n ...(resolved[id]?.props as Record<string, unknown> | undefined),\n }\n delete props[key]\n }\n if (!props) continue\n held = held ?? { ...resolved }\n held[id] = { ...resolved[id], props } as N\n }\n return held ?? resolved\n}\n\n/**\n * A definition's declared props resolved over a set of its nodes for one page,\n * then the parts that page hides pruned (AGL-1314) — the single sequence the\n * component graft, detach and a composed layout all run.\n *\n * `values` is the page's own map, and `rootId` the node the prune never\n * removes. Visibility directives are evaluated on the result, never before:\n * they read `{{prop.*}}` like everything else, so pruning ahead of\n * substitution would see a token instead of the value and hide whatever the\n * definition merely MENTIONED.\n */\nexport function applyDeclaredProps<N extends AglynNodeSchema = AglynNodeSchema>(\n nodes: NormalizedNodes<N>,\n declared: ReusableComponentProp[] | undefined | null,\n values: Readonly<Record<string, unknown>> | null | undefined,\n rootId: NodeId,\n): NormalizedNodes<N> {\n const resolved = resolveReusablePropValues(declared, values)\n return pruneHiddenNodes(\n resolveComponentPropTokens(\n nodes,\n declared,\n resolved.tokens,\n resolved.iconPaths,\n resolved.values,\n ),\n rootId,\n )\n}\n\n/**\n * Whether a node's props ask for it to be dropped (AGL-1314) — see\n * {@link NODE_HIDE_IF_PROP} and {@link NODE_HIDE_UNLESS_PROP}.\n *\n * Evaluated on SUBSTITUTED props, so callers must run this after the\n * declared-prop tokens have resolved; against a raw definition node every\n * directive is still a token and reads as \"no opinion\" by design, which is\n * what keeps the component editor showing the parts a page will hide.\n */\nexport function isNodeHiddenByDirective(props: unknown): boolean {\n if (!props || typeof props !== 'object' || Array.isArray(props)) return false\n const bag = props as Record<string, unknown>\n if (readYesNoValue(bag[NODE_HIDE_IF_PROP]) === true) return true\n return readYesNoValue(bag[NODE_HIDE_UNLESS_PROP]) === false\n}\n\nfunction hasVisibilityDirective(props: unknown): boolean {\n if (!props || typeof props !== 'object' || Array.isArray(props)) return false\n const bag = props as Record<string, unknown>\n return NODE_HIDE_IF_PROP in bag || NODE_HIDE_UNLESS_PROP in bag\n}\n\n/**\n * The node minus its visibility directives — they are compose-time\n * instructions, and `Leaf` spreads whatever survives onto the component,\n * so leaving them would put `hideif=\"…\"` on the DOM of every node that\n * declared one and stayed.\n */\nfunction withoutVisibilityDirectives<N extends AglynNodeSchema>(node: N): N {\n if (!hasVisibilityDirective(node?.props)) return node\n const props = { ...(node.props as Record<string, unknown>) }\n delete props[NODE_HIDE_IF_PROP]\n delete props[NODE_HIDE_UNLESS_PROP]\n return { ...node, props: props as N['props'] }\n}\n\n/**\n * Drops every node under `rootId` whose props ask to be hidden, along with\n * its whole subtree and its entry in its parent's child list, and strips\n * the directives off everything that survives (AGL-1314).\n *\n * Structural rather than a `display: none`: an instance can already hide a\n * leaf with a per-leaf style override (AGL-1332), but that still ships the\n * markup, still fetches the image, still leaves the grid column, and still\n * leaves the control in the tab order. \"This page has no mockup\" is a\n * statement about the tree, so it is made in the tree.\n *\n * `rootId` itself is never dropped. The graft below wires the instance\n * node's single child to the definition root by id, so a self-hiding root\n * would leave a dangling reference; a component that should not appear at\n * all is a decision for the page that placed it, not for the definition.\n *\n * Returns the input unchanged when no node carries a directive, so the\n * overwhelmingly common case costs one scan and allocates nothing.\n */\nexport function pruneHiddenNodes<N extends AglynNodeSchema = AglynNodeSchema>(\n nodes: NormalizedNodes<N>,\n rootId: NodeId,\n): NormalizedNodes<N> {\n if (!nodes) return nodes\n let sawDirective = false\n for (const node of Object.values(nodes)) {\n if (hasVisibilityDirective(node?.props)) {\n sawDirective = true\n break\n }\n }\n if (!sawDirective) return nodes\n\n const hidden = new Set<NodeId>()\n const seen = new Set<NodeId>()\n const walk = (id: NodeId) => {\n const node = nodes[id]\n // `seen` bounds the walk: a definition that referenced an ancestor\n // would otherwise recurse until the stack gave out.\n if (!node || seen.has(id)) return\n seen.add(id)\n const children = Array.isArray(node.nodes) ? (node.nodes as NodeId[]) : []\n for (const childId of children) {\n if (typeof childId !== 'string' || !nodes[childId]) continue\n if (isNodeHiddenByDirective(nodes[childId]?.props)) {\n hidden.add(childId)\n for (const descendant of collectDescendantIds(nodes, childId)) {\n hidden.add(descendant)\n }\n continue\n }\n walk(childId)\n }\n }\n walk(rootId)\n\n const next: NormalizedNodes<N> = {}\n for (const [id, node] of Object.entries(nodes)) {\n if (hidden.has(id)) continue\n const kept = withoutVisibilityDirectives(node as N)\n const children = Array.isArray(kept?.nodes) ? (kept.nodes as NodeId[]) : null\n const survivors =\n children && children.some((childId) => hidden.has(childId as NodeId))\n ? children.filter((childId) => !hidden.has(childId as NodeId))\n : null\n next[id] = survivors ? ({ ...kept, nodes: survivors } as N) : kept\n }\n return next\n}\n\n/**\n * Expands reusable-component instance nodes (componentId\n * {@link REUSABLE_INSTANCE_COMPONENT_ID}, `props.refId` → definition id) by\n * grafting the referenced definition's subtree under each instance:\n *\n * - Grafted node ids are namespaced per instance (`cmp__{instanceId}__…`).\n * - The instance node keeps its identity (selection/attributes target) and\n * gains the grafted root as its only child.\n * - Unresolvable refIds leave the instance untouched — a deleted definition\n * must never take a published screen down.\n * - Definitions may contain instances of other definitions; expansion\n * repeats up to {@link MAX_COMPONENT_DEPTH} passes, which also bounds\n * accidental self-reference.\n * - A definition's declared props (AGL-1247) resolve per instance as the\n * subtree is grafted: `{{prop.name}}` tokens take that instance's\n * override, falling back to the prop's default. This is what lets one\n * hero serve eleven pages instead of being copied onto each.\n * - A grafted node asking to be hidden ({@link NODE_HIDE_IF_PROP} /\n * {@link NODE_HIDE_UNLESS_PROP}, AGL-1314) is pruned with its subtree —\n * which is how one hero renders with a mockup on `/product` and without\n * one on `/press`.\n * - Inputs are never mutated.\n *\n * `morePlacements` adds further node kinds that stand for a stored tree — a\n * placed form is the second one ({@link PlacementKind}) — expanded in the same\n * passes as instances, so the two nest inside each other in either order.\n *\n * ⛔ **A placement is expanded only when its tree RESOLVES**, meaning the\n * document is in the map AND carries a `rootId` its `nodes` actually hold. An\n * unresolvable one is left exactly as authored. That is what makes the\n * child-replacing kind safe to introduce on a live site: a form bound to an\n * entity that has never been published still renders the fields drawn on the\n * page, and the graft can only ever swap a page's copy of a form for the\n * entity's own.\n */\nexport function composeReusableComponentNodes<\n N extends AglynNodeSchema = AglynNodeSchema,\n>(\n nodes: NormalizedNodes<N>,\n definitionsById:\n | Record<string, ReusableComponentTree<N> | undefined>\n | undefined,\n morePlacements?: readonly PlacementKind<N>[],\n): NormalizedNodes<N> {\n const placements: PlacementKind<N>[] = [\n {\n componentId: REUSABLE_INSTANCE_COMPONENT_ID,\n refProp: 'refId',\n definitionsById,\n },\n ...(morePlacements ?? []),\n ].filter((placement) => placement.definitionsById)\n if (!placements.length) return nodes\n\n /**\n * The kind and tree this node stands for, or `undefined` when it stands for\n * nothing resolvable.\n *\n * The `nodes[rootId]` check is the resolution rule stated once: a document\n * whose root is not among its own nodes has no design to graft, and wiring\n * the placement's only child to an id nothing holds would blank it on the\n * page while reading, downstream, as already expanded.\n */\n const resolvePlacement = (node: N | undefined) => {\n for (const placement of placements) {\n if (node?.componentId !== placement.componentId) continue\n const refId = (node.props as any)?.[placement.refProp]\n if (typeof refId !== 'string' || !refId) continue\n const definition = placement.definitionsById?.[refId]\n if (!definition?.rootId || !definition.nodes?.[definition.rootId]) continue\n return { placement, definition }\n }\n return undefined\n }\n\n /** Expanded by an earlier pass — its children already carry its prefix. */\n const alreadyGrafted = (id: NodeId, node: N) => {\n const childIds = Array.isArray(node.nodes) ? (node.nodes as NodeId[]) : []\n return childIds.some(\n (childId) =>\n typeof childId === 'string' && childId.startsWith(instancePrefix(id)),\n )\n }\n\n let composed: NormalizedNodes<N> = nodes\n\n /*\n * WHAT A RESOLVED FORM REPLACES, DROPPED BEFORE ANYTHING IS GRAFTED.\n *\n * Ahead of the passes rather than inside them so the drop is decided against\n * the authored tree alone. Inside a pass it would race the expansions\n * running beside it: an inline field that was itself a component instance\n * could be grafted in the same pass that discards it, and its grafted\n * subtree — keyed off ids this walk never sees — would survive its own\n * parent as unreachable nodes on a published page.\n */\n const doomed = new Set<NodeId>()\n const emptied: NodeId[] = []\n for (const [id, node] of Object.entries(nodes)) {\n if (!node || !resolvePlacement(node)?.placement.replacesAuthoredChildren) {\n continue\n }\n if (alreadyGrafted(id, node)) continue\n const descendants = collectDescendantIds(nodes, id)\n if (!descendants.size) continue\n for (const descendantId of descendants) doomed.add(descendantId)\n emptied.push(id)\n }\n if (doomed.size) {\n const pruned: NormalizedNodes<N> = {}\n for (const [id, node] of Object.entries(nodes)) {\n if (!doomed.has(id)) pruned[id] = node as N\n }\n for (const id of emptied) {\n // A replaced form nested in another replaced form's authored children is\n // gone with it, so there is nothing left here to empty.\n if (pruned[id]) pruned[id] = { ...pruned[id], nodes: [] }\n }\n composed = pruned\n }\n\n /**\n * Which definition each graft brought in, keyed by the id prefix its nodes\n * carry — the ancestry a node cannot expand into again.\n *\n * `alreadyGrafted` bounds an instance against ITSELF: once a node's children\n * carry its prefix, that node is done. It cannot see the other shape, where\n * a definition's own subtree contains a FRESH instance naming the same\n * definition. Each pass mints a new instance id, so that node looks new to\n * every check there was, and the graft ran again on its own output until\n * {@link MAX_COMPONENT_DEPTH} stopped it.\n *\n * A depth cap is the right backstop for a reusable component, where\n * self-reference is an authoring mistake. It is the wrong bound for a FORM:\n * `checkFormContract` REQUIRES a form design's tree to contain a `form` node\n * naming that same form, so a placed form does not merely risk grafting into\n * itself — it always does, to the cap, every render. Six nested `<form>`\n * elements is invalid HTML, so the server parser drops the inner ones and\n * the client tree then disagrees with the server tree, which is a hydration\n * failure on a public page.\n *\n * Keyed by prefix because the prefix chain IS the ancestry: a node grafted\n * inside instance X has an id beginning with X's prefix, and one nested two\n * deep begins with both. Testing `startsWith` against a definition already\n * open above therefore asks exactly the right question — \"is this the same\n * definition, inside its own expansion?\" — while leaving a genuinely\n * different form placed inside a form free to expand.\n */\n const graftedAncestry: Array<{ prefix: string; refId: string }> = []\n\n /**\n * The definition id a node points at, and the placement that claims it.\n *\n * Scoped to placements that REPLACE authored children. That is what a form\n * does and what a reusable-component instance does not, and the difference\n * is the whole reason this guard is narrow: for a component, a definition\n * naming itself is an authoring mistake whose documented behaviour is a\n * depth-bounded expansion, and collapsing it here would change a semantic\n * this fix has no business touching. For a placement that replaces children,\n * the instance and the definition's root denote the same thing.\n */\n const replacingRefOf = (\n node: N | undefined,\n ): { refId: string; placement: PlacementKind<N> } | null => {\n for (const placement of placements) {\n if (!placement.replacesAuthoredChildren) continue\n // `componentId` sits on the NODE and the ref on its props, matching\n // `resolvePlacement` exactly — a predicate that drifted from that one\n // would not fail loudly, it would simply never match and leave the guard\n // switched off.\n if (node?.componentId !== placement.componentId) continue\n const refId = (node.props as any)?.[placement.refProp]\n if (typeof refId === 'string' && refId) return { refId, placement }\n }\n return null\n }\n\n /** Just the id, for the two call sites that do not need the placement. */\n const refIdOf = (node: N | undefined): string | null =>\n replacingRefOf(node)?.refId ?? null\n\n /**\n * Is this node an instance of a definition already open above it?\n *\n * Left completely untouched when so — not pruned, not emptied. An unexpanded\n * form node renders its own authored children, which is the same thing an\n * unresolvable ref does, and matches the rule that a missing definition must\n * never take a published page down.\n */\n const withinOwnExpansion = (id: NodeId, node: N): boolean => {\n const refId = refIdOf(node)\n if (!refId) return false\n return graftedAncestry.some(\n (entry) => entry.refId === refId && id.startsWith(entry.prefix),\n )\n }\n\n for (let depth = 0; depth < MAX_COMPONENT_DEPTH; depth++) {\n const pending = Object.entries(composed).filter(\n ([id, node]) =>\n Boolean(resolvePlacement(node)) &&\n !alreadyGrafted(id, node) &&\n !withinOwnExpansion(id, node),\n )\n if (!pending.length) break\n\n const next: NormalizedNodes<N> = { ...composed }\n for (const [instanceId, instanceNode] of pending) {\n const definition = (\n resolvePlacement(instanceNode) as {\n definition: ReusableComponentTree<N>\n }\n ).definition\n const prefix = instancePrefix(instanceId)\n // Recorded BEFORE the subtree is written, so the nodes this graft is\n // about to produce are already inside its ancestry when the next pass\n // considers them.\n const grafting = refIdOf(instanceNode)\n if (grafting) graftedAncestry.push({ prefix, refId: grafting })\n const prefixId = (id: NodeId) => `${prefix}${id}`\n // Style overrides (AGL-1306 root, AGL-1332 per leaf): merged over\n // each definition node's own sx as this instance's copy is grafted —\n // per-instance scope exists only here, exactly like the declared-prop\n // substitution below. Merging into the graft (rather than a renderer\n // patch) is what gives canvas/Preview/tenant parity for free, and\n // reading the definition's CURRENT nodes each pass is why an override\n // can never pin the instance to an old component version.\n //\n // Per-leaf is not a nicety: a component's text leaves usually set\n // their OWN colour, so a root-level `color` never reaches them and an\n // instance given a white background renders white-on-white (AGL-1318).\n //\n // A placed form carries the same two layers (AGL-3285), so one page can\n // restyle a field's label without editing the form for every page.\n const styleOverrides = getInstanceStyleOverrides(\n instanceNode as { componentId?: string; styleOverrides?: unknown },\n )\n // Attribute overrides (AGL-1899) ride the same graft for the same\n // reason: this is the one point where per-instance scope exists, so\n // merging here is what makes canvas, Preview and tenant SSR agree\n // without any of them knowing an override happened.\n //\n // Applied to the props BEFORE `resolveNamedTokens` below, which is\n // what lets an override be written in `{{prop.*}}`/`{{var:id}}` and\n // still resolve, and what makes an override on a bound prop beat the\n // component's own binding — the more specific placement wins.\n const attrOverrides = getInstanceAttrOverrides(\n instanceNode as { componentId?: string; attrOverrides?: unknown },\n )\n\n const grafted: NormalizedNodes<N> = {}\n for (const [defId, defNode] of Object.entries(definition.nodes)) {\n if (!defNode) continue\n grafted[prefixId(defId)] = {\n ...defNode,\n $id: prefixId(defNode.$id ?? defId),\n parentId:\n defId === definition.rootId\n ? instanceId\n : defNode.parentId != null\n ? prefixId(defNode.parentId)\n : defNode.parentId,\n ...(Array.isArray(defNode.nodes) && {\n nodes: (defNode.nodes as NodeId[]).map((childId) =>\n typeof childId === 'string' ? prefixId(childId) : childId,\n ),\n }),\n ...((instanceSxPatch(\n defNode.sx,\n styleOverrides,\n defId,\n definition.rootId,\n ) ?? {}) as any),\n ...((instancePropsPatch(\n defNode.props,\n attrOverrides,\n defId,\n definition.rootId,\n ) ?? {}) as any),\n }\n }\n // Declared props (AGL-1247) substitute HERE, on this instance's copy\n // of the subtree — the only point in the pipeline where per-instance\n // scope exists, since after the merge every grafted node is just\n // another entry in one flat map.\n //\n // The value lands in a real string prop and compose runs graft →\n // repeatables → `resolveNodesBindings`, so a `{{var:id}}` typed into\n // an override still resolves downstream for free. A field bound to a\n // prop that is not text is finished by that prop's kind instead — see\n // `resolveComponentPropTokens` — and the parts this page hides are\n // pruned from the result (`applyDeclaredProps`).\n Object.assign(\n next,\n applyDeclaredProps(\n grafted,\n definition.props,\n instancePropValues(instanceNode.props),\n prefixId(definition.rootId),\n ),\n )\n /*\n * A definition whose ROOT names the definition itself is grafted\n * UNWRAPPED — its root's children attach to the instance, and the\n * duplicate root is dropped.\n *\n * Bounding the recursion above stops the runaway, but one graft of a\n * self-naming design still produces two of the same element nested: the\n * placed node, and the design's root inside it. For a form that is a\n * `<form>` inside a `<form>`, which is invalid HTML — the server parser\n * drops the inner one, the client keeps it, and the two trees disagree.\n * Six of them or two, the page still fails to hydrate.\n *\n * Unwrapping is not a special case bolted on for forms: the instance and\n * the definition's root denote THE SAME THING here, and rendering both\n * was always the duplicate. `checkFormContract` is what makes a form\n * design always take this shape, so for forms this branch is the normal\n * path rather than the exception.\n *\n * The instance keeps its own id and place: it is the node the page\n * authored, carrying the id everything else resolves against. What it\n * DRAWS is the design root's, with the placement's own settings on top\n * (AGL-3494) — see {@link placementPropsOverRoot}.\n */\n const graftedRootId = prefixId(definition.rootId)\n const definitionRoot = definition.nodes[definition.rootId] as N | undefined\n const rootNamesItself =\n Boolean(grafting) && refIdOf(definitionRoot) === grafting\n const graftedRoot = next[graftedRootId]\n if (rootNamesItself && graftedRoot) {\n const adopted = Array.isArray(graftedRoot.nodes)\n ? (graftedRoot.nodes as NodeId[])\n : []\n for (const childId of adopted) {\n if (next[childId]) {\n next[childId] = { ...next[childId], parentId: instanceId }\n }\n }\n delete next[graftedRootId]\n /*\n * THE DESIGN'S ROOT SETTINGS ARE THE FORM'S OWN (AGL-3494).\n *\n * The submit label, the success message and the root's styling are\n * edited on the saved form, once, for every page placing it. The\n * grafted root carries them — already with this placement's `root`\n * override slices merged in by the graft above (AGL-3285) — so it is\n * the base, and the placement's own settings go over it one prop at a\n * time. A placement that never set a label shows the form's; one that\n * did keeps showing its own, which is every placement saved before\n * the design's settings reached the page.\n *\n * The `root` attribute slice is laid over once more, last, because a\n * \"Change it on this page only\" edit is the most specific statement\n * there is about this one element — the order it already had over the\n * placement's own props before this merge existed.\n *\n * `sx` composes the same way `mergeNodeSx` composes it for an\n * instance: the design root's (with the `root` slice), then the\n * placement's own over it.\n */\n const rootAttrs = attrOverrides[STYLE_OVERRIDES_ROOT_KEY]\n const unwrappedProps = placementPropsOverRoot(\n revealTargetInPlacement(\n graftedRoot.props,\n definition,\n prefixId,\n instanceId,\n ),\n instanceNode.props,\n rootAttrs,\n )\n const unwrappedSx = mergeNodeSx(graftedRoot.sx, instanceNode.sx)\n const unwrappedClassName = joinClassNames(\n (graftedRoot as { className?: unknown }).className,\n (instanceNode as { className?: unknown }).className,\n )\n // Root's first, like the merge branch below: the form's own\n // choreography enrolls before what this page adds.\n const unwrappedInteractions = [\n ...interactionsOf(graftedRoot),\n ...interactionsOf(instanceNode),\n ]\n next[instanceId] = {\n ...instanceNode,\n ...(unwrappedProps === undefined\n ? {}\n : { props: unwrappedProps as N['props'] }),\n ...(unwrappedSx === undefined ? {} : { sx: unwrappedSx as N['sx'] }),\n ...(unwrappedClassName ? { className: unwrappedClassName } : {}),\n ...(unwrappedInteractions.length\n ? { interactions: unwrappedInteractions }\n : {}),\n nodes: adopted,\n }\n } else if (graftedRoot) {\n /*\n * THE INSTANCE AND THE DEFINITION'S ROOT ARE ONE ELEMENT (AGL-2521).\n *\n * The graft used to keep both — the instance as a container with the\n * definition's root inside it — so every placement published a `div`\n * the author never drew. On `aglyn.com` that was four of them on the\n * home page, one per placement, each sitting between a landmark and\n * its parent and breaking any direct-child selector the layout wrote.\n *\n * So the root TAKES THE INSTANCE'S PLACE: same id, same parent, same\n * slot in the parent's child list. Its own grafted id disappears and\n * its children keep theirs, which is what leaves the `cmp__{instance}\n * __{defId}` scheme — and everything reading it, from per-leaf\n * overrides to {@link resolveInstanceLeafBinding} — untouched.\n *\n * Keeping the INSTANCE'S id rather than the root's is the half that\n * matters: interactions, animations and analytics are all keyed to the\n * node the page authored, and a swap to the prefixed id would silently\n * drop every one of them.\n *\n * What the instance contributed as an element comes with it. Its `sx`\n * merges OVER the root's, because a placement styling its component is\n * the more specific of the two. Its universal directives — hide,\n * animate — move across for the same reason: they were authored\n * against \"this placement\", which is now this element. What stays\n * behind is the bookkeeping that only ever addressed the wrapper:\n * `refId`, `name`, the declared-prop values and the override slices,\n * all of them already consumed by the graft above.\n */\n /*\n * Interactions come from BOTH nodes, root's first.\n *\n * They are keyed to the element by node id, and after the merge one\n * element answers to two authors: the component, which wrote the\n * choreography its internals rely on, and the placement, which wrote\n * whatever this page wants on top. Keeping only one side silently\n * drops the other's — and because the instance keeps its own id, the\n * side that would go missing is the page's, on the very node whose id\n * it is.\n *\n * Root's run first for the reason the host actions do in\n * `getClientAutomations`: the more general enrolls before the more\n * specific, which is the order a page is read in.\n *\n * `interactions` is declared on `NodeSchema`, one layer above the\n * `AglynNodeSchema` this function is generic over, so both are read\n * off the node rather than through the type ({@link interactionsOf}).\n */\n const mergedInteractions = [\n ...interactionsOf(graftedRoot),\n ...interactionsOf(instanceNode),\n ]\n const carried: Record<string, unknown> = {}\n for (const key of INSTANCE_CARRIED_PROPS) {\n const value = (instanceNode.props as Record<string, unknown>)?.[key]\n if (value !== undefined) carried[key] = value\n }\n /*\n * A placement's repeat moves across too, and the element repeats\n * ITSELF (AGL-3111).\n *\n * It is the other universal directive authored against \"this\n * placement\": the page asked for one copy of the component per record.\n * After the merge that component is an element whose children are the\n * component's own, which would read as the item template, so the scope\n * is stated rather than left to the child list. The placement's repeat\n * replaces one on the component's root rather than mixing with it —\n * repeats do not nest, and a filter meant for the root's rows applied\n * to the placement's would be neither author's.\n */\n const repeatsPlacement = repeatKey(instanceNode) !== ''\n if (repeatsPlacement) {\n for (const key of REPEAT_DIRECTIVE_PROPS) {\n const value = (instanceNode.props as Record<string, unknown>)?.[key]\n if (value !== undefined) carried[key] = value\n }\n carried[REPEAT_SELF_PROP] = true\n }\n const rootProps = repeatsPlacement\n ? withoutRepeatDirective(graftedRoot).props\n : graftedRoot.props\n /*\n * Classes from BOTH nodes, the component root's first.\n *\n * A class names the element for the site's stylesheet and for the\n * runtime: ⋮ ▸ Start hidden writes `aglyn-hidden` into the placement's\n * `props.className`, and the show/hide steps toggle that class on the\n * element answering to the placement's id, which after the merge is\n * this one. Keeping either list alone drops the other author's names,\n * so the two are joined, each name once, in `props` and on the node.\n */\n const propsClassName = joinClassNames(\n (graftedRoot.props as Record<string, unknown> | undefined)?.[\n 'className'\n ],\n (instanceNode.props as Record<string, unknown> | undefined)?.[\n 'className'\n ],\n )\n if (propsClassName) carried['className'] = propsClassName\n const nodeClassName = joinClassNames(\n (graftedRoot as { className?: unknown }).className,\n (instanceNode as { className?: unknown }).className,\n )\n // The override slices and the reference are DOCUMENT state living on\n // the node beside `sx`, not props — the renderer never spreads them at\n // an element — so they ride along rather than being consumed and\n // dropped. A composed map that is saved back must still carry what the\n // author set on this placement (AGL-1306/AGL-1899), and a re-compose\n // is a no-op because the merged node no longer answers to\n // `reusableInstance`.\n const documentState: Record<string, unknown> = {}\n for (const key of INSTANCE_CARRIED_NODE_FIELDS) {\n const value = (instanceNode as Record<string, unknown>)[key]\n if (value !== undefined) documentState[key] = value\n }\n const mergedSx = mergeNodeSx(graftedRoot.sx, instanceNode.sx)\n const merged = {\n ...graftedRoot,\n $id: instanceId,\n parentId: instanceNode.parentId,\n ...documentState,\n ...(mergedSx === undefined ? {} : { sx: mergedSx as N['sx'] }),\n // Only when there is something to say: materializing an empty\n // `props` on a node that had none is a visible difference to\n // everything that asks whether a node was authored with any.\n ...(rootProps !== undefined || Object.keys(carried).length\n ? { props: { ...(rootProps as object), ...carried } }\n : {}),\n ...(nodeClassName ? { className: nodeClassName } : {}),\n // Absent rather than empty, like `props` above: a node the author\n // gave no choreography is one that carries no such key anywhere\n // else in the pipeline.\n ...(mergedInteractions.length\n ? { interactions: mergedInteractions }\n : {}),\n /*\n * The eye on the placement's hierarchy row hides the element the\n * placement became.\n *\n * Either author may hide it: the component, on its own root, which\n * arrives with the spread above, or the page, on the placement. Only\n * a hiding flag is carried, never a showing one: `false` and absent\n * mean the same thing on a node, so a placement whose eye was never\n * touched cannot bring back a root the component hid. Read off the\n * node for the reason `interactions` is: `hidden` is declared on\n * `NodeSchema`, above the type this function is generic over.\n */\n ...((instanceNode as { hidden?: unknown }).hidden\n ? { hidden: true }\n : {}),\n } as N\n for (const childId of Array.isArray(merged.nodes)\n ? (merged.nodes as NodeId[])\n : []) {\n if (next[childId]) {\n next[childId] = { ...next[childId], parentId: instanceId }\n }\n }\n delete next[graftedRootId]\n next[instanceId] = merged\n } else {\n /*\n * The root was pruned by its own visibility directive, so there is\n * nothing to take the instance's place. The instance stays as an empty\n * container rather than vanishing: its own hide directive has not been\n * evaluated yet, and removing a node the later passes still expect to\n * walk would strand its parent's child list.\n */\n next[instanceId] = {\n ...instanceNode,\n nodes: [],\n }\n }\n }\n composed = next\n }\n return composed\n}\n\n/**\n * Ids of every descendant of `rootId` reachable through `nodes` arrays —\n * the root itself excluded, unknown and repeated ids skipped, so a cycle\n * cannot hang the walk.\n *\n * Child lists are the only edges followed, never `parentId`. That is the\n * published renderer's own reach from the document root, which is why\n * `pageVideoObjects` asks this which Video nodes a page draws (AGL-2957).\n */\nexport function collectDescendantIds<N extends AglynNodeSchema>(\n nodes: NormalizedNodes<N>,\n rootId: NodeId,\n): Set<NodeId> {\n const found = new Set<NodeId>()\n const root = nodes?.[rootId]\n const queue: NodeId[] = Array.isArray(root?.nodes)\n ? [...(root.nodes as NodeId[])]\n : []\n while (queue.length) {\n const id = queue.shift() as NodeId\n if (found.has(id) || id === rootId || !nodes[id]) continue\n found.add(id)\n const children = nodes[id]?.nodes\n if (Array.isArray(children)) queue.push(...(children as NodeId[]))\n }\n return found\n}\n\n/**\n * Materializes the instance at `instanceId` into a plain, freely editable\n * copy of what it was RENDERING (AGL-1314) — what \"Detach from component\"\n * does, and the inverse of {@link replaceSubtreeWithInstance}.\n *\n * Deliberately here, beside the graft, because \"what the instance rendered\"\n * is a question only {@link composeReusableComponentNodes} can answer. The\n * console used to copy `definition.nodes` verbatim, which is the whole bug:\n * the definition's leaves hold `{{prop.headline}}` TOKENS, not text, so a\n * detached hero rendered its own markers and the author's copy was gone.\n * A second, simpler materializer will always drift from the renderer —\n * so this one runs the renderer's own steps:\n *\n * - Declared props (AGL-1247) resolve through {@link applyDeclaredProps},\n * exactly as the graft does: the instance's override, else the\n * definition's default. Every string prop is walked,\n * so an image's `src` bakes to the bound media for free — the token is\n * substituted by name, not by which prop happens to hold it.\n * - The style overrides (AGL-1306 root, AGL-1332 per leaf) merge over the\n * matching definition node's own sx, so the copy keeps the look the page\n * was showing rather than snapping back to the component's base styling.\n * Every node is patched, not just the root: an instance re-coloured to a\n * white band with black copy must detach as a white band with black copy.\n * - Ids are FRESH (`createId`), never the `cmp__…` graft namespace: a\n * detached copy is an ordinary subtree, and leaving graft ids behind\n * would collide the next time an instance of the same definition\n * expanded here. Only the root keeps the instance's id, so the parent's\n * child list, the undo stack and the selection all stay valid.\n * - Anything hanging under the instance (a pre-grafted layout-chrome\n * subtree, AGL-1218) is dropped with it; the copy replaces the whole\n * thing.\n *\n * A missing instance, a node that is not an instance, or a definition\n * without a resolvable root returns `nodes` UNCHANGED — detach must never\n * be the thing that empties a screen. Inputs are never mutated.\n */\nexport function detachInstanceSubtree<\n N extends AglynNodeSchema = AglynNodeSchema,\n>(\n nodes: NormalizedNodes<N>,\n instanceId: NodeId,\n definition:\n | Pick<ReusableComponentTree<N>, 'rootId' | 'nodes' | 'props'>\n | null\n | undefined,\n createId: () => NodeId,\n): NormalizedNodes<N> {\n const instanceNode = nodes?.[instanceId]\n if (instanceNode?.componentId !== REUSABLE_INSTANCE_COMPONENT_ID) {\n return nodes\n }\n const rootId = definition?.rootId\n if (!rootId || !definition?.nodes?.[rootId]) return nodes\n\n // Fresh ids for everything but the root, which inherits the instance's.\n // `createId` is injected so this stays pure (and specs stay readable);\n // the loop re-rolls rather than trusting uniqueness, because a collision\n // here would silently overwrite an unrelated node on the page.\n const taken = new Set<NodeId>(Object.keys(nodes))\n const idMap: Record<NodeId, NodeId> = { [rootId]: instanceId }\n for (const defId of Object.keys(definition.nodes)) {\n if (idMap[defId] != null) continue\n let fresh = createId()\n for (\n let attempt = 0;\n (!fresh || taken.has(fresh)) && attempt < 10;\n attempt++\n ) {\n fresh = createId()\n }\n taken.add(fresh)\n idMap[defId] = fresh\n }\n\n const styleOverrides = getInstanceStyleOverrides(\n instanceNode as { componentId?: string; styleOverrides?: unknown },\n )\n const attrOverrides = getInstanceAttrOverrides(\n instanceNode as { componentId?: string; attrOverrides?: unknown },\n )\n const copied: NormalizedNodes<N> = {}\n for (const [defId, defNode] of Object.entries(definition.nodes)) {\n if (!defNode) continue\n const newId = idMap[defId]\n copied[newId] = {\n ...defNode,\n $id: newId,\n parentId:\n defId === rootId\n ? (instanceNode.parentId ?? null)\n : defNode.parentId != null\n ? (idMap[defNode.parentId] ?? null)\n : (defNode.parentId ?? null),\n ...(Array.isArray(defNode.nodes) && {\n nodes: (defNode.nodes as NodeId[]).map((childId) =>\n typeof childId === 'string' ? (idMap[childId] ?? childId) : childId,\n ),\n }),\n // The SAME patch the graft applies, node for node (AGL-1332) — the\n // detached copy has to look identical to what the page was showing,\n // and a per-leaf override baked only at the root would repaint every\n // headline the moment an author detached.\n ...((instanceSxPatch(defNode.sx, styleOverrides, defId, rootId) ??\n {}) as any),\n // Attribute overrides bake in for the same reason (AGL-1899): a\n // detached copy that reverted to the component's own `variant` would\n // change under the author at the moment they asked for a fork.\n ...((instancePropsPatch(defNode.props, attrOverrides, defId, rootId) ??\n {}) as any),\n }\n }\n\n const doomed = collectDescendantIds(nodes, instanceId)\n const next: NormalizedNodes<N> = {}\n for (const [id, node] of Object.entries(nodes)) {\n if (id === instanceId || doomed.has(id)) continue\n next[id] = node as N\n }\n // Detach must materialize what the instance was RENDERING, so the parts\n // this page hid (AGL-1314) are absent from the copy too — a detached hero\n // that grew its mockup back is the same class of bug as one that rendered\n // `{{prop.headline}}`.\n return Object.assign(\n next,\n applyDeclaredProps(\n copied,\n definition.props,\n instancePropValues(instanceNode.props),\n instanceId,\n ),\n )\n}\n\n/**\n * The definition a subtree becomes when it is promoted (AGL-2908): the\n * element at `rootId` and everything under it, as a component document's own\n * `nodes` map.\n *\n * The other half of \"Save as reusable component\", beside\n * {@link replaceSubtreeWithInstance}: this one says what the new document\n * holds, that one says what the promoting document keeps. Both are here so\n * neither can drift from what the graft expects to read back.\n *\n * - The promoted root's `parentId` is dropped. In its old document it hung\n * from a section; in its own it IS the document, and a definition whose\n * root still points at a parent it no longer has grafts nothing.\n * - Editor-only fields go: `componentSchema` is the palette's own object and\n * `resolvedProps` is a render of the props beside them, so storing either\n * writes a snapshot of the editor into a document the renderer reads.\n * - Unknown `rootId` gives an empty map, and the input is never mutated.\n *\n * Child lists are the only edges followed, so an element the subtree does not\n * reach is not carried along even if it claims the root as its parent.\n */\nexport function reusableComponentDefinitionFrom<\n N extends AglynNodeSchema = AglynNodeSchema,\n>(nodes: NormalizedNodes<N>, rootId: NodeId): NormalizedNodes<N> {\n const root = nodes?.[rootId]\n if (!root) return {}\n const definition: NormalizedNodes<N> = {}\n for (const id of [rootId, ...collectDescendantIds(nodes, rootId)]) {\n const node = nodes[id]\n if (!node) continue\n const {\n componentSchema: _schema,\n resolvedProps: _resolved,\n ...stored\n } = node as N & { componentSchema?: unknown; resolvedProps?: unknown }\n definition[id] = (id === rootId ? { ...stored, parentId: null } : stored) as N\n }\n return definition\n}\n\n/**\n * Replaces the subtree rooted at `rootId` with an instance of `definitionId`\n * (AGL-1193) — what \"Save as reusable component\" does to the tree it was\n * promoted from.\n *\n * Without this the promoting document keeps an inline *copy*: the one place\n * guaranteed never to track the component it created, silently. Deliberately\n * in this file so the swap and {@link composeReusableComponentNodes} cannot\n * drift about what an instance node looks like.\n *\n * - The instance keeps the promoted root's `$id` and `parentId`, so the\n * parent's child list, the undo stack and the current selection all stay\n * valid — the mirror of the detach path, which reuses the instance id.\n * - Every descendant is dropped; its content now lives in the definition.\n * - `displayName` rides along as a prop purely so the editor placeholder can\n * name what it stands for (definitions are not grafted into the canvas).\n * - Unknown `rootId` is a no-op, and the input is never mutated.\n */\nexport function replaceSubtreeWithInstance<\n N extends AglynNodeSchema = AglynNodeSchema,\n>(\n nodes: NormalizedNodes<N>,\n rootId: NodeId,\n definitionId: string,\n displayName?: string,\n): NormalizedNodes<N> {\n const root = nodes?.[rootId]\n if (!root || !definitionId) return nodes\n\n // Descendants only — the root is replaced, not removed.\n const doomed = collectDescendantIds(nodes, rootId)\n\n const next: NormalizedNodes<N> = {}\n for (const [id, node] of Object.entries(nodes)) {\n if (!doomed.has(id)) next[id] = node as N\n }\n next[rootId] = {\n $id: rootId,\n parentId: root.parentId ?? null,\n componentId: REUSABLE_INSTANCE_COMPONENT_ID,\n pluginId: 'mui',\n props: {\n refId: definitionId,\n ...(displayName && { name: displayName }),\n },\n nodes: [],\n } as unknown as N\n return next\n}\n\n/**\n * The icon path an instance node should be drawn with (AGL-1193), or\n * `undefined` when the node is not an instance, its definition is unknown,\n * or that definition chose no icon — every one of which means \"fall back to\n * the component schema's own glyph\".\n *\n * The visual half of `getNodeLabelShort`: an instance stands for one\n * specific component, so a hierarchy of promoted sections drawn with one\n * repeated package glyph tells the author nothing. Unlike the label, the\n * icon is NOT denormalized onto the instance — it is read live off the\n * definition, so changing a component's icon updates every instance already\n * placed instead of only the ones inserted afterwards.\n *\n * Deliberately here rather than in the canvas manager: this file owns what\n * an instance node looks like, and a second reader that disagreed would draw\n * definition icons on nodes the graft does not treat as instances.\n *\n * Returns only the stored `iconPath`. Resolving `iconId` would need the\n * ~2.9 MB icon catalog, which render surfaces never load — and the lookup\n * that \"helpfully\" substitutes a default is what made every icon a \"help\"\n * glyph in AGL-1212.\n */\nexport function resolveInstanceIconPath(\n node:\n | { componentId?: string; props?: unknown }\n | undefined\n | null,\n definitionsById:\n | Record<string, { icon?: ReusableComponentIcon } | undefined>\n | undefined\n | null,\n): string | undefined {\n if (!node || !definitionsById) return undefined\n if (node.componentId !== REUSABLE_INSTANCE_COMPONENT_ID) return undefined\n const refId = (node.props as { refId?: unknown } | undefined)?.refId\n if (typeof refId !== 'string' || !refId) return undefined\n return definitionsById[refId]?.icon?.iconPath || undefined\n}\n\n/**\n * Whether a node map contains an instance of `definitionId` (AGL-703).\n *\n * The inverse of the graft above, and deliberately in the same file: a\n * \"Used by\" card that disagreed with {@link composeReusableComponentNodes}\n * about what counts as a reference would report \"used nowhere\" for\n * something the renderer does expand, which is an invitation to delete it.\n *\n * Scans ONLY direct instances. Callers wanting transitive usage must scan\n * definitions too — a definition may nest instances of other definitions,\n * so \"used by no screen\" does not mean \"used by nothing\".\n */\nexport function nodesReferenceComponent(\n nodes: Record<string, AglynNodeSchema | undefined> | undefined | null,\n definitionId: string,\n): boolean {\n if (!nodes || !definitionId) return false\n return Object.values(nodes).some(\n (node) =>\n node?.componentId === REUSABLE_INSTANCE_COMPONENT_ID &&\n (node.props as { refId?: unknown } | undefined)?.refId === definitionId,\n )\n}\n\n/**\n * Every definition id a node map renders, DIRECTLY or through another\n * definition (AGL-1898).\n *\n * {@link nodesReferenceComponent} answers the same question for one id and\n * scans direct instances only — its own doc says a caller wanting transitive\n * usage \"must scan definitions too\". This is that scan, kept beside the\n * graft for the same reason: a caller that disagreed with\n * {@link composeReusableComponentNodes} about what a document references\n * would be wrong about exactly the nested case the canvas draws.\n *\n * Why it exists here rather than at a call site. A screen's canvas re-grafts\n * when the host's definitions map changes, which is the whole of AGL-1898's\n * phase-2 transport — but that map changes whenever ANY component in the\n * host is published, most of them not on this page. Deciding whether a\n * change is this document's business needs the transitive set, because the\n * usual shared component is reached through a nav or a card rather than\n * placed on the screen itself.\n *\n * - Unresolvable ids are INCLUDED. A screen referencing a definition that is\n * unpublished, deleted, or simply not in the map yet still references it;\n * a caller filtering to \"what can expand\" can intersect with its own map,\n * whereas an id dropped here cannot be recovered.\n * - Cycles terminate: an id already collected is never re-walked, which\n * bounds a self-referencing definition the same way\n * {@link MAX_COMPONENT_DEPTH} bounds the graft.\n * - Traversal is over the definition's stored `nodes`, NOT a composed tree,\n * so it costs nothing and cannot be thrown off by grafted ids.\n */\nexport function collectReferencedComponentIds(\n nodes: Record<string, AglynNodeSchema | undefined> | undefined | null,\n definitionsById?:\n | Record<string, { nodes?: unknown } | undefined>\n | undefined\n | null,\n): Set<string> {\n const found = new Set<string>()\n const directRefIds = (\n source: Record<string, AglynNodeSchema | undefined> | undefined | null,\n ) => {\n const ids: string[] = []\n for (const node of Object.values(source ?? {})) {\n if (node?.componentId !== REUSABLE_INSTANCE_COMPONENT_ID) continue\n const refId = (node.props as { refId?: unknown } | undefined)?.refId\n if (typeof refId === 'string' && refId) ids.push(refId)\n }\n return ids\n }\n\n const queue = directRefIds(nodes)\n while (queue.length) {\n const refId = queue.shift() as string\n if (found.has(refId)) continue\n found.add(refId)\n const definition = definitionsById?.[refId]\n if (!definition?.nodes) continue\n queue.push(\n ...directRefIds(\n definition.nodes as Record<string, AglynNodeSchema | undefined>,\n ),\n )\n }\n return found\n}\n\nexport default composeReusableComponentNodes\n"],"names":["iconPathPropName","reusablePropValueClass","COMPONENT_NODE_ID_PREFIX","COMPONENT_PROP_TOKEN_PREFIX","INSTANCE_CARRIED_NODE_FIELDS","INSTANCE_CARRIED_PROPS","NODE_HIDE_IF_PROP","NODE_HIDE_UNLESS_PROP","REUSABLE_INSTANCE_COMPONENT_ID","REUSABLE_INSTANCE_PROP_VALUES_KEY","STYLE_OVERRIDES_ROOT_KEY","REPEAT_DIRECTIVE_PROPS","REPEAT_SELF_PROP","repeatKey","withoutRepeatDirective","FORM_COMPONENT_ID","FORM_ID_PROP","FORM_REVEAL_NODE_PROP","mergeNodeSx","hasUrlScheme","isSafeNodeUrl","NODE_URL_PROPS","readInstanceIconValue","readYesNoValue","resolveReusablePropValues","resolveNamedTokens","isStyleRecord","value","Array","isArray","Object","keys","length","joinClassNames","lists","names","filter","list","flatMap","split","Boolean","Set","join","undefined","interactionsOf","node","interactions","isSetOnPlacement","placementPropsOverRoot","rootProps","placementProps","rootAttrs","base","own","merged","key","entries","className","assign","revealTargetInPlacement","definition","prefixId","instanceId","props","target","nodes","rootId","isPlacedFormNode","componentId","formId","isDefinitionPlacement","placementDefinitionFor","sources","refId","definitions","design","formDesigns","getInstanceStyleOverrides","overrides","styleOverrides","clean","getInstanceRootStyleOverride","instanceSxPatch","baseSx","defId","rootSlice","leafSlice","sx","ATTR_OVERRIDE_REFUSED_PROPS","PLACED_FORM_REFUSED_ATTR_PROPS","isAttrOverrideRefused","placement","prop","has","getInstanceAttrOverrides","attrOverrides","slice","propValue","instancePropsPatch","baseProps","listInstanceStyleTargets","targets","seen","walk","id","depth","add","isRoot","push","componentInternalId","name","children","childId","MAX_COMPONENT_DEPTH","instancePrefix","matchComponentPropToken","match","exec","resolveInstanceLeafBinding","graftedId","contentProp","defNode","prefix","rootInternalId","find","parentId","startsWith","raw","declared","some","boundProp","instancePropValues","instanceProps","values","getInstanceEffectivePropText","propName","tokens","isNothingToGive","ownValue","typedBindingValue","valueClass","known","substituted","numeric","Number","isFinite","iconId","resolveComponentPropTokens","iconPaths","typedProps","Map","set","size","holdPropFedAddresses","knownValue","typed","get","next","finished","pathKey","path","nested","forwarded","given","icon","iconPath","PROP_TOKEN_SOURCE","replace","PROP_TOKEN_OPENING","RegExp","LATER_BINDINGS_OPENING","isRenderableAddress","address","trim","siteReferences","opening","rest","resolved","held","authored","source","test","current","applyDeclaredProps","pruneHiddenNodes","isNodeHiddenByDirective","bag","hasVisibilityDirective","withoutVisibilityDirectives","sawDirective","hidden","descendant","collectDescendantIds","kept","survivors","composeReusableComponentNodes","definitionsById","morePlacements","placements","refProp","resolvePlacement","alreadyGrafted","childIds","composed","doomed","emptied","replacesAuthoredChildren","descendants","descendantId","pruned","graftedAncestry","replacingRefOf","refIdOf","withinOwnExpansion","entry","pending","instanceNode","grafting","grafted","$id","map","graftedRootId","definitionRoot","rootNamesItself","graftedRoot","adopted","unwrappedProps","unwrappedSx","unwrappedClassName","unwrappedInteractions","mergedInteractions","carried","repeatsPlacement","propsClassName","nodeClassName","documentState","mergedSx","found","root","queue","shift","detachInstanceSubtree","createId","taken","idMap","fresh","attempt","copied","newId","reusableComponentDefinitionFrom","componentSchema","_schema","resolvedProps","_resolved","stored","replaceSubtreeWithInstance","definitionId","displayName","pluginId","resolveInstanceIconPath","nodesReferenceComponent","collectReferencedComponentIds","directRefIds","ids"],"mappings":"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"}
|