tsgrid-ui 2.9.0 → 2.10.0

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 (38) hide show
  1. package/CHANGELOG.md +84 -40
  2. package/dist/chunks/{chunk-GJD5NFWQ.js → chunk-6MOFFUV2.js} +5 -5
  3. package/dist/chunks/{chunk-YBY52G2U.js → chunk-6UCGFWIQ.js} +19 -3
  4. package/dist/chunks/chunk-6UCGFWIQ.js.map +1 -0
  5. package/dist/chunks/{chunk-BIB3X2TW.js → chunk-DZSFZLV6.js} +2 -2
  6. package/dist/chunks/chunk-EQK6JAHT.js +33 -0
  7. package/dist/chunks/chunk-EQK6JAHT.js.map +1 -0
  8. package/dist/chunks/{chunk-OFASTA2A.js → chunk-FAIRNXQR.js} +46 -6
  9. package/dist/chunks/chunk-FAIRNXQR.js.map +1 -0
  10. package/dist/chunks/{chunk-OMLGN735.js → chunk-GZFWK4LZ.js} +2 -2
  11. package/dist/chunks/{chunk-26XP2XU3.js → chunk-KLJ35UAH.js} +2 -2
  12. package/dist/chunks/{chunk-EVZMMVXO.js → chunk-LUSNRF73.js} +2 -2
  13. package/dist/chunks/{chunk-WKSLGUB3.js → chunk-N3GASHTI.js} +3 -3
  14. package/dist/field.es6.js +3 -2
  15. package/dist/form.es6.js +6 -5
  16. package/dist/layout.es6.js +5 -4
  17. package/dist/popup.d.ts +6 -1
  18. package/dist/popup.es6.js +6 -3
  19. package/dist/sidebar.es6.js +3 -2
  20. package/dist/tabs.es6.js +3 -2
  21. package/dist/toolbar.es6.js +3 -2
  22. package/dist/tooltip.d.ts +9 -1
  23. package/dist/tooltip.es6.js +6 -3
  24. package/dist/tsgrid-ui.es6.js +9 -8
  25. package/dist/tsgrid-ui.es6.js.map +1 -1
  26. package/dist/tsgrid-ui.es6.min.js +33 -33
  27. package/dist/tsgrid-ui.js +55 -6
  28. package/dist/tsgrid-ui.min.js +32 -32
  29. package/package.json +2 -3
  30. package/dist/chunks/chunk-OFASTA2A.js.map +0 -1
  31. package/dist/chunks/chunk-YBY52G2U.js.map +0 -1
  32. package/dist/metafile-esm.json +0 -1
  33. /package/dist/chunks/{chunk-GJD5NFWQ.js.map → chunk-6MOFFUV2.js.map} +0 -0
  34. /package/dist/chunks/{chunk-BIB3X2TW.js.map → chunk-DZSFZLV6.js.map} +0 -0
  35. /package/dist/chunks/{chunk-OMLGN735.js.map → chunk-GZFWK4LZ.js.map} +0 -0
  36. /package/dist/chunks/{chunk-26XP2XU3.js.map → chunk-KLJ35UAH.js.map} +0 -0
  37. /package/dist/chunks/{chunk-EVZMMVXO.js.map → chunk-LUSNRF73.js.map} +0 -0
  38. /package/dist/chunks/{chunk-WKSLGUB3.js.map → chunk-N3GASHTI.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -2,55 +2,49 @@
2
2
 
3
3
  All notable changes to **TsGrid UI** will be documented in this file.
4
4
 
5
- ## v2.8.0 — 2026-05-14
5
+ ## v2.10.0 — 2026-05-15
6
6
 
7
- ### Added
7
+ ### Tree-shake-friendly lazy singletons
8
8
 
9
- - **Subpath exports** 11 new `package.json` export entries enable tree-shakable imports
10
- (amendment #983: `./grid` deferred to Phase 3 pending `splitting:true` code-split):
11
- - `tsgrid-ui/locale` `TsLocale` (~3,843 B, 99.6% smaller than barrel)
12
- - `tsgrid-ui/base` `TsBase`, `TsEvent`, `toSafeEvent` (~32,135 B, 96.6% smaller)
13
- - `tsgrid-ui/utils` → `TsUi`, `TsUtils`, `query` (~127,812 B, 86.5% smaller)
14
- - `tsgrid-ui/popup` → `TsPopup`, `TsAlert`, `TsConfirm`, `TsPrompt`, `TsDialog` (~159,775 B, 83.1% smaller)
15
- - `tsgrid-ui/tooltip` → `TsTooltip`, `TsMenu`, `TsColor`, `TsDate`, `Tooltip` (~244,488 B, 74.1% smaller)
16
- - `tsgrid-ui/tabs` → `TsTabs` (~268,343 B, 71.6% smaller)
17
- - `tsgrid-ui/toolbar` → `TsToolbar` (~288,428 B, 69.5% smaller)
18
- - `tsgrid-ui/sidebar` → `TsSidebar` (~306,229 B, 67.6% smaller)
19
- - `tsgrid-ui/field` → `TsField` (~312,704 B, 66.9% smaller)
20
- - `tsgrid-ui/layout` → `TsLayout` (~354,172 B, 62.5% smaller)
21
- - `tsgrid-ui/form` → `TsForm` (~468,108 B, 50.5% smaller)
22
- - **`./package.json` export** — enables tooling that reads package metadata at runtime.
23
- - **`reports/bundle/v2.8.0-baseline.json`** — schemaVersion 2; per-subpath empirical byte
24
- measurements. Phase 2 gate for the v3.0 tree-shakable roadmap.
25
- - Grid users continue using the barrel import (`tsgrid-ui`); `./grid` subpath export deferred
26
- to Phase 3 once `splitting:true` reduces transitive duplication.
9
+ `TsPopup`, `TsTooltip`, `TsMenu`, `TsColor`, and `TsDate` now defer their underlying class
10
+ construction until first use via a Proxy-based lazy-init pattern. Consumers that import
11
+ `tsgrid-ui/popup` or `tsgrid-ui/tooltip` but do NOT call any method get a smaller bundle
12
+ bundlers respecting `sideEffects` can now eliminate the constructor bodies.
27
13
 
28
- ### Bundle
14
+ - `package.json#sideEffects[]` no longer lists `./dist/popup.es6.js` or `./dist/tooltip.es6.js`.
15
+ - Public API unchanged: same imports, same method calls, same `instanceof`, same `vi.spyOn` behavior.
16
+ - Internal: new `src/lazy-singleton.ts` helper, named export `__test_internals` on `tspopup.ts`
17
+ and `tstooltip.ts` for construction-count assertions.
29
18
 
30
- - Monolith `tsgrid-ui` entry unchanged at 945,470 bytes (byte-identical to v2.7.1).
31
- - Subpath bundles emitted with `splitting: false`; shared modules re-emitted per subpath.
32
- Most modern bundlers deduplicate transparently (esbuild, Rollup, Vite, webpack 5+, Parcel 2+).
33
- - `splitting: true` shared-chunk optimization planned for v2.9 / Phase 3.
34
- - Dist artifact count: 7 → 29 files (+11 ESM subpath bundles + 11 `.d.ts` files).
19
+ Not changed in this release (deferred to future cycles):
20
+ - `TsUtils` stays eager its constructor reads `navigator` and `localStorage` (real side-effects
21
+ regardless of timing).
22
+ - SSR safety remains future work.
23
+ - `Tooltip.observeRemove = new MutationObserver(...)` static field is unchanged.
35
24
 
36
- ### BC
25
+ ### Implementation
37
26
 
38
- - Public API surface: **purely additive**. The `"."` barrel entry is byte-identical to v2.7.1.
39
- - `dist/tsgrid-ui.es6.js` SHA: byte-identical to v2.7.1 (INV-SX-6 PASS).
40
- - `src/index.ts` barrel: byte-identical to v2.7.1 (INV-7 PASS).
41
- - No `require:` condition on subpaths — CJS consumers continue using `'tsgrid-ui'` barrel.
42
- CJS subpaths planned for Phase 4 (requires `wrap-legacy.mjs` per-symbol refactoring).
43
- - No barrel deprecation: `'tsgrid-ui'` barrel is fully supported with zero deprecation markers.
44
- - SEMVER MINOR per SemVer §7. No breaking changes.
27
+ - `src/lazy-singleton.ts` (NEW): `lazySingleton<T>(factory, protoRef): T` Proxy helper with
28
+ `get`, `set`, `has`, `ownKeys`, `getOwnPropertyDescriptor`, `defineProperty`, `getPrototypeOf`
29
+ traps. Factory invoked at most once; `getPrototypeOf` returns `protoRef.prototype` without
30
+ materializing to preserve `instanceof` semantics without triggering construction.
31
+ - `src/tspopup.ts`: `TsPopup = lazySingleton<TsDialog>(...)` replaces `new TsDialog()`.
32
+ - `src/tstooltip.ts`: four `lazySingleton(...)` calls replace `new Tooltip()` / `new MenuTooltip()`
33
+ / `new ColorTooltip()` / `new DateTooltip()`.
45
34
 
46
35
  ### Tests
47
36
 
48
- - `test/unit/subpath-exports.test.ts` (NEW) — 3 groups: exports shape, dist existence,
49
- bundle floor. All 3 groups GREEN from Phase 6 onward.
50
- - `test/consumer-smoke.ts` — extended with 11 named-import probes + 11 type-only probes.
51
- - Total Vitest tests: **352/352 GREEN** (v2.7.1 baseline: 301/301 +13 new assertions
52
- plus expanded parametric tests via `it.each`).
53
- - `tsup.config.analyze.ts`: UNCHANGED (INV-ANALYZE-ISOLATION PASS).
37
+ - `test/unit/singleton-lazy-init.test.ts` (NEW): T-LAZY-1..8 covering deferred construction,
38
+ exactly-once guarantee, singleton identity, `vi.spyOn` forwarding, `TsUtils.lang` init-chain
39
+ safety, and `instanceof` invariant.
40
+ - `test/unit/package-json.test.ts`: updated to assert 7-entry `sideEffects[]` and version 2.10.0.
41
+ - `test/unit/bundle-snapshot.test.ts`: added R-SLI-DESIGN-3 ctor-marker assertions for
42
+ `popup.es6.js` and `tooltip.es6.js` stubs.
43
+
44
+ ### BC
45
+
46
+ - Public API surface: **purely additive**. All existing imports and call sites work unchanged.
47
+ - SEMVER MINOR per SemVer §7. No breaking changes.
54
48
 
55
49
  ## v2.9.0 — 2026-05-15
56
50
 
@@ -175,6 +169,56 @@ All notable changes to **TsGrid UI** will be documented in this file.
175
169
  - Zero new devDependencies. Zero changes to `src/`. Zero changes to `dist/*.js` on production builds (byte-identical, verified via `shasum` gate).
176
170
  - SEMVER: chore / no version bump. Next version bump (v2.8.0) reserved for Phase 2 (subpath exports).
177
171
 
172
+ ## v2.8.0 — 2026-05-14
173
+
174
+ ### Added
175
+
176
+ - **Subpath exports** — 11 new `package.json` export entries enable tree-shakable imports
177
+ (amendment #983: `./grid` deferred to Phase 3 pending `splitting:true` code-split):
178
+ - `tsgrid-ui/locale` → `TsLocale` (~3,843 B, 99.6% smaller than barrel)
179
+ - `tsgrid-ui/base` → `TsBase`, `TsEvent`, `toSafeEvent` (~32,135 B, 96.6% smaller)
180
+ - `tsgrid-ui/utils` → `TsUi`, `TsUtils`, `query` (~127,812 B, 86.5% smaller)
181
+ - `tsgrid-ui/popup` → `TsPopup`, `TsAlert`, `TsConfirm`, `TsPrompt`, `TsDialog` (~159,775 B, 83.1% smaller)
182
+ - `tsgrid-ui/tooltip` → `TsTooltip`, `TsMenu`, `TsColor`, `TsDate`, `Tooltip` (~244,488 B, 74.1% smaller)
183
+ - `tsgrid-ui/tabs` → `TsTabs` (~268,343 B, 71.6% smaller)
184
+ - `tsgrid-ui/toolbar` → `TsToolbar` (~288,428 B, 69.5% smaller)
185
+ - `tsgrid-ui/sidebar` → `TsSidebar` (~306,229 B, 67.6% smaller)
186
+ - `tsgrid-ui/field` → `TsField` (~312,704 B, 66.9% smaller)
187
+ - `tsgrid-ui/layout` → `TsLayout` (~354,172 B, 62.5% smaller)
188
+ - `tsgrid-ui/form` → `TsForm` (~468,108 B, 50.5% smaller)
189
+ - **`./package.json` export** — enables tooling that reads package metadata at runtime.
190
+ - **`reports/bundle/v2.8.0-baseline.json`** — schemaVersion 2; per-subpath empirical byte
191
+ measurements. Phase 2 gate for the v3.0 tree-shakable roadmap.
192
+ - Grid users continue using the barrel import (`tsgrid-ui`); `./grid` subpath export deferred
193
+ to Phase 3 once `splitting:true` reduces transitive duplication.
194
+
195
+ ### Bundle
196
+
197
+ - Monolith `tsgrid-ui` entry unchanged at 945,470 bytes (byte-identical to v2.7.1).
198
+ - Subpath bundles emitted with `splitting: false`; shared modules re-emitted per subpath.
199
+ Most modern bundlers deduplicate transparently (esbuild, Rollup, Vite, webpack 5+, Parcel 2+).
200
+ - `splitting: true` shared-chunk optimization planned for v2.9 / Phase 3.
201
+ - Dist artifact count: 7 → 29 files (+11 ESM subpath bundles + 11 `.d.ts` files).
202
+
203
+ ### BC
204
+
205
+ - Public API surface: **purely additive**. The `"."` barrel entry is byte-identical to v2.7.1.
206
+ - `dist/tsgrid-ui.es6.js` SHA: byte-identical to v2.7.1 (INV-SX-6 PASS).
207
+ - `src/index.ts` barrel: byte-identical to v2.7.1 (INV-7 PASS).
208
+ - No `require:` condition on subpaths — CJS consumers continue using `'tsgrid-ui'` barrel.
209
+ CJS subpaths planned for Phase 4 (requires `wrap-legacy.mjs` per-symbol refactoring).
210
+ - No barrel deprecation: `'tsgrid-ui'` barrel is fully supported with zero deprecation markers.
211
+ - SEMVER MINOR per SemVer §7. No breaking changes.
212
+
213
+ ### Tests
214
+
215
+ - `test/unit/subpath-exports.test.ts` (NEW) — 3 groups: exports shape, dist existence,
216
+ bundle floor. All 3 groups GREEN from Phase 6 onward.
217
+ - `test/consumer-smoke.ts` — extended with 11 named-import probes + 11 type-only probes.
218
+ - Total Vitest tests: **352/352 GREEN** (v2.7.1 baseline: 301/301 — +13 new assertions
219
+ plus expanded parametric tests via `it.each`).
220
+ - `tsup.config.analyze.ts`: UNCHANGED (INV-ANALYZE-ISOLATION PASS).
221
+
178
222
  ## v2.7.1 — 2026-05-14
179
223
 
180
224
  ### Fixed
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  TsField
3
- } from "./chunk-26XP2XU3.js";
3
+ } from "./chunk-KLJ35UAH.js";
4
4
  import {
5
5
  TsTabs
6
- } from "./chunk-OMLGN735.js";
6
+ } from "./chunk-GZFWK4LZ.js";
7
7
  import {
8
8
  TsToolbar
9
- } from "./chunk-EVZMMVXO.js";
9
+ } from "./chunk-LUSNRF73.js";
10
10
  import {
11
11
  TsTooltip
12
- } from "./chunk-OFASTA2A.js";
12
+ } from "./chunk-FAIRNXQR.js";
13
13
  import {
14
14
  TsUtils
15
15
  } from "./chunk-3NYH6545.js";
