@openelement/ui 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 +78 -0
- package/package.json +142 -0
- package/src/daisy-classes.d.ts +7 -0
- package/src/daisy-classes.js +770 -0
- package/src/index.d.ts +57 -0
- package/src/index.js +62 -0
- package/src/manifest.d.ts +8 -0
- package/src/manifest.js +255 -0
- package/src/open-badge.d.ts +15 -0
- package/src/open-badge.js +88 -0
- package/src/open-brand-mark.d.ts +14 -0
- package/src/open-brand-mark.js +107 -0
- package/src/open-button.d.ts +38 -0
- package/src/open-button.js +219 -0
- package/src/open-callout.d.ts +26 -0
- package/src/open-callout.js +99 -0
- package/src/open-card.d.ts +33 -0
- package/src/open-card.js +107 -0
- package/src/open-code-block.d.ts +44 -0
- package/src/open-code-block.js +267 -0
- package/src/open-dialog.d.ts +47 -0
- package/src/open-dialog.js +235 -0
- package/src/open-dropdown.d.ts +25 -0
- package/src/open-dropdown.js +45 -0
- package/src/open-hero-ping.d.ts +27 -0
- package/src/open-hero-ping.js +136 -0
- package/src/open-input.d.ts +51 -0
- package/src/open-input.js +233 -0
- package/src/open-lab-panel.d.ts +16 -0
- package/src/open-lab-panel.js +151 -0
- package/src/open-lab-stage.d.ts +15 -0
- package/src/open-lab-stage.js +622 -0
- package/src/open-layout.d.ts +111 -0
- package/src/open-layout.js +1377 -0
- package/src/open-modal.d.ts +25 -0
- package/src/open-modal.js +48 -0
- package/src/open-props-tokens.d.ts +7 -0
- package/src/open-props-tokens.js +474 -0
- package/src/open-standards-visual.d.ts +20 -0
- package/src/open-standards-visual.js +425 -0
- package/src/open-step-card.d.ts +34 -0
- package/src/open-step-card.js +117 -0
- package/src/open-tabs.d.ts +27 -0
- package/src/open-tabs.js +56 -0
- package/src/open-theme-toggle.d.ts +38 -0
- package/src/open-theme-toggle.js +223 -0
package/src/open-tabs.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** @jsxImportSource @openelement/core */ /**
|
|
2
|
+
* @openelement/ui - open-tabs
|
|
3
|
+
*
|
|
4
|
+
* DaisyUI-style tabs using DsdElement + Signals.
|
|
5
|
+
* Reads light DOM children with `slot="tab"` and `slot="panel"`
|
|
6
|
+
* to render tab buttons and panel content.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* ```html
|
|
10
|
+
* <open-tabs>
|
|
11
|
+
* <span slot="tab">Tab 1</span>
|
|
12
|
+
* <span slot="tab">Tab 2</span>
|
|
13
|
+
* <div slot="panel">Panel 1 content</div>
|
|
14
|
+
* <div slot="panel">Panel 2 content</div>
|
|
15
|
+
* </open-tabs>
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @slot tab - Tab button labels (multiple)
|
|
19
|
+
* @slot panel - Tab panel content (multiple, one per tab)
|
|
20
|
+
*/ import { OpenElement } from '@openelement/element';
|
|
21
|
+
import { signal } from '@openelement/signal';
|
|
22
|
+
import { daisyClassSheet } from './daisy-classes.js';
|
|
23
|
+
export const tagName = 'open-tabs';
|
|
24
|
+
export class OpenTabs extends OpenElement {
|
|
25
|
+
static styles = [
|
|
26
|
+
daisyClassSheet
|
|
27
|
+
];
|
|
28
|
+
#active = signal(0);
|
|
29
|
+
#select(idx) {
|
|
30
|
+
this.#active.value = idx;
|
|
31
|
+
this.update();
|
|
32
|
+
}
|
|
33
|
+
render() {
|
|
34
|
+
const tabs = this.querySelectorAll('[slot="tab"]');
|
|
35
|
+
const panels = this.querySelectorAll('[slot="panel"]');
|
|
36
|
+
const active = this.#active.value;
|
|
37
|
+
return <div>
|
|
38
|
+
<div class='tabs'>
|
|
39
|
+
{Array.from(tabs).map((tab, i)=><button type='button' class={`tab ${i === active ? 'tab-active' : ''}`} onClick={()=>this.#select(i)}>
|
|
40
|
+
{tab.textContent}
|
|
41
|
+
</button>)}
|
|
42
|
+
</div>
|
|
43
|
+
<div>
|
|
44
|
+
{Array.from(panels).map((panel, i)=><div style={{
|
|
45
|
+
display: i === active ? 'block' : 'none'
|
|
46
|
+
}}>{panel.innerHTML}</div>)}
|
|
47
|
+
</div>
|
|
48
|
+
</div>;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export default OpenTabs;
|
|
52
|
+
// Guard: idempotent across SSR paths
|
|
53
|
+
if (typeof customElements !== 'undefined' && !customElements.get(tagName)) {
|
|
54
|
+
customElements.define(tagName, OpenTabs);
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9vcGVuZWxlbWVudC9vcGVuZWxlbWVudC9wYWNrYWdlcy91aS9zcmMvb3Blbi10YWJzLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiogQGpzeEltcG9ydFNvdXJjZSBAb3BlbmVsZW1lbnQvY29yZSAqL1xuLyoqXG4gKiBAb3BlbmVsZW1lbnQvdWkgLSBvcGVuLXRhYnNcbiAqXG4gKiBEYWlzeVVJLXN0eWxlIHRhYnMgdXNpbmcgRHNkRWxlbWVudCArIFNpZ25hbHMuXG4gKiBSZWFkcyBsaWdodCBET00gY2hpbGRyZW4gd2l0aCBgc2xvdD1cInRhYlwiYCBhbmQgYHNsb3Q9XCJwYW5lbFwiYFxuICogdG8gcmVuZGVyIHRhYiBidXR0b25zIGFuZCBwYW5lbCBjb250ZW50LlxuICpcbiAqIFVzYWdlOlxuICogYGBgaHRtbFxuICogPG9wZW4tdGFicz5cbiAqICAgPHNwYW4gc2xvdD1cInRhYlwiPlRhYiAxPC9zcGFuPlxuICogICA8c3BhbiBzbG90PVwidGFiXCI+VGFiIDI8L3NwYW4+XG4gKiAgIDxkaXYgc2xvdD1cInBhbmVsXCI+UGFuZWwgMSBjb250ZW50PC9kaXY+XG4gKiAgIDxkaXYgc2xvdD1cInBhbmVsXCI+UGFuZWwgMiBjb250ZW50PC9kaXY+XG4gKiA8L29wZW4tdGFicz5cbiAqIGBgYFxuICpcbiAqIEBzbG90IHRhYiAtIFRhYiBidXR0b24gbGFiZWxzIChtdWx0aXBsZSlcbiAqIEBzbG90IHBhbmVsIC0gVGFiIHBhbmVsIGNvbnRlbnQgKG11bHRpcGxlLCBvbmUgcGVyIHRhYilcbiAqL1xuXG5pbXBvcnQgeyBPcGVuRWxlbWVudCwgdHlwZSBWTm9kZSB9IGZyb20gJ0BvcGVuZWxlbWVudC9lbGVtZW50JztcbmltcG9ydCB7IHNpZ25hbCB9IGZyb20gJ0BvcGVuZWxlbWVudC9zaWduYWwnO1xuaW1wb3J0IHsgZGFpc3lDbGFzc1NoZWV0IH0gZnJvbSAnLi9kYWlzeS1jbGFzc2VzLmpzJztcblxuZXhwb3J0IGNvbnN0IHRhZ05hbWUgPSAnb3Blbi10YWJzJztcblxuZXhwb3J0IGNsYXNzIE9wZW5UYWJzIGV4dGVuZHMgT3BlbkVsZW1lbnQge1xuICBzdGF0aWMgb3ZlcnJpZGUgc3R5bGVzID0gW2RhaXN5Q2xhc3NTaGVldF07XG4gICNhY3RpdmUgPSBzaWduYWwoMCk7XG5cbiAgI3NlbGVjdChpZHg6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuI2FjdGl2ZS52YWx1ZSA9IGlkeDtcbiAgICB0aGlzLnVwZGF0ZSgpO1xuICB9XG5cbiAgb3ZlcnJpZGUgcmVuZGVyKCk6IFZOb2RlIHtcbiAgICBjb25zdCB0YWJzID0gdGhpcy5xdWVyeVNlbGVjdG9yQWxsPEhUTUxFbGVtZW50PignW3Nsb3Q9XCJ0YWJcIl0nKTtcbiAgICBjb25zdCBwYW5lbHMgPSB0aGlzLnF1ZXJ5U2VsZWN0b3JBbGw8SFRNTEVsZW1lbnQ+KCdbc2xvdD1cInBhbmVsXCJdJyk7XG4gICAgY29uc3QgYWN0aXZlID0gdGhpcy4jYWN0aXZlLnZhbHVlO1xuXG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9J3RhYnMnPlxuICAgICAgICAgIHtBcnJheS5mcm9tKHRhYnMpLm1hcCgodGFiLCBpKSA9PiAoXG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIHR5cGU9J2J1dHRvbidcbiAgICAgICAgICAgICAgY2xhc3M9e2B0YWIgJHtpID09PSBhY3RpdmUgPyAndGFiLWFjdGl2ZScgOiAnJ31gfVxuICAgICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiB0aGlzLiNzZWxlY3QoaSl9XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHt0YWIudGV4dENvbnRlbnR9XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICApKX1cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXY+XG4gICAgICAgICAge0FycmF5LmZyb20ocGFuZWxzKS5tYXAoKHBhbmVsLCBpKSA9PiAoXG4gICAgICAgICAgICA8ZGl2IHN0eWxlPXt7IGRpc3BsYXk6IGkgPT09IGFjdGl2ZSA/ICdibG9jaycgOiAnbm9uZScgfX0+e3BhbmVsLmlubmVySFRNTH08L2Rpdj5cbiAgICAgICAgICApKX1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IE9wZW5UYWJzO1xuXG4vLyBHdWFyZDogaWRlbXBvdGVudCBhY3Jvc3MgU1NSIHBhdGhzXG5pZiAodHlwZW9mIGN1c3RvbUVsZW1lbnRzICE9PSAndW5kZWZpbmVkJyAmJiAhY3VzdG9tRWxlbWVudHMuZ2V0KHRhZ05hbWUpKSB7XG4gIGN1c3RvbUVsZW1lbnRzLmRlZmluZSh0YWdOYW1lLCBPcGVuVGFicyk7XG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsdUNBQXVDLEdBQ3ZDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBbUJDLEdBRUQsU0FBUyxXQUFXLFFBQW9CLHVCQUF1QjtBQUMvRCxTQUFTLE1BQU0sUUFBUSxzQkFBc0I7QUFDN0MsU0FBUyxlQUFlLFFBQVEscUJBQXFCO0FBRXJELE9BQU8sTUFBTSxVQUFVLFlBQVk7QUFFbkMsT0FBTyxNQUFNLGlCQUFpQjtFQUM1QixPQUFnQixTQUFTO0lBQUM7R0FBZ0IsQ0FBQztFQUMzQyxDQUFBLE1BQU8sR0FBRyxPQUFPLEdBQUc7RUFFcEIsQ0FBQSxNQUFPLENBQUMsR0FBVztJQUNqQixJQUFJLENBQUMsQ0FBQSxNQUFPLENBQUMsS0FBSyxHQUFHO0lBQ3JCLElBQUksQ0FBQyxNQUFNO0VBQ2I7RUFFUyxTQUFnQjtJQUN2QixNQUFNLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFjO0lBQ2hELE1BQU0sU0FBUyxJQUFJLENBQUMsZ0JBQWdCLENBQWM7SUFDbEQsTUFBTSxTQUFTLElBQUksQ0FBQyxDQUFBLE1BQU8sQ0FBQyxLQUFLO0lBRWpDLFFBQ0csSUFBSTtRQUNILENBQUMsSUFBSSxNQUFNLE9BQU87VUFDaEIsQ0FBQyxNQUFNLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEtBQUssS0FDekIsT0FDQyxLQUFLLFNBQ0wsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLFNBQVMsZUFBZSxJQUFJLEVBQ2hELFNBQVMsSUFBTSxJQUFJLENBQUMsQ0FBQSxNQUFPLENBQUMsSUFDN0I7Y0FDQyxDQUFDLElBQUksV0FBVyxDQUFDO1lBQ25CLEVBQUUsU0FDRDtRQUNMLEVBQUUsSUFBSTtRQUNOLENBQUMsSUFBSTtVQUNILENBQUMsTUFBTSxJQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQyxPQUFPLEtBQzdCLElBQUksT0FBTztRQUFFLFNBQVMsTUFBTSxTQUFTLFVBQVU7TUFBTyxJQUFJLE1BQU0sU0FBUyxHQUFHLE1BQzVFO1FBQ0wsRUFBRSxJQUFJO01BQ1IsRUFBRTtFQUVOO0FBQ0Y7QUFFQSxlQUFlLFNBQVM7QUFFeEIscUNBQXFDO0FBQ3JDLElBQUksT0FBTyxtQkFBbUIsZUFBZSxDQUFDLGVBQWUsR0FBRyxDQUFDLFVBQVU7RUFDekUsZUFBZSxNQUFNLENBQUMsU0FBUztBQUNqQyJ9
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** @jsxImportSource @openelement/core */ /**
|
|
2
|
+
* @openelement/ui - open-theme-toggle
|
|
3
|
+
*
|
|
4
|
+
* Theme toggle Reactive DSD component for Dark/Light mode switching.
|
|
5
|
+
* Swiss International Style: Pure B&W, minimal.
|
|
6
|
+
*
|
|
7
|
+
* v0.21.0: Uses DsdElement + html templates + Signals.
|
|
8
|
+
* v0.24.1: Migrated from html`` template to JSX (ADR-0057).
|
|
9
|
+
*
|
|
10
|
+
* @csspart toggle -The button element
|
|
11
|
+
* @csspart icon-sun -The sun SVG icon
|
|
12
|
+
* @csspart icon-moon -The moon SVG icon
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* ```html
|
|
16
|
+
* <open-theme-toggle theme="light"></open-theme-toggle>
|
|
17
|
+
* ```
|
|
18
|
+
*/ import { OpenElement } from '@openelement/element';
|
|
19
|
+
import { type StyleSheetLike } from '@openelement/core/style-sheet';
|
|
20
|
+
export declare const tagName: 'open-theme-toggle';
|
|
21
|
+
declare const sheet: StyleSheetLike;
|
|
22
|
+
export declare class OpenThemeToggle extends OpenElement {
|
|
23
|
+
static override styles: [];
|
|
24
|
+
static delegatesFocus: boolean;
|
|
25
|
+
static override observedAttributes: [string];
|
|
26
|
+
private _theme: any;
|
|
27
|
+
private _initDone: any;
|
|
28
|
+
override connectedCallback(): void;
|
|
29
|
+
private _initTheme: any;
|
|
30
|
+
private _persistTheme: any;
|
|
31
|
+
protected override onDsdHydrated(): void;
|
|
32
|
+
protected override onCsrRendered(): void;
|
|
33
|
+
override render(): ReturnType<typeof OpenElement.prototype.render>;
|
|
34
|
+
private _handleToggle: any;
|
|
35
|
+
private _dispatchThemeChange: any;
|
|
36
|
+
override attributeChangedCallback(name: string, old: string | null, val: string | null): void;
|
|
37
|
+
}
|
|
38
|
+
export default OpenThemeToggle;
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/** @jsxImportSource @openelement/core */ /**
|
|
2
|
+
* @openelement/ui - open-theme-toggle
|
|
3
|
+
*
|
|
4
|
+
* Theme toggle Reactive DSD component for Dark/Light mode switching.
|
|
5
|
+
* Swiss International Style: Pure B&W, minimal.
|
|
6
|
+
*
|
|
7
|
+
* v0.21.0: Uses DsdElement + html templates + Signals.
|
|
8
|
+
* v0.24.1: Migrated from html`` template to JSX (ADR-0057).
|
|
9
|
+
*
|
|
10
|
+
* @csspart toggle -The button element
|
|
11
|
+
* @csspart icon-sun -The sun SVG icon
|
|
12
|
+
* @csspart icon-moon -The moon SVG icon
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* ```html
|
|
16
|
+
* <open-theme-toggle theme="light"></open-theme-toggle>
|
|
17
|
+
* ```
|
|
18
|
+
*/ import { OpenElement } from '@openelement/element';
|
|
19
|
+
import { StyleSheet } from '@openelement/core/style-sheet';
|
|
20
|
+
import { signal } from '@openelement/signal';
|
|
21
|
+
export const tagName = 'open-theme-toggle';
|
|
22
|
+
const sheet = new StyleSheet();
|
|
23
|
+
sheet.replaceSync(`
|
|
24
|
+
:host {
|
|
25
|
+
display: inline-block;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.theme-toggle {
|
|
29
|
+
display: inline-flex;
|
|
30
|
+
align-items: center;
|
|
31
|
+
justify-content: center;
|
|
32
|
+
width: 38px; height: 38px; padding: 0;
|
|
33
|
+
border: var(--border-size-1) solid color-mix(in srgb, var(--border) 72%, var(--brand));
|
|
34
|
+
border-radius: var(--radius-round);
|
|
35
|
+
background: color-mix(in srgb, var(--bg-elevated) 76%, transparent);
|
|
36
|
+
color: var(--text-muted);
|
|
37
|
+
box-shadow: inset 0 1px 0 color-mix(in srgb, var(--gray-0) 70%, transparent);
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
transition: all var(--ease-2) var(--duration-2);
|
|
40
|
+
}
|
|
41
|
+
.theme-toggle:hover {
|
|
42
|
+
color: var(--text-primary);
|
|
43
|
+
border-color: var(--brand-light);
|
|
44
|
+
background: color-mix(in srgb, var(--brand-pale) 42%, var(--bg-elevated));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.theme-toggle svg {
|
|
48
|
+
width: 16px;
|
|
49
|
+
height: 16px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.theme-toggle .icon-sun {
|
|
53
|
+
display: block;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.theme-toggle .icon-moon {
|
|
57
|
+
display: none;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.theme-toggle[data-theme="light"] .icon-sun {
|
|
61
|
+
display: none;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.theme-toggle[data-theme="light"] .icon-moon {
|
|
65
|
+
display: block;
|
|
66
|
+
}
|
|
67
|
+
`);
|
|
68
|
+
export class OpenThemeToggle extends OpenElement {
|
|
69
|
+
// ponytail: Safari does not recompute adoptedStyleSheets when
|
|
70
|
+
// :host([data-theme]) changes. The token sheets (openPropsTokenSheet,
|
|
71
|
+
// daisyClassSheet) are already injected as page-level <style> by
|
|
72
|
+
// vite.config.ts — CSS custom properties cascade from :root naturally.
|
|
73
|
+
// Only adopt the component-specific sheet.
|
|
74
|
+
static styles = [
|
|
75
|
+
sheet
|
|
76
|
+
];
|
|
77
|
+
static delegatesFocus = true;
|
|
78
|
+
static observedAttributes = [
|
|
79
|
+
'theme'
|
|
80
|
+
];
|
|
81
|
+
_theme = signal('dark');
|
|
82
|
+
_initDone = false;
|
|
83
|
+
connectedCallback() {
|
|
84
|
+
super.connectedCallback();
|
|
85
|
+
requestAnimationFrame(()=>this._initTheme());
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* v0.23.0: Theme initialization lives in _initTheme(), called from
|
|
89
|
+
* both onDsdHydrated() and onCsrRendered() so that the priority
|
|
90
|
+
* chain works regardless of hydration path.
|
|
91
|
+
*
|
|
92
|
+
* Priority: theme attribute > document.documentElement.dataset.theme
|
|
93
|
+
* > localStorage > prefers-color-scheme > default 'dark'.
|
|
94
|
+
*/ _initTheme() {
|
|
95
|
+
if (this._initDone) return;
|
|
96
|
+
this._initDone = true;
|
|
97
|
+
const themeAttr = this.getAttribute('theme');
|
|
98
|
+
if (themeAttr === 'light') {
|
|
99
|
+
this._theme.value = 'light';
|
|
100
|
+
} else if (themeAttr === 'dark') {
|
|
101
|
+
this._theme.value = 'dark';
|
|
102
|
+
} else {
|
|
103
|
+
const docTheme = document.documentElement?.dataset?.theme;
|
|
104
|
+
if (docTheme === 'light') {
|
|
105
|
+
this._theme.value = 'light';
|
|
106
|
+
} else if (docTheme === 'dark') {
|
|
107
|
+
this._theme.value = 'dark';
|
|
108
|
+
} else {
|
|
109
|
+
let resolved = false;
|
|
110
|
+
try {
|
|
111
|
+
const saved = localStorage.getItem('open-theme');
|
|
112
|
+
if (saved === 'light') {
|
|
113
|
+
this._theme.value = 'light';
|
|
114
|
+
resolved = true;
|
|
115
|
+
} else if (saved === 'dark') {
|
|
116
|
+
this._theme.value = 'dark';
|
|
117
|
+
resolved = true;
|
|
118
|
+
}
|
|
119
|
+
} catch {}
|
|
120
|
+
if (!resolved && globalThis.matchMedia) {
|
|
121
|
+
this._theme.value = globalThis.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
this.setAttribute('data-theme', this._theme.value);
|
|
126
|
+
document.documentElement.setAttribute('data-theme', this._theme.value);
|
|
127
|
+
if (document.documentElement.style) {
|
|
128
|
+
document.documentElement.style.colorScheme = this._theme.value;
|
|
129
|
+
}
|
|
130
|
+
// Propagate to parent open-layout
|
|
131
|
+
try {
|
|
132
|
+
const root = this.getRootNode();
|
|
133
|
+
if (root instanceof ShadowRoot && root.host) {
|
|
134
|
+
root.host.setAttribute('data-theme', this._theme.value);
|
|
135
|
+
}
|
|
136
|
+
} catch {}
|
|
137
|
+
this._dispatchThemeChange(this._theme.value);
|
|
138
|
+
this._persistTheme(this._theme.value);
|
|
139
|
+
}
|
|
140
|
+
_persistTheme(theme) {
|
|
141
|
+
try {
|
|
142
|
+
localStorage.setItem('open-theme', theme);
|
|
143
|
+
} catch {}
|
|
144
|
+
}
|
|
145
|
+
onDsdHydrated() {
|
|
146
|
+
super.onDsdHydrated();
|
|
147
|
+
requestAnimationFrame(()=>this._initTheme());
|
|
148
|
+
}
|
|
149
|
+
onCsrRendered() {
|
|
150
|
+
super.onCsrRendered();
|
|
151
|
+
}
|
|
152
|
+
render() {
|
|
153
|
+
// Zero signal.value reads in render (ADR-0062).
|
|
154
|
+
// effect binding that updates the attribute when theme changes.
|
|
155
|
+
// CSS selectors ([data-theme="light"]) handle icon visibility.
|
|
156
|
+
return <button type='button' className='theme-toggle' part='toggle' data-theme={this._theme} aria-label='Toggle theme' onClick={()=>this._handleToggle()}>
|
|
157
|
+
<svg className='icon-sun' part='icon-sun' viewBox='0 0 16 16' fill='none' stroke='currentColor' stroke-width='1.2' stroke-linecap='round'>
|
|
158
|
+
<circle cx='8' cy='8' r='3'/>
|
|
159
|
+
<line x1='8' y1='1' x2='8' y2='3'/>
|
|
160
|
+
<line x1='8' y1='13' x2='8' y2='15'/>
|
|
161
|
+
<line x1='1' y1='8' x2='3' y2='8'/>
|
|
162
|
+
<line x1='13' y1='8' x2='15' y2='8'/>
|
|
163
|
+
<line x1='3.05' y1='3.05' x2='4.46' y2='4.46'/>
|
|
164
|
+
<line x1='11.54' y1='11.54' x2='12.95' y2='12.95'/>
|
|
165
|
+
<line x1='3.05' y1='12.95' x2='4.46' y2='11.54'/>
|
|
166
|
+
<line x1='11.54' y1='4.46' x2='12.95' y2='3.05'/>
|
|
167
|
+
</svg>
|
|
168
|
+
<svg className='icon-moon' part='icon-moon' viewBox='0 0 16 16' fill='none' stroke='currentColor' stroke-width='1.2' stroke-linecap='round'>
|
|
169
|
+
<path d='M13.5 9.14A5.5 5.5 0 0 1 6.86 2.5 5.5 5.5 0 1 0 13.5 9.14Z'/>
|
|
170
|
+
</svg>
|
|
171
|
+
</button>;
|
|
172
|
+
}
|
|
173
|
+
_handleToggle() {
|
|
174
|
+
const theme = this._theme.value === 'light' ? 'dark' : 'light';
|
|
175
|
+
this._theme.value = theme;
|
|
176
|
+
document.documentElement.setAttribute('data-theme', theme);
|
|
177
|
+
if (document.documentElement.style) {
|
|
178
|
+
document.documentElement.style.colorScheme = theme;
|
|
179
|
+
}
|
|
180
|
+
// Propagate data-theme to parent <open-layout> so :host([data-theme="dark"]) matches
|
|
181
|
+
try {
|
|
182
|
+
const root = this.getRootNode();
|
|
183
|
+
if (root instanceof ShadowRoot && root.host) {
|
|
184
|
+
root.host.setAttribute('data-theme', theme);
|
|
185
|
+
}
|
|
186
|
+
} catch (e) {
|
|
187
|
+
console.debug('[open-theme-toggle] getRootNode unavailable:', e);
|
|
188
|
+
}
|
|
189
|
+
this._dispatchThemeChange(theme);
|
|
190
|
+
try {
|
|
191
|
+
localStorage.setItem('open-theme', theme);
|
|
192
|
+
} catch (e) {
|
|
193
|
+
console.debug('[open-theme-toggle] localStorage.setItem unavailable:', e);
|
|
194
|
+
}
|
|
195
|
+
// data-theme attribute is managed by signal prop binding (data-theme={this._theme})
|
|
196
|
+
}
|
|
197
|
+
_dispatchThemeChange(theme) {
|
|
198
|
+
try {
|
|
199
|
+
if (typeof CustomEvent !== 'undefined' && typeof globalThis.dispatchEvent === 'function') {
|
|
200
|
+
globalThis.dispatchEvent(new CustomEvent('open:theme-change', {
|
|
201
|
+
detail: {
|
|
202
|
+
theme
|
|
203
|
+
}
|
|
204
|
+
}));
|
|
205
|
+
}
|
|
206
|
+
} catch (e) {
|
|
207
|
+
console.debug('[open-theme-toggle] theme event dispatch unavailable:', e);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
attributeChangedCallback(name, old, val) {
|
|
211
|
+
if (old === val) return;
|
|
212
|
+
if (name === 'theme' && val) {
|
|
213
|
+
this._theme.value = val === 'light' ? 'light' : 'dark';
|
|
214
|
+
this.setAttribute('data-theme', this._theme.value);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
export default OpenThemeToggle;
|
|
219
|
+
// Guard: idempotent across SSR paths
|
|
220
|
+
if (typeof customElements !== 'undefined' && !customElements.get(tagName)) {
|
|
221
|
+
customElements.define(tagName, OpenThemeToggle);
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9vcGVuZWxlbWVudC9vcGVuZWxlbWVudC9wYWNrYWdlcy91aS9zcmMvb3Blbi10aGVtZS10b2dnbGUudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKiBAanN4SW1wb3J0U291cmNlIEBvcGVuZWxlbWVudC9jb3JlICovXG4vKipcbiAqIEBvcGVuZWxlbWVudC91aSAtIG9wZW4tdGhlbWUtdG9nZ2xlXG4gKlxuICogVGhlbWUgdG9nZ2xlIFJlYWN0aXZlIERTRCBjb21wb25lbnQgZm9yIERhcmsvTGlnaHQgbW9kZSBzd2l0Y2hpbmcuXG4gKiBTd2lzcyBJbnRlcm5hdGlvbmFsIFN0eWxlOiBQdXJlIEImVywgbWluaW1hbC5cbiAqXG4gKiB2MC4yMS4wOiBVc2VzIERzZEVsZW1lbnQgKyBodG1sIHRlbXBsYXRlcyArIFNpZ25hbHMuXG4gKiB2MC4yNC4xOiBNaWdyYXRlZCBmcm9tIGh0bWxgYCB0ZW1wbGF0ZSB0byBKU1ggKEFEUi0wMDU3KS5cbiAqXG4gKiBAY3NzcGFydCB0b2dnbGUgLVRoZSBidXR0b24gZWxlbWVudFxuICogQGNzc3BhcnQgaWNvbi1zdW4gLVRoZSBzdW4gU1ZHIGljb25cbiAqIEBjc3NwYXJ0IGljb24tbW9vbiAtVGhlIG1vb24gU1ZHIGljb25cbiAqXG4gKiBVc2FnZTpcbiAqIGBgYGh0bWxcbiAqIDxvcGVuLXRoZW1lLXRvZ2dsZSB0aGVtZT1cImxpZ2h0XCI+PC9vcGVuLXRoZW1lLXRvZ2dsZT5cbiAqIGBgYFxuICovXG5cbmltcG9ydCB7IE9wZW5FbGVtZW50IH0gZnJvbSAnQG9wZW5lbGVtZW50L2VsZW1lbnQnO1xuaW1wb3J0IHsgU3R5bGVTaGVldCwgdHlwZSBTdHlsZVNoZWV0TGlrZSB9IGZyb20gJ0BvcGVuZWxlbWVudC9jb3JlL3N0eWxlLXNoZWV0JztcbmltcG9ydCB7IHNpZ25hbCB9IGZyb20gJ0BvcGVuZWxlbWVudC9zaWduYWwnO1xuZXhwb3J0IGNvbnN0IHRhZ05hbWUgPSAnb3Blbi10aGVtZS10b2dnbGUnO1xuXG5jb25zdCBzaGVldDogU3R5bGVTaGVldExpa2UgPSBuZXcgU3R5bGVTaGVldCgpO1xuc2hlZXQucmVwbGFjZVN5bmMoYFxuICA6aG9zdCB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICB9XG5cbiAgLnRoZW1lLXRvZ2dsZSB7XG4gICAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICB3aWR0aDogMzhweDsgaGVpZ2h0OiAzOHB4OyBwYWRkaW5nOiAwO1xuICAgIGJvcmRlcjogdmFyKC0tYm9yZGVyLXNpemUtMSkgc29saWQgY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLWJvcmRlcikgNzIlLCB2YXIoLS1icmFuZCkpO1xuICAgIGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cy1yb3VuZCk7XG4gICAgYmFja2dyb3VuZDogY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLWJnLWVsZXZhdGVkKSA3NiUsIHRyYW5zcGFyZW50KTtcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1tdXRlZCk7XG4gICAgYm94LXNoYWRvdzogaW5zZXQgMCAxcHggMCBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tZ3JheS0wKSA3MCUsIHRyYW5zcGFyZW50KTtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgdHJhbnNpdGlvbjogYWxsIHZhcigtLWVhc2UtMikgdmFyKC0tZHVyYXRpb24tMik7XG4gIH1cbiAgLnRoZW1lLXRvZ2dsZTpob3ZlciB7XG4gICAgY29sb3I6IHZhcigtLXRleHQtcHJpbWFyeSk7XG4gICAgYm9yZGVyLWNvbG9yOiB2YXIoLS1icmFuZC1saWdodCk7XG4gICAgYmFja2dyb3VuZDogY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLWJyYW5kLXBhbGUpIDQyJSwgdmFyKC0tYmctZWxldmF0ZWQpKTtcbiAgfVxuXG4gIC50aGVtZS10b2dnbGUgc3ZnIHtcbiAgICB3aWR0aDogMTZweDtcbiAgICBoZWlnaHQ6IDE2cHg7XG4gIH1cblxuICAudGhlbWUtdG9nZ2xlIC5pY29uLXN1biB7XG4gICAgZGlzcGxheTogYmxvY2s7XG4gIH1cblxuICAudGhlbWUtdG9nZ2xlIC5pY29uLW1vb24ge1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gIH1cblxuICAudGhlbWUtdG9nZ2xlW2RhdGEtdGhlbWU9XCJsaWdodFwiXSAuaWNvbi1zdW4ge1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gIH1cblxuICAudGhlbWUtdG9nZ2xlW2RhdGEtdGhlbWU9XCJsaWdodFwiXSAuaWNvbi1tb29uIHtcbiAgICBkaXNwbGF5OiBibG9jaztcbiAgfVxuYCk7XG5cbmV4cG9ydCBjbGFzcyBPcGVuVGhlbWVUb2dnbGUgZXh0ZW5kcyBPcGVuRWxlbWVudCB7XG4gIC8vIHBvbnl0YWlsOiBTYWZhcmkgZG9lcyBub3QgcmVjb21wdXRlIGFkb3B0ZWRTdHlsZVNoZWV0cyB3aGVuXG4gIC8vIDpob3N0KFtkYXRhLXRoZW1lXSkgY2hhbmdlcy4gVGhlIHRva2VuIHNoZWV0cyAob3BlblByb3BzVG9rZW5TaGVldCxcbiAgLy8gZGFpc3lDbGFzc1NoZWV0KSBhcmUgYWxyZWFkeSBpbmplY3RlZCBhcyBwYWdlLWxldmVsIDxzdHlsZT4gYnlcbiAgLy8gdml0ZS5jb25maWcudHMg4oCUIENTUyBjdXN0b20gcHJvcGVydGllcyBjYXNjYWRlIGZyb20gOnJvb3QgbmF0dXJhbGx5LlxuICAvLyBPbmx5IGFkb3B0IHRoZSBjb21wb25lbnQtc3BlY2lmaWMgc2hlZXQuXG4gIHN0YXRpYyBvdmVycmlkZSBzdHlsZXMgPSBbc2hlZXRdO1xuICBzdGF0aWMgb3ZlcnJpZGUgZGVsZWdhdGVzRm9jdXMgPSB0cnVlO1xuICBzdGF0aWMgb3ZlcnJpZGUgb2JzZXJ2ZWRBdHRyaWJ1dGVzID0gWyd0aGVtZSddO1xuXG4gIHByaXZhdGUgX3RoZW1lID0gc2lnbmFsPCdkYXJrJyB8ICdsaWdodCc+KCdkYXJrJyk7XG4gIHByaXZhdGUgX2luaXREb25lID0gZmFsc2U7XG5cbiAgb3ZlcnJpZGUgY29ubmVjdGVkQ2FsbGJhY2soKTogdm9pZCB7XG4gICAgc3VwZXIuY29ubmVjdGVkQ2FsbGJhY2soKTtcbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gdGhpcy5faW5pdFRoZW1lKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIHYwLjIzLjA6IFRoZW1lIGluaXRpYWxpemF0aW9uIGxpdmVzIGluIF9pbml0VGhlbWUoKSwgY2FsbGVkIGZyb21cbiAgICogYm90aCBvbkRzZEh5ZHJhdGVkKCkgYW5kIG9uQ3NyUmVuZGVyZWQoKSBzbyB0aGF0IHRoZSBwcmlvcml0eVxuICAgKiBjaGFpbiB3b3JrcyByZWdhcmRsZXNzIG9mIGh5ZHJhdGlvbiBwYXRoLlxuICAgKlxuICAgKiBQcmlvcml0eTogdGhlbWUgYXR0cmlidXRlID4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmRhdGFzZXQudGhlbWVcbiAgICogPiBsb2NhbFN0b3JhZ2UgPiBwcmVmZXJzLWNvbG9yLXNjaGVtZSA+IGRlZmF1bHQgJ2RhcmsnLlxuICAgKi9cbiAgcHJpdmF0ZSBfaW5pdFRoZW1lKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9pbml0RG9uZSkgcmV0dXJuO1xuICAgIHRoaXMuX2luaXREb25lID0gdHJ1ZTtcbiAgICBjb25zdCB0aGVtZUF0dHIgPSB0aGlzLmdldEF0dHJpYnV0ZSgndGhlbWUnKTtcbiAgICBpZiAodGhlbWVBdHRyID09PSAnbGlnaHQnKSB7XG4gICAgICB0aGlzLl90aGVtZS52YWx1ZSA9ICdsaWdodCc7XG4gICAgfSBlbHNlIGlmICh0aGVtZUF0dHIgPT09ICdkYXJrJykge1xuICAgICAgdGhpcy5fdGhlbWUudmFsdWUgPSAnZGFyayc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGRvY1RoZW1lID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50Py5kYXRhc2V0Py50aGVtZTtcbiAgICAgIGlmIChkb2NUaGVtZSA9PT0gJ2xpZ2h0Jykge1xuICAgICAgICB0aGlzLl90aGVtZS52YWx1ZSA9ICdsaWdodCc7XG4gICAgICB9IGVsc2UgaWYgKGRvY1RoZW1lID09PSAnZGFyaycpIHtcbiAgICAgICAgdGhpcy5fdGhlbWUudmFsdWUgPSAnZGFyayc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZXQgcmVzb2x2ZWQgPSBmYWxzZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBzYXZlZCA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdvcGVuLXRoZW1lJyk7XG4gICAgICAgICAgaWYgKHNhdmVkID09PSAnbGlnaHQnKSB7XG4gICAgICAgICAgICB0aGlzLl90aGVtZS52YWx1ZSA9ICdsaWdodCc7XG4gICAgICAgICAgICByZXNvbHZlZCA9IHRydWU7XG4gICAgICAgICAgfSBlbHNlIGlmIChzYXZlZCA9PT0gJ2RhcmsnKSB7XG4gICAgICAgICAgICB0aGlzLl90aGVtZS52YWx1ZSA9ICdkYXJrJztcbiAgICAgICAgICAgIHJlc29sdmVkID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggeyAvKiBsb2NhbFN0b3JhZ2UgYmxvY2tlZCAqLyB9XG4gICAgICAgIGlmICghcmVzb2x2ZWQgJiYgZ2xvYmFsVGhpcy5tYXRjaE1lZGlhKSB7XG4gICAgICAgICAgdGhpcy5fdGhlbWUudmFsdWUgPSBnbG9iYWxUaGlzLm1hdGNoTWVkaWEoJyhwcmVmZXJzLWNvbG9yLXNjaGVtZTogbGlnaHQpJykubWF0Y2hlc1xuICAgICAgICAgICAgPyAnbGlnaHQnXG4gICAgICAgICAgICA6ICdkYXJrJztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuc2V0QXR0cmlidXRlKCdkYXRhLXRoZW1lJywgdGhpcy5fdGhlbWUudmFsdWUpO1xuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2RhdGEtdGhlbWUnLCB0aGlzLl90aGVtZS52YWx1ZSk7XG4gICAgaWYgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZSkge1xuICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlLmNvbG9yU2NoZW1lID0gdGhpcy5fdGhlbWUudmFsdWU7XG4gICAgfVxuICAgIC8vIFByb3BhZ2F0ZSB0byBwYXJlbnQgb3Blbi1sYXlvdXRcbiAgICB0cnkge1xuICAgICAgY29uc3Qgcm9vdCA9IHRoaXMuZ2V0Um9vdE5vZGUoKTtcbiAgICAgIGlmIChyb290IGluc3RhbmNlb2YgU2hhZG93Um9vdCAmJiByb290Lmhvc3QpIHtcbiAgICAgICAgcm9vdC5ob3N0LnNldEF0dHJpYnV0ZSgnZGF0YS10aGVtZScsIHRoaXMuX3RoZW1lLnZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIHsgLyogbm90IGluIHNoYWRvdyBET00gKi8gfVxuICAgIHRoaXMuX2Rpc3BhdGNoVGhlbWVDaGFuZ2UodGhpcy5fdGhlbWUudmFsdWUpO1xuICAgIHRoaXMuX3BlcnNpc3RUaGVtZSh0aGlzLl90aGVtZS52YWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIF9wZXJzaXN0VGhlbWUodGhlbWU6ICdkYXJrJyB8ICdsaWdodCcpOiB2b2lkIHtcbiAgICB0cnkge1xuICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ29wZW4tdGhlbWUnLCB0aGVtZSk7XG4gICAgfSBjYXRjaCB7IC8qIGJsb2NrZWQgKi8gfVxuICB9XG5cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIG9uRHNkSHlkcmF0ZWQoKTogdm9pZCB7XG4gICAgc3VwZXIub25Ec2RIeWRyYXRlZCgpO1xuICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB0aGlzLl9pbml0VGhlbWUoKSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgb25Dc3JSZW5kZXJlZCgpOiB2b2lkIHtcbiAgICBzdXBlci5vbkNzclJlbmRlcmVkKCk7XG4gIH1cblxuICBvdmVycmlkZSByZW5kZXIoKTogUmV0dXJuVHlwZTx0eXBlb2YgT3BlbkVsZW1lbnQucHJvdG90eXBlLnJlbmRlcj4ge1xuICAgIC8vIFplcm8gc2lnbmFsLnZhbHVlIHJlYWRzIGluIHJlbmRlciAoQURSLTAwNjIpLlxuICAgIC8vIGVmZmVjdCBiaW5kaW5nIHRoYXQgdXBkYXRlcyB0aGUgYXR0cmlidXRlIHdoZW4gdGhlbWUgY2hhbmdlcy5cbiAgICAvLyBDU1Mgc2VsZWN0b3JzIChbZGF0YS10aGVtZT1cImxpZ2h0XCJdKSBoYW5kbGUgaWNvbiB2aXNpYmlsaXR5LlxuICAgIHJldHVybiAoXG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9J2J1dHRvbidcbiAgICAgICAgY2xhc3NOYW1lPSd0aGVtZS10b2dnbGUnXG4gICAgICAgIHBhcnQ9J3RvZ2dsZSdcbiAgICAgICAgZGF0YS10aGVtZT17dGhpcy5fdGhlbWV9XG4gICAgICAgIGFyaWEtbGFiZWw9J1RvZ2dsZSB0aGVtZSdcbiAgICAgICAgb25DbGljaz17KCkgPT4gdGhpcy5faGFuZGxlVG9nZ2xlKCl9XG4gICAgICA+XG4gICAgICAgIDxzdmdcbiAgICAgICAgICBjbGFzc05hbWU9J2ljb24tc3VuJ1xuICAgICAgICAgIHBhcnQ9J2ljb24tc3VuJ1xuICAgICAgICAgIHZpZXdCb3g9JzAgMCAxNiAxNidcbiAgICAgICAgICBmaWxsPSdub25lJ1xuICAgICAgICAgIHN0cm9rZT0nY3VycmVudENvbG9yJ1xuICAgICAgICAgIHN0cm9rZS13aWR0aD0nMS4yJ1xuICAgICAgICAgIHN0cm9rZS1saW5lY2FwPSdyb3VuZCdcbiAgICAgICAgPlxuICAgICAgICAgIDxjaXJjbGUgY3g9JzgnIGN5PSc4JyByPSczJyAvPlxuICAgICAgICAgIDxsaW5lIHgxPSc4JyB5MT0nMScgeDI9JzgnIHkyPSczJyAvPlxuICAgICAgICAgIDxsaW5lIHgxPSc4JyB5MT0nMTMnIHgyPSc4JyB5Mj0nMTUnIC8+XG4gICAgICAgICAgPGxpbmUgeDE9JzEnIHkxPSc4JyB4Mj0nMycgeTI9JzgnIC8+XG4gICAgICAgICAgPGxpbmUgeDE9JzEzJyB5MT0nOCcgeDI9JzE1JyB5Mj0nOCcgLz5cbiAgICAgICAgICA8bGluZSB4MT0nMy4wNScgeTE9JzMuMDUnIHgyPSc0LjQ2JyB5Mj0nNC40NicgLz5cbiAgICAgICAgICA8bGluZSB4MT0nMTEuNTQnIHkxPScxMS41NCcgeDI9JzEyLjk1JyB5Mj0nMTIuOTUnIC8+XG4gICAgICAgICAgPGxpbmUgeDE9JzMuMDUnIHkxPScxMi45NScgeDI9JzQuNDYnIHkyPScxMS41NCcgLz5cbiAgICAgICAgICA8bGluZSB4MT0nMTEuNTQnIHkxPSc0LjQ2JyB4Mj0nMTIuOTUnIHkyPSczLjA1JyAvPlxuICAgICAgICA8L3N2Zz5cbiAgICAgICAgPHN2Z1xuICAgICAgICAgIGNsYXNzTmFtZT0naWNvbi1tb29uJ1xuICAgICAgICAgIHBhcnQ9J2ljb24tbW9vbidcbiAgICAgICAgICB2aWV3Qm94PScwIDAgMTYgMTYnXG4gICAgICAgICAgZmlsbD0nbm9uZSdcbiAgICAgICAgICBzdHJva2U9J2N1cnJlbnRDb2xvcidcbiAgICAgICAgICBzdHJva2Utd2lkdGg9JzEuMidcbiAgICAgICAgICBzdHJva2UtbGluZWNhcD0ncm91bmQnXG4gICAgICAgID5cbiAgICAgICAgICA8cGF0aCBkPSdNMTMuNSA5LjE0QTUuNSA1LjUgMCAwIDEgNi44NiAyLjUgNS41IDUuNSAwIDEgMCAxMy41IDkuMTRaJyAvPlxuICAgICAgICA8L3N2Zz5cbiAgICAgIDwvYnV0dG9uPlxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIF9oYW5kbGVUb2dnbGUoKTogdm9pZCB7XG4gICAgY29uc3QgdGhlbWUgPSB0aGlzLl90aGVtZS52YWx1ZSA9PT0gJ2xpZ2h0JyA/ICdkYXJrJyA6ICdsaWdodCc7XG4gICAgdGhpcy5fdGhlbWUudmFsdWUgPSB0aGVtZTtcblxuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2RhdGEtdGhlbWUnLCB0aGVtZSk7XG4gICAgaWYgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZSkge1xuICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlLmNvbG9yU2NoZW1lID0gdGhlbWU7XG4gICAgfVxuXG4gICAgLy8gUHJvcGFnYXRlIGRhdGEtdGhlbWUgdG8gcGFyZW50IDxvcGVuLWxheW91dD4gc28gOmhvc3QoW2RhdGEtdGhlbWU9XCJkYXJrXCJdKSBtYXRjaGVzXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJvb3QgPSB0aGlzLmdldFJvb3ROb2RlKCk7XG4gICAgICBpZiAocm9vdCBpbnN0YW5jZW9mIFNoYWRvd1Jvb3QgJiYgcm9vdC5ob3N0KSB7XG4gICAgICAgIHJvb3QuaG9zdC5zZXRBdHRyaWJ1dGUoJ2RhdGEtdGhlbWUnLCB0aGVtZSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS5kZWJ1ZygnW29wZW4tdGhlbWUtdG9nZ2xlXSBnZXRSb290Tm9kZSB1bmF2YWlsYWJsZTonLCBlKTtcbiAgICB9XG5cbiAgICB0aGlzLl9kaXNwYXRjaFRoZW1lQ2hhbmdlKHRoZW1lKTtcblxuICAgIHRyeSB7XG4gICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnb3Blbi10aGVtZScsIHRoZW1lKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLmRlYnVnKCdbb3Blbi10aGVtZS10b2dnbGVdIGxvY2FsU3RvcmFnZS5zZXRJdGVtIHVuYXZhaWxhYmxlOicsIGUpO1xuICAgIH1cbiAgICAvLyBkYXRhLXRoZW1lIGF0dHJpYnV0ZSBpcyBtYW5hZ2VkIGJ5IHNpZ25hbCBwcm9wIGJpbmRpbmcgKGRhdGEtdGhlbWU9e3RoaXMuX3RoZW1lfSlcbiAgfVxuXG4gIHByaXZhdGUgX2Rpc3BhdGNoVGhlbWVDaGFuZ2UodGhlbWU6ICdkYXJrJyB8ICdsaWdodCcpOiB2b2lkIHtcbiAgICB0cnkge1xuICAgICAgaWYgKHR5cGVvZiBDdXN0b21FdmVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGdsb2JhbFRoaXMuZGlzcGF0Y2hFdmVudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBnbG9iYWxUaGlzLmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KCdvcGVuOnRoZW1lLWNoYW5nZScsIHsgZGV0YWlsOiB7IHRoZW1lIH0gfSkpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUuZGVidWcoJ1tvcGVuLXRoZW1lLXRvZ2dsZV0gdGhlbWUgZXZlbnQgZGlzcGF0Y2ggdW5hdmFpbGFibGU6JywgZSk7XG4gICAgfVxuICB9XG5cbiAgb3ZlcnJpZGUgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKG5hbWU6IHN0cmluZywgb2xkOiBzdHJpbmcgfCBudWxsLCB2YWw6IHN0cmluZyB8IG51bGwpOiB2b2lkIHtcbiAgICBpZiAob2xkID09PSB2YWwpIHJldHVybjtcbiAgICBpZiAobmFtZSA9PT0gJ3RoZW1lJyAmJiB2YWwpIHtcbiAgICAgIHRoaXMuX3RoZW1lLnZhbHVlID0gdmFsID09PSAnbGlnaHQnID8gJ2xpZ2h0JyA6ICdkYXJrJztcbiAgICAgIHRoaXMuc2V0QXR0cmlidXRlKCdkYXRhLXRoZW1lJywgdGhpcy5fdGhlbWUudmFsdWUpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBPcGVuVGhlbWVUb2dnbGU7XG5cbi8vIEd1YXJkOiBpZGVtcG90ZW50IGFjcm9zcyBTU1IgcGF0aHNcbmlmICh0eXBlb2YgY3VzdG9tRWxlbWVudHMgIT09ICd1bmRlZmluZWQnICYmICFjdXN0b21FbGVtZW50cy5nZXQodGFnTmFtZSkpIHtcbiAgY3VzdG9tRWxlbWVudHMuZGVmaW5lKHRhZ05hbWUsIE9wZW5UaGVtZVRvZ2dsZSk7XG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsdUNBQXVDLEdBQ3ZDOzs7Ozs7Ozs7Ozs7Ozs7OztDQWlCQyxHQUVELFNBQVMsV0FBVyxRQUFRLHVCQUF1QjtBQUNuRCxTQUFTLFVBQVUsUUFBNkIsZ0NBQWdDO0FBQ2hGLFNBQVMsTUFBTSxRQUFRLHNCQUFzQjtBQUM3QyxPQUFPLE1BQU0sVUFBVSxvQkFB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
|