@bgub/fig-dom 0.0.1

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/CHANGELOG.md ADDED
@@ -0,0 +1 @@
1
+ # Changelog
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Ben Gubler
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # @bgub/fig-dom
2
+
3
+ Fig DOM renderer.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @bgub/fig-dom
9
+ ```
10
+
11
+ Fig packages are ESM-only and require Node `^20.19.0 || >=22.12.0` for Node runtime entry
12
+ points.
13
+
14
+ ## Usage
15
+
16
+ ```ts
17
+ import { createPortal, createRoot, hydrateRoot } from "@bgub/fig-dom";
18
+ ```
19
+
20
+ `hydrateRoot(container, node)` reuses server HTML, attaches Fig DOM
21
+ bindings/events, and reports recoverable mismatches through
22
+ `onRecoverableError`. Components that read external stores with
23
+ `useSyncExternalStore` use their server snapshot during hydration, then subscribe
24
+ and reconcile to the current client snapshot after commit.
25
+
26
+ Suspense hydration is boundary-based: server Suspense markers stay
27
+ dehydrated after the shell hydrates, then hydrate in background work or
28
+ synchronously when an interaction lands inside that boundary. Pending
29
+ boundaries stay dehydrated until the server completes them, while
30
+ server-recovered boundaries schedule client rendering for that boundary.
31
+
32
+ `createPortal(children, container, key?)` renders children into an existing DOM
33
+ container while keeping context, effects, and delegated events attached to the
34
+ logical Fig tree.
35
+
36
+ Testing utilities live under `@bgub/fig-dom/test-utils`; `act(callback)` runs
37
+ the callback and drains scheduled Fig DOM work before resolving.
38
+
39
+ ## DOM Compatibility
40
+
41
+ Fig DOM treats ordinary host props as attributes instead of maintaining a large
42
+ React-style property table. Native HTML/SVG attribute names such as `class`,
43
+ `for`, `tabindex`, `readonly`, `maxlength`, `viewBox`, `stroke-width`,
44
+ `xlink:href`, `aria-*`, and `data-*` pass through directly. Object `style`
45
+ props support camel-cased CSS properties and CSS custom properties such as
46
+ `--accent`.
47
+
48
+ SVG and MathML elements are created in their own namespaces, and
49
+ `foreignObject` children return to the HTML namespace. Hydration compares
50
+ against Fig's native attribute names so browser-normalized server attributes
51
+ such as `tabindex`, `readonly`, and `xlink:href` do not look like extras.
52
+
53
+ Use `unsafeHTML="<p>trusted html</p>"` to write raw `innerHTML`. Fig does not
54
+ sanitize this string, so only pass trusted or sanitized markup. `unsafeHTML`
55
+ manages the element contents directly and cannot be combined with children.
56
+
57
+ Fig lowers render-discovered `title`, `meta`, stylesheet/preload `link`, and
58
+ external `script` elements into the asset-resource registry. Matching assets
59
+ are hoisted to `document.head`, deduped against server output, and reference
60
+ counted; persistent assets such as stylesheets and scripts may remain after
61
+ unmount. Plain `style` elements are ordinary host elements. Fig does not warn
62
+ for `contentEditable`; native DOM behavior applies.
63
+
64
+ ## License
65
+
66
+ MIT
package/dist/act.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import { act } from "@bgub/fig-reconciler";
2
+ export { act };
package/dist/act.js ADDED
@@ -0,0 +1 @@
1
+ import{act as e}from"@bgub/fig-reconciler";export{e as act};
@@ -0,0 +1,295 @@
1
+ import { FigAssetResource, FigNode, FigPortal, Key } from "@bgub/fig";
2
+ import { FigRoot, FigRootOptions, RecoverableErrorInfo } from "@bgub/fig-reconciler";
3
+ //#region src/bind.d.ts
4
+ type Bind<T extends Element = Element> = (node: T, signal: AbortSignal) => void;
5
+ declare function composeBind<T extends Element = Element>(...binds: Array<Bind<T> | false | null | undefined>): Bind<T>;
6
+ //#endregion
7
+ //#region src/events.d.ts
8
+ type Container = Element | DocumentFragment;
9
+ type EventOptions = Pick<AddEventListenerOptions, "capture" | "passive">;
10
+ type EventCallback<E extends Event = Event> = (event: E, signal: AbortSignal) => void;
11
+ interface EventDescriptor<E extends Event = Event> {
12
+ readonly $$typeof: symbol;
13
+ readonly type: string;
14
+ readonly callback: EventCallback<E>;
15
+ readonly options?: EventOptions;
16
+ }
17
+ /**
18
+ * Declares a listener for the `events` prop. Events keep their native
19
+ * semantics: bubbling events are delegated through the Fig tree (including
20
+ * portals), while non-bubbling events — `focus` and `blur` included — attach
21
+ * directly to the element and fire only there. Fig does not emulate React's
22
+ * bubbling `focus`/`blur`; to observe focus changes from an ancestor, use
23
+ * the platform's bubbling variants, `focusin` and `focusout`.
24
+ */
25
+ declare function on<K extends keyof HTMLElementEventMap>(type: K, callback: EventCallback<HTMLElementEventMap[K]>, options?: EventOptions): EventDescriptor<HTMLElementEventMap[K]>;
26
+ declare function on<E extends Event = Event>(type: string, callback: EventCallback<E>, options?: EventOptions): EventDescriptor<E>;
27
+ //#endregion
28
+ //#region src/jsx-attributes.generated.d.ts
29
+ type HtmlGlobalAttributeName = "accesskey" | "autocapitalize" | "autocorrect" | "autofocus" | "class" | "contenteditable" | "dir" | "draggable" | "enterkeyhint" | "exportparts" | "hidden" | "id" | "inert" | "inputmode" | "is" | "itemid" | "itemprop" | "itemref" | "itemscope" | "itemtype" | "lang" | "nonce" | "part" | "popover" | "slot" | "spellcheck" | "style" | "tabindex" | "title" | "translate" | "writingsuggestions";
30
+ interface HtmlAttributeNameByTag {
31
+ a: HtmlGlobalAttributeName | "charset" | "coords" | "download" | "href" | "hreflang" | "name" | "ping" | "referrerpolicy" | "rel" | "rev" | "shape" | "target" | "type";
32
+ applet: HtmlGlobalAttributeName | "align" | "alt" | "archive" | "code" | "codebase" | "height" | "hspace" | "name" | "object" | "vspace" | "width";
33
+ area: HtmlGlobalAttributeName | "alt" | "coords" | "download" | "href" | "hreflang" | "nohref" | "ping" | "referrerpolicy" | "rel" | "shape" | "target" | "type";
34
+ audio: HtmlGlobalAttributeName | "autoplay" | "controls" | "crossorigin" | "loop" | "muted" | "preload" | "src";
35
+ base: HtmlGlobalAttributeName | "href" | "target";
36
+ basefont: HtmlGlobalAttributeName | "color" | "face" | "size";
37
+ blockquote: HtmlGlobalAttributeName | "cite";
38
+ body: HtmlGlobalAttributeName | "alink" | "background" | "bgcolor" | "link" | "text" | "vlink";
39
+ br: HtmlGlobalAttributeName | "clear";
40
+ button: HtmlGlobalAttributeName | "command" | "commandfor" | "disabled" | "form" | "formaction" | "formenctype" | "formmethod" | "formnovalidate" | "formtarget" | "name" | "popovertarget" | "popovertargetaction" | "type" | "value";
41
+ canvas: HtmlGlobalAttributeName | "height" | "width";
42
+ caption: HtmlGlobalAttributeName | "align";
43
+ col: HtmlGlobalAttributeName | "align" | "char" | "charoff" | "span" | "valign" | "width";
44
+ colgroup: HtmlGlobalAttributeName | "align" | "char" | "charoff" | "span" | "valign" | "width";
45
+ data: HtmlGlobalAttributeName | "value";
46
+ del: HtmlGlobalAttributeName | "cite" | "datetime";
47
+ details: HtmlGlobalAttributeName | "name" | "open";
48
+ dialog: HtmlGlobalAttributeName | "closedby" | "open";
49
+ dir: HtmlGlobalAttributeName | "compact";
50
+ div: HtmlGlobalAttributeName | "align";
51
+ dl: HtmlGlobalAttributeName | "compact";
52
+ embed: HtmlGlobalAttributeName | "height" | "src" | "type" | "width";
53
+ fieldset: HtmlGlobalAttributeName | "disabled" | "form" | "name";
54
+ font: HtmlGlobalAttributeName | "color" | "face" | "size";
55
+ form: HtmlGlobalAttributeName | "accept" | "accept-charset" | "action" | "autocomplete" | "enctype" | "method" | "name" | "novalidate" | "target";
56
+ frame: HtmlGlobalAttributeName | "frameborder" | "longdesc" | "marginheight" | "marginwidth" | "name" | "noresize" | "scrolling" | "src";
57
+ frameset: HtmlGlobalAttributeName | "cols" | "rows";
58
+ h1: HtmlGlobalAttributeName | "align";
59
+ h2: HtmlGlobalAttributeName | "align";
60
+ h3: HtmlGlobalAttributeName | "align";
61
+ h4: HtmlGlobalAttributeName | "align";
62
+ h5: HtmlGlobalAttributeName | "align";
63
+ h6: HtmlGlobalAttributeName | "align";
64
+ head: HtmlGlobalAttributeName | "profile";
65
+ hr: HtmlGlobalAttributeName | "align" | "noshade" | "size" | "width";
66
+ html: HtmlGlobalAttributeName | "manifest" | "version";
67
+ iframe: HtmlGlobalAttributeName | "align" | "allow" | "allowfullscreen" | "allowpaymentrequest" | "allowusermedia" | "frameborder" | "height" | "loading" | "longdesc" | "marginheight" | "marginwidth" | "name" | "referrerpolicy" | "sandbox" | "scrolling" | "src" | "srcdoc" | "width";
68
+ img: HtmlGlobalAttributeName | "align" | "alt" | "border" | "crossorigin" | "decoding" | "fetchpriority" | "height" | "hspace" | "ismap" | "loading" | "longdesc" | "name" | "referrerpolicy" | "sizes" | "src" | "srcset" | "usemap" | "vspace" | "width";
69
+ input: HtmlGlobalAttributeName | "accept" | "align" | "alpha" | "alt" | "autocomplete" | "checked" | "colorspace" | "dirname" | "disabled" | "form" | "formaction" | "formenctype" | "formmethod" | "formnovalidate" | "formtarget" | "height" | "ismap" | "list" | "max" | "maxlength" | "min" | "minlength" | "multiple" | "name" | "pattern" | "placeholder" | "popovertarget" | "popovertargetaction" | "readonly" | "required" | "size" | "src" | "step" | "type" | "usemap" | "value" | "width";
70
+ ins: HtmlGlobalAttributeName | "cite" | "datetime";
71
+ isindex: HtmlGlobalAttributeName | "prompt";
72
+ label: HtmlGlobalAttributeName | "for" | "form";
73
+ legend: HtmlGlobalAttributeName | "align";
74
+ li: HtmlGlobalAttributeName | "type" | "value";
75
+ link: HtmlGlobalAttributeName | "as" | "blocking" | "charset" | "color" | "crossorigin" | "disabled" | "fetchpriority" | "href" | "hreflang" | "imagesizes" | "imagesrcset" | "integrity" | "media" | "referrerpolicy" | "rel" | "rev" | "sizes" | "target" | "type";
76
+ map: HtmlGlobalAttributeName | "name";
77
+ menu: HtmlGlobalAttributeName | "compact";
78
+ meta: HtmlGlobalAttributeName | "charset" | "content" | "http-equiv" | "media" | "name" | "scheme";
79
+ meter: HtmlGlobalAttributeName | "high" | "low" | "max" | "min" | "optimum" | "value";
80
+ object: HtmlGlobalAttributeName | "align" | "archive" | "border" | "classid" | "codebase" | "codetype" | "data" | "declare" | "form" | "height" | "hspace" | "name" | "standby" | "type" | "typemustmatch" | "usemap" | "vspace" | "width";
81
+ ol: HtmlGlobalAttributeName | "compact" | "reversed" | "start" | "type";
82
+ optgroup: HtmlGlobalAttributeName | "disabled" | "label";
83
+ option: HtmlGlobalAttributeName | "disabled" | "label" | "selected" | "value";
84
+ output: HtmlGlobalAttributeName | "for" | "form" | "name";
85
+ p: HtmlGlobalAttributeName | "align";
86
+ param: HtmlGlobalAttributeName | "name" | "type" | "value" | "valuetype";
87
+ pre: HtmlGlobalAttributeName | "width";
88
+ progress: HtmlGlobalAttributeName | "max" | "value";
89
+ q: HtmlGlobalAttributeName | "cite";
90
+ script: HtmlGlobalAttributeName | "async" | "blocking" | "charset" | "crossorigin" | "defer" | "fetchpriority" | "integrity" | "language" | "nomodule" | "referrerpolicy" | "src" | "type";
91
+ select: HtmlGlobalAttributeName | "autocomplete" | "disabled" | "form" | "multiple" | "name" | "required" | "size";
92
+ slot: HtmlGlobalAttributeName | "name";
93
+ source: HtmlGlobalAttributeName | "height" | "media" | "sizes" | "src" | "srcset" | "type" | "width";
94
+ style: HtmlGlobalAttributeName | "blocking" | "media" | "type";
95
+ table: HtmlGlobalAttributeName | "align" | "bgcolor" | "border" | "cellpadding" | "cellspacing" | "frame" | "rules" | "summary" | "width";
96
+ tbody: HtmlGlobalAttributeName | "align" | "char" | "charoff" | "valign";
97
+ td: HtmlGlobalAttributeName | "abbr" | "align" | "axis" | "bgcolor" | "char" | "charoff" | "colspan" | "headers" | "height" | "nowrap" | "rowspan" | "scope" | "valign" | "width";
98
+ template: HtmlGlobalAttributeName | "shadowrootclonable" | "shadowrootcustomelementregistry" | "shadowrootdelegatesfocus" | "shadowrootmode" | "shadowrootserializable";
99
+ textarea: HtmlGlobalAttributeName | "autocomplete" | "cols" | "dirname" | "disabled" | "form" | "maxlength" | "minlength" | "name" | "placeholder" | "readonly" | "required" | "rows" | "wrap";
100
+ tfoot: HtmlGlobalAttributeName | "align" | "char" | "charoff" | "valign";
101
+ th: HtmlGlobalAttributeName | "abbr" | "align" | "axis" | "bgcolor" | "char" | "charoff" | "colspan" | "headers" | "height" | "nowrap" | "rowspan" | "scope" | "valign" | "width";
102
+ thead: HtmlGlobalAttributeName | "align" | "char" | "charoff" | "valign";
103
+ time: HtmlGlobalAttributeName | "datetime";
104
+ tr: HtmlGlobalAttributeName | "align" | "bgcolor" | "char" | "charoff" | "valign";
105
+ track: HtmlGlobalAttributeName | "default" | "kind" | "label" | "src" | "srclang";
106
+ ul: HtmlGlobalAttributeName | "compact" | "type";
107
+ video: HtmlGlobalAttributeName | "autoplay" | "controls" | "crossorigin" | "height" | "loop" | "muted" | "playsinline" | "poster" | "preload" | "src" | "width";
108
+ }
109
+ type SvgGlobalAttributeName = "about" | "class" | "content" | "datatype" | "id" | "lang" | "property" | "rel" | "resource" | "rev" | "style" | "tabindex" | "typeof";
110
+ interface SvgAttributeNameByTag {
111
+ a: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "download" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "focusable" | "focusHighlight" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "href" | "hreflang" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "opacity" | "overflow" | "ping" | "pointer-events" | "referrerpolicy" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "target" | "text-anchor" | "text-decoration" | "text-rendering" | "transform" | "type" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode";
112
+ altGlyph: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "dx" | "dy" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "format" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "glyphRef" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "requiredExtensions" | "requiredFeatures" | "rotate" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode" | "x" | "y";
113
+ altGlyphDef: SvgGlobalAttributeName;
114
+ altGlyphItem: SvgGlobalAttributeName;
115
+ animate: SvgGlobalAttributeName | "accumulate" | "additive" | "alignment-baseline" | "attributeName" | "attributeType" | "baseline-shift" | "begin" | "by" | "calcMode" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "dur" | "enable-background" | "end" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "from" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "href" | "image-rendering" | "kerning" | "keySplines" | "keyTimes" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "max" | "min" | "opacity" | "overflow" | "pointer-events" | "repeatCount" | "repeatDur" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "restart" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "to" | "unicode-bidi" | "values" | "visibility" | "word-spacing" | "writing-mode";
116
+ animateColor: SvgGlobalAttributeName | "accumulate" | "additive" | "alignment-baseline" | "attributeName" | "attributeType" | "baseline-shift" | "begin" | "by" | "calcMode" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "dur" | "enable-background" | "end" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "from" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "image-rendering" | "kerning" | "keySplines" | "keyTimes" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "max" | "min" | "opacity" | "overflow" | "pointer-events" | "repeatCount" | "repeatDur" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "restart" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "to" | "unicode-bidi" | "values" | "visibility" | "word-spacing" | "writing-mode";
117
+ animateMotion: SvgGlobalAttributeName | "accumulate" | "additive" | "begin" | "by" | "calcMode" | "dur" | "end" | "externalResourcesRequired" | "fill" | "from" | "href" | "keyPoints" | "keySplines" | "keyTimes" | "max" | "min" | "origin" | "path" | "repeatCount" | "repeatDur" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "restart" | "rotate" | "systemLanguage" | "to" | "values";
118
+ animateTransform: SvgGlobalAttributeName | "accumulate" | "additive" | "attributeName" | "attributeType" | "begin" | "by" | "calcMode" | "dur" | "end" | "externalResourcesRequired" | "fill" | "from" | "href" | "keySplines" | "keyTimes" | "max" | "min" | "repeatCount" | "repeatDur" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "restart" | "systemLanguage" | "to" | "type" | "values";
119
+ animation: SvgGlobalAttributeName | "begin" | "dur" | "end" | "externalResourcesRequired" | "fill" | "focusable" | "focusHighlight" | "height" | "initialVisibility" | "max" | "min" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "preserveAspectRatio" | "repeatCount" | "repeatDur" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "restart" | "syncBehavior" | "syncMaster" | "syncTolerance" | "systemLanguage" | "transform" | "width" | "x" | "y";
120
+ audio: SvgGlobalAttributeName | "begin" | "dur" | "end" | "externalResourcesRequired" | "fill" | "max" | "min" | "repeatCount" | "repeatDur" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "restart" | "syncBehavior" | "syncMaster" | "syncTolerance" | "systemLanguage" | "type";
121
+ canvas: SvgGlobalAttributeName | "preserveAspectRatio" | "requiredExtensions" | "systemLanguage";
122
+ circle: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "cx" | "cy" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "focusable" | "focusHighlight" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "opacity" | "overflow" | "pathLength" | "pointer-events" | "r" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "transform" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode";
123
+ clipPath: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "clipPathUnits" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "requiredExtensions" | "requiredFeatures" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "transform" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode";
124
+ "color-profile": SvgGlobalAttributeName | "local" | "name" | "rendering-intent";
125
+ cursor: SvgGlobalAttributeName | "externalResourcesRequired" | "requiredExtensions" | "requiredFeatures" | "systemLanguage" | "x" | "y";
126
+ defs: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "requiredExtensions" | "requiredFeatures" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "transform" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode";
127
+ desc: SvgGlobalAttributeName | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "systemLanguage";
128
+ discard: SvgGlobalAttributeName | "begin" | "href" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "systemLanguage";
129
+ ellipse: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "cx" | "cy" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "focusable" | "focusHighlight" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "opacity" | "overflow" | "pathLength" | "pointer-events" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "rx" | "ry" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "transform" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode";
130
+ feBlend: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "in" | "in2" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "mode" | "opacity" | "overflow" | "pointer-events" | "result" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
131
+ feColorMatrix: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "in" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "result" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "type" | "unicode-bidi" | "values" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
132
+ feComponentTransfer: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "in" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "result" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
133
+ feComposite: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "in" | "in2" | "k1" | "k2" | "k3" | "k4" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "operator" | "overflow" | "pointer-events" | "result" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
134
+ feConvolveMatrix: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "bias" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "divisor" | "dominant-baseline" | "edgeMode" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "in" | "kernelMatrix" | "kernelUnitLength" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "order" | "overflow" | "pointer-events" | "preserveAlpha" | "result" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "targetX" | "targetY" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
135
+ feDiffuseLighting: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "diffuseConstant" | "direction" | "display" | "dominant-baseline" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "in" | "kernelUnitLength" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "result" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "surfaceScale" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
136
+ feDisplacementMap: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "in" | "in2" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "result" | "scale" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "xChannelSelector" | "y" | "yChannelSelector";
137
+ feDistantLight: SvgGlobalAttributeName | "azimuth" | "elevation";
138
+ feDropShadow: SvgGlobalAttributeName | "dx" | "dy" | "height" | "in" | "result" | "stdDeviation" | "width" | "x" | "y";
139
+ feFlood: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "result" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
140
+ feFuncA: SvgGlobalAttributeName | "amplitude" | "exponent" | "intercept" | "offset" | "slope" | "tableValues" | "type";
141
+ feFuncB: SvgGlobalAttributeName | "amplitude" | "exponent" | "intercept" | "offset" | "slope" | "tableValues" | "type";
142
+ feFuncG: SvgGlobalAttributeName | "amplitude" | "exponent" | "intercept" | "offset" | "slope" | "tableValues" | "type";
143
+ feFuncR: SvgGlobalAttributeName | "amplitude" | "exponent" | "intercept" | "offset" | "slope" | "tableValues" | "type";
144
+ feGaussianBlur: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "edgeMode" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "in" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "result" | "shape-rendering" | "stdDeviation" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
145
+ feImage: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "crossorigin" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "href" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "preserveAspectRatio" | "result" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
146
+ feMerge: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "result" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
147
+ feMergeNode: SvgGlobalAttributeName | "in";
148
+ feMorphology: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "in" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "operator" | "overflow" | "pointer-events" | "radius" | "result" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
149
+ feOffset: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "dx" | "dy" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "in" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "result" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
150
+ fePointLight: SvgGlobalAttributeName | "x" | "y" | "z";
151
+ feSpecularLighting: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "in" | "kernelUnitLength" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "result" | "shape-rendering" | "specularConstant" | "specularExponent" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "surfaceScale" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
152
+ feSpotLight: SvgGlobalAttributeName | "limitingConeAngle" | "pointsAtX" | "pointsAtY" | "pointsAtZ" | "specularExponent" | "x" | "y" | "z";
153
+ feTile: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "in" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "result" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
154
+ feTurbulence: SvgGlobalAttributeName | "alignment-baseline" | "baseFrequency" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "numOctaves" | "opacity" | "overflow" | "pointer-events" | "result" | "seed" | "shape-rendering" | "stitchTiles" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "type" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
155
+ filter: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "filterRes" | "filterUnits" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "primitiveUnits" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
156
+ font: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "horiz-adv-x" | "horiz-origin-x" | "horiz-origin-y" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "vert-adv-y" | "vert-origin-x" | "vert-origin-y" | "visibility" | "word-spacing" | "writing-mode";
157
+ "font-face": SvgGlobalAttributeName | "accent-height" | "alphabetic" | "ascent" | "bbox" | "cap-height" | "descent" | "externalResourcesRequired" | "font-family" | "font-size" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "hanging" | "ideographic" | "mathematical" | "overline-position" | "overline-thickness" | "panose-1" | "slope" | "stemh" | "stemv" | "strikethrough-position" | "strikethrough-thickness" | "underline-position" | "underline-thickness" | "unicode-range" | "units-per-em" | "v-alphabetic" | "v-hanging" | "v-ideographic" | "v-mathematical" | "widths" | "x-height";
158
+ "font-face-format": SvgGlobalAttributeName | "string";
159
+ "font-face-name": SvgGlobalAttributeName | "name";
160
+ "font-face-src": SvgGlobalAttributeName;
161
+ "font-face-uri": SvgGlobalAttributeName | "externalResourcesRequired";
162
+ foreignObject: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "focusable" | "focusHighlight" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "opacity" | "overflow" | "pointer-events" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "transform" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
163
+ g: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "focusable" | "focusHighlight" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "opacity" | "overflow" | "pointer-events" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "transform" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode";
164
+ glyph: SvgGlobalAttributeName | "alignment-baseline" | "arabic-form" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "d" | "direction" | "display" | "dominant-baseline" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-name" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "horiz-adv-x" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "orientation" | "overflow" | "pointer-events" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode" | "unicode-bidi" | "vert-adv-y" | "vert-origin-x" | "vert-origin-y" | "visibility" | "word-spacing" | "writing-mode";
165
+ glyphRef: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "dx" | "dy" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "format" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "glyphRef" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode" | "x" | "y";
166
+ handler: SvgGlobalAttributeName | "externalResourcesRequired" | "type";
167
+ hkern: SvgGlobalAttributeName | "g1" | "g2" | "k" | "u1" | "u2";
168
+ iframe: SvgGlobalAttributeName | "requiredExtensions" | "systemLanguage";
169
+ image: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "crossorigin" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "focusable" | "focusHighlight" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "href" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "opacity" | "overflow" | "pointer-events" | "preserveAspectRatio" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "transform" | "type" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
170
+ line: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "focusable" | "focusHighlight" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "opacity" | "overflow" | "pathLength" | "pointer-events" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "transform" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode" | "x1" | "x2" | "y1" | "y2";
171
+ linearGradient: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "gradientTransform" | "gradientUnits" | "href" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "shape-rendering" | "spreadMethod" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode" | "x1" | "x2" | "y1" | "y2";
172
+ listener: SvgGlobalAttributeName | "defaultAction" | "event" | "handler" | "observer" | "phase" | "propagate" | "target";
173
+ marker: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "markerHeight" | "markerUnits" | "markerWidth" | "mask" | "opacity" | "orient" | "overflow" | "pointer-events" | "preserveAspectRatio" | "refX" | "refY" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "viewBox" | "visibility" | "word-spacing" | "writing-mode";
174
+ mask: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "maskContentUnits" | "maskUnits" | "opacity" | "overflow" | "pointer-events" | "requiredExtensions" | "requiredFeatures" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
175
+ metadata: SvgGlobalAttributeName | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "systemLanguage";
176
+ "missing-glyph": SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "d" | "direction" | "display" | "dominant-baseline" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "horiz-adv-x" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "vert-adv-y" | "vert-origin-x" | "vert-origin-y" | "visibility" | "word-spacing" | "writing-mode";
177
+ mpath: SvgGlobalAttributeName | "externalResourcesRequired" | "href";
178
+ path: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "d" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "focusable" | "focusHighlight" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "opacity" | "overflow" | "pathLength" | "pointer-events" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "transform" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode";
179
+ pattern: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "href" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "patternContentUnits" | "patternTransform" | "patternUnits" | "pointer-events" | "preserveAspectRatio" | "requiredExtensions" | "requiredFeatures" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "viewBox" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
180
+ polygon: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "focusable" | "focusHighlight" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "opacity" | "overflow" | "pathLength" | "pointer-events" | "points" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "transform" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode";
181
+ polyline: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "focusable" | "focusHighlight" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "opacity" | "overflow" | "pathLength" | "pointer-events" | "points" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "transform" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode";
182
+ prefetch: SvgGlobalAttributeName | "bandwidth" | "mediaCharacterEncoding" | "mediaContentEncodings" | "mediaSize" | "mediaTime";
183
+ radialGradient: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "cx" | "cy" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "fr" | "fx" | "fy" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "gradientTransform" | "gradientUnits" | "href" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "r" | "shape-rendering" | "spreadMethod" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode";
184
+ rect: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "focusable" | "focusHighlight" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "opacity" | "overflow" | "pathLength" | "pointer-events" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "rx" | "ry" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "transform" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
185
+ script: SvgGlobalAttributeName | "crossorigin" | "externalResourcesRequired" | "href" | "type";
186
+ set: SvgGlobalAttributeName | "attributeName" | "attributeType" | "begin" | "dur" | "end" | "externalResourcesRequired" | "fill" | "href" | "max" | "min" | "repeatCount" | "repeatDur" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "restart" | "systemLanguage" | "to";
187
+ solidColor: SvgGlobalAttributeName;
188
+ stop: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "offset" | "opacity" | "overflow" | "pointer-events" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode";
189
+ style: SvgGlobalAttributeName | "media" | "title" | "type";
190
+ svg: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "baseProfile" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "contentScriptType" | "contentStyleType" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "focusable" | "focusHighlight" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "opacity" | "overflow" | "playbackorder" | "playbackOrder" | "pointer-events" | "preserveAspectRatio" | "requiredExtensions" | "requiredFeatures" | "shape-rendering" | "snapshotTime" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "syncBehaviorDefault" | "syncToleranceDefault" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "timelinebegin" | "timelineBegin" | "transform" | "unicode-bidi" | "version" | "viewBox" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y" | "zoomAndPan";
191
+ switch: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "focusable" | "focusHighlight" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "opacity" | "overflow" | "pointer-events" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "transform" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode";
192
+ symbol: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "preserveAspectRatio" | "refX" | "refY" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "text-anchor" | "text-decoration" | "text-rendering" | "unicode-bidi" | "viewBox" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
193
+ tbreak: SvgGlobalAttributeName | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "systemLanguage";
194
+ text: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "dx" | "dy" | "editable" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "focusable" | "focusHighlight" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "image-rendering" | "kerning" | "lengthAdjust" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "opacity" | "overflow" | "pointer-events" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "rotate" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "textLength" | "transform" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode" | "x" | "y";
195
+ textArea: SvgGlobalAttributeName | "editable" | "focusable" | "focusHighlight" | "height" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "systemLanguage" | "transform" | "width" | "x" | "y";
196
+ textPath: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "href" | "image-rendering" | "kerning" | "lengthAdjust" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "method" | "opacity" | "overflow" | "path" | "pointer-events" | "requiredExtensions" | "requiredFeatures" | "shape-rendering" | "side" | "spacing" | "startOffset" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "textLength" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode";
197
+ title: SvgGlobalAttributeName | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "systemLanguage";
198
+ tref: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "dx" | "dy" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "image-rendering" | "kerning" | "lengthAdjust" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "opacity" | "overflow" | "pointer-events" | "requiredExtensions" | "requiredFeatures" | "rotate" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "textLength" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode" | "x" | "y";
199
+ tspan: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "dx" | "dy" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "focusable" | "focusHighlight" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "image-rendering" | "kerning" | "lengthAdjust" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "opacity" | "overflow" | "pointer-events" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "rotate" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "textLength" | "unicode-bidi" | "visibility" | "word-spacing" | "writing-mode" | "x" | "y";
200
+ unknown: SvgGlobalAttributeName | "requiredExtensions" | "systemLanguage";
201
+ use: SvgGlobalAttributeName | "alignment-baseline" | "baseline-shift" | "clip" | "clip-path" | "clip-rule" | "color" | "color-interpolation" | "color-interpolation-filters" | "color-profile" | "color-rendering" | "cursor" | "direction" | "display" | "dominant-baseline" | "enable-background" | "externalResourcesRequired" | "fill" | "fill-opacity" | "fill-rule" | "filter" | "flood-color" | "flood-opacity" | "focusable" | "focusHighlight" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch" | "font-style" | "font-variant" | "font-weight" | "glyph-orientation-horizontal" | "glyph-orientation-vertical" | "height" | "href" | "image-rendering" | "kerning" | "letter-spacing" | "lighting-color" | "marker-end" | "marker-mid" | "marker-start" | "mask" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "opacity" | "overflow" | "pointer-events" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "shape-rendering" | "stop-color" | "stop-opacity" | "stroke" | "stroke-dasharray" | "stroke-dashoffset" | "stroke-linecap" | "stroke-linejoin" | "stroke-miterlimit" | "stroke-opacity" | "stroke-width" | "systemLanguage" | "text-anchor" | "text-decoration" | "text-rendering" | "transform" | "unicode-bidi" | "visibility" | "width" | "word-spacing" | "writing-mode" | "x" | "y";
202
+ video: SvgGlobalAttributeName | "begin" | "dur" | "end" | "externalResourcesRequired" | "fill" | "focusable" | "focusHighlight" | "height" | "initialVisibility" | "max" | "min" | "nav-down" | "nav-down-left" | "nav-down-right" | "nav-left" | "nav-next" | "nav-prev" | "nav-right" | "nav-up" | "nav-up-left" | "nav-up-right" | "overlay" | "preserveAspectRatio" | "repeatCount" | "repeatDur" | "requiredExtensions" | "requiredFeatures" | "requiredFonts" | "requiredFormats" | "restart" | "syncBehavior" | "syncMaster" | "syncTolerance" | "systemLanguage" | "transform" | "transformBehavior" | "type" | "width" | "x" | "y";
203
+ view: SvgGlobalAttributeName | "externalResourcesRequired" | "preserveAspectRatio" | "viewBox" | "viewTarget" | "zoomAndPan";
204
+ vkern: SvgGlobalAttributeName | "g1" | "g2" | "k" | "u1" | "u2";
205
+ }
206
+ //#endregion
207
+ //#region src/jsx-attribute-policy.d.ts
208
+ type EmptyPropValue = false | null | undefined;
209
+ type AttributeValue = string | number | true | EmptyPropValue;
210
+ type HostStyle = Readonly<Record<string, string | EmptyPropValue>>;
211
+ type HostEvents = ReadonlyArray<EventDescriptor<any> | EmptyPropValue>;
212
+ interface FigHostProps<E extends Element> {
213
+ bind?: Bind<E> | EmptyPropValue;
214
+ children?: FigNode;
215
+ events?: HostEvents | EmptyPropValue;
216
+ key?: Key | null;
217
+ style?: HostStyle | EmptyPropValue;
218
+ suppressHydrationWarning?: boolean | null;
219
+ unsafeHTML?: string | EmptyPropValue;
220
+ }
221
+ interface ReactHabitTraps {
222
+ className?: never;
223
+ dangerouslySetInnerHTML?: never;
224
+ htmlFor?: never;
225
+ ref?: never;
226
+ [handler: `on${string}`]: never;
227
+ }
228
+ type FigOwnedPropName = keyof FigHostProps<Element> | keyof ReactHabitTraps;
229
+ type FormValue = string | number | EmptyPropValue;
230
+ type SelectValue = string | number | ReadonlyArray<string | number>;
231
+ interface FormStatePropsByTag {
232
+ input: {
233
+ checked?: boolean | null | undefined;
234
+ defaultChecked?: boolean | null | undefined;
235
+ defaultValue?: FormValue;
236
+ value?: FormValue;
237
+ };
238
+ select: {
239
+ defaultValue?: SelectValue | EmptyPropValue;
240
+ value?: SelectValue | EmptyPropValue;
241
+ };
242
+ textarea: {
243
+ defaultValue?: FormValue;
244
+ value?: FormValue;
245
+ };
246
+ }
247
+ type FormStateProps<Tag extends string> = Tag extends keyof FormStatePropsByTag ? FormStatePropsByTag[Tag] : unknown;
248
+ type FormStatePropName<Tag> = Tag extends keyof FormStatePropsByTag ? keyof FormStatePropsByTag[Tag] : never;
249
+ type FigGlobalAttributeName = `aria-${string}` | `data-${string}` | "role";
250
+ type SvgLegacyAttributeName = "xlink:href" | "xml:space" | "xmlns:xlink";
251
+ type HostAttributeProps<AttributeName extends string> = { [Name in Exclude<AttributeName, FigOwnedPropName>]?: AttributeValue; };
252
+ type HtmlAttributes<Tag extends keyof HtmlAttributeNameByTag> = Exclude<HtmlAttributeNameByTag[Tag], FormStatePropName<Tag>> | FigGlobalAttributeName;
253
+ type SvgAttributes<Tag extends keyof SvgAttributeNameByTag> = SvgAttributeNameByTag[Tag] | FigGlobalAttributeName | SvgLegacyAttributeName;
254
+ type HostProps<E extends Element, AttributeName extends string = never> = FigHostProps<E> & ReactHabitTraps & HostAttributeProps<AttributeName>;
255
+ type HtmlHostProps<Tag extends string, E extends Element> = HostProps<E, Tag extends keyof HtmlAttributeNameByTag ? HtmlAttributes<Tag> : HtmlGlobalAttributeName | FigGlobalAttributeName> & FormStateProps<Tag>;
256
+ type SvgHostProps<Tag extends string, E extends Element> = HostProps<E, Tag extends keyof SvgAttributeNameByTag ? SvgAttributes<Tag> : SvgGlobalAttributeName | FigGlobalAttributeName | SvgLegacyAttributeName>;
257
+ type OpenHtmlHostProps<E extends Element> = HostProps<E, HtmlGlobalAttributeName | FigGlobalAttributeName>;
258
+ interface OpenHostProps<E extends Element> extends FigHostProps<E>, ReactHabitTraps {
259
+ [attribute: string]: FigNode | HostStyle | HostEvents | Bind<E>;
260
+ }
261
+ //#endregion
262
+ //#region src/jsx.d.ts
263
+ type HtmlHostPropsByTag<TagNameMap> = { [Tag in keyof TagNameMap]: Tag extends string ? HtmlHostProps<Tag, TagNameMap[Tag] & Element> : OpenHtmlHostProps<TagNameMap[Tag] & Element>; };
264
+ type SvgHostPropsByTag<TagNameMap> = { [Tag in keyof TagNameMap]: Tag extends string ? SvgHostProps<Tag, TagNameMap[Tag] & Element> : OpenHostProps<TagNameMap[Tag] & Element>; };
265
+ type OpenHostPropsByTag<TagNameMap> = { [Tag in keyof TagNameMap]: OpenHostProps<TagNameMap[Tag] & Element>; };
266
+ type HostIntrinsicElements = HtmlHostPropsByTag<HTMLElementTagNameMap> & SvgHostPropsByTag<Omit<SVGElementTagNameMap, keyof HTMLElementTagNameMap>> & OpenHostPropsByTag<Omit<MathMLElementTagNameMap, keyof HTMLElementTagNameMap | keyof SVGElementTagNameMap>> & {
267
+ [customElement: `${string}-${string}`]: OpenHostProps<HTMLElement>;
268
+ };
269
+ //#endregion
270
+ //#region src/jsx-augmentation.d.ts
271
+ declare module "@bgub/fig/jsx-runtime" {
272
+ namespace JSX {
273
+ interface IntrinsicElements extends HostIntrinsicElements {}
274
+ }
275
+ }
276
+ //#endregion
277
+ //#region src/asset-resources.d.ts
278
+ /**
279
+ * Insert render-discovered asset resources (e.g. from a payload response's
280
+ * `getAssetResources()`) into the document head, deduped against resources
281
+ * already inserted by SSR, a host-rendered element, or an earlier call — using
282
+ * the same key semantics as host resources. Returns a promise that resolves once
283
+ * every freshly inserted *critical* stylesheet has loaded or errored, so callers
284
+ * can gate revealing the dependent content. Non-critical hints (preload,
285
+ * preconnect, scripts, fonts, `blocking: "none"` stylesheets) never block.
286
+ */
287
+ declare function insertAssetResources(resources: readonly FigAssetResource[]): Promise<void>;
288
+ //#endregion
289
+ //#region src/index.d.ts
290
+ declare const flushSync: <T>(this: void, callback: () => T) => T;
291
+ declare function createRoot(container: Container, options?: FigRootOptions): FigRoot;
292
+ declare function hydrateRoot(container: Container, children: FigNode, options?: FigRootOptions): FigRoot;
293
+ declare function createPortal(children: FigNode, container: Container, key?: Key | null): FigPortal;
294
+ //#endregion
295
+ export { type Bind, type Container, type EmptyPropValue, type EventCallback, type EventDescriptor, type EventOptions, type FigRoot, type FigRootOptions, type HostEvents, type HostIntrinsicElements, type HostProps, type HostStyle, type RecoverableErrorInfo, composeBind, createPortal, createRoot, flushSync, hydrateRoot, insertAssetResources, on };
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import{configureDomRefreshScheduler as e}from"./refresh.js";import{createPortalNode as t}from"@bgub/fig";import{ACTIVITY_TEMPLATE_ATTRIBUTE as n,EARLY_EVENT_HANDLER_PROPERTY as r,EARLY_EVENT_QUEUE_PROPERTY as i,REPLAYABLE_EVENT_TYPES as a,SUSPENSE_CLIENT_MARKER as o,SUSPENSE_COMPLETED_MARKER as s,SUSPENSE_END_MARKER as c,SUSPENSE_PENDING_PREFIX as l,VIEW_TRANSITION_PENDING_PROPERTY as u,assetResourceFromHostAttributes as d,assetResourceFromHostProps as f,assetResourceHostAttributes as p,assetResourceKey as m,isFigAssetResource as ee}from"@bgub/fig/internal";import{createRenderer as te,runWithEventPriority as h}from"@bgub/fig-reconciler";function g(e,t){if(_(e)&&t(e),!(!(`childNodes`in e)||e.firstChild===null))for(let n of Array.from(e.childNodes))g(n,t)}function _(e){return typeof e==`object`&&!!e&&`nodeType`in e&&e.nodeType===1}function v(e){return _(e)?`localName`in e&&typeof e.localName==`string`?e.localName.toLowerCase():`tagName`in e&&typeof e.tagName==`string`?e.tagName.toLowerCase():``:``}function ne(e){return!(`namespaceURI`in e)||e.namespaceURI===null||e.namespaceURI===`http://www.w3.org/1999/xhtml`}function y(e){return typeof e==`object`&&e&&`parentNode`in e?e.parentNode:null}function b(e){return e==null||e===!1}const x=new WeakMap,S=new WeakSet;function re(...e){let t=e.filter(e=>typeof e==`function`);return(e,n)=>{for(let r of t)r(e,n)}}function ie(e,t){let n=le(t),r=x.get(e);if(n===null){r!==void 0&&w(r),x.delete(e);return}if(r===void 0){let t={callback:n,controller:null,strictRan:!1};x.set(e,t),C(e,t)}else r.callback!==n&&(w(r),r.callback=n,C(e,r))}function ae(e){let t=x.get(e);t!==void 0&&C(e,t)}function oe(e){S.add(e);let t=x.get(e);t!==void 0&&w(t)}function se(e){S.delete(e);let t=x.get(e);t!==void 0&&C(e,t)}function ce(e){let t=x.get(e);t!==void 0&&(w(t),x.delete(e))}function C(e,t){t.controller!==null||e.parentNode===null||S.has(e)||(t.controller=new AbortController,t.callback(e,t.controller.signal))}function w(e){e.controller?.abort(),e.controller=null}function le(e){if(b(e))return null;if(typeof e==`function`)return e;throw Error(`The bind prop must be a function.`)}const ue=Symbol.for(`fig.event`),T=new WeakMap,E=new WeakMap,de=new WeakMap,D=[],fe=new Set([`beforeinput`,`blur`,`change`,`click`,`contextmenu`,`dblclick`,`focus`,`focusin`,`focusout`,`input`,`keydown`,`keyup`,`mousedown`,`mouseup`,`pointerdown`,`pointerup`,`submit`,`touchend`,`touchstart`]),pe=new Set(a),me=new Set([`drag`,`dragover`,`mousemove`,`pointermove`,`scroll`,`touchmove`,`wheel`]),he=new Set([...fe,...me,`mouseenter`,`mouseleave`]),ge=new Set(`abort.blur.cancel.canplay.canplaythrough.close.durationchange.emptied.encrypted.ended.error.focus.invalid.load.loadeddata.loadedmetadata.loadstart.mouseenter.mouseleave.pause.play.playing.pointerenter.pointerleave.progress.ratechange.resize.scroll.scrollend.seeked.seeking.stalled.suspend.timeupdate.toggle.volumechange.waiting`.split(`.`));let _e=e=>e();function ve(e){_e=e}function ye(e,t,n){let r=O(e);r.root=!0,n!==void 0&&(r.scope=n),t!==void 0&&(r.hydrate=t,Ne(e,r),xe(e))}const be=new WeakMap;function xe(e){let t=e.ownerDocument??e,n=be.get(t);if(n===void 0){let e=t[i];if(!Array.isArray(e))return;let o=t[r];if(typeof o==`function`&&typeof t.removeEventListener==`function`)for(let e of a)t.removeEventListener(e,o,!0);delete t[i],delete t[r],n=e,be.set(t,n)}let o=!1;for(let t=0;t<n.length;){let r=n[t];if(pe.has(r.type)&&z(e,r.target)){n.splice(t,1),Fe(e,r.type,r),o=!0;continue}t+=1}o&&queueMicrotask(j)}function Se(e){let t=E.get(e);if(t!==void 0){Ce(e);for(let n of t.listeners.values())e.removeEventListener(n.type,n.listener,{capture:n.capture});we(e),E.delete(e);for(let t=D.length-1;t>=0;--t)D[t].root===e&&D.splice(t,1)}}function Ce(e){let t=E.get(e);if(t!==void 0){t.hydrate=null;for(let[n,r]of t.hydrationListeners??[])e.removeEventListener(n,r,{capture:!0});t.hydrationListeners=null}}function we(e){for(let t of E.get(e)?.portals??[])we(t),A(t)}function O(e){let t=E.get(e);return t===void 0&&(t={hydrate:null,hydrationListeners:null,listeners:new Map,portalOwner:null,portals:null,root:!1,scope:null},E.set(e,t)),t}function Te(e,t,n){return{$$typeof:ue,type:e,callback:t,options:n}}function Ee(e,t){let n=Ue(e),r=Be(t,v(e)),i=null;for(let t=0;t<r.length;t+=1){let a=r[t];if(a===void 0){let e=n[t];e!==void 0&&(M(e),n[t]=void 0);continue}let o=rt(a.options),s=it(a.type,o),c=n[t];c===void 0?(i??=k(e),n[t]=je(e,i.root,i.listenerTarget,a,o,s)):c.key===s?c.callback!==a.callback&&(c.callback=a.callback):(i??=k(e),M(c),n[t]=je(e,i.root,i.listenerTarget,a,o,s))}for(let e=n.length-1;e>=r.length;--e){let t=n[e];t!==void 0&&M(t)}n.length=r.length}function De(e){let t=ke(e),n=B(e);for(let r of T.get(e)??[])r!==void 0&&We(e,t,n,r)}function Oe(e){for(let t of T.get(e)??[])t!==void 0&&M(t);T.delete(e)}function ke(e){return k(e).root}function k(e){let t=B(e);if(t===null)return{listenerTarget:null,root:null};let n=E.get(t);return{listenerTarget:t,root:n?.portalOwner?.root??(n?.root===!0?t:null)}}function Ae(e,t,n){let r=O(e),i=B(n)??t;if(r.portalOwner!==null){if(r.portalOwner.root===t&&r.portalOwner.parentTarget===i){r.portalOwner={logicalParent:n,parentTarget:i,root:t};return}A(e)}r.portalOwner={logicalParent:n,parentTarget:i,root:t};let a=O(i);(a.portals??=new Set).add(e);for(let n of a.listeners.values())I(t,e,n.type,n.capture,n.passive)}function A(e){let t=E.get(e),n=t?.portalOwner??null;if(t===void 0||n===null)return;t.portalOwner=null;let r=E.get(n.parentTarget);if(r!==void 0){r.portals?.delete(e);for(let t of r.listeners.keys())L(e,t)}}function j(){let e=new Set;for(let t=0;t<D.length;){let n=D[t];if(!z(n.listenerTarget??n.root,n.event.target)){D.splice(t,1);continue}if(Ie(n)===`blocked`){e.add(n.root),t+=1;continue}if(e.has(n.root)){t+=1;continue}D.splice(t,1),Le(n)}}function je(e,t,n,r,i,a){let o={key:a,type:r.type,callback:r.callback,options:i,controller:null,element:null,listener:null,listenerTarget:null,root:null};return We(e,t,n,o),o}function M(e){R(e),F(e)}function Me(e,t,n,r,i,a){let o=B(a.target);if(o!==t&&((o===null?null:E.get(o)??null)?.portalOwner?.root===e||!z(t,a.target))||Pe(e,n,a)===`blocked`)return;let s=N(e,t,n,r,i,a);s.length!==0&&et(a,!1,e=>P(s,a,e))}function Ne(e,t){if(t.hydrationListeners===null){t.hydrationListeners=[];for(let n of he){let r=t=>Pe(e,n,t);t.hydrationListeners.push([n,r]),e.addEventListener(n,r,{capture:!0,passive:at(n)})}}}function Pe(e,t,n){let r=E.get(e)?.hydrate??null;if(r===null)return`none`;let i=de.get(n),a=i?.get(e);if(a!==void 0)return a;let o=V(t),s=h(o,()=>r(n.target,o));return i===void 0&&(i=new WeakMap,de.set(n,i)),i.set(e,s),s===`blocked`&&pe.has(t)&&Fe(e,t,n),s}function Fe(e,t,n){D.push({event:n,listenerTarget:B(n.target),root:e,type:t})}function Ie(e){let t=E.get(e.root)?.hydrate??null;if(t===null)return`none`;let n=V(e.type);return h(n,()=>t(e.event.target,n))}function Le(e){let{event:t,root:n,type:r}=e,i=e.listenerTarget??e.root;et(t,!0,e=>{P(N(n,i,r,!0,null,t),t,e),!(e.immediateStopped||e.stopped)&&P(N(n,i,r,!1,null,t),t,e)})}function N(e,t,n,r,i,a){let o=Ze(e,t,a),s=[],c=r?-1:1;for(let t=r?o.length-1:0;t>=0&&t<o.length;t+=c){let a=o[t];for(let t of T.get(a)??[])t!==void 0&&(t.root!==e||t.type!==n||t.options.capture!==r||i!==null&&t.options.passive!==i||s.push({callback:t.callback,element:a,root:t.root,slot:t,type:t.type}))}return s}function P(e,t,n){let r=null;for(let i of e){if(n.immediateStopped)return;if(i.element!==r){if(r!==null&&n.stopped)return;r=i.element}try{Re(i,t)}finally{let e=i.slot;e.element===null&&e.listenerTarget===null&&F(e)}}}function Re(e,t){let n=e.slot;F(n),n.controller=new AbortController;let r=n.controller.signal;_e(()=>{ze(e.root,()=>h(V(e.type),()=>{$e(t,e.element,t=>{e.callback(t,r)})}))})}function ze(e,t){let n=e===null?null:E.get(e)?.scope??null;return n===null?t():n(t)}function F(e){e.controller?.abort(),e.controller=null}function Be(e,t){if(b(e))return[];if(Array.isArray(e)){let n=[];for(let r of e){if(b(r)){n.push(void 0);continue}He(r)||Ve(t),n.push(r)}return n}Ve(t)}function Ve(e){let t=e===``?`an element`:`<${e}>`;throw Error(`The events prop on ${t} must be an array of event descriptors created with on(type, callback).`)}function He(e){return typeof e==`object`&&!!e&&e.$$typeof===ue}function Ue(e){let t=T.get(e);return t===void 0&&(t=[],T.set(e,t)),t}function We(e,t,n,r){ot(r.type)?Ge(e,t,r):Ke(t,n,r)}function Ge(e,t,n){if(n.element===e){t!==null&&(n.root=t);return}R(n),n.element=e,n.root=t,n.listener=t=>{try{Re({callback:n.callback,element:e,root:n.root,slot:n,type:n.type},t)}finally{n.element===null&&n.listenerTarget===null&&F(n)}},e.addEventListener(n.type,n.listener,n.options)}function Ke(e,t,n){e===null||t===null||n.root===e&&n.listenerTarget===t||(R(n),n.root=e,n.listenerTarget=t,I(e,t,n.type,n.options.capture,n.options.passive))}function I(e,t,n,r,i){let a=Ye(t),o=`${n}:${r}:${i}`,s=a.get(o);if(s===void 0){s={capture:r,count:0,listener:a=>Me(e,t,n,r,i,a),passive:i,type:n},t.addEventListener(n,s.listener,{capture:r,passive:i}),a.set(o,s);for(let a of E.get(t)?.portals??[])I(e,a,n,r,i)}s.count+=1}function L(e,t){let n=E.get(e)?.listeners,r=n?.get(t);if(!(n===void 0||r===void 0)&&(--r.count,!(r.count>0))){e.removeEventListener(r.type,r.listener,{capture:r.capture}),n.delete(t);for(let n of E.get(e)?.portals??[])L(n,t)}}function R(e){qe(e),Je(e)}function qe(e){e.element===null||e.listener===null||(e.element.removeEventListener(e.type,e.listener,{capture:e.options.capture}),e.element=null,e.listener=null,e.root=null)}function Je(e){let t=e.listenerTarget;t!==null&&(e.root=null,e.listenerTarget=null,L(t,Xe(e)))}function Ye(e){return O(e).listeners}function Xe(e){return`${e.type}:${e.options.capture}:${e.options.passive}`}function Ze(e,t,n){let r=n.composedPath?.();if(r!==void 0){let n=r.indexOf(t);if(n!==-1)return[...r.slice(0,n).filter(_),...Qe(e,t)]}let i=[];for(let e=n.target;e!==t&&(_(e)&&i.push(e),e=y(e),e!==null););return[...i,...Qe(e,t)]}function Qe(e,t){let n=E.get(t)?.portalOwner??null;if(n===null||n.root!==e)return[];let r=[],i=n.logicalParent;for(;i!==null&&i!==e;){if(st(i)){let t=E.get(i)?.portalOwner??null;if(t!==null&&t.root===e){i=t.logicalParent;continue}}_(i)&&r.push(i),i=y(i)}return r}function z(e,t){for(let n=t;n!==null;){if(n===e)return!0;n=y(n)}return!1}function B(e){for(let t=e;t!==null;){if(st(t)){let e=E.get(t);if(e!==void 0&&(e.portalOwner!==null||e.root))return t}t=y(t)}return null}function $e(e,t,n){let r=Object.getOwnPropertyDescriptor(e,`currentTarget`),i=Reflect.defineProperty(e,"currentTarget",{configurable:!0,value:t});try{return n(e)}finally{i&&(r===void 0?delete e.currentTarget:Object.defineProperty(e,"currentTarget",r))}}function et(e,t,n){let r=e.cancelBubble===!0,i={immediateStopped:!1,stopped:!t&&r},a=nt(e,`stopPropagation`,()=>{i.stopped=!0}),o=nt(e,`stopImmediatePropagation`,()=>{i.stopped=!0,i.immediateStopped=!0}),s=tt(e,i);try{return n(i)}finally{s(),o(),a(),i.stopped&&(e.cancelBubble=!0)}}function tt(e,t){let n=Object.getOwnPropertyDescriptor(e,`cancelBubble`),r=Reflect.defineProperty(e,"cancelBubble",{configurable:!0,get:()=>t.stopped,set(e){e===!0&&(t.stopped=!0)}});return()=>{r&&(n===void 0?delete e.cancelBubble:Object.defineProperty(e,"cancelBubble",n))}}function nt(e,t,n){let r=Reflect.get(e,t);if(typeof r!=`function`)return()=>void 0;let i=Object.getOwnPropertyDescriptor(e,t),a=Reflect.defineProperty(e,t,{configurable:!0,value(){n(),r.call(e)}});return()=>{a&&(i===void 0?delete e[t]:Object.defineProperty(e,t,i))}}function rt(e={}){return{capture:e.capture===!0,passive:e.passive===!0}}function it(e,t){return`${e}:${t.capture}:${t.passive}`}function V(e){return fe.has(e)?`discrete`:me.has(e)?`continuous`:`default`}function at(e){return me.has(e)||e===`touchstart`||e===`touchend`}function ot(e){return ge.has(e)}function st(e){return typeof e==`object`&&!!e&&`addEventListener`in e&&`childNodes`in e}function ct(e){g(e,e=>{ae(e),De(e)})}function H(e){g(e,e=>{ce(e),Oe(e)})}const U=new WeakMap,lt=`http://www.w3.org/1999/xlink`;function W(e,t,n,r={}){let i=v(e),a=ne(e),o=new Set([...Object.keys(t),...Object.keys(n)]);for(let s of o){if(s===`events`){Ee(e,n[s]);continue}if(s===`bind`){ie(e,n[s]);continue}let o=t[s],c=n[s];if(s===`unsafeHTML`){if(r.hydrating===!0){gt(c);continue}o!==c&&ht(e,c);continue}if(!Nt(s)){if(jt(s)){dt(e,i,s,c,n,r);continue}o!==c&&(s===`style`?Tt(e,o,c):K(e,kt(s,a),c))}}_t(e,i,t,n,r),(i===`option`||i===`optgroup`)&&G(e)}function ut(e,t){W(e,{},t,{hydrating:!0})}function dt(e,t,n,r,i,a){if(t===`select`&&Mt(n))return;if(t===`option`&&n===`value`){K(e,`value`,pt(r));return}let o=a.initial===!0&&a.hydrating!==!0;if(n===`value`){if(b(r))return;ft(e,r,t,{live:!0})}else if(n===`defaultValue`)ft(e,r,t,{defaultValue:!0,live:o&&i.value===void 0});else if(n===`checked`){if(r===void 0)return;mt(e,r,{live:!0})}else n===`defaultChecked`&&mt(e,r,{defaultChecked:!0,live:o&&i.checked===void 0})}function ft(e,t,n,r){let i=n===`textarea`,a=pt(t);r.defaultValue===!0&&`defaultValue`in e&&(e.defaultValue=a??``),r.defaultValue===!0&&(i?e.textContent=a??``:K(e,`value`,a)),r.live===!0&&`value`in e?e.value!==(a??``)&&(e.value=a??``):r.live===!0&&a!==null&&K(e,`value`,a)}function pt(e){return b(e)?null:String(e)}function mt(e,t,n){let r=t===!0;n.defaultChecked===!0&&(`defaultChecked`in e&&(e.defaultChecked=r),K(e,`checked`,r)),n.live===!0&&`checked`in e?e.checked=r:n.live===!0&&K(e,`checked`,r)}function ht(e,t){let n=gt(t);`innerHTML`in e&&(e.innerHTML=n??``)}function gt(e){if(b(e))return null;if(typeof e==`string`)return e;throw Error(`The unsafeHTML prop must be a string.`)}function _t(e,t,n,r,i={}){if(t!==`select`)return;let a=r.value!==void 0,o=a?r.value:r.defaultValue;if(o==null||o===!1){U.delete(e);return}let s=!a&&i.hydrating===!0,c=U.get(e),l=!s&&(a||!a&&i.initial===!0),u={appliedDefault:c?.appliedDefault===!0||!a,applyDefaultToInsertedOptions:!s&&!a&&i.initial===!0,controlled:a,selectedValues:vt(o),value:o};U.set(e,u),l&&yt(e,u.selectedValues)}function G(e,t=!1){let n=xt(e);if(n===null)return;let r=U.get(n);r!==void 0&&(!r.controlled&&r.appliedDefault&&!t||!r.controlled&&t&&!r.applyDefaultToInsertedOptions||(yt(e,r.selectedValues),r.controlled||(r.appliedDefault=!0)))}function vt(e){return new Set(Array.isArray(e)?e.map(String):[String(e)])}function yt(e,t){if(v(e)===`option`){bt(e,t);return}St(e,e=>{bt(e,t)})}function bt(e,t){e.selected=t.has(Ct(e))}function xt(e){let t=e.parentNode;for(;t!==null;){if(_(t)&&v(t)===`select`)return t;t=t.parentNode}return null}function St(e,t){for(let n=e.firstChild;n!==null;){let e=n.nextSibling;_(n)&&(v(n)===`option`?t(n):St(n,t)),n=e}}function Ct(e){let t=wt(e,`value`);return t===null?(e.textContent??``).replace(/\s+/g,` `).trim():t}function wt(e,t){return e.getAttribute(t)}function Tt(e,t,n){let r=e.style;if(r===void 0)return;let i=Et(t),a=Et(n);for(let e of Object.keys(i))e in a||Ot(r,e);for(let[e,t]of Object.entries(a))t==null||t===!1?Ot(r,e):Dt(r,e,t)}function Et(e){return typeof e==`object`&&e?e:{}}function Dt(e,t,n){typeof n==`number`||typeof n==`bigint`||(t.startsWith(`--`)&&typeof e.setProperty==`function`?e.setProperty(t,String(n)):e[t]=n)}function Ot(e,t){t.startsWith(`--`)&&typeof e.removeProperty==`function`?e.removeProperty(t):e[t]=``}function kt(e,t){return t?e.toLowerCase():e}function K(e,t,n){if(b(n)){At(e,t);return}if(t===`xlink:href`){e.setAttributeNS(lt,t,String(n));return}e.setAttribute(t,String(n))}function At(e,t){if(t===`xlink:href`){e.removeAttributeNS(lt,`href`);return}e.removeAttribute(t)}function jt(e){return Mt(e)||e===`checked`||e===`defaultChecked`}function Mt(e){return e===`value`||e===`defaultValue`}function Nt(e){return e===`children`||e===`key`||e===`suppressHydrationWarning`||e===`unsafeHTML`||Pt(e)}function Pt(e){return/^on[A-Z]/.test(e)}const q=new WeakMap,J=new WeakMap;function Ft(e,t){let n=X(),r=f(e,t);if(n===null||r===null)return null;let i=m(r),a=Y(n),o=a.get(i),s=o?.element??Ut(n,i)??document.createElement(e);return o===void 0&&(a.set(i,{count:0,element:s,ready:null}),J.set(s,{key:i,kind:r.kind})),s}function It(e){let t=X();if(t===null)return e;let n=Y(t),r=J.get(e);if(r===void 0){let t=d(v(e),t=>e.getAttribute(t));if(t===null)return e;r={key:m(t),kind:t.kind},J.set(e,r)}let i=n.get(r.key);return i!==void 0&&i.element!==e?(i.count+=1,Lt(t,i.element)):(i===void 0?n.set(r.key,{count:1,element:e,ready:null}):i.count+=1,Lt(t,e))}function Lt(e,t){return t.parentNode!==e&&e.appendChild(t),ct(t),t}function Y(e){let t=q.get(e);return t===void 0&&(t=new Map,q.set(e,t)),t}function Rt(e){let t=X(),n=J.get(e);if(t===null||n===void 0)return;let r=q.get(t),i=r?.get(n.key);if(i===void 0||i.element!==e){if(Vt(r,e))return;J.delete(e),Bt(n.kind)&&zt(e);return}i.count>0&&--i.count,!(i.count>0)&&Bt(n.kind)&&(r?.delete(n.key),J.delete(e),zt(e))}function zt(e){H(e),e.parentNode?.removeChild(e)}function Bt(e){return e===`title`||e===`meta`}function Vt(e,t){if(e===void 0)return!1;for(let n of e.values())if(n.element===t)return!0;return!1}function Ht(e,t,n){let r=v(e),i=f(r,n),a=J.get(e),o=i===null?null:m(i);if(o===null||a===void 0||o===a.key)return W(e,t,n),e;Rt(e);let s=X(),c=s===null?void 0:Y(s).get(o),l=c!==void 0&&c.count>0?c.element:void 0,u=Ft(r,n)??e;return u===e?(W(e,t,n),e):(l!==u&&W(u,{},n),It(u))}function X(){return typeof document<`u`&&document.head!==void 0?document.head:null}function Ut(e,t){for(let n of Array.from(e.childNodes)){if(!_(n))continue;let e=d(n.localName,e=>n.getAttribute(e));if(e!==null&&m(e)===t)return n}return null}function Wt(e){let t=X();if(t===null)return Promise.resolve();let n=Y(t),r=[];for(let i of e){if(!ee(i)||i.kind===`title`||i.kind===`meta`)continue;let e=Gt(i),a=m(e),o=n.get(a)?.element,s=(o!==void 0&&o.parentNode===t?o:null)??Ut(t,a);if(s!==null){let t=n.get(a);t?.element!==s&&(t={count:1,element:s,ready:null},n.set(a,t),J.set(s,{key:a,kind:e.kind}));let i=qt(e,t,a,n);i!==null&&r.push(i);continue}let c=Xt(e),l={count:1,element:c,ready:null},u=Kt(e)?Yt(c).then(()=>{n.get(a)===l&&(l.ready=null)}):null;l.ready=u,n.set(a,l),J.set(c,{key:a,kind:e.kind}),t.appendChild(c),u!==null&&r.push(u)}return r.length===0?Promise.resolve():Promise.all(r).then(()=>void 0)}function Gt(e){return e.kind===`font`?{as:`font`,crossOrigin:e.crossOrigin??`anonymous`,fetchPriority:e.fetchPriority,href:e.href,key:e.key,kind:`preload`,type:e.type}:e}function Kt(e){return e.kind!==`stylesheet`||e.blocking===`none`?!1:e.media===void 0||e.media===``||typeof matchMedia!=`function`||matchMedia(e.media).matches}function qt(e,t,n,r){if(!Kt(e))return null;if(t.ready!==null)return t.ready;if(!Jt(t.element))return null;let i=Yt(t.element).then(()=>{r.get(n)===t&&(t.ready=null)});return t.ready=i,i}function Jt(e){return e.localName===`link`&&e.getAttribute(`rel`)===`stylesheet`&&`sheet`in e&&e.sheet===null}function Yt(e){return new Promise(t=>{let n=()=>{e.removeEventListener(`load`,n),e.removeEventListener(`error`,n),t()};e.addEventListener(`load`,n),e.addEventListener(`error`,n)})}function Xt(e){let t=document.createElement(e.kind===`script`?`script`:`link`);for(let[n,r]of p(e))t.setAttribute(n,r===!0?``:r);return t}function Zt(e){if(!Q(e))return null;let t=Z(e);return t===null?null:Qt(e,t)}function Qt(e,t){let n=$t(e);return n===null?null:{end:n,forceClientRender:!1,id:t.id,start:e,get error(){return en(e)},get status(){return Z(e)?.status??t.status}}}function Z(e){if(!Q(e))return null;if(e.data===s)return{id:null,status:`completed`};if(e.data===o)return{id:null,status:`client-rendered`};let t=e.data.startsWith(l)?e.data.slice(l.length):null;return t!==null&&t!==``?{id:t,status:`pending`}:null}function $t(e){let t=0;for(let n=e.nextSibling;n!==null;n=n.nextSibling)if(Q(n)){if(Z(n)!==null){t+=1;continue}if(n.data===c){if(t===0)return n;--t}}return null}function en(e){let t=e.nextSibling;return cn(t)?{digest:t.dataset.dgst,message:t.dataset.msg}:null}function tn(e){if(!ln(e))return null;for(let t=e;t!==null;t=t.parentNode){let e=0;for(let n=t.previousSibling;n!==null;n=n.previousSibling)if(Q(n)){if(n.data===c){e+=1;continue}if(Z(n)!==null){if(e===0)return n;--e}}}return null}function nn(e,t){if(!ln(e))return!1;let n=t.start.parentNode,r=t.end.parentNode;if(n===null&&r===null)return!1;for(let i=e;i!==null;i=i.parentNode){if(i===t.start||i===t.end)return!1;if(n!==null&&i.parentNode===n)return rn(i,t.start,t.end);if(r!==null&&r!==n&&i.parentNode===r)return an(i,t.end)}return!1}function rn(e,t,n){for(let r=e;r!==null;r=r.previousSibling){if(r===t)return!0;if(r===n)return!1}return!1}function an(e,t){for(let n=e;n!==null;n=n.nextSibling)if(n===t)return!0;return!1}function on(e){for(let t=e.start;t!==null;){let n=t.nextSibling;if(sn(t),t===e.end)return;t=n}}function sn(e){e.parentNode?.removeChild(e)}function Q(e){return typeof e==`object`&&!!e&&`data`in e&&`nodeType`in e&&e.nodeType===8}function cn(e){return typeof e==`object`&&!!e&&`dataset`in e}function ln(e){return typeof e==`object`&&!!e&&`parentNode`in e}function un(e,t,n,r){let i=vn(e),a=i.startViewTransition;if(typeof a!=`function`)return!1;let o=!1,s=!1,c=!1,l=null,d=null,f=()=>{t();try{let e=a.call(i,()=>{o=!0,d=n(),d.cancelRootSnapshot&&(l=dn(i))});e!==void 0&&(pn(i,e),fn(i,e,()=>d));let t=e?.finished??e?.ready,s=()=>l?.();t===void 0?(s(),r()):((e?.ready??t).then(r,r),t.then(s,s))}catch(e){if(l?.(),!o){s?(o=!0,n()):c=!0,r();return}if(r(),!s)throw e;setTimeout(()=>{throw e})}},p=i[u],m=p?.finished??p?.ready;return p!=null&&m!==void 0?(s=!0,m.then(f,f),`deferred`):(f(),c?!1:o?`committed`:`deferred`)}function dn(e){let t=e.documentElement;if(t===null)return()=>void 0;let n=t.style,r=n.viewTransitionName??``;return n.viewTransitionName=`none`,()=>{n.viewTransitionName=r,t.getAttribute(`style`)===``&&t.removeAttribute(`style`)}}function fn(e,t,n){let r=[],i=()=>{for(let e of r)try{e.cancel()}catch{}r.length=0},a=()=>{let t=n();if(t===null||t.canceledNames.length===0&&!t.cancelRootSnapshot)return;let i=e.documentElement;if(i===null||typeof i.animate!=`function`)return;let a=e=>{typeof e?.cancel==`function`&&r.push(e)},o=e=>{a(i.animate?.({opacity:[0,0],pointerEvents:[`none`,`none`]},{duration:0,fill:`forwards`,pseudoElement:`::view-transition-group(${e})`}))};try{for(let e of t.canceledNames)o(yn(e));t.cancelRootSnapshot&&(o(`root`),a(i.animate({height:[0,0],width:[0,0]},{duration:0,fill:`forwards`,pseudoElement:`::view-transition`})))}catch{}},o=t.ready??t.finished;o===void 0?a():o.then(a,()=>void 0);let s=t.finished??t.ready;s===void 0?i():s.then(i,i)}function pn(e,t){e[u]=t;let n=()=>{e[u]===t&&(e[u]=null)},r=t.finished??t.ready;r===void 0?n():r.then(n,n)}function mn(e,t){let n=vn(e)[u],r=n?.finished??n?.ready;return n==null||r===void 0?!1:(r.then(t,t),!0)}function hn(e){if(typeof e.getBoundingClientRect!=`function`)return null;let t=e.getBoundingClientRect(),n=e.ownerDocument?.defaultView??null,r=n===null||t.bottom>=0&&t.right>=0&&t.top<=n.innerHeight&&t.left<=n.innerWidth,i=!1;try{i=n?.getComputedStyle(e).position===`absolute`}catch{}return{absolutelyPositioned:i,height:t.height,inViewport:r,width:t.width,x:t.left,y:t.top}}function gn(e,t,n){let r=e.style;r.viewTransitionName=yn(t),n!==null&&(r.viewTransitionClass=n)}function _n(e,t){let n=e.style,r=t.style,i=r?.viewTransitionName??r?.[`view-transition-name`],a=r?.viewTransitionClass??r?.[`view-transition-class`];n.viewTransitionName=bn(i),n.viewTransitionClass=bn(a)}function vn(e){return`ownerDocument`in e&&e.ownerDocument!==null?e.ownerDocument:document}function yn(e){let t=globalThis.CSS?.escape;return t===void 0?e:t(e)}function bn(e){return typeof e==`string`||typeof e==`number`?String(e).trim():``}const $=te({createInstance:(e,t,n)=>kn(e,t,n),createTextInstance:e=>document.createTextNode(e),validateInstanceNesting:(e,t,n)=>{},validateTextNesting:(e,t)=>{},containerType:e=>_(e)?v(e):null,appendInitialChild:(e,t)=>{e.appendChild(t),_(t)&&Rn(t)&&G(t,!0)},finalizeInitialInstance:(e,t)=>W(e,{},t,{initial:!0}),setTextContent:(e,t)=>{e.textContent!==t&&(e.textContent=t)},getFirstHydratableChild:(e,t)=>jn(e,t),getNextHydratableSibling:e=>Mn(e.nextSibling),canHydrateInstance:(e,t,n)=>On(e,t,n),canHydrateTextInstance:(e,t,n)=>Ln(e)&&(n===!0||e.nodeValue===t),isHoistedInstance:(e,t)=>f(e,t)!==null,commitHoistedInstance:e=>It(e),removeHoistedInstance:e=>Rt(e),updateHoistedInstance:(e,t,n)=>Ht(e,t,n),shouldCommitUpdate:(e,t,n)=>zn(e,n),clearContainer:e=>{let t=e.firstChild;for(;t!==null;){let n=t.nextSibling;H(t),e.removeChild(t),t=n}queueMicrotask(j)},insertBefore:(e,t,n)=>{e.insertBefore(t,n),_(t)&&Rn(t)&&G(t),ct(t)},removeChild:(e,t)=>{H(t),e.removeChild(t)},commitTextUpdate:(e,t)=>{e.nodeValue!==t&&(e.nodeValue=t)},commitUpdate:(e,t,n)=>W(e,t,n),commitHydratedInstance:(e,t)=>ut(e,t),getActivityBoundary:e=>Dn(e)?e:null,getFirstActivityHydratable:e=>Mn(En(e).firstChild??null),commitHydratedActivityBoundary:e=>{let t=e.parentNode;if(t===null)return;let n=En(e);for(;n.firstChild!==null;)t.insertBefore(n.firstChild,e);t.removeChild(e)},hideInstance:e=>{oe(e),e.style.setProperty(`display`,`none`,`important`)},unhideInstance:(e,t)=>{let n=(t.style??{}).display;e.style.setProperty(`display`,typeof n==`string`?n:``),se(e)},hideTextInstance:e=>{e.nodeValue=``},unhideTextInstance:(e,t)=>{e.nodeValue!==t&&(e.nodeValue=t)},getSuspenseBoundary:e=>Zt(e),getEnclosingSuspenseBoundaryStart:e=>tn(e),isTargetWithinSuspenseBoundary:(e,t)=>nn(e,t),registerSuspenseBoundaryRetry:(e,t)=>{e.start.__figRetry=t},commitHydratedSuspenseBoundary:e=>{e.status===`completed`&&!e.forceClientRender?(sn(e.start),sn(e.end)):on(e),queueMicrotask(j)},removeDehydratedSuspenseBoundary:e=>{on(e),queueMicrotask(j)},completeRootHydration:e=>{Ce(e),queueMicrotask(j)},preparePortalContainer:(e,t,n)=>{Ae(e,t,n)},removePortalContainer:e=>{A(e)},viewTransition:{commit:un,apply:gn,restore:_n,measure:hn,suspend:mn}});ve($.batchedUpdates),e($.scheduleRefresh);const xn=$.flushSync;function Sn(e,t){let n=$.createRoot(e,t);return ye(e,void 0,e=>n.data.run(e)),wn(n,e)}function Cn(e,t,n){let r=$.hydrateRoot(e,t,n);return ye(e,(t,n)=>$.hydrateTarget(e,t,n),e=>r.data.run(e)),wn(r,e)}function wn(e,t){return{...e,unmount:()=>{e.unmount(),Se(t)}}}function Tn(e,n,r=null){return t(e,n,r)}function En(e){return`content`in e?e.content:e}function Dn(e){return v(e)===`template`&&`getAttribute`in e&&e.getAttribute(n)!==null}function On(e,t,n){return!_(e)||!(`setAttribute`in e)||v(e)!==t.toLowerCase()?!1:In(e,n)}function kn(e,t,n){let r=Ft(e,t);if(r!==null)return r;let i=An(e,n);return i===`http://www.w3.org/1999/xhtml`?document.createElement(e):document.createElementNS(i,e)}function An(e,t){let n=e.toLowerCase();return n===`svg`?`http://www.w3.org/2000/svg`:n===`math`?`http://www.w3.org/1998/Math/MathML`:`namespaceURI`in t&&v(t)!==`foreignobject`?t.namespaceURI??`http://www.w3.org/1999/xhtml`:`http://www.w3.org/1999/xhtml`}function jn(e,t){return t!==void 0&&Fn(t)!==null||v(e)===`textarea`&&t!==void 0&&Pn(t)?null:Mn(e.firstChild)}function Mn(e){let t=e;for(;t!==null&&Nn(t);)t=t.nextSibling;return t}function Nn(e){return`nodeType`in e&&e.nodeType===8&&e.data===`,`}function Pn(e){return e.value!==void 0||e.defaultValue!==void 0}function Fn(e){return b(e.unsafeHTML)?null:e.unsafeHTML}function In(e,t){let n=Fn(t);return n===null||typeof n!=`string`||`innerHTML`in e}function Ln(e){return`nodeType`in e&&e.nodeType!==3?!1:!(`setAttribute`in e)&&`nodeValue`in e}function Rn(e){let t=v(e);return t===`option`||t===`optgroup`}function zn(e,t){return(e===`input`||e===`textarea`||e===`select`)&&(t.value!==void 0||t.checked!==void 0)}export{re as composeBind,Tn as createPortal,Sn as createRoot,xn as flushSync,Cn as hydrateRoot,Wt as insertAssetResources,Te as on};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["unsafeHTMLValue"],"sources":["../src/tree.ts","../src/bind.ts","../src/events.ts","../src/attachment.ts","../src/props.ts","../src/asset-resources.ts","../src/suspense-markers.ts","../src/view-transition.ts","../src/index.ts"],"sourcesContent":["export const htmlNamespace = \"http://www.w3.org/1999/xhtml\";\nexport const mathNamespace = \"http://www.w3.org/1998/Math/MathML\";\nexport const svgNamespace = \"http://www.w3.org/2000/svg\";\n\nexport function visitElementSubtree(\n node: Element | Text,\n visitor: (element: Element) => void,\n): void {\n if (isElementNode(node)) visitor(node);\n if (!(\"childNodes\" in node) || node.firstChild === null) return;\n\n for (const child of Array.from(node.childNodes)) {\n visitElementSubtree(child as Element | Text, visitor);\n }\n}\n\nexport function isElementNode(node: unknown): node is Element {\n return (\n typeof node === \"object\" &&\n node !== null &&\n \"nodeType\" in node &&\n node.nodeType === 1\n );\n}\n\nexport function elementName(node: unknown): string {\n if (!isElementNode(node)) return \"\";\n\n return \"localName\" in node && typeof node.localName === \"string\"\n ? node.localName.toLowerCase()\n : \"tagName\" in node && typeof node.tagName === \"string\"\n ? node.tagName.toLowerCase()\n : \"\";\n}\n\nexport function isHtmlElement(element: Element): boolean {\n return (\n !(\"namespaceURI\" in element) ||\n element.namespaceURI === null ||\n element.namespaceURI === htmlNamespace\n );\n}\n\n// Known limitation: the walk follows parentNode only and never hops shadow\n// boundaries (a ShadowRoot's parentNode is null, and there is no `.host`\n// fallback). Fig content rendered inside shadow trees is out of scope for\n// root resolution, delegated dispatch, and replay targeting; register the\n// in-shadow container as a portal target to route events explicitly.\nexport function parentOf(node: unknown): unknown {\n return typeof node === \"object\" && node !== null && \"parentNode\" in node\n ? node.parentNode\n : null;\n}\n\n// The shared \"absent prop\" predicate: null, undefined, and false all mean\n// \"not provided\" for prop-shaped values (bind, events, unsafeHTML,\n// attributes) — one authority so the prop kinds cannot drift.\nexport function isEmptyPropValue(value: unknown): boolean {\n return value === null || value === undefined || value === false;\n}\n","import { isEmptyPropValue } from \"./tree.ts\";\n\ndeclare const __FIG_DEV__: boolean | undefined;\n\nconst __DEV__ = typeof __FIG_DEV__ === \"boolean\" ? __FIG_DEV__ : false;\n\nexport type Bind<T extends Element = Element> = (\n node: T,\n signal: AbortSignal,\n) => void;\n\ninterface BindSlot {\n callback: Bind;\n controller: AbortController | null;\n // Persists for the slot's lifetime; gates the dev-only strict re-run to\n // the first attach so callback changes and re-attachments run single.\n strictRan: boolean;\n}\n\nconst bindSlots = new WeakMap<Element, BindSlot>();\n// Elements inside hidden Activity trees: binds must not run while hidden.\n// Keyed by element (not a slot flag) so a bind that first appears while its\n// element is already hidden is covered too.\nconst suspendedBindElements = new WeakSet<Element>();\n\nexport function composeBind<T extends Element = Element>(\n ...binds: Array<Bind<T> | false | null | undefined>\n): Bind<T> {\n const callbacks = binds.filter(\n (bind): bind is Bind<T> => typeof bind === \"function\",\n );\n\n return (node, signal) => {\n for (const bind of callbacks) bind(node, signal);\n };\n}\n\nexport function updateBind(element: Element, value: unknown): void {\n const callback = bindCallback(value);\n const slot = bindSlots.get(element);\n\n if (callback === null) {\n if (slot !== undefined) removeBindSlot(slot);\n bindSlots.delete(element);\n return;\n }\n\n if (slot === undefined) {\n const nextSlot: BindSlot = { callback, controller: null, strictRan: false };\n bindSlots.set(element, nextSlot);\n attachBindSlot(element, nextSlot);\n } else if (slot.callback !== callback) {\n removeBindSlot(slot);\n slot.callback = callback;\n attachBindSlot(element, slot);\n }\n}\n\nexport function attachElementBind(element: Element): void {\n const slot = bindSlots.get(element);\n if (slot !== undefined) attachBindSlot(element, slot);\n}\n\nexport function suspendBind(element: Element): void {\n suspendedBindElements.add(element);\n const slot = bindSlots.get(element);\n if (slot !== undefined) removeBindSlot(slot);\n}\n\nexport function resumeBind(element: Element): void {\n suspendedBindElements.delete(element);\n const slot = bindSlots.get(element);\n if (slot !== undefined) attachBindSlot(element, slot);\n}\n\nexport function detachElementBind(element: Element): void {\n const slot = bindSlots.get(element);\n if (slot !== undefined) {\n removeBindSlot(slot);\n bindSlots.delete(element);\n }\n}\n\nfunction attachBindSlot(element: Element, slot: BindSlot): void {\n if (\n slot.controller !== null ||\n element.parentNode === null ||\n suspendedBindElements.has(element)\n ) {\n return;\n }\n\n let runStrict = false;\n if (__DEV__) {\n // Marked before the callback so re-entrant attaches cannot re-enter the\n // strict cycle.\n runStrict = !slot.strictRan;\n slot.strictRan = true;\n }\n slot.controller = new AbortController();\n slot.callback(element, slot.controller.signal);\n if (__DEV__ && runStrict) {\n // Strict re-run: abort and re-invoke first-time binds so callbacks that\n // ignore their AbortSignal surface in development.\n removeBindSlot(slot);\n slot.controller = new AbortController();\n slot.callback(element, slot.controller.signal);\n }\n}\n\nfunction removeBindSlot(slot: BindSlot): void {\n slot.controller?.abort();\n slot.controller = null;\n}\n\nfunction bindCallback(value: unknown): Bind | null {\n if (isEmptyPropValue(value)) return null;\n if (typeof value === \"function\") return value as Bind;\n throw new Error(\"The bind prop must be a function.\");\n}\n","import {\n EARLY_EVENT_HANDLER_PROPERTY,\n EARLY_EVENT_QUEUE_PROPERTY,\n REPLAYABLE_EVENT_TYPES,\n} from \"@bgub/fig/internal\";\nimport {\n type EventPriority,\n type HydrationTargetResult,\n runWithEventPriority,\n} from \"@bgub/fig-reconciler\";\nimport {\n elementName,\n isElementNode,\n isEmptyPropValue,\n parentOf,\n} from \"./tree.ts\";\n\nexport type Container = Element | DocumentFragment;\nexport type EventOptions = Pick<AddEventListenerOptions, \"capture\" | \"passive\">;\nexport type EventCallback<E extends Event = Event> = (\n event: E,\n signal: AbortSignal,\n) => void;\ntype Batch = <T>(callback: () => T) => T;\ntype RootScope = <T>(callback: () => T) => T;\n\nexport interface EventDescriptor<E extends Event = Event> {\n readonly $$typeof: symbol;\n readonly type: string;\n readonly callback: EventCallback<E>;\n readonly options?: EventOptions;\n}\n\ninterface EventSlot {\n key: string;\n type: string;\n callback: EventCallback;\n options: Required<EventOptions>;\n controller: AbortController | null;\n element: Element | null;\n listener: EventListener | null;\n listenerTarget: Container | null;\n root: Container | null;\n}\ntype EventSlotList = Array<EventSlot | undefined>;\n\n// Snapshot of one handler invocation, extracted before any handler runs: a\n// re-entrant commit inside a handler may detach slots or swap callbacks\n// mid-dispatch, and listeners subscribed when the event fired must still\n// run exactly once with the fields they had at extraction.\ninterface DispatchEntry {\n callback: EventCallback;\n element: Element;\n root: Container | null;\n slot: EventSlot;\n type: string;\n}\n\n// Propagation is tracked per logical dispatch rather than on the event:\n// a queued replay must not inherit cancelBubble state a third-party\n// listener left on the spent native event.\ninterface PropagationState {\n immediateStopped: boolean;\n stopped: boolean;\n}\n\n// type/capture/passive are stored rather than re-parsed from the listener\n// key: event types may themselves contain the key separator (\":\").\ninterface RootListener {\n capture: boolean;\n count: number;\n listener: EventListener;\n passive: boolean;\n type: string;\n}\n\ninterface QueuedReplayableEvent {\n event: Event;\n // The logical dispatch origin (a portal target or the root), captured\n // while the target is still attached so replays keep portal bubbling.\n listenerTarget: Container | null;\n root: Container;\n type: string;\n}\n\ninterface PortalOwner {\n logicalParent: Container | Element;\n // The logical parent's listener target at registration time: the container\n // whose delegated keys this portal mirrors (an enclosing portal target, or\n // the root).\n parentTarget: Container;\n root: Container;\n}\n\n// One record per container that participates in event routing — a root, a\n// portal target, or both roles' delegated listener host. Keeping every\n// per-container datum here keeps registration, dispatch, and teardown\n// reading one structure.\ninterface ContainerRecord {\n hydrate: HydrationCallback | null;\n hydrationListeners: Array<readonly [string, EventListener]> | null;\n listeners: Map<string, RootListener>;\n portalOwner: PortalOwner | null;\n // Portal targets whose logical parent resolves to this container: this\n // container's delegated listener keys mirror onto them (cascading down\n // nested portals) so portal-inner events always have a dispatch point for\n // logical bubbling, even when no portal-inner handler shares the key.\n portals: Set<Container> | null;\n root: boolean;\n scope: RootScope | null;\n}\n\nconst EventDescriptorSymbol = Symbol.for(\"fig.event\");\nconst eventSlots = new WeakMap<Element, EventSlotList>();\nconst containerRecords = new WeakMap<Container, ContainerRecord>();\n// Keyed per (event, root): each root resolves selective hydration against\n// its own tree, so an outer root's \"none\" must not shadow a nested root's\n// \"blocked\". The inner WeakMap avoids retaining other roots' containers\n// while a queued replayable event keeps the native event alive.\nconst eventHydrationResults = new WeakMap<\n Event,\n WeakMap<Container, HydrationTargetResult>\n>();\nconst queuedReplayableEvents: QueuedReplayableEvent[] = [];\nconst discreteEvents = new Set([\n \"beforeinput\",\n \"blur\",\n \"change\",\n \"click\",\n \"contextmenu\",\n \"dblclick\",\n \"focus\",\n \"focusin\",\n \"focusout\",\n \"input\",\n \"keydown\",\n \"keyup\",\n \"mousedown\",\n \"mouseup\",\n \"pointerdown\",\n \"pointerup\",\n \"submit\",\n \"touchend\",\n \"touchstart\",\n]);\n// Shared with the server's inline early-event-capture script: both sides\n// must agree on which events queue for replay.\nconst replayableEvents = new Set<string>(REPLAYABLE_EVENT_TYPES);\nconst continuousEvents = new Set([\n \"drag\",\n \"dragover\",\n \"mousemove\",\n \"pointermove\",\n \"scroll\",\n \"touchmove\",\n \"wheel\",\n]);\nconst hydrationEvents = new Set([\n ...discreteEvents,\n ...continuousEvents,\n \"mouseenter\",\n \"mouseleave\",\n]);\n// Non-bubbling events attach directly to their element with native\n// semantics: a delegated bubble-phase root listener would never fire for\n// them in a real browser. focus/blur included — the platform's bubbling\n// variants are focusin/focusout, which delegate like any bubbling event, so\n// Fig does not emulate bubbling focus the way React does.\nconst nonDelegatedEvents = new Set([\n \"abort\",\n \"blur\",\n \"cancel\",\n \"canplay\",\n \"canplaythrough\",\n \"close\",\n \"durationchange\",\n \"emptied\",\n \"encrypted\",\n \"ended\",\n \"error\",\n \"focus\",\n \"invalid\",\n \"load\",\n \"loadeddata\",\n \"loadedmetadata\",\n \"loadstart\",\n \"mouseenter\",\n \"mouseleave\",\n \"pause\",\n \"play\",\n \"playing\",\n \"pointerenter\",\n \"pointerleave\",\n \"progress\",\n \"ratechange\",\n \"resize\",\n \"scroll\",\n \"scrollend\",\n \"seeked\",\n \"seeking\",\n \"stalled\",\n \"suspend\",\n \"timeupdate\",\n \"toggle\",\n \"volumechange\",\n \"waiting\",\n]);\nlet batch: Batch = (callback) => callback();\n\ntype HydrationCallback = (\n target: EventTarget | null,\n priority: EventPriority,\n) => HydrationTargetResult;\n\nexport function setEventBatching(nextBatch: Batch): void {\n batch = nextBatch;\n}\n\nexport function registerRoot(\n container: Container,\n hydrate?: HydrationCallback,\n scope?: RootScope,\n): void {\n const record = containerRecord(container);\n record.root = true;\n if (scope !== undefined) record.scope = scope;\n if (hydrate === undefined) return;\n\n record.hydrate = hydrate;\n ensureHydrationListeners(container, record);\n adoptEarlyEvents(container);\n}\n\ntype EarlyEventCarrier = Document & {\n [EARLY_EVENT_QUEUE_PROPERTY]?: Event[];\n [EARLY_EVENT_HANDLER_PROPERTY]?: EventListener;\n};\n\n// Events left over after each root claimed its own, kept per document so\n// later-hydrating roots (multiple containers on one page) still find theirs.\nconst unclaimedEarlyEvents = new WeakMap<Document, Event[]>();\n\n// The server's inline capture script queues replayable events that fired\n// before this bundle executed. Adopt them into the standard replay queue:\n// a discrete replay forces synchronous hydration of its target, so a\n// pre-bundle click on server-rendered content is honored as soon as the\n// drain microtask runs instead of being lost.\nfunction adoptEarlyEvents(root: Container): void {\n const carrier = (root.ownerDocument ?? root) as EarlyEventCarrier;\n let unclaimed = unclaimedEarlyEvents.get(carrier);\n\n if (unclaimed === undefined) {\n const queue = carrier[EARLY_EVENT_QUEUE_PROPERTY];\n if (!Array.isArray(queue)) return;\n\n const handler = carrier[EARLY_EVENT_HANDLER_PROPERTY];\n if (\n typeof handler === \"function\" &&\n typeof carrier.removeEventListener === \"function\"\n ) {\n for (const type of REPLAYABLE_EVENT_TYPES) {\n carrier.removeEventListener(type, handler, true);\n }\n }\n delete carrier[EARLY_EVENT_QUEUE_PROPERTY];\n delete carrier[EARLY_EVENT_HANDLER_PROPERTY];\n\n unclaimed = queue;\n unclaimedEarlyEvents.set(carrier, unclaimed);\n }\n\n let claimed = false;\n for (let index = 0; index < unclaimed.length;) {\n const event = unclaimed[index];\n if (\n replayableEvents.has(event.type) &&\n targetWithinRoot(root, event.target)\n ) {\n unclaimed.splice(index, 1);\n queueReplayableEvent(root, event.type, event);\n claimed = true;\n continue;\n }\n index += 1;\n }\n\n if (claimed) queueMicrotask(replayQueuedEvents);\n}\n\nexport function unregisterRoot(container: Container): void {\n const record = containerRecords.get(container);\n if (record === undefined) return;\n\n disableRootHydration(container);\n\n // Slot teardown normally empties this map before unmount finishes; sweep\n // whatever remains so no delegated listener outlives the root.\n for (const rootListener of record.listeners.values()) {\n container.removeEventListener(rootListener.type, rootListener.listener, {\n capture: rootListener.capture,\n });\n }\n\n // Portal teardown normally clears these during unmount; sweep stragglers\n // (nested portals hang off their parent target's record, so recurse).\n sweepPortals(container);\n\n containerRecords.delete(container);\n\n for (let index = queuedReplayableEvents.length - 1; index >= 0; index -= 1) {\n if (queuedReplayableEvents[index].root === container) {\n queuedReplayableEvents.splice(index, 1);\n }\n }\n}\n\nexport function disableRootHydration(container: Container): void {\n const record = containerRecords.get(container);\n if (record === undefined) return;\n\n record.hydrate = null;\n for (const [type, listener] of record.hydrationListeners ?? []) {\n container.removeEventListener(type, listener, { capture: true });\n }\n record.hydrationListeners = null;\n}\n\nfunction sweepPortals(target: Container): void {\n for (const portal of containerRecords.get(target)?.portals ?? []) {\n sweepPortals(portal);\n removePortalContainer(portal);\n }\n}\n\nfunction containerRecord(container: Container): ContainerRecord {\n let record = containerRecords.get(container);\n if (record === undefined) {\n record = {\n hydrate: null,\n hydrationListeners: null,\n listeners: new Map(),\n portalOwner: null,\n portals: null,\n root: false,\n scope: null,\n };\n containerRecords.set(container, record);\n }\n return record;\n}\n\n/**\n * Declares a listener for the `events` prop. Events keep their native\n * semantics: bubbling events are delegated through the Fig tree (including\n * portals), while non-bubbling events — `focus` and `blur` included — attach\n * directly to the element and fire only there. Fig does not emulate React's\n * bubbling `focus`/`blur`; to observe focus changes from an ancestor, use\n * the platform's bubbling variants, `focusin` and `focusout`.\n */\nexport function on<K extends keyof HTMLElementEventMap>(\n type: K,\n callback: EventCallback<HTMLElementEventMap[K]>,\n options?: EventOptions,\n): EventDescriptor<HTMLElementEventMap[K]>;\nexport function on<E extends Event = Event>(\n type: string,\n callback: EventCallback<E>,\n options?: EventOptions,\n): EventDescriptor<E>;\nexport function on(\n type: string,\n callback: EventCallback,\n options?: EventOptions,\n): EventDescriptor {\n return { $$typeof: EventDescriptorSymbol, type, callback, options };\n}\n\nexport function updateEvents(element: Element, value: unknown): void {\n const slots = eventSlotsFor(element);\n const descriptors = eventDescriptors(value, elementName(element));\n let location: EventLocation | null = null;\n\n for (let index = 0; index < descriptors.length; index += 1) {\n const descriptor = descriptors[index];\n if (descriptor === undefined) {\n const slot = slots[index];\n if (slot !== undefined) {\n removeEventSlot(slot);\n slots[index] = undefined;\n }\n continue;\n }\n\n const options = normalizedOptions(descriptor.options);\n const key = eventKey(descriptor.type, options);\n const slot = slots[index];\n\n if (slot === undefined) {\n location ??= eventLocationFor(element);\n slots[index] = addEventSlot(\n element,\n location.root,\n location.listenerTarget,\n descriptor,\n options,\n key,\n );\n } else if (slot.key !== key) {\n location ??= eventLocationFor(element);\n removeEventSlot(slot);\n slots[index] = addEventSlot(\n element,\n location.root,\n location.listenerTarget,\n descriptor,\n options,\n key,\n );\n } else if (slot.callback !== descriptor.callback) {\n slot.callback = descriptor.callback as EventCallback;\n }\n }\n\n for (let index = slots.length - 1; index >= descriptors.length; index -= 1) {\n const slot = slots[index];\n if (slot !== undefined) removeEventSlot(slot);\n }\n\n slots.length = descriptors.length;\n}\n\nexport function attachElementEvents(element: Element): void {\n const root = rootFor(element);\n const listenerTarget = listenerTargetFor(element);\n\n for (const slot of eventSlots.get(element) ?? []) {\n if (slot === undefined) continue;\n attachEventSlot(element, root, listenerTarget, slot);\n }\n}\n\nexport function detachElementEvents(element: Element): void {\n for (const slot of eventSlots.get(element) ?? []) {\n if (slot !== undefined) removeEventSlot(slot);\n }\n eventSlots.delete(element);\n}\n\n// Derived from listenerTargetFor so the two walks cannot disagree about\n// which container a node belongs to: the dispatch origin is the nearest\n// registered container, and its root is itself or its portal owner's root.\nexport function rootFor(\n node: Element | Text | Comment | Container,\n): Container | null {\n return eventLocationFor(node).root;\n}\n\ninterface EventLocation {\n listenerTarget: Container | null;\n root: Container | null;\n}\n\nfunction eventLocationFor(\n node: Element | Text | Comment | Container,\n): EventLocation {\n const listenerTarget = listenerTargetFor(node);\n if (listenerTarget === null) return { listenerTarget: null, root: null };\n\n const record = containerRecords.get(listenerTarget);\n return {\n listenerTarget,\n root:\n record?.portalOwner?.root ??\n (record?.root === true ? listenerTarget : null),\n };\n}\n\nexport function registerPortalContainer(\n container: Container,\n root: Container,\n logicalParent: Container | Element,\n): void {\n const record = containerRecord(container);\n const parentTarget = listenerTargetFor(logicalParent) ?? root;\n\n if (record.portalOwner !== null) {\n // Re-registration on a later commit: refresh the logical position; the\n // mirrors are already in place while the parent target is unchanged.\n if (\n record.portalOwner.root === root &&\n record.portalOwner.parentTarget === parentTarget\n ) {\n record.portalOwner = { logicalParent, parentTarget, root };\n return;\n }\n removePortalContainer(container);\n }\n\n record.portalOwner = {\n logicalParent,\n parentTarget,\n root,\n };\n\n const parentRecord = containerRecord(parentTarget);\n (parentRecord.portals ??= new Set()).add(container);\n // Mirror the logical parent target's active delegated keys (which already\n // include its own ancestors' mirrors) so events inside the portal have a\n // dispatch point for every handler along the logical ancestor chain.\n for (const mirrored of parentRecord.listeners.values()) {\n acquireRootListener(\n root,\n container,\n mirrored.type,\n mirrored.capture,\n mirrored.passive,\n );\n }\n}\n\nexport function removePortalContainer(container: Container): void {\n const record = containerRecords.get(container);\n const owner = record?.portalOwner ?? null;\n if (record === undefined || owner === null) return;\n\n record.portalOwner = null;\n\n const parentRecord = containerRecords.get(owner.parentTarget);\n if (parentRecord === undefined) return;\n parentRecord.portals?.delete(container);\n for (const key of parentRecord.listeners.keys()) {\n releaseRootListener(container, key);\n }\n}\n\nexport function replayQueuedEvents(): void {\n // Replays preserve the user's input order per root: a still-blocked entry\n // stalls later entries of ITS root only, so an independent root's\n // never-completing boundary cannot head-of-line block everyone else.\n const stalledRoots = new Set<Container>();\n\n for (let index = 0; index < queuedReplayableEvents.length;) {\n const queued = queuedReplayableEvents[index];\n\n // Liveness is checked against the logical dispatch origin: a portal\n // target lives outside the root container's DOM.\n const anchor = queued.listenerTarget ?? queued.root;\n if (!targetWithinRoot(anchor, queued.event.target)) {\n queuedReplayableEvents.splice(index, 1);\n continue;\n }\n\n // Attempt hydration even for stalled roots so later boundaries make\n // progress; only dispatch is withheld to keep ordering.\n if (hydrateQueuedEvent(queued) === \"blocked\") {\n stalledRoots.add(queued.root);\n index += 1;\n continue;\n }\n\n if (stalledRoots.has(queued.root)) {\n index += 1;\n continue;\n }\n\n queuedReplayableEvents.splice(index, 1);\n dispatchReplayedEvent(queued);\n }\n}\n\nfunction addEventSlot(\n element: Element,\n root: Container | null,\n listenerTarget: Container | null,\n descriptor: EventDescriptor,\n options: Required<EventOptions>,\n key: string,\n): EventSlot {\n const slot: EventSlot = {\n key,\n type: descriptor.type,\n callback: descriptor.callback as EventCallback,\n options,\n controller: null,\n element: null,\n listener: null,\n listenerTarget: null,\n root: null,\n };\n attachEventSlot(element, root, listenerTarget, slot);\n return slot;\n}\n\nfunction removeEventSlot(slot: EventSlot): void {\n detachEventSlot(slot);\n abortEventSlot(slot);\n}\n\nfunction dispatchRootEvent(\n root: Container,\n listenerTarget: Container,\n type: string,\n capture: boolean,\n passive: boolean,\n event: Event,\n): void {\n const targetListenerTarget = listenerTargetFor(event.target);\n if (targetListenerTarget !== listenerTarget) {\n const targetRecord =\n targetListenerTarget === null\n ? null\n : (containerRecords.get(targetListenerTarget) ?? null);\n if (targetRecord?.portalOwner?.root === root) return;\n if (!targetWithinRoot(listenerTarget, event.target)) return;\n }\n if (hydrateForEvent(root, type, event) === \"blocked\") return;\n\n const entries = extractDispatches(\n root,\n listenerTarget,\n type,\n capture,\n passive,\n event,\n );\n if (entries.length === 0) return;\n\n withPropagationState(event, false, (state) =>\n invokeDispatches(entries, event, state),\n );\n}\n\nfunction ensureHydrationListeners(\n root: Container,\n record: ContainerRecord,\n): void {\n if (record.hydrationListeners !== null) return;\n record.hydrationListeners = [];\n\n for (const type of hydrationEvents) {\n const listener = (event: Event) => hydrateForEvent(root, type, event);\n record.hydrationListeners.push([type, listener]);\n root.addEventListener(type, listener, {\n capture: true,\n passive: passiveHydrationEvent(type),\n });\n }\n}\n\nfunction hydrateForEvent(\n root: Container,\n type: string,\n event: Event,\n): HydrationTargetResult {\n const hydrate = containerRecords.get(root)?.hydrate ?? null;\n if (hydrate === null) return \"none\";\n\n let results = eventHydrationResults.get(event);\n const previousResult = results?.get(root);\n if (previousResult !== undefined) return previousResult;\n\n const priority = eventPriority(type);\n const result = runWithEventPriority(priority, () =>\n hydrate(event.target, priority),\n );\n if (results === undefined) {\n results = new WeakMap();\n eventHydrationResults.set(event, results);\n }\n results.set(root, result);\n\n // Queue only on the fresh computation: the capture hydration listener and\n // the delegated dispatch guard both land here for the same (event, root).\n if (result === \"blocked\" && replayableEvents.has(type)) {\n queueReplayableEvent(root, type, event);\n }\n\n return result;\n}\n\nfunction queueReplayableEvent(\n root: Container,\n type: string,\n event: Event,\n): void {\n queuedReplayableEvents.push({\n event,\n listenerTarget: listenerTargetFor(event.target),\n root,\n type,\n });\n}\n\nfunction hydrateQueuedEvent(\n queued: QueuedReplayableEvent,\n): HydrationTargetResult {\n const hydrate = containerRecords.get(queued.root)?.hydrate ?? null;\n if (hydrate === null) return \"none\";\n\n const priority = eventPriority(queued.type);\n return runWithEventPriority(priority, () =>\n hydrate(queued.event.target, priority),\n );\n}\n\n// Replays a queued event after selective hydration: the spent native event\n// no longer propagates, so one synthetic dispatch stands in for both phases\n// (`passive: null` matches every slot — no live root listener partitions\n// them by key here). The bubble phase extracts after capture handlers ran,\n// mirroring live DOM listener semantics; one propagation state spans both\n// phases, ignoring the spent event's stale cancelBubble.\nfunction dispatchReplayedEvent(queued: QueuedReplayableEvent): void {\n const { event, root, type } = queued;\n const listenerTarget = queued.listenerTarget ?? queued.root;\n\n withPropagationState(event, true, (state) => {\n invokeDispatches(\n extractDispatches(root, listenerTarget, type, true, null, event),\n event,\n state,\n );\n\n if (state.immediateStopped || state.stopped) return;\n\n invokeDispatches(\n extractDispatches(root, listenerTarget, type, false, null, event),\n event,\n state,\n );\n });\n}\n\nfunction extractDispatches(\n root: Container,\n listenerTarget: Container,\n type: string,\n capture: boolean,\n passive: boolean | null,\n event: Event,\n): DispatchEntry[] {\n const path = eventPath(root, listenerTarget, event);\n const entries: DispatchEntry[] = [];\n const step = capture ? -1 : 1;\n\n for (\n let index = capture ? path.length - 1 : 0;\n index >= 0 && index < path.length;\n index += step\n ) {\n const element = path[index];\n\n for (const slot of eventSlots.get(element) ?? []) {\n if (slot === undefined) continue;\n if (\n slot.root !== root ||\n slot.type !== type ||\n slot.options.capture !== capture ||\n (passive !== null && slot.options.passive !== passive)\n ) {\n continue;\n }\n\n entries.push({\n callback: slot.callback,\n element,\n root: slot.root,\n slot,\n type: slot.type,\n });\n }\n }\n\n return entries;\n}\n\nfunction invokeDispatches(\n entries: DispatchEntry[],\n event: Event,\n state: PropagationState,\n): void {\n let currentElement: Element | null = null;\n\n for (const entry of entries) {\n if (state.immediateStopped) return;\n\n // stopPropagation lets remaining handlers on the same element run and\n // skips every later element.\n if (entry.element !== currentElement) {\n if (currentElement !== null && state.stopped) return;\n currentElement = entry.element;\n }\n\n try {\n dispatchEventSlot(entry, event);\n } finally {\n // A slot detached mid-dispatch still ran — it was subscribed when the\n // event fired — but its signal must end aborted per the abort-on-removal\n // contract, even if the handler threw.\n const slot = entry.slot;\n if (slot.element === null && slot.listenerTarget === null) {\n abortEventSlot(slot);\n }\n }\n }\n}\n\nfunction dispatchEventSlot(entry: DispatchEntry, event: Event): void {\n const slot = entry.slot;\n abortEventSlot(slot);\n slot.controller = new AbortController();\n const signal = slot.controller.signal;\n\n batch(() => {\n runWithRootScope(entry.root, () =>\n runWithEventPriority(eventPriority(entry.type), () => {\n withCurrentTarget(event, entry.element, (currentEvent) => {\n entry.callback(currentEvent, signal);\n });\n }),\n );\n });\n}\n\nfunction runWithRootScope<T>(root: Container | null, callback: () => T): T {\n const scope =\n root === null ? null : (containerRecords.get(root)?.scope ?? null);\n return scope === null ? callback() : scope(callback);\n}\n\nfunction abortEventSlot(slot: EventSlot): void {\n slot.controller?.abort();\n slot.controller = null;\n}\n\nfunction eventDescriptors(\n value: unknown,\n elementType: string,\n): Array<EventDescriptor | undefined> {\n if (isEmptyPropValue(value)) return [];\n if (Array.isArray(value)) {\n const descriptors: Array<EventDescriptor | undefined> = [];\n for (const item of value) {\n if (isEmptyPropValue(item)) {\n descriptors.push(undefined);\n continue;\n }\n if (!isEventDescriptor(item)) {\n throwInvalidEventsProp(elementType);\n }\n descriptors.push(item);\n }\n return descriptors;\n }\n throwInvalidEventsProp(elementType);\n}\n\nfunction throwInvalidEventsProp(elementType: string): never {\n const target = elementType === \"\" ? \"an element\" : `<${elementType}>`;\n throw new Error(\n `The events prop on ${target} must be an array of event descriptors created with on(type, callback).`,\n );\n}\n\nfunction isEventDescriptor(value: unknown): value is EventDescriptor {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as EventDescriptor).$$typeof === EventDescriptorSymbol\n );\n}\n\nfunction eventSlotsFor(element: Element): EventSlotList {\n let slots = eventSlots.get(element);\n if (slots === undefined) {\n slots = [];\n eventSlots.set(element, slots);\n }\n return slots;\n}\n\nfunction attachEventSlot(\n element: Element,\n root: Container | null,\n listenerTarget: Container | null,\n slot: EventSlot,\n): void {\n if (direct(slot.type)) {\n attachDirectEventSlot(element, root, slot);\n } else {\n attachDelegatedEventSlot(root, listenerTarget, slot);\n }\n}\n\nfunction attachDirectEventSlot(\n element: Element,\n root: Container | null,\n slot: EventSlot,\n): void {\n // The root scopes dispatch (root.data.run and friends), same as the\n // delegated path. The first attach can run before insertion, when\n // rootFor() is still null, so a re-attach on the same element refreshes\n // the root without re-adding the DOM listener.\n if (slot.element === element) {\n if (root !== null) slot.root = root;\n return;\n }\n\n detachEventSlot(slot);\n slot.element = element;\n slot.root = root;\n slot.listener = (event) => {\n try {\n dispatchEventSlot(\n {\n callback: slot.callback,\n element,\n root: slot.root,\n slot,\n type: slot.type,\n },\n event,\n );\n } finally {\n if (slot.element === null && slot.listenerTarget === null) {\n abortEventSlot(slot);\n }\n }\n };\n element.addEventListener(slot.type, slot.listener, slot.options);\n}\n\nfunction attachDelegatedEventSlot(\n root: Container | null,\n listenerTarget: Container | null,\n slot: EventSlot,\n): void {\n if (\n root === null ||\n listenerTarget === null ||\n (slot.root === root && slot.listenerTarget === listenerTarget)\n ) {\n return;\n }\n\n detachEventSlot(slot);\n slot.root = root;\n slot.listenerTarget = listenerTarget;\n\n acquireRootListener(\n root,\n listenerTarget,\n slot.type,\n slot.options.capture,\n slot.options.passive,\n );\n}\n\nfunction acquireRootListener(\n root: Container,\n listenerTarget: Container,\n type: string,\n capture: boolean,\n passive: boolean,\n): void {\n const listeners = rootListenerMap(listenerTarget);\n const key = `${type}:${capture}:${passive}`;\n let rootListener = listeners.get(key);\n\n if (rootListener === undefined) {\n rootListener = {\n capture,\n count: 0,\n listener: (event) =>\n dispatchRootEvent(root, listenerTarget, type, capture, passive, event),\n passive,\n type,\n };\n listenerTarget.addEventListener(type, rootListener.listener, {\n capture,\n passive,\n });\n listeners.set(key, rootListener);\n\n // A key newly active on a target mirrors onto its portal targets\n // (cascading through nested portals) so portal-inner events dispatch\n // through the logical tree for it.\n for (const portal of containerRecords.get(listenerTarget)?.portals ?? []) {\n acquireRootListener(root, portal, type, capture, passive);\n }\n }\n\n rootListener.count += 1;\n}\n\nfunction releaseRootListener(listenerTarget: Container, key: string): void {\n const listeners = containerRecords.get(listenerTarget)?.listeners;\n const rootListener = listeners?.get(key);\n if (listeners === undefined || rootListener === undefined) return;\n\n rootListener.count -= 1;\n if (rootListener.count > 0) return;\n\n listenerTarget.removeEventListener(rootListener.type, rootListener.listener, {\n capture: rootListener.capture,\n });\n listeners.delete(key);\n\n // The key died on this target: drop its mirrors from the portal targets.\n for (const portal of containerRecords.get(listenerTarget)?.portals ?? []) {\n releaseRootListener(portal, key);\n }\n}\n\nfunction detachEventSlot(slot: EventSlot): void {\n detachDirectEventSlot(slot);\n detachDelegatedEventSlot(slot);\n}\n\nfunction detachDirectEventSlot(slot: EventSlot): void {\n if (slot.element === null || slot.listener === null) return;\n\n slot.element.removeEventListener(slot.type, slot.listener, {\n capture: slot.options.capture,\n });\n slot.element = null;\n slot.listener = null;\n slot.root = null;\n}\n\nfunction detachDelegatedEventSlot(slot: EventSlot): void {\n const listenerTarget = slot.listenerTarget;\n if (listenerTarget === null) return;\n\n slot.root = null;\n slot.listenerTarget = null;\n releaseRootListener(listenerTarget, rootListenerKey(slot));\n}\n\nfunction rootListenerMap(root: Container): Map<string, RootListener> {\n return containerRecord(root).listeners;\n}\n\nfunction rootListenerKey(slot: EventSlot): string {\n return `${slot.type}:${slot.options.capture}:${slot.options.passive}`;\n}\n\nfunction eventPath(\n root: Container,\n listenerTarget: Container,\n event: Event,\n): Element[] {\n const composedPath = event.composedPath?.();\n\n if (composedPath !== undefined) {\n const index = composedPath.indexOf(listenerTarget);\n if (index !== -1) {\n return [\n ...composedPath.slice(0, index).filter(isElementNode),\n ...logicalPortalPath(root, listenerTarget),\n ];\n }\n }\n\n const path: Element[] = [];\n for (let current: unknown = event.target; current !== listenerTarget;) {\n if (isElementNode(current)) path.push(current);\n current = parentOf(current);\n if (current === null) break;\n }\n\n return [...path, ...logicalPortalPath(root, listenerTarget)];\n}\n\nfunction logicalPortalPath(\n root: Container,\n listenerTarget: Container,\n): Element[] {\n const owner = containerRecords.get(listenerTarget)?.portalOwner ?? null;\n if (owner === null || owner.root !== root) return [];\n\n const path: Element[] = [];\n let cursor: unknown = owner.logicalParent;\n\n while (cursor !== null && cursor !== root) {\n // A portal container in the chain (nested portals): continue from its\n // logical parent; the target element itself is not a logical ancestor.\n if (isContainer(cursor)) {\n const hop = containerRecords.get(cursor)?.portalOwner ?? null;\n if (hop !== null && hop.root === root) {\n cursor = hop.logicalParent;\n continue;\n }\n }\n\n if (isElementNode(cursor)) path.push(cursor);\n cursor = parentOf(cursor);\n }\n\n return path;\n}\n\nfunction targetWithinRoot(\n root: Container,\n target: EventTarget | null,\n): boolean {\n for (let current: unknown = target; current !== null;) {\n if (current === root) return true;\n current = parentOf(current);\n }\n\n return false;\n}\n\nfunction listenerTargetFor(node: EventTarget | null): Container | null {\n for (let current: unknown = node; current !== null;) {\n if (isContainer(current)) {\n const record = containerRecords.get(current);\n if (\n record !== undefined &&\n (record.portalOwner !== null || record.root)\n ) {\n return current;\n }\n }\n\n current = parentOf(current);\n }\n\n return null;\n}\n\nfunction withCurrentTarget<T>(\n event: Event,\n currentTarget: Element,\n callback: (event: Event) => T,\n): T {\n const previous = Object.getOwnPropertyDescriptor(event, \"currentTarget\");\n const changed = Reflect.defineProperty(event, \"currentTarget\", {\n configurable: true,\n value: currentTarget,\n });\n\n try {\n return callback(event);\n } finally {\n if (changed) {\n if (previous === undefined) {\n delete (event as unknown as { currentTarget?: EventTarget | null })\n .currentTarget;\n } else {\n Object.defineProperty(event, \"currentTarget\", previous);\n }\n }\n }\n}\n\n// Runs one logical dispatch with its own propagation state: the stop\n// methods and the legacy cancelBubble property are patched (save/restore,\n// so nested dispatches of other events are isolated) to record into the\n// state while still driving the natives. Replays set\n// `ignoreExistingCancelBubble`: a spent event's stale cancelBubble must not\n// drop the replay, while a LIVE dispatch honors cancelBubble a sibling root\n// listener's handler already set. Stops made DURING the dispatch — method\n// calls or `event.cancelBubble = true` assignments — are observed either\n// way via the patches.\nfunction withPropagationState<T>(\n event: Event,\n ignoreExistingCancelBubble: boolean,\n callback: (state: PropagationState) => T,\n): T {\n const existingCancelBubble = event.cancelBubble === true;\n const state: PropagationState = {\n immediateStopped: false,\n stopped: !ignoreExistingCancelBubble && existingCancelBubble,\n };\n\n const restoreStop = patchEventMethod(event, \"stopPropagation\", () => {\n state.stopped = true;\n });\n const restoreImmediate = patchEventMethod(\n event,\n \"stopImmediatePropagation\",\n () => {\n state.stopped = true;\n state.immediateStopped = true;\n },\n );\n const restoreCancelBubble = patchCancelBubble(event, state);\n\n try {\n return callback(state);\n } finally {\n restoreCancelBubble();\n restoreImmediate();\n restoreStop();\n // Reflect a stop from this dispatch onto the real event once the\n // patches are gone (a legacy assignment only reached the shadow).\n if (state.stopped) event.cancelBubble = true;\n }\n}\n\nfunction patchCancelBubble(event: Event, state: PropagationState): () => void {\n const previous = Object.getOwnPropertyDescriptor(event, \"cancelBubble\");\n const changed = Reflect.defineProperty(event, \"cancelBubble\", {\n configurable: true,\n // `stopped` is seeded from the effective pre-existing value (ignored\n // for replays), so reads reflect THIS dispatch: a replay handler must\n // not observe the spent event's stale stop state.\n get: () => state.stopped,\n set(value: unknown) {\n // Per spec, assigning false does nothing.\n if (value === true) state.stopped = true;\n },\n });\n\n return () => {\n if (!changed) return;\n if (previous === undefined) {\n delete (event as unknown as Record<string, unknown>).cancelBubble;\n } else {\n Object.defineProperty(event, \"cancelBubble\", previous);\n }\n };\n}\n\nfunction patchEventMethod(\n event: Event,\n name: \"stopImmediatePropagation\" | \"stopPropagation\",\n onCall: () => void,\n): () => void {\n const native = Reflect.get(event, name);\n if (typeof native !== \"function\") return () => undefined;\n\n const previous = Object.getOwnPropertyDescriptor(event, name);\n const changed = Reflect.defineProperty(event, name, {\n configurable: true,\n value() {\n onCall();\n native.call(event);\n },\n });\n\n return () => {\n if (!changed) return;\n if (previous === undefined) {\n delete (event as unknown as Record<string, unknown>)[name];\n } else {\n Object.defineProperty(event, name, previous);\n }\n };\n}\n\nfunction normalizedOptions(options: EventOptions = {}): Required<EventOptions> {\n return {\n capture: options.capture === true,\n passive: options.passive === true,\n };\n}\n\nfunction eventKey(type: string, options: Required<EventOptions>): string {\n return `${type}:${options.capture}:${options.passive}`;\n}\n\nfunction eventPriority(type: string): EventPriority {\n if (discreteEvents.has(type)) return \"discrete\";\n if (continuousEvents.has(type)) return \"continuous\";\n return \"default\";\n}\n\nfunction passiveHydrationEvent(type: string): boolean {\n // Hydration listeners never call preventDefault, so scroll-blocking touch\n // events can stay passive alongside the continuous set.\n return (\n continuousEvents.has(type) || type === \"touchstart\" || type === \"touchend\"\n );\n}\n\nfunction direct(type: string): boolean {\n return nonDelegatedEvents.has(type);\n}\n\nfunction isContainer(node: unknown): node is Container {\n return (\n typeof node === \"object\" &&\n node !== null &&\n \"addEventListener\" in node &&\n \"childNodes\" in node\n );\n}\n","import { attachElementBind, detachElementBind } from \"./bind.ts\";\nimport { attachElementEvents, detachElementEvents } from \"./events.ts\";\nimport { visitElementSubtree } from \"./tree.ts\";\n\n// Bind and event state always attach and detach together when DOM moves in\n// or out of the live tree; a single walk keeps that pairing unforgettable\n// (a hook calling one without the other leaks signals or listeners) and\n// halves the traversal per insertion/removal.\n\nexport function attachSubtree(node: Element | Text): void {\n visitElementSubtree(node, (element) => {\n attachElementBind(element);\n attachElementEvents(element);\n });\n}\n\nexport function detachSubtree(node: Element | Text): void {\n visitElementSubtree(node, (element) => {\n detachElementBind(element);\n detachElementEvents(element);\n });\n}\n","import type { Props } from \"@bgub/fig\";\nimport { updateBind } from \"./bind.ts\";\nimport { updateEvents } from \"./events.ts\";\nimport {\n elementName,\n isElementNode,\n isEmptyPropValue,\n isHtmlElement,\n} from \"./tree.ts\";\n\ndeclare const __FIG_DEV__: boolean | undefined;\n\nconst __DEV__ = typeof __FIG_DEV__ === \"boolean\" ? __FIG_DEV__ : false;\n\ninterface SelectState {\n appliedDefault: boolean;\n applyDefaultToInsertedOptions: boolean;\n controlled: boolean;\n selectedValues: ReadonlySet<string>;\n value: unknown;\n}\n\ninterface UpdateOptions {\n hydrating?: boolean;\n // The instance's first render: the only time defaultValue/defaultChecked\n // may live-write the element's value/checked state.\n initial?: boolean;\n}\n\ntype StyleTarget = Record<string, unknown> & {\n readonly length?: number;\n item?: (index: number) => string;\n removeProperty?: (name: string) => void;\n setProperty?: (name: string, value: string) => void;\n};\n\nconst selectState = new WeakMap<Element, SelectState>();\nconst xlinkNamespace = \"http://www.w3.org/1999/xlink\";\n\nexport function updateElement(\n element: Element,\n previousProps: Props,\n nextProps: Props,\n options: UpdateOptions = {},\n): void {\n const type = elementName(element);\n const html = isHtmlElement(element);\n const names = new Set([\n ...Object.keys(previousProps),\n ...Object.keys(nextProps),\n ]);\n\n for (const name of names) {\n if (name === \"events\") {\n updateEvents(element, nextProps[name]);\n continue;\n }\n\n if (name === \"bind\") {\n updateBind(element, nextProps[name]);\n continue;\n }\n\n const previous = previousProps[name];\n const next = nextProps[name];\n\n if (name === \"unsafeHTML\") {\n if (options.hydrating === true) {\n unsafeHTMLValue(next);\n continue;\n }\n if (previous !== next) setUnsafeHTML(element, next);\n continue;\n }\n\n if (reserved(name)) {\n if (__DEV__ && event(name)) {\n warnDroppedProp(name, eventPropWarning(name, type, nextProps));\n }\n continue;\n }\n\n if (formProp(name)) {\n if (\n __DEV__ &&\n (name === \"checked\" || name === \"defaultChecked\") &&\n next !== undefined &&\n typeof next !== \"boolean\" &&\n next !== null\n ) {\n warnDroppedProp(\n `${name}:${typeof next}`,\n `The \"${name}\" prop received a ${typeof next} (${String(next)}); ` +\n \"Fig treats only `true` as checked, so this renders unchecked.\",\n );\n }\n setFormProperty(element, type, name, next, nextProps, options);\n continue;\n }\n\n if (previous === next) continue;\n if (name === \"style\") {\n if (__DEV__ && typeof next === \"string\" && next !== \"\") {\n warnDroppedProp(\n \"style:string\",\n \"The style prop must be an object of properties; string styles \" +\n \"are ignored.\",\n );\n }\n setStyle(element, previous, next);\n } else setAttribute(element, hostAttributeName(name, html), next);\n }\n\n updateSelectOptions(element, type, previousProps, nextProps, options);\n // Only option updates (value/text) can change which option a parent\n // select's stored value matches; skip the ancestor walk for everything\n // else.\n if (type === \"option\" || type === \"optgroup\") updateParentSelect(element);\n}\n\n// Dev-only, deduped by key: silently dropping a prop the author clearly\n// intended (onClick, checked={1}, string styles) is the worst failure mode —\n// nothing renders wrong, the behavior just never happens.\nconst warnedDroppedProps = new Set<string>();\n\nfunction warnDroppedProp(key: string, message: string): void {\n if (warnedDroppedProps.has(key)) return;\n warnedDroppedProps.add(key);\n console.error(message);\n}\n\nfunction eventPropWarning(name: string, type: string, props: Props): string {\n // A trailing \"Capture\" is React's capture-phase suffix, except when it is\n // part of the event name itself (onGotPointerCapture/onLostPointerCapture\n // are bubble-phase props for gotpointercapture/lostpointercapture) or is\n // the entire name (an \"onCapture\" prop would leave an empty event name).\n const capture =\n name.endsWith(\"Capture\") &&\n name.length > \"onCapture\".length &&\n name !== \"onGotPointerCapture\" &&\n name !== \"onLostPointerCapture\";\n const rawName = name.slice(2, capture ? -\"Capture\".length : undefined);\n const options = capture ? \", { capture: true }\" : \"\";\n const suggest = (eventName: string) =>\n `Fig has no \"${name}\" event props; use ` +\n `events={[on(\"${eventName}\", handler${options})]} instead.`;\n\n if (rawName === \"DoubleClick\") return suggest(\"dblclick\");\n if (rawName === \"Change\" && reactChangeUsesInputEvent(type, props)) {\n return (\n suggest(\"input\") +\n ` (React's onChange on text-editing controls fires per change like the` +\n ` native \"input\" event; on(\"change\") fires only on commit.)`\n );\n }\n return suggest(rawName.toLowerCase());\n}\n\n// React backs onChange on text-editing controls with the native \"input\"\n// event; only checkbox/radio/file inputs (and selects) match the native\n// \"change\" timing, so everything else steers to on(\"input\").\nfunction reactChangeUsesInputEvent(type: string, props: Props): boolean {\n if (type === \"textarea\") return true;\n if (type !== \"input\") return false;\n const inputType = typeof props.type === \"string\" ? props.type : \"text\";\n return (\n inputType !== \"checkbox\" && inputType !== \"radio\" && inputType !== \"file\"\n );\n}\n\nexport function hydrateElement(element: Element, nextProps: Props): void {\n // Snapshot before the update applies: updateElement writes the client\n // style prop into the same declaration and runs the bind callback (which\n // may set attributes), so a post-update enumeration could not tell\n // server-set names from client-set ones.\n const serverStyles = __DEV__ ? hydratedStyleNames(element) : [];\n const serverAttributes = __DEV__ ? attributeNames(element) : [];\n\n updateElement(element, {}, nextProps, { hydrating: true });\n\n if (__DEV__ && nextProps.suppressHydrationWarning !== true) {\n warnExtraHydratedAttributes(\n element,\n nextProps,\n serverStyles,\n serverAttributes,\n );\n }\n}\n\n// Server-only attributes and styles are preserved (extensions and internal\n// markers make removal unsafe), so surface the divergence from a pure client\n// render as a dev warning instead.\nfunction warnExtraHydratedAttributes(\n element: Element,\n nextProps: Props,\n serverStyles: readonly string[],\n serverAttributes: readonly string[],\n): void {\n if (serverAttributes.length === 0 && serverStyles.length === 0) return;\n\n const expectedAttributes = new Set<string>();\n const type = elementName(element);\n const html = isHtmlElement(element);\n\n for (const name of Object.keys(nextProps)) {\n if (name === \"events\" || name === \"bind\" || reserved(name)) continue;\n\n const attribute = hydratedAttributeName(type, name, html);\n if (attribute !== null) expectedAttributes.add(attribute);\n }\n\n const extra: string[] = [];\n for (const name of serverAttributes) {\n const attribute = hostAttributeName(name, html);\n if (attribute.startsWith(\"data-fig-\")) continue;\n if (!expectedAttributes.has(attribute)) extra.push(name);\n }\n\n extra.push(...extraHydratedStyleNames(serverStyles, nextProps.style));\n\n if (extra.length === 0) return;\n\n console.error(\n `Hydration preserved extra server attributes or styles on <${type}>: ` +\n `${extra.sort().join(\", \")}. They were preserved, so this element now ` +\n \"differs from a pure client render.\",\n );\n}\n\n// Writing the client style prop to a scratch declaration routes both name\n// sets through the same CSSOM canonicalization (shorthand expansion, name\n// casing), so server-set and client-produced names compare directly.\nfunction extraHydratedStyleNames(\n serverStyles: readonly string[],\n next: unknown,\n): string[] {\n if (serverStyles.length === 0) return [];\n\n const scratch = document.createElement(\"div\");\n setStyle(scratch, {}, next);\n const expected = new Set(hydratedStyleNames(scratch));\n\n return serverStyles\n .filter((name) => !expected.has(name))\n .map((name) => `style.${name}`);\n}\n\nfunction hydratedStyleNames(element: Element): string[] {\n const style = (element as HTMLElement).style as unknown as\n | StyleTarget\n | undefined;\n if (style === undefined) return [];\n\n if (typeof style.length === \"number\" && typeof style.item === \"function\") {\n const names: string[] = [];\n for (let index = 0; index < style.length; index += 1) {\n const name = style.item(index);\n if (name !== \"\") names.push(name);\n }\n return names;\n }\n\n return Object.keys(style).filter((name) => style[name] !== \"\");\n}\n\nfunction hydratedAttributeName(\n type: string,\n name: string,\n html: boolean,\n): string | null {\n if ((type === \"textarea\" || type === \"select\") && valueProp(name)) {\n return null;\n }\n\n if (name === \"defaultValue\") return \"value\";\n if (name === \"defaultChecked\") return \"checked\";\n return hostAttributeName(name, html);\n}\n\nfunction attributeNames(element: Element): string[] {\n const attributes = element.attributes as\n | (NamedNodeMap & Iterable<Attr>)\n | Record<string, unknown>\n | undefined;\n\n if (attributes === undefined) return [];\n\n if (\n \"length\" in attributes &&\n typeof attributes.length === \"number\" &&\n \"item\" in attributes &&\n typeof attributes.item === \"function\"\n ) {\n const names: string[] = [];\n for (let index = 0; index < attributes.length; index += 1) {\n const attribute = attributes.item(index);\n if (attribute !== null) names.push(attribute.name);\n }\n return names;\n }\n\n if (Symbol.iterator in attributes) {\n return Array.from(\n attributes as Iterable<Attr>,\n (attribute) => attribute.name,\n );\n }\n\n return Object.keys(attributes);\n}\n\nfunction setFormProperty(\n element: Element,\n type: string,\n name: string,\n next: unknown,\n nextProps: Props,\n options: UpdateOptions,\n): void {\n if (type === \"select\" && valueProp(name)) return;\n if (type === \"option\" && name === \"value\") {\n setAttribute(element, \"value\", formValue(next));\n return;\n }\n\n // Defaults live-write only on the instance's very first render (and never\n // during hydration, or when a controlling sibling prop wins): a\n // defaultValue/defaultChecked that APPEARS on a later update must not\n // clobber what the user typed or toggled since mount.\n const initial = options.initial === true && options.hydrating !== true;\n\n if (name === \"value\") {\n if (isEmptyPropValue(next)) return;\n setFormValue(element, next, type, { live: true });\n } else if (name === \"defaultValue\") {\n setFormValue(element, next, type, {\n defaultValue: true,\n live: initial && nextProps.value === undefined,\n });\n } else if (name === \"checked\") {\n if (next === undefined) return;\n setChecked(element, next, { live: true });\n } else if (name === \"defaultChecked\") {\n setChecked(element, next, {\n defaultChecked: true,\n live: initial && nextProps.checked === undefined,\n });\n }\n}\n\nfunction setFormValue(\n element: Element,\n value: unknown,\n type: string,\n options: { defaultValue?: boolean; live?: boolean },\n): void {\n const textArea = type === \"textarea\";\n const next = formValue(value);\n\n if (options.defaultValue === true && \"defaultValue\" in element) {\n (element as unknown as { defaultValue: string }).defaultValue = next ?? \"\";\n }\n if (options.defaultValue === true) {\n if (textArea) {\n element.textContent = next ?? \"\";\n } else {\n setAttribute(element, \"value\", next);\n }\n }\n\n if (options.live === true && \"value\" in element) {\n if ((element as unknown as { value: string }).value !== (next ?? \"\")) {\n (element as unknown as { value: string }).value = next ?? \"\";\n }\n } else if (options.live === true && next !== null) {\n setAttribute(element, \"value\", next);\n }\n}\n\nfunction formValue(value: unknown): string | null {\n return isEmptyPropValue(value) ? null : String(value);\n}\n\nfunction setChecked(\n element: Element,\n value: unknown,\n options: { defaultChecked?: boolean; live?: boolean },\n): void {\n const checked = value === true;\n\n // The checked content attribute IS defaultChecked's reflection, so only\n // the defaultChecked prop may touch it — a controlled `checked` writes the\n // live property alone, mirroring value/defaultValue above.\n if (options.defaultChecked === true) {\n if (\"defaultChecked\" in element) {\n (element as unknown as { defaultChecked: boolean }).defaultChecked =\n checked;\n }\n setAttribute(element, \"checked\", checked);\n }\n\n if (options.live === true && \"checked\" in element) {\n (element as unknown as { checked: boolean }).checked = checked;\n } else if (options.live === true) {\n setAttribute(element, \"checked\", checked);\n }\n}\n\nfunction setUnsafeHTML(element: Element, value: unknown): void {\n const html = unsafeHTMLValue(value);\n if (!(\"innerHTML\" in element)) return;\n\n (element as unknown as { innerHTML: string }).innerHTML = html ?? \"\";\n}\n\nfunction unsafeHTMLValue(value: unknown): string | null {\n if (isEmptyPropValue(value)) return null;\n if (typeof value === \"string\") return value;\n throw new Error(\"The unsafeHTML prop must be a string.\");\n}\n\nfunction updateSelectOptions(\n element: Element,\n type: string,\n previousProps: Props,\n nextProps: Props,\n options: UpdateOptions = {},\n): void {\n if (type !== \"select\") return;\n\n const controlled = nextProps.value !== undefined;\n const value = controlled ? nextProps.value : nextProps.defaultValue;\n if (value === undefined || value === null || value === false) {\n selectState.delete(element);\n return;\n }\n\n // A hydrating uncontrolled select trusts the server DOM's selection (the\n // user may have changed it before JS loaded); record the default as\n // applied so later updates don't re-apply it either. Controlled selects\n // still re-assert their value.\n const hydratingDefault = !controlled && options.hydrating === true;\n\n const state = selectState.get(element);\n const shouldApply =\n !hydratingDefault &&\n (controlled || (!controlled && options.initial === true));\n const nextState = {\n appliedDefault: state?.appliedDefault === true || !controlled,\n applyDefaultToInsertedOptions:\n !hydratingDefault && !controlled && options.initial === true,\n controlled,\n selectedValues: selectValues(value),\n value,\n };\n selectState.set(element, nextState);\n if (!shouldApply) return;\n\n setSelectValue(element, nextState.selectedValues);\n}\n\nexport function updateParentSelect(\n element: Element,\n applyDefault = false,\n): void {\n const select = closestParentSelect(element);\n if (select === null) return;\n\n const state = selectState.get(select);\n if (state === undefined) return;\n if (!state.controlled && state.appliedDefault && !applyDefault) return;\n if (\n !state.controlled &&\n applyDefault &&\n !state.applyDefaultToInsertedOptions\n ) {\n return;\n }\n\n setSelectValue(element, state.selectedValues);\n if (!state.controlled) {\n state.appliedDefault = true;\n }\n}\n\nfunction selectValues(value: unknown): ReadonlySet<string> {\n return new Set(Array.isArray(value) ? value.map(String) : [String(value)]);\n}\n\nfunction setSelectValue(element: Element, values: ReadonlySet<string>): void {\n if (elementName(element) === \"option\") {\n setOptionSelected(element, values);\n return;\n }\n\n forEachDescendantOption(element, (option) => {\n setOptionSelected(option, values);\n });\n}\n\nfunction setOptionSelected(option: Element, values: ReadonlySet<string>): void {\n (option as unknown as { selected: boolean }).selected = values.has(\n currentOptionValue(option),\n );\n}\n\nfunction closestParentSelect(element: Element): Element | null {\n let parent: Node | null = element.parentNode;\n while (parent !== null) {\n if (isElementNode(parent) && elementName(parent) === \"select\") {\n return parent;\n }\n parent = parent.parentNode;\n }\n\n return null;\n}\n\nfunction forEachDescendantOption(\n element: Element,\n visitor: (option: Element) => void,\n): void {\n for (let child = element.firstChild; child !== null;) {\n const next = child.nextSibling;\n if (isElementNode(child)) {\n if (elementName(child) === \"option\") {\n visitor(child);\n } else {\n forEachDescendantOption(child, visitor);\n }\n }\n child = next;\n }\n}\n\nfunction currentOptionValue(option: Element): string {\n const value = attributeValue(option, \"value\");\n if (value !== null) return value;\n\n // Spec-ish option.text: pretty-printed markup collapses to the visible\n // label, so implicit values match their authored form.\n return (option.textContent ?? \"\").replace(/\\s+/g, \" \").trim();\n}\n\nfunction attributeValue(element: Element, name: string): string | null {\n return element.getAttribute(name);\n}\n\nfunction setStyle(element: Element, previous: unknown, next: unknown): void {\n const style = (element as HTMLElement).style as unknown as\n | StyleTarget\n | undefined;\n if (style === undefined) return;\n\n const previousStyle = styleProps(previous);\n const nextStyle = styleProps(next);\n\n for (const name of Object.keys(previousStyle)) {\n if (!(name in nextStyle)) clearStyleProperty(style, name);\n }\n\n for (const [name, value] of Object.entries(nextStyle)) {\n if (value === null || value === undefined || value === false) {\n clearStyleProperty(style, name);\n } else {\n setStyleProperty(style, name, value);\n }\n }\n}\n\nfunction styleProps(value: unknown): Record<string, unknown> {\n return typeof value === \"object\" && value !== null\n ? (value as Record<string, unknown>)\n : {};\n}\n\nfunction setStyleProperty(\n style: StyleTarget,\n name: string,\n value: unknown,\n): void {\n if (typeof value === \"number\" || typeof value === \"bigint\") {\n if (__DEV__) {\n warnDroppedProp(\n `style:${name}:${typeof value}`,\n `The style property \"${name}\" received a ${typeof value} ` +\n `(${String(value)}); Fig style values must be strings, so this ` +\n \"style is ignored.\",\n );\n }\n return;\n }\n\n if (name.startsWith(\"--\") && typeof style.setProperty === \"function\") {\n style.setProperty(name, String(value));\n } else {\n style[name] = value;\n }\n}\n\nfunction clearStyleProperty(style: StyleTarget, name: string): void {\n if (name.startsWith(\"--\") && typeof style.removeProperty === \"function\") {\n style.removeProperty(name);\n } else {\n style[name] = \"\";\n }\n}\n\nfunction hostAttributeName(name: string, html: boolean): string {\n return html ? name.toLowerCase() : name;\n}\n\nfunction setAttribute(\n element: Element,\n attribute: string,\n value: unknown,\n): void {\n if (isEmptyPropValue(value)) {\n removeAttribute(element, attribute);\n return;\n }\n\n if (attribute === \"xlink:href\") {\n element.setAttributeNS(xlinkNamespace, attribute, String(value));\n return;\n }\n\n element.setAttribute(attribute, String(value));\n}\n\nfunction removeAttribute(element: Element, attribute: string): void {\n if (attribute === \"xlink:href\") {\n element.removeAttributeNS(xlinkNamespace, \"href\");\n return;\n }\n\n element.removeAttribute(attribute);\n}\n\nfunction formProp(name: string): boolean {\n return valueProp(name) || name === \"checked\" || name === \"defaultChecked\";\n}\n\nfunction valueProp(name: string): boolean {\n return name === \"value\" || name === \"defaultValue\";\n}\n\nfunction reserved(name: string): boolean {\n return (\n name === \"children\" ||\n name === \"key\" ||\n name === \"suppressHydrationWarning\" ||\n name === \"unsafeHTML\" ||\n event(name)\n );\n}\n\nfunction event(name: string): boolean {\n return /^on[A-Z]/.test(name);\n}\n","import { type FigAssetResource, type Props } from \"@bgub/fig\";\nimport {\n assetResourceFromHostAttributes,\n assetResourceFromHostProps,\n assetResourceHostAttributes,\n assetResourceKey,\n isFigAssetResource,\n} from \"@bgub/fig/internal\";\nimport { attachSubtree, detachSubtree } from \"./attachment.ts\";\nimport { updateElement } from \"./props.ts\";\nimport { elementName, isElementNode } from \"./tree.ts\";\n\n// The document/asset-resource registry: hoisted head elements (stylesheets,\n// scripts, preloads, fonts, title/meta) are found-or-created during render,\n// acquired/released with commit-phase refcounting through the hoisted host\n// hooks, and deduped against SSR output by assetResourceKey.\n\ninterface DocumentResourceEntry {\n count: number;\n element: Element;\n ready: Promise<void> | null;\n}\n\ninterface DocumentResourceMeta {\n key: string;\n kind: FigAssetResource[\"kind\"];\n}\n\nconst documentResourceRegistries = new WeakMap<\n Element,\n Map<string, DocumentResourceEntry>\n>();\nconst documentResourceMeta = new WeakMap<Element, DocumentResourceMeta>();\n\n// Render-phase find-or-create only: renders can be discarded and retried, so\n// acquisition (refcounting, head insertion) waits for commitHoistedInstance.\n// The zero-count registry entry dedupes sibling adopts within a render pass.\nexport function adoptDocumentResource(\n type: string,\n props: Props,\n): Element | null {\n const head = documentHead();\n const resource = assetResourceFromHostProps(type, props);\n if (head === null || resource === null) return null;\n\n const key = assetResourceKey(resource);\n const registry = documentResourceRegistry(head);\n const adopted = registry.get(key);\n const element =\n adopted?.element ??\n findDocumentResource(head, key) ??\n document.createElement(type);\n\n if (adopted === undefined) {\n registry.set(key, { count: 0, element, ready: null });\n documentResourceMeta.set(element, { key, kind: resource.kind });\n }\n\n return element;\n}\n\nexport function acquireDocumentResource(element: Element): Element {\n const head = documentHead();\n if (head === null) return element;\n\n const registry = documentResourceRegistry(head);\n let meta = documentResourceMeta.get(element);\n\n // Deletions commit before placements, so a sibling's release in the same\n // commit may have dropped the element from the registry; re-derive its\n // identity from its attributes and revive it.\n if (meta === undefined) {\n const resource = assetResourceFromHostAttributes(\n elementName(element),\n (name: string) => element.getAttribute(name),\n );\n if (resource === null) return element;\n meta = { key: assetResourceKey(resource), kind: resource.kind };\n documentResourceMeta.set(element, meta);\n }\n\n const entry = registry.get(meta.key);\n\n // The key already resolves to a different live element (e.g. inserted by\n // insertAssetResources while this owner's render was suspended): adopt the\n // authoritative element instead of appending a stale duplicate.\n if (entry !== undefined && entry.element !== element) {\n entry.count += 1;\n return attachDocumentResource(head, entry.element);\n }\n\n if (entry === undefined) {\n registry.set(meta.key, { count: 1, element, ready: null });\n } else {\n entry.count += 1;\n }\n\n return attachDocumentResource(head, element);\n}\n\nfunction attachDocumentResource(head: Element, element: Element): Element {\n if (element.parentNode !== head) head.appendChild(element);\n attachSubtree(element);\n return element;\n}\n\nfunction documentResourceRegistry(\n head: Element,\n): Map<string, DocumentResourceEntry> {\n let registry = documentResourceRegistries.get(head);\n if (registry === undefined) {\n registry = new Map();\n documentResourceRegistries.set(head, registry);\n }\n return registry;\n}\n\nexport function releaseDocumentResource(element: Element): void {\n const head = documentHead();\n const meta = documentResourceMeta.get(element);\n if (head === null || meta === undefined) return;\n\n const registry = documentResourceRegistries.get(head);\n const entry = registry?.get(meta.key);\n\n // An element displaced from the registry (rekey collision) is untracked:\n // remove it with its owner unless another entry still shares it.\n if (entry === undefined || entry.element !== element) {\n if (registryReferencesElement(registry, element)) return;\n documentResourceMeta.delete(element);\n if (removableResourceKind(meta.kind)) removeReleasedResource(element);\n return;\n }\n\n if (entry.count > 0) entry.count -= 1;\n if (entry.count > 0) return;\n\n // Stylesheets, scripts, and fetch hints persist once inserted: removal\n // cannot undo a load and would unstyle content that still races on it.\n // Document metadata is removed with its last owner.\n if (!removableResourceKind(meta.kind)) return;\n\n registry?.delete(meta.key);\n documentResourceMeta.delete(element);\n removeReleasedResource(element);\n}\n\nfunction removeReleasedResource(element: Element): void {\n detachSubtree(element);\n element.parentNode?.removeChild(element);\n}\n\nfunction removableResourceKind(kind: FigAssetResource[\"kind\"]): boolean {\n return kind === \"title\" || kind === \"meta\";\n}\n\nfunction registryReferencesElement(\n registry: Map<string, DocumentResourceEntry> | undefined,\n element: Element,\n): boolean {\n if (registry === undefined) return false;\n for (const entry of registry.values()) {\n if (entry.element === element) return true;\n }\n return false;\n}\n\n// Hoisted instances are shared by key, so an identity change must not mutate\n// the shared element in place: release this owner's share of the old\n// identity and adopt (or create) the element for the new one. Other owners\n// keep the old element and its attributes untouched.\nexport function updateHoistedResource(\n element: Element,\n previousProps: Props,\n nextProps: Props,\n): Element {\n const type = elementName(element);\n const resource = assetResourceFromHostProps(type, nextProps);\n const meta = documentResourceMeta.get(element);\n const key = resource === null ? null : assetResourceKey(resource);\n\n if (key === null || meta === undefined || key === meta.key) {\n updateElement(element, previousProps, nextProps);\n return element;\n }\n\n releaseDocumentResource(element);\n\n const head = documentHead();\n const entry =\n head === null ? undefined : documentResourceRegistry(head).get(key);\n const claimed =\n entry !== undefined && entry.count > 0 ? entry.element : undefined;\n const next = adoptDocumentResource(type, nextProps) ?? element;\n if (next === element) {\n // No head to adopt into; fall back to the in-place update.\n updateElement(element, previousProps, nextProps);\n return element;\n }\n\n // Style only a fresh or unclaimed element; an element other owners already\n // committed keeps its attributes (identity is key-authoritative).\n if (claimed !== next) updateElement(next, {}, nextProps);\n return acquireDocumentResource(next);\n}\n\nfunction documentHead(): Element | null {\n return typeof document !== \"undefined\" && document.head !== undefined\n ? document.head\n : null;\n}\n\nfunction findDocumentResource(head: Element, key: string): Element | null {\n for (const child of Array.from(head.childNodes)) {\n if (!isElementNode(child)) continue;\n\n const resource = assetResourceFromHostAttributes(\n child.localName,\n (name: string) => child.getAttribute(name),\n );\n if (resource !== null && assetResourceKey(resource) === key) {\n return child;\n }\n }\n\n return null;\n}\n\n/**\n * Insert render-discovered asset resources (e.g. from a payload response's\n * `getAssetResources()`) into the document head, deduped against resources\n * already inserted by SSR, a host-rendered element, or an earlier call — using\n * the same key semantics as host resources. Returns a promise that resolves once\n * every freshly inserted *critical* stylesheet has loaded or errored, so callers\n * can gate revealing the dependent content. Non-critical hints (preload,\n * preconnect, scripts, fonts, `blocking: \"none\"` stylesheets) never block.\n */\nexport function insertAssetResources(\n resources: readonly FigAssetResource[],\n): Promise<void> {\n const head = documentHead();\n if (head === null) return Promise.resolve();\n\n const registry = documentResourceRegistry(head);\n const gates: Promise<void>[] = [];\n\n for (const resource of resources) {\n if (!isFigAssetResource(resource)) continue;\n if (resource.kind === \"title\" || resource.kind === \"meta\") continue;\n\n // A font is delivered as <link rel=\"preload\" as=\"font\">, which parses back\n // to a preload resource. Normalize it to that shape so its key and DOM\n // round-trip match and it dedupes against SSR/host-rendered font preloads\n // (otherwise the font:<href> lookup key never matches the preload:font:<href>\n // a head <link> parses to, and a duplicate is appended).\n const asset = asInsertableResource(resource);\n const key = assetResourceKey(asset);\n // A registry entry only counts as present while its element is attached:\n // a discarded render can leave a detached zero-count element built from\n // host props that need not match this descriptor (media, explicit-key\n // href), so a stale entry is discarded and replaced by a fresh element\n // created from the descriptor below.\n const tracked = registry.get(key)?.element;\n const existing: Element | null =\n (tracked !== undefined && tracked.parentNode === head ? tracked : null) ??\n findDocumentResource(head, key);\n\n if (existing !== null) {\n // Already present (SSR, a host-rendered element, or a prior call):\n // adopt it into the registry for O(1) future lookups. If Fig inserted it\n // and it is still loading, dependents join that pending gate. In dev,\n // Vite may insert a CSS link first; claim that still-loading element too\n // so route reveal waits for the stylesheet instead of committing a blank\n // payload slot.\n let entry = registry.get(key);\n if (entry?.element !== existing) {\n entry = { count: 1, element: existing, ready: null };\n registry.set(key, entry);\n documentResourceMeta.set(existing, { key, kind: asset.kind });\n }\n const existingGate = gateExistingStylesheet(asset, entry, key, registry);\n if (existingGate !== null) {\n gates.push(existingGate);\n }\n continue;\n }\n\n const element = createAssetResourceElement(asset);\n const entry: DocumentResourceEntry = {\n count: 1,\n element,\n ready: null,\n };\n const gate = isCriticalStylesheet(asset)\n ? whenResourceSettled(element).then(() => {\n if (registry.get(key) === entry) entry.ready = null;\n })\n : null;\n entry.ready = gate;\n registry.set(key, entry);\n documentResourceMeta.set(element, { key, kind: asset.kind });\n head.appendChild(element);\n\n if (gate !== null) gates.push(gate);\n }\n\n return gates.length === 0\n ? Promise.resolve()\n : Promise.all(gates).then(() => undefined);\n}\n\nfunction asInsertableResource(resource: FigAssetResource): FigAssetResource {\n // Fonts share the DOM representation (and therefore the key space) of a\n // font-targeted preload; everything else is already in its own key space.\n if (resource.kind !== \"font\") return resource;\n\n return {\n as: \"font\",\n crossOrigin: resource.crossOrigin ?? \"anonymous\",\n fetchPriority: resource.fetchPriority,\n href: resource.href,\n key: resource.key,\n kind: \"preload\",\n type: resource.type,\n };\n}\n\nfunction isCriticalStylesheet(resource: FigAssetResource): boolean {\n // Client-reference stylesheets gate reveal by default; opt out with\n // blocking: \"none\". Every other kind is a hint that must never block.\n if (resource.kind !== \"stylesheet\" || resource.blocking === \"none\") {\n return false;\n }\n if (resource.media === undefined || resource.media === \"\") return true;\n // Outside browsers there is no reliable media evaluation, so keep media\n // stylesheets conservative and gate them as potentially critical.\n return typeof matchMedia !== \"function\" || matchMedia(resource.media).matches;\n}\n\nfunction gateExistingStylesheet(\n resource: FigAssetResource,\n entry: DocumentResourceEntry,\n key: string,\n registry: Map<string, DocumentResourceEntry>,\n): Promise<void> | null {\n if (!isCriticalStylesheet(resource)) return null;\n if (entry.ready !== null) return entry.ready;\n if (!isPendingStylesheetElement(entry.element)) return null;\n\n const gate = whenResourceSettled(entry.element).then(() => {\n if (registry.get(key) === entry) entry.ready = null;\n });\n entry.ready = gate;\n return gate;\n}\n\nfunction isPendingStylesheetElement(element: Element): boolean {\n return (\n element.localName === \"link\" &&\n element.getAttribute(\"rel\") === \"stylesheet\" &&\n \"sheet\" in element &&\n (element as { sheet: StyleSheet | null }).sheet === null\n );\n}\n\nfunction whenResourceSettled(element: Element): Promise<void> {\n return new Promise<void>((resolve) => {\n const settle = () => {\n element.removeEventListener(\"load\", settle);\n element.removeEventListener(\"error\", settle);\n resolve();\n };\n // Resolve on error too: a failed stylesheet must not block reveal forever.\n element.addEventListener(\"load\", settle);\n element.addEventListener(\"error\", settle);\n });\n}\n\n// The attribute set is shared with the server's registry writer, so a\n// client-inserted asset element cannot drift from its SSR counterpart.\nfunction createAssetResourceElement(resource: FigAssetResource): Element {\n const element = document.createElement(\n resource.kind === \"script\" ? \"script\" : \"link\",\n );\n\n for (const [name, value] of assetResourceHostAttributes(resource)) {\n element.setAttribute(name, value === true ? \"\" : value);\n }\n\n return element;\n}\n","import {\n SUSPENSE_CLIENT_MARKER,\n SUSPENSE_COMPLETED_MARKER,\n SUSPENSE_END_MARKER,\n SUSPENSE_PENDING_PREFIX,\n} from \"@bgub/fig/internal\";\nimport type {\n DehydratedSuspenseBoundary,\n DehydratedSuspenseError,\n} from \"@bgub/fig-reconciler\";\n\n// Parsing of the server's Suspense streaming markers (see\n// @bgub/fig/internal suspense-protocol) into dehydrated boundaries, plus the\n// DOM-range helpers that consume them.\n\ntype TextLike = Text | Comment;\n\ninterface SuspenseMarker {\n id: string | null;\n status: DehydratedSuspenseBoundary<Element, TextLike>[\"status\"];\n}\n\nexport function suspenseBoundaryFor(\n node: Element | TextLike,\n): DehydratedSuspenseBoundary<Element, TextLike> | null {\n if (!isComment(node)) return null;\n\n const marker = suspenseMarker(node);\n return marker === null ? null : suspenseBoundary(node, marker);\n}\n\nfunction suspenseBoundary(\n start: TextLike,\n initialMarker: SuspenseMarker,\n): DehydratedSuspenseBoundary<Element, TextLike> | null {\n const end = suspenseBoundaryEnd(start);\n if (end === null) return null;\n return {\n end,\n forceClientRender: false,\n id: initialMarker.id,\n start,\n get error() {\n return suspenseBoundaryError(start);\n },\n get status() {\n return suspenseMarker(start)?.status ?? initialMarker.status;\n },\n };\n}\n\nfunction suspenseMarker(node: unknown): SuspenseMarker | null {\n if (!isComment(node)) return null;\n\n if (node.data === SUSPENSE_COMPLETED_MARKER) {\n return { id: null, status: \"completed\" };\n }\n\n if (node.data === SUSPENSE_CLIENT_MARKER) {\n return { id: null, status: \"client-rendered\" };\n }\n\n const pending = node.data.startsWith(SUSPENSE_PENDING_PREFIX)\n ? node.data.slice(SUSPENSE_PENDING_PREFIX.length)\n : null;\n if (pending !== null && pending !== \"\") {\n return { id: pending, status: \"pending\" };\n }\n return null;\n}\n\nfunction suspenseBoundaryEnd(start: TextLike): TextLike | null {\n let depth = 0;\n\n for (\n let node = start.nextSibling as Element | TextLike | null;\n node !== null;\n node = node.nextSibling as Element | TextLike | null\n ) {\n if (!isComment(node)) continue;\n\n if (suspenseMarker(node) !== null) {\n depth += 1;\n continue;\n }\n\n if (node.data !== SUSPENSE_END_MARKER) continue;\n if (depth === 0) return node;\n depth -= 1;\n }\n\n return null;\n}\n\nfunction suspenseBoundaryError(\n start: TextLike,\n): DehydratedSuspenseError | null {\n const placeholder = start.nextSibling;\n if (!hasDataset(placeholder)) return null;\n\n return {\n digest: placeholder.dataset.dgst,\n message: placeholder.dataset.msg,\n };\n}\n\n// Event-target boundary discovery walks outward from the target instead of\n// searching the tree: at each ancestor level, scanning the preceding siblings\n// right-to-left, an end marker closes over a boundary that sits entirely\n// before the target, so a start marker reached at depth zero is unmatched and\n// its range encloses the target. Passing a returned start marker back in\n// resumes the search at the next enclosing boundary (needed when a marker has\n// no live fiber because it is nested inside an outer dehydrated boundary).\nexport function enclosingSuspenseBoundaryStart(\n target: unknown,\n): TextLike | null {\n if (!isNode(target)) return null;\n\n for (let node: Node | null = target; node !== null; node = node.parentNode) {\n let depth = 0;\n\n for (\n let sibling = node.previousSibling;\n sibling !== null;\n sibling = sibling.previousSibling\n ) {\n if (!isComment(sibling)) continue;\n\n if (sibling.data === SUSPENSE_END_MARKER) {\n depth += 1;\n continue;\n }\n\n if (suspenseMarker(sibling) === null) continue;\n if (depth === 0) return sibling;\n depth -= 1;\n }\n }\n\n return null;\n}\n\nexport function isWithinSuspenseBoundary(\n target: unknown,\n boundary: DehydratedSuspenseBoundary<Element, TextLike>,\n): boolean {\n if (!isNode(target)) return false;\n\n const startParent = boundary.start.parentNode;\n const endParent = boundary.end.parentNode;\n if (startParent === null && endParent === null) return false;\n\n for (let node: Node | null = target; node !== null; node = node.parentNode) {\n if (node === boundary.start || node === boundary.end) return false;\n\n if (startParent !== null && node.parentNode === startParent) {\n return isSiblingAfterStartBeforeEnd(\n node as Element | TextLike,\n boundary.start,\n boundary.end,\n );\n }\n if (\n endParent !== null &&\n endParent !== startParent &&\n node.parentNode === endParent\n ) {\n return isSiblingBeforeEnd(node as Element | TextLike, boundary.end);\n }\n }\n\n return false;\n}\n\nfunction isSiblingAfterStartBeforeEnd(\n node: Element | TextLike,\n start: Element | TextLike,\n end: Element | TextLike,\n): boolean {\n for (\n let sibling: Node | null = node;\n sibling !== null;\n sibling = sibling.previousSibling\n ) {\n if (sibling === start) return true;\n if (sibling === end) return false;\n }\n\n return false;\n}\n\nfunction isSiblingBeforeEnd(\n node: Element | TextLike,\n end: Element | TextLike,\n): boolean {\n for (\n let sibling: Node | null = node;\n sibling !== null;\n sibling = sibling.nextSibling\n ) {\n if (sibling === end) return true;\n }\n\n return false;\n}\n\nexport function removeSuspenseBoundaryRange(\n boundary: DehydratedSuspenseBoundary<Element, TextLike>,\n): void {\n for (let node: Element | TextLike | null = boundary.start; node !== null;) {\n const next = node.nextSibling as Element | TextLike | null;\n removeNode(node);\n if (node === boundary.end) return;\n node = next;\n }\n}\n\nexport function removeNode(node: Element | TextLike): void {\n node.parentNode?.removeChild(node);\n}\n\nfunction isComment(node: unknown): node is Comment {\n return (\n typeof node === \"object\" &&\n node !== null &&\n \"data\" in node &&\n \"nodeType\" in node &&\n node.nodeType === 8\n );\n}\n\nfunction hasDataset(\n node: unknown,\n): node is Element & { dataset: DOMStringMap } {\n return typeof node === \"object\" && node !== null && \"dataset\" in node;\n}\n\nfunction isNode(value: unknown): value is Node {\n return typeof value === \"object\" && value !== null && \"parentNode\" in value;\n}\n","import type { Props } from \"@bgub/fig\";\nimport { VIEW_TRANSITION_PENDING_PROPERTY } from \"@bgub/fig/internal\";\nimport type {\n ViewTransitionCommitResult,\n ViewTransitionHostConfig,\n ViewTransitionMutationResult,\n ViewTransitionSurfaceMeasurement,\n} from \"@bgub/fig-reconciler\";\nimport type { Container } from \"./events.ts\";\n\ninterface RunningViewTransition {\n finished?: Promise<unknown>;\n ready?: Promise<unknown>;\n}\n\ninterface CancellableAnimation {\n cancel(): void;\n}\n\ntype ViewTransitionDocument = Document & {\n startViewTransition?: (\n update: () => void,\n ) => RunningViewTransition | undefined;\n [VIEW_TRANSITION_PENDING_PROPERTY]?: RunningViewTransition | null;\n};\n\ninterface CssGlobal {\n CSS?: {\n escape?: (value: string) => string;\n };\n}\n\nfunction commitViewTransition(\n container: Container,\n prepareSnapshot: () => void,\n mutate: () => ViewTransitionMutationResult,\n cleanup: () => void,\n): ViewTransitionCommitResult {\n const owner = ownerDocument(container) as ViewTransitionDocument;\n const start = owner.startViewTransition;\n if (typeof start !== \"function\") return false;\n\n let didMutate = false;\n let chained = false;\n let failedBeforeMutate = false;\n let restoreRootName: (() => void) | null = null;\n let mutationResult: ViewTransitionMutationResult | null = null;\n\n const run = (): void => {\n prepareSnapshot();\n try {\n const transition = start.call(owner, () => {\n didMutate = true;\n mutationResult = mutate();\n // Before the new capture: when measurement shows every change is\n // contained in a named boundary, drop the root's own snapshot so the\n // page-wide overlay does not swallow pointer events for the\n // animation's duration.\n if (mutationResult.cancelRootSnapshot) {\n restoreRootName = cancelRootViewTransitionName(owner);\n }\n });\n if (transition !== undefined) {\n registerPendingTransition(owner, transition);\n hideCanceledSnapshots(owner, transition, () => mutationResult);\n }\n // Root-name restore waits for the transition to fully settle: putting\n // `view-transition-name: root` back on the live <html> while the\n // transition still runs can re-associate the live root with its\n // (force-hidden) captured group, which paints the page blank for the\n // rest of the animation.\n const settleAfterTransition = transition?.finished ?? transition?.ready;\n const restore = (): void => restoreRootName?.();\n if (settleAfterTransition === undefined) {\n restore();\n cleanup();\n } else {\n (transition?.ready ?? settleAfterTransition).then(cleanup, cleanup);\n settleAfterTransition.then(restore, restore);\n }\n } catch (error) {\n restoreRootName?.();\n if (!didMutate) {\n // A chained run has no caller to report a fallback to and the\n // reconciler stays frozen until mutate runs: commit unanimated.\n // A synchronous run reports `false` so the caller falls back.\n if (chained) {\n didMutate = true;\n mutate();\n } else {\n failedBeforeMutate = true;\n }\n cleanup();\n return;\n }\n cleanup();\n if (!chained) throw error;\n // Chained commit errors were already routed by the reconciler's\n // deferred-commit handling; a residual throw here is a transition\n // failure that must not vanish into the pending promise.\n setTimeout(() => {\n throw error;\n });\n }\n };\n\n // Serialize per document: starting a transition while one is running makes\n // the browser abruptly skip the running animation, and the skipped\n // transition's restore could race this one's old-state capture. The\n // reconciler normally parks eligible commits upstream (render-during-wait\n // via the adapter's suspend hook), so for fig-dom this chain is a fallback\n // for renderers that wire commit without suspend — chaining freezes the root\n // until the previous animation finishes, parking keeps rendering live.\n const pending = owner[VIEW_TRANSITION_PENDING_PROPERTY];\n const pendingSettled = pending?.finished ?? pending?.ready;\n if (pending != null && pendingSettled !== undefined) {\n chained = true;\n pendingSettled.then(run, run);\n return \"deferred\";\n }\n\n run();\n if (failedBeforeMutate) return false;\n return didMutate ? \"committed\" : \"deferred\";\n}\n\n// Remove the root element from the new capture, remembering how to restore\n// the author's inline style afterwards.\nfunction cancelRootViewTransitionName(\n owner: ViewTransitionDocument,\n): () => void {\n const element = owner.documentElement as HTMLElement | null;\n if (element === null) return () => undefined;\n\n const style = element.style as CSSStyleDeclaration & {\n viewTransitionName?: string;\n };\n const previous = style.viewTransitionName ?? \"\";\n style.viewTransitionName = \"none\";\n\n return () => {\n style.viewTransitionName = previous;\n if (element.getAttribute(\"style\") === \"\") element.removeAttribute(\"style\");\n };\n}\n\n// Old snapshots were captured before the update callback ran and cannot be\n// un-captured; once the pseudo tree exists (ready), hide the groups of\n// measurement-canceled boundaries — and the root group plus the\n// ::view-transition overlay when the whole-page snapshot was dropped — with\n// filling zero-duration animations so untouched regions stay interactive\n// while the remaining groups animate. Mirrors React's\n// cancelViewTransitionName / cancelRootViewTransitionName.\nfunction hideCanceledSnapshots(\n owner: ViewTransitionDocument,\n transition: RunningViewTransition,\n getResult: () => ViewTransitionMutationResult | null,\n): void {\n // The filled zero-duration animations outlive their pseudo tree: without\n // an explicit cancel once the transition settles they would apply to the\n // next transition's pseudo tree and hide its groups.\n const hideAnimations: CancellableAnimation[] = [];\n const cancelHideAnimations = (): void => {\n for (const animation of hideAnimations) {\n try {\n animation.cancel();\n } catch {\n // Cancelling a finished pseudo animation is best-effort.\n }\n }\n hideAnimations.length = 0;\n };\n\n const hide = (): void => {\n const result = getResult();\n if (result === null) return;\n if (result.canceledNames.length === 0 && !result.cancelRootSnapshot) {\n return;\n }\n\n const element = owner.documentElement as\n | (HTMLElement & {\n animate?: (\n keyframes: Record<string, unknown>,\n options: Record<string, unknown>,\n ) => unknown;\n })\n | null;\n if (element === null || typeof element.animate !== \"function\") return;\n\n const track = (animation: unknown): void => {\n if (\n typeof (animation as CancellableAnimation | null)?.cancel === \"function\"\n ) {\n hideAnimations.push(animation as CancellableAnimation);\n }\n };\n\n const hideGroup = (name: string): void => {\n track(\n element.animate?.(\n { opacity: [0, 0], pointerEvents: [\"none\", \"none\"] },\n {\n duration: 0,\n fill: \"forwards\",\n pseudoElement: `::view-transition-group(${name})`,\n },\n ),\n );\n };\n\n try {\n for (const name of result.canceledNames) {\n hideGroup(escapeViewTransitionName(name));\n }\n if (result.cancelRootSnapshot) {\n hideGroup(\"root\");\n track(\n element.animate(\n { height: [0, 0], width: [0, 0] },\n {\n duration: 0,\n fill: \"forwards\",\n pseudoElement: \"::view-transition\",\n },\n ),\n );\n }\n } catch {\n // Pseudo-element animation is best-effort: without it the canceled\n // snapshots fall back to the browser's default cross-fade.\n }\n };\n\n const ready = transition.ready ?? transition.finished;\n if (ready === undefined) hide();\n else ready.then(hide, () => undefined);\n\n const settled = transition.finished ?? transition.ready;\n if (settled === undefined) cancelHideAnimations();\n else settled.then(cancelHideAnimations, cancelHideAnimations);\n}\n\nfunction registerPendingTransition(\n owner: ViewTransitionDocument,\n transition: RunningViewTransition,\n): void {\n owner[VIEW_TRANSITION_PENDING_PROPERTY] = transition;\n const release = (): void => {\n if (owner[VIEW_TRANSITION_PENDING_PROPERTY] === transition) {\n owner[VIEW_TRANSITION_PENDING_PROPERTY] = null;\n }\n };\n const settled = transition.finished ?? transition.ready;\n if (settled === undefined) release();\n else settled.then(release, release);\n}\n\n// The reconciler parks eligible commits behind a running transition (the\n// shared per-document mutex — client commits and streaming reveals alike)\n// and re-schedules once it settles. Rendering continues during the park;\n// only the commit waits.\nfunction suspendOnActiveViewTransition(\n container: Container,\n onFinished: () => void,\n): boolean {\n const owner = ownerDocument(container) as ViewTransitionDocument;\n const pending = owner[VIEW_TRANSITION_PENDING_PROPERTY];\n const settled = pending?.finished ?? pending?.ready;\n if (pending == null || settled === undefined) return false;\n\n settled.then(onFinished, onFinished);\n return true;\n}\n\nfunction measureViewTransitionSurface(\n element: Element,\n): ViewTransitionSurfaceMeasurement | null {\n if (typeof element.getBoundingClientRect !== \"function\") return null;\n\n const rect = element.getBoundingClientRect();\n const view = element.ownerDocument?.defaultView ?? null;\n const inViewport =\n view === null\n ? true\n : rect.bottom >= 0 &&\n rect.right >= 0 &&\n rect.top <= view.innerHeight &&\n rect.left <= view.innerWidth;\n let absolutelyPositioned = false;\n try {\n absolutelyPositioned =\n view?.getComputedStyle(element).position === \"absolute\";\n } catch {\n // Detached elements or minimal test environments: assume static\n // positioning, the conservative choice (resizes keep the root snapshot).\n }\n\n return {\n absolutelyPositioned,\n height: rect.height,\n inViewport,\n width: rect.width,\n x: rect.left,\n y: rect.top,\n };\n}\n\nfunction applyViewTransitionName(\n element: Element,\n name: string,\n className: string | null,\n): void {\n const style = (element as HTMLElement).style as CSSStyleDeclaration & {\n viewTransitionClass?: string;\n viewTransitionName?: string;\n };\n\n style.viewTransitionName = escapeViewTransitionName(name);\n if (className !== null) style.viewTransitionClass = className;\n}\n\nfunction restoreViewTransitionName(element: Element, props: Props): void {\n const style = (element as HTMLElement).style as CSSStyleDeclaration & {\n viewTransitionClass?: string;\n viewTransitionName?: string;\n };\n const styleProp = props.style as Record<string, unknown> | undefined;\n const name =\n styleProp?.viewTransitionName ?? styleProp?.[\"view-transition-name\"];\n const className =\n styleProp?.viewTransitionClass ?? styleProp?.[\"view-transition-class\"];\n\n style.viewTransitionName = styleValue(name);\n style.viewTransitionClass = styleValue(className);\n}\n\nfunction ownerDocument(container: Container): Document {\n return \"ownerDocument\" in container && container.ownerDocument !== null\n ? container.ownerDocument\n : document;\n}\n\nfunction escapeViewTransitionName(name: string): string {\n const escape = (globalThis as CssGlobal).CSS?.escape;\n return escape === undefined ? name : escape(name);\n}\n\nfunction styleValue(value: unknown): string {\n if (typeof value === \"string\" || typeof value === \"number\") {\n return String(value).trim();\n }\n\n return \"\";\n}\n\nexport const viewTransitionHostConfig: ViewTransitionHostConfig<\n Container,\n Element\n> = {\n commit: commitViewTransition,\n apply: applyViewTransitionName,\n restore: restoreViewTransitionName,\n measure: measureViewTransitionSurface,\n suspend: suspendOnActiveViewTransition,\n};\n","import {\n createPortalNode,\n type FigNode,\n type FigPortal,\n type Key,\n type Props,\n} from \"@bgub/fig\";\nimport \"./jsx-augmentation.ts\";\nimport {\n ACTIVITY_TEMPLATE_ATTRIBUTE,\n assetResourceFromHostProps,\n validateInstanceNesting,\n validateTextNesting,\n} from \"@bgub/fig/internal\";\nimport {\n createRenderer,\n type FigRoot,\n type FigRootOptions,\n type HostConfig,\n type RecoverableErrorInfo,\n} from \"@bgub/fig-reconciler\";\nimport {\n acquireDocumentResource,\n adoptDocumentResource,\n releaseDocumentResource,\n updateHoistedResource,\n} from \"./asset-resources.ts\";\nimport { attachSubtree, detachSubtree } from \"./attachment.ts\";\nimport { composeBind, resumeBind, suspendBind } from \"./bind.ts\";\nimport {\n type Container,\n disableRootHydration,\n registerPortalContainer,\n registerRoot,\n removePortalContainer,\n replayQueuedEvents,\n setEventBatching,\n unregisterRoot,\n} from \"./events.ts\";\nimport { hydrateElement, updateElement, updateParentSelect } from \"./props.ts\";\nimport { configureDomRefreshScheduler, type RefreshUpdate } from \"./refresh.ts\";\nimport {\n enclosingSuspenseBoundaryStart,\n isWithinSuspenseBoundary,\n removeNode,\n removeSuspenseBoundaryRange,\n suspenseBoundaryFor,\n} from \"./suspense-markers.ts\";\nimport {\n elementName,\n htmlNamespace,\n isElementNode,\n isEmptyPropValue,\n mathNamespace,\n svgNamespace,\n} from \"./tree.ts\";\nimport { viewTransitionHostConfig } from \"./view-transition.ts\";\n\ntype TextLike = Text | Comment;\ntype RetriableSuspenseMarker = TextLike & { __figRetry?: () => void };\n\ninterface DomRenderer {\n batchedUpdates<T>(this: void, callback: () => T): T;\n createRoot(\n this: void,\n container: Container,\n options?: FigRootOptions,\n ): FigRoot;\n hydrateRoot(\n this: void,\n container: Container,\n children: FigNode,\n options?: FigRootOptions,\n ): FigRoot;\n hydrateTarget(\n this: void,\n container: Container,\n target: unknown,\n priority?: \"default\" | \"continuous\" | \"discrete\",\n ): \"none\" | \"hydrated\" | \"blocked\";\n flushSync<T>(this: void, callback: () => T): T;\n scheduleRefresh(this: void, update: RefreshUpdate): void;\n}\n\ndeclare const __FIG_DEV__: boolean | undefined;\n\nexport { insertAssetResources } from \"./asset-resources.ts\";\nexport type { Bind } from \"./bind.ts\";\nexport {\n type EventCallback,\n type EventDescriptor,\n type EventOptions,\n on,\n} from \"./events.ts\";\nexport type {\n EmptyPropValue,\n HostEvents,\n HostIntrinsicElements,\n HostProps,\n HostStyle,\n} from \"./jsx.ts\";\nexport { composeBind };\n\nconst __DEV__ = typeof __FIG_DEV__ === \"boolean\" ? __FIG_DEV__ : false;\n\nconst hostConfig: HostConfig<Container, Element, TextLike> = {\n createInstance: (type, props, parent) =>\n createDomElement(type, props, parent),\n createTextInstance: (text) => document.createTextNode(text),\n // The dev gates below run at call time (never at module scope, which\n // would throw on import wherever bundler defines don't apply). They must\n // stay in block form — `if (dev) { validate() }` — not early-return form:\n // esbuild only eliminates the constant branch (and with it the dom-nesting\n // module import) at parse time, before symbol retention is decided; code\n // after an `if (prod) return` keeps the import referenced and ships the\n // whole module in production bundles.\n validateInstanceNesting: (type, props, ancestors) => {\n if (__DEV__) {\n // Asset resources hoist to <head>, so their fiber position is not\n // their DOM position; the server exempts them the same way.\n if (assetResourceFromHostProps(type, props) !== null) return;\n validateInstanceNesting(type, ancestors);\n }\n },\n validateTextNesting: (text, ancestors) => {\n if (__DEV__) {\n validateTextNesting(text, ancestors);\n }\n },\n containerType: (container) =>\n isElementNode(container) ? elementName(container) : null,\n appendInitialChild: (parent, child) => {\n parent.appendChild(child);\n // Render-phase assembly: the select is not live yet, so applying its\n // default to options that assemble after it is always safe. Only\n // option-bearing children can change a selection.\n if (isElementNode(child) && optionLike(child)) {\n updateParentSelect(child, true);\n }\n },\n finalizeInitialInstance: (instance, props) =>\n updateElement(instance, {}, props, { initial: true }),\n setTextContent: (instance, text) => {\n if (instance.textContent !== text) instance.textContent = text;\n },\n getFirstHydratableChild: (parent, props) =>\n hydratableFirstChild(parent, props),\n getNextHydratableSibling: (node) =>\n skipTextSeparators(node.nextSibling as Element | TextLike | null),\n canHydrateInstance: (node, type, props) =>\n isHydratableElement(node, type, props),\n canHydrateTextInstance: (node, text, suppressHydrationWarning) =>\n isHydratableText(node) &&\n (suppressHydrationWarning === true || node.nodeValue === text),\n // Hoisted asset resources never appear at their fiber's server position\n // (the server registers them and emits nothing inline): hydration must not\n // match them against the DOM cursor, and commit acquires/releases them in\n // the head registry instead of inserting/removing at the fiber position.\n isHoistedInstance: (type, props) =>\n assetResourceFromHostProps(type, props) !== null,\n commitHoistedInstance: (instance) => acquireDocumentResource(instance),\n removeHoistedInstance: (instance) => releaseDocumentResource(instance),\n updateHoistedInstance: (instance, previousProps, nextProps) =>\n updateHoistedResource(instance, previousProps, nextProps),\n shouldCommitUpdate: (type, _previousProps, nextProps) =>\n shouldRestoreControlledFormState(type, nextProps),\n clearContainer: (container) => {\n let child = container.firstChild as Element | TextLike | null;\n\n while (child !== null) {\n const next = child.nextSibling as Element | TextLike | null;\n detachSubtree(child as Element | Text);\n container.removeChild(child);\n child = next;\n }\n\n // A cleared container (hydration-mismatch recovery) detaches every\n // queued replayable event's target; drain them.\n queueMicrotask(replayQueuedEvents);\n },\n insertBefore: (parent, child, before) => {\n parent.insertBefore(child, before);\n // Live insertion: re-assert a controlled select's value, but never\n // re-apply an uncontrolled default — the user owns the live selection\n // (defaults are mount-time only, matching React).\n if (isElementNode(child) && optionLike(child)) updateParentSelect(child);\n attachSubtree(child as Element | Text);\n },\n removeChild: (parent, child) => {\n detachSubtree(child as Element | Text);\n parent.removeChild(child);\n },\n commitTextUpdate: (text, value) => {\n if (text.nodeValue !== value) text.nodeValue = value;\n },\n commitUpdate: (instance, previousProps, nextProps) =>\n updateElement(instance, previousProps, nextProps),\n commitHydratedInstance: (instance, nextProps) =>\n hydrateElement(instance, nextProps),\n getActivityBoundary: (node) =>\n isActivityTemplate(node) ? (node as Element) : null,\n getFirstActivityHydratable: (boundary) =>\n skipTextSeparators(\n (activityTemplateContent(boundary).firstChild ?? null) as\n | Element\n | TextLike\n | null,\n ),\n commitHydratedActivityBoundary: (boundary) => {\n const parent = boundary.parentNode;\n if (parent === null) return;\n\n const content = activityTemplateContent(boundary);\n while (content.firstChild !== null) {\n parent.insertBefore(content.firstChild, boundary);\n }\n parent.removeChild(boundary);\n },\n hideInstance: (instance) => {\n suspendBind(instance);\n (instance as HTMLElement).style.setProperty(\"display\", \"none\", \"important\");\n },\n unhideInstance: (instance, props) => {\n const style = (props.style ?? {}) as Record<string, unknown>;\n const display = style.display;\n (instance as HTMLElement).style.setProperty(\n \"display\",\n typeof display === \"string\" ? display : \"\",\n );\n resumeBind(instance);\n },\n hideTextInstance: (text) => {\n text.nodeValue = \"\";\n },\n unhideTextInstance: (text, value) => {\n if (text.nodeValue !== value) text.nodeValue = value;\n },\n getSuspenseBoundary: (node) => suspenseBoundaryFor(node),\n getEnclosingSuspenseBoundaryStart: (target) =>\n enclosingSuspenseBoundaryStart(target),\n isTargetWithinSuspenseBoundary: (target, boundary) =>\n isWithinSuspenseBoundary(target, boundary),\n registerSuspenseBoundaryRetry: (boundary, retry) => {\n (boundary.start as RetriableSuspenseMarker).__figRetry = retry;\n },\n commitHydratedSuspenseBoundary: (boundary) => {\n if (boundary.status === \"completed\" && !boundary.forceClientRender) {\n removeNode(boundary.start);\n removeNode(boundary.end);\n } else {\n removeSuspenseBoundaryRange(boundary);\n }\n\n queueMicrotask(replayQueuedEvents);\n },\n removeDehydratedSuspenseBoundary: (boundary) => {\n // The replay pass drops queued events whose targets left the tree with\n // the boundary.\n removeSuspenseBoundaryRange(boundary);\n queueMicrotask(replayQueuedEvents);\n },\n completeRootHydration: (container) => {\n disableRootHydration(container as Container);\n // Non-discrete early events blocked on the pre-commit shell have no\n // boundary hook to re-drain them; root completion is their backstop.\n queueMicrotask(replayQueuedEvents);\n },\n preparePortalContainer: (container, root, logicalParent) => {\n registerPortalContainer(\n container as Container,\n root,\n logicalParent as Container | Element,\n );\n },\n removePortalContainer: (container) => {\n removePortalContainer(container as Container);\n },\n viewTransition: viewTransitionHostConfig,\n};\n\nconst renderer: DomRenderer = createRenderer(hostConfig);\nsetEventBatching(renderer.batchedUpdates);\nconfigureDomRefreshScheduler(renderer.scheduleRefresh);\n\nexport const flushSync = renderer.flushSync;\n\nexport type { FigRoot, FigRootOptions, RecoverableErrorInfo };\n\nexport function createRoot(\n container: Container,\n options?: FigRootOptions,\n): FigRoot {\n const root = renderer.createRoot(container, options);\n registerRoot(container, undefined, (callback) => root.data.run(callback));\n return withRootTeardown(root, container);\n}\n\nexport function hydrateRoot(\n container: Container,\n children: FigNode,\n options?: FigRootOptions,\n): FigRoot {\n // Registration can follow the initial hydration render: it runs\n // synchronously in this task, so no DOM event can dispatch in between.\n const root = renderer.hydrateRoot(container, children, options);\n registerRoot(\n container,\n (target, lane) => renderer.hydrateTarget(container, target, lane),\n (callback) => root.data.run(callback),\n );\n return withRootTeardown(root, container);\n}\n\n// Root event state (hydration listeners, delegated listener maps, queued\n// replayable events) lives outside the reconciler; tear it down with the\n// root so nothing dispatches against or retains an unmounted tree.\nfunction withRootTeardown(root: FigRoot, container: Container): FigRoot {\n return {\n ...root,\n unmount: () => {\n root.unmount();\n unregisterRoot(container);\n },\n };\n}\n\nexport function createPortal(\n children: FigNode,\n container: Container,\n key: Key | null = null,\n): FigPortal {\n return createPortalNode(children, container, key);\n}\n\n// Real templates hold children in a content fragment; test doubles hold\n// them directly.\nfunction activityTemplateContent(boundary: Element): ParentNode {\n return \"content\" in boundary\n ? (boundary.content as ParentNode)\n : (boundary as ParentNode);\n}\n\nfunction isActivityTemplate(node: Element | TextLike): boolean {\n return (\n elementName(node) === \"template\" &&\n \"getAttribute\" in node &&\n node.getAttribute(ACTIVITY_TEMPLATE_ATTRIBUTE) !== null\n );\n}\n\nfunction isHydratableElement(\n node: Element | TextLike,\n type: string,\n props: Props,\n): boolean {\n if (!isElementNode(node) || !(\"setAttribute\" in node)) return false;\n if (elementName(node) !== type.toLowerCase()) return false;\n return hasMatchingUnsafeHTML(node, props);\n}\n\nfunction createDomElement(\n type: string,\n props: Props,\n parent: Container | Element,\n): Element {\n const resource = adoptDocumentResource(type, props);\n if (resource !== null) return resource;\n\n const namespace = namespaceFor(type, parent);\n return namespace === htmlNamespace\n ? document.createElement(type)\n : document.createElementNS(namespace, type);\n}\n\nfunction namespaceFor(type: string, parent: Container | Element): string {\n const normalizedType = type.toLowerCase();\n if (normalizedType === \"svg\") return svgNamespace;\n if (normalizedType === \"math\") return mathNamespace;\n\n return \"namespaceURI\" in parent && elementName(parent) !== \"foreignobject\"\n ? (parent.namespaceURI ?? htmlNamespace)\n : htmlNamespace;\n}\n\nfunction hydratableFirstChild(\n parent: Container | Element,\n props?: Props,\n): Element | TextLike | null {\n if (props !== undefined && unsafeHTMLValue(props) !== null) return null;\n\n if (\n elementName(parent) === \"textarea\" &&\n props !== undefined &&\n hasManagedTextareaContent(props)\n ) {\n return null;\n }\n\n return skipTextSeparators(parent.firstChild as Element | TextLike | null);\n}\n\n// The server writes a `<!--,-->` comment between adjacent text nodes that\n// come from different fibers (browser parsing would otherwise merge them\n// into a single DOM text node while the client keeps one text fiber each —\n// see TEXT_SEPARATOR in @bgub/fig-server). The hydration cursor steps over\n// separators when advancing; only comments with exactly this data are\n// skipped, so the fig:suspense marker comments are never affected.\nconst TEXT_SEPARATOR_DATA = \",\";\n\nfunction skipTextSeparators(\n node: Element | TextLike | null,\n): Element | TextLike | null {\n let current = node;\n while (current !== null && isTextSeparator(current)) {\n current = current.nextSibling as Element | TextLike | null;\n }\n return current;\n}\n\nfunction isTextSeparator(node: Element | TextLike): boolean {\n return (\n \"nodeType\" in node &&\n node.nodeType === 8 &&\n (node as Comment).data === TEXT_SEPARATOR_DATA\n );\n}\n\nfunction hasManagedTextareaContent(props: Props): boolean {\n return props.value !== undefined || props.defaultValue !== undefined;\n}\n\nfunction unsafeHTMLValue(props: Props): unknown {\n return isEmptyPropValue(props.unsafeHTML) ? null : props.unsafeHTML;\n}\n\nfunction hasMatchingUnsafeHTML(element: Element, props: Props): boolean {\n const expected = unsafeHTMLValue(props);\n if (expected === null) return true;\n return typeof expected !== \"string\" || \"innerHTML\" in element;\n}\n\nfunction isHydratableText(node: Element | TextLike): boolean {\n if (\"nodeType\" in node && node.nodeType !== 3) return false;\n return !(\"setAttribute\" in node) && \"nodeValue\" in node;\n}\n\nfunction optionLike(element: Element): boolean {\n const name = elementName(element);\n return name === \"option\" || name === \"optgroup\";\n}\n\nfunction shouldRestoreControlledFormState(type: string, props: Props): boolean {\n return (\n (type === \"input\" || type === \"textarea\" || type === \"select\") &&\n (props.value !== undefined || props.checked !== undefined)\n );\n}\n\nexport type { Container };\n"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { RefreshFamily, RefreshUpdate } from "@bgub/fig-reconciler/refresh";
2
+ //#region src/refresh.d.ts
3
+ declare function configureDomRefreshScheduler(scheduleRefresh: (update: RefreshUpdate) => void): void;
4
+ declare function scheduleRefresh(update: RefreshUpdate): void;
5
+ //#endregion
6
+ export { type RefreshFamily, type RefreshUpdate, configureDomRefreshScheduler, scheduleRefresh };
@@ -0,0 +1,2 @@
1
+ let e=null,t=null;function n(n){if(e=n,t!==null){let e=t;t=null;for(let t of e)n(t)}}function r(n){if(e===null){(t??=[]).push(n);return}e(n)}export{n as configureDomRefreshScheduler,r as scheduleRefresh};
2
+ //# sourceMappingURL=refresh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh.js","names":[],"sources":["../src/refresh.ts"],"sourcesContent":["import type {\n RefreshFamily,\n RefreshUpdate,\n} from \"@bgub/fig-reconciler/refresh\";\n\nlet scheduleDomRefresh: ((update: RefreshUpdate) => void) | null = null;\n\n// Updates that arrive before the @bgub/fig-dom main entry has evaluated (it\n// configures the scheduler as a module side effect). A code-split app can load\n// this entry first, and dropping those updates would silently skip a refresh.\nlet pendingUpdates: RefreshUpdate[] | null = null;\n\nexport type { RefreshFamily, RefreshUpdate };\n\nexport function configureDomRefreshScheduler(\n scheduleRefresh: (update: RefreshUpdate) => void,\n): void {\n scheduleDomRefresh = scheduleRefresh;\n\n if (pendingUpdates !== null) {\n const updates = pendingUpdates;\n pendingUpdates = null;\n for (const update of updates) scheduleRefresh(update);\n }\n}\n\nexport function scheduleRefresh(update: RefreshUpdate): void {\n if (scheduleDomRefresh === null) {\n (pendingUpdates ??= []).push(update);\n return;\n }\n\n scheduleDomRefresh(update);\n}\n"],"mappings":"AAKA,IAAI,EAA+D,KAK/D,EAAyC,KAI7C,SAAgB,EACd,EACM,CAGN,GAFA,EAAqB,EAEjB,IAAmB,KAAM,CAC3B,IAAM,EAAU,EAChB,EAAiB,KACjB,IAAK,IAAM,KAAU,EAAS,EAAgB,CAAM,CACtD,CACF,CAEA,SAAgB,EAAgB,EAA6B,CAC3D,GAAI,IAAuB,KAAM,EAC9B,IAAmB,CAAC,EAAA,CAAG,KAAK,CAAM,EACnC,MACF,CAEA,EAAmB,CAAM,CAC3B"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@bgub/fig-dom",
3
+ "version": "0.0.1",
4
+ "description": "Fig DOM renderer",
5
+ "keywords": [],
6
+ "homepage": "https://github.com/bgub/fig",
7
+ "type": "module",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "default": "./dist/index.js"
13
+ },
14
+ "./refresh": {
15
+ "types": "./dist/refresh.d.ts",
16
+ "import": "./dist/refresh.js",
17
+ "default": "./dist/refresh.js"
18
+ },
19
+ "./test-utils": {
20
+ "types": "./dist/act.d.ts",
21
+ "import": "./dist/act.js",
22
+ "default": "./dist/act.js"
23
+ },
24
+ "./package.json": "./package.json"
25
+ },
26
+ "types": "./dist/index.d.ts",
27
+ "files": [
28
+ "dist",
29
+ "CHANGELOG.md"
30
+ ],
31
+ "author": "Ben Gubler <nebrelbug@gmail.com>",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/bgub/fig",
35
+ "directory": "packages/fig-dom"
36
+ },
37
+ "bugs": {
38
+ "url": "https://github.com/bgub/fig/issues"
39
+ },
40
+ "license": "MIT",
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "peerDependencies": {
45
+ "@bgub/fig": "0.0.1",
46
+ "@bgub/fig-reconciler": "0.0.1"
47
+ },
48
+ "devDependencies": {
49
+ "@bgub/fig": "0.0.1",
50
+ "@bgub/fig-reconciler": "0.0.1",
51
+ "@bgub/fig-server": "0.0.1"
52
+ },
53
+ "engines": {
54
+ "node": "^20.19.0 || >=22.12.0"
55
+ },
56
+ "scripts": {
57
+ "build": "tsdown --config ../../tsdown.config.ts && node ../../scripts/strip-declaration-map-comments.mjs dist",
58
+ "test": "vitest run --config ../../vite.config.ts src"
59
+ }
60
+ }