domma-js 0.54.0 → 0.55.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.
@@ -30,6 +30,18 @@ export interface ComponentInstance {
30
30
  /** Update component options at runtime */
31
31
  setOptions(newOptions: Record<string, any>): this;
32
32
 
33
+ /**
34
+ * Listen for a component event - the name of an `onX` option without `on`, lower-cased
35
+ * ('change', 'open', 'beforeclose'). The handler gets the same arguments as the option;
36
+ * returning false from a `before...` handler cancels. The same event is dispatched on
37
+ * `element` as `dm:<component>:<event>` with `detail = {instance, args}`.
38
+ */
39
+ on(event: string, handler: (...args: any[]) => any): this;
40
+ /** Listen once */
41
+ once(event: string, handler: (...args: any[]) => any): this;
42
+ /** Stop listening (every handler for the event when none is given) */
43
+ off(event: string, handler?: (...args: any[]) => any): this;
44
+
33
45
  /** Destroy the component and cleanup event listeners */
34
46
  destroy(): void;
35
47
  }
@@ -79,6 +91,14 @@ export interface ModalOptions {
79
91
  animationDuration?: number;
80
92
  /** Show close button */
81
93
  closeButton?: boolean;
94
+ /** Return false to keep the modal closed (also `.on('beforeopen')`, `dm:modal:beforeopen`) */
95
+ onBeforeOpen?: (modal: ModalInstance) => boolean | void;
96
+ /** Return false to keep the modal open (also `.on('beforeclose')`, `dm:modal:beforeclose`) */
97
+ onBeforeClose?: (modal: ModalInstance) => boolean | void;
98
+ /** Modal content (HTML, sanitised like $().html() unless `safe: false`) */
99
+ content?: string;
100
+ /** false: insert `content` as trusted markup */
101
+ safe?: boolean;
82
102
  /** Callback before opening */
83
103
  onOpen?: (modal: ModalInstance) => void;
84
104
  /** Callback after open animation completes */
@@ -622,7 +642,8 @@ export interface Elements {
622
642
  accordion(selector: string | HTMLElement, options?: AccordionOptions): AccordionInstance;
623
643
 
624
644
  /** Create Tooltip(s) - returns array if multiple elements match */
625
- tooltip(selector: string | HTMLElement, options?: TooltipOptions): TooltipInstance | TooltipInstance[];
645
+ /** Sets up every match; returns the first, with `all()` for every instance */
646
+ tooltip(selector: string | HTMLElement, options?: TooltipOptions): TooltipInstance & {all(): TooltipInstance[]};
626
647
 
627
648
  /** Create Badge(s) - returns array if multiple elements match */
628
649
  badge(selector: string | HTMLElement, options?: BadgeOptions): BadgeInstance | BadgeInstance[];
@@ -642,8 +663,8 @@ export interface Elements {
642
663
  /** Toast notification system */
643
664
  toast: ToastStatic;
644
665
 
645
- /** Get component instance for an element */
646
- get(selector: string | HTMLElement): ComponentInstance | undefined;
666
+ /** Get the component on an element - factory-made ones too. `name` picks one when an element hosts several. */
667
+ get(selector: string | HTMLElement, name?: string): ComponentInstance | undefined;
647
668
 
648
669
  /** Destroy a component */
649
670
  destroy(selector: string | HTMLElement): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-js",
3
- "version": "0.54.0",
3
+ "version": "0.55.0",
4
4
  "description": "Dynamic Object Manipulation & Modeling API - A complete front-end toolkit.",
5
5
  "main": "public/dist/domma.min.js",
6
6
  "module": "public/dist/domma.esm.js",
@@ -1,8 +1,8 @@
1
1
  /*!
2
- * Domma Complete CSS Bundle v0.54.0
2
+ * Domma Complete CSS Bundle v0.55.0
3
3
  * Dynamic Object Manipulation & Modeling API
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-10-24T13:16:34.503Z
5
+ * Built: 2026-10-24T15:07:57.680Z
6
6
  */
7
7
 
8
8
  /* ============================================
@@ -11,11 +11,11 @@
11
11
  ============================================ */
12
12
 
13
13
  /*!
14
- * Domma Core CSS v0.54.0
14
+ * Domma Core CSS v0.55.0
15
15
  * Dynamic Object Manipulation & Modeling API
16
16
  * (c) 2026 Darryl Waterhouse & DCBW-IT
17
- * Built: 2026-10-24T13:16:34.331Z
18
- * Commit: 8d2b9ea
17
+ * Built: 2026-10-24T15:07:57.499Z
18
+ * Commit: 253e259
19
19
  */
20
20
 
21
21
  /**
@@ -4971,11 +4971,11 @@ body.dm-cloaked.dm-ready {
4971
4971
  ============================================ */
4972
4972
 
4973
4973
  /*!
4974
- * Domma Grid CSS v0.54.0
4974
+ * Domma Grid CSS v0.55.0
4975
4975
  * Dynamic Object Manipulation & Modeling API
4976
4976
  * (c) 2026 Darryl Waterhouse & DCBW-IT
4977
- * Built: 2026-10-24T13:16:34.336Z
4978
- * Commit: 8d2b9ea
4977
+ * Built: 2026-10-24T15:07:57.504Z
4978
+ * Commit: 253e259
4979
4979
  */
4980
4980
 
4981
4981
  /**
@@ -5596,11 +5596,11 @@ body.dm-cloaked.dm-ready {
5596
5596
  ============================================ */
5597
5597
 
5598
5598
  /*!
5599
- * Domma Elements CSS v0.54.0
5599
+ * Domma Elements CSS v0.55.0
5600
5600
  * Dynamic Object Manipulation & Modeling API
5601
5601
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5602
- * Built: 2026-10-24T13:16:34.341Z
5603
- * Commit: 8d2b9ea
5602
+ * Built: 2026-10-24T15:07:57.510Z
5603
+ * Commit: 253e259
5604
5604
  */
5605
5605
 
5606
5606
  /**
@@ -5963,6 +5963,54 @@ body.dm-cloaked.dm-ready {
5963
5963
  padding-bottom: 0;
5964
5964
  }
5965
5965
 
5966
+ /* E.card options (src/components/card.js) */
5967
+ .card-collapsible .card-body,
5968
+ .card-collapse-icon {
5969
+ transition-duration: var(--dm-card-duration, 200ms);
5970
+ }
5971
+
5972
+ .card-no-animation,
5973
+ .card-no-animation .card-body,
5974
+ .card-no-animation .card-collapse-icon {
5975
+ transition: none;
5976
+ }
5977
+
5978
+ .card-collapse-icon {
5979
+ display: inline-flex;
5980
+ align-items: center;
5981
+ }
5982
+
5983
+ .card-primary .card-collapse-icon,
5984
+ .card-primary.card-collapsible .card-header:hover .card-collapse-icon {
5985
+ color: inherit;
5986
+ }
5987
+
5988
+ .card-title-icon {
5989
+ display: inline-flex;
5990
+ vertical-align: -0.125em;
5991
+ margin-right: var(--dm-space-2);
5992
+ }
5993
+
5994
+ .card-clickable {
5995
+ cursor: pointer;
5996
+ }
5997
+
5998
+ .card-shadow-none {
5999
+ box-shadow: none;
6000
+ }
6001
+
6002
+ .card-shadow-sm {
6003
+ box-shadow: var(--dm-shadow-sm);
6004
+ }
6005
+
6006
+ .card-shadow-lg {
6007
+ box-shadow: var(--dm-shadow-lg);
6008
+ }
6009
+
6010
+ .card-square {
6011
+ border-radius: 0;
6012
+ }
6013
+
5966
6014
 
5967
6015
  /* ============================================
5968
6016
  MODAL
@@ -6065,6 +6113,50 @@ body.dm-cloaked.dm-ready {
6065
6113
  max-width: 1200px !important;
6066
6114
  }
6067
6115
 
6116
+ /* E.modal (src/components/modal.js): the caller's element becomes the full-screen layer
6117
+ that holds the dialog drawn in its shadow root. The class is doubled so it outranks
6118
+ .modal / .modal-sm / .modal.active, which describe the hand-written, JS-free modal
6119
+ box and would otherwise hide or shrink the layer. z-index stays settable inline. */
6120
+ .dm-modal-host.dm-modal-host {
6121
+ display: none;
6122
+ position: fixed;
6123
+ inset: 0;
6124
+ top: 0;
6125
+ left: 0;
6126
+ right: 0;
6127
+ bottom: 0;
6128
+ width: auto;
6129
+ max-width: none;
6130
+ height: auto;
6131
+ max-height: none;
6132
+ margin: 0;
6133
+ padding: 0;
6134
+ border: 0;
6135
+ border-radius: 0;
6136
+ background: none;
6137
+ box-shadow: none;
6138
+ overflow: visible;
6139
+ opacity: 1;
6140
+ transform: none;
6141
+ transition: none;
6142
+ pointer-events: auto;
6143
+ align-items: center;
6144
+ justify-content: center;
6145
+ }
6146
+
6147
+ .dm-modal-host.dm-modal-host.dm-modal-visible {
6148
+ display: flex;
6149
+ }
6150
+
6151
+ .dm-modal-host.dm-modal-host.dm-modal-no-backdrop {
6152
+ pointer-events: none;
6153
+ }
6154
+
6155
+ .dm-modal-host.dm-modal-host.dm-modal-top {
6156
+ align-items: flex-start;
6157
+ padding-top: 5vh;
6158
+ }
6159
+
6068
6160
 
6069
6161
  /* ============================================
6070
6162
  TABS
@@ -7043,6 +7135,57 @@ textarea:not([class])::placeholder {
7043
7135
  color: var(--dm-info-text, var(--dm-white));
7044
7136
  }
7045
7137
 
7138
+ .badge-light {
7139
+ background-color: var(--dm-background-alt);
7140
+ color: var(--dm-text);
7141
+ }
7142
+
7143
+ .badge-dark {
7144
+ background-color: var(--dm-text);
7145
+ color: var(--dm-background);
7146
+ }
7147
+
7148
+ /* E.badge options (src/components/badge.js) */
7149
+ .badge {
7150
+ gap: 0.25rem;
7151
+ }
7152
+
7153
+ .badge-sm {
7154
+ padding: 2px 6px;
7155
+ font-size: 0.625rem;
7156
+ }
7157
+
7158
+ .badge-lg {
7159
+ padding: var(--dm-space-1) var(--dm-space-3);
7160
+ font-size: var(--dm-font-size-sm);
7161
+ }
7162
+
7163
+ .badge-rounded {
7164
+ border-radius: var(--dm-radius-sm);
7165
+ }
7166
+
7167
+ .badge-pill {
7168
+ border-radius: var(--dm-radius-full);
7169
+ }
7170
+
7171
+ /* Outline badges carry .badge-outline-<variant> instead of the filled .badge-<variant>:
7172
+ the page's text on its surface, ringed in the variant colour - legible in every theme
7173
+ (variant-coloured text is not: warning on a light surface is under 2:1) */
7174
+ .badge-outline {
7175
+ background-color: var(--dm-surface);
7176
+ color: var(--dm-text);
7177
+ box-shadow: inset 0 0 0 1px var(--dm-border);
7178
+ }
7179
+
7180
+ .badge-outline-primary { box-shadow: inset 0 0 0 1px var(--dm-primary); }
7181
+ .badge-outline-secondary { box-shadow: inset 0 0 0 1px var(--dm-text-secondary); }
7182
+ .badge-outline-success { box-shadow: inset 0 0 0 1px var(--dm-success); }
7183
+ .badge-outline-danger { box-shadow: inset 0 0 0 1px var(--dm-danger); }
7184
+ .badge-outline-warning { box-shadow: inset 0 0 0 1px var(--dm-warning); }
7185
+ .badge-outline-info { box-shadow: inset 0 0 0 1px var(--dm-info); }
7186
+ .badge-outline-light { box-shadow: inset 0 0 0 1px var(--dm-border); }
7187
+ .badge-outline-dark { box-shadow: inset 0 0 0 1px var(--dm-text); }
7188
+
7046
7189
  /* Pulse animation for new content indicators */
7047
7190
  .badge-pulse {
7048
7191
  animation: badge-pulse 2s ease-in-out infinite;
@@ -7088,6 +7231,15 @@ textarea:not([class])::placeholder {
7088
7231
  background-color: var(--dm-danger);
7089
7232
  }
7090
7233
 
7234
+ /* E.numberBadge puts the counter inside its target; a target already positioned keeps its own */
7235
+ :where(.badge-counter-host) {
7236
+ position: relative;
7237
+ }
7238
+
7239
+ domma-number-badge {
7240
+ display: inline-flex;
7241
+ }
7242
+
7091
7243
  /* Wrapper for positioned counter badges */
7092
7244
  .badge-counter-wrapper {
7093
7245
  position: relative;
@@ -11088,17 +11240,22 @@ code {
11088
11240
  TOOLTIP
11089
11241
  ============================================ */
11090
11242
 
11243
+ /* E.tooltip's bubble (src/components/tooltip.js): on document.body, placed at the target.
11244
+ Inverted against the page - the text colour as its fill - in light and dark themes. */
11091
11245
  .domma-tooltip {
11092
- position: absolute;
11093
- z-index: 9999;
11094
- background-color: var(--dm-background);
11095
- color: var(--dm-text);
11246
+ --dm-tooltip-bg: var(--dm-text);
11247
+ position: fixed;
11248
+ top: 0;
11249
+ left: 0;
11250
+ z-index: 10050;
11251
+ background-color: var(--dm-text);
11252
+ color: var(--dm-background);
11096
11253
  padding: 0.5rem 0.75rem;
11097
11254
  border-radius: var(--dm-radius-md);
11098
11255
  font-size: 0.875rem;
11099
11256
  line-height: 1.4;
11100
- max-width: 200px;
11101
- word-wrap: break-word;
11257
+ max-width: 250px;
11258
+ overflow-wrap: break-word;
11102
11259
  pointer-events: none;
11103
11260
  opacity: 0;
11104
11261
  transition: opacity var(--dm-transition-fast);
@@ -11109,9 +11266,42 @@ code {
11109
11266
  opacity: 1;
11110
11267
  }
11111
11268
 
11112
- [data-mode="dark"] .domma-tooltip {
11113
- background-color: var(--dm-text);
11114
- color: var(--dm-text-inverse);
11269
+ .domma-tooltip::before {
11270
+ content: '';
11271
+ position: absolute;
11272
+ border: 5px solid transparent;
11273
+ }
11274
+
11275
+ .domma-tooltip[data-position="top"]::before {
11276
+ top: 100%;
11277
+ left: 50%;
11278
+ transform: translateX(-50%);
11279
+ border-top-color: var(--dm-tooltip-bg);
11280
+ }
11281
+
11282
+ .domma-tooltip[data-position="bottom"]::before {
11283
+ bottom: 100%;
11284
+ left: 50%;
11285
+ transform: translateX(-50%);
11286
+ border-bottom-color: var(--dm-tooltip-bg);
11287
+ }
11288
+
11289
+ .domma-tooltip[data-position="left"]::before {
11290
+ left: 100%;
11291
+ top: 50%;
11292
+ transform: translateY(-50%);
11293
+ border-left-color: var(--dm-tooltip-bg);
11294
+ }
11295
+
11296
+ .domma-tooltip[data-position="right"]::before {
11297
+ right: 100%;
11298
+ top: 50%;
11299
+ transform: translateY(-50%);
11300
+ border-right-color: var(--dm-tooltip-bg);
11301
+ }
11302
+
11303
+ domma-tooltip {
11304
+ display: inline-block;
11115
11305
  }
11116
11306
 
11117
11307
 
@@ -11333,21 +11523,36 @@ code {
11333
11523
  }
11334
11524
 
11335
11525
  /* Toast variants */
11526
+ .domma-toast {
11527
+ position: relative;
11528
+ overflow: hidden;
11529
+ align-items: flex-start;
11530
+ border: 1px solid var(--dm-border);
11531
+ transition-duration: var(--dm-toast-duration, 300ms);
11532
+ }
11533
+
11336
11534
  .domma-toast.domma-toast-success {
11337
11535
  background-color: var(--dm-success);
11536
+ color: var(--dm-success-text, var(--dm-white));
11537
+ border-color: transparent;
11338
11538
  }
11339
11539
 
11340
11540
  .domma-toast.domma-toast-error {
11341
11541
  background-color: var(--dm-danger);
11542
+ color: var(--dm-danger-text, var(--dm-white));
11543
+ border-color: transparent;
11342
11544
  }
11343
11545
 
11344
11546
  .domma-toast.domma-toast-warning {
11345
11547
  background-color: var(--dm-warning);
11346
11548
  color: var(--dm-warning-text, var(--dm-text));
11549
+ border-color: transparent;
11347
11550
  }
11348
11551
 
11349
11552
  .domma-toast.domma-toast-info {
11350
11553
  background-color: var(--dm-info);
11554
+ color: var(--dm-info-text, var(--dm-white));
11555
+ border-color: transparent;
11351
11556
  }
11352
11557
 
11353
11558
  /* Toast internal structure */
@@ -11391,6 +11596,72 @@ code {
11391
11596
  display: block;
11392
11597
  }
11393
11598
 
11599
+ .domma-toast-close {
11600
+ font-size: 1.25rem;
11601
+ line-height: 1;
11602
+ }
11603
+
11604
+ .domma-toast-icon {
11605
+ display: flex;
11606
+ align-items: center;
11607
+ }
11608
+
11609
+ .domma-toast-title[hidden],
11610
+ .domma-toast-actions[hidden] {
11611
+ display: none;
11612
+ }
11613
+
11614
+ .domma-toast-message {
11615
+ overflow-wrap: anywhere;
11616
+ }
11617
+
11618
+ .domma-toast-actions {
11619
+ display: flex;
11620
+ gap: 0.5rem;
11621
+ margin-top: 0.5rem;
11622
+ }
11623
+
11624
+ .domma-toast-action {
11625
+ padding: 0.25rem 0.75rem;
11626
+ border: 1px solid currentColor;
11627
+ border-radius: var(--dm-radius-sm);
11628
+ background: transparent;
11629
+ color: inherit;
11630
+ font: inherit;
11631
+ font-size: 0.8rem;
11632
+ font-weight: 500;
11633
+ cursor: pointer;
11634
+ }
11635
+
11636
+ .domma-toast-action.is-primary {
11637
+ background-color: var(--dm-primary);
11638
+ color: var(--dm-primary-text, var(--dm-white));
11639
+ border-color: var(--dm-primary);
11640
+ }
11641
+
11642
+ .domma-toast-progress {
11643
+ position: absolute;
11644
+ left: 0;
11645
+ right: 0;
11646
+ bottom: 0;
11647
+ height: 3px;
11648
+ background: color-mix(in srgb, currentColor 15%, transparent);
11649
+ }
11650
+
11651
+ .domma-toast-progress-bar {
11652
+ width: 100%;
11653
+ height: 100%;
11654
+ background: currentColor;
11655
+ opacity: 0.6;
11656
+ }
11657
+
11658
+ @media (prefers-reduced-motion: reduce) {
11659
+ .domma-toast,
11660
+ .domma-toast-progress-bar {
11661
+ transition: none !important;
11662
+ }
11663
+ }
11664
+
11394
11665
 
11395
11666
  /* ============================================
11396
11667
  BACK TO TOP BUTTON
@@ -11439,6 +11710,20 @@ code {
11439
11710
  box-shadow: 0 0 0 3px var(--dm-focus-ring);
11440
11711
  }
11441
11712
 
11713
+ /* E.backToTop on a button inside the container it watches: it sticks to that
11714
+ container's bottom corner instead of the viewport's */
11715
+ .dm-back-to-top.dm-back-to-top-contained {
11716
+ position: sticky;
11717
+ right: auto;
11718
+ left: auto;
11719
+ margin-left: auto;
11720
+ }
11721
+
11722
+ .dm-back-to-top.dm-back-to-top-contained.dm-back-to-top-left {
11723
+ margin-left: 0;
11724
+ margin-right: auto;
11725
+ }
11726
+
11442
11727
  /* Desktop (≥577px) - Back to Top enhancements */
11443
11728
  @media (min-width: 577px) {
11444
11729
  .dm-back-to-top {
@@ -11462,6 +11747,103 @@ code {
11462
11747
  gap: 0.75rem;
11463
11748
  }
11464
11749
 
11750
+ .dm-loader[hidden] {
11751
+ display: none !important;
11752
+ }
11753
+
11754
+ /* E.loader's indicator (src/components/loader.js); size and colour come from
11755
+ --dm-loader-size / --dm-loader-color, set from the options */
11756
+ .dm-loader-js {
11757
+ --dm-loader-size: 40px;
11758
+ --dm-loader-color: var(--dm-primary);
11759
+ }
11760
+
11761
+ /* Centred over the nearest positioned ancestor, as <domma-loader> always drew it - the
11762
+ container's own content stays where it is and the loader sits on top of it. */
11763
+ .dm-loader-js.dm-loader-centered {
11764
+ position: absolute;
11765
+ top: 50%;
11766
+ left: 50%;
11767
+ transform: translate(-50%, -50%);
11768
+ }
11769
+
11770
+ :where(.dm-loader-host) {
11771
+ position: relative;
11772
+ }
11773
+
11774
+ .dm-loader-anim {
11775
+ flex-shrink: 0;
11776
+ }
11777
+
11778
+ .dm-loader-anim-spinner {
11779
+ width: var(--dm-loader-size);
11780
+ height: var(--dm-loader-size);
11781
+ border: max(2px, calc(var(--dm-loader-size) / 10)) solid var(--dm-loader-color);
11782
+ border-top-color: transparent;
11783
+ border-radius: 50%;
11784
+ animation: dm-loader-spin 0.8s linear infinite;
11785
+ }
11786
+
11787
+ .dm-loader-anim-dots,
11788
+ .dm-loader-anim-bars {
11789
+ display: flex;
11790
+ align-items: center;
11791
+ gap: calc(var(--dm-loader-size) / 8);
11792
+ height: var(--dm-loader-size);
11793
+ }
11794
+
11795
+ .dm-loader-anim-dots span {
11796
+ /* Shapes are drawn with borders, not backgrounds: they hold no text */
11797
+ width: 0;
11798
+ height: 0;
11799
+ border: calc(var(--dm-loader-size) / 8) solid var(--dm-loader-color);
11800
+ border-radius: 50%;
11801
+ animation: dm-loader-bounce 1.4s ease-in-out infinite both;
11802
+ }
11803
+
11804
+ .dm-loader-anim-dots span:nth-child(2) { animation-delay: 0.16s; }
11805
+ .dm-loader-anim-dots span:nth-child(3) { animation-delay: 0.32s; }
11806
+
11807
+ .dm-loader-anim-pulse {
11808
+ width: 0;
11809
+ height: 0;
11810
+ border: calc(var(--dm-loader-size) / 2) solid var(--dm-loader-color);
11811
+ border-radius: 50%;
11812
+ animation: dm-loader-pulse 1.2s ease-in-out infinite;
11813
+ }
11814
+
11815
+ .dm-loader-anim-bars span {
11816
+ width: 0;
11817
+ height: 100%;
11818
+ border-left: calc(var(--dm-loader-size) / 6) solid var(--dm-loader-color);
11819
+ border-radius: 2px;
11820
+ animation: dm-loader-bars 1s ease-in-out infinite;
11821
+ }
11822
+
11823
+ .dm-loader-anim-bars span:nth-child(2) { animation-delay: 0.1s; }
11824
+ .dm-loader-anim-bars span:nth-child(3) { animation-delay: 0.2s; }
11825
+ .dm-loader-anim-bars span:nth-child(4) { animation-delay: 0.3s; }
11826
+
11827
+ .dm-loader-fullscreen {
11828
+ position: fixed;
11829
+ inset: 0;
11830
+ z-index: 9999;
11831
+ display: flex;
11832
+ align-items: center;
11833
+ justify-content: center;
11834
+ background-color: rgba(0, 0, 0, 0.7);
11835
+ }
11836
+
11837
+ .dm-loader-fullscreen .dm-loader-text {
11838
+ color: #fff;
11839
+ }
11840
+
11841
+ domma-loader,
11842
+ domma-card,
11843
+ domma-back-to-top {
11844
+ display: block;
11845
+ }
11846
+
11465
11847
  .dm-loader.dm-loader-overlay {
11466
11848
  position: absolute;
11467
11849
  top: 0;
@@ -15161,11 +15543,11 @@ a.avatar-more-person:hover .avatar-more-name {
15161
15543
  ============================================ */
15162
15544
 
15163
15545
  /*!
15164
- * Domma Themes v0.54.0
15546
+ * Domma Themes v0.55.0
15165
15547
  * Dynamic Object Manipulation & Modeling API
15166
15548
  * (c) 2026 Darryl Waterhouse & DCBW-IT
15167
- * Built: 2026-10-24T13:16:34.318Z
15168
- * Commit: 8d2b9ea
15549
+ * Built: 2026-10-24T15:07:57.484Z
15550
+ * Commit: 253e259
15169
15551
  */
15170
15552
 
15171
15553
  /**