@openelement/core 0.41.0-alpha.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.
Files changed (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +36 -0
  3. package/package.json +124 -0
  4. package/src/binding-activation.d.ts +2 -0
  5. package/src/binding-activation.js +254 -0
  6. package/src/binding-descriptor.d.ts +79 -0
  7. package/src/binding-descriptor.js +9 -0
  8. package/src/context.d.ts +32 -0
  9. package/src/context.js +76 -0
  10. package/src/csr.d.ts +13 -0
  11. package/src/csr.js +14 -0
  12. package/src/dsd-hydration-events.d.ts +2 -0
  13. package/src/dsd-hydration-events.js +13 -0
  14. package/src/dsd-hydration.d.ts +40 -0
  15. package/src/dsd-hydration.js +48 -0
  16. package/src/errors.d.ts +54 -0
  17. package/src/errors.js +113 -0
  18. package/src/event-hydration.d.ts +12 -0
  19. package/src/event-hydration.js +118 -0
  20. package/src/event-marker.d.ts +7 -0
  21. package/src/event-marker.js +54 -0
  22. package/src/html-escape.d.ts +29 -0
  23. package/src/html-escape.js +126 -0
  24. package/src/hydrate.d.ts +15 -0
  25. package/src/hydrate.js +15 -0
  26. package/src/index.d.ts +58 -0
  27. package/src/index.js +46 -0
  28. package/src/island-transform.d.ts +14 -0
  29. package/src/island-transform.js +60 -0
  30. package/src/island.d.ts +59 -0
  31. package/src/island.js +342 -0
  32. package/src/isr-runtime.d.ts +28 -0
  33. package/src/isr-runtime.js +99 -0
  34. package/src/isr.d.ts +22 -0
  35. package/src/isr.js +41 -0
  36. package/src/jsx-render-dom.d.ts +22 -0
  37. package/src/jsx-render-dom.js +376 -0
  38. package/src/jsx-runtime.d.ts +58 -0
  39. package/src/jsx-runtime.js +99 -0
  40. package/src/jsx-types.d.ts +46 -0
  41. package/src/logger.d.ts +15 -0
  42. package/src/logger.js +24 -0
  43. package/src/prop.d.ts +24 -0
  44. package/src/prop.js +160 -0
  45. package/src/registry.d.ts +17 -0
  46. package/src/registry.js +219 -0
  47. package/src/render-dsd-stream.d.ts +46 -0
  48. package/src/render-dsd-stream.js +86 -0
  49. package/src/render-dsd.d.ts +27 -0
  50. package/src/render-dsd.js +315 -0
  51. package/src/render-ir.d.ts +32 -0
  52. package/src/render-ir.js +245 -0
  53. package/src/runtime.d.ts +9 -0
  54. package/src/runtime.js +16 -0
  55. package/src/security.d.ts +1 -0
  56. package/src/security.js +40 -0
  57. package/src/signal-context.d.ts +15 -0
  58. package/src/signal-context.js +59 -0
  59. package/src/static.d.ts +35 -0
  60. package/src/static.js +34 -0
  61. package/src/style-sheet.d.ts +9 -0
  62. package/src/style-sheet.js +56 -0
  63. package/src/tag-utils.d.ts +11 -0
  64. package/src/tag-utils.js +28 -0
  65. package/src/vnode.d.ts +15 -0
  66. package/src/vnode.js +31 -0
@@ -0,0 +1,376 @@
1
+ /**
2
+ * Converts a VNode tree to real DOM nodes for client-side rendering and hydration.
3
+ *
4
+ * Design (ADR-0057 / ADR-0109 Phase 2):
5
+ * - Props are translated into BindingDescriptor objects
6
+ * - Binding descriptors are applied via applyBindingDescriptor()
7
+ * - Signal names are resolved through an optional signalRegistry and emitted as
8
+ * data-signal markers for DSD hydration consistency.
9
+ *
10
+ * @module @openelement/core/jsx-render-dom
11
+ */ import { isComponentCtor, isComponentFn, isVNode } from './vnode.js';
12
+ import { FOR_TAG, Fragment, HTML_TAG, SHOW_TAG } from './jsx-runtime.js';
13
+ import { isSignalLike, unwrapSignalLike } from '@openelement/signal';
14
+ import { eventTypeFromProp } from './event-hydration.js';
15
+ import { trustRenderHtml } from './security.js';
16
+ import { effect } from '@openelement/signal';
17
+ import { createLogger } from './logger.js';
18
+ import { formatError } from './errors.js';
19
+ import { applyBindingDescriptor } from './binding-activation.js';
20
+ import { DATA_SIGNAL } from '@openelement/protocol/hydration-markers';
21
+ const SVG_NS = 'http://www.w3.org/2000/svg';
22
+ /**
23
+ * Elements that MUST be created with createElementNS(SVG_NS, tag) to render
24
+ * correctly. Using createElement() puts them in the HTML namespace where
25
+ * browsers won't render them as SVG shapes.
26
+ */ const SVG_TAGS = new Set([
27
+ 'svg',
28
+ 'circle',
29
+ 'ellipse',
30
+ 'line',
31
+ 'path',
32
+ 'polygon',
33
+ 'polyline',
34
+ 'rect',
35
+ 'g',
36
+ 'defs',
37
+ 'clipPath',
38
+ 'mask',
39
+ 'pattern',
40
+ 'use',
41
+ 'symbol',
42
+ 'image',
43
+ 'text',
44
+ 'tspan',
45
+ 'textPath',
46
+ 'linearGradient',
47
+ 'radialGradient',
48
+ 'stop',
49
+ 'animate',
50
+ 'animateTransform',
51
+ 'animateMotion',
52
+ 'foreignObject',
53
+ 'title',
54
+ 'desc',
55
+ 'feBlend',
56
+ 'feColorMatrix',
57
+ 'feComponentTransfer',
58
+ 'feComposite',
59
+ 'feConvolveMatrix',
60
+ 'feDiffuseLighting',
61
+ 'feDisplacementMap',
62
+ 'feDistantLight',
63
+ 'feDropShadow',
64
+ 'feFlood',
65
+ 'feFuncA',
66
+ 'feFuncB',
67
+ 'feFuncG',
68
+ 'feFuncR',
69
+ 'feGaussianBlur',
70
+ 'feImage',
71
+ 'feMerge',
72
+ 'feMergeNode',
73
+ 'feMorphology',
74
+ 'feOffset',
75
+ 'fePointLight',
76
+ 'feSpecularLighting',
77
+ 'feSpotLight',
78
+ 'feTile',
79
+ 'feTurbulence'
80
+ ]);
81
+ function createElementForTag(tag) {
82
+ if (SVG_TAGS.has(tag)) {
83
+ return document.createElementNS(SVG_NS, tag);
84
+ }
85
+ return document.createElement(tag);
86
+ }
87
+ /** Resolve a signal object to its registered name, if any. */ function signalNameFor(value, signalRegistry) {
88
+ if (!signalRegistry || !isSignalLike(value)) return undefined;
89
+ for (const [name, sig] of signalRegistry.entries()){
90
+ if (sig === value) return name;
91
+ }
92
+ return undefined;
93
+ }
94
+ /**
95
+ * Collect BindingDescriptor objects from a JSX props object.
96
+ *
97
+ * @param el - Target element the descriptors will apply to.
98
+ * @param props - VNode props.
99
+ * @param signalRegistry - Optional registry used to name signals for hydration markers.
100
+ * @returns Array of binding descriptors.
101
+ */ export function collectPropBindings(el, props, signalRegistry) {
102
+ const descriptors = [];
103
+ const trustedHtml = props.trustedHtml === true;
104
+ for (const [key, value] of Object.entries(props)){
105
+ if (key === 'children' || key === 'key' || key === 'trustedHtml') continue;
106
+ // ref callback
107
+ if (key === 'ref' && typeof value === 'function') {
108
+ descriptors.push({
109
+ kind: 'ref',
110
+ el,
111
+ callback: value
112
+ });
113
+ continue;
114
+ }
115
+ // Event handlers
116
+ if (key.startsWith('on') && typeof value === 'function') {
117
+ const eventType = eventTypeFromProp(key);
118
+ if (!eventType) continue;
119
+ descriptors.push({
120
+ kind: 'event',
121
+ el,
122
+ type: eventType,
123
+ handler: value
124
+ });
125
+ continue;
126
+ }
127
+ if (value == null) continue;
128
+ // innerHTML maps to signal-html / static text injection.
129
+ if (key === 'innerHTML') {
130
+ if (isSignalLike(value)) {
131
+ descriptors.push({
132
+ kind: 'signal-html',
133
+ el,
134
+ signal: value,
135
+ trusted: trustedHtml
136
+ });
137
+ } else {
138
+ const resolved = String(unwrapSignalLike(value));
139
+ if (trustedHtml) {
140
+ el.innerHTML = trustRenderHtml(resolved);
141
+ } else {
142
+ el.textContent = resolved;
143
+ }
144
+ }
145
+ continue;
146
+ }
147
+ // Signal binding — emit data-signal marker when we can resolve a name.
148
+ if (isSignalLike(value)) {
149
+ const sig = value;
150
+ const name = signalNameFor(sig, signalRegistry);
151
+ const attrName = key === 'className' ? 'class' : key === 'htmlFor' ? 'for' : key;
152
+ if (name) {
153
+ el.setAttribute(DATA_SIGNAL, name);
154
+ }
155
+ if (key === 'className' || key === 'class') {
156
+ // ponytail: CSR signal-class only supports a single toggle class today;
157
+ // the string-prop branch below is unreachable because this block is gated
158
+ // by isSignalLike. Use explicit data-signal-class markers for arbitrary
159
+ // class names; revisit when signal-class accepts a class-name accessor.
160
+ const className = attrName === 'class' ? '' : attrName;
161
+ descriptors.push({
162
+ kind: 'signal-class',
163
+ el,
164
+ className,
165
+ signal: sig
166
+ });
167
+ } else {
168
+ descriptors.push({
169
+ kind: 'signal-attr',
170
+ el,
171
+ attrNames: [
172
+ attrName
173
+ ],
174
+ signal: sig
175
+ });
176
+ }
177
+ continue;
178
+ }
179
+ const resolved = unwrapSignalLike(value);
180
+ if (key === 'style' && typeof resolved === 'object' && resolved !== null) {
181
+ const styleObj = {};
182
+ for (const [sk, sv] of Object.entries(resolved)){
183
+ styleObj[sk] = unwrapSignalLike(sv);
184
+ }
185
+ descriptors.push({
186
+ kind: 'static-style',
187
+ el,
188
+ value: styleObj
189
+ });
190
+ continue;
191
+ }
192
+ // DOM properties that are NOT HTML attributes
193
+ if (key === 'textContent') {
194
+ descriptors.push({
195
+ kind: 'static-prop',
196
+ el,
197
+ propName: 'textContent',
198
+ value: resolved
199
+ });
200
+ continue;
201
+ }
202
+ const attrName = key === 'className' ? 'class' : key === 'htmlFor' ? 'for' : key;
203
+ if (typeof resolved === 'boolean') {
204
+ descriptors.push({
205
+ kind: 'static-boolean',
206
+ el,
207
+ attrName,
208
+ value: resolved
209
+ });
210
+ continue;
211
+ }
212
+ descriptors.push({
213
+ kind: 'static-attr',
214
+ el,
215
+ key,
216
+ attrName,
217
+ value: resolved
218
+ });
219
+ }
220
+ return descriptors;
221
+ }
222
+ /**
223
+ * Apply a props object to a real DOM element.
224
+ */ export function applyProps(el, props, lifecycle, signalRegistry) {
225
+ const descriptors = collectPropBindings(el, props, signalRegistry);
226
+ for (const desc of descriptors){
227
+ applyBindingDescriptor(desc, lifecycle ?? {});
228
+ }
229
+ }
230
+ /**
231
+ * Render a VNode tree to a real DOM node.
232
+ *
233
+ * @param node - VNode, string, number, or null/undefined
234
+ * @param lifecycle - Optional BindingLifecycle for automatic cleanup
235
+ * @param disposers - Optional Set to collect effect dispose fns (backward compat)
236
+ * @param signalRegistry - Optional registry used to resolve signal names for markers
237
+ * @returns DOM Node (Element, Text, or DocumentFragment)
238
+ */ export function renderToDom(node, lifecycle, disposers, signalRegistry) {
239
+ const fullLifecycle = lifecycle ?? (disposers ? {
240
+ disposers
241
+ } : {});
242
+ if (disposers && !lifecycle?.disposers) {
243
+ fullLifecycle.disposers = disposers;
244
+ }
245
+ if (node == null || node === false) {
246
+ return document.createTextNode('');
247
+ }
248
+ if (typeof node === 'string') {
249
+ return document.createTextNode(node);
250
+ }
251
+ if (typeof node === 'number' || typeof node === 'boolean') {
252
+ return document.createTextNode(String(node));
253
+ }
254
+ // Signal-to-TextNode reactive binding (ADR-0058/0059).
255
+ if (isSignalLike(node)) {
256
+ const sig = node;
257
+ const textNode = document.createTextNode(String(sig.value ?? ''));
258
+ applyBindingDescriptor({
259
+ kind: 'signal-text',
260
+ el: textNode,
261
+ signal: sig
262
+ }, fullLifecycle);
263
+ return textNode;
264
+ }
265
+ if (!isVNode(node)) {
266
+ return document.createTextNode(String(node));
267
+ }
268
+ const { tag, props, children } = node;
269
+ if (tag === Fragment || typeof tag === 'symbol' && String(tag) === 'Symbol(openelement.fragment)') {
270
+ const frag = document.createDocumentFragment();
271
+ for (const child of children){
272
+ frag.appendChild(renderToDom(child, fullLifecycle, undefined, signalRegistry));
273
+ }
274
+ return frag;
275
+ }
276
+ // Trusted HTML — parse raw HTML string into real DOM nodes
277
+ if (tag === HTML_TAG) {
278
+ const container = document.createElement('div');
279
+ const html = props?.html ?? '';
280
+ container.innerHTML = trustRenderHtml(String(html));
281
+ const frag = document.createDocumentFragment();
282
+ while(container.firstChild){
283
+ frag.appendChild(container.firstChild);
284
+ }
285
+ return frag;
286
+ }
287
+ if (tag === SHOW_TAG || tag === 'show') {
288
+ const whenSig = props?.when;
289
+ const ch = children;
290
+ const truthy = ch[0];
291
+ const falsy = ch[1];
292
+ const marker = document.createComment('show');
293
+ let anchor = null;
294
+ const swap = ()=>{
295
+ const show = Boolean(isSignalLike(whenSig) ? whenSig.value : whenSig);
296
+ const target = show ? truthy : falsy;
297
+ if (anchor) anchor.remove();
298
+ if (target != null) {
299
+ anchor = renderToDom(target, fullLifecycle, undefined, signalRegistry);
300
+ marker.parentNode?.insertBefore(anchor, marker.nextSibling);
301
+ } else {
302
+ anchor = null;
303
+ }
304
+ };
305
+ const dispose = effect(()=>swap());
306
+ if (fullLifecycle.signal) {
307
+ fullLifecycle.signal.addEventListener('abort', dispose, {
308
+ once: true
309
+ });
310
+ }
311
+ fullLifecycle.disposers?.add(dispose);
312
+ swap();
313
+ return marker;
314
+ }
315
+ if (tag === FOR_TAG || tag === 'fore') {
316
+ const eachSig = props?.each;
317
+ const renderFn = children[0] ?? (()=>document.createTextNode(''));
318
+ const marker = document.createComment('for');
319
+ let anchors = [];
320
+ const reconcile = ()=>{
321
+ const items = isSignalLike(eachSig) ? eachSig.value : eachSig;
322
+ if (!Array.isArray(items)) return;
323
+ // Remove old
324
+ for (const a of anchors)a.remove();
325
+ anchors = [];
326
+ // Render new
327
+ for(let i = 0; i < items.length; i++){
328
+ const vn = renderFn(items[i], i);
329
+ const dom = renderToDom(vn, fullLifecycle, undefined, signalRegistry);
330
+ marker.parentNode?.insertBefore(dom, marker.nextSibling);
331
+ anchors.push(dom);
332
+ }
333
+ };
334
+ const dispose = effect(()=>reconcile());
335
+ if (fullLifecycle.signal) {
336
+ fullLifecycle.signal.addEventListener('abort', dispose, {
337
+ once: true
338
+ });
339
+ }
340
+ fullLifecycle.disposers?.add(dispose);
341
+ reconcile();
342
+ return marker;
343
+ }
344
+ if (isComponentCtor(tag)) {
345
+ try {
346
+ const instance = new tag();
347
+ for (const [k, v] of Object.entries(props)){
348
+ instance[k] = v;
349
+ }
350
+ const result = instance.render();
351
+ return renderToDom(result, fullLifecycle, undefined, signalRegistry);
352
+ } catch (err) {
353
+ createLogger('dom-render').error(`renderToDom() failed for <${String(tag)}>: ${formatError(err)}`);
354
+ return document.createTextNode('');
355
+ }
356
+ }
357
+ if (isComponentFn(tag)) {
358
+ try {
359
+ const result = tag({
360
+ ...props,
361
+ children
362
+ });
363
+ return renderToDom(result, fullLifecycle, undefined, signalRegistry);
364
+ } catch (err) {
365
+ createLogger('dom-render').error(`renderToDom() failed for <${String(tag)}>: ${formatError(err)}`);
366
+ return document.createTextNode('');
367
+ }
368
+ }
369
+ const el = createElementForTag(tag);
370
+ applyProps(el, props, fullLifecycle, signalRegistry);
371
+ for (const child of children){
372
+ el.appendChild(renderToDom(child, fullLifecycle, undefined, signalRegistry));
373
+ }
374
+ return el;
375
+ }
376
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9vcGVuZWxlbWVudC9vcGVuZWxlbWVudC9wYWNrYWdlcy9jb3JlL3NyYy9qc3gtcmVuZGVyLWRvbS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbnZlcnRzIGEgVk5vZGUgdHJlZSB0byByZWFsIERPTSBub2RlcyBmb3IgY2xpZW50LXNpZGUgcmVuZGVyaW5nIGFuZCBoeWRyYXRpb24uXG4gKlxuICogRGVzaWduIChBRFItMDA1NyAvIEFEUi0wMTA5IFBoYXNlIDIpOlxuICogLSBQcm9wcyBhcmUgdHJhbnNsYXRlZCBpbnRvIEJpbmRpbmdEZXNjcmlwdG9yIG9iamVjdHNcbiAqIC0gQmluZGluZyBkZXNjcmlwdG9ycyBhcmUgYXBwbGllZCB2aWEgYXBwbHlCaW5kaW5nRGVzY3JpcHRvcigpXG4gKiAtIFNpZ25hbCBuYW1lcyBhcmUgcmVzb2x2ZWQgdGhyb3VnaCBhbiBvcHRpb25hbCBzaWduYWxSZWdpc3RyeSBhbmQgZW1pdHRlZCBhc1xuICogICBkYXRhLXNpZ25hbCBtYXJrZXJzIGZvciBEU0QgaHlkcmF0aW9uIGNvbnNpc3RlbmN5LlxuICpcbiAqIEBtb2R1bGUgQG9wZW5lbGVtZW50L2NvcmUvanN4LXJlbmRlci1kb21cbiAqL1xuXG5pbXBvcnQgeyBpc0NvbXBvbmVudEN0b3IsIGlzQ29tcG9uZW50Rm4sIGlzVk5vZGUgfSBmcm9tICcuL3Zub2RlLmpzJztcbmltcG9ydCB0eXBlIHsgUmVuZGVyRm4sIFZOb2RlIH0gZnJvbSAnQG9wZW5lbGVtZW50L3Byb3RvY29sL3Zub2RlJztcbmltcG9ydCB0eXBlIHsgU2lnbmFsIH0gZnJvbSAnQG9wZW5lbGVtZW50L3Byb3RvY29sL3NpZ25hbCc7XG5pbXBvcnQgeyBGT1JfVEFHLCBGcmFnbWVudCwgSFRNTF9UQUcsIFNIT1dfVEFHIH0gZnJvbSAnLi9qc3gtcnVudGltZS5qcyc7XG5pbXBvcnQgeyBpc1NpZ25hbExpa2UsIHVud3JhcFNpZ25hbExpa2UgfSBmcm9tICdAb3BlbmVsZW1lbnQvc2lnbmFsJztcbmltcG9ydCB7IGV2ZW50VHlwZUZyb21Qcm9wIH0gZnJvbSAnLi9ldmVudC1oeWRyYXRpb24uanMnO1xuaW1wb3J0IHsgdHJ1c3RSZW5kZXJIdG1sIH0gZnJvbSAnLi9zZWN1cml0eS5qcyc7XG5pbXBvcnQgeyBlZmZlY3QgfSBmcm9tICdAb3BlbmVsZW1lbnQvc2lnbmFsJztcbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyLmpzJztcbmltcG9ydCB7IGZvcm1hdEVycm9yIH0gZnJvbSAnLi9lcnJvcnMuanMnO1xuaW1wb3J0IHsgYXBwbHlCaW5kaW5nRGVzY3JpcHRvciB9IGZyb20gJy4vYmluZGluZy1hY3RpdmF0aW9uLmpzJztcbmltcG9ydCB0eXBlIHsgQmluZGluZ0Rlc2NyaXB0b3IsIEJpbmRpbmdMaWZlY3ljbGUgfSBmcm9tICcuL2JpbmRpbmctZGVzY3JpcHRvci5qcyc7XG5pbXBvcnQgeyBEQVRBX1NJR05BTCB9IGZyb20gJ0BvcGVuZWxlbWVudC9wcm90b2NvbC9oeWRyYXRpb24tbWFya2Vycyc7XG5cbmNvbnN0IFNWR19OUyA9ICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc7XG5cbi8qKlxuICogRWxlbWVudHMgdGhhdCBNVVNUIGJlIGNyZWF0ZWQgd2l0aCBjcmVhdGVFbGVtZW50TlMoU1ZHX05TLCB0YWcpIHRvIHJlbmRlclxuICogY29ycmVjdGx5LiBVc2luZyBjcmVhdGVFbGVtZW50KCkgcHV0cyB0aGVtIGluIHRoZSBIVE1MIG5hbWVzcGFjZSB3aGVyZVxuICogYnJvd3NlcnMgd29uJ3QgcmVuZGVyIHRoZW0gYXMgU1ZHIHNoYXBlcy5cbiAqL1xuY29uc3QgU1ZHX1RBR1MgPSBuZXcgU2V0KFtcbiAgJ3N2ZycsXG4gICdjaXJjbGUnLFxuICAnZWxsaXBzZScsXG4gICdsaW5lJyxcbiAgJ3BhdGgnLFxuICAncG9seWdvbicsXG4gICdwb2x5bGluZScsXG4gICdyZWN0JyxcbiAgJ2cnLFxuICAnZGVmcycsXG4gICdjbGlwUGF0aCcsXG4gICdtYXNrJyxcbiAgJ3BhdHRlcm4nLFxuICAndXNlJyxcbiAgJ3N5bWJvbCcsXG4gICdpbWFnZScsXG4gICd0ZXh0JyxcbiAgJ3RzcGFuJyxcbiAgJ3RleHRQYXRoJyxcbiAgJ2xpbmVhckdyYWRpZW50JyxcbiAgJ3JhZGlhbEdyYWRpZW50JyxcbiAgJ3N0b3AnLFxuICAnYW5pbWF0ZScsXG4gICdhbmltYXRlVHJhbnNmb3JtJyxcbiAgJ2FuaW1hdGVNb3Rpb24nLFxuICAnZm9yZWlnbk9iamVjdCcsXG4gICd0aXRsZScsXG4gICdkZXNjJyxcbiAgJ2ZlQmxlbmQnLFxuICAnZmVDb2xvck1hdHJpeCcsXG4gICdmZUNvbXBvbmVudFRyYW5zZmVyJyxcbiAgJ2ZlQ29tcG9zaXRlJyxcbiAgJ2ZlQ29udm9sdmVNYXRyaXgnLFxuICAnZmVEaWZmdXNlTGlnaHRpbmcnLFxuICAnZmVEaXNwbGFjZW1lbnRNYXAnLFxuICAnZmVEaXN0YW50TGlnaHQnLFxuICAnZmVEcm9wU2hhZG93JyxcbiAgJ2ZlRmxvb2QnLFxuICAnZmVGdW5jQScsXG4gICdmZUZ1bmNCJyxcbiAgJ2ZlRnVuY0cnLFxuICAnZmVGdW5jUicsXG4gICdmZUdhdXNzaWFuQmx1cicsXG4gICdmZUltYWdlJyxcbiAgJ2ZlTWVyZ2UnLFxuICAnZmVNZXJnZU5vZGUnLFxuICAnZmVNb3JwaG9sb2d5JyxcbiAgJ2ZlT2Zmc2V0JyxcbiAgJ2ZlUG9pbnRMaWdodCcsXG4gICdmZVNwZWN1bGFyTGlnaHRpbmcnLFxuICAnZmVTcG90TGlnaHQnLFxuICAnZmVUaWxlJyxcbiAgJ2ZlVHVyYnVsZW5jZScsXG5dKTtcblxuZnVuY3Rpb24gY3JlYXRlRWxlbWVudEZvclRhZyh0YWc6IHN0cmluZyk6IEVsZW1lbnQge1xuICBpZiAoU1ZHX1RBR1MuaGFzKHRhZykpIHtcbiAgICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFNWR19OUywgdGFnKTtcbiAgfVxuICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWcpO1xufVxuXG4vKiogUmVzb2x2ZSBhIHNpZ25hbCBvYmplY3QgdG8gaXRzIHJlZ2lzdGVyZWQgbmFtZSwgaWYgYW55LiAqL1xuZnVuY3Rpb24gc2lnbmFsTmFtZUZvcihcbiAgdmFsdWU6IHVua25vd24sXG4gIHNpZ25hbFJlZ2lzdHJ5PzogTWFwPHN0cmluZywgU2lnbmFsPHVua25vd24+Pixcbik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICghc2lnbmFsUmVnaXN0cnkgfHwgIWlzU2lnbmFsTGlrZSh2YWx1ZSkpIHJldHVybiB1bmRlZmluZWQ7XG4gIGZvciAoY29uc3QgW25hbWUsIHNpZ10gb2Ygc2lnbmFsUmVnaXN0cnkuZW50cmllcygpKSB7XG4gICAgaWYgKHNpZyA9PT0gdmFsdWUpIHJldHVybiBuYW1lO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogQ29sbGVjdCBCaW5kaW5nRGVzY3JpcHRvciBvYmplY3RzIGZyb20gYSBKU1ggcHJvcHMgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSBlbCAtIFRhcmdldCBlbGVtZW50IHRoZSBkZXNjcmlwdG9ycyB3aWxsIGFwcGx5IHRvLlxuICogQHBhcmFtIHByb3BzIC0gVk5vZGUgcHJvcHMuXG4gKiBAcGFyYW0gc2lnbmFsUmVnaXN0cnkgLSBPcHRpb25hbCByZWdpc3RyeSB1c2VkIHRvIG5hbWUgc2lnbmFscyBmb3IgaHlkcmF0aW9uIG1hcmtlcnMuXG4gKiBAcmV0dXJucyBBcnJheSBvZiBiaW5kaW5nIGRlc2NyaXB0b3JzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29sbGVjdFByb3BCaW5kaW5ncyhcbiAgZWw6IEVsZW1lbnQsXG4gIHByb3BzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgc2lnbmFsUmVnaXN0cnk/OiBNYXA8c3RyaW5nLCBTaWduYWw8dW5rbm93bj4+LFxuKTogQmluZGluZ0Rlc2NyaXB0b3JbXSB7XG4gIGNvbnN0IGRlc2NyaXB0b3JzOiBCaW5kaW5nRGVzY3JpcHRvcltdID0gW107XG4gIGNvbnN0IHRydXN0ZWRIdG1sID0gcHJvcHMudHJ1c3RlZEh0bWwgPT09IHRydWU7XG5cbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHMpKSB7XG4gICAgaWYgKGtleSA9PT0gJ2NoaWxkcmVuJyB8fCBrZXkgPT09ICdrZXknIHx8IGtleSA9PT0gJ3RydXN0ZWRIdG1sJykgY29udGludWU7XG5cbiAgICAvLyByZWYgY2FsbGJhY2tcbiAgICBpZiAoa2V5ID09PSAncmVmJyAmJiB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGRlc2NyaXB0b3JzLnB1c2goeyBraW5kOiAncmVmJywgZWwsIGNhbGxiYWNrOiB2YWx1ZSBhcyAoZWw6IEVsZW1lbnQpID0+IHZvaWQgfSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyBFdmVudCBoYW5kbGVyc1xuICAgIGlmIChrZXkuc3RhcnRzV2l0aCgnb24nKSAmJiB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGNvbnN0IGV2ZW50VHlwZSA9IGV2ZW50VHlwZUZyb21Qcm9wKGtleSk7XG4gICAgICBpZiAoIWV2ZW50VHlwZSkgY29udGludWU7XG4gICAgICBkZXNjcmlwdG9ycy5wdXNoKHsga2luZDogJ2V2ZW50JywgZWwsIHR5cGU6IGV2ZW50VHlwZSwgaGFuZGxlcjogdmFsdWUgYXMgRXZlbnRMaXN0ZW5lciB9KTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmICh2YWx1ZSA9PSBudWxsKSBjb250aW51ZTtcblxuICAgIC8vIGlubmVySFRNTCBtYXBzIHRvIHNpZ25hbC1odG1sIC8gc3RhdGljIHRleHQgaW5qZWN0aW9uLlxuICAgIGlmIChrZXkgPT09ICdpbm5lckhUTUwnKSB7XG4gICAgICBpZiAoaXNTaWduYWxMaWtlKHZhbHVlKSkge1xuICAgICAgICBkZXNjcmlwdG9ycy5wdXNoKHtcbiAgICAgICAgICBraW5kOiAnc2lnbmFsLWh0bWwnLFxuICAgICAgICAgIGVsLFxuICAgICAgICAgIHNpZ25hbDogdmFsdWUgYXMgU2lnbmFsPHVua25vd24+LFxuICAgICAgICAgIHRydXN0ZWQ6IHRydXN0ZWRIdG1sLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHJlc29sdmVkID0gU3RyaW5nKHVud3JhcFNpZ25hbExpa2UodmFsdWUpKTtcbiAgICAgICAgaWYgKHRydXN0ZWRIdG1sKSB7XG4gICAgICAgICAgKGVsIGFzIEhUTUxFbGVtZW50KS5pbm5lckhUTUwgPSB0cnVzdFJlbmRlckh0bWwocmVzb2x2ZWQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIChlbCBhcyBIVE1MRWxlbWVudCkudGV4dENvbnRlbnQgPSByZXNvbHZlZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gU2lnbmFsIGJpbmRpbmcg4oCUIGVtaXQgZGF0YS1zaWduYWwgbWFya2VyIHdoZW4gd2UgY2FuIHJlc29sdmUgYSBuYW1lLlxuICAgIGlmIChpc1NpZ25hbExpa2UodmFsdWUpKSB7XG4gICAgICBjb25zdCBzaWcgPSB2YWx1ZSBhcyBTaWduYWw8dW5rbm93bj47XG4gICAgICBjb25zdCBuYW1lID0gc2lnbmFsTmFtZUZvcihzaWcsIHNpZ25hbFJlZ2lzdHJ5KTtcbiAgICAgIGNvbnN0IGF0dHJOYW1lID0ga2V5ID09PSAnY2xhc3NOYW1lJyA/ICdjbGFzcycgOiBrZXkgPT09ICdodG1sRm9yJyA/ICdmb3InIDoga2V5O1xuXG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoREFUQV9TSUdOQUwsIG5hbWUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoa2V5ID09PSAnY2xhc3NOYW1lJyB8fCBrZXkgPT09ICdjbGFzcycpIHtcbiAgICAgICAgLy8gcG9ueXRhaWw6IENTUiBzaWduYWwtY2xhc3Mgb25seSBzdXBwb3J0cyBhIHNpbmdsZSB0b2dnbGUgY2xhc3MgdG9kYXk7XG4gICAgICAgIC8vIHRoZSBzdHJpbmctcHJvcCBicmFuY2ggYmVsb3cgaXMgdW5yZWFjaGFibGUgYmVjYXVzZSB0aGlzIGJsb2NrIGlzIGdhdGVkXG4gICAgICAgIC8vIGJ5IGlzU2lnbmFsTGlrZS4gVXNlIGV4cGxpY2l0IGRhdGEtc2lnbmFsLWNsYXNzIG1hcmtlcnMgZm9yIGFyYml0cmFyeVxuICAgICAgICAvLyBjbGFzcyBuYW1lczsgcmV2aXNpdCB3aGVuIHNpZ25hbC1jbGFzcyBhY2NlcHRzIGEgY2xhc3MtbmFtZSBhY2Nlc3Nvci5cbiAgICAgICAgY29uc3QgY2xhc3NOYW1lID0gYXR0ck5hbWUgPT09ICdjbGFzcycgPyAnJyA6IGF0dHJOYW1lO1xuICAgICAgICBkZXNjcmlwdG9ycy5wdXNoKHtcbiAgICAgICAgICBraW5kOiAnc2lnbmFsLWNsYXNzJyxcbiAgICAgICAgICBlbCxcbiAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgc2lnbmFsOiBzaWcsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVzY3JpcHRvcnMucHVzaCh7IGtpbmQ6ICdzaWduYWwtYXR0cicsIGVsLCBhdHRyTmFtZXM6IFthdHRyTmFtZV0sIHNpZ25hbDogc2lnIH0pO1xuICAgICAgfVxuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzb2x2ZWQgPSB1bndyYXBTaWduYWxMaWtlKHZhbHVlKTtcblxuICAgIGlmIChrZXkgPT09ICdzdHlsZScgJiYgdHlwZW9mIHJlc29sdmVkID09PSAnb2JqZWN0JyAmJiByZXNvbHZlZCAhPT0gbnVsbCkge1xuICAgICAgY29uc3Qgc3R5bGVPYmo6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IG51bWJlcj4gPSB7fTtcbiAgICAgIGZvciAoY29uc3QgW3NrLCBzdl0gb2YgT2JqZWN0LmVudHJpZXMocmVzb2x2ZWQgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pKSB7XG4gICAgICAgIHN0eWxlT2JqW3NrXSA9IHVud3JhcFNpZ25hbExpa2Uoc3YpIGFzIHN0cmluZyB8IG51bWJlcjtcbiAgICAgIH1cbiAgICAgIGRlc2NyaXB0b3JzLnB1c2goeyBraW5kOiAnc3RhdGljLXN0eWxlJywgZWwsIHZhbHVlOiBzdHlsZU9iaiB9KTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIERPTSBwcm9wZXJ0aWVzIHRoYXQgYXJlIE5PVCBIVE1MIGF0dHJpYnV0ZXNcbiAgICBpZiAoa2V5ID09PSAndGV4dENvbnRlbnQnKSB7XG4gICAgICBkZXNjcmlwdG9ycy5wdXNoKHsga2luZDogJ3N0YXRpYy1wcm9wJywgZWwsIHByb3BOYW1lOiAndGV4dENvbnRlbnQnLCB2YWx1ZTogcmVzb2x2ZWQgfSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBhdHRyTmFtZSA9IGtleSA9PT0gJ2NsYXNzTmFtZScgPyAnY2xhc3MnIDoga2V5ID09PSAnaHRtbEZvcicgPyAnZm9yJyA6IGtleTtcblxuICAgIGlmICh0eXBlb2YgcmVzb2x2ZWQgPT09ICdib29sZWFuJykge1xuICAgICAgZGVzY3JpcHRvcnMucHVzaCh7IGtpbmQ6ICdzdGF0aWMtYm9vbGVhbicsIGVsLCBhdHRyTmFtZSwgdmFsdWU6IHJlc29sdmVkIH0pO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgZGVzY3JpcHRvcnMucHVzaCh7IGtpbmQ6ICdzdGF0aWMtYXR0cicsIGVsLCBrZXksIGF0dHJOYW1lLCB2YWx1ZTogcmVzb2x2ZWQgfSk7XG4gIH1cblxuICByZXR1cm4gZGVzY3JpcHRvcnM7XG59XG5cbi8qKlxuICogQXBwbHkgYSBwcm9wcyBvYmplY3QgdG8gYSByZWFsIERPTSBlbGVtZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlQcm9wcyhcbiAgZWw6IEVsZW1lbnQsXG4gIHByb3BzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgbGlmZWN5Y2xlPzogQmluZGluZ0xpZmVjeWNsZSxcbiAgc2lnbmFsUmVnaXN0cnk/OiBNYXA8c3RyaW5nLCBTaWduYWw8dW5rbm93bj4+LFxuKTogdm9pZCB7XG4gIGNvbnN0IGRlc2NyaXB0b3JzID0gY29sbGVjdFByb3BCaW5kaW5ncyhlbCwgcHJvcHMsIHNpZ25hbFJlZ2lzdHJ5KTtcbiAgZm9yIChjb25zdCBkZXNjIG9mIGRlc2NyaXB0b3JzKSB7XG4gICAgYXBwbHlCaW5kaW5nRGVzY3JpcHRvcihkZXNjLCBsaWZlY3ljbGUgPz8ge30pO1xuICB9XG59XG5cbi8qKlxuICogUmVuZGVyIGEgVk5vZGUgdHJlZSB0byBhIHJlYWwgRE9NIG5vZGUuXG4gKlxuICogQHBhcmFtIG5vZGUgLSBWTm9kZSwgc3RyaW5nLCBudW1iZXIsIG9yIG51bGwvdW5kZWZpbmVkXG4gKiBAcGFyYW0gbGlmZWN5Y2xlIC0gT3B0aW9uYWwgQmluZGluZ0xpZmVjeWNsZSBmb3IgYXV0b21hdGljIGNsZWFudXBcbiAqIEBwYXJhbSBkaXNwb3NlcnMgLSBPcHRpb25hbCBTZXQgdG8gY29sbGVjdCBlZmZlY3QgZGlzcG9zZSBmbnMgKGJhY2t3YXJkIGNvbXBhdClcbiAqIEBwYXJhbSBzaWduYWxSZWdpc3RyeSAtIE9wdGlvbmFsIHJlZ2lzdHJ5IHVzZWQgdG8gcmVzb2x2ZSBzaWduYWwgbmFtZXMgZm9yIG1hcmtlcnNcbiAqIEByZXR1cm5zIERPTSBOb2RlIChFbGVtZW50LCBUZXh0LCBvciBEb2N1bWVudEZyYWdtZW50KVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyVG9Eb20oXG4gIG5vZGU6IHVua25vd24sXG4gIGxpZmVjeWNsZT86IEJpbmRpbmdMaWZlY3ljbGUsXG4gIGRpc3Bvc2Vycz86IFNldDwoKSA9PiB2b2lkPixcbiAgc2lnbmFsUmVnaXN0cnk/OiBNYXA8c3RyaW5nLCBTaWduYWw8dW5rbm93bj4+LFxuKTogTm9kZSB7XG4gIGNvbnN0IGZ1bGxMaWZlY3ljbGU6IEJpbmRpbmdMaWZlY3ljbGUgPSBsaWZlY3ljbGUgPz8gKGRpc3Bvc2VycyA/IHsgZGlzcG9zZXJzIH0gOiB7fSk7XG4gIGlmIChkaXNwb3NlcnMgJiYgIWxpZmVjeWNsZT8uZGlzcG9zZXJzKSB7XG4gICAgZnVsbExpZmVjeWNsZS5kaXNwb3NlcnMgPSBkaXNwb3NlcnM7XG4gIH1cblxuICBpZiAobm9kZSA9PSBudWxsIHx8IG5vZGUgPT09IGZhbHNlKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCcnKTtcbiAgfVxuICBpZiAodHlwZW9mIG5vZGUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKG5vZGUpO1xuICB9XG4gIGlmICh0eXBlb2Ygbm9kZSA9PT0gJ251bWJlcicgfHwgdHlwZW9mIG5vZGUgPT09ICdib29sZWFuJykge1xuICAgIHJldHVybiBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShTdHJpbmcobm9kZSkpO1xuICB9XG5cbiAgLy8gU2lnbmFsLXRvLVRleHROb2RlIHJlYWN0aXZlIGJpbmRpbmcgKEFEUi0wMDU4LzAwNTkpLlxuICBpZiAoaXNTaWduYWxMaWtlKG5vZGUpKSB7XG4gICAgY29uc3Qgc2lnID0gbm9kZSBhcyBTaWduYWw8dW5rbm93bj47XG4gICAgY29uc3QgdGV4dE5vZGUgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShTdHJpbmcoc2lnLnZhbHVlID8/ICcnKSk7XG4gICAgYXBwbHlCaW5kaW5nRGVzY3JpcHRvcih7IGtpbmQ6ICdzaWduYWwtdGV4dCcsIGVsOiB0ZXh0Tm9kZSwgc2lnbmFsOiBzaWcgfSwgZnVsbExpZmVjeWNsZSk7XG4gICAgcmV0dXJuIHRleHROb2RlO1xuICB9XG5cbiAgaWYgKCFpc1ZOb2RlKG5vZGUpKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKFN0cmluZyhub2RlKSk7XG4gIH1cblxuICBjb25zdCB7IHRhZywgcHJvcHMsIGNoaWxkcmVuIH0gPSBub2RlIGFzIFZOb2RlO1xuXG4gIGlmIChcbiAgICB0YWcgPT09IEZyYWdtZW50IHx8ICh0eXBlb2YgdGFnID09PSAnc3ltYm9sJyAmJiBTdHJpbmcodGFnKSA9PT0gJ1N5bWJvbChvcGVuZWxlbWVudC5mcmFnbWVudCknKVxuICApIHtcbiAgICBjb25zdCBmcmFnID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICAgIGZvciAoY29uc3QgY2hpbGQgb2YgY2hpbGRyZW4pIHtcbiAgICAgIGZyYWcuYXBwZW5kQ2hpbGQocmVuZGVyVG9Eb20oY2hpbGQsIGZ1bGxMaWZlY3ljbGUsIHVuZGVmaW5lZCwgc2lnbmFsUmVnaXN0cnkpKTtcbiAgICB9XG4gICAgcmV0dXJuIGZyYWc7XG4gIH1cblxuICAvLyBUcnVzdGVkIEhUTUwg4oCUIHBhcnNlIHJhdyBIVE1MIHN0cmluZyBpbnRvIHJlYWwgRE9NIG5vZGVzXG4gIGlmICh0YWcgPT09IEhUTUxfVEFHKSB7XG4gICAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgY29uc3QgaHRtbCA9IHByb3BzPy5odG1sID8/ICcnO1xuICAgIGNvbnRhaW5lci5pbm5lckhUTUwgPSB0cnVzdFJlbmRlckh0bWwoU3RyaW5nKGh0bWwpKTtcbiAgICBjb25zdCBmcmFnID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICAgIHdoaWxlIChjb250YWluZXIuZmlyc3RDaGlsZCkge1xuICAgICAgZnJhZy5hcHBlbmRDaGlsZChjb250YWluZXIuZmlyc3RDaGlsZCk7XG4gICAgfVxuICAgIHJldHVybiBmcmFnO1xuICB9XG5cbiAgaWYgKHRhZyA9PT0gU0hPV19UQUcgfHwgdGFnID09PSAnc2hvdycpIHtcbiAgICBjb25zdCB3aGVuU2lnID0gcHJvcHM/LndoZW47XG4gICAgY29uc3QgY2ggPSBjaGlsZHJlbiBhcyBWTm9kZVtdO1xuICAgIGNvbnN0IHRydXRoeTogdW5rbm93biA9IGNoWzBdO1xuICAgIGNvbnN0IGZhbHN5OiB1bmtub3duID0gY2hbMV07XG4gICAgY29uc3QgbWFya2VyID0gZG9jdW1lbnQuY3JlYXRlQ29tbWVudCgnc2hvdycpO1xuXG4gICAgbGV0IGFuY2hvcjogQ2hpbGROb2RlIHwgbnVsbCA9IG51bGw7XG4gICAgY29uc3Qgc3dhcCA9ICgpID0+IHtcbiAgICAgIGNvbnN0IHNob3cgPSBCb29sZWFuKFxuICAgICAgICBpc1NpZ25hbExpa2Uod2hlblNpZykgPyAod2hlblNpZyBhcyB7IHZhbHVlOiB1bmtub3duIH0pLnZhbHVlIDogd2hlblNpZyxcbiAgICAgICk7XG4gICAgICBjb25zdCB0YXJnZXQgPSBzaG93ID8gdHJ1dGh5IDogZmFsc3k7XG4gICAgICBpZiAoYW5jaG9yKSBhbmNob3IucmVtb3ZlKCk7XG4gICAgICBpZiAodGFyZ2V0ICE9IG51bGwpIHtcbiAgICAgICAgYW5jaG9yID0gcmVuZGVyVG9Eb20odGFyZ2V0LCBmdWxsTGlmZWN5Y2xlLCB1bmRlZmluZWQsIHNpZ25hbFJlZ2lzdHJ5KSBhcyBDaGlsZE5vZGU7XG4gICAgICAgIG1hcmtlci5wYXJlbnROb2RlPy5pbnNlcnRCZWZvcmUoYW5jaG9yLCBtYXJrZXIubmV4dFNpYmxpbmcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYW5jaG9yID0gbnVsbDtcbiAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0IGRpc3Bvc2UgPSBlZmZlY3QoKCkgPT4gc3dhcCgpKTtcbiAgICBpZiAoZnVsbExpZmVjeWNsZS5zaWduYWwpIHtcbiAgICAgIGZ1bGxMaWZlY3ljbGUuc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgZGlzcG9zZSwgeyBvbmNlOiB0cnVlIH0pO1xuICAgIH1cbiAgICBmdWxsTGlmZWN5Y2xlLmRpc3Bvc2Vycz8uYWRkKGRpc3Bvc2UpO1xuICAgIHN3YXAoKTtcbiAgICByZXR1cm4gbWFya2VyO1xuICB9XG5cbiAgaWYgKHRhZyA9PT0gRk9SX1RBRyB8fCB0YWcgPT09ICdmb3JlJykge1xuICAgIGNvbnN0IGVhY2hTaWcgPSBwcm9wcz8uZWFjaDtcbiAgICBjb25zdCByZW5kZXJGbiA9IChjaGlsZHJlblswXSBhcyBSZW5kZXJGbikgPz9cbiAgICAgICgoKCkgPT4gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJycpIGFzIHVua25vd24pIGFzIFJlbmRlckZuKTtcblxuICAgIGNvbnN0IG1hcmtlciA9IGRvY3VtZW50LmNyZWF0ZUNvbW1lbnQoJ2ZvcicpO1xuICAgIGxldCBhbmNob3JzOiBDaGlsZE5vZGVbXSA9IFtdO1xuXG4gICAgY29uc3QgcmVjb25jaWxlID0gKCkgPT4ge1xuICAgICAgY29uc3QgaXRlbXMgPVxuICAgICAgICAoaXNTaWduYWxMaWtlKGVhY2hTaWcpID8gKGVhY2hTaWcgYXMgeyB2YWx1ZTogdW5rbm93biB9KS52YWx1ZSA6IGVhY2hTaWcpIGFzIHVua25vd25bXTtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShpdGVtcykpIHJldHVybjtcblxuICAgICAgLy8gUmVtb3ZlIG9sZFxuICAgICAgZm9yIChjb25zdCBhIG9mIGFuY2hvcnMpIGEucmVtb3ZlKCk7XG4gICAgICBhbmNob3JzID0gW107XG5cbiAgICAgIC8vIFJlbmRlciBuZXdcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3Qgdm4gPSByZW5kZXJGbihpdGVtc1tpXSwgaSk7XG4gICAgICAgIGNvbnN0IGRvbSA9IHJlbmRlclRvRG9tKHZuLCBmdWxsTGlmZWN5Y2xlLCB1bmRlZmluZWQsIHNpZ25hbFJlZ2lzdHJ5KSBhcyBDaGlsZE5vZGU7XG4gICAgICAgIG1hcmtlci5wYXJlbnROb2RlPy5pbnNlcnRCZWZvcmUoZG9tLCBtYXJrZXIubmV4dFNpYmxpbmcpO1xuICAgICAgICBhbmNob3JzLnB1c2goZG9tKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0IGRpc3Bvc2UgPSBlZmZlY3QoKCkgPT4gcmVjb25jaWxlKCkpO1xuICAgIGlmIChmdWxsTGlmZWN5Y2xlLnNpZ25hbCkge1xuICAgICAgZnVsbExpZmVjeWNsZS5zaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBkaXNwb3NlLCB7IG9uY2U6IHRydWUgfSk7XG4gICAgfVxuICAgIGZ1bGxMaWZlY3ljbGUuZGlzcG9zZXJzPy5hZGQoZGlzcG9zZSk7XG4gICAgcmVjb25jaWxlKCk7XG4gICAgcmV0dXJuIG1hcmtlcjtcbiAgfVxuXG4gIGlmIChpc0NvbXBvbmVudEN0b3IodGFnKSkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBpbnN0YW5jZSA9IG5ldyB0YWcoKTtcbiAgICAgIGZvciAoY29uc3QgW2ssIHZdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzKSkge1xuICAgICAgICAoaW5zdGFuY2UgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW2tdID0gdjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGluc3RhbmNlLnJlbmRlcigpO1xuICAgICAgcmV0dXJuIHJlbmRlclRvRG9tKHJlc3VsdCwgZnVsbExpZmVjeWNsZSwgdW5kZWZpbmVkLCBzaWduYWxSZWdpc3RyeSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjcmVhdGVMb2dnZXIoJ2RvbS1yZW5kZXInKS5lcnJvcihcbiAgICAgICAgYHJlbmRlclRvRG9tKCkgZmFpbGVkIGZvciA8JHtTdHJpbmcodGFnKX0+OiAke2Zvcm1hdEVycm9yKGVycil9YCxcbiAgICAgICk7XG4gICAgICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJycpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNDb21wb25lbnRGbih0YWcpKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHRhZyh7IC4uLnByb3BzLCBjaGlsZHJlbiB9KTtcbiAgICAgIHJldHVybiByZW5kZXJUb0RvbShyZXN1bHQsIGZ1bGxMaWZlY3ljbGUsIHVuZGVmaW5lZCwgc2lnbmFsUmVnaXN0cnkpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY3JlYXRlTG9nZ2VyKCdkb20tcmVuZGVyJykuZXJyb3IoXG4gICAgICAgIGByZW5kZXJUb0RvbSgpIGZhaWxlZCBmb3IgPCR7U3RyaW5nKHRhZyl9PjogJHtmb3JtYXRFcnJvcihlcnIpfWAsXG4gICAgICApO1xuICAgICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCcnKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBlbCA9IGNyZWF0ZUVsZW1lbnRGb3JUYWcodGFnIGFzIHN0cmluZyk7XG4gIGFwcGx5UHJvcHMoZWwsIHByb3BzLCBmdWxsTGlmZWN5Y2xlLCBzaWduYWxSZWdpc3RyeSk7XG4gIGZvciAoY29uc3QgY2hpbGQgb2YgY2hpbGRyZW4pIHtcbiAgICBlbC5hcHBlbmRDaGlsZChyZW5kZXJUb0RvbShjaGlsZCwgZnVsbExpZmVjeWNsZSwgdW5kZWZpbmVkLCBzaWduYWxSZWdpc3RyeSkpO1xuICB9XG5cbiAgcmV0dXJuIGVsO1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7O0NBVUMsR0FFRCxTQUFTLGVBQWUsRUFBRSxhQUFhLEVBQUUsT0FBTyxRQUFRLGFBQWE7QUFHckUsU0FBUyxPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxRQUFRLFFBQVEsbUJBQW1CO0FBQ3pFLFNBQVMsWUFBWSxFQUFFLGdCQUFnQixRQUFRLHNCQUFzQjtBQUNyRSxTQUFTLGlCQUFpQixRQUFRLHVCQUF1QjtBQUN6RCxTQUFTLGVBQWUsUUFBUSxnQkFBZ0I7QUFDaEQsU0FBUyxNQUFNLFFBQVEsc0JBQXNCO0FBQzdDLFNBQVMsWUFBWSxRQUFRLGNBQWM7QUFDM0MsU0FBUyxXQUFXLFFBQVEsY0FBYztBQUMxQyxTQUFTLHNCQUFzQixRQUFRLDBCQUEwQjtBQUVqRSxTQUFTLFdBQVcsUUFBUSwwQ0FBMEM7QUFFdEUsTUFBTSxTQUFTO0FBRWY7Ozs7Q0FJQyxHQUNELE1BQU0sV0FBVyxJQUFJLElBQUk7RUFDdkI7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7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
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @openelement/core - JSX Runtime.
3
+ *
4
+ * Implements the React-compatible jsx/jsxs/jsxDEV/Fragment interface.
5
+ * Consumed by TypeScript/esbuild JSX transform when `jsxImportSource: "@openelement/core"`.
6
+ *
7
+ * Design (ADR-0057):
8
+ * - Fragment groups multiple children without a wrapping element
9
+ * - jsxDEV adds source-map information in development builds
10
+ *
11
+ * @module @openelement/core/jsx-runtime
12
+ */ import type { ComponentCtor, ComponentFn, VNode } from '@openelement/protocol/vnode';
13
+ /**
14
+ * Usage in TSX:
15
+ * return <><div>a</div><div>b</div></>;
16
+ */ export declare const Fragment: unique symbol;
17
+ /** @internal Symbol for <Show> tag matching in renderToDom */ export declare const SHOW_TAG: unique symbol;
18
+ /** @internal Symbol for <For> tag matching in renderToDom */ export declare const FOR_TAG: unique symbol;
19
+ /** @internal Symbol for raw HTML insertion (trustedHtml helper) */ export declare const HTML_TAG: unique symbol;
20
+ /**
21
+ * Create a VNode that renders as raw trusted HTML.
22
+ *
23
+ * During SSR the HTML string is emitted verbatim; on the client it is parsed
24
+ * into real DOM nodes via innerHTML. The caller is responsible for sanitizing
25
+ * the input — this is a trust boundary, not a sanitizer.
26
+ *
27
+ * @param html - The raw HTML string to render.
28
+ * @returns A VNode that the render pipeline treats as trusted HTML.
29
+ */ export declare function trustedHtml(html: string): VNode;
30
+ /**
31
+ * Show conditional rendering factory (ADR-0059).
32
+ *
33
+ * Returns a VNode with the internal SHOW_TAG symbol so renderToDom
34
+ * can intercept it as a control flow directive. Exported as a
35
+ * function (not a Symbol) for TypeScript JSX compatibility.
36
+ *
37
+ * Usage: <Show when={this.#loading}><Spinner/><Content/></Show>
38
+ */ export declare function Show(props: Record<string, unknown>): VNode;
39
+ /**
40
+ * For list rendering factory (ADR-0059).
41
+ *
42
+ * Usage: <For each={this.#items}>{(item) => <li>{item.name}</li>}</For>
43
+ */ export declare function For(props: Record<string, unknown>): VNode;
44
+ type ComponentTag = string | ComponentFn | ComponentCtor | symbol;
45
+ /**
46
+ * Called by the TypeScript JSX transform for elements with a single child.
47
+ */ export declare function jsx(tag: ComponentTag | typeof Fragment, props: Record<string, unknown>, key?: string | number): VNode;
48
+ /**
49
+ * Called by the TypeScript JSX transform for elements with multiple children.
50
+ */ export declare function jsxs(tag: ComponentTag | typeof Fragment, props: Record<string, unknown>, key?: string | number): VNode;
51
+ /**
52
+ * JSX factory for development mode.
53
+ * Same as `jsx` but receives source-map information for better error messages.
54
+ */ export declare function jsxDEV(tag: ComponentTag | typeof Fragment, props: Record<string, unknown>, key?: string | number, _isStaticChildren?: boolean, source?: {
55
+ fileName: string;
56
+ lineNumber: number;
57
+ columnNumber: number;
58
+ }, _self?: unknown): VNode;
@@ -0,0 +1,99 @@
1
+ /**
2
+ * @openelement/core - JSX Runtime.
3
+ *
4
+ * Implements the React-compatible jsx/jsxs/jsxDEV/Fragment interface.
5
+ * Consumed by TypeScript/esbuild JSX transform when `jsxImportSource: "@openelement/core"`.
6
+ *
7
+ * Design (ADR-0057):
8
+ * - Fragment groups multiple children without a wrapping element
9
+ * - jsxDEV adds source-map information in development builds
10
+ *
11
+ * @module @openelement/core/jsx-runtime
12
+ */ /// <reference path="./jsx-types.d.ts" />
13
+ /**
14
+ * Usage in TSX:
15
+ * return <><div>a</div><div>b</div></>;
16
+ */ export const Fragment = Symbol.for('openelement.fragment');
17
+ /** @internal Symbol for <Show> tag matching in renderToDom */ export const SHOW_TAG = Symbol.for('openelement.show');
18
+ /** @internal Symbol for <For> tag matching in renderToDom */ export const FOR_TAG = Symbol.for('openelement.for');
19
+ /** @internal Symbol for raw HTML insertion (trustedHtml helper) */ export const HTML_TAG = Symbol.for('openelement.html');
20
+ /**
21
+ * Create a VNode that renders as raw trusted HTML.
22
+ *
23
+ * During SSR the HTML string is emitted verbatim; on the client it is parsed
24
+ * into real DOM nodes via innerHTML. The caller is responsible for sanitizing
25
+ * the input — this is a trust boundary, not a sanitizer.
26
+ *
27
+ * @param html - The raw HTML string to render.
28
+ * @returns A VNode that the render pipeline treats as trusted HTML.
29
+ */ export function trustedHtml(html) {
30
+ return {
31
+ tag: HTML_TAG,
32
+ props: {
33
+ html
34
+ },
35
+ children: []
36
+ };
37
+ }
38
+ /**
39
+ * Show conditional rendering factory (ADR-0059).
40
+ *
41
+ * Returns a VNode with the internal SHOW_TAG symbol so renderToDom
42
+ * can intercept it as a control flow directive. Exported as a
43
+ * function (not a Symbol) for TypeScript JSX compatibility.
44
+ *
45
+ * Usage: <Show when={this.#loading}><Spinner/><Content/></Show>
46
+ */ export function Show(props) {
47
+ return createVNode(SHOW_TAG, props);
48
+ }
49
+ /**
50
+ * For list rendering factory (ADR-0059).
51
+ *
52
+ * Usage: <For each={this.#items}>{(item) => <li>{item.name}</li>}</For>
53
+ */ export function For(props) {
54
+ return createVNode(FOR_TAG, props);
55
+ }
56
+ function normaliseChildren(raw) {
57
+ if (raw == null) return [];
58
+ if (Array.isArray(raw)) {
59
+ return raw.flat(Infinity).filter((c)=>c != null && c !== false && c !== true);
60
+ }
61
+ if (raw === false || raw === true) return [];
62
+ return [
63
+ raw
64
+ ];
65
+ }
66
+ function createVNode(tag, props, key) {
67
+ const { children, ref, ...rest } = props;
68
+ const childArray = normaliseChildren(children);
69
+ const vnode = {
70
+ tag,
71
+ props: rest,
72
+ children: childArray
73
+ };
74
+ if (key !== undefined) vnode.key = key;
75
+ if (ref !== undefined) vnode.ref = ref;
76
+ return vnode;
77
+ }
78
+ /**
79
+ * Called by the TypeScript JSX transform for elements with a single child.
80
+ */ export function jsx(tag, props, key) {
81
+ return createVNode(tag, props, key);
82
+ }
83
+ /**
84
+ * Called by the TypeScript JSX transform for elements with multiple children.
85
+ */ export function jsxs(tag, props, key) {
86
+ return createVNode(tag, props, key);
87
+ }
88
+ /**
89
+ * JSX factory for development mode.
90
+ * Same as `jsx` but receives source-map information for better error messages.
91
+ */ export function jsxDEV(tag, props, key, _isStaticChildren, source, _self) {
92
+ const vnode = createVNode(tag, props, key);
93
+ if (source) {
94
+ vnode.__source = source;
95
+ }
96
+ return vnode;
97
+ } // augmentations in published packages. The ambient declarations in
98
+ // jsx-types.d.ts provide the same TypeScript JSX type-checking.
99
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9vcGVuZWxlbWVudC9vcGVuZWxlbWVudC9wYWNrYWdlcy9jb3JlL3NyYy9qc3gtcnVudGltZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBvcGVuZWxlbWVudC9jb3JlIC0gSlNYIFJ1bnRpbWUuXG4gKlxuICogSW1wbGVtZW50cyB0aGUgUmVhY3QtY29tcGF0aWJsZSBqc3gvanN4cy9qc3hERVYvRnJhZ21lbnQgaW50ZXJmYWNlLlxuICogQ29uc3VtZWQgYnkgVHlwZVNjcmlwdC9lc2J1aWxkIEpTWCB0cmFuc2Zvcm0gd2hlbiBganN4SW1wb3J0U291cmNlOiBcIkBvcGVuZWxlbWVudC9jb3JlXCJgLlxuICpcbiAqIERlc2lnbiAoQURSLTAwNTcpOlxuICogLSBGcmFnbWVudCBncm91cHMgbXVsdGlwbGUgY2hpbGRyZW4gd2l0aG91dCBhIHdyYXBwaW5nIGVsZW1lbnRcbiAqIC0ganN4REVWIGFkZHMgc291cmNlLW1hcCBpbmZvcm1hdGlvbiBpbiBkZXZlbG9wbWVudCBidWlsZHNcbiAqXG4gKiBAbW9kdWxlIEBvcGVuZWxlbWVudC9jb3JlL2pzeC1ydW50aW1lXG4gKi9cblxuLy8vIDxyZWZlcmVuY2UgcGF0aD1cIi4vanN4LXR5cGVzLmQudHNcIiAvPlxuXG5pbXBvcnQgdHlwZSB7IENvbXBvbmVudEN0b3IsIENvbXBvbmVudEZuLCBWTm9kZSB9IGZyb20gJ0BvcGVuZWxlbWVudC9wcm90b2NvbC92bm9kZSc7XG5cbi8qKlxuICogVXNhZ2UgaW4gVFNYOlxuICogICByZXR1cm4gPD48ZGl2PmE8L2Rpdj48ZGl2PmI8L2Rpdj48Lz47XG4gKi9cbmV4cG9ydCBjb25zdCBGcmFnbWVudDogdW5pcXVlIHN5bWJvbCA9IFN5bWJvbC5mb3IoJ29wZW5lbGVtZW50LmZyYWdtZW50Jyk7XG5cbi8qKiBAaW50ZXJuYWwgU3ltYm9sIGZvciA8U2hvdz4gdGFnIG1hdGNoaW5nIGluIHJlbmRlclRvRG9tICovXG5leHBvcnQgY29uc3QgU0hPV19UQUc6IHVuaXF1ZSBzeW1ib2wgPSBTeW1ib2wuZm9yKCdvcGVuZWxlbWVudC5zaG93Jyk7XG4vKiogQGludGVybmFsIFN5bWJvbCBmb3IgPEZvcj4gdGFnIG1hdGNoaW5nIGluIHJlbmRlclRvRG9tICovXG5leHBvcnQgY29uc3QgRk9SX1RBRzogdW5pcXVlIHN5bWJvbCA9IFN5bWJvbC5mb3IoJ29wZW5lbGVtZW50LmZvcicpO1xuLyoqIEBpbnRlcm5hbCBTeW1ib2wgZm9yIHJhdyBIVE1MIGluc2VydGlvbiAodHJ1c3RlZEh0bWwgaGVscGVyKSAqL1xuZXhwb3J0IGNvbnN0IEhUTUxfVEFHOiB1bmlxdWUgc3ltYm9sID0gU3ltYm9sLmZvcignb3BlbmVsZW1lbnQuaHRtbCcpO1xuXG4vKipcbiAqIENyZWF0ZSBhIFZOb2RlIHRoYXQgcmVuZGVycyBhcyByYXcgdHJ1c3RlZCBIVE1MLlxuICpcbiAqIER1cmluZyBTU1IgdGhlIEhUTUwgc3RyaW5nIGlzIGVtaXR0ZWQgdmVyYmF0aW07IG9uIHRoZSBjbGllbnQgaXQgaXMgcGFyc2VkXG4gKiBpbnRvIHJlYWwgRE9NIG5vZGVzIHZpYSBpbm5lckhUTUwuIFRoZSBjYWxsZXIgaXMgcmVzcG9uc2libGUgZm9yIHNhbml0aXppbmdcbiAqIHRoZSBpbnB1dCDigJQgdGhpcyBpcyBhIHRydXN0IGJvdW5kYXJ5LCBub3QgYSBzYW5pdGl6ZXIuXG4gKlxuICogQHBhcmFtIGh0bWwgLSBUaGUgcmF3IEhUTUwgc3RyaW5nIHRvIHJlbmRlci5cbiAqIEByZXR1cm5zIEEgVk5vZGUgdGhhdCB0aGUgcmVuZGVyIHBpcGVsaW5lIHRyZWF0cyBhcyB0cnVzdGVkIEhUTUwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cnVzdGVkSHRtbChodG1sOiBzdHJpbmcpOiBWTm9kZSB7XG4gIHJldHVybiB7IHRhZzogSFRNTF9UQUcsIHByb3BzOiB7IGh0bWwgfSwgY2hpbGRyZW46IFtdIH07XG59XG5cbi8qKlxuICogU2hvdyBjb25kaXRpb25hbCByZW5kZXJpbmcgZmFjdG9yeSAoQURSLTAwNTkpLlxuICpcbiAqIFJldHVybnMgYSBWTm9kZSB3aXRoIHRoZSBpbnRlcm5hbCBTSE9XX1RBRyBzeW1ib2wgc28gcmVuZGVyVG9Eb21cbiAqIGNhbiBpbnRlcmNlcHQgaXQgYXMgYSBjb250cm9sIGZsb3cgZGlyZWN0aXZlLiBFeHBvcnRlZCBhcyBhXG4gKiBmdW5jdGlvbiAobm90IGEgU3ltYm9sKSBmb3IgVHlwZVNjcmlwdCBKU1ggY29tcGF0aWJpbGl0eS5cbiAqXG4gKiBVc2FnZTogPFNob3cgd2hlbj17dGhpcy4jbG9hZGluZ30+PFNwaW5uZXIvPjxDb250ZW50Lz48L1Nob3c+XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBTaG93KHByb3BzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFZOb2RlIHtcbiAgcmV0dXJuIGNyZWF0ZVZOb2RlKFNIT1dfVEFHLCBwcm9wcyk7XG59XG5cbi8qKlxuICogRm9yIGxpc3QgcmVuZGVyaW5nIGZhY3RvcnkgKEFEUi0wMDU5KS5cbiAqXG4gKiBVc2FnZTogPEZvciBlYWNoPXt0aGlzLiNpdGVtc30+eyhpdGVtKSA9PiA8bGk+e2l0ZW0ubmFtZX08L2xpPn08L0Zvcj5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEZvcihwcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBWTm9kZSB7XG4gIHJldHVybiBjcmVhdGVWTm9kZShGT1JfVEFHLCBwcm9wcyk7XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGlzZUNoaWxkcmVuKHJhdzogdW5rbm93bik6IChWTm9kZSB8IHN0cmluZylbXSB7XG4gIGlmIChyYXcgPT0gbnVsbCkgcmV0dXJuIFtdO1xuICBpZiAoQXJyYXkuaXNBcnJheShyYXcpKSB7XG4gICAgcmV0dXJuIHJhdy5mbGF0KEluZmluaXR5KS5maWx0ZXIoKGMpID0+IGMgIT0gbnVsbCAmJiBjICE9PSBmYWxzZSAmJiBjICE9PSB0cnVlKSBhcyAoXG4gICAgICB8IFZOb2RlXG4gICAgICB8IHN0cmluZ1xuICAgIClbXTtcbiAgfVxuICBpZiAocmF3ID09PSBmYWxzZSB8fCByYXcgPT09IHRydWUpIHJldHVybiBbXTtcbiAgcmV0dXJuIFtyYXcgYXMgVk5vZGUgfCBzdHJpbmddO1xufVxuXG50eXBlIENvbXBvbmVudFRhZyA9IHN0cmluZyB8IENvbXBvbmVudEZuIHwgQ29tcG9uZW50Q3RvciB8IHN5bWJvbDtcblxuZnVuY3Rpb24gY3JlYXRlVk5vZGUoXG4gIHRhZzogQ29tcG9uZW50VGFnIHwgdHlwZW9mIEZyYWdtZW50LFxuICBwcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gIGtleT86IHN0cmluZyB8IG51bWJlcixcbik6IFZOb2RlIHtcbiAgY29uc3QgeyBjaGlsZHJlbiwgcmVmLCAuLi5yZXN0IH0gPSBwcm9wcyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiAmIHtcbiAgICBjaGlsZHJlbj86IHVua25vd247XG4gICAgcmVmPzogKGVsOiBFbGVtZW50KSA9PiB2b2lkO1xuICB9O1xuICBjb25zdCBjaGlsZEFycmF5ID0gbm9ybWFsaXNlQ2hpbGRyZW4oY2hpbGRyZW4pO1xuICBjb25zdCB2bm9kZTogVk5vZGUgPSB7IHRhZywgcHJvcHM6IHJlc3QsIGNoaWxkcmVuOiBjaGlsZEFycmF5IH07XG4gIGlmIChrZXkgIT09IHVuZGVmaW5lZCkgdm5vZGUua2V5ID0ga2V5O1xuICBpZiAocmVmICE9PSB1bmRlZmluZWQpIHZub2RlLnJlZiA9IHJlZiBhcyAoZWw6IEVsZW1lbnQpID0+IHZvaWQ7XG4gIHJldHVybiB2bm9kZTtcbn1cblxuLyoqXG4gKiBDYWxsZWQgYnkgdGhlIFR5cGVTY3JpcHQgSlNYIHRyYW5zZm9ybSBmb3IgZWxlbWVudHMgd2l0aCBhIHNpbmdsZSBjaGlsZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGpzeChcbiAgdGFnOiBDb21wb25lbnRUYWcgfCB0eXBlb2YgRnJhZ21lbnQsXG4gIHByb3BzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAga2V5Pzogc3RyaW5nIHwgbnVtYmVyLFxuKTogVk5vZGUge1xuICByZXR1cm4gY3JlYXRlVk5vZGUodGFnLCBwcm9wcywga2V5KTtcbn1cblxuLyoqXG4gKiBDYWxsZWQgYnkgdGhlIFR5cGVTY3JpcHQgSlNYIHRyYW5zZm9ybSBmb3IgZWxlbWVudHMgd2l0aCBtdWx0aXBsZSBjaGlsZHJlbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGpzeHMoXG4gIHRhZzogQ29tcG9uZW50VGFnIHwgdHlwZW9mIEZyYWdtZW50LFxuICBwcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gIGtleT86IHN0cmluZyB8IG51bWJlcixcbik6IFZOb2RlIHtcbiAgcmV0dXJuIGNyZWF0ZVZOb2RlKHRhZywgcHJvcHMsIGtleSk7XG59XG5cbi8qKlxuICogSlNYIGZhY3RvcnkgZm9yIGRldmVsb3BtZW50IG1vZGUuXG4gKiBTYW1lIGFzIGBqc3hgIGJ1dCByZWNlaXZlcyBzb3VyY2UtbWFwIGluZm9ybWF0aW9uIGZvciBiZXR0ZXIgZXJyb3IgbWVzc2FnZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBqc3hERVYoXG4gIHRhZzogQ29tcG9uZW50VGFnIHwgdHlwZW9mIEZyYWdtZW50LFxuICBwcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gIGtleT86IHN0cmluZyB8IG51bWJlcixcbiAgX2lzU3RhdGljQ2hpbGRyZW4/OiBib29sZWFuLFxuICBzb3VyY2U/OiB7IGZpbGVOYW1lOiBzdHJpbmc7IGxpbmVOdW1iZXI6IG51bWJlcjsgY29sdW1uTnVtYmVyOiBudW1iZXIgfSxcbiAgX3NlbGY/OiB1bmtub3duLFxuKTogVk5vZGUge1xuICBjb25zdCB2bm9kZSA9IGNyZWF0ZVZOb2RlKHRhZywgcHJvcHMsIGtleSk7XG4gIGlmIChzb3VyY2UpIHtcbiAgICAodm5vZGUgYXMgVk5vZGUgJiB7IF9fc291cmNlPzogdW5rbm93biB9KS5fX3NvdXJjZSA9IHNvdXJjZTtcbiAgfVxuICByZXR1cm4gdm5vZGU7XG59XG5cbi8vIGF1Z21lbnRhdGlvbnMgaW4gcHVibGlzaGVkIHBhY2thZ2VzLiBUaGUgYW1iaWVudCBkZWNsYXJhdGlvbnMgaW5cbi8vIGpzeC10eXBlcy5kLnRzIHByb3ZpZGUgdGhlIHNhbWUgVHlwZVNjcmlwdCBKU1ggdHlwZS1jaGVja2luZy5cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Q0FXQyxHQUVELHlDQUF5QztBQUl6Qzs7O0NBR0MsR0FDRCxPQUFPLE1BQU0sV0FBMEIsT0FBTyxHQUFHLENBQUMsd0JBQXdCO0FBRTFFLDREQUE0RCxHQUM1RCxPQUFPLE1BQU0sV0FBMEIsT0FBTyxHQUFHLENBQUMsb0JBQW9CO0FBQ3RFLDJEQUEyRCxHQUMzRCxPQUFPLE1BQU0sVUFBeUIsT0FBTyxHQUFHLENBQUMsbUJBQW1CO0FBQ3BFLGlFQUFpRSxHQUNqRSxPQUFPLE1BQU0sV0FBMEIsT0FBTyxHQUFHLENBQUMsb0JBQW9CO0FBRXRFOzs7Ozs7Ozs7Q0FTQyxHQUNELE9BQU8sU0FBUyxZQUFZLElBQVk7RUFDdEMsT0FBTztJQUFFLEtBQUs7SUFBVSxPQUFPO01BQUU7SUFBSztJQUFHLFVBQVUsRUFBRTtFQUFDO0FBQ3hEO0FBRUE7Ozs7Ozs7O0NBUUMsR0FDRCxPQUFPLFNBQVMsS0FBSyxLQUE4QjtFQUNqRCxPQUFPLFlBQVksVUFBVTtBQUMvQjtBQUVBOzs7O0NBSUMsR0FDRCxPQUFPLFNBQVMsSUFBSSxLQUE4QjtFQUNoRCxPQUFPLFlBQVksU0FBUztBQUM5QjtBQUVBLFNBQVMsa0JBQWtCLEdBQVk7RUFDckMsSUFBSSxPQUFPLE1BQU0sT0FBTyxFQUFFO0VBQzFCLElBQUksTUFBTSxPQUFPLENBQUMsTUFBTTtJQUN0QixPQUFPLElBQUksSUFBSSxDQUFDLFVBQVUsTUFBTSxDQUFDLENBQUMsSUFBTSxLQUFLLFFBQVEsTUFBTSxTQUFTLE1BQU07RUFJNUU7RUFDQSxJQUFJLFFBQVEsU0FBUyxRQUFRLE1BQU0sT0FBTyxFQUFFO0VBQzVDLE9BQU87SUFBQztHQUFzQjtBQUNoQztBQUlBLFNBQVMsWUFDUCxHQUFtQyxFQUNuQyxLQUE4QixFQUM5QixHQUFxQjtFQUVyQixNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRSxHQUFHLE1BQU0sR0FBRztFQUluQyxNQUFNLGFBQWEsa0JBQWtCO0VBQ3JDLE1BQU0sUUFBZTtJQUFFO0lBQUssT0FBTztJQUFNLFVBQVU7RUFBVztFQUM5RCxJQUFJLFFBQVEsV0FBVyxNQUFNLEdBQUcsR0FBRztFQUNuQyxJQUFJLFFBQVEsV0FBVyxNQUFNLEdBQUcsR0FBRztFQUNuQyxPQUFPO0FBQ1Q7QUFFQTs7Q0FFQyxHQUNELE9BQU8sU0FBUyxJQUNkLEdBQW1DLEVBQ25DLEtBQThCLEVBQzlCLEdBQXFCO0VBRXJCLE9BQU8sWUFBWSxLQUFLLE9BQU87QUFDakM7QUFFQTs7Q0FFQyxHQUNELE9BQU8sU0FBUyxLQUNkLEdBQW1DLEVBQ25DLEtBQThCLEVBQzlCLEdBQXFCO0VBRXJCLE9BQU8sWUFBWSxLQUFLLE9BQU87QUFDakM7QUFFQTs7O0NBR0MsR0FDRCxPQUFPLFNBQVMsT0FDZCxHQUFtQyxFQUNuQyxLQUE4QixFQUM5QixHQUFxQixFQUNyQixpQkFBMkIsRUFDM0IsTUFBdUUsRUFDdkUsS0FBZTtFQUVmLE1BQU0sUUFBUSxZQUFZLEtBQUssT0FBTztFQUN0QyxJQUFJLFFBQVE7SUFDVCxNQUF5QyxRQUFRLEdBQUc7RUFDdkQ7RUFDQSxPQUFPO0FBQ1QsRUFFQSxtRUFBbUU7Q0FDbkUsZ0VBQWdFIn0=
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @openelement/core - JSX type declarations.
3
+ *
4
+ * Required by TypeScript's `jsx: "react-jsx"` mode.
5
+ * Defines JSX.Element as VNode so function components returning VNode
6
+ * are recognized as valid JSX component types.
7
+ *
8
+ * @module @openelement/core/jsx-types
9
+ */
10
+
11
+ declare namespace JSX {
12
+ /**
13
+ * JSX expression result — structurally compatible with VNode.
14
+ *
15
+ * children must match VNode.children: (VNode | string)[] to satisfy
16
+ * TypeScript's structural assignability check when a JSX expression
17
+ * is returned from DsdElement.render(): VNode | null.
18
+ */
19
+ interface Element {
20
+ tag:
21
+ | string
22
+ | import('@openelement/protocol/vnode').ComponentFn
23
+ | import('@openelement/protocol/vnode').ComponentCtor
24
+ | symbol;
25
+ props: Record<string, unknown>;
26
+ children: (string | import('@openelement/protocol/vnode').VNode)[];
27
+ key?: string | number;
28
+ ref?: (el: globalThis.Element) => void;
29
+ }
30
+
31
+ interface ElementClass {
32
+ render(): unknown;
33
+ }
34
+
35
+ interface IntrinsicElements {
36
+ [elemName: string]: Record<string, unknown>;
37
+ }
38
+
39
+ interface ElementAttributesProperty {
40
+ props: Record<string, unknown>;
41
+ }
42
+
43
+ interface ElementChildrenAttribute {
44
+ children: unknown;
45
+ }
46
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @openelement/core - Tagged console logger.
3
+ *
4
+ * Lightweight scoped logger. Returns plain functions so it is tree-shakable
5
+ * and has zero class overhead.
6
+ *
7
+ * @module @openelement/core/logger
8
+ */ export interface Logger {
9
+ debug: (msg: string, ...args: unknown[]) => void;
10
+ info: (msg: string, ...args: unknown[]) => void;
11
+ warn: (msg: string, ...args: unknown[]) => void;
12
+ error: (msg: string, ...args: unknown[]) => void;
13
+ }
14
+ export declare function createLogger(tag: string): Logger;
15
+ export declare function warnOnce(key: string, logger: Logger, msg: string): void;