@@ -2302,4 +2302,4 @@ var TsForm = class extends TsBase {
2302
2302
  export {
2303
2303
  TsForm
2304
2304
  };
2305
- //# sourceMappingURL=chunk-GJD5NFWQ.js.map
2305
+ //# sourceMappingURL=chunk-6MOFFUV2.js.map
@@ -1,3 +1,6 @@
1
+ import {
2
+ lazySingleton
3
+ } from "./chunk-EQK6JAHT.js";
1
4
  import {
2
5
  TsUtils
3
6
  } from "./chunk-3NYH6545.js";
@@ -837,13 +840,26 @@ function TsPrompt(label, title, callBack) {
837
840
  });
838
841
  return prom;
839
842
  }
840
- var TsPopup = new TsDialog();
843
+ var _TsDialogCtorCount = 0;
844
+ var TsPopup = lazySingleton(() => {
845
+ _TsDialogCtorCount++;
846
+ return new TsDialog();
847
+ }, TsDialog);
848
+ var __test_internals = {
849
+ get tsDialogCtorCount() {
850
+ return _TsDialogCtorCount;
851
+ },
852
+ reset() {
853
+ _TsDialogCtorCount = 0;
854
+ }
855
+ };
841
856
 
842
857
  export {
843
858
  TsDialog,
844
859
  TsAlert,
845
860
  TsConfirm,
846
861
  TsPrompt,
847
- TsPopup
862
+ TsPopup,
863
+ __test_internals
848
864
  };
