@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,27 @@
1
+ /**
2
+ * @openelement/core - DSD Renderer.
3
+ *
4
+ * Declarative Shadow DOM SSR renderer.
5
+ * Framework-agnostic: no Lit dependency and no TemplateResult knowledge.
6
+ *
7
+ * v0.29.1: Inlined render-errors, render-instantiate, and render-serialize helpers.
8
+ * Uses unified serializeAttrs from render-ir. Removed renderDsdByName.
9
+ * Changed renderDsdTree import from jsx-render-string to render-ir.
10
+ *
11
+ * @module @openelement/core/render-dsd
12
+ */ import { type DsdOptions, type RenderHooks, type RenderOutput } from '@openelement/protocol/render';
13
+ import { type RenderNode } from "./render-ir.js";
14
+ export interface RenderDsdOptions {
15
+ componentClass?: CustomElementConstructor;
16
+ props?: Record<string, unknown>;
17
+ sourceInfo?: {
18
+ route?: string;
19
+ source?: string;
20
+ };
21
+ dsdOptions?: DsdOptions;
22
+ nestingDepth?: number;
23
+ hooks?: RenderHooks;
24
+ lightDom?: RenderNode[];
25
+ }
26
+ export declare function renderDsd(input: string | CustomElementConstructor, options?: RenderDsdOptions): Promise<RenderOutput>;
27
+ export { createRenderDsdStreamMetrics, renderDsdStream } from "./render-dsd-stream.js";
@@ -0,0 +1,315 @@
1
+ /**
2
+ * @openelement/core - DSD Renderer.
3
+ *
4
+ * Declarative Shadow DOM SSR renderer.
5
+ * Framework-agnostic: no Lit dependency and no TemplateResult knowledge.
6
+ *
7
+ * v0.29.1: Inlined render-errors, render-instantiate, and render-serialize helpers.
8
+ * Uses unified serializeAttrs from render-ir. Removed renderDsdByName.
9
+ * Changed renderDsdTree import from jsx-render-string to render-ir.
10
+ *
11
+ * @module @openelement/core/render-dsd
12
+ */ import { createLogger } from './logger.js';
13
+ import { formatError } from './errors.js';
14
+ import { escapeAttrValue } from './html-escape.js';
15
+ import { isVNode } from './vnode.js';
16
+ import { renderDsdTree } from './render-ir.js';
17
+ import { dsdHostNode, serializeAttrs, serializeRenderNode, trustedHtmlNode } from './render-ir.js';
18
+ import { DANGEROUS_KEYS } from './security.js';
19
+ const log = createLogger('core');
20
+ // ─── Error Classification ──────────────────────────────────────
21
+ // RenderPhase and RenderErrorCode are imported from @openelement/protocol/render.
22
+ export function classifyError(phase, tagName, err, recoverable = false) {
23
+ const message = formatError(err);
24
+ return {
25
+ code: codeForRenderError(phase, message),
26
+ severity: recoverable ? 'warning' : 'error',
27
+ phase,
28
+ tagName,
29
+ message,
30
+ recoverable
31
+ };
32
+ }
33
+ // ponytail: lookup table replaces 5-case if/else chain
34
+ const ERROR_CODES = {
35
+ instantiate: 'LESS_RENDER_INSTANTIATE_FAILED',
36
+ nested: 'LESS_RENDER_NESTED_FAILED',
37
+ style: 'LESS_RENDER_STYLE_FAILED',
38
+ serialize: 'LESS_RENDER_SERIALIZE_FAILED'
39
+ };
40
+ function codeForRenderError(phase, message) {
41
+ if (message.includes('Components must return a VNode')) {
42
+ return 'LESS_RENDER_INVALID_OUTPUT';
43
+ }
44
+ return ERROR_CODES[phase] ?? 'LESS_RENDER_RENDER_FAILED';
45
+ }
46
+ function instantiationErrorHtml(tagName, _errMsg, _sourceStr, _route, _source) {
47
+ return `<${tagName}></${tagName}>`;
48
+ }
49
+ // ─── Component Instantiation ───────────────────────────────────
50
+ function instantiateComponent(tagName, componentClass) {
51
+ try {
52
+ const instance = new componentClass();
53
+ if (!isDsdComponent(instance)) {
54
+ log.error(`<${tagName}> does not implement render(): VNode | null.`);
55
+ return null;
56
+ }
57
+ return instance;
58
+ } catch (err) {
59
+ const errMsg = formatError(err);
60
+ log.error(`Failed to instantiate <${tagName}>: ${errMsg}`);
61
+ return null;
62
+ }
63
+ }
64
+ function isDsdComponent(value) {
65
+ return typeof value === 'object' && value !== null && typeof Reflect.get(value, 'render') === 'function';
66
+ }
67
+ function injectProps(instance, tagName, props) {
68
+ for (const [key, value] of Object.entries(props)){
69
+ if (DANGEROUS_KEYS.has(key)) {
70
+ log.warn(`Skipping dangerous prop key "${key}" on <${tagName}> - potential prototype pollution`);
71
+ continue;
72
+ }
73
+ try {
74
+ instance[key] = value;
75
+ } catch (e) {
76
+ log.debug(`Cannot set read-only property "${key}" on <${tagName}>: ${formatError(e)}`);
77
+ }
78
+ }
79
+ }
80
+ // ─── DSD Template Attributes ───────────────────────────────────
81
+ function buildDsdTemplateAttrs(options) {
82
+ if (!options) return '';
83
+ const parts = [];
84
+ if (options.delegatesFocus) parts.push(' shadowrootdelegatesfocus');
85
+ if (options.clonable) parts.push(' shadowrootclonable');
86
+ if (options.serializable) parts.push(' shadowrootserializable');
87
+ if (options.slotAssignment === 'manual') {
88
+ parts.push(' shadowrootslotassignment="manual"');
89
+ }
90
+ if (options.customElementRegistry) {
91
+ parts.push(' shadowrootcustomelementregistry');
92
+ }
93
+ return parts.join('');
94
+ }
95
+ // ─── DSD Output Wrapping ───────────────────────────────────────
96
+ function wrapDsdOutput(params) {
97
+ const { tagName, props, content, styleCss, layer, sourceStr, dsdOptions, lightDom } = params;
98
+ const publicProps = filterPublicDsdProps(props);
99
+ const ssrPropsAttr = Object.keys(publicProps).length > 0 ? ` data-ssr-props="${escapeAttrValue(JSON.stringify(publicProps))}"` : '';
100
+ return serializeRenderNode(dsdHostNode({
101
+ tag: tagName,
102
+ attrs: publicProps,
103
+ ssrPropsAttr,
104
+ source: sourceStr,
105
+ templateAttrs: buildDsdTemplateAttrs(dsdOptions),
106
+ styleCss,
107
+ shadow: [
108
+ trustedHtmlNode(content)
109
+ ],
110
+ light: lightDom ?? [],
111
+ layer
112
+ }));
113
+ }
114
+ function filterPublicDsdProps(props) {
115
+ const publicProps = {};
116
+ for (const [key, value] of Object.entries(props)){
117
+ if (key.startsWith('__openElement')) continue;
118
+ publicProps[key] = value;
119
+ }
120
+ return publicProps;
121
+ }
122
+ export async function renderDsd(input, options = {}) {
123
+ let tagName;
124
+ let componentClass;
125
+ const props = options.props ?? {};
126
+ if (typeof input === 'string') {
127
+ tagName = input;
128
+ if (options?.componentClass) {
129
+ componentClass = options.componentClass;
130
+ } else {
131
+ const cls = globalThis.customElements?.get(tagName);
132
+ if (!cls) {
133
+ log.warn(`<${tagName}> is not registered - rendering as void element`);
134
+ const attrs = serializeAttrs(tagName, props);
135
+ const html = `<${tagName}${attrs}></${tagName}>`;
136
+ return {
137
+ html,
138
+ errors: [],
139
+ metrics: {
140
+ tagName,
141
+ renderTimeMs: 0,
142
+ templateSize: 0,
143
+ layer: 'dsd-static',
144
+ hasError: false,
145
+ nestingDepth: 0
146
+ },
147
+ hydrationHints: []
148
+ };
149
+ }
150
+ componentClass = cls;
151
+ }
152
+ } else {
153
+ componentClass = input;
154
+ tagName = input.tagName ?? 'unknown';
155
+ }
156
+ const sourceInfo = options.sourceInfo;
157
+ const dsdOptions = options.dsdOptions;
158
+ const nestingDepth = options.nestingDepth;
159
+ const hooks = options.hooks;
160
+ const _nestingDepth = nestingDepth ?? 0;
161
+ const startTime = typeof performance !== 'undefined' ? performance.now() : 0;
162
+ const sourceStr = sourceInfo ? `${sourceInfo.route ? ` route="${sourceInfo.route}"` : ''}${sourceInfo.source ? ` source="${sourceInfo.source}"` : ''}` : '';
163
+ const collectedErrors = [];
164
+ const collectedHints = [];
165
+ let hasError = false;
166
+ const renderInput = {
167
+ tagName,
168
+ componentClass,
169
+ props,
170
+ dsdOptions,
171
+ nestingDepth: _nestingDepth
172
+ };
173
+ if (hooks?.beforeRender) {
174
+ try {
175
+ hooks.beforeRender(renderInput);
176
+ } catch (e) {
177
+ log.debug(`beforeRender hook threw: ${formatError(e)}`);
178
+ }
179
+ }
180
+ const instance = instantiateComponent(tagName, componentClass);
181
+ if (!instance) {
182
+ const errMsg = 'Failed to instantiate';
183
+ const err = classifyError('instantiate', tagName, errMsg, false);
184
+ collectedErrors.push(err);
185
+ hasError = true;
186
+ hooks?.onError?.(err);
187
+ const html = instantiationErrorHtml(tagName, errMsg, sourceStr, sourceInfo?.route, sourceInfo?.source);
188
+ const result = {
189
+ html,
190
+ errors: collectedErrors,
191
+ metrics: {
192
+ tagName,
193
+ renderTimeMs: 0,
194
+ templateSize: 0,
195
+ layer: 'dsd-static',
196
+ hasError: true,
197
+ nestingDepth: _nestingDepth
198
+ },
199
+ hydrationHints: collectedHints
200
+ };
201
+ hooks?.afterRender?.(result);
202
+ return result;
203
+ }
204
+ injectProps(instance, tagName, props);
205
+ let content = '';
206
+ try {
207
+ const result = instance.render();
208
+ if (result == null) {
209
+ content = '';
210
+ } else if (isVNode(result)) {
211
+ content = await renderDsdTree(result);
212
+ } else {
213
+ log.debug(`Unsupported render() return for <${tagName}>: ${describeRenderValue(result)}`);
214
+ const errDetail = `Components must return a VNode from render(), got ${typeof result}.`;
215
+ const err = classifyError('render', tagName, errDetail, false);
216
+ collectedErrors.push(err);
217
+ hasError = true;
218
+ hooks?.onError?.(err);
219
+ content = '';
220
+ }
221
+ } catch (err) {
222
+ const classifiedErr = classifyError('render', tagName, err, true);
223
+ collectedErrors.push(classifiedErr);
224
+ hasError = true;
225
+ hooks?.onError?.(classifiedErr);
226
+ const attrs = serializeAttrs(tagName, props);
227
+ const renderEndFallback = safeNow();
228
+ const fallbackResult = {
229
+ html: `<${tagName}${attrs}></${tagName}>`,
230
+ errors: collectedErrors,
231
+ metrics: {
232
+ tagName,
233
+ renderTimeMs: renderEndFallback - startTime,
234
+ templateSize: 0,
235
+ layer: 'dsd-static',
236
+ hasError: hasError,
237
+ nestingDepth: _nestingDepth
238
+ },
239
+ hydrationHints: collectedHints
240
+ };
241
+ hooks?.afterRender?.(fallbackResult);
242
+ return fallbackResult;
243
+ }
244
+ let styleCss = '';
245
+ const ctor = componentClass;
246
+ if (ctor.styles) {
247
+ const sheets = Array.isArray(ctor.styles) ? ctor.styles : [
248
+ ctor.styles
249
+ ];
250
+ for (const sheet of sheets){
251
+ try {
252
+ for (const rule of [
253
+ ...sheet.cssRules
254
+ ]){
255
+ styleCss += rule.cssText + '\n';
256
+ }
257
+ } catch {
258
+ // Cross-origin stylesheet or empty sheet - skip silently
259
+ }
260
+ }
261
+ }
262
+ const renderMode = ctor.renderMode ?? 'shadow';
263
+ const resolvedLayer = renderMode === 'light' ? 'light-dom' : dsdOptions?.layer || instance.layer || 'dsd-static';
264
+ const renderEnd = safeNow();
265
+ const renderTimeMs = renderEnd - startTime;
266
+ const metrics = {
267
+ tagName,
268
+ renderTimeMs,
269
+ templateSize: content.length,
270
+ layer: resolvedLayer,
271
+ hasError,
272
+ nestingDepth: _nestingDepth
273
+ };
274
+ if (resolvedLayer !== 'dsd-static') {
275
+ collectedHints.push({
276
+ tagName,
277
+ layer: resolvedLayer
278
+ });
279
+ }
280
+ const html = wrapDsdOutput({
281
+ tagName,
282
+ props,
283
+ content,
284
+ styleCss,
285
+ layer: resolvedLayer,
286
+ sourceStr,
287
+ dsdOptions,
288
+ lightDom: options.lightDom
289
+ });
290
+ const output = {
291
+ html,
292
+ errors: collectedErrors,
293
+ metrics,
294
+ hydrationHints: collectedHints
295
+ };
296
+ if (hooks?.afterRender) {
297
+ try {
298
+ hooks.afterRender(output);
299
+ } catch (e) {
300
+ log.debug(`afterRender hook threw: ${formatError(e)}`);
301
+ }
302
+ }
303
+ return output;
304
+ }
305
+ /** Safe high-resolution timestamp with SSR/environment fallback. */ export function safeNow() {
306
+ return typeof performance !== 'undefined' ? performance.now() : Date.now();
307
+ }
308
+ function describeRenderValue(value) {
309
+ if (value === null || typeof value !== 'object') return typeof value;
310
+ const keys = Object.keys(value).join(',');
311
+ return `object keys=[${keys}]`;
312
+ }
313
+ // v0.21.0: Streaming types and functions moved to render-dsd-stream.ts.
314
+ export { createRenderDsdStreamMetrics, renderDsdStream } from './render-dsd-stream.js';
315
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9vcGVuZWxlbWVudC9vcGVuZWxlbWVudC9wYWNrYWdlcy9jb3JlL3NyYy9yZW5kZXItZHNkLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQG9wZW5lbGVtZW50L2NvcmUgLSBEU0QgUmVuZGVyZXIuXG4gKlxuICogRGVjbGFyYXRpdmUgU2hhZG93IERPTSBTU1IgcmVuZGVyZXIuXG4gKiBGcmFtZXdvcmstYWdub3N0aWM6IG5vIExpdCBkZXBlbmRlbmN5IGFuZCBubyBUZW1wbGF0ZVJlc3VsdCBrbm93bGVkZ2UuXG4gKlxuICogdjAuMjkuMTogSW5saW5lZCByZW5kZXItZXJyb3JzLCByZW5kZXItaW5zdGFudGlhdGUsIGFuZCByZW5kZXItc2VyaWFsaXplIGhlbHBlcnMuXG4gKiBVc2VzIHVuaWZpZWQgc2VyaWFsaXplQXR0cnMgZnJvbSByZW5kZXItaXIuIFJlbW92ZWQgcmVuZGVyRHNkQnlOYW1lLlxuICogQ2hhbmdlZCByZW5kZXJEc2RUcmVlIGltcG9ydCBmcm9tIGpzeC1yZW5kZXItc3RyaW5nIHRvIHJlbmRlci1pci5cbiAqXG4gKiBAbW9kdWxlIEBvcGVuZWxlbWVudC9jb3JlL3JlbmRlci1kc2RcbiAqL1xuXG5pbXBvcnQge1xuICB0eXBlIERzZENvbXBvbmVudCxcbiAgdHlwZSBEc2RPcHRpb25zLFxuICB0eXBlIERzZFJlbmRlck1ldHJpY3MsXG4gIHR5cGUgSHlkcmF0aW9uSGludCxcbiAgdHlwZSBSZW5kZXJFcnJvcixcbiAgdHlwZSBSZW5kZXJFcnJvckNvZGUsXG4gIHR5cGUgUmVuZGVySG9va3MsXG4gIHR5cGUgUmVuZGVySW5wdXQsXG4gIHR5cGUgUmVuZGVyT3V0cHV0LFxuICB0eXBlIFJlbmRlclBoYXNlLFxufSBmcm9tICdAb3BlbmVsZW1lbnQvcHJvdG9jb2wvcmVuZGVyJztcbmltcG9ydCB7IHR5cGUgRHNkQ29tcG9uZW50Q29uc3RydWN0b3IgfSBmcm9tICdAb3BlbmVsZW1lbnQvcHJvdG9jb2wvcmVuZGVyJztcbmltcG9ydCB0eXBlIHsgQ29tcG9uZW50TGF5ZXIgfSBmcm9tICdAb3BlbmVsZW1lbnQvcHJvdG9jb2wvZnJhbWV3b3JrJztcbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyLmpzJztcbmltcG9ydCB7IGZvcm1hdEVycm9yIH0gZnJvbSAnLi9lcnJvcnMuanMnO1xuaW1wb3J0IHsgZXNjYXBlQXR0clZhbHVlIH0gZnJvbSAnLi9odG1sLWVzY2FwZS5qcyc7XG5pbXBvcnQgeyBpc1ZOb2RlIH0gZnJvbSAnLi92bm9kZS5qcyc7XG5pbXBvcnQgeyByZW5kZXJEc2RUcmVlIH0gZnJvbSAnLi9yZW5kZXItaXIuanMnO1xuaW1wb3J0IHtcbiAgZHNkSG9zdE5vZGUsXG4gIHR5cGUgUmVuZGVyTm9kZSxcbiAgc2VyaWFsaXplQXR0cnMsXG4gIHNlcmlhbGl6ZVJlbmRlck5vZGUsXG4gIHRydXN0ZWRIdG1sTm9kZSxcbn0gZnJvbSAnLi9yZW5kZXItaXIuanMnO1xuaW1wb3J0IHsgREFOR0VST1VTX0tFWVMgfSBmcm9tICcuL3NlY3VyaXR5LmpzJztcblxuY29uc3QgbG9nID0gY3JlYXRlTG9nZ2VyKCdjb3JlJyk7XG5cbi8vIOKUgOKUgOKUgCBFcnJvciBDbGFzc2lmaWNhdGlvbiDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbi8vIFJlbmRlclBoYXNlIGFuZCBSZW5kZXJFcnJvckNvZGUgYXJlIGltcG9ydGVkIGZyb20gQG9wZW5lbGVtZW50L3Byb3RvY29sL3JlbmRlci5cblxuZXhwb3J0IGZ1bmN0aW9uIGNsYXNzaWZ5RXJyb3IoXG4gIHBoYXNlOiBSZW5kZXJQaGFzZSxcbiAgdGFnTmFtZTogc3RyaW5nLFxuICBlcnI6IHVua25vd24sXG4gIHJlY292ZXJhYmxlID0gZmFsc2UsXG4pOiBSZW5kZXJFcnJvciB7XG4gIGNvbnN0IG1lc3NhZ2UgPSBmb3JtYXRFcnJvcihlcnIpO1xuICByZXR1cm4ge1xuICAgIGNvZGU6IGNvZGVGb3JSZW5kZXJFcnJvcihwaGFzZSwgbWVzc2FnZSksXG4gICAgc2V2ZXJpdHk6IHJlY292ZXJhYmxlID8gJ3dhcm5pbmcnIDogJ2Vycm9yJyxcbiAgICBwaGFzZSxcbiAgICB0YWdOYW1lLFxuICAgIG1lc3NhZ2UsXG4gICAgcmVjb3ZlcmFibGUsXG4gIH07XG59XG5cbi8vIHBvbnl0YWlsOiBsb29rdXAgdGFibGUgcmVwbGFjZXMgNS1jYXNlIGlmL2Vsc2UgY2hhaW5cbmNvbnN0IEVSUk9SX0NPREVTOiBSZWNvcmQ8c3RyaW5nLCBSZW5kZXJFcnJvckNvZGU+ID0ge1xuICBpbnN0YW50aWF0ZTogJ0xFU1NfUkVOREVSX0lOU1RBTlRJQVRFX0ZBSUxFRCcsXG4gIG5lc3RlZDogJ0xFU1NfUkVOREVSX05FU1RFRF9GQUlMRUQnLFxuICBzdHlsZTogJ0xFU1NfUkVOREVSX1NUWUxFX0ZBSUxFRCcsXG4gIHNlcmlhbGl6ZTogJ0xFU1NfUkVOREVSX1NFUklBTElaRV9GQUlMRUQnLFxufTtcblxuZnVuY3Rpb24gY29kZUZvclJlbmRlckVycm9yKHBoYXNlOiBSZW5kZXJQaGFzZSwgbWVzc2FnZTogc3RyaW5nKTogUmVuZGVyRXJyb3JDb2RlIHtcbiAgaWYgKG1lc3NhZ2UuaW5jbHVkZXMoJ0NvbXBvbmVudHMgbXVzdCByZXR1cm4gYSBWTm9kZScpKSB7XG4gICAgcmV0dXJuICdMRVNTX1JFTkRFUl9JTlZBTElEX09VVFBVVCc7XG4gIH1cbiAgcmV0dXJuIEVSUk9SX0NPREVTW3BoYXNlXSA/PyAnTEVTU19SRU5ERVJfUkVOREVSX0ZBSUxFRCc7XG59XG5cbmZ1bmN0aW9uIGluc3RhbnRpYXRpb25FcnJvckh0bWwoXG4gIHRhZ05hbWU6IHN0cmluZyxcbiAgX2Vyck1zZzogc3RyaW5nLFxuICBfc291cmNlU3RyOiBzdHJpbmcsXG4gIF9yb3V0ZT86IHN0cmluZyxcbiAgX3NvdXJjZT86IHN0cmluZyxcbik6IHN0cmluZyB7XG4gIHJldHVybiBgPCR7dGFnTmFtZX0+PC8ke3RhZ05hbWV9PmA7XG59XG5cbi8vIOKUgOKUgOKUgCBDb21wb25lbnQgSW5zdGFudGlhdGlvbiDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZnVuY3Rpb24gaW5zdGFudGlhdGVDb21wb25lbnQoXG4gIHRhZ05hbWU6IHN0cmluZyxcbiAgY29tcG9uZW50Q2xhc3M6IEN1c3RvbUVsZW1lbnRDb25zdHJ1Y3Rvcixcbik6IERzZENvbXBvbmVudCB8IG51bGwge1xuICB0cnkge1xuICAgIGNvbnN0IGluc3RhbmNlID0gbmV3IGNvbXBvbmVudENsYXNzKCk7XG4gICAgaWYgKCFpc0RzZENvbXBvbmVudChpbnN0YW5jZSkpIHtcbiAgICAgIGxvZy5lcnJvcihgPCR7dGFnTmFtZX0+IGRvZXMgbm90IGltcGxlbWVudCByZW5kZXIoKTogVk5vZGUgfCBudWxsLmApO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgY29uc3QgZXJyTXNnID0gZm9ybWF0RXJyb3IoZXJyKTtcbiAgICBsb2cuZXJyb3IoYEZhaWxlZCB0byBpbnN0YW50aWF0ZSA8JHt0YWdOYW1lfT46ICR7ZXJyTXNnfWApO1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzRHNkQ29tcG9uZW50KHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgRHNkQ29tcG9uZW50IHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICB2YWx1ZSAhPT0gbnVsbCAmJlxuICAgIHR5cGVvZiBSZWZsZWN0LmdldCh2YWx1ZSwgJ3JlbmRlcicpID09PSAnZnVuY3Rpb24nO1xufVxuXG5mdW5jdGlvbiBpbmplY3RQcm9wcyhcbiAgaW5zdGFuY2U6IERzZENvbXBvbmVudCxcbiAgdGFnTmFtZTogc3RyaW5nLFxuICBwcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4pOiB2b2lkIHtcbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHMpKSB7XG4gICAgaWYgKERBTkdFUk9VU19LRVlTLmhhcyhrZXkpKSB7XG4gICAgICBsb2cud2FybihcbiAgICAgICAgYFNraXBwaW5nIGRhbmdlcm91cyBwcm9wIGtleSBcIiR7a2V5fVwiIG9uIDwke3RhZ05hbWV9PiAtIHBvdGVudGlhbCBwcm90b3R5cGUgcG9sbHV0aW9uYCxcbiAgICAgICk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIChpbnN0YW5jZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilba2V5XSA9IHZhbHVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGxvZy5kZWJ1ZyhcbiAgICAgICAgYENhbm5vdCBzZXQgcmVhZC1vbmx5IHByb3BlcnR5IFwiJHtrZXl9XCIgb24gPCR7dGFnTmFtZX0+OiAke2Zvcm1hdEVycm9yKGUpfWAsXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuXG4vLyDilIDilIDilIAgRFNEIFRlbXBsYXRlIEF0dHJpYnV0ZXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmZ1bmN0aW9uIGJ1aWxkRHNkVGVtcGxhdGVBdHRycyhvcHRpb25zPzogRHNkT3B0aW9ucyk6IHN0cmluZyB7XG4gIGlmICghb3B0aW9ucykgcmV0dXJuICcnO1xuICBjb25zdCBwYXJ0czogc3RyaW5nW10gPSBbXTtcbiAgaWYgKG9wdGlvbnMuZGVsZWdhdGVzRm9jdXMpIHBhcnRzLnB1c2goJyBzaGFkb3dyb290ZGVsZWdhdGVzZm9jdXMnKTtcbiAgaWYgKG9wdGlvbnMuY2xvbmFibGUpIHBhcnRzLnB1c2goJyBzaGFkb3dyb290Y2xvbmFibGUnKTtcbiAgaWYgKG9wdGlvbnMuc2VyaWFsaXphYmxlKSBwYXJ0cy5wdXNoKCcgc2hhZG93cm9vdHNlcmlhbGl6YWJsZScpO1xuICBpZiAob3B0aW9ucy5zbG90QXNzaWdubWVudCA9PT0gJ21hbnVhbCcpIHtcbiAgICBwYXJ0cy5wdXNoKCcgc2hhZG93cm9vdHNsb3Rhc3NpZ25tZW50PVwibWFudWFsXCInKTtcbiAgfVxuICBpZiAob3B0aW9ucy5jdXN0b21FbGVtZW50UmVnaXN0cnkpIHtcbiAgICBwYXJ0cy5wdXNoKCcgc2hhZG93cm9vdGN1c3RvbWVsZW1lbnRyZWdpc3RyeScpO1xuICB9XG4gIHJldHVybiBwYXJ0cy5qb2luKCcnKTtcbn1cblxuLy8g4pSA4pSA4pSAIERTRCBPdXRwdXQgV3JhcHBpbmcg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmZ1bmN0aW9uIHdyYXBEc2RPdXRwdXQocGFyYW1zOiB7XG4gIHRhZ05hbWU6IHN0cmluZztcbiAgcHJvcHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBjb250ZW50OiBzdHJpbmc7XG4gIHN0eWxlQ3NzOiBzdHJpbmc7XG4gIGxheWVyOiBzdHJpbmc7XG4gIHNvdXJjZVN0cjogc3RyaW5nO1xuICBkc2RPcHRpb25zPzogRHNkT3B0aW9ucztcbiAgbGlnaHREb20/OiBSZW5kZXJOb2RlW107XG59KTogc3RyaW5nIHtcbiAgY29uc3QgeyB0YWdOYW1lLCBwcm9wcywgY29udGVudCwgc3R5bGVDc3MsIGxheWVyLCBzb3VyY2VTdHIsIGRzZE9wdGlvbnMsIGxpZ2h0RG9tIH0gPSBwYXJhbXM7XG4gIGNvbnN0IHB1YmxpY1Byb3BzID0gZmlsdGVyUHVibGljRHNkUHJvcHMocHJvcHMpO1xuICBjb25zdCBzc3JQcm9wc0F0dHIgPSBPYmplY3Qua2V5cyhwdWJsaWNQcm9wcykubGVuZ3RoID4gMFxuICAgID8gYCBkYXRhLXNzci1wcm9wcz1cIiR7ZXNjYXBlQXR0clZhbHVlKEpTT04uc3RyaW5naWZ5KHB1YmxpY1Byb3BzKSl9XCJgXG4gICAgOiAnJztcblxuICByZXR1cm4gc2VyaWFsaXplUmVuZGVyTm9kZShcbiAgICBkc2RIb3N0Tm9kZSh7XG4gICAgICB0YWc6IHRhZ05hbWUsXG4gICAgICBhdHRyczogcHVibGljUHJvcHMsXG4gICAgICBzc3JQcm9wc0F0dHIsXG4gICAgICBzb3VyY2U6IHNvdXJjZVN0cixcbiAgICAgIHRlbXBsYXRlQXR0cnM6IGJ1aWxkRHNkVGVtcGxhdGVBdHRycyhkc2RPcHRpb25zKSxcbiAgICAgIHN0eWxlQ3NzLFxuICAgICAgc2hhZG93OiBbdHJ1c3RlZEh0bWxOb2RlKGNvbnRlbnQpXSxcbiAgICAgIGxpZ2h0OiBsaWdodERvbSA/PyBbXSxcbiAgICAgIGxheWVyLFxuICAgIH0pLFxuICApO1xufVxuXG5mdW5jdGlvbiBmaWx0ZXJQdWJsaWNEc2RQcm9wcyhwcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIGNvbnN0IHB1YmxpY1Byb3BzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhwcm9wcykpIHtcbiAgICBpZiAoa2V5LnN0YXJ0c1dpdGgoJ19fb3BlbkVsZW1lbnQnKSkgY29udGludWU7XG4gICAgcHVibGljUHJvcHNba2V5XSA9IHZhbHVlO1xuICB9XG4gIHJldHVybiBwdWJsaWNQcm9wcztcbn1cblxuLy8g4pSA4pSA4pSAIERTRCBSZW5kZXJpbmcg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVuZGVyRHNkT3B0aW9ucyB7XG4gIGNvbXBvbmVudENsYXNzPzogQ3VzdG9tRWxlbWVudENvbnN0cnVjdG9yO1xuICBwcm9wcz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBzb3VyY2VJbmZvPzogeyByb3V0ZT86IHN0cmluZzsgc291cmNlPzogc3RyaW5nIH07XG4gIGRzZE9wdGlvbnM/OiBEc2RPcHRpb25zO1xuICBuZXN0aW5nRGVwdGg/OiBudW1iZXI7XG4gIGhvb2tzPzogUmVuZGVySG9va3M7XG4gIGxpZ2h0RG9tPzogUmVuZGVyTm9kZVtdO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVuZGVyRHNkKFxuICBpbnB1dDogc3RyaW5nIHwgQ3VzdG9tRWxlbWVudENvbnN0cnVjdG9yLFxuICBvcHRpb25zOiBSZW5kZXJEc2RPcHRpb25zID0ge30sXG4pOiBQcm9taXNlPFJlbmRlck91dHB1dD4ge1xuICBsZXQgdGFnTmFtZTogc3RyaW5nO1xuICBsZXQgY29tcG9uZW50Q2xhc3M6IEN1c3RvbUVsZW1lbnRDb25zdHJ1Y3RvcjtcbiAgY29uc3QgcHJvcHMgPSBvcHRpb25zLnByb3BzID8/IHt9O1xuXG4gIGlmICh0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnKSB7XG4gICAgdGFnTmFtZSA9IGlucHV0O1xuICAgIGlmIChvcHRpb25zPy5jb21wb25lbnRDbGFzcykge1xuICAgICAgY29tcG9uZW50Q2xhc3MgPSBvcHRpb25zLmNvbXBvbmVudENsYXNzO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBjbHMgPSBnbG9iYWxUaGlzLmN1c3RvbUVsZW1lbnRzPy5nZXQodGFnTmFtZSkgYXMgQ3VzdG9tRWxlbWVudENvbnN0cnVjdG9yIHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKCFjbHMpIHtcbiAgICAgICAgbG9nLndhcm4oYDwke3RhZ05hbWV9PiBpcyBub3QgcmVnaXN0ZXJlZCAtIHJlbmRlcmluZyBhcyB2b2lkIGVsZW1lbnRgKTtcbiAgICAgICAgY29uc3QgYXR0cnMgPSBzZXJpYWxpemVBdHRycyh0YWdOYW1lLCBwcm9wcyk7XG4gICAgICAgIGNvbnN0IGh0bWwgPSBgPCR7dGFnTmFtZX0ke2F0dHJzfT48LyR7dGFnTmFtZX0+YDtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBodG1sLFxuICAgICAgICAgIGVycm9yczogW10sXG4gICAgICAgICAgbWV0cmljczoge1xuICAgICAgICAgICAgdGFnTmFtZSxcbiAgICAgICAgICAgIHJlbmRlclRpbWVNczogMCxcbiAgICAgICAgICAgIHRlbXBsYXRlU2l6ZTogMCxcbiAgICAgICAgICAgIGxheWVyOiAnZHNkLXN0YXRpYycsXG4gICAgICAgICAgICBoYXNFcnJvcjogZmFsc2UsXG4gICAgICAgICAgICBuZXN0aW5nRGVwdGg6IDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBoeWRyYXRpb25IaW50czogW10sXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBjb21wb25lbnRDbGFzcyA9IGNscztcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgY29tcG9uZW50Q2xhc3MgPSBpbnB1dDtcbiAgICB0YWdOYW1lID0gKGlucHV0IGFzIERzZENvbXBvbmVudENvbnN0cnVjdG9yKS50YWdOYW1lID8/ICd1bmtub3duJztcbiAgfVxuXG4gIGNvbnN0IHNvdXJjZUluZm8gPSBvcHRpb25zLnNvdXJjZUluZm87XG4gIGNvbnN0IGRzZE9wdGlvbnMgPSBvcHRpb25zLmRzZE9wdGlvbnM7XG4gIGNvbnN0IG5lc3RpbmdEZXB0aCA9IG9wdGlvbnMubmVzdGluZ0RlcHRoO1xuICBjb25zdCBob29rcyA9IG9wdGlvbnMuaG9va3M7XG5cbiAgY29uc3QgX25lc3RpbmdEZXB0aCA9IG5lc3RpbmdEZXB0aCA/PyAwO1xuICBjb25zdCBzdGFydFRpbWUgPSB0eXBlb2YgcGVyZm9ybWFuY2UgIT09ICd1bmRlZmluZWQnID8gcGVyZm9ybWFuY2Uubm93KCkgOiAwO1xuICBjb25zdCBzb3VyY2VTdHIgPSBzb3VyY2VJbmZvXG4gICAgPyBgJHtzb3VyY2VJbmZvLnJvdXRlID8gYCByb3V0ZT1cIiR7c291cmNlSW5mby5yb3V0ZX1cImAgOiAnJ30ke1xuICAgICAgc291cmNlSW5mby5zb3VyY2UgPyBgIHNvdXJjZT1cIiR7c291cmNlSW5mby5zb3VyY2V9XCJgIDogJydcbiAgICB9YFxuICAgIDogJyc7XG5cbiAgY29uc3QgY29sbGVjdGVkRXJyb3JzOiBSZW5kZXJFcnJvcltdID0gW107XG4gIGNvbnN0IGNvbGxlY3RlZEhpbnRzOiBIeWRyYXRpb25IaW50W10gPSBbXTtcbiAgbGV0IGhhc0Vycm9yID0gZmFsc2U7XG5cbiAgY29uc3QgcmVuZGVySW5wdXQ6IFJlbmRlcklucHV0ID0ge1xuICAgIHRhZ05hbWUsXG4gICAgY29tcG9uZW50Q2xhc3MsXG4gICAgcHJvcHMsXG4gICAgZHNkT3B0aW9ucyxcbiAgICBuZXN0aW5nRGVwdGg6IF9uZXN0aW5nRGVwdGgsXG4gIH07XG5cbiAgaWYgKGhvb2tzPy5iZWZvcmVSZW5kZXIpIHtcbiAgICB0cnkge1xuICAgICAgaG9va3MuYmVmb3JlUmVuZGVyKHJlbmRlcklucHV0KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2cuZGVidWcoYGJlZm9yZVJlbmRlciBob29rIHRocmV3OiAke2Zvcm1hdEVycm9yKGUpfWApO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGluc3RhbmNlID0gaW5zdGFudGlhdGVDb21wb25lbnQodGFnTmFtZSwgY29tcG9uZW50Q2xhc3MpO1xuICBpZiAoIWluc3RhbmNlKSB7XG4gICAgY29uc3QgZXJyTXNnID0gJ0ZhaWxlZCB0byBpbnN0YW50aWF0ZSc7XG4gICAgY29uc3QgZXJyID0gY2xhc3NpZnlFcnJvcignaW5zdGFudGlhdGUnLCB0YWdOYW1lLCBlcnJNc2csIGZhbHNlKTtcbiAgICBjb2xsZWN0ZWRFcnJvcnMucHVzaChlcnIpO1xuICAgIGhhc0Vycm9yID0gdHJ1ZTtcbiAgICBob29rcz8ub25FcnJvcj8uKGVycik7XG5cbiAgICBjb25zdCBodG1sID0gaW5zdGFudGlhdGlvbkVycm9ySHRtbChcbiAgICAgIHRhZ05hbWUsXG4gICAgICBlcnJNc2csXG4gICAgICBzb3VyY2VTdHIsXG4gICAgICBzb3VyY2VJbmZvPy5yb3V0ZSxcbiAgICAgIHNvdXJjZUluZm8/LnNvdXJjZSxcbiAgICApO1xuXG4gICAgY29uc3QgcmVzdWx0OiBSZW5kZXJPdXRwdXQgPSB7XG4gICAgICBodG1sLFxuICAgICAgZXJyb3JzOiBjb2xsZWN0ZWRFcnJvcnMsXG4gICAgICBtZXRyaWNzOiB7XG4gICAgICAgIHRhZ05hbWUsXG4gICAgICAgIHJlbmRlclRpbWVNczogMCxcbiAgICAgICAgdGVtcGxhdGVTaXplOiAwLFxuICAgICAgICBsYXllcjogJ2RzZC1zdGF0aWMnLFxuICAgICAgICBoYXNFcnJvcjogdHJ1ZSxcbiAgICAgICAgbmVzdGluZ0RlcHRoOiBfbmVzdGluZ0RlcHRoLFxuICAgICAgfSxcbiAgICAgIGh5ZHJhdGlvbkhpbnRzOiBjb2xsZWN0ZWRIaW50cyxcbiAgICB9O1xuICAgIGhvb2tzPy5hZnRlclJlbmRlcj8uKHJlc3VsdCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGluamVjdFByb3BzKGluc3RhbmNlLCB0YWdOYW1lLCBwcm9wcyk7XG5cbiAgbGV0IGNvbnRlbnQgPSAnJztcbiAgdHJ5IHtcbiAgICBjb25zdCByZXN1bHQ6IHVua25vd24gPSBpbnN0YW5jZS5yZW5kZXIoKTtcbiAgICBpZiAocmVzdWx0ID09IG51bGwpIHtcbiAgICAgIGNvbnRlbnQgPSAnJztcbiAgICB9IGVsc2UgaWYgKGlzVk5vZGUocmVzdWx0KSkge1xuICAgICAgY29udGVudCA9IGF3YWl0IHJlbmRlckRzZFRyZWUocmVzdWx0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9nLmRlYnVnKGBVbnN1cHBvcnRlZCByZW5kZXIoKSByZXR1cm4gZm9yIDwke3RhZ05hbWV9PjogJHtkZXNjcmliZVJlbmRlclZhbHVlKHJlc3VsdCl9YCk7XG4gICAgICBjb25zdCBlcnJEZXRhaWwgPSBgQ29tcG9uZW50cyBtdXN0IHJldHVybiBhIFZOb2RlIGZyb20gcmVuZGVyKCksIGdvdCAke3R5cGVvZiByZXN1bHR9LmA7XG4gICAgICBjb25zdCBlcnIgPSBjbGFzc2lmeUVycm9yKCdyZW5kZXInLCB0YWdOYW1lLCBlcnJEZXRhaWwsIGZhbHNlKTtcbiAgICAgIGNvbGxlY3RlZEVycm9ycy5wdXNoKGVycik7XG4gICAgICBoYXNFcnJvciA9IHRydWU7XG4gICAgICBob29rcz8ub25FcnJvcj8uKGVycik7XG4gICAgICBjb250ZW50ID0gJyc7XG4gICAgfVxuICB9IGNhdGNoIChlcnIpIHtcbiAgICBjb25zdCBjbGFzc2lmaWVkRXJyID0gY2xhc3NpZnlFcnJvcigncmVuZGVyJywgdGFnTmFtZSwgZXJyLCB0cnVlKTtcbiAgICBjb2xsZWN0ZWRFcnJvcnMucHVzaChjbGFzc2lmaWVkRXJyKTtcbiAgICBoYXNFcnJvciA9IHRydWU7XG4gICAgaG9va3M/Lm9uRXJyb3I/LihjbGFzc2lmaWVkRXJyKTtcblxuICAgIGNvbnN0IGF0dHJzID0gc2VyaWFsaXplQXR0cnModGFnTmFtZSwgcHJvcHMpO1xuICAgIGNvbnN0IHJlbmRlckVuZEZhbGxiYWNrID0gc2FmZU5vdygpO1xuICAgIGNvbnN0IGZhbGxiYWNrUmVzdWx0OiBSZW5kZXJPdXRwdXQgPSB7XG4gICAgICBodG1sOiBgPCR7dGFnTmFtZX0ke2F0dHJzfT48LyR7dGFnTmFtZX0+YCxcbiAgICAgIGVycm9yczogY29sbGVjdGVkRXJyb3JzLFxuICAgICAgbWV0cmljczoge1xuICAgICAgICB0YWdOYW1lLFxuICAgICAgICByZW5kZXJUaW1lTXM6IHJlbmRlckVuZEZhbGxiYWNrIC0gc3RhcnRUaW1lLFxuICAgICAgICB0ZW1wbGF0ZVNpemU6IDAsXG4gICAgICAgIGxheWVyOiAnZHNkLXN0YXRpYycsXG4gICAgICAgIGhhc0Vycm9yOiBoYXNFcnJvcixcbiAgICAgICAgbmVzdGluZ0RlcHRoOiBfbmVzdGluZ0RlcHRoLFxuICAgICAgfSxcbiAgICAgIGh5ZHJhdGlvbkhpbnRzOiBjb2xsZWN0ZWRIaW50cyxcbiAgICB9O1xuICAgIGhvb2tzPy5hZnRlclJlbmRlcj8uKGZhbGxiYWNrUmVzdWx0KTtcbiAgICByZXR1cm4gZmFsbGJhY2tSZXN1bHQ7XG4gIH1cblxuICBsZXQgc3R5bGVDc3MgPSAnJztcblxuICBjb25zdCBjdG9yID0gY29tcG9uZW50Q2xhc3MgYXMgRHNkQ29tcG9uZW50Q29uc3RydWN0b3I7XG4gIGlmIChjdG9yLnN0eWxlcykge1xuICAgIGNvbnN0IHNoZWV0cyA9IEFycmF5LmlzQXJyYXkoY3Rvci5zdHlsZXMpID8gY3Rvci5zdHlsZXMgOiBbY3Rvci5zdHlsZXNdO1xuICAgIGZvciAoY29uc3Qgc2hlZXQgb2Ygc2hlZXRzKSB7XG4gICAgICB0cnkge1xuICAgICAgICBmb3IgKGNvbnN0IHJ1bGUgb2YgWy4uLnNoZWV0LmNzc1J1bGVzXSkge1xuICAgICAgICAgIHN0eWxlQ3NzICs9IHJ1bGUuY3NzVGV4dCArICdcXG4nO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gQ3Jvc3Mtb3JpZ2luIHN0eWxlc2hlZXQgb3IgZW1wdHkgc2hlZXQgLSBza2lwIHNpbGVudGx5XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgcmVuZGVyTW9kZSA9IGN0b3IucmVuZGVyTW9kZSA/PyAnc2hhZG93JztcbiAgY29uc3QgcmVzb2x2ZWRMYXllciA9IHJlbmRlck1vZGUgPT09ICdsaWdodCdcbiAgICA/ICdsaWdodC1kb20nXG4gICAgOiBkc2RPcHRpb25zPy5sYXllciB8fCBpbnN0YW5jZS5sYXllciB8fCAnZHNkLXN0YXRpYyc7XG5cbiAgY29uc3QgcmVuZGVyRW5kID0gc2FmZU5vdygpO1xuICBjb25zdCByZW5kZXJUaW1lTXMgPSByZW5kZXJFbmQgLSBzdGFydFRpbWU7XG5cbiAgY29uc3QgbWV0cmljczogRHNkUmVuZGVyTWV0cmljcyA9IHtcbiAgICB0YWdOYW1lLFxuICAgIHJlbmRlclRpbWVNcyxcbiAgICB0ZW1wbGF0ZVNpemU6IGNvbnRlbnQubGVuZ3RoLFxuICAgIGxheWVyOiByZXNvbHZlZExheWVyLFxuICAgIGhhc0Vycm9yLFxuICAgIG5lc3RpbmdEZXB0aDogX25lc3RpbmdEZXB0aCxcbiAgfTtcblxuICBpZiAocmVzb2x2ZWRMYXllciAhPT0gJ2RzZC1zdGF0aWMnKSB7XG4gICAgY29sbGVjdGVkSGludHMucHVzaCh7XG4gICAgICB0YWdOYW1lLFxuICAgICAgbGF5ZXI6IHJlc29sdmVkTGF5ZXIgYXMgQ29tcG9uZW50TGF5ZXIsXG4gICAgfSk7XG4gIH1cblxuICBjb25zdCBodG1sID0gd3JhcERzZE91dHB1dCh7XG4gICAgdGFnTmFtZSxcbiAgICBwcm9wcyxcbiAgICBjb250ZW50LFxuICAgIHN0eWxlQ3NzLFxuICAgIGxheWVyOiByZXNvbHZlZExheWVyLFxuICAgIHNvdXJjZVN0cixcbiAgICBkc2RPcHRpb25zLFxuICAgIGxpZ2h0RG9tOiBvcHRpb25zLmxpZ2h0RG9tLFxuICB9KTtcblxuICBjb25zdCBvdXRwdXQ6IFJlbmRlck91dHB1dCA9IHtcbiAgICBodG1sLFxuICAgIGVycm9yczogY29sbGVjdGVkRXJyb3JzLFxuICAgIG1ldHJpY3MsXG4gICAgaHlkcmF0aW9uSGludHM6IGNvbGxlY3RlZEhpbnRzLFxuICB9O1xuXG4gIGlmIChob29rcz8uYWZ0ZXJSZW5kZXIpIHtcbiAgICB0cnkge1xuICAgICAgaG9va3MuYWZ0ZXJSZW5kZXIob3V0cHV0KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2cuZGVidWcoYGFmdGVyUmVuZGVyIGhvb2sgdGhyZXc6ICR7Zm9ybWF0RXJyb3IoZSl9YCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuLyoqIFNhZmUgaGlnaC1yZXNvbHV0aW9uIHRpbWVzdGFtcCB3aXRoIFNTUi9lbnZpcm9ubWVudCBmYWxsYmFjay4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzYWZlTm93KCk6IG51bWJlciB7XG4gIHJldHVybiB0eXBlb2YgcGVyZm9ybWFuY2UgIT09ICd1bmRlZmluZWQnID8gcGVyZm9ybWFuY2Uubm93KCkgOiBEYXRlLm5vdygpO1xufVxuXG5mdW5jdGlvbiBkZXNjcmliZVJlbmRlclZhbHVlKHZhbHVlOiB1bmtub3duKTogc3RyaW5nIHtcbiAgaWYgKHZhbHVlID09PSBudWxsIHx8IHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHJldHVybiB0eXBlb2YgdmFsdWU7XG4gIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyh2YWx1ZSkuam9pbignLCcpO1xuICByZXR1cm4gYG9iamVjdCBrZXlzPVske2tleXN9XWA7XG59XG5cbi8vIHYwLjIxLjA6IFN0cmVhbWluZyB0eXBlcyBhbmQgZnVuY3Rpb25zIG1vdmVkIHRvIHJlbmRlci1kc2Qtc3RyZWFtLnRzLlxuZXhwb3J0IHsgY3JlYXRlUmVuZGVyRHNkU3RyZWFtTWV0cmljcywgcmVuZGVyRHNkU3RyZWFtIH0gZnJvbSAnLi9yZW5kZXItZHNkLXN0cmVhbS5qcyc7XG5leHBvcnQgdHlwZSB7XG4gIFJlbmRlckRzZFN0cmVhbUNodW5rLFxuICBSZW5kZXJEc2RTdHJlYW1Db21wb25lbnQsXG4gIFJlbmRlckRzZFN0cmVhbU1ldHJpY3MsXG4gIFJlbmRlckRzZFN0cmVhbU9wdGlvbnMsXG59IGZyb20gJy4vcmVuZGVyLWRzZC1zdHJlYW0uanMnO1xuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7OztDQVdDLEdBZ0JELFNBQVMsWUFBWSxRQUFRLGNBQWM7QUFDM0MsU0FBUyxXQUFXLFFBQVEsY0FBYztBQUMxQyxTQUFTLGVBQWUsUUFBUSxtQkFBbUI7QUFDbkQsU0FBUyxPQUFPLFFBQVEsYUFBYTtBQUNyQyxTQUFTLGFBQWEsUUFBUSxpQkFBaUI7QUFDL0Ms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
@@ -0,0 +1,32 @@
1
+ import { type EventMarkerContext } from "./event-marker.js";
2
+ export type RenderNode = {
3
+ kind: 'text';
4
+ value: string;
5
+ } | {
6
+ kind: 'trusted-html';
7
+ value: string;
8
+ } | {
9
+ kind: 'fragment';
10
+ children: RenderNode[];
11
+ } | {
12
+ kind: 'element';
13
+ tag: string;
14
+ attrs: Record<string, unknown>;
15
+ eventAttrs?: string;
16
+ children: RenderNode[];
17
+ voidElement?: boolean;
18
+ } | {
19
+ kind: 'dsd-host';
20
+ tag: string;
21
+ attrs: Record<string, unknown>;
22
+ ssrPropsAttr: string;
23
+ source: string;
24
+ templateAttrs: string;
25
+ styleCss: string;
26
+ shadow: RenderNode[];
27
+ light: RenderNode[];
28
+ layer: string;
29
+ };
30
+ export declare function camelToKebab(str: string): string;
31
+ export declare function serializeAttrs(tag: string, props: Record<string, unknown>): string;
32
+ export declare function renderDsdTree(node: unknown, eventContext?: EventMarkerContext): Promise<string>;