@ixfx/components 0.4.3 → 0.5.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.
- package/bundle/index.d.ts +518 -1176
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +4861 -17274
- package/bundle/index.js.map +1 -1
- package/bundle/style.css +1 -1
- package/dist/ac-text.d.ts +12 -7
- package/dist/ac-text.d.ts.map +1 -1
- package/dist/ac-text.js +2 -3
- package/dist/ac-text.js.map +1 -1
- package/dist/{button-C3fLMKUv.js → button-DxYee1ZH.js} +2 -2
- package/dist/{button-C3fLMKUv.js.map → button-DxYee1ZH.js.map} +1 -1
- package/dist/button.d.ts +1 -2
- package/dist/button.d.ts.map +1 -1
- package/dist/button.js +1 -2
- package/dist/checkbox.d.ts +0 -1
- package/dist/checkbox.d.ts.map +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/checkbox.js.map +1 -1
- package/dist/{colour-picker-0sgAha1T.js → colour-picker-C3Ag4uh-.js} +15 -17
- package/dist/colour-picker-C3Ag4uh-.js.map +1 -0
- package/dist/colour-picker.d.ts +1 -1
- package/dist/colour-picker.js +1 -1
- package/dist/crumbs.d.ts +5 -2
- package/dist/crumbs.d.ts.map +1 -1
- package/dist/crumbs.js +45 -20
- package/dist/crumbs.js.map +1 -1
- package/dist/data-display.d.ts +1 -2
- package/dist/data-display.d.ts.map +1 -1
- package/dist/data-display.js +25 -23
- package/dist/data-display.js.map +1 -1
- package/dist/{data-provider-DgI909FP.js → data-provider-35TyWclX.js} +2 -2
- package/dist/data-provider-35TyWclX.js.map +1 -0
- package/dist/{decorate-DdjvVHS-.js → decorate-VRK8rslU.js} +2 -2
- package/dist/{decorate-DdjvVHS-.js.map → decorate-VRK8rslU.js.map} +1 -1
- package/dist/{defaults-C3b9OWJD.js → defaults-DcE8RQJc.js} +19 -1
- package/dist/defaults-DcE8RQJc.js.map +1 -0
- package/dist/editable-label.d.ts +1 -2
- package/dist/editable-label.d.ts.map +1 -1
- package/dist/editable-label.js +1 -1
- package/dist/editable-label.js.map +1 -1
- package/dist/{hex-editor-WZrjRtvL.js → hex-editor-Bk6rxhfg.js} +9 -11
- package/dist/hex-editor-Bk6rxhfg.js.map +1 -0
- package/dist/{hex-editor-CMIxtNgT.d.ts → hex-editor-Caq8vNQk.d.ts} +2 -3
- package/dist/hex-editor-Caq8vNQk.d.ts.map +1 -0
- package/dist/hex.d.ts +1 -1
- package/dist/hex.js +1 -1
- package/dist/highlight-B-eQrhhb.js.map +1 -1
- package/dist/{icon-Ndo40kNO.js → icon-B22XVlCt.js} +6 -4
- package/dist/{icon-Ndo40kNO.js.map → icon-B22XVlCt.js.map} +1 -1
- package/dist/{icon-Bd5BiU4b.d.ts → icon-DpA9x2Ve.d.ts} +2 -3
- package/dist/icon-DpA9x2Ve.d.ts.map +1 -0
- package/dist/icons.d.ts +2 -2
- package/dist/icons.js +2 -2
- package/dist/{incr-search-CeERfijK.js → incr-search-2pz21xtR.js} +9 -6
- package/dist/incr-search-2pz21xtR.js.map +1 -0
- package/dist/incr-search.d.ts +1 -1
- package/dist/incr-search.js +1 -1
- package/dist/{index-CowKi2mo.d.ts → index-BeuCXtiO.d.ts} +3 -4
- package/dist/index-BeuCXtiO.d.ts.map +1 -0
- package/dist/{index-D87kRcEs.d.ts → index-BtGFYfaK.d.ts} +2 -1
- package/dist/index-BtGFYfaK.d.ts.map +1 -0
- package/dist/{index-s_IhSnwc.d.ts → index-CoqtMSd9.d.ts} +6 -4
- package/dist/index-CoqtMSd9.d.ts.map +1 -0
- package/dist/{index-9fGVAg1d.d.ts → index-Cxwxtj6g.d.ts} +3 -3
- package/dist/index-Cxwxtj6g.d.ts.map +1 -0
- package/dist/index-D_ftz_IT.d.ts +184 -0
- package/dist/index-D_ftz_IT.d.ts.map +1 -0
- package/dist/{index-_RTQSKHi.d.ts → index-DfEkTGvT.d.ts} +11 -11
- package/dist/index-DfEkTGvT.d.ts.map +1 -0
- package/dist/index.d.ts +167 -29
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +712 -2970
- package/dist/index.js.map +1 -1
- package/dist/keyboard-B5xD7Fz-.js +36 -0
- package/dist/keyboard-B5xD7Fz-.js.map +1 -0
- package/dist/{labelled-input-base-ORb1rGq6.d.ts → labelled-input-base-DiTme1JO.d.ts} +1 -2
- package/dist/labelled-input-base-DiTme1JO.d.ts.map +1 -0
- package/dist/{labelled-input-base-9K_w3oLj.js → labelled-input-base-hoKGwyKT.js} +2 -2
- package/dist/{labelled-input-base-9K_w3oLj.js.map → labelled-input-base-hoKGwyKT.js.map} +1 -1
- package/dist/labelled-radial-input.d.ts +5 -4
- package/dist/labelled-radial-input.d.ts.map +1 -1
- package/dist/labelled-radial-input.js +7 -3
- package/dist/labelled-radial-input.js.map +1 -1
- package/dist/labelled-range-input.d.ts +1 -1
- package/dist/labelled-range-input.js +27 -3
- package/dist/labelled-range-input.js.map +1 -1
- package/dist/led.d.ts +1 -2
- package/dist/led.d.ts.map +1 -1
- package/dist/led.js +1 -1
- package/dist/led.js.map +1 -1
- package/dist/{menu-vjoiHZ13.js → menu-g6yd7ddN.js} +8 -9
- package/dist/menu-g6yd7ddN.js.map +1 -0
- package/dist/{menu-item-COx-Azgj.d.ts → menu-item-DSyf9f_L.d.ts} +4 -4
- package/dist/menu-item-DSyf9f_L.d.ts.map +1 -0
- package/dist/{menu-item-BrIuORYD.js → menu-item-NUKwJ4s5.js} +3 -4
- package/dist/{menu-item-BrIuORYD.js.map → menu-item-NUKwJ4s5.js.map} +1 -1
- package/dist/menu.d.ts +2 -2
- package/dist/menu.js +2 -2
- package/dist/miller.d.ts +8 -5
- package/dist/miller.d.ts.map +1 -1
- package/dist/miller.js +22 -24
- package/dist/miller.js.map +1 -1
- package/dist/narrowed-text.d.ts +7 -3
- package/dist/narrowed-text.d.ts.map +1 -1
- package/dist/narrowed-text.js +73 -47
- package/dist/narrowed-text.js.map +1 -1
- package/dist/panel.d.ts +1 -1
- package/dist/panel.d.ts.map +1 -1
- package/dist/panel.js +2 -2
- package/dist/panel.js.map +1 -1
- package/dist/plots.d.ts +2 -2
- package/dist/plots.js +1 -1
- package/dist/polar-pad.d.ts +15 -3
- package/dist/polar-pad.d.ts.map +1 -1
- package/dist/polar-pad.js +64 -11
- package/dist/polar-pad.js.map +1 -1
- package/dist/{radial-input-CpQPs1Mp.d.ts → radial-input-BhZeyyP-.d.ts} +6 -4
- package/dist/radial-input-BhZeyyP-.d.ts.map +1 -0
- package/dist/{radial-input-DZ7eQCcM.js → radial-input-DxCrt_NE.js} +41 -19
- package/dist/radial-input-DxCrt_NE.js.map +1 -0
- package/dist/radial-input.d.ts +1 -1
- package/dist/radial-input.js +1 -1
- package/dist/range-input.d.ts +15 -4
- package/dist/range-input.d.ts.map +1 -1
- package/dist/range-input.js +23 -2
- package/dist/range-input.js.map +1 -1
- package/dist/range.d.ts +15 -4
- package/dist/range.d.ts.map +1 -1
- package/dist/range.js +23 -2
- package/dist/range.js.map +1 -1
- package/dist/selecthorizontal.d.ts +1 -2
- package/dist/selecthorizontal.d.ts.map +1 -1
- package/dist/selecthorizontal.js +1 -1
- package/dist/selecthorizontal.js.map +1 -1
- package/dist/slider-input-DFpG23bS.js +1592 -0
- package/dist/slider-input-DFpG23bS.js.map +1 -0
- package/dist/slider-input-TidGhvXt.d.ts +160 -0
- package/dist/slider-input-TidGhvXt.d.ts.map +1 -0
- package/dist/slider-input.d.ts +2 -0
- package/dist/slider-input.js +2 -0
- package/dist/snap-container.d.ts +1 -2
- package/dist/snap-container.d.ts.map +1 -1
- package/dist/snap-container.js +6 -5
- package/dist/snap-container.js.map +1 -1
- package/dist/split-layout.d.ts +1 -2
- package/dist/split-layout.d.ts.map +1 -1
- package/dist/split-layout.js +6 -4
- package/dist/split-layout.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/swipe.d.ts +12 -2
- package/dist/swipe.d.ts.map +1 -1
- package/dist/swipe.js +22 -3
- package/dist/swipe.js.map +1 -1
- package/dist/{tab-list-DLzb-m-I.d.ts → tab-list-BohmbvqF.d.ts} +14 -5
- package/dist/tab-list-BohmbvqF.d.ts.map +1 -0
- package/dist/tab-list-DhkVhRQc.js +597 -0
- package/dist/tab-list-DhkVhRQc.js.map +1 -0
- package/dist/tabs.d.ts +2 -2
- package/dist/tabs.js +1 -208
- package/dist/{tickled-controller-BjYCzGrU.d.ts → tickled-controller-BF2Ea0DE.d.ts} +2 -31
- package/dist/tickled-controller-BF2Ea0DE.d.ts.map +1 -0
- package/dist/tickled-styles-fNDdqf6l.js.map +1 -1
- package/dist/{timeline-2OFtN4Ta.js → timeline-B2fgDL4U.js} +37 -1438
- package/dist/timeline-B2fgDL4U.js.map +1 -0
- package/dist/timeline.d.ts +1 -1
- package/dist/timeline.js +1 -1
- package/dist/{tooltip-RGVIwHrZ.d.ts → tooltip-BlvBUQxx.d.ts} +3 -3
- package/dist/tooltip-BlvBUQxx.d.ts.map +1 -0
- package/dist/{tree-D84RUgFC.js → tree-BnvzhsAw.js} +8 -9
- package/dist/tree-BnvzhsAw.js.map +1 -0
- package/dist/{tree-component-BaCSPWg1.d.ts → tree-component-DCmmKZ4j.d.ts} +8 -124
- package/dist/tree-component-DCmmKZ4j.d.ts.map +1 -0
- package/dist/tree.d.ts +10 -4
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +1 -1
- package/dist/types-DO3gt5vg.d.ts +130 -0
- package/dist/types-DO3gt5vg.d.ts.map +1 -0
- package/dist/wheel-nudge-BlSCe_hD.js +86 -0
- package/dist/wheel-nudge-BlSCe_hD.js.map +1 -0
- package/dist/wheel-nudge-DgMTRYlh.d.ts +29 -0
- package/dist/wheel-nudge-DgMTRYlh.d.ts.map +1 -0
- package/dist/{xy-axis-BeWRMmbo.d.ts → xy-axis-5KhVTNoX.d.ts} +30 -7
- package/dist/xy-axis-5KhVTNoX.d.ts.map +1 -0
- package/dist/xy-axis-CxHC8z5E.js +1849 -0
- package/dist/xy-axis-CxHC8z5E.js.map +1 -0
- package/dist/xy-pad.d.ts +13 -2
- package/dist/xy-pad.d.ts.map +1 -1
- package/dist/xy-pad.js +47 -6
- package/dist/xy-pad.js.map +1 -1
- package/docs-user/README.md +2 -0
- package/docs-user/button.md +48 -0
- package/docs-user/narrowed-text.md +33 -1
- package/docs-user/notifier.md +131 -0
- package/docs-user/plots.md +61 -1
- package/docs-user/radial-input.md +2 -2
- package/docs-user/slider-input.md +673 -0
- package/docs-user/tabs.md +12 -14
- package/docs-user/user-catalog.md +69 -4
- package/docs-user/vertical-list.md +75 -7
- package/package.json +23 -20
- package/dist/colour-C3MQIjFJ-vRCdr8W-.js +0 -3732
- package/dist/colour-C3MQIjFJ-vRCdr8W-.js.map +0 -1
- package/dist/colour-picker-0sgAha1T.js.map +0 -1
- package/dist/data-provider-DgI909FP.js.map +0 -1
- package/dist/defaults-C3b9OWJD.js.map +0 -1
- package/dist/dist-CA13FvMn.js +0 -980
- package/dist/dist-CA13FvMn.js.map +0 -1
- package/dist/hex-editor-CMIxtNgT.d.ts.map +0 -1
- package/dist/hex-editor-WZrjRtvL.js.map +0 -1
- package/dist/icon-Bd5BiU4b.d.ts.map +0 -1
- package/dist/incr-search-CeERfijK.js.map +0 -1
- package/dist/index-9fGVAg1d.d.ts.map +0 -1
- package/dist/index-CowKi2mo.d.ts.map +0 -1
- package/dist/index-D87kRcEs.d.ts.map +0 -1
- package/dist/index-DgXpCg_G.d.ts +0 -1244
- package/dist/index-DgXpCg_G.d.ts.map +0 -1
- package/dist/index-_RTQSKHi.d.ts.map +0 -1
- package/dist/index-s_IhSnwc.d.ts.map +0 -1
- package/dist/keyboard-CimiEskD.js +0 -20
- package/dist/keyboard-CimiEskD.js.map +0 -1
- package/dist/labelled-input-base-ORb1rGq6.d.ts.map +0 -1
- package/dist/menu-item-COx-Azgj.d.ts.map +0 -1
- package/dist/menu-vjoiHZ13.js.map +0 -1
- package/dist/radial-input-CpQPs1Mp.d.ts.map +0 -1
- package/dist/radial-input-DZ7eQCcM.js.map +0 -1
- package/dist/tab-list-DLzb-m-I.d.ts.map +0 -1
- package/dist/tabs.js.map +0 -1
- package/dist/tickled-controller-BjYCzGrU.d.ts.map +0 -1
- package/dist/timeline-2OFtN4Ta.js.map +0 -1
- package/dist/tooltip-RGVIwHrZ.d.ts.map +0 -1
- package/dist/tree-D84RUgFC.js.map +0 -1
- package/dist/tree-component-BaCSPWg1.d.ts.map +0 -1
- package/dist/types-DSfbtHs3.d.ts +0 -8
- package/dist/types-DSfbtHs3.d.ts.map +0 -1
- package/dist/xy-axis-BeWRMmbo.d.ts.map +0 -1
- package/dist/xy-axis-no0OL_O1.js +0 -7893
- package/dist/xy-axis-no0OL_O1.js.map +0 -1
- /package/bundle/{chunk-D7D4PA-g.js → rolldown-runtime-D7D4PA-g.js} +0 -0
- /package/dist/{chunk-D7D4PA-g.js → rolldown-runtime-D7D4PA-g.js} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,52 +1,54 @@
|
|
|
1
1
|
import { n as buildHighlightTargets, r as clearHighlights, t as applyHighlights } from "./highlight-B-eQrhhb.js";
|
|
2
2
|
import { n as tickledStyles, r as TickledController, t as tickledItemStyles } from "./tickled-styles-fNDdqf6l.js";
|
|
3
3
|
import { t as themeFallbacks } from "./fallbacks-pNMOMx38.js";
|
|
4
|
-
import { n as safeCustomElement, t as __decorate } from "./decorate-
|
|
4
|
+
import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
|
|
5
5
|
import { a as svgToDataUri, i as registerIcon, n as hasIcon, r as iconBus, t as getIcon } from "./registry-CkW7q09Q.js";
|
|
6
|
-
import { t as IxfxIconElement } from "./icon-
|
|
6
|
+
import { t as IxfxIconElement } from "./icon-B22XVlCt.js";
|
|
7
7
|
import { AcTextElement } from "./ac-text.js";
|
|
8
|
-
import { a as createFuzzySearch, i as createAcCompletionProvider, n as IncrSearchTreeController, r as createIncrSearch, t as createElementIncrSearch } from "./incr-search-
|
|
9
|
-
import { i as ICON_CLOSE, n as ICON_CHECK, r as ICON_CHEVRON_DOWN, t as ICON_CARET_RIGHT } from "./defaults-
|
|
8
|
+
import { a as createFuzzySearch, i as createAcCompletionProvider, n as IncrSearchTreeController, r as createIncrSearch, t as createElementIncrSearch } from "./incr-search-2pz21xtR.js";
|
|
9
|
+
import { i as ICON_CLOSE, n as ICON_CHECK, r as ICON_CHEVRON_DOWN, t as ICON_CARET_RIGHT } from "./defaults-DcE8RQJc.js";
|
|
10
10
|
import "./icons.js";
|
|
11
11
|
import { t as prominenceStyles } from "./prominence-DlFShic3.js";
|
|
12
|
-
import { n as buttonStyles, t as ButtonElement } from "./button-
|
|
12
|
+
import { n as buttonStyles, t as ButtonElement } from "./button-DxYee1ZH.js";
|
|
13
13
|
import { t as popupSurfaceStyles } from "./popup-DiWMxsWj.js";
|
|
14
|
-
import "./menu-item-
|
|
14
|
+
import "./menu-item-NUKwJ4s5.js";
|
|
15
15
|
import { Checkbox } from "./checkbox.js";
|
|
16
|
-
import {
|
|
17
|
-
import { C as resultThrow, T as throwIfFailed, d as scaler, h as without, n as clamper, p as containsDuplicateInstances, y as nullUndefTest } from "./dist-CA13FvMn.js";
|
|
18
|
-
import { n as ColourPicker, t as ColourPickerPopup } from "./colour-picker-0sgAha1T.js";
|
|
16
|
+
import { n as ColourPicker, t as ColourPickerPopup } from "./colour-picker-C3Ag4uh-.js";
|
|
19
17
|
import { LabelledRangeInput } from "./labelled-range-input.js";
|
|
20
|
-
import { t as collectDataResult } from "./data-provider-
|
|
21
|
-
import { i as TreeDataModel, n as TreeListElement, r as TreeBaseElement, t as TreeController } from "./tree-
|
|
18
|
+
import { t as collectDataResult } from "./data-provider-35TyWclX.js";
|
|
19
|
+
import { i as TreeDataModel, n as TreeListElement, r as TreeBaseElement, t as TreeController } from "./tree-BnvzhsAw.js";
|
|
22
20
|
import { NarrowedTextElement } from "./narrowed-text.js";
|
|
23
21
|
import { CrumbNavigationElement } from "./crumbs.js";
|
|
24
22
|
import { DataDisplayComponent } from "./data-display.js";
|
|
25
23
|
import { EditableLabel } from "./editable-label.js";
|
|
26
|
-
import { t as
|
|
24
|
+
import { t as resolveAxisStep } from "./keyboard-B5xD7Fz-.js";
|
|
25
|
+
import { t as WheelNudgeMixin } from "./wheel-nudge-BlSCe_hD.js";
|
|
27
26
|
import { PanelElement } from "./panel.js";
|
|
28
|
-
import { t as IxfxHexEditorElement } from "./hex-editor-
|
|
29
|
-
import { t as RadialInputElement } from "./radial-input-
|
|
27
|
+
import { t as IxfxHexEditorElement } from "./hex-editor-Bk6rxhfg.js";
|
|
28
|
+
import { t as RadialInputElement } from "./radial-input-DxCrt_NE.js";
|
|
30
29
|
import { LabelledRadialInput } from "./labelled-radial-input.js";
|
|
31
30
|
import { LedElement } from "./led.js";
|
|
32
|
-
import { t as menu_exports } from "./menu-
|
|
31
|
+
import { t as menu_exports } from "./menu-g6yd7ddN.js";
|
|
33
32
|
import { MillerBaseElement, MillerListElement, MillerTreeController } from "./miller.js";
|
|
33
|
+
import { a as TooltipElement, c as computeColour, i as PlotMultiAxis, l as parseColourScaleAttr, n as PlotSingleAxis, o as PlotDataSeries, r as PlotHistogram, s as applyAgeModification, t as PlotXyAxis, u as readBaseColour } from "./xy-axis-CxHC8z5E.js";
|
|
34
34
|
import { PolarPad } from "./polar-pad.js";
|
|
35
35
|
import { t as tooltipValueStyles } from "./tooltip-CJt3WLmN.js";
|
|
36
36
|
import { RangeInput } from "./range-input.js";
|
|
37
37
|
import { RangeElement } from "./range.js";
|
|
38
38
|
import { SelectHorizontalElement } from "./selecthorizontal.js";
|
|
39
|
+
import { t as SliderInputElement } from "./slider-input-DFpG23bS.js";
|
|
39
40
|
import { SnapContainer } from "./snap-container.js";
|
|
40
41
|
import { SplitLayoutElement } from "./split-layout.js";
|
|
41
42
|
import { SwipeElement } from "./swipe.js";
|
|
42
|
-
import { TabListElement } from "./
|
|
43
|
-
import { a as resolveCssVars, i as attachTimelineInteractions, n as TimelineTrackTabElement, o as resolveGrid, r as timelineStyles, s as TimelineController, t as IxfxTimelineElement } from "./timeline-
|
|
43
|
+
import { t as TabListElement } from "./tab-list-DhkVhRQc.js";
|
|
44
|
+
import { a as resolveCssVars, i as attachTimelineInteractions, n as TimelineTrackTabElement, o as resolveGrid, r as timelineStyles, s as TimelineController, t as IxfxTimelineElement } from "./timeline-B2fgDL4U.js";
|
|
44
45
|
import { XyPad } from "./xy-pad.js";
|
|
45
|
-
import { LitElement, css, html, nothing } from "lit";
|
|
46
|
+
import { LitElement, css, html, nothing, render } from "lit";
|
|
46
47
|
import { eventOptions, property, query, queryAssignedElements, state } from "lit/decorators.js";
|
|
47
48
|
import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
|
49
|
+
import { Trees } from "@ixfx/collections";
|
|
50
|
+
import { clamper, scaler } from "@ixfx/numbers";
|
|
48
51
|
import { repeat } from "lit/directives/repeat.js";
|
|
49
|
-
import { classMap } from "lit/directives/class-map.js";
|
|
50
52
|
import { keyed } from "lit/directives/keyed.js";
|
|
51
53
|
//#region src/common/data-controller.ts
|
|
52
54
|
function isAsyncIterable(v) {
|
|
@@ -451,7 +453,6 @@ let AcTokenElement = class AcTokenElement extends LitElement {
|
|
|
451
453
|
e.preventDefault();
|
|
452
454
|
this.#closePopup();
|
|
453
455
|
this._selectedTokenIndex = void 0;
|
|
454
|
-
break;
|
|
455
456
|
}
|
|
456
457
|
}
|
|
457
458
|
#onPaste;
|
|
@@ -569,9 +570,10 @@ let AcTokenElement = class AcTokenElement extends LitElement {
|
|
|
569
570
|
});
|
|
570
571
|
}
|
|
571
572
|
#renderChip(item, index) {
|
|
573
|
+
const isSelected = this._selectedTokenIndex === index;
|
|
572
574
|
return html`
|
|
573
575
|
<span
|
|
574
|
-
class="token-chip ${
|
|
576
|
+
class="token-chip ${isSelected ? `selected` : ``}"
|
|
575
577
|
title=${item.subLabel ?? nothing}
|
|
576
578
|
@pointerdown=${(e) => this.#onChipPointerDown(e, index)}
|
|
577
579
|
>
|
|
@@ -999,9 +1001,11 @@ let RadioGroup = class RadioGroup extends LitElement {
|
|
|
999
1001
|
min-width: min-content;
|
|
1000
1002
|
box-sizing: border-box;
|
|
1001
1003
|
/* Default to looking like a cohesive control group */
|
|
1002
|
-
background: var(--surface-
|
|
1004
|
+
background: var(--surface-4, transparent);
|
|
1005
|
+
background: oklch(from var(--surface-4) l calc(c*0.2) h / 0.4);
|
|
1006
|
+
|
|
1003
1007
|
border: var(--border, none);
|
|
1004
|
-
border-radius: var(--radius-
|
|
1008
|
+
border-radius: var(--radius-xl, 8px);
|
|
1005
1009
|
}
|
|
1006
1010
|
|
|
1007
1011
|
* {
|
|
@@ -1031,6 +1035,7 @@ let RadioGroup = class RadioGroup extends LitElement {
|
|
|
1031
1035
|
gap: var(--item-spacing, 0);
|
|
1032
1036
|
overflow: hidden;
|
|
1033
1037
|
border-radius: inherit;
|
|
1038
|
+
justify-content: center;
|
|
1034
1039
|
}
|
|
1035
1040
|
|
|
1036
1041
|
.radio-group.horizontal {
|
|
@@ -1072,13 +1077,13 @@ let RadioGroup = class RadioGroup extends LitElement {
|
|
|
1072
1077
|
|
|
1073
1078
|
.radio-item:hover:not([disabled]) {
|
|
1074
1079
|
opacity: 0.9;
|
|
1075
|
-
background: var(--surface-4
|
|
1080
|
+
background: color-mix(in oklch, var(--surface-4) 80%, transparent);
|
|
1076
1081
|
}
|
|
1077
1082
|
|
|
1078
1083
|
.radio-item.selected {
|
|
1079
1084
|
font-weight: bold;
|
|
1080
1085
|
color: var(--color-fg-accent, var(--surface-2-text));
|
|
1081
|
-
background: var(--surface-
|
|
1086
|
+
background: var(--surface-5, rgba(255,255,255,0.1));
|
|
1082
1087
|
}
|
|
1083
1088
|
|
|
1084
1089
|
.radio-item[disabled] {
|
|
@@ -1540,2757 +1545,28 @@ let SplitButton = class SplitButton extends ButtonElement {
|
|
|
1540
1545
|
align-items: stretch;
|
|
1541
1546
|
}
|
|
1542
1547
|
`
|
|
1543
|
-
];
|
|
1544
|
-
}
|
|
1545
|
-
};
|
|
1546
|
-
__decorate([property({ attribute: false })], SplitButton.prototype, "registry", void 0);
|
|
1547
|
-
__decorate([property({ attribute: false })], SplitButton.prototype, "keyboardManager", void 0);
|
|
1548
|
-
__decorate([property({ type: String })], SplitButton.prototype, "mode", void 0);
|
|
1549
|
-
__decorate([property({
|
|
1550
|
-
type: String,
|
|
1551
|
-
attribute: `default-value`
|
|
1552
|
-
})], SplitButton.prototype, "defaultValue", void 0);
|
|
1553
|
-
__decorate([property({ attribute: false })], SplitButton.prototype, "itemsProvider", void 0);
|
|
1554
|
-
__decorate([property({ attribute: false })], SplitButton.prototype, "items", void 0);
|
|
1555
|
-
__decorate([query(`ixfx-menu-trigger`)], SplitButton.prototype, "_menuTrigger", void 0);
|
|
1556
|
-
__decorate([state()], SplitButton.prototype, "_compact", void 0);
|
|
1557
|
-
__decorate([state()], SplitButton.prototype, "_selectedCommand", void 0);
|
|
1558
|
-
__decorate([state()], SplitButton.prototype, "_selectedLabel", void 0);
|
|
1559
|
-
__decorate([state()], SplitButton.prototype, "_selectedIcon", void 0);
|
|
1560
|
-
__decorate([state()], SplitButton.prototype, "_switcherItems", void 0);
|
|
1561
|
-
__decorate([state()], SplitButton.prototype, "_dynamicItems", void 0);
|
|
1562
|
-
__decorate([state()], SplitButton.prototype, "_loadingItems", void 0);
|
|
1563
|
-
__decorate([state()], SplitButton.prototype, "_menuHasItems", void 0);
|
|
1564
|
-
SplitButton = __decorate([safeCustomElement(`ixfx-split-button`)], SplitButton);
|
|
1565
|
-
//#endregion
|
|
1566
|
-
//#region node_modules/.pnpm/@ixfx+collections@0.56.13/node_modules/@ixfx/collections/dist/StackMutable-B9Qm32K8.js
|
|
1567
|
-
const trimStack = (opts, stack, toAdd) => {
|
|
1568
|
-
const potentialLength = stack.length + toAdd.length;
|
|
1569
|
-
const policy = opts.discardPolicy ?? `additions`;
|
|
1570
|
-
const capacity = opts.capacity ?? potentialLength;
|
|
1571
|
-
const toRemove = potentialLength - capacity;
|
|
1572
|
-
if (opts.debug) console.log(`Stack.push: stackLen: ${stack.length} potentialLen: ${potentialLength} toRemove: ${toRemove} policy: ${policy}`);
|
|
1573
|
-
switch (policy) {
|
|
1574
|
-
case `additions`:
|
|
1575
|
-
if (opts.debug) console.log(`Stack.push:DiscardAdditions: stackLen: ${stack.length} slice: ${potentialLength - capacity} toAddLen: ${toAdd.length}`);
|
|
1576
|
-
if (stack.length === opts.capacity) return stack;
|
|
1577
|
-
else return [...stack, ...toAdd.slice(0, toAdd.length - toRemove)];
|
|
1578
|
-
case `newer`: {
|
|
1579
|
-
if (toAdd.length >= capacity) return toAdd.slice(toAdd.length - capacity);
|
|
1580
|
-
const keepFromOld = capacity - toAdd.length;
|
|
1581
|
-
return [...stack.slice(0, keepFromOld), ...toAdd];
|
|
1582
|
-
}
|
|
1583
|
-
case `older`: return [...stack, ...toAdd].slice(toRemove);
|
|
1584
|
-
default: throw new Error(`Unknown discard policy ${policy}`);
|
|
1585
|
-
}
|
|
1586
|
-
};
|
|
1587
|
-
const push = (opts, stack, ...toAdd) => {
|
|
1588
|
-
const potentialLength = stack.length + toAdd.length;
|
|
1589
|
-
return opts.capacity && potentialLength > opts.capacity ? trimStack(opts, stack, toAdd) : [...stack, ...toAdd];
|
|
1590
|
-
};
|
|
1591
|
-
const pop = (opts, stack) => {
|
|
1592
|
-
if (stack.length === 0) throw new Error(`Stack is empty`);
|
|
1593
|
-
return stack.slice(0, -1);
|
|
1594
|
-
};
|
|
1595
|
-
/**
|
|
1596
|
-
* Peek at the top of the stack (end of array)
|
|
1597
|
-
*
|
|
1598
|
-
* @typeParam V - Type of stored items
|
|
1599
|
-
* @param {StackOpts} opts
|
|
1600
|
-
* @param {V[]} stack
|
|
1601
|
-
* @returns {(V | undefined)}
|
|
1602
|
-
*/
|
|
1603
|
-
const peek = (opts, stack) => stack.at(-1);
|
|
1604
|
-
const isEmpty = (opts, stack) => stack.length === 0;
|
|
1605
|
-
const isFull = (opts, stack) => {
|
|
1606
|
-
if (opts.capacity) return stack.length >= opts.capacity;
|
|
1607
|
-
return false;
|
|
1608
|
-
};
|
|
1609
|
-
/**
|
|
1610
|
-
* Creates a stack. Mutable. Use {@link StackImmutable} for an immutable alternative.
|
|
1611
|
-
*
|
|
1612
|
-
* @example Basic usage
|
|
1613
|
-
* ```js
|
|
1614
|
-
* // Create
|
|
1615
|
-
* const s = new StackMutable();
|
|
1616
|
-
* // Add one or more items
|
|
1617
|
-
* s.push(1, 2, 3, 4);
|
|
1618
|
-
*
|
|
1619
|
-
* // See what's on top
|
|
1620
|
-
* s.peek; // 4
|
|
1621
|
-
*
|
|
1622
|
-
* // Remove the top-most, and return it
|
|
1623
|
-
* s.pop(); // 4
|
|
1624
|
-
*
|
|
1625
|
-
* // Now there's a new top-most element
|
|
1626
|
-
* s.peek; // 3
|
|
1627
|
-
* ```
|
|
1628
|
-
*/
|
|
1629
|
-
var StackMutable = class {
|
|
1630
|
-
opts;
|
|
1631
|
-
data;
|
|
1632
|
-
/**
|
|
1633
|
-
* Create a new StackMutable.
|
|
1634
|
-
*
|
|
1635
|
-
* @param opts Options
|
|
1636
|
-
* @param data Initial data to use
|
|
1637
|
-
*/
|
|
1638
|
-
constructor(opts = {}, data = []) {
|
|
1639
|
-
this.opts = opts;
|
|
1640
|
-
this.data = data;
|
|
1641
|
-
}
|
|
1642
|
-
/**
|
|
1643
|
-
* Push data onto the stack.
|
|
1644
|
-
* If `toAdd` is empty, nothing happens
|
|
1645
|
-
* @param toAdd Data to add
|
|
1646
|
-
* @returns Length of stack
|
|
1647
|
-
*/
|
|
1648
|
-
push(...toAdd) {
|
|
1649
|
-
if (toAdd.length === 0) return this.data.length;
|
|
1650
|
-
this.data = push(this.opts, this.data, ...toAdd);
|
|
1651
|
-
return this.data.length;
|
|
1652
|
-
}
|
|
1653
|
-
/**
|
|
1654
|
-
* Iterate from bottom to top. Note that `forEachFromTop` iterates from top to bottom, so this is the reverse.
|
|
1655
|
-
* @param fn
|
|
1656
|
-
*/
|
|
1657
|
-
forEach(fn) {
|
|
1658
|
-
this.data.forEach(fn);
|
|
1659
|
-
}
|
|
1660
|
-
/**
|
|
1661
|
-
* Iterate from top to bottom. Note that `forEach` iterates from bottom to top, so this is the reverse.
|
|
1662
|
-
* @param fn
|
|
1663
|
-
*/
|
|
1664
|
-
forEachFromTop(fn) {
|
|
1665
|
-
[...this.data].reverse().forEach(fn);
|
|
1666
|
-
}
|
|
1667
|
-
/**
|
|
1668
|
-
* Pop the top-most item from the stack, and return it. If the stack is empty, returns _undefined_.
|
|
1669
|
-
* @returns
|
|
1670
|
-
*/
|
|
1671
|
-
pop() {
|
|
1672
|
-
const v = peek(this.opts, this.data);
|
|
1673
|
-
this.data = pop(this.opts, this.data);
|
|
1674
|
-
return v;
|
|
1675
|
-
}
|
|
1676
|
-
/**
|
|
1677
|
-
* Returns _true_ if the stack is empty, _false_ otherwise.
|
|
1678
|
-
*/
|
|
1679
|
-
get isEmpty() {
|
|
1680
|
-
return isEmpty(this.opts, this.data);
|
|
1681
|
-
}
|
|
1682
|
-
/**
|
|
1683
|
-
* Returns _true_ if the stack is full, _false_ otherwise. Note that a stack is only full if a `maxSize` option was provided at construction time.
|
|
1684
|
-
*/
|
|
1685
|
-
get isFull() {
|
|
1686
|
-
return isFull(this.opts, this.data);
|
|
1687
|
-
}
|
|
1688
|
-
/**
|
|
1689
|
-
* Returns the top-most item on the stack, without modifying the stack. If the stack is empty, returns _undefined_.
|
|
1690
|
-
*/
|
|
1691
|
-
get peek() {
|
|
1692
|
-
return peek(this.opts, this.data);
|
|
1693
|
-
}
|
|
1694
|
-
/**
|
|
1695
|
-
* Returns the number of items currently on the stack.
|
|
1696
|
-
*/
|
|
1697
|
-
get length() {
|
|
1698
|
-
return this.data.length;
|
|
1699
|
-
}
|
|
1700
|
-
};
|
|
1701
|
-
//#endregion
|
|
1702
|
-
//#region node_modules/.pnpm/@ixfx+collections@0.56.13/node_modules/@ixfx/collections/dist/tree-C6jGRTgK.js
|
|
1703
|
-
const compare$1 = (a, b, eq = isEqualValueIgnoreOrder, parent) => {
|
|
1704
|
-
const valueEqual = valueOrIdentityEqual(a, b, eq);
|
|
1705
|
-
const childrenCompare = compareChildren(a, b, eq);
|
|
1706
|
-
const diff = {
|
|
1707
|
-
valueChanged: !valueEqual,
|
|
1708
|
-
a,
|
|
1709
|
-
b,
|
|
1710
|
-
added: childrenCompare.added,
|
|
1711
|
-
removed: childrenCompare.removed,
|
|
1712
|
-
childChanged: false
|
|
1713
|
-
};
|
|
1714
|
-
const diffNode = {
|
|
1715
|
-
value: diff,
|
|
1716
|
-
childrenStore: [],
|
|
1717
|
-
parent
|
|
1718
|
-
};
|
|
1719
|
-
const childrenDiff = childrenCompare.identical.map((c) => compare$1(c[0], c[1], eq, diffNode));
|
|
1720
|
-
const someChildChange = hasChange(diff) || childrenDiff.some((v) => hasChange(v.value));
|
|
1721
|
-
setChildren(diffNode, childrenDiff);
|
|
1722
|
-
diffNode.toString = () => toString$1(diffNode, 0);
|
|
1723
|
-
diffNode.value.childChanged = someChildChange;
|
|
1724
|
-
throwTreeTest(diffNode);
|
|
1725
|
-
return diffNode;
|
|
1726
|
-
};
|
|
1727
|
-
const hasChange = (vv) => {
|
|
1728
|
-
if (vv === void 0) return false;
|
|
1729
|
-
if (vv.valueChanged) return true;
|
|
1730
|
-
if (vv.childChanged) return true;
|
|
1731
|
-
if (vv.added.length > 0) return true;
|
|
1732
|
-
if (vv.removed.length > 0) return true;
|
|
1733
|
-
return false;
|
|
1734
|
-
};
|
|
1735
|
-
const compareChildren = (a, b, eq = isEqualValueIgnoreOrder) => {
|
|
1736
|
-
const childrenOfA = [...a.children()];
|
|
1737
|
-
const childrenOfB = [...b.children()];
|
|
1738
|
-
const identical = [];
|
|
1739
|
-
const removed = [];
|
|
1740
|
-
for (const childA of childrenOfA) {
|
|
1741
|
-
let foundIndex = -1;
|
|
1742
|
-
for (const [index, childOfB] of childrenOfB.entries()) if (valueOrIdentityEqual(childA, childOfB, eq)) {
|
|
1743
|
-
identical.push([childA, childOfB]);
|
|
1744
|
-
foundIndex = index;
|
|
1745
|
-
break;
|
|
1746
|
-
}
|
|
1747
|
-
if (foundIndex === -1) removed.push(childA);
|
|
1748
|
-
else childrenOfB.splice(foundIndex, 1);
|
|
1749
|
-
}
|
|
1750
|
-
return {
|
|
1751
|
-
added: [...childrenOfB],
|
|
1752
|
-
identical,
|
|
1753
|
-
removed
|
|
1754
|
-
};
|
|
1755
|
-
};
|
|
1756
|
-
const valueOrIdentityEqual = (a, b, eq) => {
|
|
1757
|
-
if (a.getIdentity() === b.getIdentity()) return true;
|
|
1758
|
-
if (eq(a.getValue(), b.getValue())) return true;
|
|
1759
|
-
return false;
|
|
1760
|
-
};
|
|
1761
|
-
const toStringSingle = (n) => {
|
|
1762
|
-
return JSON.stringify(n.getValue());
|
|
1763
|
-
};
|
|
1764
|
-
const toString$1 = (n, indent = 0) => {
|
|
1765
|
-
if (n === void 0) return `(undefined)`;
|
|
1766
|
-
let t = toStringDiff(n.value, indent);
|
|
1767
|
-
for (const c of n.childrenStore) t += toString$1(c, indent + 2);
|
|
1768
|
-
return t;
|
|
1769
|
-
};
|
|
1770
|
-
const toStringDiff = (n, indent) => {
|
|
1771
|
-
const spaces = ` `.repeat(indent);
|
|
1772
|
-
if (n === void 0) return `${spaces}(undefined)`;
|
|
1773
|
-
const t = [];
|
|
1774
|
-
t.push(`a: ${toStringSingle(n.a)} b: ${toStringSingle(n.b)}`);
|
|
1775
|
-
if (n.valueChanged) t.push(`Value changed. Child changed: ${n.childChanged}`);
|
|
1776
|
-
else t.push(`Value unchanged. Child changed: ${n.childChanged}`);
|
|
1777
|
-
if (n.added.length > 0) {
|
|
1778
|
-
t.push(`Added:`);
|
|
1779
|
-
for (const c of n.added) t.push(` - ` + toStringSingle(c));
|
|
1780
|
-
}
|
|
1781
|
-
if (n.removed.length > 0) {
|
|
1782
|
-
t.push(`Removed: ${n.removed.length}`);
|
|
1783
|
-
for (const c of n.removed) t.push(` - ` + toStringSingle(c));
|
|
1784
|
-
}
|
|
1785
|
-
t.push(`----\n`);
|
|
1786
|
-
return t.map((line) => spaces + line).join(`\n`);
|
|
1787
|
-
};
|
|
1788
|
-
var tree_mutable_exports = /* @__PURE__ */ __exportAll({
|
|
1789
|
-
add: () => add,
|
|
1790
|
-
addValue: () => addValue,
|
|
1791
|
-
asDynamicTraversable: () => asDynamicTraversable$1,
|
|
1792
|
-
breadthFirst: () => breadthFirst$2,
|
|
1793
|
-
children: () => children$2,
|
|
1794
|
-
childrenLength: () => childrenLength$1,
|
|
1795
|
-
childrenValues: () => childrenValues,
|
|
1796
|
-
compare: () => compare,
|
|
1797
|
-
computeMaxDepth: () => computeMaxDepth,
|
|
1798
|
-
createNode: () => createNode$1,
|
|
1799
|
-
depthFirst: () => depthFirst$3,
|
|
1800
|
-
findAnyChildByValue: () => findAnyChildByValue$2,
|
|
1801
|
-
findChildByValue: () => findChildByValue$1,
|
|
1802
|
-
findParentsValue: () => findParentsValue,
|
|
1803
|
-
followValue: () => followValue$1,
|
|
1804
|
-
fromPlainObject: () => fromPlainObject,
|
|
1805
|
-
getRoot: () => getRoot,
|
|
1806
|
-
hasAnyChild: () => hasAnyChild$1,
|
|
1807
|
-
hasAnyParent: () => hasAnyParent$1,
|
|
1808
|
-
hasChild: () => hasChild$1,
|
|
1809
|
-
hasParent: () => hasParent$1,
|
|
1810
|
-
nodeDepth: () => nodeDepth,
|
|
1811
|
-
parents: () => parents$1,
|
|
1812
|
-
parentsValues: () => parentsValues,
|
|
1813
|
-
queryByValue: () => queryByValue,
|
|
1814
|
-
queryParentsValue: () => queryParentsValue,
|
|
1815
|
-
remove: () => remove$1,
|
|
1816
|
-
removeValuelessNodesFromChild: () => removeValuelessNodesFromChild,
|
|
1817
|
-
root: () => root$2,
|
|
1818
|
-
rootWrapped: () => rootWrapped$1,
|
|
1819
|
-
setChildren: () => setChildren,
|
|
1820
|
-
siblings: () => siblings$2,
|
|
1821
|
-
stripParentage: () => stripParentage,
|
|
1822
|
-
throwTreeTest: () => throwTreeTest,
|
|
1823
|
-
toStringDeep: () => toStringDeep$4,
|
|
1824
|
-
treeTest: () => treeTest,
|
|
1825
|
-
value: () => value,
|
|
1826
|
-
wrap: () => wrap$1
|
|
1827
|
-
});
|
|
1828
|
-
/**
|
|
1829
|
-
* Compares two nodes.
|
|
1830
|
-
*
|
|
1831
|
-
* By default uses `isEqualValueIgnoreOrder` to compare nodes. This means
|
|
1832
|
-
* values of nodes will be compared, ignoring the order of fields.
|
|
1833
|
-
* @param a
|
|
1834
|
-
* @param b
|
|
1835
|
-
* @param eq Comparison function. Uses `isEqualValueIgnoreOrder` by default.
|
|
1836
|
-
* @returns Compare results
|
|
1837
|
-
*/
|
|
1838
|
-
function compare(a, b, eq) {
|
|
1839
|
-
return compare$1(asDynamicTraversable$1(a), asDynamicTraversable$1(b), eq);
|
|
1840
|
-
}
|
|
1841
|
-
/**
|
|
1842
|
-
* Converts {@link Trees.TreeNode} to {@link Trees.SimplifiedNode}, removing the 'parent' fields.
|
|
1843
|
-
* This can be useful because if you have the whole tree, the parent field
|
|
1844
|
-
* is redundant and because it makes circular references can make dumping to console etc more troublesome.
|
|
1845
|
-
*
|
|
1846
|
-
* Recursive: strips parentage of all children and so on too.
|
|
1847
|
-
* @param node
|
|
1848
|
-
*/
|
|
1849
|
-
function stripParentage(node) {
|
|
1850
|
-
return {
|
|
1851
|
-
value: node.value,
|
|
1852
|
-
childrenStore: node.childrenStore.map((c) => stripParentage(c))
|
|
1853
|
-
};
|
|
1854
|
-
}
|
|
1855
|
-
const unwrapped = (node) => `wraps` in node ? node.wraps : node;
|
|
1856
|
-
const wrapped = (node) => `wraps` in node ? node : wrap$1(node);
|
|
1857
|
-
/**
|
|
1858
|
-
* Wraps node `n` for a more object-oriented means of access.
|
|
1859
|
-
* It will wrap child nodes on demand. For this reason, WrappedNode object
|
|
1860
|
-
* identity is not stable
|
|
1861
|
-
* @param n Node to wrap
|
|
1862
|
-
*/
|
|
1863
|
-
function wrap$1(n) {
|
|
1864
|
-
return {
|
|
1865
|
-
*children() {
|
|
1866
|
-
for (const c of n.childrenStore) yield wrap$1(c);
|
|
1867
|
-
},
|
|
1868
|
-
getValue: () => n.value,
|
|
1869
|
-
getIdentity: () => n,
|
|
1870
|
-
*queryValue(value) {
|
|
1871
|
-
for (const v of queryByValue(value, unwrapped(n))) yield wrap$1(v);
|
|
1872
|
-
},
|
|
1873
|
-
*queryParentsValue(child, value, eq) {
|
|
1874
|
-
for (const v of queryParentsValue(unwrapped(child), value, eq)) yield wrap$1(v);
|
|
1875
|
-
},
|
|
1876
|
-
*parentsValues(child) {
|
|
1877
|
-
yield* parentsValues(unwrapped(child));
|
|
1878
|
-
},
|
|
1879
|
-
findParentsValue(child, value, eq) {
|
|
1880
|
-
const n = findParentsValue(child, value, eq);
|
|
1881
|
-
if (n !== void 0) return wrap$1(n);
|
|
1882
|
-
},
|
|
1883
|
-
getParent: () => n.parent === void 0 ? void 0 : wrap$1(n.parent),
|
|
1884
|
-
hasParent: (parent) => {
|
|
1885
|
-
return hasParent$1(n, unwrapped(parent));
|
|
1886
|
-
},
|
|
1887
|
-
hasAnyParent: (parent) => {
|
|
1888
|
-
return hasAnyParent$1(n, unwrapped(parent));
|
|
1889
|
-
},
|
|
1890
|
-
hasChild: (child) => {
|
|
1891
|
-
return hasChild$1(unwrapped(child), n);
|
|
1892
|
-
},
|
|
1893
|
-
hasAnyChild: (child) => {
|
|
1894
|
-
return hasAnyChild$1(unwrapped(child), n);
|
|
1895
|
-
},
|
|
1896
|
-
remove: () => {
|
|
1897
|
-
remove$1(n);
|
|
1898
|
-
},
|
|
1899
|
-
addValue: (value) => {
|
|
1900
|
-
return wrap$1(addValue(value, n));
|
|
1901
|
-
},
|
|
1902
|
-
add: (child) => {
|
|
1903
|
-
add(unwrapped(child), n);
|
|
1904
|
-
return wrapped(child);
|
|
1905
|
-
},
|
|
1906
|
-
wraps: n
|
|
1907
|
-
};
|
|
1908
|
-
}
|
|
1909
|
-
/**
|
|
1910
|
-
* Removes `child` from the tree structure it is in.
|
|
1911
|
-
* It removes `child` from its parent. Any sub-children of `child` still remain connected.
|
|
1912
|
-
* @param child
|
|
1913
|
-
*/
|
|
1914
|
-
function remove$1(child) {
|
|
1915
|
-
const p = child.parent;
|
|
1916
|
-
if (p === void 0) return false;
|
|
1917
|
-
child.parent = void 0;
|
|
1918
|
-
const count = p.childrenStore.length;
|
|
1919
|
-
p.childrenStore = without(p.childrenStore, child);
|
|
1920
|
-
return count !== p.childrenStore.length;
|
|
1921
|
-
}
|
|
1922
|
-
/**
|
|
1923
|
-
* Starting from a child node, work backwards, removing it and ancestors that have no value
|
|
1924
|
-
*
|
|
1925
|
-
* If `child` is an only child, it will recursively call the same function on the parent.
|
|
1926
|
-
* @param child Child to start from
|
|
1927
|
-
*/
|
|
1928
|
-
function removeValuelessNodesFromChild(child) {
|
|
1929
|
-
if (typeof child.value !== `undefined`) return false;
|
|
1930
|
-
const parent = child.parent;
|
|
1931
|
-
if (!parent) return false;
|
|
1932
|
-
const sibs = [...siblings$2(child)];
|
|
1933
|
-
remove$1(child);
|
|
1934
|
-
if (sibs.length === 0) return removeValuelessNodesFromChild(parent);
|
|
1935
|
-
return true;
|
|
1936
|
-
}
|
|
1937
|
-
/**
|
|
1938
|
-
* Enumeate all siblings of `child`. This won't include `child` itself.
|
|
1939
|
-
* If `child` is not part of a tree (ie has no parent) no values are yielded.
|
|
1940
|
-
*/
|
|
1941
|
-
function* siblings$2(child, eq = isEqualDefault) {
|
|
1942
|
-
const parent = child.parent;
|
|
1943
|
-
if (typeof parent === `undefined`) return;
|
|
1944
|
-
for (const c of parent.childrenStore) {
|
|
1945
|
-
if (eq(c, child)) continue;
|
|
1946
|
-
yield c;
|
|
1947
|
-
}
|
|
1948
|
-
}
|
|
1949
|
-
/**
|
|
1950
|
-
* Depth-first iteration of the children of `node`
|
|
1951
|
-
* @param node
|
|
1952
|
-
*/
|
|
1953
|
-
function* depthFirst$3(node) {
|
|
1954
|
-
if (!root$2) return;
|
|
1955
|
-
const stack = new StackMutable();
|
|
1956
|
-
stack.push(...node.childrenStore);
|
|
1957
|
-
let entry = stack.pop();
|
|
1958
|
-
while (entry) {
|
|
1959
|
-
yield entry;
|
|
1960
|
-
if (entry) stack.push(...entry.childrenStore);
|
|
1961
|
-
if (stack.isEmpty) break;
|
|
1962
|
-
entry = stack.pop();
|
|
1963
|
-
}
|
|
1964
|
-
}
|
|
1965
|
-
/**
|
|
1966
|
-
* Breadth-first iteration of the children of `node`
|
|
1967
|
-
* @param node
|
|
1968
|
-
*/
|
|
1969
|
-
function* breadthFirst$2(node) {
|
|
1970
|
-
if (!node) return;
|
|
1971
|
-
const queue = new QueueMutable();
|
|
1972
|
-
queue.enqueue(...node.childrenStore);
|
|
1973
|
-
let entry = queue.dequeue();
|
|
1974
|
-
while (entry) {
|
|
1975
|
-
yield entry;
|
|
1976
|
-
if (entry) queue.enqueue(...entry.childrenStore);
|
|
1977
|
-
if (queue.isEmpty) break;
|
|
1978
|
-
entry = queue.dequeue();
|
|
1979
|
-
}
|
|
1980
|
-
}
|
|
1981
|
-
/**
|
|
1982
|
-
* Validates the tree from `root` downwards.
|
|
1983
|
-
* @param root
|
|
1984
|
-
* @param seen
|
|
1985
|
-
*/
|
|
1986
|
-
function treeTest(root, seen = []) {
|
|
1987
|
-
if (root.parent === root) return [
|
|
1988
|
-
false,
|
|
1989
|
-
`Root has itself as parent`,
|
|
1990
|
-
root
|
|
1991
|
-
];
|
|
1992
|
-
if (seen.includes(root)) return [
|
|
1993
|
-
false,
|
|
1994
|
-
`Same node instance is appearing further in tree`,
|
|
1995
|
-
root
|
|
1996
|
-
];
|
|
1997
|
-
seen.push(root);
|
|
1998
|
-
if (containsDuplicateInstances(root.childrenStore)) return [
|
|
1999
|
-
false,
|
|
2000
|
-
`Children list contains duplicates`,
|
|
2001
|
-
root
|
|
2002
|
-
];
|
|
2003
|
-
for (const c of root.childrenStore) {
|
|
2004
|
-
if (c.parent !== root) return [
|
|
2005
|
-
false,
|
|
2006
|
-
`Member of childrenStore does not have .parent set`,
|
|
2007
|
-
c
|
|
2008
|
-
];
|
|
2009
|
-
if (hasAnyChild$1(root, c)) return [
|
|
2010
|
-
false,
|
|
2011
|
-
`Child has parent as its own child`,
|
|
2012
|
-
c
|
|
2013
|
-
];
|
|
2014
|
-
const v = treeTest(c, seen);
|
|
2015
|
-
if (!v[0]) return v;
|
|
2016
|
-
}
|
|
2017
|
-
return [
|
|
2018
|
-
true,
|
|
2019
|
-
``,
|
|
2020
|
-
root
|
|
2021
|
-
];
|
|
2022
|
-
}
|
|
2023
|
-
/**
|
|
2024
|
-
* Throws an exception if `root` fails tree validation
|
|
2025
|
-
* @param root
|
|
2026
|
-
*/
|
|
2027
|
-
function throwTreeTest(root) {
|
|
2028
|
-
const v = treeTest(root);
|
|
2029
|
-
if (v[0]) return;
|
|
2030
|
-
throw new Error(`${v[1]} Node: ${toStringAbbreviate(v[2].value, 30)}`, { cause: v[2] });
|
|
2031
|
-
}
|
|
2032
|
-
/**
|
|
2033
|
-
* Iterate over direct children of `root`, yielding {@link TreeNode} instances.
|
|
2034
|
-
* Use {@link childrenValues} to iterate over child values
|
|
2035
|
-
* @param root
|
|
2036
|
-
*/
|
|
2037
|
-
function* children$2(root) {
|
|
2038
|
-
for (const c of root.childrenStore) yield c;
|
|
2039
|
-
}
|
|
2040
|
-
/**
|
|
2041
|
-
* Iterate over the value of direct children of `root`.
|
|
2042
|
-
* Use {@link children} if you want to iterate over {@link TreeNode} instances instead.
|
|
2043
|
-
* @param root
|
|
2044
|
-
*/
|
|
2045
|
-
function* childrenValues(root) {
|
|
2046
|
-
for (const c of root.childrenStore) if (typeof c.value !== `undefined`) yield c.value;
|
|
2047
|
-
}
|
|
2048
|
-
/**
|
|
2049
|
-
* Iterate over all parents of `child`. First result is the immediate parent.
|
|
2050
|
-
* @param child
|
|
2051
|
-
*/
|
|
2052
|
-
function* parents$1(child) {
|
|
2053
|
-
let p = child.parent;
|
|
2054
|
-
while (p) {
|
|
2055
|
-
yield p;
|
|
2056
|
-
p = p.parent;
|
|
2057
|
-
}
|
|
2058
|
-
}
|
|
2059
|
-
/**
|
|
2060
|
-
* Returns the depth of `node`. A root node (ie. with no parents) has a depth of 0.
|
|
2061
|
-
* @param node
|
|
2062
|
-
*/
|
|
2063
|
-
function nodeDepth(node) {
|
|
2064
|
-
return [...parents$1(node)].length;
|
|
2065
|
-
}
|
|
2066
|
-
/**
|
|
2067
|
-
* Returns _true_ if `child` is an immediate child of `parent`.
|
|
2068
|
-
* @param child
|
|
2069
|
-
* @param parent
|
|
2070
|
-
* @param eq Equality function to compare nodes. Uses `isEqualDefault` by default, which compares by reference.
|
|
2071
|
-
*/
|
|
2072
|
-
function hasChild$1(child, parent, eq = isEqualDefault) {
|
|
2073
|
-
for (const c of parent.childrenStore) if (eq(c, child)) return true;
|
|
2074
|
-
return false;
|
|
2075
|
-
}
|
|
2076
|
-
/**
|
|
2077
|
-
* Returns the first immediate child of `parent` that matches `value`.
|
|
2078
|
-
*
|
|
2079
|
-
* Use {@link queryByValue} if you want all matching children.
|
|
2080
|
-
* @param value
|
|
2081
|
-
* @param parent
|
|
2082
|
-
* @param eq
|
|
2083
|
-
*/
|
|
2084
|
-
function findChildByValue$1(value, parent, eq = isEqualDefault) {
|
|
2085
|
-
for (const c of parent.childrenStore) if (eq(value, c.value)) return c;
|
|
2086
|
-
}
|
|
2087
|
-
/**
|
|
2088
|
-
* Yield all immediate children of `parent` that match `value`.
|
|
2089
|
-
*
|
|
2090
|
-
* Use {@link findChildByValue} if you only want the first matching child.
|
|
2091
|
-
* @param value
|
|
2092
|
-
* @param parent
|
|
2093
|
-
* @param eq
|
|
2094
|
-
*/
|
|
2095
|
-
function* queryByValue(value, parent, eq = isEqualDefault) {
|
|
2096
|
-
for (const c of parent.childrenStore) if (eq(value, c.value)) yield c;
|
|
2097
|
-
}
|
|
2098
|
-
/**
|
|
2099
|
-
* Returns _true_ if `prospectiveChild` is some child node of `parent`,
|
|
2100
|
-
* anywhere in the tree structure.
|
|
2101
|
-
*
|
|
2102
|
-
* Use {@link hasChild} to only check immediate children.
|
|
2103
|
-
* @param prospectiveChild
|
|
2104
|
-
* @param parent
|
|
2105
|
-
*/
|
|
2106
|
-
function hasAnyChild$1(prospectiveChild, parent) {
|
|
2107
|
-
for (const c of breadthFirst$2(parent)) if (c === prospectiveChild) return true;
|
|
2108
|
-
return false;
|
|
2109
|
-
}
|
|
2110
|
-
/**
|
|
2111
|
-
* Using a breadth-first search, return the first child of `parent` that has `value`.
|
|
2112
|
-
* @param value Value being sought
|
|
2113
|
-
* @param parent Parent node
|
|
2114
|
-
* @param eq Equality function to compare values. Uses `isEqualDefault` by default, which compares by reference.
|
|
2115
|
-
*/
|
|
2116
|
-
function findAnyChildByValue$2(value, parent, eq = isEqualDefault) {
|
|
2117
|
-
for (const c of breadthFirst$2(parent)) if (eq(c.value, value)) return c;
|
|
2118
|
-
}
|
|
2119
|
-
/**
|
|
2120
|
-
* Traverses up a node to find the root.
|
|
2121
|
-
* @param node
|
|
2122
|
-
*/
|
|
2123
|
-
function getRoot(node) {
|
|
2124
|
-
if (node.parent) return getRoot(node.parent);
|
|
2125
|
-
return node;
|
|
2126
|
-
}
|
|
2127
|
-
/**
|
|
2128
|
-
* Returns _true_ if `prospectiveParent` is any ancestor
|
|
2129
|
-
* parent of `child`.
|
|
2130
|
-
*
|
|
2131
|
-
* Use {@link hasParent} to only check immediate parent.
|
|
2132
|
-
* @param child
|
|
2133
|
-
* @param prospectiveParent
|
|
2134
|
-
*/
|
|
2135
|
-
function hasAnyParent$1(child, prospectiveParent) {
|
|
2136
|
-
for (const p of parents$1(child)) if (p === prospectiveParent) return true;
|
|
2137
|
-
return false;
|
|
2138
|
-
}
|
|
2139
|
-
/**
|
|
2140
|
-
* Yields the node value of each parent of `child`.
|
|
2141
|
-
* _undefined_ values are not returned.
|
|
2142
|
-
*
|
|
2143
|
-
* Use {@link queryParentsValue} to search for a particular value
|
|
2144
|
-
* @param child
|
|
2145
|
-
*/
|
|
2146
|
-
function* parentsValues(child) {
|
|
2147
|
-
for (const p of parents$1(child)) if (typeof p.value !== `undefined`) yield p.value;
|
|
2148
|
-
return false;
|
|
2149
|
-
}
|
|
2150
|
-
/**
|
|
2151
|
-
* Yields all parents of `child` that have a given value.
|
|
2152
|
-
* Use {@link findParentsValue} to find the first match only.
|
|
2153
|
-
* @param child
|
|
2154
|
-
* @param value
|
|
2155
|
-
* @param eq
|
|
2156
|
-
*/
|
|
2157
|
-
function* queryParentsValue(child, value, eq = isEqualDefault) {
|
|
2158
|
-
for (const p of parents$1(child)) if (typeof p.value !== `undefined`) {
|
|
2159
|
-
if (eq(p.value, value)) yield p;
|
|
2160
|
-
}
|
|
2161
|
-
return false;
|
|
2162
|
-
}
|
|
2163
|
-
/**
|
|
2164
|
-
* Returns the first parent that has a given value.
|
|
2165
|
-
* @param child
|
|
2166
|
-
* @param value
|
|
2167
|
-
* @param eq
|
|
2168
|
-
*/
|
|
2169
|
-
function findParentsValue(child, value, eq = isEqualDefault) {
|
|
2170
|
-
return [...queryParentsValue(child, value, eq)][0];
|
|
2171
|
-
}
|
|
2172
|
-
/**
|
|
2173
|
-
* Returns _true_ if `prospectiveParent` is the immediate
|
|
2174
|
-
* parent of `child`.
|
|
2175
|
-
*
|
|
2176
|
-
* Use {@link hasAnyParent} to check for any ancestor parent.
|
|
2177
|
-
* @param child
|
|
2178
|
-
* @param prospectiveParent
|
|
2179
|
-
*/
|
|
2180
|
-
function hasParent$1(child, prospectiveParent) {
|
|
2181
|
-
return child.parent === prospectiveParent;
|
|
2182
|
-
}
|
|
2183
|
-
/**
|
|
2184
|
-
* Computes the maximum depth of the tree.
|
|
2185
|
-
* That is, how many steps down from `node` it can go.
|
|
2186
|
-
* If a tree is: root -> childA -> subChildB
|
|
2187
|
-
* ```js
|
|
2188
|
-
* // Yields 2, since there are at max two steps down from root
|
|
2189
|
-
* computeMaxDepth(root);
|
|
2190
|
-
* ```
|
|
2191
|
-
* @param node
|
|
2192
|
-
*/
|
|
2193
|
-
function computeMaxDepth(node) {
|
|
2194
|
-
return computeMaxDepthImpl(node, 0);
|
|
2195
|
-
}
|
|
2196
|
-
function computeMaxDepthImpl(node, startingDepth = 0) {
|
|
2197
|
-
let depth = startingDepth;
|
|
2198
|
-
for (const c of node.childrenStore) depth = Math.max(depth, computeMaxDepthImpl(c, startingDepth + 1));
|
|
2199
|
-
return depth;
|
|
2200
|
-
}
|
|
2201
|
-
/**
|
|
2202
|
-
* Adds a child node to `parent`.
|
|
2203
|
-
* If `child` already has a parent, it is removed from that parent.
|
|
2204
|
-
* @param child
|
|
2205
|
-
* @param parent
|
|
2206
|
-
* @throws Error if adding a child would break tree structure
|
|
2207
|
-
*/
|
|
2208
|
-
function add(child, parent) {
|
|
2209
|
-
throwAttemptedChild(child, parent);
|
|
2210
|
-
const p = child.parent;
|
|
2211
|
-
parent.childrenStore = [...parent.childrenStore, child];
|
|
2212
|
-
child.parent = parent;
|
|
2213
|
-
if (p) p.childrenStore = without(p.childrenStore, child);
|
|
2214
|
-
}
|
|
2215
|
-
/**
|
|
2216
|
-
* Adds a new child node based on a value
|
|
2217
|
-
*/
|
|
2218
|
-
function addValue(value, parent) {
|
|
2219
|
-
return createNode$1(value, parent);
|
|
2220
|
-
}
|
|
2221
|
-
/**
|
|
2222
|
-
* Creates the root for a tree, with an optional `value`.
|
|
2223
|
-
* Use {@link rootWrapped} if you want a more object-oriented mode of access.
|
|
2224
|
-
* @param value
|
|
2225
|
-
*/
|
|
2226
|
-
function root$2(value) {
|
|
2227
|
-
return createNode$1(value);
|
|
2228
|
-
}
|
|
2229
|
-
function fromPlainObject(value, label = ``, parent, seen = []) {
|
|
2230
|
-
const entries = Object.entries(value);
|
|
2231
|
-
parent = parent === void 0 ? root$2() : addValue({
|
|
2232
|
-
label,
|
|
2233
|
-
value
|
|
2234
|
-
}, parent);
|
|
2235
|
-
for (const entry of entries) {
|
|
2236
|
-
const value = entry[1];
|
|
2237
|
-
if (seen.includes(value)) continue;
|
|
2238
|
-
seen.push(value);
|
|
2239
|
-
if (typeof entry[1] === `object`) fromPlainObject(value, entry[0], parent, seen);
|
|
2240
|
-
else addValue({
|
|
2241
|
-
label: entry[0],
|
|
2242
|
-
value
|
|
2243
|
-
}, parent);
|
|
2244
|
-
}
|
|
2245
|
-
return parent;
|
|
2246
|
-
}
|
|
2247
|
-
/**
|
|
2248
|
-
* Creates a tree, returning it as a {@link WrappedNode} for object-oriented access.
|
|
2249
|
-
* Use {@link Trees.Mutable.root} alternatively.
|
|
2250
|
-
* @param value
|
|
2251
|
-
*/
|
|
2252
|
-
function rootWrapped$1(value) {
|
|
2253
|
-
return wrap$1(createNode$1(value));
|
|
2254
|
-
}
|
|
2255
|
-
/**
|
|
2256
|
-
* Creates a `TreeNode` instance with a given value and parent.
|
|
2257
|
-
* Parent node, if specified, has its `childrenStore` property changed to include new child.
|
|
2258
|
-
* @param value
|
|
2259
|
-
* @param parent
|
|
2260
|
-
*/
|
|
2261
|
-
function createNode$1(value, parent) {
|
|
2262
|
-
const n = {
|
|
2263
|
-
childrenStore: [],
|
|
2264
|
-
parent,
|
|
2265
|
-
value
|
|
2266
|
-
};
|
|
2267
|
-
if (parent !== void 0) parent.childrenStore = [...parent.childrenStore, n];
|
|
2268
|
-
return n;
|
|
2269
|
-
}
|
|
2270
|
-
function childrenLength$1(node) {
|
|
2271
|
-
return node.childrenStore.length;
|
|
2272
|
-
}
|
|
2273
|
-
function value(node) {
|
|
2274
|
-
return node.value;
|
|
2275
|
-
}
|
|
2276
|
-
/**
|
|
2277
|
-
* Projects `node` as a dynamic traversable.
|
|
2278
|
-
* Dynamic in the sense that it creates the traversable project for nodes on demand.
|
|
2279
|
-
* A consequence is that node identities are not stable.
|
|
2280
|
-
* @param node
|
|
2281
|
-
*/
|
|
2282
|
-
function asDynamicTraversable$1(node) {
|
|
2283
|
-
return {
|
|
2284
|
-
*children() {
|
|
2285
|
-
for (const c of node.childrenStore) yield asDynamicTraversable$1(c);
|
|
2286
|
-
},
|
|
2287
|
-
getParent() {
|
|
2288
|
-
if (node.parent === void 0) return;
|
|
2289
|
-
return asDynamicTraversable$1(node.parent);
|
|
2290
|
-
},
|
|
2291
|
-
getValue() {
|
|
2292
|
-
return node.value;
|
|
2293
|
-
},
|
|
2294
|
-
getIdentity() {
|
|
2295
|
-
return node;
|
|
2296
|
-
}
|
|
2297
|
-
};
|
|
2298
|
-
}
|
|
2299
|
-
/**
|
|
2300
|
-
* Throws an error if:
|
|
2301
|
-
* 1. `child` is the same node as `parent`
|
|
2302
|
-
* 2. `child` is already an immediate child of `parent`
|
|
2303
|
-
* 3. `child` is an ancestor parent of `parent`
|
|
2304
|
-
* 4. `child` has `parent` as its own child
|
|
2305
|
-
* @param c
|
|
2306
|
-
* @param parent
|
|
2307
|
-
*/
|
|
2308
|
-
function throwAttemptedChild(c, parent) {
|
|
2309
|
-
if (parent === c) throw new Error(`Cannot add self as child`);
|
|
2310
|
-
if (c.parent === parent) return;
|
|
2311
|
-
if (hasAnyParent$1(parent, c)) throw new Error(`Child contains parent (1)`, { cause: c });
|
|
2312
|
-
if (hasAnyParent$1(c, parent)) throw new Error(`Parent already contains child`, { cause: c });
|
|
2313
|
-
if (hasAnyChild$1(parent, c)) throw new Error(`Child contains parent (2)`, { cause: c });
|
|
2314
|
-
}
|
|
2315
|
-
/**
|
|
2316
|
-
* Sets the children of `parent` to a list of `children`.
|
|
2317
|
-
*
|
|
2318
|
-
* Any previous children are disconnected from this parent.
|
|
2319
|
-
* All new children have their parent set to `parent`.
|
|
2320
|
-
*
|
|
2321
|
-
* There is some validation to ensure that adding the children doesn't break the tree.
|
|
2322
|
-
*/
|
|
2323
|
-
function setChildren(parent, children) {
|
|
2324
|
-
for (const c of children) throwAttemptedChild(c, parent);
|
|
2325
|
-
parent.childrenStore = [...children];
|
|
2326
|
-
for (const c of children) c.parent = parent;
|
|
2327
|
-
}
|
|
2328
|
-
function toStringDeep$4(node, indent = 0) {
|
|
2329
|
-
const t = `${` `.repeat(indent)} + ${node.value ? JSON.stringify(node.value) : `-`}`;
|
|
2330
|
-
return node.childrenStore.length > 0 ? `${t}\n${node.childrenStore.map((d) => toStringDeep$4(d, indent + 1)).join(`\n`)}` : t;
|
|
2331
|
-
}
|
|
2332
|
-
function* followValue$1(root, continuePredicate, depth = 1) {
|
|
2333
|
-
for (const c of root.childrenStore) {
|
|
2334
|
-
const value = c.value;
|
|
2335
|
-
if (value === void 0) continue;
|
|
2336
|
-
if (continuePredicate(value, depth)) {
|
|
2337
|
-
yield c.value;
|
|
2338
|
-
yield* followValue$1(c, continuePredicate, depth + 1);
|
|
2339
|
-
}
|
|
2340
|
-
}
|
|
2341
|
-
}
|
|
2342
|
-
var traverse_object_exports = /* @__PURE__ */ __exportAll({
|
|
2343
|
-
asDynamicTraversable: () => asDynamicTraversable,
|
|
2344
|
-
children: () => children$1,
|
|
2345
|
-
create: () => create$1,
|
|
2346
|
-
createSimplified: () => createSimplified,
|
|
2347
|
-
createWrapped: () => createWrapped,
|
|
2348
|
-
depthFirst: () => depthFirst$2,
|
|
2349
|
-
getByPath: () => getByPath,
|
|
2350
|
-
prettyPrint: () => prettyPrint,
|
|
2351
|
-
prettyPrintEntries: () => prettyPrintEntries,
|
|
2352
|
-
toStringDeep: () => toStringDeep$3,
|
|
2353
|
-
traceByPath: () => traceByPath
|
|
2354
|
-
});
|
|
2355
|
-
/**
|
|
2356
|
-
* Helper function to get a 'friendly' string representation of an array of {@link TraverseObjectEntry}.
|
|
2357
|
-
* @param entries
|
|
2358
|
-
* @returns
|
|
2359
|
-
*/
|
|
2360
|
-
function prettyPrintEntries(entries) {
|
|
2361
|
-
if (entries.length === 0) return `(empty)`;
|
|
2362
|
-
let t = ``;
|
|
2363
|
-
for (const [index, entry] of entries.entries()) {
|
|
2364
|
-
t += ` `.repeat(index);
|
|
2365
|
-
t += entry.name + ` = ` + JSON.stringify(entry.leafValue) + `\n`;
|
|
2366
|
-
}
|
|
2367
|
-
return t;
|
|
2368
|
-
}
|
|
2369
|
-
/**
|
|
2370
|
-
* Returns a human-friendly debug string for a tree-like structure
|
|
2371
|
-
* ```js
|
|
2372
|
-
* console.log(Trees.prettyPrint(obj));
|
|
2373
|
-
* ```
|
|
2374
|
-
* @param indent
|
|
2375
|
-
* @param node
|
|
2376
|
-
* @param options
|
|
2377
|
-
* @returns
|
|
2378
|
-
*/
|
|
2379
|
-
const prettyPrint = (node, indent = 0, options = {}) => {
|
|
2380
|
-
resultThrow(nullUndefTest(node, `node`));
|
|
2381
|
-
const entry = getNamedEntry(node, options.name ?? `node`);
|
|
2382
|
-
const t = `${` `.repeat(indent)} + name: ${entry.name} value: ${JSON.stringify(entry.leafValue)}`;
|
|
2383
|
-
const childrenAsArray = [...children$1(node, options)];
|
|
2384
|
-
return childrenAsArray.length > 0 ? t + `\n` + childrenAsArray.map((d) => prettyPrint(d.leafValue, indent + 1, {
|
|
2385
|
-
...options,
|
|
2386
|
-
name: d.name
|
|
2387
|
-
})).join(`\n`) : t;
|
|
2388
|
-
};
|
|
2389
|
-
/**
|
|
2390
|
-
* Returns a debug string representation of the node (recursive)
|
|
2391
|
-
* @param node
|
|
2392
|
-
* @param indent
|
|
2393
|
-
* @returns
|
|
2394
|
-
*/
|
|
2395
|
-
const toStringDeep$3 = (node, indent = 0) => {
|
|
2396
|
-
let t = ` `.repeat(indent) + ` ${node.value?.name}`;
|
|
2397
|
-
if (node.value !== void 0) {
|
|
2398
|
-
if (`sourceValue` in node.value && `leafValue` in node.value) {
|
|
2399
|
-
let sourceValue = toStringAbbreviate(node.value.sourceValue, 20);
|
|
2400
|
-
const leafValue = toStringAbbreviate(node.value.leafValue, 20);
|
|
2401
|
-
sourceValue = sourceValue === leafValue ? `` : `source: ` + sourceValue;
|
|
2402
|
-
t += ` = ${leafValue} ${sourceValue}`;
|
|
2403
|
-
} else if (`sourceValue` in node.value && node.value.sourceValue !== void 0) t += ` = ${node.value.sourceValue}`;
|
|
2404
|
-
if (`ancestors` in node.value) t += ` (ancestors: ${node.value.ancestors.join(`, `)})`;
|
|
2405
|
-
}
|
|
2406
|
-
t += `\n`;
|
|
2407
|
-
for (const c of node.childrenStore) t += toStringDeep$3(c, indent + 1);
|
|
2408
|
-
return t;
|
|
2409
|
-
};
|
|
2410
|
-
/**
|
|
2411
|
-
* Yields the direct (ie. non-recursive) children of a tree-like object as a pairing
|
|
2412
|
-
* of node name and value. Supports basic objects, Maps and arrays.
|
|
2413
|
-
*
|
|
2414
|
-
* To iterate recursively, consider {@link depthFirst}
|
|
2415
|
-
*
|
|
2416
|
-
* Each child is returned in an {@link TraverseObjectEntry} structure:
|
|
2417
|
-
* ```typescript
|
|
2418
|
-
* type Entry = Readonly<{
|
|
2419
|
-
* // Property name
|
|
2420
|
-
* name: string,
|
|
2421
|
-
* // Value of property, as if you called `object[propertyName]`
|
|
2422
|
-
* sourceValue: any,
|
|
2423
|
-
* // Branch nodes will have _undefined_, leaf nodes will contain the value
|
|
2424
|
-
* leafValue: any
|
|
2425
|
-
* }>;
|
|
2426
|
-
* ```
|
|
2427
|
-
*
|
|
2428
|
-
* For example, iterating over a flat object:
|
|
2429
|
-
* ```js
|
|
2430
|
-
* const verySimpleObject = { field: `hello`, flag: true }
|
|
2431
|
-
* const kids = [ ...children(verySimpleObject) ];
|
|
2432
|
-
* // Yields:
|
|
2433
|
-
* // [ { name: "field", sourceValue: `hello`, leafValue: `hello` },
|
|
2434
|
-
* // { name: "flag", sourceValue: true, leafValue: true } ]
|
|
2435
|
-
* ```
|
|
2436
|
-
*
|
|
2437
|
-
* For objects containing objects:
|
|
2438
|
-
* ```js
|
|
2439
|
-
* const lessSimpleObject = { field: `hello`, flag: true, colour: { `red`, opacity: 0.5 } }
|
|
2440
|
-
* const kids = [ ...children(verySimpleObject) ];
|
|
2441
|
-
* // Yields as before, plus:
|
|
2442
|
-
* // { name: "colour", sourceValue: { name: 'red', opacity: 0.5 }, leafValue: undefined }
|
|
2443
|
-
* ```
|
|
2444
|
-
*
|
|
2445
|
-
* Note that 'sourceValue' always contains the property value, as if you
|
|
2446
|
-
* access it via `object[propName]`. 'leafValue' only contains the value if it's a leaf
|
|
2447
|
-
* node.
|
|
2448
|
-
*
|
|
2449
|
-
* Arrays are assigned a name based on index.
|
|
2450
|
-
* @example Arrays
|
|
2451
|
-
* ```js
|
|
2452
|
-
* const colours = [ { r: 1, g: 0, b: 0 }, { r: 0, g: 1, b: 0 }, { r: 0, g: 0, b: 1 } ];
|
|
2453
|
-
* // Children:
|
|
2454
|
-
* // [
|
|
2455
|
-
* // { name: "array[0]", value: {r:1,g:0,b:0} },
|
|
2456
|
-
* // { name: "array[1]", value: {r:0,g:1,b:0} },
|
|
2457
|
-
* // { name: "array[2]", value: {r:0,g:0,b:1} },
|
|
2458
|
-
* // ]
|
|
2459
|
-
* ```
|
|
2460
|
-
*
|
|
2461
|
-
* Pass in `options.name` (eg 'colours') to have names generated as 'colours[0]', etc.
|
|
2462
|
-
* Options can also be used to filter children. By default all direct children are returned.
|
|
2463
|
-
* @param node
|
|
2464
|
-
* @param options
|
|
2465
|
-
*/
|
|
2466
|
-
function* children$1(node, options = {}) {
|
|
2467
|
-
resultThrow(nullUndefTest(node, `node`));
|
|
2468
|
-
const filteringOption = options.filter ?? `none`;
|
|
2469
|
-
const filterByValue = (v) => {
|
|
2470
|
-
if (filteringOption === `none`) return [true, isPrimitive(v)];
|
|
2471
|
-
else if (filteringOption === `leaves` && isPrimitive(v)) return [true, true];
|
|
2472
|
-
else if (filteringOption === `branches` && !isPrimitive(v)) return [true, false];
|
|
2473
|
-
return [false, isPrimitive(v)];
|
|
2474
|
-
};
|
|
2475
|
-
if (Array.isArray(node)) for (const [index, element] of node.entries()) {
|
|
2476
|
-
const f = filterByValue(element);
|
|
2477
|
-
if (f[0]) yield {
|
|
2478
|
-
name: index.toString(),
|
|
2479
|
-
_kind: `entry`,
|
|
2480
|
-
sourceValue: element,
|
|
2481
|
-
leafValue: f[1] ? element : void 0
|
|
2482
|
-
};
|
|
2483
|
-
}
|
|
2484
|
-
else if (typeof node === `object`) {
|
|
2485
|
-
const entriesIter = `entries` in node ? node.entries() : Object.entries(node);
|
|
2486
|
-
for (const [name, value] of entriesIter) {
|
|
2487
|
-
const [filter, isPrimitive] = filterByValue(value);
|
|
2488
|
-
if (filter) yield {
|
|
2489
|
-
name,
|
|
2490
|
-
_kind: `entry`,
|
|
2491
|
-
sourceValue: value,
|
|
2492
|
-
leafValue: isPrimitive ? value : void 0
|
|
2493
|
-
};
|
|
2494
|
-
}
|
|
2495
|
-
}
|
|
2496
|
-
}
|
|
2497
|
-
function* depthFirst$2(node, options = {}, ancestors = []) {
|
|
2498
|
-
for (const c of children$1(node, options)) {
|
|
2499
|
-
yield {
|
|
2500
|
-
...c,
|
|
2501
|
-
ancestors: [...ancestors],
|
|
2502
|
-
_kind: `entry-ancestors`
|
|
2503
|
-
};
|
|
2504
|
-
yield* depthFirst$2(c.sourceValue, options, [...ancestors, c.name]);
|
|
2505
|
-
}
|
|
2506
|
-
}
|
|
2507
|
-
/**
|
|
2508
|
-
* Finds a given direct child by name
|
|
2509
|
-
* @param name
|
|
2510
|
-
* @param node
|
|
2511
|
-
* @returns
|
|
2512
|
-
*/
|
|
2513
|
-
function childByName(name, node) {
|
|
2514
|
-
for (const d of children$1(node)) if (d.name === name) return d;
|
|
2515
|
-
}
|
|
2516
|
-
/**
|
|
2517
|
-
* Returns the closest matching entry, tracing `path` in an array, Map or simple object.
|
|
2518
|
-
* Returns an entry with _undefined_ value at the point where tracing stopped.
|
|
2519
|
-
* Use {@link traceByPath} to step through all the segments.
|
|
2520
|
-
*
|
|
2521
|
-
* ```js
|
|
2522
|
-
* const people = {
|
|
2523
|
-
* jane: {
|
|
2524
|
-
* address: {
|
|
2525
|
-
* postcode: 1000,
|
|
2526
|
-
* street: 'West St',
|
|
2527
|
-
* city: 'Blahville'
|
|
2528
|
-
* },
|
|
2529
|
-
* colour: 'red'
|
|
2530
|
-
* }
|
|
2531
|
-
* }
|
|
2532
|
-
* Trees.getByPath('jane.address.postcode', people); // '.' default separator
|
|
2533
|
-
* // ['postcode', 1000]
|
|
2534
|
-
* Trees.getByPath('jane.address.country.state', people);
|
|
2535
|
-
* // ['country', undefined] - since full path could not be resolved.
|
|
2536
|
-
* ```
|
|
2537
|
-
* @param path Path, eg `jane.address.postcode`
|
|
2538
|
-
* @param node Node to look within
|
|
2539
|
-
* @param options Options for parsing path. By default '.' is used as a separator
|
|
2540
|
-
* @returns
|
|
2541
|
-
*/
|
|
2542
|
-
function getByPath(path, node, options = {}) {
|
|
2543
|
-
const v = last(traceByPath(path, node, options));
|
|
2544
|
-
if (!v) throw new Error(`Could not trace path: ${path} `);
|
|
2545
|
-
return v;
|
|
2546
|
-
}
|
|
2547
|
-
/**
|
|
2548
|
-
* Enumerates over children of `node` towards the node named in `path`.
|
|
2549
|
-
* This is useful if you want to get the interim steps to the target node.
|
|
2550
|
-
*
|
|
2551
|
-
* Use {@link getByPath} if you don't care about interim steps.
|
|
2552
|
-
*
|
|
2553
|
-
* ```js
|
|
2554
|
-
* const people = {
|
|
2555
|
-
* jane: {
|
|
2556
|
-
* address: {
|
|
2557
|
-
* postcode: 1000,
|
|
2558
|
-
* street: 'West St',
|
|
2559
|
-
* city: 'Blahville'
|
|
2560
|
-
* },
|
|
2561
|
-
* colour: 'red'
|
|
2562
|
-
* }
|
|
2563
|
-
* }
|
|
2564
|
-
* for (const p of Trees.traceByPath('jane.address.street', people)) {
|
|
2565
|
-
* // { name: "jane", value: { address: { postcode: 1000,street: 'West St', city: 'Blahville' }, colour: 'red'} },
|
|
2566
|
-
* // { name: "address", value: { postcode: 1000, street: 'West St', city: 'Blahville' } },
|
|
2567
|
-
* // { name: "street", value: "West St" } }
|
|
2568
|
-
* }
|
|
2569
|
-
* ```
|
|
2570
|
-
*
|
|
2571
|
-
* Results stop when the path can't be followed any further.
|
|
2572
|
-
* The last entry will have a name of the last sought path segment, and _undefined_ as its value.
|
|
2573
|
-
*
|
|
2574
|
-
* @param path Path to traverse
|
|
2575
|
-
* @param node Starting node
|
|
2576
|
-
* @param options Options for path traversal logic
|
|
2577
|
-
* @returns
|
|
2578
|
-
*/
|
|
2579
|
-
function* traceByPath(path, node, options = {}) {
|
|
2580
|
-
resultThrow(nullUndefTest(path, `path`), nullUndefTest(node, `node`));
|
|
2581
|
-
const separator = options.separator ?? `.`;
|
|
2582
|
-
const pathSplit = path.split(separator);
|
|
2583
|
-
const ancestors = [];
|
|
2584
|
-
for (const p of pathSplit) {
|
|
2585
|
-
const entry = childByName(p, node);
|
|
2586
|
-
if (!entry) {
|
|
2587
|
-
yield {
|
|
2588
|
-
name: p,
|
|
2589
|
-
sourceValue: void 0,
|
|
2590
|
-
leafValue: void 0,
|
|
2591
|
-
ancestors,
|
|
2592
|
-
_kind: `entry-ancestors`
|
|
2593
|
-
};
|
|
2594
|
-
return;
|
|
2595
|
-
}
|
|
2596
|
-
node = entry.sourceValue;
|
|
2597
|
-
yield {
|
|
2598
|
-
...entry,
|
|
2599
|
-
ancestors: [...ancestors],
|
|
2600
|
-
_kind: `entry-ancestors`
|
|
2601
|
-
};
|
|
2602
|
-
ancestors.push(p);
|
|
2603
|
-
}
|
|
2604
|
-
}
|
|
2605
|
-
/**
|
|
2606
|
-
* Returns a projection of `node` as a dynamic traversable.
|
|
2607
|
-
* This means that the tree structure is dynamically created as last-minute as possible.
|
|
2608
|
-
*
|
|
2609
|
-
* The type when calling `getValue()` is {@link TraverseObjectEntryStatic}:
|
|
2610
|
-
* ```typescript
|
|
2611
|
-
* type EntryStatic = Readonly<{
|
|
2612
|
-
* name: string,
|
|
2613
|
-
* value: any
|
|
2614
|
-
* ancestors: string[]
|
|
2615
|
-
* }>
|
|
2616
|
-
* ```
|
|
2617
|
-
*
|
|
2618
|
-
* Note that the object identity of TraversableTree return results is not stable.
|
|
2619
|
-
* This is because they are created on-the-fly by reading fields of `node`.
|
|
2620
|
-
*
|
|
2621
|
-
* ```js
|
|
2622
|
-
* const c1 = [ ...asDynamicTraversable(someObject).children() ];
|
|
2623
|
-
* const c2 = [ ...asDynamicTraversable(someObject).children() ];
|
|
2624
|
-
*
|
|
2625
|
-
* // Object identity is not the same
|
|
2626
|
-
* c1[ 0 ] === c1[ 0 ]; // false
|
|
2627
|
-
*
|
|
2628
|
-
* // ...even though its referring to the same value
|
|
2629
|
-
* c1[ 0 ].getValue() === c1[ 0 ].getValue(); // true
|
|
2630
|
-
* ```
|
|
2631
|
-
*
|
|
2632
|
-
* Instead .getIdentity() to get a stable identity:
|
|
2633
|
-
* ```js
|
|
2634
|
-
* c1[ 0 ].getIdentity() === c2[ 0 ].getIdentity(); // true
|
|
2635
|
-
* ```
|
|
2636
|
-
*
|
|
2637
|
-
* @example
|
|
2638
|
-
* ```js
|
|
2639
|
-
* const myObj = { name: `Pedro`, size: 45, colour: `orange` };
|
|
2640
|
-
* const root = Trees.FromObject.asDynamicTraversable(myObj);
|
|
2641
|
-
* for (const v of Trees.Traverse.breadthFirst(root)) {
|
|
2642
|
-
* // v.getValue() yields:
|
|
2643
|
-
* // { name: 'name', sourceValue: 'Pedro' ...},
|
|
2644
|
-
* // { name: 'size', sourceValue: 45 ... }
|
|
2645
|
-
* // ...
|
|
2646
|
-
* }
|
|
2647
|
-
* ```
|
|
2648
|
-
* @param node Object to read
|
|
2649
|
-
* @param options Options when creating traversable
|
|
2650
|
-
* @param ancestors Do not use
|
|
2651
|
-
* @param parent Do not use
|
|
2652
|
-
* @returns
|
|
2653
|
-
*/
|
|
2654
|
-
const asDynamicTraversable = (node, options = {}, ancestors = [], parent) => {
|
|
2655
|
-
const name = options.name ?? `object`;
|
|
2656
|
-
const t = {
|
|
2657
|
-
*children() {
|
|
2658
|
-
for (const { name: childName, sourceValue, leafValue } of children$1(node, options)) yield asDynamicTraversable(sourceValue, {
|
|
2659
|
-
...options,
|
|
2660
|
-
name: childName
|
|
2661
|
-
}, [...ancestors, name], t);
|
|
2662
|
-
},
|
|
2663
|
-
getParent() {
|
|
2664
|
-
return parent;
|
|
2665
|
-
},
|
|
2666
|
-
getValue() {
|
|
2667
|
-
return {
|
|
2668
|
-
name,
|
|
2669
|
-
sourceValue: node,
|
|
2670
|
-
ancestors,
|
|
2671
|
-
_kind: `entry-static`
|
|
2672
|
-
};
|
|
2673
|
-
},
|
|
2674
|
-
getIdentity() {
|
|
2675
|
-
return node;
|
|
2676
|
-
}
|
|
2677
|
-
};
|
|
2678
|
-
return t;
|
|
2679
|
-
};
|
|
2680
|
-
/**
|
|
2681
|
-
* Reads all fields and sub-fields of `node`, returning as a 'wrapped' tree structure.
|
|
2682
|
-
* Is a snapshot of `node`, and won't update if it mutates.
|
|
2683
|
-
* @param node
|
|
2684
|
-
* @param options
|
|
2685
|
-
* @returns
|
|
2686
|
-
*/
|
|
2687
|
-
const createWrapped = (node, options) => {
|
|
2688
|
-
return wrap$1(create$1(node, options));
|
|
2689
|
-
};
|
|
2690
|
-
/**
|
|
2691
|
-
* Reads all fields and sub-fields of `node`, returning as a basic tree structure.
|
|
2692
|
-
* The structure is a snapshot of the object. If the object changes afterwards, the tree will
|
|
2693
|
-
* remain the same.
|
|
2694
|
-
*
|
|
2695
|
-
* Alternatively, consider {@link asDynamicTraversable} which reads the object dynamically.
|
|
2696
|
-
* @example
|
|
2697
|
-
* ```js
|
|
2698
|
-
* const myObj = { name: `Pedro`, size: 45, colour: `orange` };
|
|
2699
|
-
* const root = Trees.FromObject.create(myObj);
|
|
2700
|
-
* for (const v of Trees.Traverse.breadthFirst(root)) {
|
|
2701
|
-
* // v.getValue() yields:
|
|
2702
|
-
* // { name: 'name', sourceValue: 'Pedro' ...},
|
|
2703
|
-
* // { name: 'size', sourceValue: 45 ... }
|
|
2704
|
-
* // ...
|
|
2705
|
-
* }
|
|
2706
|
-
* ```
|
|
2707
|
-
* @param node
|
|
2708
|
-
* @param options
|
|
2709
|
-
* @returns
|
|
2710
|
-
*/
|
|
2711
|
-
const create$1 = (node, options = {}) => {
|
|
2712
|
-
return createImpl(node, (options.valuesAtLeaves ?? false ? (v) => {
|
|
2713
|
-
if (isPrimitive(v)) return v;
|
|
2714
|
-
} : (v) => v)(node), options, []);
|
|
2715
|
-
};
|
|
2716
|
-
const createImpl = (sourceValue, leafValue, options = {}, ancestors) => {
|
|
2717
|
-
const defaultName = options.name ?? `object_ci`;
|
|
2718
|
-
const r = root$2({
|
|
2719
|
-
name: defaultName,
|
|
2720
|
-
sourceValue: leafValue,
|
|
2721
|
-
ancestors: [...ancestors],
|
|
2722
|
-
_kind: `entry-static`
|
|
2723
|
-
});
|
|
2724
|
-
ancestors = [...ancestors, defaultName];
|
|
2725
|
-
for (const c of children$1(sourceValue, options)) {
|
|
2726
|
-
const v = options.valuesAtLeaves ? c.leafValue : c.sourceValue;
|
|
2727
|
-
add(createImpl(c.sourceValue, v, {
|
|
2728
|
-
...options,
|
|
2729
|
-
name: c.name
|
|
2730
|
-
}, ancestors), r);
|
|
2731
|
-
}
|
|
2732
|
-
return r;
|
|
2733
|
-
};
|
|
2734
|
-
/**
|
|
2735
|
-
* Returns a copy of `node` with its (and all its childrens') parent information removed.
|
|
2736
|
-
*
|
|
2737
|
-
* Under the hood:
|
|
2738
|
-
* ```js
|
|
2739
|
-
* TreeArrayBacked.stripParentage(create(node, options));
|
|
2740
|
-
* ```
|
|
2741
|
-
* @param node
|
|
2742
|
-
* @param options
|
|
2743
|
-
* @returns
|
|
2744
|
-
*/
|
|
2745
|
-
const createSimplified = (node, options = {}) => {
|
|
2746
|
-
return stripParentage(create$1(node, options));
|
|
2747
|
-
};
|
|
2748
|
-
/**
|
|
2749
|
-
* Generates a name for a node.
|
|
2750
|
-
* Uses the 'name' property if it exists, otherwise uses `defaultName`
|
|
2751
|
-
* @param node
|
|
2752
|
-
* @param defaultName
|
|
2753
|
-
* @returns
|
|
2754
|
-
*/
|
|
2755
|
-
function getNamedEntry(node, defaultName = ``) {
|
|
2756
|
-
if (`name` in node && `leafValue` in node && `sourceValue` in node) return {
|
|
2757
|
-
name: node.name,
|
|
2758
|
-
_kind: `entry`,
|
|
2759
|
-
leafValue: node.leafValue,
|
|
2760
|
-
sourceValue: node.sourceValue
|
|
2761
|
-
};
|
|
2762
|
-
if (`name` in node) return {
|
|
2763
|
-
name: node.name,
|
|
2764
|
-
leafValue: node,
|
|
2765
|
-
sourceValue: node,
|
|
2766
|
-
_kind: `entry`
|
|
2767
|
-
};
|
|
2768
|
-
return {
|
|
2769
|
-
name: defaultName,
|
|
2770
|
-
leafValue: node,
|
|
2771
|
-
sourceValue: node,
|
|
2772
|
-
_kind: `entry`
|
|
2773
|
-
};
|
|
2774
|
-
}
|
|
2775
|
-
function isSingleValue(v) {
|
|
2776
|
-
if (`value` in v) return true;
|
|
2777
|
-
return false;
|
|
2778
|
-
}
|
|
2779
|
-
function isMultiValue(v) {
|
|
2780
|
-
if (`values` in v) return Array.isArray(v.values);
|
|
2781
|
-
return false;
|
|
2782
|
-
}
|
|
2783
|
-
var pathed_exports = /* @__PURE__ */ __exportAll({
|
|
2784
|
-
Pathed: () => Pathed,
|
|
2785
|
-
addValueByPath: () => addValueByPath,
|
|
2786
|
-
children: () => children,
|
|
2787
|
-
childrenLengthByPath: () => childrenLengthByPath,
|
|
2788
|
-
clearValuesByPath: () => clearValuesByPath,
|
|
2789
|
-
findAnyChildByValue: () => findAnyChildByValue$1,
|
|
2790
|
-
hasValue: () => hasValue,
|
|
2791
|
-
parent: () => parent,
|
|
2792
|
-
parentValues: () => parentValues,
|
|
2793
|
-
removeValueByPath: () => removeValueByPath,
|
|
2794
|
-
siblings: () => siblings$1,
|
|
2795
|
-
siblingsValues: () => siblingsValues,
|
|
2796
|
-
toStringDeep: () => toStringDeep$2,
|
|
2797
|
-
valueByPath: () => valueByPath,
|
|
2798
|
-
valuesByPath: () => valuesByPath
|
|
2799
|
-
});
|
|
2800
|
-
/**
|
|
2801
|
-
* Creates a wrapper for working with 'pathed' trees.
|
|
2802
|
-
* An example is a filesystem.
|
|
2803
|
-
*
|
|
2804
|
-
* ```js
|
|
2805
|
-
* const t = new Pathed();
|
|
2806
|
-
* // Store a value. Path implies a structure of
|
|
2807
|
-
* // c -> users -> admin
|
|
2808
|
-
* // ...which is automatically created
|
|
2809
|
-
* t.add({x:10}, `c.users.admin`);
|
|
2810
|
-
*
|
|
2811
|
-
* t.add({x:20}, `c.users.guest`);
|
|
2812
|
-
* // Tree will now be:
|
|
2813
|
-
* // c-> users -> admin
|
|
2814
|
-
* // -> guest
|
|
2815
|
-
*
|
|
2816
|
-
* t.getValue(`c.users.guest`); // { x:20 }
|
|
2817
|
-
* ```
|
|
2818
|
-
*
|
|
2819
|
-
* By default only a single value can be stored at a path.
|
|
2820
|
-
* Set options to allow this:
|
|
2821
|
-
* ```js
|
|
2822
|
-
* const t = new Pathed({ duplicates: `allow` });
|
|
2823
|
-
* t.add({x:10}, `c.users.admin`);
|
|
2824
|
-
* t.add({x:20}, `c.users.admin`);
|
|
2825
|
-
* t.getValue(`c.users.admin`); // Throws an error because there are multiple values
|
|
2826
|
-
* t.getValues(`c.users.admin`); // [ {x:10}, {x:20 } ]
|
|
2827
|
-
* ```
|
|
2828
|
-
* @param pathOpts
|
|
2829
|
-
* @returns
|
|
2830
|
-
*/
|
|
2831
|
-
var Pathed = class {
|
|
2832
|
-
#root;
|
|
2833
|
-
#pathOpts;
|
|
2834
|
-
/**
|
|
2835
|
-
* Create, using default options
|
|
2836
|
-
* @param pathOpts
|
|
2837
|
-
*/
|
|
2838
|
-
constructor(pathOpts = {}) {
|
|
2839
|
-
this.#pathOpts = {
|
|
2840
|
-
separator: `.`,
|
|
2841
|
-
startsWithSeparator: false,
|
|
2842
|
-
duplicates: `overwrite`,
|
|
2843
|
-
...pathOpts
|
|
2844
|
-
};
|
|
2845
|
-
}
|
|
2846
|
-
/**
|
|
2847
|
-
* Adds a value at the string path, automatically creating intermediate nodes as needed.
|
|
2848
|
-
* By default, if a value already exists at the path, it will be overwritten. Set options to change this.
|
|
2849
|
-
* @param value Value to associate with path
|
|
2850
|
-
* @param path Path
|
|
2851
|
-
*/
|
|
2852
|
-
add(value, path) {
|
|
2853
|
-
throwIfFailed(this.validate(path));
|
|
2854
|
-
const n = addValueByPath(value, path, this.#pathOpts, this.#root);
|
|
2855
|
-
if (this.#root === void 0) this.#root = getRoot(n);
|
|
2856
|
-
}
|
|
2857
|
-
validate(path) {
|
|
2858
|
-
if (this.#pathOpts.startsWithSeparator && !path.startsWith(this.#pathOpts.separator)) return {
|
|
2859
|
-
success: false,
|
|
2860
|
-
error: `Path must start with separator when 'startsWithSeparator' is enabled. Got: ${path}`
|
|
2861
|
-
};
|
|
2862
|
-
return {
|
|
2863
|
-
success: true,
|
|
2864
|
-
value: path
|
|
2865
|
-
};
|
|
2866
|
-
}
|
|
2867
|
-
/**
|
|
2868
|
-
* Returns a string representation of tree
|
|
2869
|
-
* @returns Returns a string representation of tree
|
|
2870
|
-
*/
|
|
2871
|
-
prettyPrint() {
|
|
2872
|
-
if (this.#root === void 0) return `(empty)`;
|
|
2873
|
-
return toStringDeep$4(this.#root);
|
|
2874
|
-
}
|
|
2875
|
-
/**
|
|
2876
|
-
* Removes the value at the given path, returning _true_
|
|
2877
|
-
* if there was a value. This will delete tree nodes if they become empty
|
|
2878
|
-
* @param path
|
|
2879
|
-
* @returns _true_ if value was removed
|
|
2880
|
-
*/
|
|
2881
|
-
remove(path) {
|
|
2882
|
-
throwIfFailed(this.validate(path));
|
|
2883
|
-
if (this.#root === void 0) return false;
|
|
2884
|
-
return removeValueByPath(path, this.#root, this.#pathOpts);
|
|
2885
|
-
}
|
|
2886
|
-
/**
|
|
2887
|
-
* Returns _true_ if we have a value at `path`
|
|
2888
|
-
* @param path
|
|
2889
|
-
* @returns _true_ if value exists at path
|
|
2890
|
-
*/
|
|
2891
|
-
hasPath(path) {
|
|
2892
|
-
throwIfFailed(this.validate(path));
|
|
2893
|
-
if (this.#root === void 0) return false;
|
|
2894
|
-
return findChildByPath(path, this.#root, this.#pathOpts) !== void 0;
|
|
2895
|
-
}
|
|
2896
|
-
/**
|
|
2897
|
-
* Returns a tree node for a given path, or _undefined_
|
|
2898
|
-
* if path does not exist.
|
|
2899
|
-
*
|
|
2900
|
-
* Use {@link getValue} to get the value at a node instead.
|
|
2901
|
-
* @param path
|
|
2902
|
-
* @returns The tree node for the given path, or _undefined_ if not found
|
|
2903
|
-
*/
|
|
2904
|
-
getNode(path) {
|
|
2905
|
-
throwIfFailed(this.validate(path));
|
|
2906
|
-
if (this.#root === void 0) return;
|
|
2907
|
-
return findChildByPath(path, this.#root, this.#pathOpts);
|
|
2908
|
-
}
|
|
2909
|
-
/**
|
|
2910
|
-
* Returns the value at the path, or _undefined_ if path is not found.
|
|
2911
|
-
* Use {@link getNode} to get the tree node instead.
|
|
2912
|
-
* @param path
|
|
2913
|
-
* @returns The value at the path, or _undefined_ if path is not found
|
|
2914
|
-
*/
|
|
2915
|
-
getValue(path) {
|
|
2916
|
-
throwIfFailed(this.validate(path));
|
|
2917
|
-
if (this.#root === void 0) return;
|
|
2918
|
-
return valueByPath(path, this.#root, this.#pathOpts);
|
|
2919
|
-
}
|
|
2920
|
-
/**
|
|
2921
|
-
* Gets the containing path to `node`. If _includeNode_ is true, we also include the
|
|
2922
|
-
* node's own label.
|
|
2923
|
-
*/
|
|
2924
|
-
getPath(node, includeNode) {
|
|
2925
|
-
if (this.#root === void 0) return ``;
|
|
2926
|
-
const segments = [];
|
|
2927
|
-
if (includeNode && node.value) segments.push(node.value?.label);
|
|
2928
|
-
for (const p of parentValues(node)) segments.unshift(p.label);
|
|
2929
|
-
let path = segments.join(this.#pathOpts.separator);
|
|
2930
|
-
if (this.#pathOpts.startsWithSeparator) {
|
|
2931
|
-
if (!path.startsWith(this.#pathOpts.separator)) path = this.#pathOpts.separator + path;
|
|
2932
|
-
if (!path.endsWith(this.#pathOpts.separator) && (node.childrenStore.length > 0 || !includeNode)) path += this.#pathOpts.separator;
|
|
2933
|
-
}
|
|
2934
|
-
return path;
|
|
2935
|
-
}
|
|
2936
|
-
/**
|
|
2937
|
-
* Gets the number of children at a given path.
|
|
2938
|
-
* Returns NaN if path does not exist or has no children.
|
|
2939
|
-
* @param path
|
|
2940
|
-
* @returns The number of children at the path, or NaN if path is not found
|
|
2941
|
-
*/
|
|
2942
|
-
childrenLength(path) {
|
|
2943
|
-
throwIfFailed(this.validate(path));
|
|
2944
|
-
if (this.#root === void 0) return NaN;
|
|
2945
|
-
const c = findChildByPath(path, this.#root, this.#pathOpts);
|
|
2946
|
-
if (c === void 0) return NaN;
|
|
2947
|
-
return c.childrenStore.length;
|
|
2948
|
-
}
|
|
2949
|
-
/**
|
|
2950
|
-
* Get all the values stored at a path, if multiple values are allowed. Returns an empty array if path does not exist or has no value.
|
|
2951
|
-
* @param path
|
|
2952
|
-
* @returns An array of values at the path, or an empty array if path is not found
|
|
2953
|
-
*/
|
|
2954
|
-
getValues(path) {
|
|
2955
|
-
throwIfFailed(this.validate(path));
|
|
2956
|
-
if (this.#root === void 0) return void 0;
|
|
2957
|
-
return valuesByPath(path, this.#root, this.#pathOpts);
|
|
2958
|
-
}
|
|
2959
|
-
/**
|
|
2960
|
-
* Removes all values at the given path, but leaves the structure of the tree intact. Returns _true_ if there was a value to clear.
|
|
2961
|
-
* @param path
|
|
2962
|
-
* @returns _true_ if there was a value to clear at the path
|
|
2963
|
-
*/
|
|
2964
|
-
clearValues(path) {
|
|
2965
|
-
throwIfFailed(this.validate(path));
|
|
2966
|
-
if (this.#root === void 0) return false;
|
|
2967
|
-
return clearValuesByPath(path, this.#root, this.#pathOpts);
|
|
2968
|
-
}
|
|
2969
|
-
/**
|
|
2970
|
-
* Iterate all children of this path
|
|
2971
|
-
*/
|
|
2972
|
-
*children(path) {
|
|
2973
|
-
throwIfFailed(this.validate(path));
|
|
2974
|
-
if (this.#root === void 0) return;
|
|
2975
|
-
yield* children(path, this.#root, this.#pathOpts);
|
|
2976
|
-
}
|
|
2977
|
-
/**
|
|
2978
|
-
* Iterate all siblings of this path
|
|
2979
|
-
*/
|
|
2980
|
-
*siblings(path) {
|
|
2981
|
-
throwIfFailed(this.validate(path));
|
|
2982
|
-
if (this.#root === void 0) return;
|
|
2983
|
-
yield* siblings$1(path, this.#root, this.#pathOpts);
|
|
2984
|
-
}
|
|
2985
|
-
/**
|
|
2986
|
-
* Iterate all siblings of this path
|
|
2987
|
-
*/
|
|
2988
|
-
*siblingsValues(path) {
|
|
2989
|
-
throwIfFailed(this.validate(path));
|
|
2990
|
-
if (this.#root === void 0) return;
|
|
2991
|
-
yield* siblingsValues(path, this.#root, this.#pathOpts);
|
|
2992
|
-
}
|
|
2993
|
-
/**
|
|
2994
|
-
* Returns the parent node of `path`, or _undefined_ if not found or at root.
|
|
2995
|
-
*/
|
|
2996
|
-
parent(path) {
|
|
2997
|
-
throwIfFailed(this.validate(path));
|
|
2998
|
-
if (this.#root === void 0) return;
|
|
2999
|
-
return parent(path, this.#root, this.#pathOpts);
|
|
3000
|
-
}
|
|
3001
|
-
get separator() {
|
|
3002
|
-
return this.#pathOpts.separator;
|
|
3003
|
-
}
|
|
3004
|
-
/**
|
|
3005
|
-
* Returns the root tree node.
|
|
3006
|
-
* @returns The root tree node, or _undefined_ if tree is empty
|
|
3007
|
-
*/
|
|
3008
|
-
get root() {
|
|
3009
|
-
return this.#root;
|
|
3010
|
-
}
|
|
3011
|
-
};
|
|
3012
|
-
/**
|
|
3013
|
-
* Adds a value by a string path, with '.' as a the default delimiter
|
|
3014
|
-
* Automatically generates intermediate nodes.
|
|
3015
|
-
*
|
|
3016
|
-
* ```js
|
|
3017
|
-
* const root = addValueByPath({}, 'c');
|
|
3018
|
-
* addValueByPath({x:'blah'}, 'c.users.admin', root);
|
|
3019
|
-
* ```
|
|
3020
|
-
*
|
|
3021
|
-
* Creates the structure:
|
|
3022
|
-
* ```
|
|
3023
|
-
* c value: { } label: c
|
|
3024
|
-
* + users value: undefined label: users
|
|
3025
|
-
* + admin value: { x: 'blah' } label: admin
|
|
3026
|
-
* ```
|
|
3027
|
-
*
|
|
3028
|
-
* By default, multiple values under same key are overwritten, with the most recent winning.
|
|
3029
|
-
* @param value Value to add
|
|
3030
|
-
* @param path Path to add at
|
|
3031
|
-
* @param node Node to insert
|
|
3032
|
-
* @param pathOpts Options
|
|
3033
|
-
*/
|
|
3034
|
-
function addValueByPath(value, path, pathOpts, node) {
|
|
3035
|
-
const separator = pathOpts.separator;
|
|
3036
|
-
const duplicatePath = pathOpts.duplicates;
|
|
3037
|
-
const split = path.split(separator);
|
|
3038
|
-
let count = 0;
|
|
3039
|
-
for (const p of split) {
|
|
3040
|
-
const lastEntry = count === split.length - 1;
|
|
3041
|
-
const found = findChildByLabel(p, node);
|
|
3042
|
-
if (found === void 0) node = createNode$1({
|
|
3043
|
-
value: lastEntry ? value : void 0,
|
|
3044
|
-
label: p
|
|
3045
|
-
}, node);
|
|
3046
|
-
else {
|
|
3047
|
-
node = found;
|
|
3048
|
-
if (lastEntry) switch (duplicatePath) {
|
|
3049
|
-
case `ignore`: break;
|
|
3050
|
-
case `allow`: {
|
|
3051
|
-
const existing = getValuesFromNode(node);
|
|
3052
|
-
node.value = {
|
|
3053
|
-
values: [...existing, value],
|
|
3054
|
-
label: p
|
|
3055
|
-
};
|
|
3056
|
-
break;
|
|
3057
|
-
}
|
|
3058
|
-
case `overwrite`:
|
|
3059
|
-
node.value = {
|
|
3060
|
-
value,
|
|
3061
|
-
label: p
|
|
3062
|
-
};
|
|
3063
|
-
break;
|
|
3064
|
-
}
|
|
3065
|
-
else node = found;
|
|
3066
|
-
}
|
|
3067
|
-
count++;
|
|
3068
|
-
}
|
|
3069
|
-
if (node === void 0) throw new Error(`Could not create tree`);
|
|
3070
|
-
return node;
|
|
3071
|
-
}
|
|
3072
|
-
/**
|
|
3073
|
-
* Removes the value at the given path, returning _true_ if there was something to remove.
|
|
3074
|
-
* @param node
|
|
3075
|
-
* @returns _true_ if something removed
|
|
3076
|
-
*/
|
|
3077
|
-
function isLabelledNodeEmpty(node) {
|
|
3078
|
-
if (node.value === void 0) return true;
|
|
3079
|
-
if (`values` in node.value) return node.value.values.length === 0;
|
|
3080
|
-
if (`value` in node.value) return node.value.value === void 0;
|
|
3081
|
-
return true;
|
|
3082
|
-
}
|
|
3083
|
-
function pruneLabelledBranch(node) {
|
|
3084
|
-
if (node.childrenStore.length > 0) return;
|
|
3085
|
-
if (!isLabelledNodeEmpty(node)) return;
|
|
3086
|
-
const parent = node.parent;
|
|
3087
|
-
if (!parent) return;
|
|
3088
|
-
remove$1(node);
|
|
3089
|
-
pruneLabelledBranch(parent);
|
|
3090
|
-
}
|
|
3091
|
-
function removeValueByPath(path, root, pathOpts) {
|
|
3092
|
-
if (root === void 0) return false;
|
|
3093
|
-
const c = findChildByPath(path, root, pathOpts);
|
|
3094
|
-
if (c === void 0) return false;
|
|
3095
|
-
c.value = void 0;
|
|
3096
|
-
pruneLabelledBranch(c);
|
|
3097
|
-
return true;
|
|
3098
|
-
}
|
|
3099
|
-
function clearValuesByPath(path, root, pathOpts) {
|
|
3100
|
-
if (root === void 0) return false;
|
|
3101
|
-
const c = findChildByPath(path, root, pathOpts);
|
|
3102
|
-
if (c === void 0) return false;
|
|
3103
|
-
c.value = {
|
|
3104
|
-
label: c.value?.label ?? ``,
|
|
3105
|
-
value: void 0
|
|
3106
|
-
};
|
|
3107
|
-
return true;
|
|
3108
|
-
}
|
|
3109
|
-
/**
|
|
3110
|
-
* Return the length of children of `path`, or NaN if path not found.
|
|
3111
|
-
*/
|
|
3112
|
-
function childrenLengthByPath(path, searchStart, pathOpts) {
|
|
3113
|
-
if (searchStart === void 0) return NaN;
|
|
3114
|
-
const c = findChildByPath(path, searchStart, pathOpts);
|
|
3115
|
-
if (c === void 0) return NaN;
|
|
3116
|
-
return c.childrenStore.length;
|
|
3117
|
-
}
|
|
3118
|
-
/**
|
|
3119
|
-
* Iterate over all the children of `path`
|
|
3120
|
-
*/
|
|
3121
|
-
function* children(path, searchStart, pathOpts) {
|
|
3122
|
-
if (searchStart === void 0) return;
|
|
3123
|
-
const c = findChildByPath(path, searchStart, pathOpts);
|
|
3124
|
-
if (c === void 0) return;
|
|
3125
|
-
for (const ch of c.childrenStore) yield ch;
|
|
3126
|
-
}
|
|
3127
|
-
/**
|
|
3128
|
-
* Iterate over all the siblings of `path`, excluding the node at `path` itself.
|
|
3129
|
-
* Yields LabelledNode instances, which allow you to traverse tree. If all you care about is the values, use {@link siblingsValues} instead.
|
|
3130
|
-
*/
|
|
3131
|
-
function* siblings$1(path, searchStart, pathOpts) {
|
|
3132
|
-
if (searchStart === void 0) return;
|
|
3133
|
-
const c = findChildByPath(path, searchStart, pathOpts);
|
|
3134
|
-
if (c === void 0) return;
|
|
3135
|
-
const parent = c.parent;
|
|
3136
|
-
if (parent === void 0) return;
|
|
3137
|
-
for (const ch of parent.childrenStore) {
|
|
3138
|
-
if (ch === c) continue;
|
|
3139
|
-
if (typeof ch === `undefined`) throw new TypeError(`Unexpected undefined child node`);
|
|
3140
|
-
yield ch;
|
|
3141
|
-
}
|
|
3142
|
-
}
|
|
3143
|
-
/**
|
|
3144
|
-
* Iterate over the values of all the siblings of `path`, excluding the node at `path` itself. If you need to traverse tree, use {@link siblings} instead.
|
|
3145
|
-
* @param path
|
|
3146
|
-
* @param searchStart
|
|
3147
|
-
* @param pathOpts
|
|
3148
|
-
*/
|
|
3149
|
-
function* siblingsValues(path, searchStart, pathOpts) {
|
|
3150
|
-
for (const s of siblings$1(path, searchStart, pathOpts)) {
|
|
3151
|
-
if (s.value === void 0) continue;
|
|
3152
|
-
yield s.value;
|
|
3153
|
-
}
|
|
3154
|
-
}
|
|
3155
|
-
/**
|
|
3156
|
-
* Return the parent node of `path`, or undefined if not found or at root.
|
|
3157
|
-
*/
|
|
3158
|
-
function parent(path, searchStart, pathOpts) {
|
|
3159
|
-
if (searchStart === void 0) return;
|
|
3160
|
-
const c = findChildByPath(path, searchStart, pathOpts);
|
|
3161
|
-
if (c === void 0) return;
|
|
3162
|
-
return c.parent;
|
|
3163
|
-
}
|
|
3164
|
-
function* parentValues(start) {
|
|
3165
|
-
for (const p of parents$1(start)) {
|
|
3166
|
-
if (p.value === void 0) continue;
|
|
3167
|
-
yield p.value;
|
|
3168
|
-
}
|
|
3169
|
-
}
|
|
3170
|
-
/**
|
|
3171
|
-
* Searches direct children, returning the node that has the given `label`
|
|
3172
|
-
* @param label
|
|
3173
|
-
* @param node
|
|
3174
|
-
* @returns Child node, or _undefined_
|
|
3175
|
-
*/
|
|
3176
|
-
function findChildByLabel(label, node) {
|
|
3177
|
-
if (node === void 0) return void 0;
|
|
3178
|
-
if (label === void 0) throw new Error(`Parameter 'label' cannot be undefined`);
|
|
3179
|
-
if (node.value?.label === label) return node;
|
|
3180
|
-
for (const c of node.childrenStore) if (c.value?.label === label) return c;
|
|
3181
|
-
}
|
|
3182
|
-
/**
|
|
3183
|
-
* Searches children, returning the node that has the given `value`.
|
|
3184
|
-
* @param value Value
|
|
3185
|
-
* @param node Node to start search from
|
|
3186
|
-
* @param maxDepth Maximum depth, defaults to full recursion
|
|
3187
|
-
* @param eq Equality function
|
|
3188
|
-
* @returns Child, or _undefined_ if not found
|
|
3189
|
-
*/
|
|
3190
|
-
function findAnyChildByValue$1(value, node, maxDepth = Number.MAX_SAFE_INTEGER, eq = isEqualValueDefault) {
|
|
3191
|
-
if (typeof node === `undefined`) throw new TypeError(`Param 'node' is undefined`);
|
|
3192
|
-
if (maxDepth <= 0) return;
|
|
3193
|
-
if (typeof value === `undefined`) throw new Error(`Param 'value' cannot be undefined`);
|
|
3194
|
-
for (const c of node.childrenStore) if (hasValue(value, c, eq)) return c;
|
|
3195
|
-
for (const c of node.childrenStore) {
|
|
3196
|
-
const result = findAnyChildByValue$1(value, c, maxDepth - 1, eq);
|
|
3197
|
-
if (typeof result !== `undefined`) return result;
|
|
3198
|
-
}
|
|
3199
|
-
}
|
|
3200
|
-
function hasValue(value, node, eq = isEqualDefault) {
|
|
3201
|
-
if (typeof node.value === `undefined`) return false;
|
|
3202
|
-
if (isSingleValue(node.value)) {
|
|
3203
|
-
if (eq(node.value.value, value)) return true;
|
|
3204
|
-
} else if (isMultiValue(node.value)) {
|
|
3205
|
-
for (const v of node.value.values) if (eq(v, value)) return true;
|
|
3206
|
-
}
|
|
3207
|
-
return false;
|
|
3208
|
-
}
|
|
3209
|
-
function valueByPath(path, node, pathOpts = {}) {
|
|
3210
|
-
const values = valuesByPath(path, node, pathOpts);
|
|
3211
|
-
if (typeof values === `undefined`) return;
|
|
3212
|
-
if (values.length === 0) return void 0;
|
|
3213
|
-
if (values.length > 1) throw new Error(`Multiple values at path. Use getValues instead`);
|
|
3214
|
-
return values[0];
|
|
3215
|
-
}
|
|
3216
|
-
function getValuesFromNode(node) {
|
|
3217
|
-
if (node.value === void 0) return [];
|
|
3218
|
-
if (`values` in node.value) return node.value.values;
|
|
3219
|
-
if (`value` in node.value) {
|
|
3220
|
-
if (node.value.value === void 0) return [];
|
|
3221
|
-
return [node.value.value];
|
|
3222
|
-
}
|
|
3223
|
-
return [];
|
|
3224
|
-
}
|
|
3225
|
-
function findChildByPath(path, searchStart, pathOpts) {
|
|
3226
|
-
if (path.endsWith(pathOpts.separator) && pathOpts.startsWithSeparator) path = path.slice(0, -pathOpts.separator.length);
|
|
3227
|
-
const split = path.split(pathOpts.separator);
|
|
3228
|
-
let c = searchStart;
|
|
3229
|
-
for (const p of split) {
|
|
3230
|
-
c = findChildByLabel(p, c);
|
|
3231
|
-
if (c === void 0) return;
|
|
3232
|
-
}
|
|
3233
|
-
return c;
|
|
3234
|
-
}
|
|
3235
|
-
function valuesByPath(path, searchStart, pathOpts = {}) {
|
|
3236
|
-
const separator = pathOpts.separator ?? `.`;
|
|
3237
|
-
const split = path.split(separator);
|
|
3238
|
-
let c = searchStart;
|
|
3239
|
-
for (const p of split) {
|
|
3240
|
-
c = findChildByLabel(p, c);
|
|
3241
|
-
if (c === void 0) return;
|
|
3242
|
-
}
|
|
3243
|
-
return getValuesFromNode(c);
|
|
3244
|
-
}
|
|
3245
|
-
function formatInspectValue(v) {
|
|
3246
|
-
if (v === void 0) return `undefined`;
|
|
3247
|
-
if (v === null) return `null`;
|
|
3248
|
-
if (typeof v === `string`) return `"${v}"`;
|
|
3249
|
-
if (typeof v === `number` || typeof v === `boolean`) return String(v);
|
|
3250
|
-
if (Array.isArray(v)) {
|
|
3251
|
-
if (v.length === 0) return `[]`;
|
|
3252
|
-
return `[ ${v.map(formatInspectValue).join(`, `)} ]`;
|
|
3253
|
-
}
|
|
3254
|
-
if (typeof v === `object`) return `{ ${Object.entries(v).map(([k, val]) => `${k}: ${formatInspectValue(val)}`).join(`, `)} }`;
|
|
3255
|
-
return String(v);
|
|
3256
|
-
}
|
|
3257
|
-
/**
|
|
3258
|
-
* Returns a string representation of a LabelledNode tree.
|
|
3259
|
-
* Format: `{ label: "x", value: ..., children: [...] }`
|
|
3260
|
-
*/
|
|
3261
|
-
function toStringDeep$2(node) {
|
|
3262
|
-
const label = node.value?.label ?? `?`;
|
|
3263
|
-
const innerValue = node.value === void 0 ? void 0 : `values` in node.value ? node.value.values : `value` in node.value ? node.value.value : void 0;
|
|
3264
|
-
const children = node.childrenStore.map((c) => toStringDeep$2(c));
|
|
3265
|
-
const childrenStr = children.length === 0 ? `[]` : `[ ${children.join(`, `)} ]`;
|
|
3266
|
-
return `{ label: "${label}", value: ${formatInspectValue(innerValue)}, children: ${childrenStr} }`;
|
|
3267
|
-
}
|
|
3268
|
-
var traversable_tree_exports = /* @__PURE__ */ __exportAll({
|
|
3269
|
-
breadthFirst: () => breadthFirst$1,
|
|
3270
|
-
childrenLength: () => childrenLength,
|
|
3271
|
-
couldAddChild: () => couldAddChild,
|
|
3272
|
-
depthFirst: () => depthFirst$1,
|
|
3273
|
-
find: () => find$2,
|
|
3274
|
-
findAnyChildByValue: () => findAnyChildByValue,
|
|
3275
|
-
findAnyParentByValue: () => findAnyParentByValue,
|
|
3276
|
-
findByValue: () => findByValue,
|
|
3277
|
-
findChildByValue: () => findChildByValue,
|
|
3278
|
-
findParentByValue: () => findParentByValue,
|
|
3279
|
-
followValue: () => followValue,
|
|
3280
|
-
hasAnyChild: () => hasAnyChild,
|
|
3281
|
-
hasAnyChildValue: () => hasAnyChildValue,
|
|
3282
|
-
hasAnyParent: () => hasAnyParent,
|
|
3283
|
-
hasAnyParentValue: () => hasAnyParentValue,
|
|
3284
|
-
hasChild: () => hasChild,
|
|
3285
|
-
hasChildValue: () => hasChildValue,
|
|
3286
|
-
hasParent: () => hasParent,
|
|
3287
|
-
hasParentValue: () => hasParentValue,
|
|
3288
|
-
parents: () => parents,
|
|
3289
|
-
siblings: () => siblings,
|
|
3290
|
-
toString: () => toString,
|
|
3291
|
-
toStringDeep: () => toStringDeep$1
|
|
3292
|
-
});
|
|
3293
|
-
/**
|
|
3294
|
-
* Returns the number of children of `tree`.
|
|
3295
|
-
* Under the hood is just `[ ...tree.children() ].length`
|
|
3296
|
-
* @param tree
|
|
3297
|
-
* @returns
|
|
3298
|
-
*/
|
|
3299
|
-
const childrenLength = (tree) => {
|
|
3300
|
-
return [...tree.children()].length;
|
|
3301
|
-
};
|
|
3302
|
-
/**
|
|
3303
|
-
* Returns _true_ if `child` is parented at any level (grand-parented etc) by `possibleParent`
|
|
3304
|
-
* @param child Child being sought
|
|
3305
|
-
* @param possibleParent Possible parent of child
|
|
3306
|
-
* @param eq Equality comparison function {@link isEqualDefault} used by default
|
|
3307
|
-
* @returns
|
|
3308
|
-
*/
|
|
3309
|
-
const hasAnyParent = (child, possibleParent, eq) => {
|
|
3310
|
-
return hasParent(child, possibleParent, eq, Number.MAX_SAFE_INTEGER);
|
|
3311
|
-
};
|
|
3312
|
-
/**
|
|
3313
|
-
* Returns _true_ if `child` is parented at any level (grand-parented etc) by a parent with value `possibleParentValue`
|
|
3314
|
-
* @param child Child being sought
|
|
3315
|
-
* @param possibleParentValue Value of possible parent of child
|
|
3316
|
-
* @param eq Equality comparison function {@link isEqualDefault} used by default
|
|
3317
|
-
* @throws TypeError if `child` is undefined
|
|
3318
|
-
* @returns
|
|
3319
|
-
*/
|
|
3320
|
-
const hasAnyParentValue = (child, possibleParentValue, eq) => {
|
|
3321
|
-
if (typeof child === `undefined`) throw new TypeError(`Param 'child' is undefined`);
|
|
3322
|
-
return hasParentValue(child, possibleParentValue, eq, Number.MAX_SAFE_INTEGER);
|
|
3323
|
-
};
|
|
3324
|
-
/**
|
|
3325
|
-
* Returns any parent of `child` that has value `possibleParentValue`. Returns _undefined_ if not found.
|
|
3326
|
-
* @param child Child being sought
|
|
3327
|
-
* @param possibleParentValue Value of possible parent of child
|
|
3328
|
-
* @param eq Equality comparison function {@link isEqualDefault} used by default
|
|
3329
|
-
* @returns
|
|
3330
|
-
*/
|
|
3331
|
-
const findAnyParentByValue = (child, possibleParentValue, eq) => {
|
|
3332
|
-
return findParentByValue(child, possibleParentValue, eq, Number.MAX_SAFE_INTEGER);
|
|
3333
|
-
};
|
|
3334
|
-
/**
|
|
3335
|
-
* Returns _true_ if `child` exists within `possibleParent`. By default it only looks at the immediate
|
|
3336
|
-
* parent (maxDepth: 0). Use Number.MAX_SAFE_INTEGER for searching recursively upwards (or {@link hasAnyParent})
|
|
3337
|
-
* @param child Child being sought
|
|
3338
|
-
* @param possibleParent Possible parent of child
|
|
3339
|
-
* @param maxDepth Max depth of traversal. Default of 0 only looks for immediate parent.
|
|
3340
|
-
* @param eq Equality comparison function. {@link isEqualDefault} used by default.
|
|
3341
|
-
* @returns
|
|
3342
|
-
*/
|
|
3343
|
-
const hasParent = (child, possibleParent, eq = isEqualDefault, maxDepth = 0) => {
|
|
3344
|
-
if (maxDepth < 0) return false;
|
|
3345
|
-
const isChildTrav = isTraversable(child);
|
|
3346
|
-
const isParentTrav = isTraversable(possibleParent);
|
|
3347
|
-
const p = isChildTrav ? child.getParent() : child.parent;
|
|
3348
|
-
if (typeof p === `undefined`) return false;
|
|
3349
|
-
if (eq(p, possibleParent)) return true;
|
|
3350
|
-
if (eq(isChildTrav ? p.getIdentity() : p.value, isParentTrav ? possibleParent.getIdentity() : possibleParent.value)) return true;
|
|
3351
|
-
return hasParent(p, possibleParent, eq, maxDepth - 1);
|
|
3352
|
-
};
|
|
3353
|
-
/**
|
|
3354
|
-
* Checks if a child node has a parent with a certain value
|
|
3355
|
-
* Note: by default only checks immediate parent. Set maxDepth to a large value to recurse
|
|
3356
|
-
*
|
|
3357
|
-
* Uses `getValue()` on the parent if that function exists.
|
|
3358
|
-
* @param child Node to start looking from
|
|
3359
|
-
* @param possibleParentValue Value to seek
|
|
3360
|
-
* @param eq Equality checker
|
|
3361
|
-
* @param maxDepth Defaults to 0, so it only checks immediate parent
|
|
3362
|
-
* @returns
|
|
3363
|
-
*/
|
|
3364
|
-
const hasParentValue = (child, possibleParentValue, eq = isEqualDefault, maxDepth = 0) => {
|
|
3365
|
-
if (child === void 0) throw new Error(`Param 'child' is undefined`);
|
|
3366
|
-
if (maxDepth < 0) return false;
|
|
3367
|
-
const p = `getParent` in child ? child.getParent() : child.parent;
|
|
3368
|
-
if (p === void 0) return false;
|
|
3369
|
-
if (eq(`getValue` in p ? p.getValue() : p.value, possibleParentValue)) return true;
|
|
3370
|
-
return hasParentValue(p, possibleParentValue, eq, maxDepth - 1);
|
|
3371
|
-
};
|
|
3372
|
-
/**
|
|
3373
|
-
* Returns any parent of `child` that has value `possibleParentValue`. Returns _undefined_ if not found.
|
|
3374
|
-
* @param child Child being sought
|
|
3375
|
-
* @param possibleParentValue Value of possible parent of child
|
|
3376
|
-
* @param eq Equality comparison function {@link isEqualDefault} used by default
|
|
3377
|
-
* @param maxDepth Maximum depth of traversal. Default of 0 only looks for immediate parent.
|
|
3378
|
-
* @returns
|
|
3379
|
-
*/
|
|
3380
|
-
const findParentByValue = (child, possibleParentValue, eq = isEqualDefault, maxDepth = 0) => {
|
|
3381
|
-
if (maxDepth < 0) return;
|
|
3382
|
-
const p = `getParent` in child ? child.getParent() : child.parent;
|
|
3383
|
-
if (p === void 0) return;
|
|
3384
|
-
if (eq(`getValue` in p ? p.getValue() : p.value, possibleParentValue)) return p;
|
|
3385
|
-
return findParentByValue(p, possibleParentValue, eq, maxDepth - 1);
|
|
3386
|
-
};
|
|
3387
|
-
/**
|
|
3388
|
-
* Returns _true_ if `prospectiveChild` can be legally added to `parent`.
|
|
3389
|
-
* _False_ is returned if:
|
|
3390
|
-
* * `parent` and `prospectiveChild` are equal
|
|
3391
|
-
* * `parent` already contains `prospectiveChild`
|
|
3392
|
-
* * `prospectiveChild` has `parent` as its own child
|
|
3393
|
-
*
|
|
3394
|
-
* Throws an error if `parent` or `prospectiveChild` is null/undefined.
|
|
3395
|
-
* @param parent Parent to add to
|
|
3396
|
-
* @param prospectiveChild Prospective child
|
|
3397
|
-
* @param eq Equality function
|
|
3398
|
-
*/
|
|
3399
|
-
const couldAddChild = (parent, prospectiveChild, eq = isEqualDefault) => {
|
|
3400
|
-
if (eq(parent, prospectiveChild)) throw new Error(`Child equals parent`);
|
|
3401
|
-
if (hasAnyChild(parent, prospectiveChild, eq)) throw new Error(`Circular. Parent already has child`);
|
|
3402
|
-
if (hasAnyChild(prospectiveChild, parent, eq)) throw new Error(`Prospective child has parent as child relation`);
|
|
3403
|
-
};
|
|
3404
|
-
/**
|
|
3405
|
-
* Returns _true_ if _possibleChild_ is contained within _parent_ tree.
|
|
3406
|
-
* That is, it is any sub-child.
|
|
3407
|
-
* @param parent Parent tree
|
|
3408
|
-
* @param possibleChild Sought child
|
|
3409
|
-
* @param eq Equality function, or {@link isEqualDefault} if undefined.
|
|
3410
|
-
* @returns
|
|
3411
|
-
*/
|
|
3412
|
-
const hasAnyChild = (parent, possibleChild, eq = isEqualDefault) => {
|
|
3413
|
-
return hasChild(parent, possibleChild, eq, Number.MAX_SAFE_INTEGER);
|
|
3414
|
-
};
|
|
3415
|
-
/**
|
|
3416
|
-
* Returns _true_ if `parent` has any child with value `possibleChildValue`. It explores
|
|
3417
|
-
* at children at any depth from `parent`.
|
|
3418
|
-
* @param parent
|
|
3419
|
-
* @param possibleChildValue
|
|
3420
|
-
* @param eq
|
|
3421
|
-
* @returns
|
|
3422
|
-
*/
|
|
3423
|
-
const hasAnyChildValue = (parent, possibleChildValue, eq = isEqualDefault) => {
|
|
3424
|
-
return hasChildValue(parent, possibleChildValue, eq, Number.MAX_SAFE_INTEGER);
|
|
3425
|
-
};
|
|
3426
|
-
/**
|
|
3427
|
-
* Returns _true_ if _possibleChild_ is contained within _maxDepth_ children
|
|
3428
|
-
* of _parent_ node. By default only looks at immediate children (maxDepth = 0).
|
|
3429
|
-
*
|
|
3430
|
-
* ```js
|
|
3431
|
-
* // Just check parentNode for childNode
|
|
3432
|
-
* Trees.hasChild(parentNode, childNode);
|
|
3433
|
-
* // See if parentNode or parentNode's parents have childNode
|
|
3434
|
-
* Trees.hasChild(parentNode, childNode, 1);
|
|
3435
|
-
* // Use custom equality function, in this case comparing on name field
|
|
3436
|
-
* Trees.hasChild(parentNode, childNode, 0, (a, b) => a.name === b.name);
|
|
3437
|
-
* ```
|
|
3438
|
-
* @param parent Parent tree
|
|
3439
|
-
* @param possibleChild Sought child
|
|
3440
|
-
* @param maxDepth Maximum depth. 0 for immediate children, Number.MAX_SAFE_INTEGER for boundless
|
|
3441
|
-
* @param eq Equality function, or {@link isEqualDefault} if undefined.
|
|
3442
|
-
* @returns
|
|
3443
|
-
*/
|
|
3444
|
-
const hasChild = (parent, possibleChild, eq = isEqualDefault, maxDepth = 0) => {
|
|
3445
|
-
if (maxDepth < 0) return false;
|
|
3446
|
-
if (eq(parent, possibleChild)) return true;
|
|
3447
|
-
const pId = `getIdentity` in parent ? parent.getIdentity() : parent.value;
|
|
3448
|
-
const pcId = `getIdentity` in possibleChild ? possibleChild.getIdentity() : possibleChild.value;
|
|
3449
|
-
if (eq(pId, pcId)) return true;
|
|
3450
|
-
for (const c of breadthFirst$1(parent, maxDepth)) {
|
|
3451
|
-
const cId = `getIdentity` in c ? c.getIdentity() : c.value;
|
|
3452
|
-
if (eq(c, possibleChild)) return true;
|
|
3453
|
-
if (eq(cId, pcId)) return true;
|
|
3454
|
-
}
|
|
3455
|
-
return false;
|
|
3456
|
-
};
|
|
3457
|
-
/**
|
|
3458
|
-
* Returns _true_ if `parent` has any child with value `possibleChildValue`. It explores
|
|
3459
|
-
* at children up to `maxDepth` from `parent`. By default only looks at immediate children (maxDepth = 0).
|
|
3460
|
-
* @param parent
|
|
3461
|
-
* @param possibleValue
|
|
3462
|
-
* @param eq
|
|
3463
|
-
* @param maxDepth
|
|
3464
|
-
* @returns
|
|
3465
|
-
*/
|
|
3466
|
-
const hasChildValue = (parent, possibleValue, eq = isEqualDefault, maxDepth = 0) => {
|
|
3467
|
-
if (maxDepth < 0) return false;
|
|
3468
|
-
if (eq(parent.getValue(), possibleValue)) return true;
|
|
3469
|
-
for (const c of breadthFirst$1(parent, maxDepth)) if (eq(c.getValue(), possibleValue)) return true;
|
|
3470
|
-
return false;
|
|
3471
|
-
};
|
|
3472
|
-
/**
|
|
3473
|
-
* Iterates over siblings of `node`.
|
|
3474
|
-
*
|
|
3475
|
-
* Other iteration options:
|
|
3476
|
-
* * {@link breadthFirst}: Children, breadth-first
|
|
3477
|
-
* * {@link depthFirst}: Children, depth-first
|
|
3478
|
-
* * {@link parents}: Chain of parents, starting with immediate parent
|
|
3479
|
-
* * {@link siblings}: Nodes with same parent
|
|
3480
|
-
* @param node Node to begin from
|
|
3481
|
-
* @returns
|
|
3482
|
-
*/
|
|
3483
|
-
function* siblings(node) {
|
|
3484
|
-
const p = node.getParent();
|
|
3485
|
-
if (p === void 0) return;
|
|
3486
|
-
for (const s of p.children()) {
|
|
3487
|
-
if (s === node) continue;
|
|
3488
|
-
yield s;
|
|
3489
|
-
}
|
|
3490
|
-
}
|
|
3491
|
-
/**
|
|
3492
|
-
* Iterates over parents of `node`, starting with immediate parent
|
|
3493
|
-
*
|
|
3494
|
-
* Other iteration options:
|
|
3495
|
-
* * {@link breadthFirst}: Children, breadth-first
|
|
3496
|
-
* * {@link depthFirst}: Children, depth-first
|
|
3497
|
-
* * {@link parents}: Chain of parents, starting with immediate parent
|
|
3498
|
-
* * {@link siblings}: Nodes with same parent
|
|
3499
|
-
* @param node Node to begin from
|
|
3500
|
-
* @returns
|
|
3501
|
-
*/
|
|
3502
|
-
function* parents(node) {
|
|
3503
|
-
if (isTraversable(node)) {
|
|
3504
|
-
let p = node.getParent();
|
|
3505
|
-
while (p !== void 0) {
|
|
3506
|
-
yield p;
|
|
3507
|
-
p = p.getParent();
|
|
3508
|
-
}
|
|
3509
|
-
} else {
|
|
3510
|
-
let p = node.parent;
|
|
3511
|
-
while (p !== void 0) {
|
|
3512
|
-
yield p;
|
|
3513
|
-
p = p.parent;
|
|
3514
|
-
}
|
|
3515
|
-
}
|
|
3516
|
-
}
|
|
3517
|
-
/**
|
|
3518
|
-
* Descends `parent`, breadth-first, looking for a particular value.
|
|
3519
|
-
* Returns _undefined_ if not found.
|
|
3520
|
-
* @param parent
|
|
3521
|
-
* @param possibleValue
|
|
3522
|
-
* @param eq
|
|
3523
|
-
* @returns
|
|
3524
|
-
*/
|
|
3525
|
-
function findAnyChildByValue(parent, possibleValue, eq = isEqualDefault) {
|
|
3526
|
-
return findChildByValue(parent, possibleValue, eq, Number.MAX_SAFE_INTEGER);
|
|
3527
|
-
}
|
|
3528
|
-
/**
|
|
3529
|
-
* Searches breadth-first for `possibleValue` under and including `parent`.
|
|
3530
|
-
* `maxDepth` sets he maximum level to which the tree is searched.
|
|
3531
|
-
* @param parent
|
|
3532
|
-
* @param possibleValue
|
|
3533
|
-
* @param eq
|
|
3534
|
-
* @param maxDepth
|
|
3535
|
-
* @returns
|
|
3536
|
-
*/
|
|
3537
|
-
function findChildByValue(parent, possibleValue, eq = isEqualDefault, maxDepth = 0) {
|
|
3538
|
-
if (maxDepth < 0) return;
|
|
3539
|
-
const isTraver = isTraversable(parent);
|
|
3540
|
-
if (isTraver) {
|
|
3541
|
-
if (eq(parent.getValue(), possibleValue)) return parent;
|
|
3542
|
-
} else if (eq(parent.value, possibleValue)) return parent;
|
|
3543
|
-
for (const d of breadthFirst$1(parent, maxDepth)) if (isTraver) {
|
|
3544
|
-
if (eq(d.getValue(), possibleValue)) return d;
|
|
3545
|
-
} else if (eq(d.value, possibleValue)) return d;
|
|
3546
|
-
}
|
|
3547
|
-
/**
|
|
3548
|
-
* Iterates over children of `root`, depth-first.
|
|
3549
|
-
*
|
|
3550
|
-
* Other iteration options:
|
|
3551
|
-
* * {@link breadthFirst}: Children, breadth-first
|
|
3552
|
-
* * {@link depthFirst}: Children, depth-first
|
|
3553
|
-
* * {@link parents}: Chain of parents, starting with immediate parent
|
|
3554
|
-
* * {@link siblings}: Nodes with same parent
|
|
3555
|
-
* @param root Root node
|
|
3556
|
-
* @returns
|
|
3557
|
-
*/
|
|
3558
|
-
function* depthFirst$1(root) {
|
|
3559
|
-
if (!root) return;
|
|
3560
|
-
const stack = new StackMutable();
|
|
3561
|
-
let entry = root;
|
|
3562
|
-
while (entry) {
|
|
3563
|
-
const entries = isTraversable(entry) ? [...entry.children()] : [...entry.childrenStore];
|
|
3564
|
-
stack.push(...entries);
|
|
3565
|
-
if (stack.isEmpty) break;
|
|
3566
|
-
entry = stack.pop();
|
|
3567
|
-
if (entry) yield entry;
|
|
3568
|
-
}
|
|
3569
|
-
}
|
|
3570
|
-
/**
|
|
3571
|
-
* Iterates over the children of `root`, breadth-first
|
|
3572
|
-
*
|
|
3573
|
-
* Other iteration options:
|
|
3574
|
-
* * {@link breadthFirst}: Children, breadth-first
|
|
3575
|
-
* * {@link depthFirst}: Children, depth-first
|
|
3576
|
-
* * {@link parents}: Chain of parents, starting with immediate parent
|
|
3577
|
-
* * {@link siblings}: Nodes with same parent
|
|
3578
|
-
*
|
|
3579
|
-
* @example Traversing over a simple object
|
|
3580
|
-
* ```js
|
|
3581
|
-
* const myObj = { name: `Pedro`, size: 45, colour: `orange` };
|
|
3582
|
-
* const root = Trees.FromObject.asDynamicTraversable(myObj);
|
|
3583
|
-
* for (const v of Trees.Traverse.breadthFirst(root)) {
|
|
3584
|
-
* // v.getValue() yields:
|
|
3585
|
-
* // { name: 'name', sourceValue: 'Pedro' ...},
|
|
3586
|
-
* // { name: 'size', sourceValue: 45 ... }
|
|
3587
|
-
* // ...
|
|
3588
|
-
* }
|
|
3589
|
-
* ```
|
|
3590
|
-
* @param root Root node
|
|
3591
|
-
* @param depth How many levels to traverse
|
|
3592
|
-
* @returns
|
|
3593
|
-
*/
|
|
3594
|
-
function* breadthFirst$1(root, depth = Number.MAX_SAFE_INTEGER) {
|
|
3595
|
-
if (!root) return;
|
|
3596
|
-
const queue = isTraversable(root) ? new QueueMutable() : new QueueMutable();
|
|
3597
|
-
let entry = root;
|
|
3598
|
-
while (entry) {
|
|
3599
|
-
if (depth < 0) return;
|
|
3600
|
-
if (entry !== void 0) {
|
|
3601
|
-
const kids = `childrenStore` in entry ? entry.childrenStore : entry.children();
|
|
3602
|
-
for (const c of kids) {
|
|
3603
|
-
yield c;
|
|
3604
|
-
queue.enqueue(c);
|
|
3605
|
-
}
|
|
3606
|
-
}
|
|
3607
|
-
entry = queue.dequeue();
|
|
3608
|
-
depth--;
|
|
3609
|
-
}
|
|
3610
|
-
}
|
|
3611
|
-
/**
|
|
3612
|
-
* Applies `predicate` to `root` and all its child nodes, returning the node where
|
|
3613
|
-
* `predicate` yields _true_.
|
|
3614
|
-
* Use {@link findByValue} to find a node by its value
|
|
3615
|
-
* @param root
|
|
3616
|
-
* @param predicate
|
|
3617
|
-
* @param order Iterate children by breadth or depth. Default 'breadth'
|
|
3618
|
-
* @returns
|
|
3619
|
-
*/
|
|
3620
|
-
function find$2(root, predicate, order = `breadth`) {
|
|
3621
|
-
if (predicate(root)) return root;
|
|
3622
|
-
const iter = order === `breadth` ? breadthFirst$1 : depthFirst$1;
|
|
3623
|
-
for (const c of iter(root)) if (predicate(c)) return c;
|
|
3624
|
-
}
|
|
3625
|
-
/**
|
|
3626
|
-
* Applies `predicate` to `root` and all its child nodes, returning the node value for
|
|
3627
|
-
* `predicate` yields _true_.
|
|
3628
|
-
* Use {@link find} to filter by nodes rather than values
|
|
3629
|
-
*
|
|
3630
|
-
* ```js
|
|
3631
|
-
* const n = findByValue(root, (v) => v.name === 'Bob');
|
|
3632
|
-
* ```
|
|
3633
|
-
* @param root
|
|
3634
|
-
* @param predicate
|
|
3635
|
-
* @param order Iterate children by breadth or depth. Default 'breadth'
|
|
3636
|
-
* @returns
|
|
3637
|
-
*/
|
|
3638
|
-
function findByValue(root, predicate, order = `breadth`) {
|
|
3639
|
-
if (predicate(root.getValue())) return root;
|
|
3640
|
-
const iter = order === `breadth` ? breadthFirst$1 : depthFirst$1;
|
|
3641
|
-
for (const c of iter(root)) if (predicate(c.getValue())) return c;
|
|
3642
|
-
}
|
|
3643
|
-
/**
|
|
3644
|
-
* Search through children in a path-like manner.
|
|
3645
|
-
*
|
|
3646
|
-
* It finds the first child of `root` that matches `continuePredicate`.
|
|
3647
|
-
* The function gets passed a depth of 1 to begin with. It recurses, looking for the next sub-child, etc.
|
|
3648
|
-
*
|
|
3649
|
-
* If it can't find a child, it stops.
|
|
3650
|
-
*
|
|
3651
|
-
* This is different to 'find' functions, which exhaustively search all possible child nodes, regardless of position in tree.
|
|
3652
|
-
*
|
|
3653
|
-
* ```js
|
|
3654
|
-
* const path = 'a.aa.aaa'.split('.');
|
|
3655
|
-
* const pred = (nodeValue, depth) => {
|
|
3656
|
-
* if (nodeValue === path[0]) {
|
|
3657
|
-
* path.shift(); // Remove first element
|
|
3658
|
-
* return true;
|
|
3659
|
-
* }
|
|
3660
|
-
* return false;
|
|
3661
|
-
* }
|
|
3662
|
-
*
|
|
3663
|
-
* // Assuming we have a tree of string values:
|
|
3664
|
-
* // a
|
|
3665
|
-
* // - aa
|
|
3666
|
-
* // - aaa
|
|
3667
|
-
* // - ab
|
|
3668
|
-
* // b
|
|
3669
|
-
* // - ba
|
|
3670
|
-
* for (const c of follow(tree, pred)) {
|
|
3671
|
-
* // Returns nodes: a, aa and then aaa
|
|
3672
|
-
* }
|
|
3673
|
-
* ```
|
|
3674
|
-
* @param root
|
|
3675
|
-
* @param continuePredicate
|
|
3676
|
-
* @param depth
|
|
3677
|
-
*/
|
|
3678
|
-
function* followValue(root, continuePredicate, depth = 1) {
|
|
3679
|
-
for (const c of root.children()) if (continuePredicate(c.getValue(), depth)) {
|
|
3680
|
-
yield c.getValue();
|
|
3681
|
-
yield* followValue(c, continuePredicate, depth + 1);
|
|
3682
|
-
}
|
|
3683
|
-
}
|
|
3684
|
-
function toStringDeep$1(node, depth = 0) {
|
|
3685
|
-
if (node === void 0) return `(undefined)`;
|
|
3686
|
-
if (node === null) return `(null)`;
|
|
3687
|
-
const v = node.getValue();
|
|
3688
|
-
let type = typeof v;
|
|
3689
|
-
if (Array.isArray(v)) type = `array`;
|
|
3690
|
-
let t = ` `.repeat(depth) + `value: ${JSON.stringify(v)} (${type})\n`;
|
|
3691
|
-
for (const n of node.children()) t += toStringDeep$1(n, depth + 1);
|
|
3692
|
-
return t;
|
|
3693
|
-
}
|
|
3694
|
-
function toString(...nodes) {
|
|
3695
|
-
let t = ``;
|
|
3696
|
-
for (const node of nodes) {
|
|
3697
|
-
const v = node.getValue();
|
|
3698
|
-
const vString = toStringAbbreviate(v);
|
|
3699
|
-
const children = [...node.children()];
|
|
3700
|
-
const parent = node.getParent();
|
|
3701
|
-
let type = typeof v;
|
|
3702
|
-
if (Array.isArray(v)) type = `array`;
|
|
3703
|
-
t += `value: ${vString} (${type}) kids: ${children.length} parented: ${parent ? `y` : `n`}\n`;
|
|
3704
|
-
}
|
|
3705
|
-
return t;
|
|
3706
|
-
}
|
|
3707
|
-
var binary_tree_exports = /* @__PURE__ */ __exportAll({
|
|
3708
|
-
addLeft: () => addLeft,
|
|
3709
|
-
addRight: () => addRight,
|
|
3710
|
-
balanceFactor: () => balanceFactor,
|
|
3711
|
-
breadthFirst: () => breadthFirst,
|
|
3712
|
-
createNode: () => createNode,
|
|
3713
|
-
depthFirst: () => depthFirst,
|
|
3714
|
-
find: () => find$1,
|
|
3715
|
-
fromArray: () => fromArray$1,
|
|
3716
|
-
getLeft: () => getLeft,
|
|
3717
|
-
getRight: () => getRight,
|
|
3718
|
-
grandparent: () => grandparent,
|
|
3719
|
-
hasLeft: () => hasLeft,
|
|
3720
|
-
hasRight: () => hasRight,
|
|
3721
|
-
height: () => height,
|
|
3722
|
-
inOrder: () => inOrder$1,
|
|
3723
|
-
isLeaf: () => isLeaf,
|
|
3724
|
-
isParentLeftChild: () => isParentLeftChild,
|
|
3725
|
-
isParentRightChild: () => isParentRightChild,
|
|
3726
|
-
leftSubtreeHeightFn: () => leftSubtreeHeightFn,
|
|
3727
|
-
parentChildSide: () => parentChildSide,
|
|
3728
|
-
postOrder: () => postOrder$1,
|
|
3729
|
-
preOrder: () => preOrder$1,
|
|
3730
|
-
removeNode: () => removeNode,
|
|
3731
|
-
rightSubtreeHeightFn: () => rightSubtreeHeightFn,
|
|
3732
|
-
root: () => root$1,
|
|
3733
|
-
rootWrapped: () => rootWrapped,
|
|
3734
|
-
setLeft: () => setLeft,
|
|
3735
|
-
setRight: () => setRight,
|
|
3736
|
-
sibling: () => sibling,
|
|
3737
|
-
toArray: () => toArray,
|
|
3738
|
-
toStringDeep: () => toStringDeep,
|
|
3739
|
-
uncle: () => uncle,
|
|
3740
|
-
wrap: () => wrap
|
|
3741
|
-
});
|
|
3742
|
-
const getLeftChild = (node) => {
|
|
3743
|
-
return node.childrenStore[0];
|
|
3744
|
-
};
|
|
3745
|
-
const getRightChild = (node) => {
|
|
3746
|
-
return node.childrenStore[1];
|
|
3747
|
-
};
|
|
3748
|
-
const getLeft = (node) => {
|
|
3749
|
-
return getLeftChild(node);
|
|
3750
|
-
};
|
|
3751
|
-
const getRight = (node) => {
|
|
3752
|
-
return getRightChild(node);
|
|
3753
|
-
};
|
|
3754
|
-
const hasLeft = (node) => {
|
|
3755
|
-
return getLeftChild(node) !== void 0;
|
|
3756
|
-
};
|
|
3757
|
-
const hasRight = (node) => {
|
|
3758
|
-
return getRightChild(node) !== void 0;
|
|
3759
|
-
};
|
|
3760
|
-
const isLeaf = (node) => {
|
|
3761
|
-
return !hasLeft(node) && !hasRight(node);
|
|
3762
|
-
};
|
|
3763
|
-
const setLeft = (parent, child) => {
|
|
3764
|
-
const existingLeft = getLeftChild(parent);
|
|
3765
|
-
if (existingLeft) existingLeft.parent = void 0;
|
|
3766
|
-
const children = [...parent.childrenStore];
|
|
3767
|
-
if (child === void 0 && children.length <= 1) {
|
|
3768
|
-
parent.childrenStore = [];
|
|
3769
|
-
return;
|
|
3770
|
-
} else if (child === void 0) {
|
|
3771
|
-
children[0] = void 0;
|
|
3772
|
-
parent.childrenStore = children;
|
|
3773
|
-
return;
|
|
3774
|
-
}
|
|
3775
|
-
if (children.length === 0) children.push(child);
|
|
3776
|
-
else children[0] = child;
|
|
3777
|
-
parent.childrenStore = children;
|
|
3778
|
-
child.parent = parent;
|
|
3779
|
-
};
|
|
3780
|
-
const setRight = (parent, child) => {
|
|
3781
|
-
const existingRight = getRightChild(parent);
|
|
3782
|
-
if (existingRight) existingRight.parent = void 0;
|
|
3783
|
-
const children = [...parent.childrenStore];
|
|
3784
|
-
if (child === void 0) {
|
|
3785
|
-
if (children.length >= 2) {
|
|
3786
|
-
children[1] = void 0;
|
|
3787
|
-
if (children[0] === void 0) parent.childrenStore = [];
|
|
3788
|
-
else parent.childrenStore = children;
|
|
3789
|
-
}
|
|
3790
|
-
return;
|
|
3791
|
-
}
|
|
3792
|
-
if (children.length === 0) children.push(void 0, child);
|
|
3793
|
-
else if (children.length === 1) children.push(child);
|
|
3794
|
-
else children[1] = child;
|
|
3795
|
-
parent.childrenStore = children;
|
|
3796
|
-
child.parent = parent;
|
|
3797
|
-
};
|
|
3798
|
-
const removeNode = (node) => {
|
|
3799
|
-
const p = node.parent;
|
|
3800
|
-
if (!p) return;
|
|
3801
|
-
if (p.childrenStore[0] === node) setLeft(p, void 0);
|
|
3802
|
-
else if (p.childrenStore[1] === node) setRight(p, void 0);
|
|
3803
|
-
};
|
|
3804
|
-
const sibling = (node) => {
|
|
3805
|
-
const parent = node.parent;
|
|
3806
|
-
if (!parent) return void 0;
|
|
3807
|
-
const left = getLeftChild(parent);
|
|
3808
|
-
const right = getRightChild(parent);
|
|
3809
|
-
if (left === node) return right;
|
|
3810
|
-
if (right === node) return left;
|
|
3811
|
-
};
|
|
3812
|
-
const uncle = (node) => {
|
|
3813
|
-
const parent = node.parent;
|
|
3814
|
-
if (!parent) return void 0;
|
|
3815
|
-
return sibling(parent);
|
|
3816
|
-
};
|
|
3817
|
-
const grandparent = (node) => {
|
|
3818
|
-
const parent = node.parent;
|
|
3819
|
-
if (!parent) return void 0;
|
|
3820
|
-
return parent.parent;
|
|
3821
|
-
};
|
|
3822
|
-
const isParentLeftChild = (node) => {
|
|
3823
|
-
const parent = node.parent;
|
|
3824
|
-
if (!parent) return false;
|
|
3825
|
-
return getLeftChild(parent) === node;
|
|
3826
|
-
};
|
|
3827
|
-
const isParentRightChild = (node) => {
|
|
3828
|
-
const parent = node.parent;
|
|
3829
|
-
if (!parent) return false;
|
|
3830
|
-
return getRightChild(parent) === node;
|
|
3831
|
-
};
|
|
3832
|
-
const parentChildSide = (node) => {
|
|
3833
|
-
if (!node.parent) return `neutral`;
|
|
3834
|
-
return isParentLeftChild(node) ? `left` : `right`;
|
|
3835
|
-
};
|
|
3836
|
-
const leftSubtreeHeight = (node) => {
|
|
3837
|
-
const left = getLeftChild(node);
|
|
3838
|
-
return left ? subtreeHeight(left) + 1 : 0;
|
|
3839
|
-
};
|
|
3840
|
-
const rightSubtreeHeight = (node) => {
|
|
3841
|
-
const right = getRightChild(node);
|
|
3842
|
-
return right ? subtreeHeight(right) + 1 : 0;
|
|
3843
|
-
};
|
|
3844
|
-
const subtreeHeight = (node) => {
|
|
3845
|
-
return Math.max(leftSubtreeHeight(node), rightSubtreeHeight(node));
|
|
3846
|
-
};
|
|
3847
|
-
const height = (node) => {
|
|
3848
|
-
return subtreeHeight(node);
|
|
3849
|
-
};
|
|
3850
|
-
const balanceFactor = (node) => {
|
|
3851
|
-
return leftSubtreeHeight(node) - rightSubtreeHeight(node);
|
|
3852
|
-
};
|
|
3853
|
-
const leftSubtreeHeightFn = leftSubtreeHeight;
|
|
3854
|
-
const rightSubtreeHeightFn = rightSubtreeHeight;
|
|
3855
|
-
const addLeft = (value, parent) => {
|
|
3856
|
-
const existingLeft = getLeftChild(parent);
|
|
3857
|
-
if (existingLeft) existingLeft.parent = void 0;
|
|
3858
|
-
const child = {
|
|
3859
|
-
value,
|
|
3860
|
-
parent,
|
|
3861
|
-
childrenStore: []
|
|
3862
|
-
};
|
|
3863
|
-
const children = [...parent.childrenStore];
|
|
3864
|
-
if (children.length === 0) children.push(child);
|
|
3865
|
-
else if (children.length === 1) children[0] = child;
|
|
3866
|
-
else children[0] = child;
|
|
3867
|
-
parent.childrenStore = children;
|
|
3868
|
-
return child;
|
|
3869
|
-
};
|
|
3870
|
-
const addRight = (value, parent) => {
|
|
3871
|
-
const existingRight = getRightChild(parent);
|
|
3872
|
-
if (existingRight) existingRight.parent = void 0;
|
|
3873
|
-
const child = {
|
|
3874
|
-
value,
|
|
3875
|
-
parent,
|
|
3876
|
-
childrenStore: []
|
|
3877
|
-
};
|
|
3878
|
-
const children = [...parent.childrenStore];
|
|
3879
|
-
if (children.length === 0) {
|
|
3880
|
-
children.push(void 0);
|
|
3881
|
-
children.push(child);
|
|
3882
|
-
} else if (children.length === 1) children.push(child);
|
|
3883
|
-
else children[1] = child;
|
|
3884
|
-
parent.childrenStore = children;
|
|
3885
|
-
return child;
|
|
3886
|
-
};
|
|
3887
|
-
const root$1 = (value) => {
|
|
3888
|
-
return root$2(value);
|
|
3889
|
-
};
|
|
3890
|
-
const createNode = (value, parent) => {
|
|
3891
|
-
return createNode$1(value, parent);
|
|
3892
|
-
};
|
|
3893
|
-
const unwrapNode = (node) => {
|
|
3894
|
-
return `node` in node ? node.node : node;
|
|
3895
|
-
};
|
|
3896
|
-
const wrapNode = (node) => {
|
|
3897
|
-
return wrap(node);
|
|
3898
|
-
};
|
|
3899
|
-
const wrap = (node) => {
|
|
3900
|
-
return {
|
|
3901
|
-
node,
|
|
3902
|
-
get left() {
|
|
3903
|
-
const left = getLeftChild(node);
|
|
3904
|
-
return left ? wrapNode(left) : void 0;
|
|
3905
|
-
},
|
|
3906
|
-
get right() {
|
|
3907
|
-
const right = getRightChild(node);
|
|
3908
|
-
return right ? wrapNode(right) : void 0;
|
|
3909
|
-
},
|
|
3910
|
-
set left(value) {
|
|
3911
|
-
setLeft(node, value ? unwrapNode(value) : void 0);
|
|
3912
|
-
},
|
|
3913
|
-
set right(value) {
|
|
3914
|
-
setRight(node, value ? unwrapNode(value) : void 0);
|
|
3915
|
-
},
|
|
3916
|
-
get parentChildSide() {
|
|
3917
|
-
return parentChildSide(node);
|
|
3918
|
-
},
|
|
3919
|
-
get isParentLeftChild() {
|
|
3920
|
-
return isParentLeftChild(node);
|
|
3921
|
-
},
|
|
3922
|
-
get isParentRightChild() {
|
|
3923
|
-
return isParentRightChild(node);
|
|
3924
|
-
},
|
|
3925
|
-
get isLeaf() {
|
|
3926
|
-
return isLeaf(node);
|
|
3927
|
-
},
|
|
3928
|
-
get sibling() {
|
|
3929
|
-
const sib = sibling(node);
|
|
3930
|
-
return sib ? wrapNode(sib) : void 0;
|
|
3931
|
-
},
|
|
3932
|
-
get uncle() {
|
|
3933
|
-
const unc = uncle(node);
|
|
3934
|
-
return unc ? wrapNode(unc) : void 0;
|
|
3935
|
-
},
|
|
3936
|
-
get grandparent() {
|
|
3937
|
-
const gp = grandparent(node);
|
|
3938
|
-
return gp ? wrapNode(gp) : void 0;
|
|
3939
|
-
},
|
|
3940
|
-
get leftSubtreeHeight() {
|
|
3941
|
-
return leftSubtreeHeight(node);
|
|
3942
|
-
},
|
|
3943
|
-
get rightSubtreeHeight() {
|
|
3944
|
-
return rightSubtreeHeight(node);
|
|
3945
|
-
},
|
|
3946
|
-
get height() {
|
|
3947
|
-
return height(node);
|
|
3948
|
-
},
|
|
3949
|
-
get balanceFactor() {
|
|
3950
|
-
return balanceFactor(node);
|
|
3951
|
-
},
|
|
3952
|
-
has(value) {
|
|
3953
|
-
return find$1(node, value) !== void 0;
|
|
3954
|
-
},
|
|
3955
|
-
addLeft(value) {
|
|
3956
|
-
return wrapNode(addLeft(value, node));
|
|
3957
|
-
},
|
|
3958
|
-
addRight(value) {
|
|
3959
|
-
return wrapNode(addRight(value, node));
|
|
3960
|
-
},
|
|
3961
|
-
setLeft(nodeOrWrapped) {
|
|
3962
|
-
setLeft(node, unwrapNode(nodeOrWrapped));
|
|
3963
|
-
},
|
|
3964
|
-
setRight(nodeOrWrapped) {
|
|
3965
|
-
setRight(node, unwrapNode(nodeOrWrapped));
|
|
3966
|
-
},
|
|
3967
|
-
remove() {
|
|
3968
|
-
removeNode(node);
|
|
3969
|
-
}
|
|
3970
|
-
};
|
|
3971
|
-
};
|
|
3972
|
-
const rootWrapped = (value) => {
|
|
3973
|
-
return wrap(root$2(value));
|
|
3974
|
-
};
|
|
3975
|
-
const find$1 = (root, value) => {
|
|
3976
|
-
for (const n of breadthFirst(root)) if (n.value === value) return n;
|
|
3977
|
-
};
|
|
3978
|
-
function* inOrder$1(node) {
|
|
3979
|
-
const left = getLeftChild(node);
|
|
3980
|
-
if (left) yield* inOrder$1(left);
|
|
3981
|
-
yield node;
|
|
3982
|
-
const right = getRightChild(node);
|
|
3983
|
-
if (right) yield* inOrder$1(right);
|
|
3984
|
-
}
|
|
3985
|
-
function* preOrder$1(node) {
|
|
3986
|
-
yield node;
|
|
3987
|
-
const left = getLeftChild(node);
|
|
3988
|
-
if (left) yield* preOrder$1(left);
|
|
3989
|
-
const right = getRightChild(node);
|
|
3990
|
-
if (right) yield* preOrder$1(right);
|
|
3991
|
-
}
|
|
3992
|
-
function* postOrder$1(node) {
|
|
3993
|
-
const left = getLeftChild(node);
|
|
3994
|
-
if (left) yield* postOrder$1(left);
|
|
3995
|
-
const right = getRightChild(node);
|
|
3996
|
-
if (right) yield* postOrder$1(right);
|
|
3997
|
-
yield node;
|
|
3998
|
-
}
|
|
3999
|
-
function* depthFirst(node) {
|
|
4000
|
-
const left = getLeftChild(node);
|
|
4001
|
-
const right = getRightChild(node);
|
|
4002
|
-
if (left) yield* depthFirst(left);
|
|
4003
|
-
if (right) yield* depthFirst(right);
|
|
4004
|
-
yield node;
|
|
4005
|
-
}
|
|
4006
|
-
function* breadthFirst(node) {
|
|
4007
|
-
yield node;
|
|
4008
|
-
const queue = [];
|
|
4009
|
-
queue.push(...node.childrenStore.filter((c) => c !== void 0 && c.value !== void 0));
|
|
4010
|
-
while (queue.length > 0) {
|
|
4011
|
-
const current = queue.shift();
|
|
4012
|
-
yield current;
|
|
4013
|
-
queue.push(...current.childrenStore.filter((c) => c !== void 0 && c.value !== void 0));
|
|
4014
|
-
}
|
|
4015
|
-
}
|
|
4016
|
-
const fromArray$1 = (array) => {
|
|
4017
|
-
if (array.length === 0) return void 0;
|
|
4018
|
-
const rootNode = root$2(array[0]);
|
|
4019
|
-
const insert = (index, parent) => {
|
|
4020
|
-
const leftIdx = 2 * index + 1;
|
|
4021
|
-
const rightIdx = 2 * index + 2;
|
|
4022
|
-
if (leftIdx < array.length) {
|
|
4023
|
-
addLeft(array[leftIdx], parent);
|
|
4024
|
-
insert(leftIdx, getLeftChild(parent));
|
|
4025
|
-
}
|
|
4026
|
-
if (rightIdx < array.length) {
|
|
4027
|
-
addRight(array[rightIdx], parent);
|
|
4028
|
-
insert(rightIdx, getRightChild(parent));
|
|
4029
|
-
}
|
|
4030
|
-
};
|
|
4031
|
-
insert(0, rootNode);
|
|
4032
|
-
return rootNode;
|
|
4033
|
-
};
|
|
4034
|
-
const toArray = (root) => {
|
|
4035
|
-
const result = [];
|
|
4036
|
-
for (const node of breadthFirst(root)) if (node.value !== void 0) result.push(node.value);
|
|
4037
|
-
return result;
|
|
4038
|
-
};
|
|
4039
|
-
const toStringDeep = (node, indent = 0) => {
|
|
4040
|
-
const v = node.value !== void 0 ? JSON.stringify(node.value) : `-`;
|
|
4041
|
-
const prefix = ` `.repeat(indent);
|
|
4042
|
-
const left = getLeftChild(node);
|
|
4043
|
-
const right = getRightChild(node);
|
|
4044
|
-
let result = `${prefix}${v}`;
|
|
4045
|
-
if (left || right) {
|
|
4046
|
-
result += `\n`;
|
|
4047
|
-
if (left) {
|
|
4048
|
-
result += `${prefix} L: ${toStringDeep(left, indent + 1)}`;
|
|
4049
|
-
if (right) result += `\n`;
|
|
4050
|
-
}
|
|
4051
|
-
if (right) result += `${prefix} R: ${toStringDeep(right, indent + 1)}`;
|
|
4052
|
-
}
|
|
4053
|
-
return result;
|
|
4054
|
-
};
|
|
4055
|
-
var binary_search_tree_exports = /* @__PURE__ */ __exportAll({
|
|
4056
|
-
Bst: () => Bst,
|
|
4057
|
-
create: () => create,
|
|
4058
|
-
find: () => find,
|
|
4059
|
-
fromArray: () => fromArray,
|
|
4060
|
-
has: () => has,
|
|
4061
|
-
inOrder: () => inOrder,
|
|
4062
|
-
insert: () => insert,
|
|
4063
|
-
max: () => max,
|
|
4064
|
-
min: () => min,
|
|
4065
|
-
postOrder: () => postOrder,
|
|
4066
|
-
preOrder: () => preOrder,
|
|
4067
|
-
remove: () => remove,
|
|
4068
|
-
root: () => root,
|
|
4069
|
-
valuesInOrder: () => valuesInOrder
|
|
4070
|
-
});
|
|
4071
|
-
var Bst = class {
|
|
4072
|
-
root;
|
|
4073
|
-
comparer;
|
|
4074
|
-
constructor(comparer = defaultComparer) {
|
|
4075
|
-
this.comparer = comparer;
|
|
4076
|
-
this.root = root$1();
|
|
4077
|
-
}
|
|
4078
|
-
insert(value) {
|
|
4079
|
-
this.root = insert(this.root, value, this.comparer);
|
|
4080
|
-
return this.root;
|
|
4081
|
-
}
|
|
4082
|
-
has(value) {
|
|
4083
|
-
return has(this.root, value, this.comparer);
|
|
4084
|
-
}
|
|
4085
|
-
find(value) {
|
|
4086
|
-
return find(this.root, value, this.comparer);
|
|
4087
|
-
}
|
|
4088
|
-
remove(value) {
|
|
4089
|
-
const result = remove(this.root, value, this.comparer);
|
|
4090
|
-
if (result) this.root = result;
|
|
4091
|
-
return result !== void 0;
|
|
4092
|
-
}
|
|
4093
|
-
min() {
|
|
4094
|
-
return min(this.root);
|
|
4095
|
-
}
|
|
4096
|
-
max() {
|
|
4097
|
-
return max(this.root);
|
|
4098
|
-
}
|
|
4099
|
-
inOrder() {
|
|
4100
|
-
return inOrder(this.root);
|
|
4101
|
-
}
|
|
4102
|
-
preOrder() {
|
|
4103
|
-
return preOrder(this.root);
|
|
4104
|
-
}
|
|
4105
|
-
postOrder() {
|
|
4106
|
-
return postOrder(this.root);
|
|
4107
|
-
}
|
|
4108
|
-
valuesInOrder() {
|
|
4109
|
-
return valuesInOrder(this.root);
|
|
4110
|
-
}
|
|
4111
|
-
toArrayInOrder() {
|
|
4112
|
-
return Array.from(this.valuesInOrder());
|
|
4113
|
-
}
|
|
4114
|
-
};
|
|
4115
|
-
const insert = (root, value, compare = defaultComparer) => {
|
|
4116
|
-
if (root.value === void 0) {
|
|
4117
|
-
root.value = value;
|
|
4118
|
-
return root;
|
|
4119
|
-
}
|
|
4120
|
-
let current = root;
|
|
4121
|
-
while (true) {
|
|
4122
|
-
const cmp = compare(value, current.value);
|
|
4123
|
-
if (cmp < 0) {
|
|
4124
|
-
const left = getLeft(current);
|
|
4125
|
-
if (left) current = left;
|
|
4126
|
-
else {
|
|
4127
|
-
addLeft(value, current);
|
|
4128
|
-
break;
|
|
4129
|
-
}
|
|
4130
|
-
} else if (cmp > 0) {
|
|
4131
|
-
const right = getRight(current);
|
|
4132
|
-
if (right) current = right;
|
|
4133
|
-
else {
|
|
4134
|
-
addRight(value, current);
|
|
4135
|
-
break;
|
|
4136
|
-
}
|
|
4137
|
-
} else break;
|
|
4138
|
-
}
|
|
4139
|
-
return root;
|
|
4140
|
-
};
|
|
4141
|
-
const has = (root, value, compare = defaultComparer) => {
|
|
4142
|
-
return find(root, value, compare) !== void 0;
|
|
4143
|
-
};
|
|
4144
|
-
const find = (root, value, compare = defaultComparer) => {
|
|
4145
|
-
if (!root || root.value === void 0) return void 0;
|
|
4146
|
-
const cmp = compare(value, root.value);
|
|
4147
|
-
if (cmp === 0) return root;
|
|
4148
|
-
else if (cmp < 0) {
|
|
4149
|
-
const left = getLeft(root);
|
|
4150
|
-
return left ? find(left, value, compare) : void 0;
|
|
4151
|
-
} else {
|
|
4152
|
-
const right = getRight(root);
|
|
4153
|
-
return right ? find(right, value, compare) : void 0;
|
|
4154
|
-
}
|
|
4155
|
-
};
|
|
4156
|
-
const min = (root) => {
|
|
4157
|
-
if (!root || root.value === void 0) return void 0;
|
|
4158
|
-
let current = root;
|
|
4159
|
-
while (getLeft(current)) current = getLeft(current);
|
|
4160
|
-
return current;
|
|
4161
|
-
};
|
|
4162
|
-
const max = (root) => {
|
|
4163
|
-
if (!root || root.value === void 0) return void 0;
|
|
4164
|
-
let current = root;
|
|
4165
|
-
while (getRight(current)) current = getRight(current);
|
|
4166
|
-
return current;
|
|
4167
|
-
};
|
|
4168
|
-
const remove = (root, value, compare = defaultComparer) => {
|
|
4169
|
-
if (!root || root.value === void 0) return void 0;
|
|
4170
|
-
const nodeToRemove = find(root, value, compare);
|
|
4171
|
-
if (!nodeToRemove) return;
|
|
4172
|
-
const left = getLeft(nodeToRemove);
|
|
4173
|
-
const right = getRight(nodeToRemove);
|
|
4174
|
-
if (!left && !right) if (nodeToRemove === root) {
|
|
4175
|
-
root.value = void 0;
|
|
4176
|
-
root.childrenStore = [];
|
|
4177
|
-
} else removeNode(nodeToRemove);
|
|
4178
|
-
else if (!left) if (nodeToRemove === root) {
|
|
4179
|
-
root.value = right.value;
|
|
4180
|
-
root.childrenStore = right.childrenStore;
|
|
4181
|
-
for (const child of root.childrenStore) if (child) child.parent = root;
|
|
4182
|
-
} else {
|
|
4183
|
-
const parent = nodeToRemove.parent;
|
|
4184
|
-
if (getLeft(parent) === nodeToRemove) setLeft(parent, right);
|
|
4185
|
-
else setRight(parent, right);
|
|
4186
|
-
}
|
|
4187
|
-
else if (!right) if (nodeToRemove === root) {
|
|
4188
|
-
root.value = left.value;
|
|
4189
|
-
root.childrenStore = left.childrenStore;
|
|
4190
|
-
for (const child of root.childrenStore) if (child) child.parent = root;
|
|
4191
|
-
} else {
|
|
4192
|
-
const parent = nodeToRemove.parent;
|
|
4193
|
-
if (getLeft(parent) === nodeToRemove) setLeft(parent, left);
|
|
4194
|
-
else setRight(parent, left);
|
|
4195
|
-
}
|
|
4196
|
-
else {
|
|
4197
|
-
const successor = min(right);
|
|
4198
|
-
nodeToRemove.value = successor.value;
|
|
4199
|
-
const succParent = successor.parent;
|
|
4200
|
-
const succRight = getRight(successor);
|
|
4201
|
-
if (getLeft(succParent) === successor) setLeft(succParent, succRight);
|
|
4202
|
-
else setRight(succParent, succRight);
|
|
4203
|
-
}
|
|
4204
|
-
return root;
|
|
4205
|
-
};
|
|
4206
|
-
function* inOrder(node) {
|
|
4207
|
-
if (!node) return;
|
|
4208
|
-
const left = getLeft(node);
|
|
4209
|
-
if (left) yield* inOrder(left);
|
|
4210
|
-
yield node;
|
|
4211
|
-
const right = getRight(node);
|
|
4212
|
-
if (right) yield* inOrder(right);
|
|
4213
|
-
}
|
|
4214
|
-
function* preOrder(node) {
|
|
4215
|
-
if (!node) return;
|
|
4216
|
-
yield node;
|
|
4217
|
-
const left = getLeft(node);
|
|
4218
|
-
if (left) yield* preOrder(left);
|
|
4219
|
-
const right = getRight(node);
|
|
4220
|
-
if (right) yield* preOrder(right);
|
|
4221
|
-
}
|
|
4222
|
-
function* postOrder(node) {
|
|
4223
|
-
if (!node) return;
|
|
4224
|
-
const left = getLeft(node);
|
|
4225
|
-
if (left) yield* postOrder(left);
|
|
4226
|
-
const right = getRight(node);
|
|
4227
|
-
if (right) yield* postOrder(right);
|
|
4228
|
-
yield node;
|
|
4229
|
-
}
|
|
4230
|
-
function* valuesInOrder(node) {
|
|
4231
|
-
for (const n of inOrder(node)) if (n.value !== void 0) yield n.value;
|
|
4232
|
-
}
|
|
4233
|
-
const create = (comparer) => {
|
|
4234
|
-
return new Bst(comparer);
|
|
4235
|
-
};
|
|
4236
|
-
const fromArray = (array, comparer = defaultComparer) => {
|
|
4237
|
-
const bst = new Bst(comparer);
|
|
4238
|
-
for (const value of array) bst.insert(value);
|
|
4239
|
-
return bst;
|
|
4240
|
-
};
|
|
4241
|
-
const root = () => {
|
|
4242
|
-
return root$1();
|
|
4243
|
-
};
|
|
4244
|
-
var tree_exports = /* @__PURE__ */ __exportAll({
|
|
4245
|
-
BinarySearchTree: () => binary_search_tree_exports,
|
|
4246
|
-
BinaryTree: () => binary_tree_exports,
|
|
4247
|
-
FromObject: () => traverse_object_exports,
|
|
4248
|
-
Mutable: () => tree_mutable_exports,
|
|
4249
|
-
Pathed: () => pathed_exports,
|
|
4250
|
-
Traverse: () => traversable_tree_exports,
|
|
4251
|
-
compare: () => compare$1,
|
|
4252
|
-
isMultiValue: () => isMultiValue,
|
|
4253
|
-
isSingleValue: () => isSingleValue,
|
|
4254
|
-
isTraversable: () => isTraversable,
|
|
4255
|
-
isTreeNode: () => isTreeNode,
|
|
4256
|
-
toTraversable: () => toTraversable
|
|
4257
|
-
});
|
|
4258
|
-
/**
|
|
4259
|
-
* Makes a 'traversable' to move around a {@link TreeNode},
|
|
4260
|
-
* an existing {@link TraversableTree} or a plain object.
|
|
4261
|
-
*
|
|
4262
|
-
* @param node
|
|
4263
|
-
* @returns
|
|
4264
|
-
*/
|
|
4265
|
-
const toTraversable = (node) => {
|
|
4266
|
-
if (isTraversable(node)) return node;
|
|
4267
|
-
if (isTreeNode(node)) return asDynamicTraversable$1(node);
|
|
4268
|
-
if (typeof node === `object`) return asDynamicTraversable(node);
|
|
4269
|
-
throw new Error(`Parameter 'node' not convertible`);
|
|
4270
|
-
};
|
|
4271
|
-
/**
|
|
4272
|
-
* Checks whether `node` is of type {@link TreeNode}.
|
|
4273
|
-
*
|
|
4274
|
-
* Checks for: parent, childrenStore and value defined on `node`.
|
|
4275
|
-
* @param node
|
|
4276
|
-
* @returns
|
|
4277
|
-
*/
|
|
4278
|
-
const isTreeNode = (node) => {
|
|
4279
|
-
if (`parent` in node && `childrenStore` in node && `value` in node) {
|
|
4280
|
-
if (Array.isArray(node.childrenStore)) return true;
|
|
1548
|
+
];
|
|
4281
1549
|
}
|
|
4282
|
-
return false;
|
|
4283
|
-
};
|
|
4284
|
-
/**
|
|
4285
|
-
* Checks if `node` is of type {@link TraversableTree}.
|
|
4286
|
-
*
|
|
4287
|
-
* Checks by looking for: children, getParent, getValue and getIdentity defined on `node`.
|
|
4288
|
-
* @param node
|
|
4289
|
-
* @returns
|
|
4290
|
-
*/
|
|
4291
|
-
const isTraversable = (node) => {
|
|
4292
|
-
return `children` in node && `getParent` in node && `getValue` in node && `getIdentity` in node;
|
|
4293
1550
|
};
|
|
1551
|
+
__decorate([property({ attribute: false })], SplitButton.prototype, "registry", void 0);
|
|
1552
|
+
__decorate([property({ attribute: false })], SplitButton.prototype, "keyboardManager", void 0);
|
|
1553
|
+
__decorate([property({ type: String })], SplitButton.prototype, "mode", void 0);
|
|
1554
|
+
__decorate([property({
|
|
1555
|
+
type: String,
|
|
1556
|
+
attribute: `default-value`
|
|
1557
|
+
})], SplitButton.prototype, "defaultValue", void 0);
|
|
1558
|
+
__decorate([property({ attribute: false })], SplitButton.prototype, "itemsProvider", void 0);
|
|
1559
|
+
__decorate([property({ attribute: false })], SplitButton.prototype, "items", void 0);
|
|
1560
|
+
__decorate([query(`ixfx-menu-trigger`)], SplitButton.prototype, "_menuTrigger", void 0);
|
|
1561
|
+
__decorate([state()], SplitButton.prototype, "_compact", void 0);
|
|
1562
|
+
__decorate([state()], SplitButton.prototype, "_selectedCommand", void 0);
|
|
1563
|
+
__decorate([state()], SplitButton.prototype, "_selectedLabel", void 0);
|
|
1564
|
+
__decorate([state()], SplitButton.prototype, "_selectedIcon", void 0);
|
|
1565
|
+
__decorate([state()], SplitButton.prototype, "_switcherItems", void 0);
|
|
1566
|
+
__decorate([state()], SplitButton.prototype, "_dynamicItems", void 0);
|
|
1567
|
+
__decorate([state()], SplitButton.prototype, "_loadingItems", void 0);
|
|
1568
|
+
__decorate([state()], SplitButton.prototype, "_menuHasItems", void 0);
|
|
1569
|
+
SplitButton = __decorate([safeCustomElement(`ixfx-split-button`)], SplitButton);
|
|
4294
1570
|
//#endregion
|
|
4295
1571
|
//#region src/crumbs/crumb-path-controller.ts
|
|
4296
1572
|
var CrumbPathController = class {
|
|
@@ -4301,7 +1577,7 @@ var CrumbPathController = class {
|
|
|
4301
1577
|
constructor(options = {}) {
|
|
4302
1578
|
this.#separator = options.separator ?? `/`;
|
|
4303
1579
|
this.#onQuery = options.onQuery;
|
|
4304
|
-
this.#pathed = new
|
|
1580
|
+
this.#pathed = new Trees.Pathed.Pathed({ separator: this.#separator });
|
|
4305
1581
|
if (options.paths) this.addPaths(options.paths);
|
|
4306
1582
|
}
|
|
4307
1583
|
get separator() {
|
|
@@ -4410,7 +1686,6 @@ let CrumbPathElement = class CrumbPathElement extends LitElement {
|
|
|
4410
1686
|
case `Escape`:
|
|
4411
1687
|
e.preventDefault();
|
|
4412
1688
|
this.#closeDropdown();
|
|
4413
|
-
break;
|
|
4414
1689
|
}
|
|
4415
1690
|
};
|
|
4416
1691
|
this.#onHostKeyDown = (e) => {
|
|
@@ -4749,9 +2024,11 @@ let CrumbPathElement = class CrumbPathElement extends LitElement {
|
|
|
4749
2024
|
#onHostKeyDown;
|
|
4750
2025
|
render() {
|
|
4751
2026
|
const segments = this.#getSegments();
|
|
4752
|
-
if (this._editing)
|
|
2027
|
+
if (this._editing) {
|
|
2028
|
+
const editValue = this.path;
|
|
2029
|
+
return html`
|
|
4753
2030
|
<ixfx-ac-text
|
|
4754
|
-
.value=${
|
|
2031
|
+
.value=${editValue}
|
|
4755
2032
|
.tabSuffix=${this.separator}
|
|
4756
2033
|
.completionProvider=${this.#makeCompletionProvider()}
|
|
4757
2034
|
@change=${this.#onAcChange}
|
|
@@ -4759,6 +2036,7 @@ let CrumbPathElement = class CrumbPathElement extends LitElement {
|
|
|
4759
2036
|
@keydown=${this.#onAcKeyDown}
|
|
4760
2037
|
></ixfx-ac-text>
|
|
4761
2038
|
`;
|
|
2039
|
+
}
|
|
4762
2040
|
const rootSegments = this.#getRootSegments();
|
|
4763
2041
|
const leadingCaret = this.siblingLookup && rootSegments.length === 0 ? html`
|
|
4764
2042
|
<div class="caret ${this._openIdx === -1 ? `open` : ``} ${this._confirmedLeafIndices.has(``) ? `disabled` : ``}"
|
|
@@ -4986,7 +2264,7 @@ CrumbPathElement = __decorate([safeCustomElement(`ixfx-crumb-path`)], CrumbPathE
|
|
|
4986
2264
|
//#endregion
|
|
4987
2265
|
//#region src/editable-label/editable-number.ts
|
|
4988
2266
|
const DRAG_THRESHOLD_PX = 3;
|
|
4989
|
-
let EditableNumber = class EditableNumber extends EditableLabel {
|
|
2267
|
+
let EditableNumber = class EditableNumber extends WheelNudgeMixin(EditableLabel) {
|
|
4990
2268
|
#dragStartY;
|
|
4991
2269
|
#dragStartValue;
|
|
4992
2270
|
#dragging;
|
|
@@ -5239,14 +2517,15 @@ let EditableNumber = class EditableNumber extends EditableLabel {
|
|
|
5239
2517
|
this.style.setProperty(`--value`, String(normalized));
|
|
5240
2518
|
let valueStart = 0;
|
|
5241
2519
|
let valueEnd = normalized;
|
|
5242
|
-
if (this.linearStyle === `bipolar`)
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
2520
|
+
if (this.linearStyle === `bipolar`) {
|
|
2521
|
+
if (normalized <= .5) {
|
|
2522
|
+
valueStart = normalized;
|
|
2523
|
+
valueEnd = .5;
|
|
2524
|
+
} else {
|
|
2525
|
+
valueStart = .5;
|
|
2526
|
+
valueEnd = normalized;
|
|
2527
|
+
}
|
|
2528
|
+
} else if (this.linearStyle === `unipolar`) {
|
|
5250
2529
|
valueStart = .5 - normalized * .5;
|
|
5251
2530
|
valueEnd = .5 + normalized * .5;
|
|
5252
2531
|
}
|
|
@@ -5288,8 +2567,7 @@ let EditableNumber = class EditableNumber extends EditableLabel {
|
|
|
5288
2567
|
_handleArrowKey(e) {
|
|
5289
2568
|
const range = (this.max ?? 100) - (this.min ?? 0);
|
|
5290
2569
|
if (range === 0) return false;
|
|
5291
|
-
const
|
|
5292
|
-
const effectiveStep = resolveStep(range, void 0, this.step) / shiftDivisor;
|
|
2570
|
+
const effectiveStep = resolveAxisStep(range, this.stops, this.step, e.shiftKey);
|
|
5293
2571
|
let delta = 0;
|
|
5294
2572
|
let handled = false;
|
|
5295
2573
|
switch (e.key) {
|
|
@@ -5310,33 +2588,49 @@ let EditableNumber = class EditableNumber extends EditableLabel {
|
|
|
5310
2588
|
case `End`:
|
|
5311
2589
|
delta = (this.max ?? 0) - this._parseValue();
|
|
5312
2590
|
handled = true;
|
|
5313
|
-
break;
|
|
5314
2591
|
}
|
|
5315
2592
|
if (handled) {
|
|
5316
2593
|
e.preventDefault();
|
|
5317
|
-
|
|
5318
|
-
const current = this._parseValue();
|
|
5319
|
-
const newValue = this._clamp(this._snap(current + delta));
|
|
5320
|
-
const newValueStr = this.step !== void 0 ? this._formatNumber(newValue) : newValue.toFixed(this.precision);
|
|
5321
|
-
this.value = newValueStr;
|
|
5322
|
-
this._requestDisplayUpdate();
|
|
5323
|
-
this._updateValueCss(this._normalizedValue(newValue));
|
|
5324
|
-
if (newValueStr !== prev) this.dispatchEvent(new CustomEvent(`input`, {
|
|
5325
|
-
detail: { value: newValueStr },
|
|
5326
|
-
bubbles: true,
|
|
5327
|
-
composed: true
|
|
5328
|
-
}));
|
|
5329
|
-
requestAnimationFrame(() => {
|
|
5330
|
-
if (this.value !== prev) this.dispatchEvent(new CustomEvent(`change`, {
|
|
5331
|
-
detail: { value: this.value },
|
|
5332
|
-
bubbles: true,
|
|
5333
|
-
composed: true
|
|
5334
|
-
}));
|
|
5335
|
-
});
|
|
2594
|
+
this._applyDelta(delta);
|
|
5336
2595
|
return true;
|
|
5337
2596
|
}
|
|
5338
2597
|
return false;
|
|
5339
2598
|
}
|
|
2599
|
+
/**
|
|
2600
|
+
* Apply a signed delta to the current value, clamp/snap/format, and fire
|
|
2601
|
+
* `input`/`change`. Shared between arrow-key handler and the wheel handler.
|
|
2602
|
+
*/
|
|
2603
|
+
_applyDelta(delta) {
|
|
2604
|
+
const prev = this.value;
|
|
2605
|
+
const current = this._parseValue();
|
|
2606
|
+
const newValue = this._clamp(this._snap(current + delta));
|
|
2607
|
+
const newValueStr = this.step !== void 0 ? this._formatNumber(newValue) : newValue.toFixed(this.precision);
|
|
2608
|
+
this.value = newValueStr;
|
|
2609
|
+
this._requestDisplayUpdate();
|
|
2610
|
+
this._updateValueCss(this._normalizedValue(newValue));
|
|
2611
|
+
if (newValueStr !== prev) this.dispatchEvent(new CustomEvent(`input`, {
|
|
2612
|
+
detail: { value: newValueStr },
|
|
2613
|
+
bubbles: true,
|
|
2614
|
+
composed: true
|
|
2615
|
+
}));
|
|
2616
|
+
requestAnimationFrame(() => {
|
|
2617
|
+
if (this.value !== prev) this.dispatchEvent(new CustomEvent(`change`, {
|
|
2618
|
+
detail: { value: this.value },
|
|
2619
|
+
bubbles: true,
|
|
2620
|
+
composed: true
|
|
2621
|
+
}));
|
|
2622
|
+
});
|
|
2623
|
+
}
|
|
2624
|
+
_shouldHandleWheel() {
|
|
2625
|
+
if (this._editing) return false;
|
|
2626
|
+
return super._shouldHandleWheel();
|
|
2627
|
+
}
|
|
2628
|
+
_applyWheelDelta(direction, event) {
|
|
2629
|
+
const range = (this.max ?? 100) - (this.min ?? 0);
|
|
2630
|
+
if (range === 0) return;
|
|
2631
|
+
const effectiveStep = resolveAxisStep(range, this.stops, this.step, event.shiftKey);
|
|
2632
|
+
this._applyDelta(direction * effectiveStep);
|
|
2633
|
+
}
|
|
5340
2634
|
_parseValue() {
|
|
5341
2635
|
return Number.parseFloat(this.value) || 0;
|
|
5342
2636
|
}
|
|
@@ -5359,6 +2653,11 @@ let EditableNumber = class EditableNumber extends EditableLabel {
|
|
|
5359
2653
|
return n;
|
|
5360
2654
|
}
|
|
5361
2655
|
_snap(n) {
|
|
2656
|
+
if (this.stops && this.stops > 1) {
|
|
2657
|
+
const min = this.min ?? 0;
|
|
2658
|
+
const stopStep = ((this.max ?? 100) - min) / this.stops;
|
|
2659
|
+
return Math.round((n - min) / stopStep) * stopStep + min;
|
|
2660
|
+
}
|
|
5362
2661
|
if (!this.step) return n;
|
|
5363
2662
|
return Math.round(n / this.step) * this.step;
|
|
5364
2663
|
}
|
|
@@ -5549,6 +2848,7 @@ let EditableNumber = class EditableNumber extends EditableLabel {
|
|
|
5549
2848
|
__decorate([property({ type: Number })], EditableNumber.prototype, "min", void 0);
|
|
5550
2849
|
__decorate([property({ type: Number })], EditableNumber.prototype, "max", void 0);
|
|
5551
2850
|
__decorate([property({ type: Number })], EditableNumber.prototype, "step", void 0);
|
|
2851
|
+
__decorate([property({ type: Number })], EditableNumber.prototype, "stops", void 0);
|
|
5552
2852
|
__decorate([property({
|
|
5553
2853
|
type: Number,
|
|
5554
2854
|
attribute: `drag-sensitivity`
|
|
@@ -5971,9 +3271,7 @@ let VerticalListElement = class VerticalListElement extends LitElement {
|
|
|
5971
3271
|
}
|
|
5972
3272
|
break;
|
|
5973
3273
|
}
|
|
5974
|
-
case `Escape`:
|
|
5975
|
-
this._clearSelection();
|
|
5976
|
-
break;
|
|
3274
|
+
case `Escape`: this._clearSelection();
|
|
5977
3275
|
}
|
|
5978
3276
|
};
|
|
5979
3277
|
this._onClick = (e) => {
|
|
@@ -6061,7 +3359,7 @@ let VerticalListElement = class VerticalListElement extends LitElement {
|
|
|
6061
3359
|
this._selectedItems = remapped;
|
|
6062
3360
|
}
|
|
6063
3361
|
this._syncItemStates();
|
|
6064
|
-
}
|
|
3362
|
+
} else if (changed.has(`checkboxRenderer`) && this.interactionMode === `checked`) this._syncCheckboxes();
|
|
6065
3363
|
}
|
|
6066
3364
|
/** The most recently selected item, or `undefined` if nothing is selected. */
|
|
6067
3365
|
get selectedItem() {
|
|
@@ -6142,7 +3440,7 @@ let VerticalListElement = class VerticalListElement extends LitElement {
|
|
|
6142
3440
|
_replaceSelection(item) {
|
|
6143
3441
|
if (this.selectionMode === `none`) return;
|
|
6144
3442
|
const previous = this._selectedItems;
|
|
6145
|
-
const next = new Set([item]);
|
|
3443
|
+
const next = /* @__PURE__ */ new Set([item]);
|
|
6146
3444
|
this._selectedItems = next;
|
|
6147
3445
|
this.#selectionAnchor = item;
|
|
6148
3446
|
this._syncItemStates();
|
|
@@ -6229,7 +3527,7 @@ let VerticalListElement = class VerticalListElement extends LitElement {
|
|
|
6229
3527
|
} else if (e.shiftKey && (this.selectionMode === `multiple` || mode === `vscode`)) this._rangeSelectTo(item);
|
|
6230
3528
|
else this._replaceSelection(item);
|
|
6231
3529
|
break;
|
|
6232
|
-
case `checked`:
|
|
3530
|
+
case `checked`:
|
|
6233
3531
|
}
|
|
6234
3532
|
}
|
|
6235
3533
|
_handleSpaceKey(item) {
|
|
@@ -6257,6 +3555,7 @@ let VerticalListElement = class VerticalListElement extends LitElement {
|
|
|
6257
3555
|
}
|
|
6258
3556
|
_syncCheckboxes() {
|
|
6259
3557
|
const inCheckedMode = this.interactionMode === `checked`;
|
|
3558
|
+
const wantsCustom = typeof this.checkboxRenderer === `function`;
|
|
6260
3559
|
if (inCheckedMode) for (const inner of Array.from(this.children)) {
|
|
6261
3560
|
if (!inner.hasAttribute(`data-list-item`)) continue;
|
|
6262
3561
|
if (inner.parentElement !== this) continue;
|
|
@@ -6281,24 +3580,70 @@ let VerticalListElement = class VerticalListElement extends LitElement {
|
|
|
6281
3580
|
this.#customWrappers.clear();
|
|
6282
3581
|
}
|
|
6283
3582
|
for (const el of this.querySelectorAll(`li`)) {
|
|
6284
|
-
|
|
6285
|
-
if (inCheckedMode) {
|
|
6286
|
-
if (
|
|
6287
|
-
|
|
6288
|
-
|
|
6289
|
-
|
|
6290
|
-
|
|
6291
|
-
|
|
6292
|
-
|
|
6293
|
-
|
|
6294
|
-
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
cb.checked
|
|
6299
|
-
|
|
3583
|
+
const existing = el.querySelector(`.ixfx-list-checkbox`);
|
|
3584
|
+
if (!inCheckedMode) {
|
|
3585
|
+
if (existing) existing.remove();
|
|
3586
|
+
continue;
|
|
3587
|
+
}
|
|
3588
|
+
const existingIsCustom = existing?.classList.contains(`ixfx-list-checkbox-custom`) ?? false;
|
|
3589
|
+
if (existing && existingIsCustom !== wantsCustom) existing.remove();
|
|
3590
|
+
let cb = el.querySelector(`.ixfx-list-checkbox`);
|
|
3591
|
+
if (!cb) {
|
|
3592
|
+
cb = wantsCustom ? this._createCustomCheckbox(el) : this._createNativeCheckboxCell(el);
|
|
3593
|
+
el.prepend(cb);
|
|
3594
|
+
}
|
|
3595
|
+
const checked = this._selectedItems.has(el);
|
|
3596
|
+
if (wantsCustom) {
|
|
3597
|
+
cb.setAttribute(`aria-checked`, String(checked));
|
|
3598
|
+
cb.toggleAttribute(`data-checked`, checked);
|
|
3599
|
+
if (this.checkboxRenderer) render(this.checkboxRenderer(checked), cb);
|
|
3600
|
+
} else {
|
|
3601
|
+
const input = cb.querySelector(`input.ixfx-list-checkbox`);
|
|
3602
|
+
if (input) input.checked = checked;
|
|
3603
|
+
}
|
|
6300
3604
|
}
|
|
6301
3605
|
}
|
|
3606
|
+
/**
|
|
3607
|
+
* Native checkbox cell: a span that stretches to the row's full cross-axis
|
|
3608
|
+
* (so the entire column height is a click target) with a real `<input>`
|
|
3609
|
+
* centred inside. The span owns the click; the input is purely visual and
|
|
3610
|
+
* has `pointer-events:none` so a single click produces one toggle.
|
|
3611
|
+
*/
|
|
3612
|
+
_createNativeCheckboxCell(el) {
|
|
3613
|
+
const cell = document.createElement(`span`);
|
|
3614
|
+
cell.className = `ixfx-list-checkbox ixfx-list-checkbox-native`;
|
|
3615
|
+
cell.style.cssText = `display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;align-self:stretch;width:18px;margin:0 6px 0 0;cursor:pointer;pointer-events:auto`;
|
|
3616
|
+
cell.tabIndex = -1;
|
|
3617
|
+
cell.setAttribute(`role`, `checkbox`);
|
|
3618
|
+
cell.setAttribute(`part`, `checkbox`);
|
|
3619
|
+
cell.addEventListener(`click`, (e) => {
|
|
3620
|
+
e.stopPropagation();
|
|
3621
|
+
this._toggleItem(el);
|
|
3622
|
+
});
|
|
3623
|
+
const input = document.createElement(`input`);
|
|
3624
|
+
input.type = `checkbox`;
|
|
3625
|
+
input.className = `ixfx-list-checkbox`;
|
|
3626
|
+
input.style.cssText = `pointer-events:none;cursor:pointer;margin:0`;
|
|
3627
|
+
cell.appendChild(input);
|
|
3628
|
+
return cell;
|
|
3629
|
+
}
|
|
3630
|
+
/**
|
|
3631
|
+
* Custom checkbox cell: same shape as the native cell (a stretching span)
|
|
3632
|
+
* so behaviour is identical. The renderer's content goes inside.
|
|
3633
|
+
*/
|
|
3634
|
+
_createCustomCheckbox(el) {
|
|
3635
|
+
const span = document.createElement(`span`);
|
|
3636
|
+
span.className = `ixfx-list-checkbox ixfx-list-checkbox-custom`;
|
|
3637
|
+
span.style.cssText = `display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;align-self:stretch;width:24px;margin:0 6px 0 0;cursor:pointer;pointer-events:auto`;
|
|
3638
|
+
span.tabIndex = -1;
|
|
3639
|
+
span.setAttribute(`role`, `checkbox`);
|
|
3640
|
+
span.setAttribute(`part`, `checkbox`);
|
|
3641
|
+
span.addEventListener(`click`, (e) => {
|
|
3642
|
+
e.stopPropagation();
|
|
3643
|
+
this._toggleItem(el);
|
|
3644
|
+
});
|
|
3645
|
+
return span;
|
|
3646
|
+
}
|
|
6302
3647
|
_findListItem(path) {
|
|
6303
3648
|
for (const target of path) {
|
|
6304
3649
|
if (!(target instanceof Element)) continue;
|
|
@@ -6360,8 +3705,14 @@ let VerticalListElement = class VerticalListElement extends LitElement {
|
|
|
6360
3705
|
padding: 0;
|
|
6361
3706
|
width: 100%;
|
|
6362
3707
|
height: 100%;
|
|
3708
|
+
overflow-x: hidden;
|
|
6363
3709
|
overflow-y: auto;
|
|
6364
3710
|
box-sizing: border-box;
|
|
3711
|
+
/* Scrollbar theming: end users override these CSS variables to control
|
|
3712
|
+
the native scrollbar (scrollbar-width, scrollbar-gutter, scrollbar-color). */
|
|
3713
|
+
scrollbar-width: var(--list-scrollbar-width, auto);
|
|
3714
|
+
scrollbar-gutter: var(--list-scrollbar-gutter, auto);
|
|
3715
|
+
scrollbar-color: var(--list-scrollbar-color, auto);
|
|
6365
3716
|
}
|
|
6366
3717
|
|
|
6367
3718
|
::slotted([hidden]) {
|
|
@@ -6391,6 +3742,25 @@ let VerticalListElement = class VerticalListElement extends LitElement {
|
|
|
6391
3742
|
outline: 1px solid transparent;
|
|
6392
3743
|
}
|
|
6393
3744
|
|
|
3745
|
+
/* In checked mode, only the checkbox column is clickable; the row body
|
|
3746
|
+
gets a default cursor so it doesn't suggest otherwise. */
|
|
3747
|
+
:host([interaction-mode="checked"]) ::slotted(li),
|
|
3748
|
+
:host([interaction-mode="checked"]) ::slotted([data-list-item]) {
|
|
3749
|
+
cursor: default;
|
|
3750
|
+
}
|
|
3751
|
+
|
|
3752
|
+
/* Wrapper inserted around custom [data-list-item] elements in checked mode.
|
|
3753
|
+
Provides the flex layout so the injected checkbox can stretch to the
|
|
3754
|
+
row's full height via align-self:stretch. */
|
|
3755
|
+
.ixfx-custom-row {
|
|
3756
|
+
display: flex;
|
|
3757
|
+
align-items: center;
|
|
3758
|
+
min-height: var(--list-item-height, 28px);
|
|
3759
|
+
box-sizing: border-box;
|
|
3760
|
+
cursor: default;
|
|
3761
|
+
user-select: none;
|
|
3762
|
+
}
|
|
3763
|
+
|
|
6394
3764
|
::slotted([data-tickled]) {
|
|
6395
3765
|
background: var(--item-bg-tickled);
|
|
6396
3766
|
outline: var(--item-border-tickled);
|
|
@@ -6498,6 +3868,7 @@ __decorate([property({
|
|
|
6498
3868
|
attribute: `interaction-mode`
|
|
6499
3869
|
})], VerticalListElement.prototype, "interactionMode", void 0);
|
|
6500
3870
|
__decorate([property({ attribute: false })], VerticalListElement.prototype, "filterPredicate", void 0);
|
|
3871
|
+
__decorate([property({ attribute: false })], VerticalListElement.prototype, "checkboxRenderer", void 0);
|
|
6501
3872
|
__decorate([state()], VerticalListElement.prototype, "_selectedItems", void 0);
|
|
6502
3873
|
__decorate([state()], VerticalListElement.prototype, "_searchVisible", void 0);
|
|
6503
3874
|
__decorate([state()], VerticalListElement.prototype, "_searchQuery", void 0);
|
|
@@ -6633,6 +4004,441 @@ function createVerticalListAdapter(renderItem, options) {
|
|
|
6633
4004
|
return adapter;
|
|
6634
4005
|
}
|
|
6635
4006
|
//#endregion
|
|
4007
|
+
//#region src/notifier/notification-pill.ts
|
|
4008
|
+
let NotificationPillElement = class NotificationPillElement extends LitElement {
|
|
4009
|
+
constructor(..._args) {
|
|
4010
|
+
super(..._args);
|
|
4011
|
+
this.notificationType = `info`;
|
|
4012
|
+
this.message = ``;
|
|
4013
|
+
this.dismissing = false;
|
|
4014
|
+
this.notificationId = ``;
|
|
4015
|
+
}
|
|
4016
|
+
#handleClick() {
|
|
4017
|
+
this.#emitTap();
|
|
4018
|
+
}
|
|
4019
|
+
#handleKeyDown(e) {
|
|
4020
|
+
if (e.key === `Enter` || e.key === ` `) {
|
|
4021
|
+
e.preventDefault();
|
|
4022
|
+
this.#emitTap();
|
|
4023
|
+
}
|
|
4024
|
+
}
|
|
4025
|
+
#emitTap() {
|
|
4026
|
+
this.dispatchEvent(new CustomEvent(`pill-tap`, {
|
|
4027
|
+
detail: { id: this.notificationId },
|
|
4028
|
+
bubbles: true,
|
|
4029
|
+
composed: true
|
|
4030
|
+
}));
|
|
4031
|
+
}
|
|
4032
|
+
#renderIcon() {
|
|
4033
|
+
if (!this.icon) return nothing;
|
|
4034
|
+
if (this.icon.startsWith(`<svg`)) return html`<span class="pill-icon">${unsafeHTML(this.icon)}</span>`;
|
|
4035
|
+
if (!getIcon(this.icon)) return nothing;
|
|
4036
|
+
return html`<ixfx-icon class="pill-icon" name="${this.icon}"></ixfx-icon>`;
|
|
4037
|
+
}
|
|
4038
|
+
render() {
|
|
4039
|
+
return html`
|
|
4040
|
+
<button
|
|
4041
|
+
type="button"
|
|
4042
|
+
class="pill"
|
|
4043
|
+
notification-type="${this.notificationType}"
|
|
4044
|
+
@click=${this.#handleClick}
|
|
4045
|
+
@keydown=${this.#handleKeyDown}
|
|
4046
|
+
aria-label="${this.message}"
|
|
4047
|
+
>
|
|
4048
|
+
${this.#renderIcon()}
|
|
4049
|
+
<span class="pill-message">${this.message}</span>
|
|
4050
|
+
</button>
|
|
4051
|
+
`;
|
|
4052
|
+
}
|
|
4053
|
+
static {
|
|
4054
|
+
this.styles = [themeFallbacks, css`
|
|
4055
|
+
:host {
|
|
4056
|
+
display: block;
|
|
4057
|
+
}
|
|
4058
|
+
|
|
4059
|
+
.pill {
|
|
4060
|
+
appearance: none;
|
|
4061
|
+
cursor: pointer;
|
|
4062
|
+
font-family: var(--font-family, inherit);
|
|
4063
|
+
font-size: var(--text-m, 12px);
|
|
4064
|
+
padding: var(--space-s, 4px) var(--space-m, 8px);
|
|
4065
|
+
border-radius: var(--radius-l, 6px);
|
|
4066
|
+
border: 1px solid var(--surface-6, #666);
|
|
4067
|
+
display: inline-flex;
|
|
4068
|
+
align-items: center;
|
|
4069
|
+
gap: var(--space-s, 4px);
|
|
4070
|
+
max-width: 300px;
|
|
4071
|
+
box-shadow: var(--shadow-m);
|
|
4072
|
+
transition: opacity 0.2s ease-out, transform 0.2s ease-out;
|
|
4073
|
+
pointer-events: auto;
|
|
4074
|
+
}
|
|
4075
|
+
|
|
4076
|
+
:host([dismissing]) .pill {
|
|
4077
|
+
opacity: 0;
|
|
4078
|
+
transform: translateX(20px);
|
|
4079
|
+
}
|
|
4080
|
+
|
|
4081
|
+
.pill[notification-type="info"] {
|
|
4082
|
+
background: var(--surface-5, #555);
|
|
4083
|
+
color: var(--surface-5-text, #fff);
|
|
4084
|
+
}
|
|
4085
|
+
|
|
4086
|
+
.pill[notification-type="warning"] {
|
|
4087
|
+
background: color-mix(in oklch, oklch(65% 0.18 70) 30%, var(--surface-5));
|
|
4088
|
+
border-color: oklch(65% 0.18 70);
|
|
4089
|
+
color: var(--surface-5-text, #fff);
|
|
4090
|
+
}
|
|
4091
|
+
|
|
4092
|
+
.pill[notification-type="error"] {
|
|
4093
|
+
background: var(--error, #c00);
|
|
4094
|
+
border-color: var(--error, #c00);
|
|
4095
|
+
color: var(--error-text, #fff);
|
|
4096
|
+
}
|
|
4097
|
+
|
|
4098
|
+
.pill-icon {
|
|
4099
|
+
display: inline-flex;
|
|
4100
|
+
align-items: center;
|
|
4101
|
+
flex-shrink: 0;
|
|
4102
|
+
}
|
|
4103
|
+
|
|
4104
|
+
.pill-icon ixfx-icon {
|
|
4105
|
+
font-size: var(--text-m, 12px);
|
|
4106
|
+
}
|
|
4107
|
+
|
|
4108
|
+
.pill-message {
|
|
4109
|
+
white-space: nowrap;
|
|
4110
|
+
overflow: hidden;
|
|
4111
|
+
text-overflow: ellipsis;
|
|
4112
|
+
}
|
|
4113
|
+
|
|
4114
|
+
.pill:focus-visible {
|
|
4115
|
+
outline: 2px solid var(--accent, #4a9);
|
|
4116
|
+
outline-offset: 2px;
|
|
4117
|
+
}
|
|
4118
|
+
|
|
4119
|
+
@media (prefers-reduced-motion: reduce) {
|
|
4120
|
+
.pill {
|
|
4121
|
+
transition: opacity 0.1s ease-out;
|
|
4122
|
+
transform: none !important;
|
|
4123
|
+
}
|
|
4124
|
+
}
|
|
4125
|
+
`];
|
|
4126
|
+
}
|
|
4127
|
+
};
|
|
4128
|
+
__decorate([property({
|
|
4129
|
+
type: String,
|
|
4130
|
+
attribute: `notification-type`
|
|
4131
|
+
})], NotificationPillElement.prototype, "notificationType", void 0);
|
|
4132
|
+
__decorate([property({ type: String })], NotificationPillElement.prototype, "message", void 0);
|
|
4133
|
+
__decorate([property({ type: String })], NotificationPillElement.prototype, "icon", void 0);
|
|
4134
|
+
__decorate([property({
|
|
4135
|
+
type: Boolean,
|
|
4136
|
+
reflect: true
|
|
4137
|
+
})], NotificationPillElement.prototype, "dismissing", void 0);
|
|
4138
|
+
__decorate([property({
|
|
4139
|
+
type: String,
|
|
4140
|
+
attribute: `notification-id`
|
|
4141
|
+
})], NotificationPillElement.prototype, "notificationId", void 0);
|
|
4142
|
+
NotificationPillElement = __decorate([safeCustomElement(`ixfx-notification-pill`)], NotificationPillElement);
|
|
4143
|
+
//#endregion
|
|
4144
|
+
//#region src/notifier/pill-renderer.ts
|
|
4145
|
+
const ROW_SPACING = 8;
|
|
4146
|
+
const DEFAULT_ROW_HEIGHT = 40;
|
|
4147
|
+
const STACK_OFFSET_STEP = 4;
|
|
4148
|
+
const STACK_OPACITY_BASE = .7;
|
|
4149
|
+
const STACK_OPACITY_DECAY = .15;
|
|
4150
|
+
const STACK_OPACITY_MIN = .2;
|
|
4151
|
+
function edgesOf(position) {
|
|
4152
|
+
return {
|
|
4153
|
+
vertical: position.startsWith(`top`) ? `top` : `bottom`,
|
|
4154
|
+
horizontal: position.endsWith(`-left`) ? `left` : position.endsWith(`-right`) ? `right` : `middle`
|
|
4155
|
+
};
|
|
4156
|
+
}
|
|
4157
|
+
function anchorStyles(position, safeArea) {
|
|
4158
|
+
const { vertical, horizontal } = edgesOf(position);
|
|
4159
|
+
const vMargin = `calc(var(--space-l, 12px) + ${(vertical === `top` ? safeArea.top : safeArea.bottom) ?? 0}px)`;
|
|
4160
|
+
let css = `position: fixed; `;
|
|
4161
|
+
css += vertical === `top` ? `top: ${vMargin}; bottom: auto; ` : `bottom: ${vMargin}; top: auto; `;
|
|
4162
|
+
if (horizontal === `left`) {
|
|
4163
|
+
const hMargin = `calc(var(--space-l, 12px) + ${safeArea.left ?? 0}px)`;
|
|
4164
|
+
css += `left: ${hMargin}; right: auto;`;
|
|
4165
|
+
} else if (horizontal === `right`) {
|
|
4166
|
+
const hMargin = `calc(var(--space-l, 12px) + ${safeArea.right ?? 0}px)`;
|
|
4167
|
+
css += `right: ${hMargin}; left: auto;`;
|
|
4168
|
+
} else css += `left: 50%; right: auto;`;
|
|
4169
|
+
return css;
|
|
4170
|
+
}
|
|
4171
|
+
/** Entry-animation starting transform: pills slide in from the edge they're anchored to. */
|
|
4172
|
+
function entryTransform(edges) {
|
|
4173
|
+
const dy = edges.vertical === `top` ? -20 : 20;
|
|
4174
|
+
if (edges.horizontal === `middle`) return `translateX(-50%) translate(0, ${dy}px)`;
|
|
4175
|
+
return `translate(${edges.horizontal === `left` ? -20 : 20}px, ${dy}px)`;
|
|
4176
|
+
}
|
|
4177
|
+
function restingTransform(edges, dx, dy) {
|
|
4178
|
+
if (edges.horizontal === `middle`) return `translateX(-50%) translate(${dx}px, ${dy}px)`;
|
|
4179
|
+
return `translate(${dx}px, ${dy}px)`;
|
|
4180
|
+
}
|
|
4181
|
+
function createPillRenderer(options = {}) {
|
|
4182
|
+
const position = options.position ?? `top-right`;
|
|
4183
|
+
const queueDisplay = options.queueDisplay ?? `list`;
|
|
4184
|
+
const safeArea = options.safeArea ?? {};
|
|
4185
|
+
const edges = edgesOf(position);
|
|
4186
|
+
let container = null;
|
|
4187
|
+
let hooks = null;
|
|
4188
|
+
const pills = /* @__PURE__ */ new Map();
|
|
4189
|
+
let rowHeight = DEFAULT_ROW_HEIGHT;
|
|
4190
|
+
let measured = false;
|
|
4191
|
+
function ensureContainer() {
|
|
4192
|
+
if (container) return container;
|
|
4193
|
+
container = document.createElement(`div`);
|
|
4194
|
+
container.className = `ixfx-notification-container`;
|
|
4195
|
+
container.setAttribute(`role`, `region`);
|
|
4196
|
+
container.setAttribute(`aria-label`, `Notifications`);
|
|
4197
|
+
document.body.appendChild(container);
|
|
4198
|
+
return container;
|
|
4199
|
+
}
|
|
4200
|
+
function updateAttributes(el, notification) {
|
|
4201
|
+
el.setAttribute(`notification-type`, notification.type);
|
|
4202
|
+
el.setAttribute(`message`, notification.message);
|
|
4203
|
+
if (notification.icon) el.setAttribute(`icon`, notification.icon);
|
|
4204
|
+
else el.removeAttribute(`icon`);
|
|
4205
|
+
}
|
|
4206
|
+
function createPillElement(notification) {
|
|
4207
|
+
const el = document.createElement(`ixfx-notification-pill`);
|
|
4208
|
+
el.setAttribute(`notification-id`, notification.id);
|
|
4209
|
+
el.style.cssText = anchorStyles(position, safeArea);
|
|
4210
|
+
updateAttributes(el, notification);
|
|
4211
|
+
el.style.opacity = `0`;
|
|
4212
|
+
el.style.transform = entryTransform(edges);
|
|
4213
|
+
el.addEventListener(`pill-tap`, (e) => {
|
|
4214
|
+
const customEvent = e;
|
|
4215
|
+
hooks?.onTap(customEvent.detail.id);
|
|
4216
|
+
});
|
|
4217
|
+
return el;
|
|
4218
|
+
}
|
|
4219
|
+
function measureRowHeight(el) {
|
|
4220
|
+
if (measured) return;
|
|
4221
|
+
requestAnimationFrame(() => {
|
|
4222
|
+
const height = el.getBoundingClientRect().height;
|
|
4223
|
+
if (height > 0) {
|
|
4224
|
+
rowHeight = height;
|
|
4225
|
+
measured = true;
|
|
4226
|
+
}
|
|
4227
|
+
});
|
|
4228
|
+
}
|
|
4229
|
+
/** Positions every currently-visible pill for its rank in `order` (index 0 = front/oldest). */
|
|
4230
|
+
function applyLayout(order) {
|
|
4231
|
+
const total = order.length;
|
|
4232
|
+
order.forEach((notification, index) => {
|
|
4233
|
+
const entry = pills.get(notification.id);
|
|
4234
|
+
if (!entry) return;
|
|
4235
|
+
const el = entry.element;
|
|
4236
|
+
let dx = 0;
|
|
4237
|
+
let dy = 0;
|
|
4238
|
+
let opacity = 1;
|
|
4239
|
+
let pointerEvents = `auto`;
|
|
4240
|
+
let filter = `none`;
|
|
4241
|
+
if (queueDisplay === `list`) {
|
|
4242
|
+
const step = index * (rowHeight + ROW_SPACING);
|
|
4243
|
+
dy = edges.vertical === `top` ? step : -step;
|
|
4244
|
+
} else {
|
|
4245
|
+
const step = index * STACK_OFFSET_STEP;
|
|
4246
|
+
dy = edges.vertical === `top` ? step : -step;
|
|
4247
|
+
dx = edges.horizontal === `left` ? step : edges.horizontal === `right` ? -step : 0;
|
|
4248
|
+
if (index > 0) {
|
|
4249
|
+
const hintIndex = index - 1;
|
|
4250
|
+
opacity = Math.max(STACK_OPACITY_MIN, STACK_OPACITY_BASE - hintIndex * STACK_OPACITY_DECAY);
|
|
4251
|
+
pointerEvents = `none`;
|
|
4252
|
+
filter = `saturate(0.6)`;
|
|
4253
|
+
}
|
|
4254
|
+
}
|
|
4255
|
+
el.style.transition = `opacity 0.2s ease-out, transform 0.2s ease-out`;
|
|
4256
|
+
el.style.opacity = `${opacity}`;
|
|
4257
|
+
el.style.zIndex = `${total - index}`;
|
|
4258
|
+
el.style.pointerEvents = pointerEvents;
|
|
4259
|
+
el.style.filter = filter;
|
|
4260
|
+
el.style.transform = restingTransform(edges, dx, dy);
|
|
4261
|
+
});
|
|
4262
|
+
}
|
|
4263
|
+
function dismiss(id) {
|
|
4264
|
+
const entry = pills.get(id);
|
|
4265
|
+
if (!entry) return;
|
|
4266
|
+
const el = entry.element;
|
|
4267
|
+
el.setAttribute(`dismissing`, `true`);
|
|
4268
|
+
const cleanup = () => {
|
|
4269
|
+
el.removeEventListener(`transitionend`, cleanup);
|
|
4270
|
+
el.remove();
|
|
4271
|
+
pills.delete(id);
|
|
4272
|
+
if (container && pills.size === 0) {
|
|
4273
|
+
container.remove();
|
|
4274
|
+
container = null;
|
|
4275
|
+
measured = false;
|
|
4276
|
+
rowHeight = DEFAULT_ROW_HEIGHT;
|
|
4277
|
+
}
|
|
4278
|
+
};
|
|
4279
|
+
el.addEventListener(`transitionend`, cleanup);
|
|
4280
|
+
setTimeout(cleanup, 300);
|
|
4281
|
+
}
|
|
4282
|
+
function setNotifications(notifications, _queueSize) {
|
|
4283
|
+
const cont = ensureContainer();
|
|
4284
|
+
const idsToKeep = new Set(notifications.map((n) => n.id));
|
|
4285
|
+
for (const notification of notifications) {
|
|
4286
|
+
const existing = pills.get(notification.id);
|
|
4287
|
+
if (existing) {
|
|
4288
|
+
existing.notification = notification;
|
|
4289
|
+
updateAttributes(existing.element, notification);
|
|
4290
|
+
continue;
|
|
4291
|
+
}
|
|
4292
|
+
const el = createPillElement(notification);
|
|
4293
|
+
pills.set(notification.id, {
|
|
4294
|
+
element: el,
|
|
4295
|
+
notification
|
|
4296
|
+
});
|
|
4297
|
+
cont.appendChild(el);
|
|
4298
|
+
measureRowHeight(el);
|
|
4299
|
+
}
|
|
4300
|
+
for (const [id] of pills) if (!idsToKeep.has(id)) dismiss(id);
|
|
4301
|
+
requestAnimationFrame(() => applyLayout(notifications));
|
|
4302
|
+
}
|
|
4303
|
+
return {
|
|
4304
|
+
attach(newHooks) {
|
|
4305
|
+
hooks = newHooks;
|
|
4306
|
+
},
|
|
4307
|
+
detach() {
|
|
4308
|
+
for (const [id] of pills) dismiss(id);
|
|
4309
|
+
if (container) {
|
|
4310
|
+
container.remove();
|
|
4311
|
+
container = null;
|
|
4312
|
+
}
|
|
4313
|
+
},
|
|
4314
|
+
setNotifications
|
|
4315
|
+
};
|
|
4316
|
+
}
|
|
4317
|
+
//#endregion
|
|
4318
|
+
//#region src/notifier/manager.ts
|
|
4319
|
+
const options = {
|
|
4320
|
+
renderer: void 0,
|
|
4321
|
+
timeout: 4e3,
|
|
4322
|
+
timeoutError: 8e3,
|
|
4323
|
+
queue: true,
|
|
4324
|
+
queueSize: 3,
|
|
4325
|
+
tapBehaviour: `dismiss`,
|
|
4326
|
+
tapHandlerDefault: void 0
|
|
4327
|
+
};
|
|
4328
|
+
/** Rank-ordered, index 0 = oldest/first (next to be evicted or timed out). Length never exceeds queueSize (or 1 when queuing is disabled). */
|
|
4329
|
+
const visible = [];
|
|
4330
|
+
let renderer = null;
|
|
4331
|
+
let defaultRenderer = null;
|
|
4332
|
+
function getDefaultRenderer() {
|
|
4333
|
+
defaultRenderer ??= createPillRenderer({ position: `top-right` });
|
|
4334
|
+
return defaultRenderer;
|
|
4335
|
+
}
|
|
4336
|
+
function getRenderer() {
|
|
4337
|
+
return renderer ?? getDefaultRenderer();
|
|
4338
|
+
}
|
|
4339
|
+
function syncRenderer() {
|
|
4340
|
+
getRenderer().setNotifications([...visible], options.queueSize);
|
|
4341
|
+
}
|
|
4342
|
+
function clearTimer(managed) {
|
|
4343
|
+
if (managed.timer !== null) {
|
|
4344
|
+
clearTimeout(managed.timer);
|
|
4345
|
+
managed.timer = null;
|
|
4346
|
+
}
|
|
4347
|
+
}
|
|
4348
|
+
/**
|
|
4349
|
+
* A message shown alone takes the full timeout. A message that joined a
|
|
4350
|
+
* non-empty queue at arrival time is permanently "wasQueued" and gets
|
|
4351
|
+
* 1/queueSize of the timeout once it reaches the front. The timer for a
|
|
4352
|
+
* given message is only ever started once - when it first becomes front.
|
|
4353
|
+
*/
|
|
4354
|
+
function startTimer(managed) {
|
|
4355
|
+
const base = managed.type === `error` ? options.timeoutError : options.timeout;
|
|
4356
|
+
const duration = managed.wasQueued ? base / options.queueSize : base;
|
|
4357
|
+
managed.timer = window.setTimeout(() => dismiss(managed.id), duration);
|
|
4358
|
+
}
|
|
4359
|
+
function ensureFrontTimer() {
|
|
4360
|
+
const front = visible[0];
|
|
4361
|
+
if (front && front.timer === null) startTimer(front);
|
|
4362
|
+
}
|
|
4363
|
+
const NotificationManager = {
|
|
4364
|
+
configure(opts) {
|
|
4365
|
+
if (opts.renderer !== void 0) {
|
|
4366
|
+
renderer?.detach?.();
|
|
4367
|
+
renderer = opts.renderer;
|
|
4368
|
+
renderer.attach({ onTap(id) {
|
|
4369
|
+
const notification = visible.find((n) => n.id === id);
|
|
4370
|
+
if (!notification) return;
|
|
4371
|
+
if (notification.onTap) notification.onTap(id);
|
|
4372
|
+
else options.tapHandlerDefault?.(notification);
|
|
4373
|
+
if (options.tapBehaviour === `dismiss`) dismiss(id);
|
|
4374
|
+
} });
|
|
4375
|
+
syncRenderer();
|
|
4376
|
+
}
|
|
4377
|
+
if (opts.timeout !== void 0) options.timeout = opts.timeout;
|
|
4378
|
+
if (opts.timeoutError !== void 0) options.timeoutError = opts.timeoutError;
|
|
4379
|
+
if (opts.queue !== void 0) options.queue = opts.queue;
|
|
4380
|
+
if (opts.queueSize !== void 0) {
|
|
4381
|
+
options.queueSize = Math.max(1, opts.queueSize);
|
|
4382
|
+
while (visible.length > options.queueSize) clearTimer(visible.shift());
|
|
4383
|
+
ensureFrontTimer();
|
|
4384
|
+
syncRenderer();
|
|
4385
|
+
}
|
|
4386
|
+
if (opts.tapBehaviour !== void 0) options.tapBehaviour = opts.tapBehaviour;
|
|
4387
|
+
if (opts.tapHandlerDefault !== void 0) options.tapHandlerDefault = opts.tapHandlerDefault;
|
|
4388
|
+
},
|
|
4389
|
+
notify(content) {
|
|
4390
|
+
const id = crypto.randomUUID();
|
|
4391
|
+
const now = Date.now();
|
|
4392
|
+
const icon = content.icon ?? (content.type === `error` ? `error` : void 0);
|
|
4393
|
+
const managed = {
|
|
4394
|
+
...content,
|
|
4395
|
+
icon,
|
|
4396
|
+
id,
|
|
4397
|
+
createdAt: now,
|
|
4398
|
+
updatedAt: now,
|
|
4399
|
+
timer: null,
|
|
4400
|
+
wasQueued: false
|
|
4401
|
+
};
|
|
4402
|
+
if (options.queue) {
|
|
4403
|
+
if (visible.length >= options.queueSize) clearTimer(visible.shift());
|
|
4404
|
+
managed.wasQueued = visible.length > 0;
|
|
4405
|
+
visible.push(managed);
|
|
4406
|
+
} else {
|
|
4407
|
+
while (visible.length > 0) clearTimer(visible.pop());
|
|
4408
|
+
visible.push(managed);
|
|
4409
|
+
}
|
|
4410
|
+
ensureFrontTimer();
|
|
4411
|
+
syncRenderer();
|
|
4412
|
+
return id;
|
|
4413
|
+
},
|
|
4414
|
+
update(id, content) {
|
|
4415
|
+
const managed = visible.find((n) => n.id === id);
|
|
4416
|
+
if (!managed) return;
|
|
4417
|
+
Object.assign(managed, content);
|
|
4418
|
+
managed.updatedAt = Date.now();
|
|
4419
|
+
if (visible[0] === managed) {
|
|
4420
|
+
clearTimer(managed);
|
|
4421
|
+
startTimer(managed);
|
|
4422
|
+
}
|
|
4423
|
+
syncRenderer();
|
|
4424
|
+
},
|
|
4425
|
+
dismiss(id) {
|
|
4426
|
+
dismiss(id);
|
|
4427
|
+
},
|
|
4428
|
+
dismissAll() {
|
|
4429
|
+
for (const m of visible) clearTimer(m);
|
|
4430
|
+
visible.length = 0;
|
|
4431
|
+
syncRenderer();
|
|
4432
|
+
}
|
|
4433
|
+
};
|
|
4434
|
+
function dismiss(id) {
|
|
4435
|
+
const idx = visible.findIndex((m) => m.id === id);
|
|
4436
|
+
if (idx === -1) return;
|
|
4437
|
+
clearTimer(visible.splice(idx, 1)[0]);
|
|
4438
|
+
ensureFrontTimer();
|
|
4439
|
+
syncRenderer();
|
|
4440
|
+
}
|
|
4441
|
+
//#endregion
|
|
6636
4442
|
//#region src/panel/panel-group.ts
|
|
6637
4443
|
let PanelGroupElement = class PanelGroupElement extends LitElement {
|
|
6638
4444
|
constructor(..._args) {
|
|
@@ -6867,11 +4673,13 @@ let RangeMultiElement = class RangeMultiElement extends LitElement {
|
|
|
6867
4673
|
}
|
|
6868
4674
|
a = newA;
|
|
6869
4675
|
b = newB;
|
|
6870
|
-
} else if (which === `a`)
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
else b
|
|
6874
|
-
|
|
4676
|
+
} else if (which === `a`) {
|
|
4677
|
+
if (v > this.b && this.crossover === `stop`) t.valueAsNumber = this.#scaleTo100(this.a);
|
|
4678
|
+
else a = v;
|
|
4679
|
+
} else if (which === `b`) {
|
|
4680
|
+
if (v < a && this.crossover === `stop`) t.valueAsNumber = this.#scaleTo100(this.b);
|
|
4681
|
+
else b = v;
|
|
4682
|
+
} else throw new Error(`Expected 'a' or 'b', got: '${t.id}'`);
|
|
6875
4683
|
this.setPoles(a, b);
|
|
6876
4684
|
}
|
|
6877
4685
|
setPoles(a, b) {
|
|
@@ -6930,63 +4738,65 @@ let RangeMultiElement = class RangeMultiElement extends LitElement {
|
|
|
6930
4738
|
const currentPos = isVertical ? current.offset.y : current.offset.x;
|
|
6931
4739
|
const amt = (isVertical ? startPos - currentPos : currentPos - startPos) / valuePerPix;
|
|
6932
4740
|
polesChanged = true;
|
|
6933
|
-
if (draggingWhich === `a`)
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
6937
|
-
|
|
6938
|
-
|
|
6939
|
-
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
4741
|
+
if (draggingWhich === `a`) {
|
|
4742
|
+
if (resizeMode === `bipolar`) {
|
|
4743
|
+
const calcA = startA + amt;
|
|
4744
|
+
const calcB = startB - amt;
|
|
4745
|
+
if (calcA < min || calcB > max || calcA > max || calcB < min) return;
|
|
4746
|
+
setPoles(calcA, calcB);
|
|
4747
|
+
} else if (resizeMode === `bipolar-flex`) {
|
|
4748
|
+
let calcA = startA + amt;
|
|
4749
|
+
let calcB = startB;
|
|
4750
|
+
if (startB <= min) calcB = min;
|
|
4751
|
+
else if (startB >= max) calcB = max;
|
|
4752
|
+
else {
|
|
4753
|
+
calcA = startA + amt;
|
|
4754
|
+
calcB = startB - amt;
|
|
4755
|
+
}
|
|
4756
|
+
if (calcA < min) calcA = min;
|
|
4757
|
+
if (calcA > max) calcA = max;
|
|
4758
|
+
if (calcB < min) calcB = min;
|
|
4759
|
+
if (calcB > max) calcB = max;
|
|
4760
|
+
if (calcA > calcB) return;
|
|
4761
|
+
setPoles(calcA, calcB);
|
|
4762
|
+
} else {
|
|
4763
|
+
let constrainedAmt = amt;
|
|
4764
|
+
if (startA + amt < min) constrainedAmt = min - startA;
|
|
4765
|
+
if (startB + constrainedAmt > max) constrainedAmt = max - startB;
|
|
4766
|
+
const finalA = startA + constrainedAmt;
|
|
4767
|
+
const finalB = startB + constrainedAmt;
|
|
4768
|
+
if (finalA >= min && finalB <= max) setPoles(finalA, finalB);
|
|
6946
4769
|
}
|
|
6947
|
-
|
|
6948
|
-
if (
|
|
6949
|
-
|
|
6950
|
-
|
|
6951
|
-
|
|
6952
|
-
|
|
6953
|
-
|
|
6954
|
-
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
|
|
6961
|
-
|
|
6962
|
-
|
|
6963
|
-
|
|
6964
|
-
|
|
6965
|
-
|
|
6966
|
-
|
|
6967
|
-
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
|
|
6972
|
-
|
|
6973
|
-
|
|
4770
|
+
} else if (draggingWhich === `b`) {
|
|
4771
|
+
if (resizeMode === `bipolar`) {
|
|
4772
|
+
const calcA = startA - amt;
|
|
4773
|
+
const calcB = startB + amt;
|
|
4774
|
+
if (calcA < min || calcB > max || calcA > max || calcB < min) return;
|
|
4775
|
+
setPoles(calcA, calcB);
|
|
4776
|
+
} else if (resizeMode === `bipolar-flex`) {
|
|
4777
|
+
let calcA = startA;
|
|
4778
|
+
let calcB = startB + amt;
|
|
4779
|
+
if (startA <= min) calcA = min;
|
|
4780
|
+
else if (startA >= max) calcA = max;
|
|
4781
|
+
else {
|
|
4782
|
+
calcA = startA - amt;
|
|
4783
|
+
calcB = startB + amt;
|
|
4784
|
+
}
|
|
4785
|
+
if (calcA < min) calcA = min;
|
|
4786
|
+
if (calcA > max) calcA = max;
|
|
4787
|
+
if (calcB < min) calcB = min;
|
|
4788
|
+
if (calcB > max) calcB = max;
|
|
4789
|
+
if (calcA > calcB) return;
|
|
4790
|
+
setPoles(calcA, calcB);
|
|
4791
|
+
} else {
|
|
4792
|
+
let constrainedAmt = amt;
|
|
4793
|
+
if (startA + amt < min) constrainedAmt = min - startA;
|
|
4794
|
+
if (startB + constrainedAmt > max) constrainedAmt = max - startB;
|
|
4795
|
+
const finalA = startA + constrainedAmt;
|
|
4796
|
+
const finalB = startB + constrainedAmt;
|
|
4797
|
+
if (finalA >= min && finalB <= max) setPoles(finalA, finalB);
|
|
6974
4798
|
}
|
|
6975
|
-
|
|
6976
|
-
if (calcA > max) calcA = max;
|
|
6977
|
-
if (calcB < min) calcB = min;
|
|
6978
|
-
if (calcB > max) calcB = max;
|
|
6979
|
-
if (calcA > calcB) return;
|
|
6980
|
-
setPoles(calcA, calcB);
|
|
6981
|
-
} else {
|
|
6982
|
-
let constrainedAmt = amt;
|
|
6983
|
-
if (startA + amt < min) constrainedAmt = min - startA;
|
|
6984
|
-
if (startB + constrainedAmt > max) constrainedAmt = max - startB;
|
|
6985
|
-
const finalA = startA + constrainedAmt;
|
|
6986
|
-
const finalB = startB + constrainedAmt;
|
|
6987
|
-
if (finalA >= min && finalB <= max) setPoles(finalA, finalB);
|
|
6988
|
-
}
|
|
6989
|
-
else if (resizeMode === `bipolar`) {
|
|
4799
|
+
} else if (resizeMode === `bipolar`) {
|
|
6990
4800
|
const calcA = startA + amt;
|
|
6991
4801
|
const calcB = startB + amt;
|
|
6992
4802
|
if (calcA < min || calcB > max) return;
|
|
@@ -7317,7 +5127,7 @@ let TabListItemElement = class TabListItemElement extends LitElement {
|
|
|
7317
5127
|
prominenceStyles,
|
|
7318
5128
|
css`
|
|
7319
5129
|
:host {
|
|
7320
|
-
--selected-colour: var(--
|
|
5130
|
+
--selected-colour: var(--surface-2-text);
|
|
7321
5131
|
--selected-border-width: 1px;
|
|
7322
5132
|
--padding: var(--space-m);
|
|
7323
5133
|
display: inline-flex;
|
|
@@ -7343,6 +5153,8 @@ let TabListItemElement = class TabListItemElement extends LitElement {
|
|
|
7343
5153
|
border-bottom-color: var(--indicator-color-bottom, transparent);
|
|
7344
5154
|
border-left-color: var(--indicator-color-left, transparent);
|
|
7345
5155
|
border-right-color: var(--indicator-color-right, transparent);
|
|
5156
|
+
background: var(--surface-5);
|
|
5157
|
+
font-weight: bold;
|
|
7346
5158
|
}
|
|
7347
5159
|
|
|
7348
5160
|
.label {
|
|
@@ -7366,13 +5178,18 @@ let TabListItemElement = class TabListItemElement extends LitElement {
|
|
|
7366
5178
|
}
|
|
7367
5179
|
|
|
7368
5180
|
.toolbar {
|
|
7369
|
-
display:
|
|
5181
|
+
/* Always laid out (display: flex) so the tab's width doesn't shift when
|
|
5182
|
+
the toolbar appears on selection. visibility: hidden keeps the
|
|
5183
|
+
toolbar from receiving pointer events or painting, while preserving
|
|
5184
|
+
the space its contents take up. */
|
|
5185
|
+
display: flex;
|
|
7370
5186
|
align-items: center;
|
|
7371
5187
|
gap: var(--space-xs);
|
|
5188
|
+
visibility: hidden;
|
|
7372
5189
|
}
|
|
7373
5190
|
|
|
7374
5191
|
:host([selected]) .toolbar {
|
|
7375
|
-
|
|
5192
|
+
visibility: visible;
|
|
7376
5193
|
}
|
|
7377
5194
|
|
|
7378
5195
|
slot[name="toolbar"] {
|
|
@@ -7795,86 +5612,11 @@ function monitorIndeterminate(targetElOrQuery, watchedElsOrQueries) {
|
|
|
7795
5612
|
};
|
|
7796
5613
|
}
|
|
7797
5614
|
//#endregion
|
|
7798
|
-
//#region src/util/is-numeric.ts
|
|
7799
|
-
function isNumeric(str) {
|
|
7800
|
-
if (typeof str === `number`) return true;
|
|
7801
|
-
if (typeof str !== `string`) return false;
|
|
7802
|
-
const trimmed = str.trim();
|
|
7803
|
-
return trimmed !== `` && !Number.isNaN(Number(trimmed));
|
|
7804
|
-
}
|
|
7805
|
-
//#endregion
|
|
7806
|
-
//#region src/util/tooltip.ts
|
|
7807
|
-
var _TooltipElement;
|
|
7808
|
-
let TooltipElement = class TooltipElement extends LitElement {
|
|
7809
|
-
static {
|
|
7810
|
-
_TooltipElement = this;
|
|
7811
|
-
}
|
|
7812
|
-
constructor(..._args) {
|
|
7813
|
-
super(..._args);
|
|
7814
|
-
this.valueFormatTooltip = _TooltipElement.defaultFormatter;
|
|
7815
|
-
this.orientation = `top`;
|
|
7816
|
-
this.anchor = `--tooltip`;
|
|
7817
|
-
}
|
|
7818
|
-
static {
|
|
7819
|
-
this.numberFormatter = (v) => Math.floor(v).toString();
|
|
7820
|
-
}
|
|
7821
|
-
static {
|
|
7822
|
-
this.defaultFormatter = (v) => {
|
|
7823
|
-
if (typeof v === `number`) {
|
|
7824
|
-
if (Number.isInteger(v)) return v.toString();
|
|
7825
|
-
return v.toFixed(2);
|
|
7826
|
-
} else if (typeof v === `string`) return v;
|
|
7827
|
-
else return JSON.stringify(v);
|
|
7828
|
-
};
|
|
7829
|
-
}
|
|
7830
|
-
#renderIcon() {
|
|
7831
|
-
if (!this.icon) return nothing;
|
|
7832
|
-
if (this.icon.startsWith(`<svg`)) return html`<span class="tooltip-icon" style="display:inline-flex;align-items:center;margin-right:0.25em">${unsafeHTML(this.icon)}</span>`;
|
|
7833
|
-
if (!getIcon(this.icon)) return nothing;
|
|
7834
|
-
return html`<ixfx-icon class="tooltip-icon" style="margin-right:0.25em" name="${this.icon}"></ixfx-icon>`;
|
|
7835
|
-
}
|
|
7836
|
-
render() {
|
|
7837
|
-
const classes = {
|
|
7838
|
-
"tooltip": true,
|
|
7839
|
-
"tooltip-orientation-top": this.orientation === `top`,
|
|
7840
|
-
"tooltip-orientation-bottom": this.orientation === `bottom`,
|
|
7841
|
-
"tooltip-orientation-right": this.orientation === `right`,
|
|
7842
|
-
"tooltip-orientation-left": this.orientation === `left`,
|
|
7843
|
-
"tooltip-type-text": true,
|
|
7844
|
-
"tooltip-type-number": false,
|
|
7845
|
-
"tooltip-style-bubble": true
|
|
7846
|
-
};
|
|
7847
|
-
let value = ``;
|
|
7848
|
-
switch (typeof this.value) {
|
|
7849
|
-
case `number`:
|
|
7850
|
-
classes[`tooltip-type-number`] = true;
|
|
7851
|
-
value = this.valueFormatTooltip(this.value);
|
|
7852
|
-
break;
|
|
7853
|
-
case `string`:
|
|
7854
|
-
if (isNumeric(this.value)) {
|
|
7855
|
-
classes[`tooltip-type-number`] = true;
|
|
7856
|
-
value = this.valueFormatTooltip(Number.parseFloat(this.value));
|
|
7857
|
-
} else value = this.value;
|
|
7858
|
-
break;
|
|
7859
|
-
default: value = JSON.stringify(this.value);
|
|
7860
|
-
}
|
|
7861
|
-
return html`<output style="--anchor-id: ${this.anchor}" class=${classMap(classes)}>${this.#renderIcon()}${value}</output>`;
|
|
7862
|
-
}
|
|
7863
|
-
createRenderRoot() {
|
|
7864
|
-
return this;
|
|
7865
|
-
}
|
|
7866
|
-
};
|
|
7867
|
-
__decorate([property({ type: String })], TooltipElement.prototype, "orientation", void 0);
|
|
7868
|
-
__decorate([property({ type: String })], TooltipElement.prototype, "anchor", void 0);
|
|
7869
|
-
__decorate([property()], TooltipElement.prototype, "value", void 0);
|
|
7870
|
-
__decorate([property({ type: String })], TooltipElement.prototype, "icon", void 0);
|
|
7871
|
-
TooltipElement = _TooltipElement = __decorate([safeCustomElement(`ixfx-tooltip`)], TooltipElement);
|
|
7872
|
-
//#endregion
|
|
7873
5615
|
//#region src/index.ts
|
|
7874
5616
|
function init() {
|
|
7875
5617
|
console.log(`Init`);
|
|
7876
5618
|
}
|
|
7877
5619
|
//#endregion
|
|
7878
|
-
export { AcTextElement, AcTokenElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, EditableLabel, EditableNumber, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, LabelledRadialInput, LabelledRangeInput, LedElement, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, SelectHorizontalElement, SnapContainer, SplitButton, SplitLayoutElement, SwipeElement, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TimelineController, TimelineTrackTabElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeListElement, VerticalListElement, XyPad, applyAgeModification, applyHighlights, attachTimelineInteractions, buildHighlightTargets, clearHighlights, collectDataResult, computeColour, createAcCompletionProvider, createElementIncrSearch, createFuzzySearch, createIncrSearch, createTreeListAdapter, createVerticalListAdapter, getIcon, hasIcon, iconBus, init, monitorIndeterminate, parseColourScaleAttr, readBaseColour, registerIcon, resolveCssVars, resolveGrid, svgToDataUri, timelineStyles };
|
|
5620
|
+
export { AcTextElement, AcTokenElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, EditableLabel, EditableNumber, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, LabelledRadialInput, LabelledRangeInput, LedElement, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, NotificationManager, NotificationPillElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, SelectHorizontalElement, SliderInputElement, SnapContainer, SplitButton, SplitLayoutElement, SwipeElement, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TimelineController, TimelineTrackTabElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeListElement, VerticalListElement, XyPad, applyAgeModification, applyHighlights, attachTimelineInteractions, buildHighlightTargets, clearHighlights, collectDataResult, computeColour, createAcCompletionProvider, createElementIncrSearch, createFuzzySearch, createIncrSearch, createPillRenderer, createTreeListAdapter, createVerticalListAdapter, getIcon, hasIcon, iconBus, init, monitorIndeterminate, parseColourScaleAttr, readBaseColour, registerIcon, resolveCssVars, resolveGrid, svgToDataUri, timelineStyles };
|
|
7879
5621
|
|
|
7880
5622
|
//# sourceMappingURL=index.js.map
|