849
- //# sourceMappingURL=chunk-YBY52G2U.js.map
865
+ //# sourceMappingURL=chunk-6UCGFWIQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/tspopup.ts"],"sourcesContent":["/**\n * Part of TsUi 2.0 library\n * - Dependencies: mQuery, TsUtils, TsBase\n *\n * == 2.0 changes\n * - CSP - fixed inline events\n * - removed jQuery dependency\n * - popup.open - returns promise like object\n * - popup.confirm - refactored\n * - popup.message - refactored\n * - removed popup.options.mutliple\n * - refactores TsAlert, TsConfirm, TsPrompt\n * - add TsPopup.open().on('')\n * - removed TsPopup.restoreTemplate\n * - deprecated onMsgOpen and onMsgClose\n * - deprecated options.bgColor\n * - rename focus -> setFocus\n * - added center() // will auto center on window resize\n * - close(immediate), also refactored if popup is closed when opening\n * - options.resizable\n * - actions in popup can be just html (for example separator)\n * - resize - returns promise\n */\n\nimport { TsBase } from './tsbase.js'\nimport { TsUtils } from './tsutils.js'\nimport { query as _queryRaw, Query } from './query.js'\nimport { lazySingleton } from './lazy-singleton.js'\n// any: query() returns Query|void but is always used in chain; cast once here\nconst query = _queryRaw as (selector: unknown, context?: unknown) => Query\n\ninterface DialogOptions {\n title?: string\n text?: string\n body?: string\n buttons?: string\n width?: number\n height?: number\n focus?: number | string | null\n actions?: Record<string, unknown> | null\n style?: string\n speed?: number\n blockPage?: boolean\n modal?: boolean\n maximized?: boolean\n keyboard?: boolean\n showClose?: boolean\n showMax?: boolean\n resizable?: boolean\n transition?: unknown\n openMaximized?: boolean\n moved?: boolean\n prevSize?: string | null\n cancelAction?: string\n closingTimer?: ReturnType<typeof setTimeout>\n _last_focus?: HTMLElement | null\n [key: string]: unknown\n}\n\nclass TsDialog extends TsBase {\n defaults: DialogOptions\n options!: DialogOptions // definite assignment: set in open() before any property access\n declare name: string\n status: string\n tmp: Record<string, unknown>\n // any: callback parameter — caller signature varies; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handleResize: (event?: any) => void\n _promCreated!: (value?: unknown) => void\n _promOpened!: (value?: unknown) => void\n _promClosing!: (value?: unknown) => void\n _promClosed!: (value?: unknown) => void\n _timer?: ReturnType<typeof setTimeout>\n\n constructor() {\n super()\n this.defaults = {\n title: '',\n text: '', // just a text (will be centered)\n body: '',\n buttons: '',\n width: 450,\n height: 250,\n focus: null, // brings focus to the element, can be a number or selector\n actions: null, // actions object\n style: '', // style of the message div\n speed: 0.3,\n blockPage: true,\n modal: false,\n maximized: false, // this is a flag to show the state - to open the popup maximized use openMaximized instead\n keyboard: true, // will close popup on esc if not modal\n showClose: true,\n showMax: false,\n resizable: false,\n transition: null,\n openMaximized: false,\n moved: false\n }\n this.name = 'popup'\n this.status = 'closed' // string that describes current status\n this['onOpen'] = null\n this['onClose'] = null\n this['onMax'] = null\n this['onMin'] = null\n this['onToggle'] = null\n this['onKeydown'] = null\n this['onAction'] = null\n this['onMove'] = null\n this.tmp = {}\n // event handler for resize\n this.handleResize = (_event) => {\n // if it was moved by the user, do not auto resize\n if (!this.options.moved) {\n this.center(undefined, undefined, true)\n }\n }\n }\n\n /**\n * Sample calls\n * - TsPopup.open('ddd').ok(() => { TsPopup.close() })\n * - TsPopup.open('ddd', { height: 120 }).ok(() => { TsPopup.close() })\n * - TsPopup.open({ body: 'text', title: 'caption', actions: [\"Close\"] }).close(() => { TsPopup.close() })\n * - TsPopup.open({ body: 'text', title: 'caption', actions: { Close() { TsPopup.close() }} })\n */\n // any: callback parameter — caller signature varies; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n open(options?: any, extraOptions?: any) {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this\n if (this.status == 'closing' || query('#tsg-popup').hasClass('animating')) {\n // if called when previous is closing\n this.close(true)\n }\n // get old options and merge them\n const old_options = this.options\n if (['string', 'number'].includes(typeof options)) {\n options = TsUtils.extend({\n title: 'Notification',\n body: `<div class=\"tsg-centered\">${options}</div>`,\n actions: { Ok() { self.close() }},\n cancelAction: 'ok'\n }, extraOptions ?? {})\n }\n if (options.text != null) options.body = `<div class=\"tsg-centered tsg-msg-text\">${options.text}</div>`\n options = Object.assign({}, this.defaults, old_options, { title: '', body : '' }, options, { maximized: false })\n this.options = options\n // if new - reset event handlers\n if (query('#tsg-popup').length === 0) {\n this.off('*')\n Object.keys(this).forEach(key => {\n if (key.startsWith('on') && key != 'on') this[key] = null\n })\n }\n // reassign events\n Object.keys(options).forEach(key => {\n if (key.startsWith('on') && key != 'on' && options[key]) {\n this[key] = options[key]\n }\n })\n options.width = parseInt(options.width)\n options.height = parseInt(options.height)\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let edata: any, msg: any // any: TsEvent + dynamic message state\n const { top, left, width, height } = this.center()\n // make sure popup is not bigger then available screen\n if (options.width > width) options.width = width\n if (options.height > height) options.height = height\n\n const prom: Record<string, unknown> & {\n self: TsDialog\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n action(callBack: any): typeof prom // any: callback event shape is dynamic\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n close(callBack: any): typeof prom // any: callback event shape is dynamic\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n then(callBack: any): typeof prom // any: callback event shape is dynamic\n } = {\n self: this,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n action(callBack: any) { // any: action callback event shape is dynamic\n self.on('action.prom', callBack)\n return prom\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n close(callBack: any) { // any: close callback event shape is dynamic\n self.on('close.prom', callBack)\n return prom\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n then(callBack: any) { // any: then callback event shape is dynamic\n self.on('open:after.prom', callBack)\n return prom\n }\n }\n // convert action arrays into buttons\n if (options.actions != null && !options.buttons) {\n options.buttons = ''\n Object.keys(options.actions).forEach((action) => {\n const handler = options.actions[action]\n let btnAction = action\n if (typeof handler == 'function') {\n options.buttons += `<button class=\"tsg-btn tsg-eaction\" name=\"${action}\" data-click='[\"action\",\"${action}\",\"event\"]'>${action}</button>`\n }\n if (typeof handler == 'object') {\n options.buttons += `<button class=\"tsg-btn tsg-eaction ${handler.class || ''}\" name=\"${action}\" data-click='[\"action\",\"${action}\",\"event\"]'\n style=\"${handler.style}\" ${handler.attrs}>${handler.text || action}</button>`\n btnAction = Array.isArray(options.actions) ? handler.text : action\n }\n if (typeof handler == 'string') {\n if (handler.trim().startsWith('<')) {\n btnAction = 'none'\n options.buttons += handler\n\n } else {\n btnAction = (handler[0] ?? '').toLowerCase() + handler.substr(1).replace(/\\s+/g, '')\n options.buttons += `<button class=\"tsg-btn tsg-eaction\" name=\"${action}\" data-click='[\"action\",\"${btnAction}\",\"event\"]'>${handler}</button>`\n }\n }\n if (typeof btnAction == 'string') {\n btnAction = (btnAction[0] ?? '').toLowerCase() + btnAction.substr(1).replace(/\\s+/g, '')\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n prom[btnAction] = function (callBack: any) { // any: button action callback event shape is dynamic\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n self.on('action.buttons', (event: any) => { // any: action event has dynamic detail\n const target = (event.detail.action[0] ?? '').toLowerCase() + event.detail.action.substr(1).replace(/\\s+/g, '')\n if (target == btnAction) callBack(event)\n })\n return prom\n }\n })\n }\n // check if message is already displayed\n let titleBtns = ''\n if (options.showClose) {\n titleBtns += `<div class=\"tsg-popup-button tsg-popup-close\">\n <span class=\"tsg-icon tsg-icon-cross tsg-eaction\" data-mousedown=\"stop\" data-click=\"close\"></span>\n </div>`\n }\n if (options.showMax) {\n titleBtns += `<div class=\"tsg-popup-button tsg-popup-max\">\n <span class=\"tsg-icon tsg-icon-box tsg-eaction\" data-mousedown=\"stop\" data-click=\"toggle\"></span>\n </div>`\n }\n\n if (query('#tsg-popup').length === 0) {\n // trigger event\n edata = this.trigger('open', { target: 'popup', present: false })\n if (edata.isCancelled === true) return\n this.status = 'opening'\n // output message\n if (options.blockPage) {\n TsUtils.lock(document.body, {\n opacity: 0.3,\n ...(options.modal ? {} : { onClick: () => { this.close() } })\n })\n }\n // first insert just body\n let styles = `\n left: ${left}px;\n top: ${top}px;\n width: ${parseInt(options.width)}px;\n height: ${parseInt(options.height)}px;\n transition: ${options.speed}s\n `\n msg = `<div id=\"tsg-popup\" class=\"tsg-popup tsg-anim-open animating ${!options.blockPage ? 'tsg-non-blocking' : ''}\" style=\"${TsUtils.stripSpaces(styles)}\"></div>`\n query('body').append(msg)\n // any: cast-to-any for dynamic dispatch; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ;(query('#tsg-popup')[0] as any)._w2popup = {\n self: this,\n created: new Promise((resolve) => { this._promCreated = resolve }),\n opened: new Promise((resolve) => { this._promOpened = resolve }),\n closing: new Promise((resolve) => { this._promClosing = resolve }),\n closed: new Promise((resolve) => { this._promClosed = resolve }),\n }\n // then content\n styles = `${!options.title ? 'top: 0px !important;' : ''} ${!options.buttons ? 'bottom: 0px !important;' : ''}`\n msg = `\n <span name=\"hidden-first\" tabindex=\"0\" style=\"position: absolute; top: -100px\"></span>\n <div class=\"tsg-popup-title-btns\">${titleBtns}</div>\n <div class=\"tsg-popup-title\" style=\"${!options.title ? 'display: none' : ''}\"></div>\n <div class=\"tsg-box\" style=\"${styles}\">\n <div class=\"tsg-popup-body ${!options.title || ' tsg-popup-no-title'}\n ${!options.buttons || ' tsg-popup-no-buttons'}\" style=\"${options.style}\">\n </div>\n </div>\n <div class=\"tsg-popup-buttons\" style=\"${!options.buttons ? 'display: none' : ''}\"></div>\n <div class=\"tsg-popup-resizer resize-point resize-icon\"></div>\n <span name=\"hidden-last\" tabindex=\"0\" style=\"position: absolute; top: -100px\"></span>\n `\n query('#tsg-popup').html(msg)\n\n if (options.title) query('#tsg-popup .tsg-popup-title').append(TsUtils.lang(options.title))\n if (options.buttons) query('#tsg-popup .tsg-popup-buttons').append(options.buttons)\n if (options.body) query('#tsg-popup .tsg-popup-body').append(options.body)\n\n // allow element to render\n setTimeout(() => {\n ;(query('#tsg-popup')\n .css('transition', options.speed + 's') as unknown as Query)\n .removeClass('tsg-anim-open')\n TsUtils.bindEvents('#tsg-popup .tsg-eaction', this)\n query('#tsg-popup').find('.tsg-popup-body').show()\n this._promCreated()\n }, 1)\n // clean transform\n clearTimeout(this._timer)\n this._timer = setTimeout(() => {\n this.status = 'open'\n self.setFocus(options.focus)\n // event after\n edata.finish()\n this._promOpened()\n query('#tsg-popup').removeClass('animating')\n }, options.speed * 1000)\n\n } else {\n // trigger event\n edata = this.trigger('open', { target: 'popup', present: true })\n if (edata.isCancelled === true) return\n // check if size changed\n this.status = 'opening'\n if (old_options != null) {\n if (!old_options.maximized && (old_options.width != options.width || old_options.height != options.height)) {\n this.resize(options.width, options.height)\n }\n options.prevSize = options.width + 'px:' + options.height + 'px'\n options.maximized = old_options.maximized\n }\n // show new items\n const cloned = (query('#tsg-popup .tsg-box').get(0) as Node).cloneNode(true)\n query(cloned as HTMLElement).removeClass('tsg-box').addClass('tsg-box-temp').find('.tsg-popup-body').empty().append(options.body as string)\n query('#tsg-popup .tsg-box').after(cloned)\n\n if (options.buttons) {\n ;(query('#tsg-popup .tsg-popup-buttons').show().html('') as unknown as Query).append(options.buttons as string)\n query('#tsg-popup .tsg-popup-body').removeClass('tsg-popup-no-buttons')\n query('#tsg-popup .tsg-box, #tsg-popup .tsg-box-temp').css('bottom', '')\n } else {\n query('#tsg-popup .tsg-popup-buttons').hide().html('')\n query('#tsg-popup .tsg-popup-body').addClass('tsg-popup-no-buttons')\n query('#tsg-popup .tsg-box, #tsg-popup .tsg-box-temp').css('bottom', '0px')\n }\n if (options.title) {\n query('#tsg-popup .tsg-popup-title')\n .show()\n .html(TsUtils.lang(options.title))\n query('#tsg-popup .tsg-popup-body').removeClass('tsg-popup-no-title')\n query('#tsg-popup .tsg-box, #tsg-popup .tsg-box-temp').css('top', '')\n } else {\n query('#tsg-popup .tsg-popup-title').hide().html('')\n query('#tsg-popup .tsg-popup-body').addClass('tsg-popup-no-title')\n query('#tsg-popup .tsg-box, #tsg-popup .tsg-box-temp').css('top', '0px')\n }\n if (titleBtns) {\n query('#tsg-popup .tsg-popup-title-btns')\n .show()\n .html(titleBtns)\n } else {\n query('#tsg-popup .tsg-popup-title-btns')\n .hide()\n }\n // transition\n const div_old = query('#tsg-popup .tsg-box')[0] as HTMLElement\n const div_new = query('#tsg-popup .tsg-box-temp')[0] as HTMLElement\n query('#tsg-popup').addClass('animating')\n TsUtils.transition(div_old, div_new, options.transition as string, () => {\n // clean up\n query(div_old).remove()\n query(div_new).removeClass('tsg-box-temp').addClass('tsg-box')\n const $body = query(div_new).find('.tsg-popup-body')\n if ($body.length == 1) {\n ($body[0] as HTMLElement).style.cssText = options.style as string\n $body.show()\n }\n // focus on first button\n self.setFocus(options.focus)\n query('#tsg-popup').removeClass('animating')\n })\n // call event onOpen\n this.status = 'open'\n edata.finish()\n TsUtils.bindEvents('#tsg-popup .tsg-eaction', this)\n query('#tsg-popup').find('.tsg-popup-body').show()\n }\n\n if (options.openMaximized) {\n this.max()\n }\n // save new options\n options._last_focus = document.activeElement\n // keyboard events\n if (options.keyboard) {\n query(document.body)\n .off('.TsPopup')\n .on('keydown.TsPopup', (event) => {\n this.keydown(event)\n })\n }\n query(window).on('resize', this.handleResize)\n // initialize move; any: drag-state bag mutated dynamically in mvStart/mvMove/mvStop\n // any: parameter typed any — runtime dispatch by call site; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const tmp: any = {\n changing : false,\n mvMove : mvMove,\n mvStop : mvStop\n }\n query('#tsg-popup .tsg-popup-title')\n .off('mousedown')\n .on('mousedown', function(event) {\n if (!self.options.maximized) mvStart(event)\n })\n\n if (options.resizable) {\n query('#tsg-popup .tsg-popup-resizer').show()\n query('#tsg-popup .tsg-popup-resizer')\n .off('mousedown')\n .on('mousedown', event => {\n mvStart(event, true)\n })\n } else {\n query('#tsg-popup .tsg-popup-resizer').hide()\n }\n\n return prom\n\n // handlers\n // any: callback parameter — caller signature varies; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function mvStart(evt: any, resizer?: any) {\n if (!evt) evt = window.event\n self.status = resizer ? 'resizing' : 'moving'\n const rect = (query('#tsg-popup').get(0) as HTMLElement).getBoundingClientRect()\n Object.assign(tmp, {\n changing: true,\n isLocked: query('#tsg-popup > .tsg-lock').length == 1 ? true : false,\n x : evt.screenX,\n y : evt.screenY,\n pos_x : rect.x,\n pos_y : rect.y,\n width : rect.width,\n height : rect.height\n })\n if (!tmp.isLocked) self.lock({ opacity: 0 })\n query(document.body)\n .on('mousemove.tsg-popup', tmp.mvMove)\n .on('mouseup.tsg-popup', tmp.mvStop)\n if (evt.stopPropagation) evt.stopPropagation(); else evt.cancelBubble = true\n if (evt.preventDefault) evt.preventDefault(); else return false\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function mvMove(evt: any): void { // any: MouseEvent or window.event\n if (tmp.changing != true) return\n if (!evt) evt = window.event\n tmp.div_x = evt.screenX - tmp.x\n tmp.div_y = evt.screenY - tmp.y\n // trigger event\n const edata = self.trigger('move', { target: 'popup', div_x: tmp.div_x, div_y: tmp.div_y, originalEvent: evt })\n if (edata.isCancelled === true) return\n // default behavior\n if (self.status == 'moving') {\n query('#tsg-popup').css({\n 'transition': 'none',\n 'transform' : 'translate3d('+ tmp.div_x +'px, '+ tmp.div_y +'px, 0px)'\n })\n self.options.moved = true\n } else {\n query('#tsg-popup').css({\n transition: 'none',\n width: (tmp.width + tmp.div_x) + 'px',\n height: (tmp.height + tmp.div_y) + 'px'\n })\n }\n // event after\n edata.finish()\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function mvStop(evt: any): void { // any: MouseEvent or window.event\n if (tmp.changing != true) return\n if (!evt) evt = window.event\n tmp.div_x = (evt.screenX - tmp.x)\n tmp.div_y = (evt.screenY - tmp.y)\n if (self.status == 'moving') {\n ;(query('#tsg-popup')\n .css({\n 'left': (tmp.pos_x + tmp.div_x) + 'px',\n 'top' : (tmp.pos_y + tmp.div_y) + 'px'\n }) as unknown as Query)\n .css({\n 'transition': 'none',\n 'transform' : 'translate3d(0px, 0px, 0px)'\n })\n } else {\n query('#tsg-popup').css({\n transition: 'none',\n width: (tmp.width + tmp.div_x) + 'px',\n height: (tmp.height + tmp.div_y) + 'px'\n })\n self.resizeMessages()\n }\n tmp.changing = false\n self.status = 'open'\n query(document.body).off('.tsg-popup')\n if (!tmp.isLocked) self.unlock()\n }\n }\n\n // any: callback parameter — caller signature varies; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n load(options: any) {\n return new Promise((resolve, reject) => {\n if (typeof options == 'string') {\n options = { url: options }\n }\n if (options.url == null) {\n console.log('ERROR: The url is not defined.')\n reject('The url is not defined')\n return\n }\n this.status = 'loading'\n const [url, selector] = String(options.url).split('#')\n if (url) {\n fetch(url).then(res => res.text()).then(html => {\n resolve(this.template(html, selector, options))\n })\n }\n })\n }\n\n // any: parameter typed any — runtime dispatch by call site; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n template(data: any, id: any, options: any = {}) {\n let html\n try {\n html = query(data)\n } catch (e) {\n // any: cast-to-any for dynamic dispatch; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n html = (_queryRaw as any).html(data)\n }\n if (id) html = html.filter('#' + id)\n Object.assign(options, {\n width: parseInt(query(html).css('width') as string),\n height: parseInt(query(html).css('height') as string),\n title: query(html).find('[rel=title]').html(),\n body: query(html).find('[rel=body]').html(),\n buttons: query(html).find('[rel=buttons]').html(),\n style: (query(html).find('[rel=body]').get(0) as HTMLElement).style.cssText,\n })\n return this.open(options)\n }\n\n // any: callback parameter — caller signature varies; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n action(action: any, event?: any) {\n // any: parameter typed any — runtime dispatch by call site; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let click: any = this.options.actions?.[action]\n // any: cast-to-any for dynamic dispatch; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (click instanceof Object && (click as any).onClick) click = (click as any).onClick\n // event before\n const edata = this.trigger('action', { action, target: 'popup', self: this,\n // any: cast-to-any for dynamic dispatch; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n originalEvent: event, value: this['input'] ? (this['input'] as any).value : null })\n if (edata.isCancelled === true) return\n // default actions\n if (typeof click === 'function') click.call(this, event)\n // event after\n edata.finish()\n }\n\n // any: callback parameter — caller signature varies; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n keydown(event: any) {\n if (this.options && !this.options.keyboard) return\n // trigger event\n const edata = this.trigger('keydown', { target: 'popup', originalEvent: event })\n if (edata.isCancelled === true) return\n // default behavior\n switch (event.keyCode) {\n case 27:\n event.preventDefault()\n if (query('#tsg-popup .tsg-message').length == 0) {\n if (this.options.cancelAction) {\n this.action(this.options.cancelAction)\n } else {\n this.close()\n }\n }\n break\n }\n // event after\n edata.finish()\n }\n\n // any: callback parameter — caller signature varies; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n close(immediate?: any) {\n // trigger event\n const edata = this.trigger('close', { target: 'popup' })\n if (edata.isCancelled === true) return\n const cleanUp = () => {\n // return template\n query('#tsg-popup').remove()\n // restore active\n if (this.options._last_focus) this.options._last_focus.focus()\n this.status = 'closed'\n this.options = {}\n // event after\n edata.finish()\n this._promClosed()\n }\n if (query('#tsg-popup').length === 0 || this.status == 'closed') { // already closed\n return\n }\n if (this.status == 'opening') { // if it is opening\n immediate = true\n }\n if (this.status == 'closing' && immediate === true) {\n cleanUp()\n clearTimeout(this.tmp['closingTimer'] as ReturnType<typeof setTimeout>)\n TsUtils.unlock(document.body, 0)\n return\n }\n // default behavior\n this.status = 'closing'\n ;(query('#tsg-popup')\n .css('transition', this.options.speed + 's') as unknown as Query)\n .addClass('tsg-anim-close animating')\n TsUtils.unlock(document.body, 300)\n this._promClosing()\n\n if (immediate) {\n cleanUp()\n } else {\n this.tmp['closingTimer'] = setTimeout(cleanUp, (this.options.speed ?? 0.3) * 1000)\n }\n // remove keyboard events\n if (this.options.keyboard) {\n query(document.body).off('keydown', this.keydown)\n }\n query(window).off('resize', this.handleResize)\n }\n\n toggle() {\n const edata = this.trigger('toggle', { target: 'popup' })\n if (edata.isCancelled === true) return\n // default action\n if (this.options.maximized === true) this.min(); else this.max()\n // event after\n setTimeout(() => {\n edata.finish()\n }, ((this.options.speed ?? 0.3) * 1000) + 50)\n }\n\n max() {\n if (this.options.maximized === true) return\n // trigger event\n const edata = this.trigger('max', { target: 'popup' })\n if (edata.isCancelled === true) return\n // default behavior\n this.status = 'resizing'\n const rect = (query('#tsg-popup').get(0) as HTMLElement).getBoundingClientRect()\n this.options.prevSize = rect.width + ':' + rect.height\n // do resize\n this.resize(10000, 10000, () => {\n this.status = 'open'\n this.options.maximized = true\n edata.finish()\n })\n }\n\n min() {\n if (this.options.maximized !== true) return\n const size = (this.options.prevSize ?? '').split(':')\n // trigger event\n const edata = this.trigger('min', { target: 'popup' })\n if (edata.isCancelled === true) return\n // default behavior\n this.status = 'resizing'\n // do resize\n this.options.maximized = false\n this.resize(parseInt(size[0] ?? '0'), parseInt(size[1] ?? '0'), () => {\n this.status = 'open'\n this.options.prevSize = null\n edata.finish()\n })\n }\n\n clear() {\n query('#tsg-popup .tsg-popup-title').html('')\n query('#tsg-popup .tsg-popup-body').html('')\n query('#tsg-popup .tsg-popup-buttons').html('')\n }\n\n reset() {\n this.open(this.defaults)\n }\n\n // any: callback parameter — caller signature varies; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n message(options: any) {\n return TsUtils.message({\n owner: this,\n box : query('#tsg-popup').get(0) as HTMLElement,\n after: '.tsg-popup-title'\n }, options)\n }\n\n // any: callback parameter — caller signature varies; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n confirm(options: any) {\n return TsUtils.confirm({\n owner: this,\n box : query('#tsg-popup').get(0) as HTMLElement,\n after: '.tsg-popup-title'\n }, options)\n }\n\n // any: callback parameter — caller signature varies; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n setFocus(focus?: any) {\n const box = query('#tsg-popup')\n const sel = 'input, button, select, textarea, [contentEditable], [tabindex], .tsg-input'\n if (focus != null) {\n const el = isNaN(focus)\n ? box.find(sel).filter(focus).filter(':not([name=hidden-first])').get(0) as HTMLElement\n : box.find(sel).filter(':not([name=hidden-first])').get(focus) as HTMLElement\n el?.focus()\n } else {\n const el = box.find('[name=hidden-first]').get(0) as HTMLElement\n if (el) el.focus()\n }\n // keep focus/blur inside popup\n query(box).find(sel)\n .off('.keep-focus')\n // any: callback parameter — caller signature varies; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .on('blur.keep-focus', function (_event: any) {\n setTimeout(() => {\n const focus = document.activeElement\n // any: cast-to-any for dynamic dispatch; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const inside = query(box).find(sel).filter(focus as any).length > 0\n // any: cast-to-any for dynamic dispatch; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const name = query(focus as any).attr('name')\n if (!inside && focus && focus !== document.body) {\n (query(box).find(sel).get(0) as HTMLElement)?.focus()\n }\n if (name == 'hidden-last') {\n (query(box).find(sel).get(1) as HTMLElement)?.focus()\n }\n if (name == 'hidden-first') {\n (query(box).find(sel).get(-2) as HTMLElement)?.focus()\n }\n }, 1)\n })\n }\n\n // any: callback parameter — caller signature varies; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n lock(msg?: any, showSpinner?: any) {\n TsUtils.lock(query('#tsg-popup'), msg, showSpinner)\n }\n\n // any: callback parameter — caller signature varies; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n unlock(speed?: any) {\n TsUtils.unlock(query('#tsg-popup'), speed)\n }\n\n // any: callback parameter — caller signature varies; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n center(width?: any, height?: any, force?: any) {\n let maxW, maxH\n if (window.innerHeight == undefined) {\n maxW = Math.floor(document.documentElement.offsetWidth)\n maxH = Math.floor(document.documentElement.offsetHeight)\n } else {\n maxW = Math.floor(window.innerWidth)\n maxH = Math.floor(window.innerHeight)\n }\n width = parseInt(width ?? this.options.width)\n height = parseInt(height ?? this.options.height)\n if (this.options.maximized === true) {\n width = maxW\n height = maxH\n }\n if (maxW - 10 < width) width = maxW - 10\n if (maxH - 10 < height) height = maxH - 10\n const top = (maxH - height) / 3 // it is my oppinion that it is more estatic to show closer to top then in exact middle\n const left = (maxW - width) / 2\n if (force) {\n query('#tsg-popup').css({\n 'transition': 'none',\n 'top' : top + 'px',\n 'left' : left + 'px',\n 'width' : width + 'px',\n 'height': height + 'px'\n })\n this.resizeMessages() // then messages resize nicely\n }\n return { top, left, width, height }\n }\n\n // any: callback parameter — caller signature varies; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n resize(newWidth: any, newHeight: any, callBack?: any) {\n return new Promise(resolve => {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this\n if (this.options.speed == null) this.options.speed = 0\n // calculate new position\n const { top, left, width, height } = this.center(newWidth, newHeight)\n const speed = this.options.speed\n query('#tsg-popup').css({\n 'transition': `${speed}s width, ${speed}s height, ${speed}s left, ${speed}s top`,\n 'top' : top + 'px',\n 'left' : left + 'px',\n 'width' : width + 'px',\n 'height': height + 'px'\n })\n const tmp_int = setInterval(() => { self.resizeMessages() }, 10) // then messages resize nicely\n setTimeout(() => {\n clearInterval(tmp_int)\n self.resizeMessages()\n if (typeof callBack == 'function') callBack()\n resolve(undefined)\n }, (this.options.speed * 1000) + 50) // give extra 50 ms\n })\n }\n\n // internal function\n resizeMessages() {\n // see if there are messages and resize them\n query('#tsg-popup .tsg-message').each((node: Node) => {\n const msg = node as HTMLElement\n // any: cast-to-any for dynamic dispatch; TsPopup options accept untyped user payloads at runtime\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mopt = (msg as any)._msg_options\n const popup = query('#tsg-popup')\n if (parseInt(mopt.width) < 10) mopt.width = 10\n if (parseInt(mopt.height) < 10) mopt.height = 10\n const rect = (popup[0] as HTMLElement).getBoundingClientRect()\n const titleHeight = (popup.find('.tsg-popup-title')[0] as HTMLElement).clientHeight\n const pWidth = Math.floor(rect.width)\n const pHeight = Math.floor(rect.height)\n // re-calc width\n mopt.width = mopt.originalWidth\n if (mopt.width > pWidth - 10) {\n mopt.width = pWidth - 10\n }\n // re-calc height\n mopt.height = mopt.originalHeight\n if (mopt.height > pHeight - titleHeight - 5) {\n mopt.height = pHeight - titleHeight - 5\n }\n if (mopt.originalHeight < 0) mopt.height = pHeight + mopt.originalHeight - titleHeight\n if (mopt.originalWidth < 0) mopt.width = pWidth + mopt.originalWidth * 2 // x 2 because there is left and right margin\n query(msg).css({\n left : ((pWidth - mopt.width) / 2) + 'px',\n width : mopt.width + 'px',\n height : mopt.height + 'px'\n })\n })\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction TsAlert(msg: any, title?: any, callBack?: any): any { // any: msg/title/callBack are heterogeneous convenience params\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let prom: any // any: return from open() or message() differs; unified at call site\n const options = {\n title: TsUtils.lang(title ?? 'Notification'),\n body: `<div class=\"tsg-centered tsg-msg-text\">${msg}</div>`,\n showClose: false,\n actions: { ok: TsUtils.lang('Ok') },\n cancelAction: 'ok'\n }\n if (query('#tsg-popup').length > 0 && TsPopup.status != 'closing') {\n prom = TsPopup.message(options)\n } else {\n prom = TsPopup.open(options)\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n prom['ok']((event: any) => { // any: ok callback event is dynamic\n if (typeof event.detail.self?.close == 'function') {\n event.detail.self.close()\n }\n if (typeof callBack == 'function') callBack()\n })\n return prom\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction TsConfirm(msg: any, title?: any, callBack?: any): any { // any: msg/title/callBack are heterogeneous convenience params\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let prom: any // any: return from open() or message() differs; unified at call site\n let options = msg\n if (['string', 'number'].includes(typeof options)) {\n options = { msg: options }\n }\n if (options.msg) {\n options.body = `<div class=\"tsg-centered tsg-msg-text\">${options.msg}</div>`,\n delete options.msg\n }\n if (typeof title == 'function' && callBack == null) {\n callBack = title\n title = undefined\n }\n TsUtils.extend(options, {\n title: TsUtils.lang(title ?? options.title ?? 'Confirmation'),\n showClose: false,\n modal: true,\n cancelAction: 'no'\n })\n if (callBack == null && options.callBack != null) {\n callBack = options.callBack\n }\n TsUtils.normButtons(options, { yes: TsUtils.lang('Yes'), no: TsUtils.lang('No') })\n if (query('#tsg-popup').length > 0 && TsPopup.status != 'closing') {\n prom = TsPopup.message(options)\n } else {\n prom = TsPopup.open(options)\n }\n prom.self\n .off('.confirm')\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .on('action:after.confirm', (event: any) => { // any: action event detail is dynamic\n if (typeof event.detail.self?.close == 'function') {\n event.detail.self.close()\n }\n if (typeof callBack == 'function') callBack(event.detail.action)\n })\n return prom\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction TsPrompt(label: any, title?: any, callBack?: any): any { // any: label/title/callBack are heterogeneous convenience params\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let prom: any // any: return from open() or message() differs; unified at call site\n let options = label\n if (['string', 'number'].includes(typeof options)) {\n options = { label: options }\n }\n if (options.label) {\n options.focus = 0 // the input should be in focus, which is first in the popup\n options.body = (options.textarea\n ? `<div class=\"tsg-prompt textarea\">\n <div>${options.label}</div>\n <textarea id=\"TsPrompt\" class=\"tsg-input\" ${options.attrs ?? ''}\n data-keydown=\"keydown|event\" data-keyup=\"change|event\"></textarea>\n </div>`\n : `<div class=\"tsg-prompt tsg-centered\">\n <label>${options.label}</label>\n <input id=\"TsPrompt\" class=\"tsg-input\" ${options.attrs ?? ''}\n data-keydown=\"keydown|event\" data-keyup=\"change|event\">\n </div>`\n )\n }\n TsUtils.extend(options, {\n title: TsUtils.lang(title ?? options.title ?? 'Notification'),\n showClose: false,\n modal: true,\n cancelAction: 'cancel'\n })\n TsUtils.normButtons(options, { ok: TsUtils.lang('Ok'), cancel: TsUtils.lang('Cancel') })\n if (query('#tsg-popup').length > 0 && TsPopup.status != 'closing') {\n prom = TsPopup.message(options)\n } else {\n prom = TsPopup.open(options)\n }\n if (prom.self.box) {\n prom.self['input'] = query(prom.self.box).find('#TsPrompt').get(0)\n } else {\n prom.self['input'] = query('#tsg-popup .tsg-popup-body #TsPrompt').get(0)\n }\n if (options.value != null) {\n prom.self['input'].value = options.value\n prom.self['input'].select()\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n prom.change = function (callback: any) { // any: change callback event shape is dynamic\n prom.self.on('change', callback)\n return this\n }\n prom.self\n .off('.prompt')\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .on('open:after.prompt', (event: any) => { // any: open event detail is dynamic\n const box = event.detail.box ? event.detail.box : query('#tsg-popup .tsg-popup-body').get(0)\n TsUtils.bindEvents(query(box).find('#TsPrompt'), {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n keydown(evt: any) { // any: KeyboardEvent\n if (evt.keyCode == 27) evt.stopPropagation()\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n change(evt: any) { // any: KeyboardEvent\n const edata = prom.self.trigger('change', { target: 'prompt', originalEvent: evt })\n if (edata.isCancelled === true) return\n if (evt.keyCode == 13 && (evt.ctrlKey || evt.metaKey || evt.target.tagName != 'TEXTAREA')) {\n prom.self.action('Ok', evt)\n }\n if (evt.keyCode == 27) {\n prom.self.action('Cancel', evt)\n }\n edata.finish()\n }\n })\n query(box).find('.tsg-eaction').trigger('keyup')\n })\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .on('action:after.prompt', (event: any) => { // any: action event detail is dynamic\n if (typeof event.detail.self?.close == 'function') {\n event.detail.self.close()\n }\n if (typeof callBack == 'function') callBack(event.detail.action)\n })\n return prom\n}\n\nlet _TsDialogCtorCount = 0\nconst TsPopup = lazySingleton<TsDialog>(() => { _TsDialogCtorCount++; return new TsDialog() }, TsDialog)\nexport { TsPopup, TsAlert, TsConfirm, TsPrompt, TsDialog }\n// DO NOT remove — used by test/unit/singleton-lazy-init.test.ts to assert lazy-init invariants.\nexport const __test_internals = {\n get tsDialogCtorCount() { return _TsDialogCtorCount },\n reset() { _TsDialogCtorCount = 0 },\n}"],"mappings":";;;;;;;;;;;;AA6BA,IAAMA,SAAQ;AA8Bd,IAAM,WAAN,cAAuB,OAAO;AAAA,EAC1B;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,cAAc;AACV,UAAM;AACN,SAAK,WAAa;AAAA,MACd,OAAO;AAAA,MACP,MAAM;AAAA;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,OAAO;AAAA;AAAA,MACP,SAAS;AAAA;AAAA,MACT,OAAO;AAAA;AAAA,MACP,OAAO;AAAA,MACP,WAAW;AAAA,MACX,OAAO;AAAA,MACP,WAAW;AAAA;AAAA,MACX,UAAU;AAAA;AAAA,MACV,WAAW;AAAA,MACX,SAAS;AAAA,MACT,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,OAAO;AAAA,IACX;AACA,SAAK,OAAa;AAClB,SAAK,SAAa;AAClB,SAAK,QAAQ,IAAQ;AACrB,SAAK,SAAS,IAAO;AACrB,SAAK,OAAO,IAAS;AACrB,SAAK,OAAO,IAAS;AACrB,SAAK,UAAU,IAAM;AACrB,SAAK,WAAW,IAAK;AACrB,SAAK,UAAU,IAAM;AACrB,SAAK,QAAQ,IAAQ;AACrB,SAAK,MAAa,CAAC;AAEnB,SAAK,eAAe,CAAC,WAAW;AAE5B,UAAI,CAAC,KAAK,QAAQ,OAAO;AACrB,aAAK,OAAO,QAAW,QAAW,IAAI;AAAA,MAC1C;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,KAAK,SAAe,cAAoB;AAEpC,UAAM,OAAO;AACb,QAAI,KAAK,UAAU,aAAaA,OAAM,YAAY,EAAE,SAAS,WAAW,GAAG;AAEvE,WAAK,MAAM,IAAI;AAAA,IACnB;AAEA,UAAM,cAAc,KAAK;AACzB,QAAI,CAAC,UAAU,QAAQ,EAAE,SAAS,OAAO,OAAO,GAAG;AAC/C,gBAAU,QAAQ,OAAO;AAAA,QACrB,OAAO;AAAA,QACP,MAAM,6BAA6B,OAAO;AAAA,QAC1C,SAAS,EAAE,KAAK;AAAE,eAAK,MAAM;AAAA,QAAE,EAAC;AAAA,QAChC,cAAc;AAAA,MAClB,GAAG,gBAAgB,CAAC,CAAC;AAAA,IACzB;AACA,QAAI,QAAQ,QAAQ,KAAM,SAAQ,OAAO,0CAA0C,QAAQ,IAAI;AAC/F,cAAU,OAAO,OAAO,CAAC,GAAG,KAAK,UAAU,aAAa,EAAE,OAAO,IAAI,MAAO,GAAG,GAAG,SAAS,EAAE,WAAW,MAAM,CAAC;AAC/G,SAAK,UAAU;AAEf,QAAIA,OAAM,YAAY,EAAE,WAAW,GAAG;AAClC,WAAK,IAAI,GAAG;AACZ,aAAO,KAAK,IAAI,EAAE,QAAQ,SAAO;AAC7B,YAAI,IAAI,WAAW,IAAI,KAAK,OAAO,KAAM,MAAK,GAAG,IAAI;AAAA,MACzD,CAAC;AAAA,IACL;AAEA,WAAO,KAAK,OAAO,EAAE,QAAQ,SAAO;AAChC,UAAI,IAAI,WAAW,IAAI,KAAK,OAAO,QAAQ,QAAQ,GAAG,GAAG;AACrD,aAAK,GAAG,IAAI,QAAQ,GAAG;AAAA,MAC3B;AAAA,IACJ,CAAC;AACD,YAAQ,QAAS,SAAS,QAAQ,KAAK;AACvC,YAAQ,SAAS,SAAS,QAAQ,MAAM;AAGxC,QAAI,OAAY;AAChB,UAAM,EAAE,KAAK,MAAM,OAAO,OAAO,IAAI,KAAK,OAAO;AAEjD,QAAI,QAAQ,QAAQ,MAAO,SAAQ,QAAQ;AAC3C,QAAI,QAAQ,SAAS,OAAQ,SAAQ,SAAS;AAE9C,UAAM,OAQF;AAAA,MACA,MAAM;AAAA;AAAA,MAEN,OAAO,UAAe;AAClB,aAAK,GAAG,eAAe,QAAQ;AAC/B,eAAO;AAAA,MACX;AAAA;AAAA,MAEA,MAAM,UAAe;AACjB,aAAK,GAAG,cAAc,QAAQ;AAC9B,eAAO;AAAA,MACX;AAAA;AAAA,MAEA,KAAK,UAAe;AAChB,aAAK,GAAG,mBAAmB,QAAQ;AACnC,eAAO;AAAA,MACX;AAAA,IACJ;AAEA,QAAI,QAAQ,WAAW,QAAQ,CAAC,QAAQ,SAAS;AAC7C,cAAQ,UAAU;AAClB,aAAO,KAAK,QAAQ,OAAO,EAAE,QAAQ,CAAC,WAAW;AAC7C,cAAM,UAAU,QAAQ,QAAQ,MAAM;AACtC,YAAI,YAAY;AAChB,YAAI,OAAO,WAAW,YAAY;AAC9B,kBAAQ,WAAW,6CAA6C,MAAM,4BAA4B,MAAM,eAAe,MAAM;AAAA,QACjI;AACA,YAAI,OAAO,WAAW,UAAU;AAC5B,kBAAQ,WAAW,sCAAsC,QAAQ,SAAS,EAAE,WAAW,MAAM,4BAA4B,MAAM;AAAA,iCAClH,QAAQ,KAAK,KAAK,QAAQ,KAAK,IAAI,QAAQ,QAAQ,MAAM;AACtE,sBAAY,MAAM,QAAQ,QAAQ,OAAO,IAAI,QAAQ,OAAO;AAAA,QAChE;AACA,YAAI,OAAO,WAAW,UAAU;AAC5B,cAAI,QAAQ,KAAK,EAAE,WAAW,GAAG,GAAG;AAChC,wBAAY;AACZ,oBAAQ,WAAW;AAAA,UAEvB,OAAO;AACH,yBAAa,QAAQ,CAAC,KAAK,IAAI,YAAY,IAAI,QAAQ,OAAO,CAAC,EAAE,QAAQ,QAAQ,EAAE;AACnF,oBAAQ,WAAW,6CAA6C,MAAM,4BAA4B,SAAS,eAAe,OAAO;AAAA,UACrI;AAAA,QACJ;AACA,YAAI,OAAO,aAAa,UAAU;AAC9B,uBAAa,UAAU,CAAC,KAAK,IAAI,YAAY,IAAI,UAAU,OAAO,CAAC,EAAE,QAAQ,QAAQ,EAAE;AAAA,QAC3F;AAEA,aAAK,SAAS,IAAI,SAAU,UAAe;AAEvC,eAAK,GAAG,kBAAkB,CAAC,UAAe;AACtC,kBAAM,UAAU,MAAM,OAAO,OAAO,CAAC,KAAK,IAAI,YAAY,IAAI,MAAM,OAAO,OAAO,OAAO,CAAC,EAAE,QAAQ,QAAQ,EAAE;AAC9G,gBAAI,UAAU,UAAW,UAAS,KAAK;AAAA,UAC3C,CAAC;AACD,iBAAO;AAAA,QACX;AAAA,MACJ,CAAC;AAAA,IACL;AAEA,QAAI,YAAY;AAChB,QAAI,QAAQ,WAAW;AACnB,mBAAa;AAAA;AAAA;AAAA,IAGjB;AACA,QAAI,QAAQ,SAAS;AACjB,mBAAa;AAAA;AAAA;AAAA,IAGjB;AAEA,QAAIA,OAAM,YAAY,EAAE,WAAW,GAAG;AAElC,cAAQ,KAAK,QAAQ,QAAQ,EAAE,QAAQ,SAAS,SAAS,MAAM,CAAC;AAChE,UAAI,MAAM,gBAAgB,KAAM;AAChC,WAAK,SAAS;AAEd,UAAI,QAAQ,WAAW;AACnB,gBAAQ,KAAK,SAAS,MAAM;AAAA,UACxB,SAAS;AAAA,UACT,GAAI,QAAQ,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM;AAAE,iBAAK,MAAM;AAAA,UAAE,EAAE;AAAA,QAC/D,CAAC;AAAA,MACL;AAEA,UAAI,SAAS;AAAA,wBACD,IAAI;AAAA,uBACL,GAAG;AAAA,yBACD,SAAS,QAAQ,KAAK,CAAC;AAAA,0BACtB,SAAS,QAAQ,MAAM,CAAC;AAAA,8BACpB,QAAQ,KAAK;AAAA;AAE/B,YAAM,gEAAgE,CAAC,QAAQ,YAAY,qBAAqB,EAAE,YAAY,QAAQ,YAAY,MAAM,CAAC;AACzJ,MAAAA,OAAM,MAAM,EAAE,OAAO,GAAG;AAGvB,MAACA,OAAM,YAAY,EAAE,CAAC,EAAU,WAAW;AAAA,QACxC,MAAM;AAAA,QACN,SAAS,IAAI,QAAQ,CAAC,YAAY;AAAE,eAAK,eAAe;AAAA,QAAQ,CAAC;AAAA,QACjE,QAAQ,IAAI,QAAQ,CAAC,YAAY;AAAE,eAAK,cAAc;AAAA,QAAQ,CAAC;AAAA,QAC/D,SAAS,IAAI,QAAQ,CAAC,YAAY;AAAE,eAAK,eAAe;AAAA,QAAQ,CAAC;AAAA,QACjE,QAAQ,IAAI,QAAQ,CAAC,YAAY;AAAE,eAAK,cAAc;AAAA,QAAQ,CAAC;AAAA,MACnE;AAEA,eAAS,GAAG,CAAC,QAAQ,QAAQ,yBAAyB,EAAE,IAAI,CAAC,QAAQ,UAAU,4BAA4B,EAAE;AAC7G,YAAM;AAAA;AAAA,oDAEkC,SAAS;AAAA,sDACP,CAAC,QAAQ,QAAQ,kBAAkB,EAAE;AAAA,8CAC7C,MAAM;AAAA,iDACH,CAAC,QAAQ,SAAS,qBAAqB;AAAA,0BAC9D,CAAC,QAAQ,WAAW,uBAAuB,YAAY,QAAQ,KAAK;AAAA;AAAA;AAAA,wDAGtC,CAAC,QAAQ,UAAU,kBAAkB,EAAE;AAAA;AAAA;AAAA;AAInF,MAAAA,OAAM,YAAY,EAAE,KAAK,GAAG;AAE5B,UAAI,QAAQ,MAAO,CAAAA,OAAM,6BAA6B,EAAE,OAAO,QAAQ,KAAK,QAAQ,KAAK,CAAC;AAC1F,UAAI,QAAQ,QAAS,CAAAA,OAAM,+BAA+B,EAAE,OAAO,QAAQ,OAAO;AAClF,UAAI,QAAQ,KAAM,CAAAA,OAAM,4BAA4B,EAAE,OAAO,QAAQ,IAAI;AAGzE,iBAAW,MAAM;AACb;AAAC,QAACA,OAAM,YAAY,EACf,IAAI,cAAc,QAAQ,QAAQ,GAAG,EACrC,YAAY,eAAe;AAChC,gBAAQ,WAAW,2BAA2B,IAAI;AAClD,QAAAA,OAAM,YAAY,EAAE,KAAK,iBAAiB,EAAE,KAAK;AACjD,aAAK,aAAa;AAAA,MACtB,GAAG,CAAC;AAEJ,mBAAa,KAAK,MAAM;AACxB,WAAK,SAAS,WAAW,MAAM;AAC3B,aAAK,SAAS;AACd,aAAK,SAAS,QAAQ,KAAK;AAE3B,cAAM,OAAO;AACb,aAAK,YAAY;AACjB,QAAAA,OAAM,YAAY,EAAE,YAAY,WAAW;AAAA,MAC/C,GAAG,QAAQ,QAAQ,GAAI;AAAA,IAE3B,OAAO;AAEH,cAAQ,KAAK,QAAQ,QAAQ,EAAE,QAAQ,SAAS,SAAS,KAAK,CAAC;AAC/D,UAAI,MAAM,gBAAgB,KAAM;AAEhC,WAAK,SAAS;AACd,UAAI,eAAe,MAAM;AACrB,YAAI,CAAC,YAAY,cAAc,YAAY,SAAS,QAAQ,SAAS,YAAY,UAAU,QAAQ,SAAS;AACxG,eAAK,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,QAC7C;AACA,gBAAQ,WAAY,QAAQ,QAAQ,QAAQ,QAAQ,SAAS;AAC7D,gBAAQ,YAAY,YAAY;AAAA,MACpC;AAEA,YAAM,SAAUA,OAAM,qBAAqB,EAAE,IAAI,CAAC,EAAW,UAAU,IAAI;AAC3E,MAAAA,OAAM,MAAqB,EAAE,YAAY,SAAS,EAAE,SAAS,cAAc,EAAE,KAAK,iBAAiB,EAAE,MAAM,EAAE,OAAO,QAAQ,IAAc;AAC1I,MAAAA,OAAM,qBAAqB,EAAE,MAAM,MAAM;AAEzC,UAAI,QAAQ,SAAS;AACjB;AAAC,QAACA,OAAM,+BAA+B,EAAE,KAAK,EAAE,KAAK,EAAE,EAAuB,OAAO,QAAQ,OAAiB;AAC9G,QAAAA,OAAM,4BAA4B,EAAE,YAAY,sBAAsB;AACtE,QAAAA,OAAM,+CAA+C,EAAE,IAAI,UAAU,EAAE;AAAA,MAC3E,OAAO;AACH,QAAAA,OAAM,+BAA+B,EAAE,KAAK,EAAE,KAAK,EAAE;AACrD,QAAAA,OAAM,4BAA4B,EAAE,SAAS,sBAAsB;AACnE,QAAAA,OAAM,+CAA+C,EAAE,IAAI,UAAU,KAAK;AAAA,MAC9E;AACA,UAAI,QAAQ,OAAO;AACf,QAAAA,OAAM,6BAA6B,EAC9B,KAAK,EACL,KAAK,QAAQ,KAAK,QAAQ,KAAK,CAAC;AACrC,QAAAA,OAAM,4BAA4B,EAAE,YAAY,oBAAoB;AACpE,QAAAA,OAAM,+CAA+C,EAAE,IAAI,OAAO,EAAE;AAAA,MACxE,OAAO;AACH,QAAAA,OAAM,6BAA6B,EAAE,KAAK,EAAE,KAAK,EAAE;AACnD,QAAAA,OAAM,4BAA4B,EAAE,SAAS,oBAAoB;AACjE,QAAAA,OAAM,+CAA+C,EAAE,IAAI,OAAO,KAAK;AAAA,MAC3E;AACA,UAAI,WAAW;AACX,QAAAA,OAAM,kCAAkC,EACnC,KAAK,EACL,KAAK,SAAS;AAAA,MACvB,OAAO;AACH,QAAAA,OAAM,kCAAkC,EACnC,KAAK;AAAA,MACd;AAEA,YAAM,UAAUA,OAAM,qBAAqB,EAAE,CAAC;AAC9C,YAAM,UAAUA,OAAM,0BAA0B,EAAE,CAAC;AACnD,MAAAA,OAAM,YAAY,EAAE,SAAS,WAAW;AACxC,cAAQ,WAAW,SAAS,SAAS,QAAQ,YAAsB,MAAM;AAErE,QAAAA,OAAM,OAAO,EAAE,OAAO;AACtB,QAAAA,OAAM,OAAO,EAAE,YAAY,cAAc,EAAE,SAAS,SAAS;AAC7D,cAAM,QAAQA,OAAM,OAAO,EAAE,KAAK,iBAAiB;AACnD,YAAI,MAAM,UAAU,GAAG;AACnB,UAAC,MAAM,CAAC,EAAkB,MAAM,UAAU,QAAQ;AAClD,gBAAM,KAAK;AAAA,QACf;AAEA,aAAK,SAAS,QAAQ,KAAK;AAC3B,QAAAA,OAAM,YAAY,EAAE,YAAY,WAAW;AAAA,MAC/C,CAAC;AAED,WAAK,SAAS;AACd,YAAM,OAAO;AACb,cAAQ,WAAW,2BAA2B,IAAI;AAClD,MAAAA,OAAM,YAAY,EAAE,KAAK,iBAAiB,EAAE,KAAK;AAAA,IACrD;AAEA,QAAI,QAAQ,eAAe;AACvB,WAAK,IAAI;AAAA,IACb;AAEA,YAAQ,cAAc,SAAS;AAE/B,QAAI,QAAQ,UAAU;AAClB,MAAAA,OAAM,SAAS,IAAI,EACd,IAAI,UAAU,EACd,GAAG,mBAAmB,CAAC,UAAU;AAC9B,aAAK,QAAQ,KAAK;AAAA,MACtB,CAAC;AAAA,IACT;AACA,IAAAA,OAAM,MAAM,EAAE,GAAG,UAAU,KAAK,YAAY;AAI5C,UAAM,MAAW;AAAA,MACb,UAAW;AAAA,MACX;AAAA,MACA;AAAA,IACJ;AACA,IAAAA,OAAM,6BAA6B,EAC9B,IAAI,WAAW,EACf,GAAG,aAAa,SAAS,OAAO;AAC7B,UAAI,CAAC,KAAK,QAAQ,UAAW,SAAQ,KAAK;AAAA,IAC9C,CAAC;AAEL,QAAI,QAAQ,WAAW;AACnB,MAAAA,OAAM,+BAA+B,EAAE,KAAK;AAC5C,MAAAA,OAAM,+BAA+B,EAChC,IAAI,WAAW,EACf,GAAG,aAAa,WAAS;AACtB,gBAAQ,OAAO,IAAI;AAAA,MACvB,CAAC;AAAA,IACT,OAAO;AACH,MAAAA,OAAM,+BAA+B,EAAE,KAAK;AAAA,IAChD;AAEA,WAAO;AAKP,aAAS,QAAQ,KAAU,SAAe;AACtC,UAAI,CAAC,IAAK,OAAM,OAAO;AACvB,WAAK,SAAS,UAAU,aAAa;AACrC,YAAM,OAAQA,OAAM,YAAY,EAAE,IAAI,CAAC,EAAkB,sBAAsB;AAC/E,aAAO,OAAO,KAAK;AAAA,QACf,UAAU;AAAA,QACV,UAAUA,OAAM,wBAAwB,EAAE,UAAU,IAAI,OAAO;AAAA,QAC/D,GAAU,IAAI;AAAA,QACd,GAAU,IAAI;AAAA,QACd,OAAU,KAAK;AAAA,QACf,OAAU,KAAK;AAAA,QACf,OAAU,KAAK;AAAA,QACf,QAAU,KAAK;AAAA,MACnB,CAAC;AACD,UAAI,CAAC,IAAI,SAAU,MAAK,KAAK,EAAE,SAAS,EAAE,CAAC;AAC3C,MAAAA,OAAM,SAAS,IAAI,EACd,GAAG,uBAAuB,IAAI,MAAM,EACpC,GAAG,qBAAqB,IAAI,MAAM;AACvC,UAAI,IAAI,gBAAiB,KAAI,gBAAgB;AAAA,UAAQ,KAAI,eAAe;AACxE,UAAI,IAAI,eAAgB,KAAI,eAAe;AAAA,UAAQ,QAAO;AAAA,IAC9D;AAGA,aAAS,OAAO,KAAgB;AAC5B,UAAI,IAAI,YAAY,KAAM;AAC1B,UAAI,CAAC,IAAK,OAAM,OAAO;AACvB,UAAI,QAAQ,IAAI,UAAU,IAAI;AAC9B,UAAI,QAAQ,IAAI,UAAU,IAAI;AAE9B,YAAMC,SAAQ,KAAK,QAAQ,QAAQ,EAAE,QAAQ,SAAS,OAAO,IAAI,OAAO,OAAO,IAAI,OAAO,eAAe,IAAI,CAAC;AAC9G,UAAIA,OAAM,gBAAgB,KAAM;AAEhC,UAAI,KAAK,UAAU,UAAU;AACzB,QAAAD,OAAM,YAAY,EAAE,IAAI;AAAA,UACpB,cAAc;AAAA,UACd,aAAc,iBAAgB,IAAI,QAAO,SAAQ,IAAI,QAAO;AAAA,QAChE,CAAC;AACD,aAAK,QAAQ,QAAQ;AAAA,MACzB,OAAO;AACH,QAAAA,OAAM,YAAY,EAAE,IAAI;AAAA,UACpB,YAAY;AAAA,UACZ,OAAQ,IAAI,QAAQ,IAAI,QAAS;AAAA,UACjC,QAAS,IAAI,SAAS,IAAI,QAAS;AAAA,QACvC,CAAC;AAAA,MACL;AAEA,MAAAC,OAAM,OAAO;AAAA,IACjB;AAGA,aAAS,OAAO,KAAgB;AAC5B,UAAI,IAAI,YAAY,KAAM;AAC1B,UAAI,CAAC,IAAK,OAAM,OAAO;AACvB,UAAI,QAAS,IAAI,UAAU,IAAI;AAC/B,UAAI,QAAS,IAAI,UAAU,IAAI;AAC/B,UAAI,KAAK,UAAU,UAAU;AACzB;AAAC,QAACD,OAAM,YAAY,EACf,IAAI;AAAA,UACD,QAAS,IAAI,QAAQ,IAAI,QAAS;AAAA,UAClC,OAAS,IAAI,QAAQ,IAAI,QAAS;AAAA,QACtC,CAAC,EACA,IAAI;AAAA,UACD,cAAc;AAAA,UACd,aAAc;AAAA,QAClB,CAAC;AAAA,MACT,OAAO;AACH,QAAAA,OAAM,YAAY,EAAE,IAAI;AAAA,UACpB,YAAY;AAAA,UACZ,OAAQ,IAAI,QAAQ,IAAI,QAAS;AAAA,UACjC,QAAS,IAAI,SAAS,IAAI,QAAS;AAAA,QACvC,CAAC;AACD,aAAK,eAAe;AAAA,MACxB;AACA,UAAI,WAAW;AACf,WAAK,SAAS;AACd,MAAAA,OAAM,SAAS,IAAI,EAAE,IAAI,YAAY;AACrC,UAAI,CAAC,IAAI,SAAU,MAAK,OAAO;AAAA,IACnC;AAAA,EACJ;AAAA;AAAA;AAAA,EAIA,KAAK,SAAc;AACf,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,UAAI,OAAO,WAAW,UAAU;AAC5B,kBAAU,EAAE,KAAK,QAAQ;AAAA,MAC7B;AACA,UAAI,QAAQ,OAAO,MAAM;AACrB,gBAAQ,IAAI,gCAAgC;AAC5C,eAAO,wBAAwB;AAC/B;AAAA,MACJ;AACA,WAAK,SAAS;AACd,YAAM,CAAC,KAAK,QAAQ,IAAI,OAAO,QAAQ,GAAG,EAAE,MAAM,GAAG;AACrD,UAAI,KAAK;AACL,cAAM,GAAG,EAAE,KAAK,SAAO,IAAI,KAAK,CAAC,EAAE,KAAK,UAAQ;AAC5C,kBAAQ,KAAK,SAAS,MAAM,UAAU,OAAO,CAAC;AAAA,QAClD,CAAC;AAAA,MACL;AAAA,IACJ,CAAC;AAAA,EACL;AAAA;AAAA;AAAA,EAIA,SAAS,MAAW,IAAS,UAAe,CAAC,GAAG;AAC5C,QAAI;AACJ,QAAI;AACA,aAAOA,OAAM,IAAI;AAAA,IACrB,SAAS,GAAG;AAGR,aAAQ,MAAkB,KAAK,IAAI;AAAA,IACvC;AACA,QAAI,GAAI,QAAO,KAAK,OAAO,MAAM,EAAE;AACnC,WAAO,OAAO,SAAS;AAAA,MACnB,OAAO,SAASA,OAAM,IAAI,EAAE,IAAI,OAAO,CAAW;AAAA,MAClD,QAAQ,SAASA,OAAM,IAAI,EAAE,IAAI,QAAQ,CAAW;AAAA,MACpD,OAAOA,OAAM,IAAI,EAAE,KAAK,aAAa,EAAE,KAAK;AAAA,MAC5C,MAAMA,OAAM,IAAI,EAAE,KAAK,YAAY,EAAE,KAAK;AAAA,MAC1C,SAASA,OAAM,IAAI,EAAE,KAAK,eAAe,EAAE,KAAK;AAAA,MAChD,OAAQA,OAAM,IAAI,EAAE,KAAK,YAAY,EAAE,IAAI,CAAC,EAAkB,MAAM;AAAA,IACxE,CAAC;AACD,WAAO,KAAK,KAAK,OAAO;AAAA,EAC5B;AAAA;AAAA;AAAA,EAIA,OAAO,QAAa,OAAa;AAG7B,QAAI,QAAa,KAAK,QAAQ,UAAU,MAAM;AAG9C,QAAI,iBAAiB,UAAW,MAAc,QAAS,SAAS,MAAc;AAE9E,UAAM,QAAQ,KAAK,QAAQ,UAAU;AAAA,MAAE;AAAA,MAAQ,QAAQ;AAAA,MAAS,MAAM;AAAA;AAAA;AAAA,MAGlE,eAAe;AAAA,MAAO,OAAO,KAAK,OAAO,IAAK,KAAK,OAAO,EAAU,QAAQ;AAAA,IAAK,CAAC;AACtF,QAAI,MAAM,gBAAgB,KAAM;AAEhC,QAAI,OAAO,UAAU,WAAY,OAAM,KAAK,MAAM,KAAK;AAEvD,UAAM,OAAO;AAAA,EACjB;AAAA;AAAA;AAAA,EAIA,QAAQ,OAAY;AAChB,QAAI,KAAK,WAAW,CAAC,KAAK,QAAQ,SAAU;AAE5C,UAAM,QAAQ,KAAK,QAAQ,WAAW,EAAE,QAAQ,SAAS,eAAe,MAAM,CAAC;AAC/E,QAAI,MAAM,gBAAgB,KAAM;AAEhC,YAAQ,MAAM,SAAS;AAAA,MACnB,KAAK;AACD,cAAM,eAAe;AACrB,YAAIA,OAAM,yBAAyB,EAAE,UAAU,GAAG;AAC9C,cAAI,KAAK,QAAQ,cAAc;AAC3B,iBAAK,OAAO,KAAK,QAAQ,YAAY;AAAA,UACzC,OAAO;AACH,iBAAK,MAAM;AAAA,UACf;AAAA,QACJ;AACA;AAAA,IACR;AAEA,UAAM,OAAO;AAAA,EACjB;AAAA;AAAA;AAAA,EAIA,MAAM,WAAiB;AAEnB,UAAM,QAAQ,KAAK,QAAQ,SAAS,EAAE,QAAQ,QAAQ,CAAC;AACvD,QAAI,MAAM,gBAAgB,KAAM;AAChC,UAAM,UAAU,MAAM;AAElB,MAAAA,OAAM,YAAY,EAAE,OAAO;AAE3B,UAAI,KAAK,QAAQ,YAAa,MAAK,QAAQ,YAAY,MAAM;AAC7D,WAAK,SAAS;AACd,WAAK,UAAU,CAAC;AAEhB,YAAM,OAAO;AACb,WAAK,YAAY;AAAA,IACrB;AACA,QAAIA,OAAM,YAAY,EAAE,WAAW,KAAK,KAAK,UAAU,UAAU;AAC7D;AAAA,IACJ;AACA,QAAI,KAAK,UAAU,WAAW;AAC1B,kBAAY;AAAA,IAChB;AACA,QAAI,KAAK,UAAU,aAAa,cAAc,MAAM;AAChD,cAAQ;AACR,mBAAa,KAAK,IAAI,cAAc,CAAkC;AACtE,cAAQ,OAAO,SAAS,MAAM,CAAC;AAC/B;AAAA,IACJ;AAEA,SAAK,SAAS;AACb,IAACA,OAAM,YAAY,EACf,IAAI,cAAc,KAAK,QAAQ,QAAQ,GAAG,EAC1C,SAAS,0BAA0B;AACxC,YAAQ,OAAO,SAAS,MAAM,GAAG;AACjC,SAAK,aAAa;AAElB,QAAI,WAAW;AACX,cAAQ;AAAA,IACZ,OAAO;AACH,WAAK,IAAI,cAAc,IAAI,WAAW,UAAU,KAAK,QAAQ,SAAS,OAAO,GAAI;AAAA,IACrF;AAEA,QAAI,KAAK,QAAQ,UAAU;AACvB,MAAAA,OAAM,SAAS,IAAI,EAAE,IAAI,WAAW,KAAK,OAAO;AAAA,IACpD;AACA,IAAAA,OAAM,MAAM,EAAE,IAAI,UAAU,KAAK,YAAY;AAAA,EACjD;AAAA,EAEA,SAAS;AACL,UAAM,QAAQ,KAAK,QAAQ,UAAU,EAAE,QAAQ,QAAQ,CAAC;AACxD,QAAI,MAAM,gBAAgB,KAAM;AAEhC,QAAI,KAAK,QAAQ,cAAc,KAAM,MAAK,IAAI;AAAA,QAAQ,MAAK,IAAI;AAE/D,eAAW,MAAM;AACb,YAAM,OAAO;AAAA,IACjB,IAAK,KAAK,QAAQ,SAAS,OAAO,MAAQ,EAAE;AAAA,EAChD;AAAA,EAEA,MAAM;AACF,QAAI,KAAK,QAAQ,cAAc,KAAM;AAErC,UAAM,QAAQ,KAAK,QAAQ,OAAO,EAAE,QAAQ,QAAQ,CAAC;AACrD,QAAI,MAAM,gBAAgB,KAAM;AAEhC,SAAK,SAAS;AACd,UAAM,OAAQA,OAAM,YAAY,EAAE,IAAI,CAAC,EAAkB,sBAAsB;AAC/E,SAAK,QAAQ,WAAW,KAAK,QAAQ,MAAM,KAAK;AAEhD,SAAK,OAAO,KAAO,KAAO,MAAM;AAC5B,WAAK,SAAS;AACd,WAAK,QAAQ,YAAY;AACzB,YAAM,OAAO;AAAA,IACjB,CAAC;AAAA,EACL;AAAA,EAEA,MAAM;AACF,QAAI,KAAK,QAAQ,cAAc,KAAM;AACrC,UAAM,QAAQ,KAAK,QAAQ,YAAY,IAAI,MAAM,GAAG;AAEpD,UAAM,QAAQ,KAAK,QAAQ,OAAO,EAAE,QAAQ,QAAQ,CAAC;AACrD,QAAI,MAAM,gBAAgB,KAAM;AAEhC,SAAK,SAAS;AAEd,SAAK,QAAQ,YAAY;AACzB,SAAK,OAAO,SAAS,KAAK,CAAC,KAAK,GAAG,GAAG,SAAS,KAAK,CAAC,KAAK,GAAG,GAAG,MAAM;AAClE,WAAK,SAAS;AACd,WAAK,QAAQ,WAAY;AACzB,YAAM,OAAO;AAAA,IACjB,CAAC;AAAA,EACL;AAAA,EAEA,QAAQ;AACJ,IAAAA,OAAM,6BAA6B,EAAE,KAAK,EAAE;AAC5C,IAAAA,OAAM,4BAA4B,EAAE,KAAK,EAAE;AAC3C,IAAAA,OAAM,+BAA+B,EAAE,KAAK,EAAE;AAAA,EAClD;AAAA,EAEA,QAAQ;AACJ,SAAK,KAAK,KAAK,QAAQ;AAAA,EAC3B;AAAA;AAAA;AAAA,EAIA,QAAQ,SAAc;AAClB,WAAO,QAAQ,QAAQ;AAAA,MACnB,OAAO;AAAA,MACP,KAAOA,OAAM,YAAY,EAAE,IAAI,CAAC;AAAA,MAChC,OAAO;AAAA,IACX,GAAG,OAAO;AAAA,EACd;AAAA;AAAA;AAAA,EAIA,QAAQ,SAAc;AAClB,WAAO,QAAQ,QAAQ;AAAA,MACnB,OAAO;AAAA,MACP,KAAOA,OAAM,YAAY,EAAE,IAAI,CAAC;AAAA,MAChC,OAAO;AAAA,IACX,GAAG,OAAO;AAAA,EACd;AAAA;AAAA;AAAA,EAIA,SAAS,OAAa;AAClB,UAAM,MAAMA,OAAM,YAAY;AAC9B,UAAM,MAAM;AACZ,QAAI,SAAS,MAAM;AACf,YAAM,KAAK,MAAM,KAAK,IAChB,IAAI,KAAK,GAAG,EAAE,OAAO,KAAK,EAAE,OAAO,2BAA2B,EAAE,IAAI,CAAC,IACrE,IAAI,KAAK,GAAG,EAAE,OAAO,2BAA2B,EAAE,IAAI,KAAK;AACjE,UAAI,MAAM;AAAA,IACd,OAAO;AACH,YAAM,KAAK,IAAI,KAAK,qBAAqB,EAAE,IAAI,CAAC;AAChD,UAAI,GAAI,IAAG,MAAM;AAAA,IACrB;AAEA,IAAAA,OAAM,GAAG,EAAE,KAAK,GAAG,EACd,IAAI,aAAa,EAGjB,GAAG,mBAAmB,SAAU,QAAa;AAC1C,iBAAW,MAAM;AACb,cAAME,SAAQ,SAAS;AAGvB,cAAM,SAASF,OAAM,GAAG,EAAE,KAAK,GAAG,EAAE,OAAOE,MAAY,EAAE,SAAS;AAGlE,cAAM,OAAOF,OAAME,MAAY,EAAE,KAAK,MAAM;AAC5C,YAAI,CAAC,UAAUA,UAASA,WAAU,SAAS,MAAM;AAC7C,UAACF,OAAM,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI,CAAC,GAAmB,MAAM;AAAA,QACxD;AACA,YAAI,QAAQ,eAAe;AACvB,UAACA,OAAM,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI,CAAC,GAAmB,MAAM;AAAA,QACxD;AACA,YAAI,QAAQ,gBAAgB;AACxB,UAACA,OAAM,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI,EAAE,GAAmB,MAAM;AAAA,QACzD;AAAA,MACJ,GAAG,CAAC;AAAA,IACR,CAAC;AAAA,EACT;AAAA;AAAA;AAAA,EAIA,KAAK,KAAW,aAAmB;AAC/B,YAAQ,KAAKA,OAAM,YAAY,GAAG,KAAK,WAAW;AAAA,EACtD;AAAA;AAAA;AAAA,EAIA,OAAO,OAAa;AAChB,YAAQ,OAAOA,OAAM,YAAY,GAAG,KAAK;AAAA,EAC7C;AAAA;AAAA;AAAA,EAIA,OAAO,OAAa,QAAc,OAAa;AAC3C,QAAI,MAAM;AACV,QAAI,OAAO,eAAe,QAAW;AACjC,aAAO,KAAK,MAAM,SAAS,gBAAgB,WAAW;AACtD,aAAO,KAAK,MAAM,SAAS,gBAAgB,YAAY;AAAA,IAC3D,OAAO;AACH,aAAO,KAAK,MAAM,OAAO,UAAU;AACnC,aAAO,KAAK,MAAM,OAAO,WAAW;AAAA,IACxC;AACA,YAAQ,SAAS,SAAS,KAAK,QAAQ,KAAK;AAC5C,aAAS,SAAS,UAAU,KAAK,QAAQ,MAAM;AAC/C,QAAI,KAAK,QAAQ,cAAc,MAAM;AACjC,cAAQ;AACR,eAAS;AAAA,IACb;AACA,QAAI,OAAO,KAAK,MAAO,SAAQ,OAAO;AACtC,QAAI,OAAO,KAAK,OAAQ,UAAS,OAAO;AACxC,UAAM,OAAQ,OAAO,UAAU;AAC/B,UAAM,QAAQ,OAAO,SAAS;AAC9B,QAAI,OAAO;AACP,MAAAA,OAAM,YAAY,EAAE,IAAI;AAAA,QACpB,cAAc;AAAA,QACd,OAAU,MAAM;AAAA,QAChB,QAAU,OAAO;AAAA,QACjB,SAAU,QAAQ;AAAA,QAClB,UAAU,SAAS;AAAA,MACvB,CAAC;AACD,WAAK,eAAe;AAAA,IACxB;AACA,WAAO,EAAE,KAAK,MAAM,OAAO,OAAO;AAAA,EACtC;AAAA;AAAA;AAAA,EAIA,OAAO,UAAe,WAAgB,UAAgB;AAClD,WAAO,IAAI,QAAQ,aAAW;AAE1B,YAAM,OAAO;AACb,UAAI,KAAK,QAAQ,SAAS,KAAM,MAAK,QAAQ,QAAQ;AAErD,YAAM,EAAE,KAAK,MAAM,OAAO,OAAO,IAAI,KAAK,OAAO,UAAU,SAAS;AACpE,YAAM,QAAQ,KAAK,QAAQ;AAC3B,MAAAA,OAAM,YAAY,EAAE,IAAI;AAAA,QACpB,cAAc,GAAG,KAAK,YAAY,KAAK,aAAa,KAAK,WAAW,KAAK;AAAA,QACzE,OAAU,MAAM;AAAA,QAChB,QAAU,OAAO;AAAA,QACjB,SAAU,QAAQ;AAAA,QAClB,UAAU,SAAS;AAAA,MACvB,CAAC;AACD,YAAM,UAAU,YAAY,MAAM;AAAE,aAAK,eAAe;AAAA,MAAE,GAAG,EAAE;AAC/D,iBAAW,MAAM;AACb,sBAAc,OAAO;AACrB,aAAK,eAAe;AACpB,YAAI,OAAO,YAAY,WAAY,UAAS;AAC5C,gBAAQ,MAAS;AAAA,MACrB,GAAI,KAAK,QAAQ,QAAQ,MAAQ,EAAE;AAAA,IACvC,CAAC;AAAA,EACL;AAAA;AAAA,EAGA,iBAAiB;AAEb,IAAAA,OAAM,yBAAyB,EAAE,KAAK,CAAC,SAAe;AAClD,YAAM,MAAM;AAGZ,YAAM,OAAQ,IAAY;AAC1B,YAAM,QAAQA,OAAM,YAAY;AAChC,UAAI,SAAS,KAAK,KAAK,IAAI,GAAI,MAAK,QAAQ;AAC5C,UAAI,SAAS,KAAK,MAAM,IAAI,GAAI,MAAK,SAAS;AAC9C,YAAM,OAAQ,MAAM,CAAC,EAAkB,sBAAsB;AAC7D,YAAM,cAAe,MAAM,KAAK,kBAAkB,EAAE,CAAC,EAAkB;AACvE,YAAM,SAAc,KAAK,MAAM,KAAK,KAAK;AACzC,YAAM,UAAc,KAAK,MAAM,KAAK,MAAM;AAE1C,WAAK,QAAQ,KAAK;AAClB,UAAI,KAAK,QAAQ,SAAS,IAAI;AAC1B,aAAK,QAAQ,SAAS;AAAA,MAC1B;AAEA,WAAK,SAAS,KAAK;AACnB,UAAI,KAAK,SAAS,UAAU,cAAc,GAAG;AACzC,aAAK,SAAS,UAAU,cAAc;AAAA,MAC1C;AACA,UAAI,KAAK,iBAAiB,EAAG,MAAK,SAAS,UAAU,KAAK,iBAAiB;AAC3E,UAAI,KAAK,gBAAgB,EAAG,MAAK,QAAQ,SAAS,KAAK,gBAAgB;AACvE,MAAAA,OAAM,GAAG,EAAE,IAAI;AAAA,QACX,OAAY,SAAS,KAAK,SAAS,IAAK;AAAA,QACxC,OAAU,KAAK,QAAQ;AAAA,QACvB,QAAU,KAAK,SAAS;AAAA,MAC5B,CAAC;AAAA,IACL,CAAC;AAAA,EACL;AACJ;AAGA,SAAS,QAAQ,KAAU,OAAa,UAAqB;AAEzD,MAAI;AACJ,QAAM,UAAU;AAAA,IACZ,OAAO,QAAQ,KAAK,SAAS,cAAc;AAAA,IAC3C,MAAM,0CAA0C,GAAG;AAAA,IACnD,WAAW;AAAA,IACX,SAAS,EAAE,IAAI,QAAQ,KAAK,IAAI,EAAE;AAAA,IAClC,cAAc;AAAA,EAClB;AACA,MAAIA,OAAM,YAAY,EAAE,SAAS,KAAK,QAAQ,UAAU,WAAW;AAC/D,WAAO,QAAQ,QAAQ,OAAO;AAAA,EAClC,OAAO;AACH,WAAO,QAAQ,KAAK,OAAO;AAAA,EAC/B;AAEA,OAAK,IAAI,EAAE,CAAC,UAAe;AACvB,QAAI,OAAO,MAAM,OAAO,MAAM,SAAS,YAAY;AAC/C,YAAM,OAAO,KAAK,MAAM;AAAA,IAC5B;AACA,QAAI,OAAO,YAAY,WAAY,UAAS;AAAA,EAChD,CAAC;AACD,SAAO;AACX;AAGA,SAAS,UAAU,KAAU,OAAa,UAAqB;AAE3D,MAAI;AACJ,MAAI,UAAU;AACd,MAAI,CAAC,UAAU,QAAQ,EAAE,SAAS,OAAO,OAAO,GAAG;AAC/C,cAAU,EAAE,KAAK,QAAQ;AAAA,EAC7B;AACA,MAAI,QAAQ,KAAK;AACb,YAAQ,OAAO,0CAA0C,QAAQ,GAAG,UACpE,OAAO,QAAQ;AAAA,EACnB;AACA,MAAI,OAAO,SAAS,cAAc,YAAY,MAAM;AAChD,eAAW;AACX,YAAQ;AAAA,EACZ;AACA,UAAQ,OAAO,SAAS;AAAA,IACpB,OAAO,QAAQ,KAAK,SAAS,QAAQ,SAAS,cAAc;AAAA,IAC5D,WAAW;AAAA,IACX,OAAO;AAAA,IACP,cAAc;AAAA,EAClB,CAAC;AACD,MAAI,YAAY,QAAQ,QAAQ,YAAY,MAAM;AAC9C,eAAW,QAAQ;AAAA,EACvB;AACA,UAAQ,YAAY,SAAS,EAAE,KAAK,QAAQ,KAAK,KAAK,GAAG,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;AACjF,MAAIA,OAAM,YAAY,EAAE,SAAS,KAAK,QAAQ,UAAU,WAAW;AAC/D,WAAO,QAAQ,QAAQ,OAAO;AAAA,EAClC,OAAO;AACH,WAAO,QAAQ,KAAK,OAAO;AAAA,EAC/B;AACA,OAAK,KACA,IAAI,UAAU,EAEd,GAAG,wBAAwB,CAAC,UAAe;AACxC,QAAI,OAAO,MAAM,OAAO,MAAM,SAAS,YAAY;AAC/C,YAAM,OAAO,KAAK,MAAM;AAAA,IAC5B;AACA,QAAI,OAAO,YAAY,WAAY,UAAS,MAAM,OAAO,MAAM;AAAA,EACnE,CAAC;AACL,SAAO;AACX;AAGA,SAAS,SAAS,OAAY,OAAa,UAAqB;AAE5D,MAAI;AACJ,MAAI,UAAU;AACd,MAAI,CAAC,UAAU,QAAQ,EAAE,SAAS,OAAO,OAAO,GAAG;AAC/C,cAAU,EAAE,OAAO,QAAQ;AAAA,EAC/B;AACA,MAAI,QAAQ,OAAO;AACf,YAAQ,QAAQ;AAChB,YAAQ,OAAQ,QAAQ,WAClB;AAAA,wBACU,QAAQ,KAAK;AAAA,6DACwB,QAAQ,SAAS,EAAE;AAAA;AAAA,yBAGlE;AAAA,0BACY,QAAQ,KAAK;AAAA,0DACmB,QAAQ,SAAS,EAAE;AAAA;AAAA;AAAA,EAIzE;AACA,UAAQ,OAAO,SAAS;AAAA,IACpB,OAAO,QAAQ,KAAK,SAAS,QAAQ,SAAS,cAAc;AAAA,IAC5D,WAAW;AAAA,IACX,OAAO;AAAA,IACP,cAAc;AAAA,EAClB,CAAC;AACD,UAAQ,YAAY,SAAS,EAAE,IAAI,QAAQ,KAAK,IAAI,GAAG,QAAQ,QAAQ,KAAK,QAAQ,EAAE,CAAC;AACvF,MAAIA,OAAM,YAAY,EAAE,SAAS,KAAK,QAAQ,UAAU,WAAW;AAC/D,WAAO,QAAQ,QAAQ,OAAO;AAAA,EAClC,OAAO;AACH,WAAO,QAAQ,KAAK,OAAO;AAAA,EAC/B;AACA,MAAI,KAAK,KAAK,KAAK;AACf,SAAK,KAAK,OAAO,IAAIA,OAAM,KAAK,KAAK,GAAG,EAAE,KAAK,WAAW,EAAE,IAAI,CAAC;AAAA,EACrE,OAAO;AACH,SAAK,KAAK,OAAO,IAAIA,OAAM,sCAAsC,EAAE,IAAI,CAAC;AAAA,EAC5E;AACA,MAAI,QAAQ,SAAS,MAAM;AACvB,SAAK,KAAK,OAAO,EAAE,QAAQ,QAAQ;AACnC,SAAK,KAAK,OAAO,EAAE,OAAO;AAAA,EAC9B;AAEA,OAAK,SAAS,SAAU,UAAe;AACnC,SAAK,KAAK,GAAG,UAAU,QAAQ;AAC/B,WAAO;AAAA,EACX;AACA,OAAK,KACA,IAAI,SAAS,EAEb,GAAG,qBAAqB,CAAC,UAAe;AACrC,UAAM,MAAM,MAAM,OAAO,MAAM,MAAM,OAAO,MAAMA,OAAM,4BAA4B,EAAE,IAAI,CAAC;AAC3F,YAAQ,WAAWA,OAAM,GAAG,EAAE,KAAK,WAAW,GAAG;AAAA;AAAA,MAE7C,QAAQ,KAAU;AACd,YAAI,IAAI,WAAW,GAAI,KAAI,gBAAgB;AAAA,MAC/C;AAAA;AAAA,MAEA,OAAO,KAAU;AACb,cAAM,QAAQ,KAAK,KAAK,QAAQ,UAAU,EAAE,QAAQ,UAAU,eAAe,IAAI,CAAC;AAClF,YAAI,MAAM,gBAAgB,KAAM;AAChC,YAAI,IAAI,WAAW,OAAO,IAAI,WAAW,IAAI,WAAW,IAAI,OAAO,WAAW,aAAa;AACvF,eAAK,KAAK,OAAO,MAAM,GAAG;AAAA,QAC9B;AACA,YAAI,IAAI,WAAW,IAAI;AACnB,eAAK,KAAK,OAAO,UAAU,GAAG;AAAA,QAClC;AACA,cAAM,OAAO;AAAA,MACjB;AAAA,IACJ,CAAC;AACD,IAAAA,OAAM,GAAG,EAAE,KAAK,cAAc,EAAE,QAAQ,OAAO;AAAA,EACnD,CAAC,EAEA,GAAG,uBAAuB,CAAC,UAAe;AACvC,QAAI,OAAO,MAAM,OAAO,MAAM,SAAS,YAAY;AAC/C,YAAM,OAAO,KAAK,MAAM;AAAA,IAC5B;AACA,QAAI,OAAO,YAAY,WAAY,UAAS,MAAM,OAAO,MAAM;AAAA,EACnE,CAAC;AACL,SAAO;AACX;AAEA,IAAI,qBAAqB;AACzB,IAAM,UAAU,cAAwB,MAAM;AAAE;AAAsB,SAAO,IAAI,SAAS;AAAE,GAAG,QAAQ;AAGhG,IAAM,mBAAmB;AAAA,EAC5B,IAAI,oBAAoB;AAAE,WAAO;AAAA,EAAmB;AAAA,EACpD,QAAQ;AAAE,yBAAqB;AAAA,EAAE;AACrC;","names":["query","edata","focus"]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  TsMenu,
3
3
  TsTooltip
