@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.
- package/LICENSE +21 -0
- package/README.md +36 -0
- package/package.json +124 -0
- package/src/binding-activation.d.ts +2 -0
- package/src/binding-activation.js +254 -0
- package/src/binding-descriptor.d.ts +79 -0
- package/src/binding-descriptor.js +9 -0
- package/src/context.d.ts +32 -0
- package/src/context.js +76 -0
- package/src/csr.d.ts +13 -0
- package/src/csr.js +14 -0
- package/src/dsd-hydration-events.d.ts +2 -0
- package/src/dsd-hydration-events.js +13 -0
- package/src/dsd-hydration.d.ts +40 -0
- package/src/dsd-hydration.js +48 -0
- package/src/errors.d.ts +54 -0
- package/src/errors.js +113 -0
- package/src/event-hydration.d.ts +12 -0
- package/src/event-hydration.js +118 -0
- package/src/event-marker.d.ts +7 -0
- package/src/event-marker.js +54 -0
- package/src/html-escape.d.ts +29 -0
- package/src/html-escape.js +126 -0
- package/src/hydrate.d.ts +15 -0
- package/src/hydrate.js +15 -0
- package/src/index.d.ts +58 -0
- package/src/index.js +46 -0
- package/src/island-transform.d.ts +14 -0
- package/src/island-transform.js +60 -0
- package/src/island.d.ts +59 -0
- package/src/island.js +342 -0
- package/src/isr-runtime.d.ts +28 -0
- package/src/isr-runtime.js +99 -0
- package/src/isr.d.ts +22 -0
- package/src/isr.js +41 -0
- package/src/jsx-render-dom.d.ts +22 -0
- package/src/jsx-render-dom.js +376 -0
- package/src/jsx-runtime.d.ts +58 -0
- package/src/jsx-runtime.js +99 -0
- package/src/jsx-types.d.ts +46 -0
- package/src/logger.d.ts +15 -0
- package/src/logger.js +24 -0
- package/src/prop.d.ts +24 -0
- package/src/prop.js +160 -0
- package/src/registry.d.ts +17 -0
- package/src/registry.js +219 -0
- package/src/render-dsd-stream.d.ts +46 -0
- package/src/render-dsd-stream.js +86 -0
- package/src/render-dsd.d.ts +27 -0
- package/src/render-dsd.js +315 -0
- package/src/render-ir.d.ts +32 -0
- package/src/render-ir.js +245 -0
- package/src/runtime.d.ts +9 -0
- package/src/runtime.js +16 -0
- package/src/security.d.ts +1 -0
- package/src/security.js +40 -0
- package/src/signal-context.d.ts +15 -0
- package/src/signal-context.js +59 -0
- package/src/static.d.ts +35 -0
- package/src/static.js +34 -0
- package/src/style-sheet.d.ts +9 -0
- package/src/style-sheet.js +56 -0
- package/src/tag-utils.d.ts +11 -0
- package/src/tag-utils.js +28 -0
- package/src/vnode.d.ts +15 -0
- 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
|
+
}
|
package/src/logger.d.ts
ADDED
|
@@ -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;
|