4
- } from "./chunk-OFASTA2A.js";
4
+ } from "./chunk-FAIRNXQR.js";
5
5
  import {
6
6
  TsUtils
7
7
  } from "./chunk-3NYH6545.js";
@@ -1635,4 +1635,4 @@ var TsSidebar = class extends TsBase {
1635
1635
  export {
1636
1636
  TsSidebar
1637
1637
  };
1638
- //# sourceMappingURL=chunk-BIB3X2TW.js.map
1638
+ //# sourceMappingURL=chunk-DZSFZLV6.js.map
@@ -0,0 +1,33 @@
1
+ // src/lazy-singleton.ts
2
+ function lazySingleton(factory, protoRef) {
3
+ let _impl = null;
4
+ const materialize = () => _impl ??= factory();
5
+ return new Proxy({}, {
6
+ get(_t, prop, receiver) {
7
+ return Reflect.get(materialize(), prop, receiver);
8
+ },
9
+ set(_t, prop, value, _receiver) {
10
+ return Reflect.set(materialize(), prop, value, materialize());
11
+ },
12
+ has(_t, prop) {
13
+ return Reflect.has(materialize(), prop);
14
+ },
15
+ ownKeys() {
16
+ return Reflect.ownKeys(materialize());
17
+ },
18
+ getOwnPropertyDescriptor(_t, prop) {
19
+ return Reflect.getOwnPropertyDescriptor(materialize(), prop);
20
+ },
21
+ defineProperty(_t, prop, desc) {
22
+ return Reflect.defineProperty(materialize(), prop, desc);
23
+ },
24
+ getPrototypeOf() {
25
+ return protoRef.prototype;
26
+ }
27
+ });
28
+ }
29
+
30
+ export {
31
+ lazySingleton
32
+ };
33
+ //# sourceMappingURL=chunk-EQK6JAHT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lazy-singleton.ts"],"sourcesContent":["/**\n * Creates a lazily-initialized singleton wrapped in a transparent Proxy.\n * The factory is invoked at most once, on first property access / set / has /\n * instanceof / ownKeys / getOwnPropertyDescriptor.\n *\n * `protoRef` is the class whose `.prototype` is returned by `getPrototypeOf`.\n * It is required so `instanceof` works without triggering materialization.\n */\nexport function lazySingleton<T extends object>(\n factory: () => T,\n protoRef: { prototype: object },\n): T {\n let _impl: T | null = null\n const materialize = (): T => (_impl ??= factory())\n // `as T` cast is purely for type erasure — runtime sees an empty object as target.\n return new Proxy({} as T, {\n get(_t, prop, receiver) { return Reflect.get(materialize(), prop, receiver) },\n set(_t, prop, value, _receiver) { return Reflect.set(materialize(), prop, value, materialize()) },\n has(_t, prop) { return Reflect.has(materialize(), prop) },\n ownKeys() { return Reflect.ownKeys(materialize()) },\n getOwnPropertyDescriptor(_t, prop) { return Reflect.getOwnPropertyDescriptor(materialize(), prop) },\n defineProperty(_t, prop, desc) { return Reflect.defineProperty(materialize(), prop, desc) },\n getPrototypeOf() { return protoRef.prototype },\n })\n}\n"],"mappings":";AAQO,SAAS,cACZ,SACA,UACC;AACD,MAAI,QAAkB;AACtB,QAAM,cAAc,MAAU,UAAU,QAAQ;AAEhD,SAAO,IAAI,MAAM,CAAC,GAAQ;AAAA,IACtB,IAAI,IAAI,MAAM,UAAU;AAAE,aAAO,QAAQ,IAAI,YAAY,GAAG,MAAM,QAAQ;AAAA,IAAE;AAAA,IAC5E,IAAI,IAAI,MAAM,OAAO,WAAW;AAAE,aAAO,QAAQ,IAAI,YAAY,GAAG,MAAM,OAAO,YAAY,CAAC;AAAA,IAAE;AAAA,IAChG,IAAI,IAAI,MAAM;AAAE,aAAO,QAAQ,IAAI,YAAY,GAAG,IAAI;AAAA,IAAE;AAAA,IACxD,UAAU;AAAE,aAAO,QAAQ,QAAQ,YAAY,CAAC;AAAA,IAAE;AAAA,IAClD,yBAAyB,IAAI,MAAM;AAAE,aAAO,QAAQ,yBAAyB,YAAY,GAAG,IAAI;AAAA,IAAE;AAAA,IAClG,eAAe,IAAI,MAAM,MAAM;AAAE,aAAO,QAAQ,eAAe,YAAY,GAAG,MAAM,IAAI;AAAA,IAAE;AAAA,IAC1F,iBAAiB;AAAE,aAAO,SAAS;AAAA,IAAU;AAAA,EACjD,CAAC;AACL;","names":[]}
@@ -1,3 +1,6 @@
1
+ import {
2
+ lazySingleton
3
+ } from "./chunk-EQK6JAHT.js";
1
4
  import {
2
5
  TsUtils
3
6
  } from "./chunk-3NYH6545.js";
@@ -2965,16 +2968,53 @@ var DateTooltip = class extends Tooltip {
2965
2968
  return ret;
2966
2969
  }
2967
2970
  };
2968
- var TsTooltip = new Tooltip();
2969
- var TsMenu = new MenuTooltip();
2970
- var TsColor = new ColorTooltip();
2971
- var TsDate = new DateTooltip();
2971
+ var _tooltipCtorCount = 0;
2972
+ var _menuCtorCount = 0;
2973
+ var _colorCtorCount = 0;
2974
+ var _dateCtorCount = 0;
2975
+ var TsTooltip = lazySingleton(() => {
2976
+ _tooltipCtorCount++;
2977
+ return new Tooltip();
2978
+ }, Tooltip);
2979
+ var TsMenu = lazySingleton(() => {
2980
+ _menuCtorCount++;
2981
+ return new MenuTooltip();
2982
+ }, MenuTooltip);
2983
+ var TsColor = lazySingleton(() => {
2984
+ _colorCtorCount++;
2985
+ return new ColorTooltip();
2986
+ }, ColorTooltip);
2987
+ var TsDate = lazySingleton(() => {
2988
+ _dateCtorCount++;
2989
+ return new DateTooltip();
2990
+ }, DateTooltip);
2991
+ var __test_internals = {
2992
+ get tooltipCtorCount() {
2993
+ return _tooltipCtorCount;
2994
+ },
2995
+ get menuCtorCount() {
2996
+ return _menuCtorCount;
2997
+ },
2998
+ get colorCtorCount() {
2999
+ return _colorCtorCount;
3000
+ },
3001
+ get dateCtorCount() {
3002
+ return _dateCtorCount;
3003
+ },
3004
+ reset() {
3005
+ _tooltipCtorCount = 0;
3006
+ _menuCtorCount = 0;
3007
+ _colorCtorCount = 0;
3008
+ _dateCtorCount = 0;
3009
+ }
3010
+ };
2972
3011
 
2973
3012
  export {
2974
3013
  Tooltip,
2975
3014
  TsTooltip,
2976
3015
  TsMenu,
2977
3016
  TsColor,
2978
- TsDate
3017
+ TsDate,
3018
+ __test_internals
2979
3019
  };
2980
- //# sourceMappingURL=chunk-OFASTA2A.js.map
3020
+ //# sourceMappingURL=chunk-FAIRNXQR.js.map