@rdlabo/ionic-theme-ios27 1.2.0-0 → 1.2.0-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +12 -2
  2. package/dist/css/components/ion-tabs.css +1 -1
  3. package/dist/css/ionic-theme-ios27.css +1 -1
  4. package/dist/css/vertical-bars.css +1 -1
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +32 -12
  8. package/dist/native/components/index.d.ts.map +1 -1
  9. package/dist/native/components/index.js +4 -1
  10. package/dist/native/components/ion-button.d.ts.map +1 -1
  11. package/dist/native/components/ion-button.js +3 -3
  12. package/dist/native/components/ion-buttons.d.ts.map +1 -1
  13. package/dist/native/components/ion-buttons.js +3 -2
  14. package/dist/native/definitions.d.ts +8 -15
  15. package/dist/native/definitions.d.ts.map +1 -1
  16. package/dist/native/definitions.js +1 -6
  17. package/dist/native/index.d.ts +1 -2
  18. package/dist/native/index.d.ts.map +1 -1
  19. package/dist/native/index.js +64 -28
  20. package/dist/native/prehide.d.ts.map +1 -1
  21. package/dist/native/prehide.js +6 -4
  22. package/dist/native/runtime.d.ts.map +1 -1
  23. package/dist/native/runtime.js +27 -12
  24. package/dist/native/shared/candidate.d.ts.map +1 -1
  25. package/dist/native/shared/candidate.js +8 -0
  26. package/dist/native/shared/dom.d.ts.map +1 -1
  27. package/dist/native/shared/dom.js +11 -10
  28. package/dist/native/shared/modal.d.ts +8 -0
  29. package/dist/native/shared/modal.d.ts.map +1 -0
  30. package/dist/native/shared/modal.js +143 -0
  31. package/dist/native/vertical-bars-web.d.ts.map +1 -1
  32. package/dist/native/vertical-bars-web.js +11 -3
  33. package/dist/native-integration/index.d.ts.map +1 -1
  34. package/dist/native-integration/index.js +7 -2
  35. package/dist/native-integration/transition.d.ts +3 -0
  36. package/dist/native-integration/transition.d.ts.map +1 -0
  37. package/dist/native-integration/transition.js +7 -0
  38. package/dist/sheets-of-glass/animations.d.ts +13 -4
  39. package/dist/sheets-of-glass/animations.d.ts.map +1 -1
  40. package/dist/sheets-of-glass/animations.js +56 -40
  41. package/dist/sheets-of-glass/index.d.ts +1 -1
  42. package/dist/sheets-of-glass/index.d.ts.map +1 -1
  43. package/dist/sheets-of-glass/index.js +64 -20
  44. package/dist/transition/ios.transition.d.ts.map +1 -1
  45. package/dist/transition/ios.transition.js +2 -3
  46. package/dist/vertical-bars.d.ts +2 -2
  47. package/dist/vertical-bars.d.ts.map +1 -1
  48. package/dist/vertical-bars.js +1 -1
  49. package/docs/iphone-duo-with-original-theme.md +171 -0
  50. package/docs/iphone-duo.md +105 -50
  51. package/docs/migration.md +23 -0
  52. package/docs/native-ui-shell.md +10 -6
  53. package/docs/special-markup.md +3 -14
  54. package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellVerticalBars.swift +23 -4
  55. package/ios/Sources/IonicNativeUIShellPlugin/IonicNativeUIShellPlugin.swift +15 -171
  56. package/ios/Sources/IonicNativeUIShellPlugin/Shared/ShellSnapshot.swift +5 -0
  57. package/ios/Tests/IonicNativeUIShellPluginTests/ShellSnapshotTests.swift +30 -0
  58. package/package.json +1 -1
  59. package/src/index.ts +41 -9
  60. package/src/native/components/index.ts +6 -1
  61. package/src/native/components/ion-button.ts +4 -3
  62. package/src/native/components/ion-buttons.ts +4 -2
  63. package/src/native/definitions.ts +11 -19
  64. package/src/native/index.ts +67 -30
  65. package/src/native/prehide.ts +7 -4
  66. package/src/native/runtime.ts +28 -11
  67. package/src/native/shared/candidate.ts +10 -0
  68. package/src/native/shared/dom.ts +11 -10
  69. package/src/native/shared/modal.ts +157 -0
  70. package/src/native/vertical-bars-web.ts +12 -3
  71. package/src/native-integration/index.ts +8 -2
  72. package/src/native-integration/transition.ts +15 -0
  73. package/src/sheets-of-glass/animations.ts +66 -41
  74. package/src/sheets-of-glass/index.ts +82 -16
  75. package/src/styles/components/ion-tabs.scss +7 -4
  76. package/src/styles/vertical-bars.scss +102 -35
  77. package/src/transition/ios.transition.ts +4 -4
  78. package/src/vertical-bars.ts +2 -2
@@ -1,3 +1,4 @@
1
+ import { inVerticalBarsSurface, topModal, modalUsesVerticalBars, modalVerticalBarFrame } from './shared/modal';
1
2
  import { LIFECYCLE_WILL_ENTER, LIFECYCLE_WILL_LEAVE, LIFECYCLE_DID_ENTER, LIFECYCLE_DID_LEAVE } from '@ionic/core';
2
3
  import { VERTICAL_BARS_TRANSITION_CANCELED, getNativeSearchBindings, setNativeUIShellIntegration } from '../native-integration';
3
4
  import { createSearchSupport } from './components/searchable-tabs';
@@ -94,7 +95,7 @@ export const createRuntime = async (doc, plugin, options = {}, nativeVerticalBar
94
95
  search.release(element);
95
96
  element.removeAttribute(marker);
96
97
  if (!stopped)
97
- crossfade.play(element, false, handoffInstant || isVerticalBarsSource(element));
98
+ crossfade.play(element, false, isVerticalBarsSource(element) ? !element.matches('ion-tab-bar') : handoffInstant);
98
99
  if (element.getAttribute('aria-hidden') === 'true') {
99
100
  const previous = sources.get(element);
100
101
  if (previous == null)
@@ -187,14 +188,17 @@ export const createRuntime = async (doc, plugin, options = {}, nativeVerticalBar
187
188
  Array.from(pages).some((scope) => scope.contains(element)) ||
188
189
  Array.from(moving.keys()).some((surface) => surface.contains(element))));
189
190
  const painted = () => new Promise((resolve) => win.requestAnimationFrame(() => win.requestAnimationFrame(() => resolve())));
190
- const overlayOpen = (includeMenu = true) => {
191
+ const overlayOpen = (includeMenu = true, allowModal = false) => {
192
+ const modal = topModal(doc);
193
+ const ignored = (element) => allowModal && !!modal && modalUsesVerticalBars(modal) && element.matches('ion-modal');
191
194
  for (const element of presented)
192
195
  if (!element.isConnected)
193
196
  presented.delete(element);
194
- const presentedOverlayOpen = Array.from(presented).some((element) => includeMenu || !element.matches('ion-menu'));
197
+ const presentedOverlayOpen = Array.from(presented).some((element) => !ignored(element) && (includeMenu || !element.matches('ion-menu')));
195
198
  return (manualSuspensions.size > 0 ||
196
199
  presentedOverlayOpen ||
197
- Array.from(doc.querySelectorAll(overlays)).some((element) => (includeMenu || !element.matches('ion-menu')) &&
200
+ Array.from(doc.querySelectorAll(overlays)).some((element) => !ignored(element) &&
201
+ (includeMenu || !element.matches('ion-menu')) &&
198
202
  (element.presented || element.classList.contains('show-menu'))));
199
203
  };
200
204
  const signature = (candidate) => JSON.stringify({ control: candidate.control, icons: candidate.icons.map(({ source }) => source) });
@@ -206,14 +210,16 @@ export const createRuntime = async (doc, plugin, options = {}, nativeVerticalBar
206
210
  for (const surface of moving.keys())
207
211
  if (!surface.isConnected)
208
212
  moving.delete(surface);
209
- if (doc.hidden || overlayOpen(false))
213
+ if (doc.hidden || overlayOpen(false, true))
210
214
  return [];
211
215
  if (win.visualViewport && (win.visualViewport.scale !== 1 || win.visualViewport.offsetTop !== 0) && !search.hasActive())
212
216
  return [];
213
217
  const menuOpen = overlayOpen();
214
218
  const candidates = unprojected(sources.keys(), () => search
215
219
  .decorate(Array.from(doc.querySelectorAll(selector))
216
- .filter((element) => !verticalBarsPages.isDeparted(element) && (!blocked(element) || (menuOpen && isVerticalBarsSource(element))))
220
+ .filter((element) => inVerticalBarsSurface(element) &&
221
+ !verticalBarsPages.isDeparted(element) &&
222
+ (!blocked(element) || (menuOpen && isVerticalBarsSource(element))))
217
223
  .map(readEnabledCandidate)
218
224
  .filter((candidate) => !!candidate), blocked)
219
225
  .filter((candidate) => !rejected.has(candidate.element) || rejected.get(candidate.element) !== signature(candidate)));
@@ -298,7 +304,14 @@ export const createRuntime = async (doc, plugin, options = {}, nativeVerticalBar
298
304
  ? 'left'
299
305
  : 'right'
300
306
  : undefined;
301
- const data = { viewportWidth: win.innerWidth, verticalBarEdge, controls: candidates.map((candidate) => candidate.control) };
307
+ const modal = topModal(doc);
308
+ const verticalBarFrame = modal && modalUsesVerticalBars(modal) ? modalVerticalBarFrame(modal) : undefined;
309
+ const data = {
310
+ verticalBarFrame,
311
+ viewportWidth: win.innerWidth,
312
+ verticalBarEdge,
313
+ controls: candidates.map((candidate) => candidate.control),
314
+ };
302
315
  const serialized = JSON.stringify(data);
303
316
  if (serialized === lastSnapshot && !forceRefresh)
304
317
  return;
@@ -365,13 +378,15 @@ export const createRuntime = async (doc, plugin, options = {}, nativeVerticalBar
365
378
  verticalBarsMembers.add(element);
366
379
  }
367
380
  for (const element of accepted.flatMap(candidateSources)) {
381
+ const newlyProjected = !sources.has(element) || !element.hasAttribute(marker);
368
382
  if (!sources.has(element)) {
369
383
  sources.set(element, element.getAttribute('aria-hidden'));
370
384
  crossfade.play(element, true, handoffInstant || isVerticalBarsSource(element));
371
- element.setAttribute(marker, '');
372
- element.setAttribute('aria-hidden', 'true');
373
- element.dispatchEvent(new CustomEvent('nativeUIShellChange'));
374
385
  }
386
+ element.setAttribute(marker, '');
387
+ element.setAttribute('aria-hidden', 'true');
388
+ if (newlyProjected)
389
+ element.dispatchEvent(new CustomEvent('nativeUIShellChange'));
375
390
  }
376
391
  const received = pendingActivations;
377
392
  pendingActivations = [];
@@ -642,7 +657,7 @@ export const createRuntime = async (doc, plugin, options = {}, nativeVerticalBar
642
657
  event.revision < acceptedRevision ||
643
658
  event.revision > revision ||
644
659
  event.sequence <= lastSequence ||
645
- overlayOpen(false))
660
+ overlayOpen(false, true))
646
661
  return;
647
662
  if (event.revision > acceptedRevision && event.revision === updatingRevision) {
648
663
  pendingActivations.push(event);
@@ -653,7 +668,7 @@ export const createRuntime = async (doc, plugin, options = {}, nativeVerticalBar
653
668
  if (!element)
654
669
  return;
655
670
  const owner = Array.from(sources.keys()).find((source) => source === element || source.contains(element));
656
- if (!owner)
671
+ if (!owner || !inVerticalBarsSurface(owner))
657
672
  return;
658
673
  const direct = !blocked(owner) && unprojected(sources.keys(), () => readEnabledCandidate(owner));
659
674
  const candidate = direct || read().find((candidate) => candidate.actions.has(event.id));
@@ -1 +1 @@
1
- {"version":3,"file":"candidate.d.ts","sourceRoot":"","sources":["../../../src/native/shared/candidate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAItF,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAClC,KAAK,EAAE;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,WAAW,CAAA;KAAE,EAAE,CAAC;CACnE;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,MAAM,CAAC;AAGxD,eAAO,MAAM,eAAe,GAAI,SAAS,WAAW,EAAE,MAAM,sBAAsB,EAAE,IAAI,QAAQ,KAAG,SAgBlG,CAAC;AAGF,eAAO,MAAM,UAAU,GACrB,WAAW,SAAS,EACpB,OAAO,WAAW,EAClB,IAAI,QAAQ,EACZ,UAAS,UAAkB,EAC3B,cAAmB,KAClB,SAAS,GAAG,SAsEd,CAAC"}
1
+ {"version":3,"file":"candidate.d.ts","sourceRoot":"","sources":["../../../src/native/shared/candidate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAItF,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAClC,KAAK,EAAE;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,WAAW,CAAA;KAAE,EAAE,CAAC;CACnE;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,MAAM,CAAC;AAGxD,eAAO,MAAM,eAAe,GAAI,SAAS,WAAW,EAAE,MAAM,sBAAsB,EAAE,IAAI,QAAQ,KAAG,SAgBlG,CAAC;AAGF,eAAO,MAAM,UAAU,GACrB,WAAW,SAAS,EACpB,OAAO,WAAW,EAClB,IAAI,QAAQ,EACZ,UAAS,UAAkB,EAC3B,cAAmB,KAClB,SAAS,GAAG,SAgFd,CAAC"}
@@ -33,6 +33,9 @@ export const appendItem = (candidate, child, id, content = child, label = text(c
33
33
  const labelStyle = getComputedStyle(labelElement);
34
34
  const badge = child.querySelector('ion-badge');
35
35
  const badgeStyle = badge && visible(badge) ? getComputedStyle(badge) : undefined;
36
+ const outline = isVerticalBarsSource(child) && child.matches('ion-button') && child.fill === 'outline'
37
+ ? getComputedStyle(native ?? child)
38
+ : undefined;
36
39
  const item = {
37
40
  id: id(child),
38
41
  ...frame(child.getBoundingClientRect(), candidate.element.getBoundingClientRect()),
@@ -48,6 +51,11 @@ export const appendItem = (candidate, child, id, content = child, label = text(c
48
51
  fontSize: parseFloat(labelStyle.fontSize),
49
52
  fontWeight: parseInt(labelStyle.fontWeight, 10) || 400,
50
53
  color: getComputedStyle(native ?? child).color,
54
+ backgroundColor: isVerticalBarsSource(child) && child.matches('ion-button') && child.fill === 'solid'
55
+ ? getComputedStyle(native ?? child).backgroundColor
56
+ : undefined,
57
+ borderColor: outline?.borderTopColor,
58
+ borderWidth: outline ? parseFloat(outline.borderTopWidth) : undefined,
51
59
  badge: badgeStyle
52
60
  ? { value: badge.textContent?.trim() ?? '', color: badgeStyle.backgroundColor, textColor: badgeStyle.color }
53
61
  : undefined,
@@ -1 +1 @@
1
- {"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["../../../src/native/shared/dom.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["../../../src/native/shared/dom.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { fadeMarker } from './crossfade';
2
+ import { modalUsesVerticalBars } from './modal';
2
3
  export const marker = 'data-native-ui-shell';
3
4
  const childNodesGet = typeof Node === 'undefined' ? undefined : Object.getOwnPropertyDescriptor(Node.prototype, 'childNodes')?.get;
4
5
  export const childNodesOf = (element) => childNodesGet ? Array.from(childNodesGet.call(element)) : Array.from(element.childNodes);
@@ -91,7 +92,8 @@ export const isDisabledButtonGroupChild = (element) => element.matches('ion-butt
91
92
  const verticalBarsTags = new Set(['ion-button', 'ion-back-button', 'ion-buttons', 'ion-menu-button', 'ion-tab-bar']);
92
93
  export const isVerticalBarsSource = (element) => verticalBarsTags.has(element.localName) &&
93
94
  (element.matches('ion-tab-bar') || verticalBarsOwned(element)) &&
94
- !element.closest('ion-menu, ion-modal, ion-popover') &&
95
+ !element.closest('ion-menu, ion-popover') &&
96
+ modalUsesVerticalBars(element) &&
95
97
  !!element.closest('ion-app.ios-theme-vertical-bars');
96
98
  export const isVerticalBarsBackPosition = (element) => {
97
99
  if (element.closest('ion-header[collapse], ion-footer[collapse]'))
@@ -101,7 +103,8 @@ export const isVerticalBarsBackPosition = (element) => {
101
103
  return true;
102
104
  const candidates = Array.from(page.querySelectorAll('ion-back-button')).filter((back) => back.closest('.ion-page') === page &&
103
105
  !back.matches('.ion-cloned-element') &&
104
- !back.closest('ion-header[collapse], ion-footer[collapse], ion-menu, ion-modal, ion-popover'));
106
+ !back.closest('ion-header[collapse], ion-footer[collapse], ion-menu, ion-popover') &&
107
+ modalUsesVerticalBars(back));
105
108
  const rank = (back) => inFixedToolbar(back) ? 0 : back.closest('ion-header ion-toolbar, ion-footer ion-toolbar') ? 1 : back.closest('ion-toolbar') ? 3 : 2;
106
109
  const best = candidates.reduce((winner, back) => (!winner || rank(back) < rank(winner) ? back : winner), undefined);
107
110
  return best === element;
@@ -119,11 +122,7 @@ export const isPermanentlyExcluded = (element) => excludedBy(element, permanentl
119
122
  export const isExcluded = (element, enteringPage) => excludedBy(element, `${permanentlyExcluded}, .ion-page-hidden`) || (!!element.closest('.ion-page-invisible') && !enteringPage);
120
123
  export const isShellDisabled = (element) => !!element.closest(shellDisabledSelector) || !!element.querySelector(shellDisabledSelector);
121
124
  export const isVerticalBarsToolbarActionShape = (element) => element.matches('ion-menu-button') ||
122
- (element.matches('ion-button') &&
123
- !!element.querySelector('ion-icon, svg') &&
124
- !childNodesOf(element).some((node) => node.nodeType === 3 && !!node.textContent?.trim()) &&
125
- !element.matches('.ion-color, [color]') &&
126
- ['default', 'clear'].includes(element.fill ?? element.getAttribute('fill') ?? 'default'));
125
+ (element.matches('ion-button') && !!element.querySelector('ion-icon[slot="icon-only"], svg[slot="icon-only"]'));
127
126
  const verticalBarsPlacement = new WeakMap();
128
127
  export const setVerticalBarsPlacement = (element, rail) => {
129
128
  verticalBarsPlacement.set(element, rail);
@@ -133,17 +132,19 @@ export const clearVerticalBarsPlacement = (element) => {
133
132
  };
134
133
  export const verticalBarsOwned = (element) => verticalBarsPlacement.get(element) === true;
135
134
  export const isVerticalBarsToolbarAction = (element) => verticalBarsOwned(element) && !isExcluded(element, verticalBarsEnteringPage(element)) && !isShellDisabled(element);
136
- const overlays = 'ion-menu, ion-modal, ion-popover';
135
+ const overlays = 'ion-menu, ion-popover';
137
136
  export const verticalBarsActionCandidate = (element) => inFixedToolbar(element) &&
138
137
  !element.closest('ion-buttons.ios-theme-horizontal-only, ion-button.ios-theme-horizontal-only') &&
139
138
  !isPermanentlyExcluded(element) &&
140
139
  !isShellDisabled(element) &&
141
- !element.closest(overlays);
140
+ !element.closest(overlays) &&
141
+ modalUsesVerticalBars(element);
142
142
  export const verticalBarsBackCandidate = (element) => isVerticalBarsBackPosition(element) &&
143
143
  !element.closest('ion-buttons.ios-theme-horizontal-only') &&
144
144
  !isPermanentlyExcluded(element) &&
145
145
  !isShellDisabled(element) &&
146
- !element.closest(overlays);
146
+ !element.closest(overlays) &&
147
+ modalUsesVerticalBars(element);
147
148
  export const verticalBarsToolbarActions = (element) => childElements(element).filter((child) => !child.matches('ion-back-button') && isVerticalBarsToolbarAction(child));
148
149
  export const isVerticalBarsToolbarGroup = (element) => {
149
150
  return (element.matches('ion-buttons') &&
@@ -0,0 +1,8 @@
1
+ import type { Frame } from '../definitions';
2
+ export declare const modalRailClass = "ios-theme-vertical-bars-modal";
3
+ export declare const topModal: (doc: Document) => HTMLIonModalElement | undefined;
4
+ export declare const modalUsesVerticalBars: (element: Element) => boolean;
5
+ export declare const inVerticalBarsSurface: (element: Element) => boolean;
6
+ export declare const observeVerticalBarsModals: (doc: Document) => (() => void);
7
+ export declare const modalVerticalBarFrame: (modal: Element) => Frame | undefined;
8
+ //# sourceMappingURL=modal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../../../src/native/shared/modal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAG5C,eAAO,MAAM,cAAc,kCAAkC,CAAC;AAG9D,eAAO,MAAM,QAAQ,GAAI,KAAK,QAAQ,KAAG,mBAAmB,GAAG,SAAiC,CAAC;AACjG,eAAO,MAAM,qBAAqB,GAAI,SAAS,OAAO,KAAG,OAGxD,CAAC;AAGF,eAAO,MAAM,qBAAqB,GAAI,SAAS,OAAO,KAAG,OAGxD,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,KAAK,QAAQ,KAAG,CAAC,MAAM,IAAI,CAgIpE,CAAC;AAGF,eAAO,MAAM,qBAAqB,GAAI,OAAO,OAAO,KAAG,KAAK,GAAG,SAO9D,CAAC"}
@@ -0,0 +1,143 @@
1
+ export const modalRailClass = 'ios-theme-vertical-bars-modal';
2
+ const states = new WeakMap();
3
+ export const topModal = (doc) => states.get(doc)?.top;
4
+ export const modalUsesVerticalBars = (element) => {
5
+ const modal = element.closest('ion-modal');
6
+ return !modal || modal.classList.contains(modalRailClass);
7
+ };
8
+ export const inVerticalBarsSurface = (element) => {
9
+ const modal = topModal(element.ownerDocument);
10
+ return modal ? element.closest('ion-modal') === modal && modalUsesVerticalBars(element) : !element.closest('ion-modal');
11
+ };
12
+ export const observeVerticalBarsModals = (doc) => {
13
+ const win = doc.defaultView;
14
+ const state = {};
15
+ states.set(doc, state);
16
+ const presenting = new Set();
17
+ const dismissed = new WeakSet();
18
+ const observed = new Set();
19
+ const listeners = new AbortController();
20
+ let stopped = false;
21
+ let frame = 0;
22
+ let pointerActive = false;
23
+ let bounds = '';
24
+ const toolbarTop = '--ios-theme-vertical-bars-modal-offset-top';
25
+ const refresh = () => {
26
+ win.cancelAnimationFrame(frame);
27
+ frame = 0;
28
+ if (stopped)
29
+ return;
30
+ const app = doc.querySelector('ion-app.ios-theme-vertical-bars');
31
+ const modals = Array.from(doc.querySelectorAll('ion-modal'));
32
+ const active = modals.filter((modal) => !dismissed.has(modal) && (modal.presented || presenting.has(modal)));
33
+ for (const modal of presenting)
34
+ if (!modal.isConnected)
35
+ presenting.delete(modal);
36
+ const top = active.sort((a, b) => a.overlayIndex - b.overlayIndex).slice(-1)[0];
37
+ let changed = state.top !== top;
38
+ state.top = top;
39
+ const nextBounds = top ? JSON.stringify(modalVerticalBarFrame(top)) : '';
40
+ changed || (changed = bounds !== nextBounds);
41
+ bounds = nextBounds;
42
+ const wanted = new Set();
43
+ for (const modal of modals) {
44
+ const content = modal.shadowRoot?.querySelector('[part~="content"]');
45
+ if (content)
46
+ wanted.add(content);
47
+ const fullWidth = !!content && Math.abs(content.offsetWidth - win.innerWidth) <= 1 && Math.abs(content.offsetLeft) <= 1;
48
+ const enabled = !!app?.contains(modal) && active.includes(modal) && fullWidth;
49
+ if (enabled) {
50
+ const top = modalVerticalBarFrame(modal)?.y ?? 0;
51
+ const offset = `${top}px`;
52
+ if (modal.style.getPropertyValue(toolbarTop) !== offset) {
53
+ modal.style.setProperty(toolbarTop, offset);
54
+ changed = true;
55
+ }
56
+ }
57
+ else
58
+ modal.style.removeProperty(toolbarTop);
59
+ if (modal.classList.contains(modalRailClass) !== enabled) {
60
+ modal.classList.toggle(modalRailClass, enabled);
61
+ changed = true;
62
+ }
63
+ }
64
+ if (wanted.size !== observed.size || [...wanted].some((element) => !observed.has(element))) {
65
+ resize?.disconnect();
66
+ observer.disconnect();
67
+ observer.observe(doc.documentElement, observation);
68
+ observed.clear();
69
+ for (const element of wanted) {
70
+ resize?.observe(element);
71
+ observer.observe(element, { attributes: true, attributeFilter: ['style', 'class'] });
72
+ observed.add(element);
73
+ }
74
+ }
75
+ if (changed)
76
+ win.dispatchEvent(new Event('nativeUIShellRefresh'));
77
+ if (top &&
78
+ (pointerActive ||
79
+ Array.from(wanted).some((element) => element.getAnimations().some((animation) => animation.playState === 'running'))))
80
+ schedule();
81
+ };
82
+ const schedule = () => {
83
+ if (!stopped && !frame)
84
+ frame = win.requestAnimationFrame(refresh);
85
+ };
86
+ const resize = win.ResizeObserver ? new win.ResizeObserver(schedule) : undefined;
87
+ const observer = new MutationObserver(schedule);
88
+ const observation = { subtree: true, childList: true, attributes: true, attributeFilter: ['class', 'style'] };
89
+ observer.observe(doc.documentElement, observation);
90
+ for (const name of ['ionModalWillPresent', 'ionModalDidPresent', 'ionModalWillDismiss', 'ionModalDidDismiss', 'ionBreakpointDidChange']) {
91
+ doc.addEventListener(name, (event) => {
92
+ const modal = event.target;
93
+ if (modal.localName !== 'ion-modal')
94
+ return;
95
+ if (name === 'ionModalDidDismiss') {
96
+ presenting.delete(modal);
97
+ dismissed.add(modal);
98
+ }
99
+ else {
100
+ presenting.add(modal);
101
+ dismissed.delete(modal);
102
+ }
103
+ refresh();
104
+ }, { capture: true, signal: listeners.signal });
105
+ }
106
+ doc.addEventListener('pointerdown', (event) => {
107
+ if (event.target.closest('ion-modal')) {
108
+ pointerActive = true;
109
+ schedule();
110
+ }
111
+ }, { capture: true, signal: listeners.signal });
112
+ for (const name of ['pointerup', 'pointercancel'])
113
+ doc.addEventListener(name, () => {
114
+ pointerActive = false;
115
+ schedule();
116
+ }, { capture: true, signal: listeners.signal });
117
+ win.addEventListener('resize', schedule, { signal: listeners.signal });
118
+ win.addEventListener('nativeUIShellRefresh', schedule, { signal: listeners.signal });
119
+ refresh();
120
+ return () => {
121
+ stopped = true;
122
+ win.cancelAnimationFrame(frame);
123
+ observer.disconnect();
124
+ resize?.disconnect();
125
+ listeners.abort();
126
+ if (states.get(doc) !== state)
127
+ return;
128
+ states.delete(doc);
129
+ doc.querySelectorAll(`.${modalRailClass}`).forEach((modal) => {
130
+ modal.classList.remove(modalRailClass);
131
+ modal.style.removeProperty(toolbarTop);
132
+ });
133
+ };
134
+ };
135
+ export const modalVerticalBarFrame = (modal) => {
136
+ const rect = modal.shadowRoot?.querySelector('[part~="content"]')?.getBoundingClientRect();
137
+ const win = modal.ownerDocument.defaultView;
138
+ if (!rect)
139
+ return;
140
+ const y = Math.max(0, rect.top);
141
+ const height = Math.min(win.innerHeight, rect.bottom) - y;
142
+ return height > 0 ? { x: 0, y, width: win.innerWidth, height } : undefined;
143
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"vertical-bars-web.d.ts","sourceRoot":"","sources":["../../src/native/vertical-bars-web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAuB,MAAM,eAAe,CAAC;AAqCpG,eAAO,MAAM,+BAA+B,GAC1C,KAAK,QAAQ,EACb,SAAS,oBAAoB,EAC7B,UAAS,MAAM,OAAoB,KAClC,mBA4UF,CAAC"}
1
+ {"version":3,"file":"vertical-bars-web.d.ts","sourceRoot":"","sources":["../../src/native/vertical-bars-web.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAuB,MAAM,eAAe,CAAC;AAqCpG,eAAO,MAAM,+BAA+B,GAC1C,KAAK,QAAQ,EACb,SAAS,oBAAoB,EAC7B,UAAS,MAAM,OAAoB,KAClC,mBAoVF,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { inVerticalBarsSurface, topModal } from './shared/modal';
1
2
  import { VERTICAL_BARS_TRANSITION_CANCELED } from '../native-integration';
2
3
  import { activateProjectedElement, createVerticalBarsPageState, verticalBarsActionCandidate, verticalBarsBackCandidate, verticalBarsEnteringPage, verticalBarsToolbarActions, isExcluded, isVerticalBarsToolbarGroup, preferredVerticalBarsBack, verticalBarsOwned, marker, prehideOnlyMutation, prehiddenClass, unprojected, withoutPrehide, } from './shared/dom';
3
4
  const backProjectionClass = 'ios-theme-vertical-bars-back-button-projection';
@@ -35,10 +36,12 @@ export const createVerticalBarsWebProjection = (doc, options, enabled = () => tr
35
36
  return element.isConnected && style.display !== 'none' && style.visibility === 'visible' && rect.width > 0 && rect.height > 0;
36
37
  });
37
38
  const inEligibleToolbar = (element) => !!verticalBarsRoot()?.contains(element) &&
39
+ inVerticalBarsSurface(element) &&
38
40
  verticalBarsActionCandidate(element) &&
39
41
  !isExcluded(element, verticalBarsEnteringPage(element)) &&
40
42
  !verticalBarsPages.isDeparted(element);
41
43
  const isEligibleBack = (element) => !!verticalBarsRoot()?.contains(element) &&
44
+ inVerticalBarsSurface(element) &&
42
45
  verticalBarsOwned(element) &&
43
46
  verticalBarsBackCandidate(element) &&
44
47
  !isExcluded(element, verticalBarsEnteringPage(element)) &&
@@ -116,7 +119,9 @@ export const createVerticalBarsWebProjection = (doc, options, enabled = () => tr
116
119
  const syncAction = (target, original) => {
117
120
  copyAttributes(target, original);
118
121
  target.classList.add('ios-theme-vertical-bars-toolbar-action', 'ion-cloned-element');
119
- const label = original.getAttribute('aria-label') ?? original.textContent?.trim();
122
+ const label = original.getAttribute('aria-label') ??
123
+ original.shadowRoot?.querySelector('[part~=native]')?.getAttribute('aria-label') ??
124
+ original.textContent?.trim();
120
125
  if (label)
121
126
  target.setAttribute('aria-label', label);
122
127
  if ('disabled' in original)
@@ -153,7 +158,7 @@ export const createVerticalBarsWebProjection = (doc, options, enabled = () => tr
153
158
  }
154
159
  };
155
160
  const project = (nextBack, groups) => {
156
- root = verticalBarsRoot();
161
+ root = topModal(doc) ?? verticalBarsRoot();
157
162
  let topOffset = 0;
158
163
  if (nextBack) {
159
164
  backSource = nextBack;
@@ -233,7 +238,7 @@ export const createVerticalBarsWebProjection = (doc, options, enabled = () => tr
233
238
  const groups = findToolbarGroups();
234
239
  if (!nextBack && !groups.length)
235
240
  return restore();
236
- if (sameSources(nextBack, groups))
241
+ if (root === (topModal(doc) ?? currentRoot) && sameSources(nextBack, groups))
237
242
  return syncExisting();
238
243
  restore();
239
244
  project(nextBack, groups);
@@ -255,6 +260,8 @@ export const createVerticalBarsWebProjection = (doc, options, enabled = () => tr
255
260
  const schedule = () => {
256
261
  if (stopped)
257
262
  return Promise.resolve();
263
+ if (!enabled())
264
+ restore();
258
265
  const done = new Promise((resolve) => waiters.push(resolve));
259
266
  if (!frame)
260
267
  frame = win.requestAnimationFrame(update);
@@ -301,6 +308,7 @@ export const createVerticalBarsWebProjection = (doc, options, enabled = () => tr
301
308
  doc.addEventListener(VERTICAL_BARS_TRANSITION_CANCELED, pageLifecycle, { capture: true, signal: listeners.signal });
302
309
  for (const name of ['ionModalWillPresent', 'ionModalDidDismiss'])
303
310
  doc.addEventListener(name, schedule, { capture: true, signal: listeners.signal });
311
+ win.addEventListener('resize', schedule, { signal: listeners.signal });
304
312
  win.addEventListener('nativeUIShellRefresh', schedule, { signal: listeners.signal });
305
313
  schedule();
306
314
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/native-integration/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC,CAAC;IACtE,MAAM,CAAC,CAAC,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3F;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAID,eAAO,MAAM,oBAAoB,GAAI,QAAQ,WAAW,EAAE,SAAS,WAAW,EAAE,QAAQ,WAAW,KAAG,mBAOrG,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,KAAK,QAAQ,KAAG,mBAAmB,EACR,CAAC;AAEpE,eAAO,MAAM,mBAAmB,GAAU,SAAS,mBAAmB,EAAE,QAAQ,OAAO,EAAE,QAAQ,OAAO,KAAG,OAAO,CAAC,OAAO,CAC3B,CAAC;AAGhG,eAAO,MAAM,iCAAiC,2CAA2C,CAAC;AAE1F,eAAO,MAAM,2BAA2B,GAAI,KAAK,QAAQ,EAAE,UAAU,wBAAwB,SAG5F,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,SAAS,WAAW,YAAiD,CAAC;AAEtG,eAAO,MAAM,oBAAoB,GAAU,QAAQ,WAAW,EAAE,KAAG,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CACxB,CAAC;AAGhF,eAAO,MAAM,8BAA8B,GAAI,WAAW,SAAS,EAAE,UAAU,WAAW,EAAE,UAAU,WAAW,SAkEhH,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/native-integration/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC,CAAC;IACtE,MAAM,CAAC,CAAC,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3F;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAID,eAAO,MAAM,oBAAoB,GAAI,QAAQ,WAAW,EAAE,SAAS,WAAW,EAAE,QAAQ,WAAW,KAAG,mBAOrG,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,KAAK,QAAQ,KAAG,mBAAmB,EACR,CAAC;AAEpE,eAAO,MAAM,mBAAmB,GAAU,SAAS,mBAAmB,EAAE,QAAQ,OAAO,EAAE,QAAQ,OAAO,KAAG,OAAO,CAAC,OAAO,CAC3B,CAAC;AAGhG,eAAO,MAAM,iCAAiC,2CAA2C,CAAC;AAE1F,eAAO,MAAM,2BAA2B,GAAI,KAAK,QAAQ,EAAE,UAAU,wBAAwB,SAG5F,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,SAAS,WAAW,YAAiD,CAAC;AAEtG,eAAO,MAAM,oBAAoB,GAAU,QAAQ,WAAW,EAAE,KAAG,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CACxB,CAAC;AAMhF,eAAO,MAAM,8BAA8B,GAAI,WAAW,SAAS,EAAE,UAAU,WAAW,EAAE,UAAU,WAAW,SAqEhH,CAAC"}
@@ -19,14 +19,19 @@ export const setNativeUIShellIntegration = (doc, runtime) => {
19
19
  };
20
20
  export const isNativeUIShell = (element) => element.hasAttribute('data-native-ui-shell');
21
21
  export const suspendNativeUIShell = async (scopes) => (await runtimes.get(scopes[0]?.ownerDocument)?.suspend(scopes)) ?? (() => { });
22
+ const connectedTransitions = new WeakSet();
23
+ const cancellationTransitions = new WeakSet();
22
24
  export const connectNativeUIShellTransition = (animation, entering, leaving) => {
23
- if (leaving)
25
+ if (leaving && !cancellationTransitions.has(animation)) {
26
+ cancellationTransitions.add(animation);
24
27
  animation.onFinish((step) => {
25
28
  if (step === 0)
26
29
  leaving.dispatchEvent(new CustomEvent(VERTICAL_BARS_TRANSITION_CANCELED, { bubbles: true, detail: { entering } }));
27
30
  });
28
- if (!runtimes.has(entering.ownerDocument))
31
+ }
32
+ if (connectedTransitions.has(animation) || !runtimes.has(entering.ownerDocument))
29
33
  return;
34
+ connectedTransitions.add(animation);
30
35
  const scopes = leaving ? [entering, leaving] : [entering];
31
36
  const play = animation.play.bind(animation);
32
37
  const progressStart = animation.progressStart.bind(animation);
@@ -0,0 +1,3 @@
1
+ import type { AnimationBuilder } from '@ionic/core';
2
+ export declare const withNativeUIShellTransition: (builder: AnimationBuilder) => AnimationBuilder;
3
+ //# sourceMappingURL=transition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transition.d.ts","sourceRoot":"","sources":["../../src/native-integration/transition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAQpD,eAAO,MAAM,2BAA2B,GACrC,SAAS,gBAAgB,KAAG,gBAK5B,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { connectNativeUIShellTransition } from './index';
2
+ export const withNativeUIShellTransition = (builder) => (baseEl, opts) => {
3
+ const animation = builder(baseEl, opts);
4
+ if (opts?.enteringEl)
5
+ connectNativeUIShellTransition(animation, opts.enteringEl, opts.leavingEl);
6
+ return animation;
7
+ };
@@ -1,14 +1,23 @@
1
1
  import type { Animation, AnimationKeyFrames } from '@ionic/core';
2
2
  import { AnimationPosition, EffectScales } from './interfaces';
3
3
  import { GestureDetail } from '@ionic/core';
4
+ export declare const animationRect: (element: Element, vertical?: boolean) => DOMRect | {
5
+ left: number;
6
+ top: number;
7
+ right: number;
8
+ width: number;
9
+ height: number;
10
+ x: number;
11
+ y: number;
12
+ };
4
13
  export declare const getScaleAnimation: (effectElement: Element) => Animation;
5
- export declare const createTabBarPressAnimation: (effect: HTMLElement, from: HTMLElement, to: HTMLElement, bar: HTMLElement) => Animation;
6
- export declare const createTabBarDragAnimation: (effect: HTMLElement, bar: HTMLElement, velocity: number) => Animation;
14
+ export declare const createTabBarPressAnimation: (effect: HTMLElement, from: HTMLElement, to: HTMLElement, bar: HTMLElement, vertical?: boolean) => Animation;
15
+ export declare const createTabBarDragAnimation: (effect: HTMLElement, bar: HTMLElement, velocity: number, vertical?: boolean) => Animation;
7
16
  export declare const createTabBarReleaseAnimation: (effectElement: Element, target: HTMLElement, tap?: {
8
17
  elapsed: number;
9
18
  distance: number;
10
- }) => Animation;
19
+ }, vertical?: boolean) => Animation;
11
20
  export declare const createPreMoveAnimation: (effectElement: Element, tabSelectedElement: Element, currentTouchedElement: Element, animationPosition: AnimationPosition) => Animation;
12
- export declare const createMoveAnimation: (effectElement: Element, detail: GestureDetail, tabSelectedElement: Element, animationPosition: AnimationPosition) => Animation;
21
+ export declare const createMoveAnimation: (effectElement: Element, detail: GestureDetail, tabSelectedElement: Element, animationPosition: AnimationPosition, vertical?: boolean) => Animation;
13
22
  export declare const getMoveAnimationKeyframe: (type: "moveRight" | "moveLeft" | "slowly", scales: EffectScales) => AnimationKeyFrames;
14
23
  //# sourceMappingURL=animations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"animations.d.ts","sourceRoot":"","sources":["../../src/sheets-of-glass/animations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;AAG7D,eAAO,MAAM,iBAAiB,GAAI,eAAe,OAAO,KAAG,SAE1D,CAAC;AAyCF,eAAO,MAAM,0BAA0B,GAAI,QAAQ,WAAW,EAAE,MAAM,WAAW,EAAE,IAAI,WAAW,EAAE,KAAK,WAAW,KAAG,SAuCtH,CAAC;AAGF,eAAO,MAAM,yBAAyB,GAAI,QAAQ,WAAW,EAAE,KAAK,WAAW,EAAE,UAAU,MAAM,KAAG,SAmBnG,CAAC;AAGF,eAAO,MAAM,4BAA4B,GACvC,eAAe,OAAO,EACtB,QAAQ,WAAW,EACnB,MAAM;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,KAC1C,SAgIF,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,eAAe,OAAO,EACtB,oBAAoB,OAAO,EAC3B,uBAAuB,OAAO,EAC9B,mBAAmB,iBAAiB,KACnC,SA0BF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,eAAe,OAAO,EACtB,QAAQ,aAAa,EACrB,oBAAoB,OAAO,EAC3B,mBAAmB,iBAAiB,KACnC,SAiBF,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,MAAM,WAAW,GAAG,UAAU,GAAG,QAAQ,EAAE,QAAQ,YAAY,KAAG,kBAqD1G,CAAC"}
1
+ {"version":3,"file":"animations.d.ts","sourceRoot":"","sources":["../../src/sheets-of-glass/animations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;AAI7D,eAAO,MAAM,aAAa,GAAI,SAAS,OAAO,EAAE,kBAAgB;;;;;;;;CAK/D,CAAC;AASF,eAAO,MAAM,iBAAiB,GAAI,eAAe,OAAO,KAAG,SAE1D,CAAC;AAyCF,eAAO,MAAM,0BAA0B,GACrC,QAAQ,WAAW,EACnB,MAAM,WAAW,EACjB,IAAI,WAAW,EACf,KAAK,WAAW,EAChB,kBAAgB,KACf,SAsCF,CAAC;AAGF,eAAO,MAAM,yBAAyB,GAAI,QAAQ,WAAW,EAAE,KAAK,WAAW,EAAE,UAAU,MAAM,EAAE,kBAAgB,KAAG,SAmBrH,CAAC;AAGF,eAAO,MAAM,4BAA4B,GACvC,eAAe,OAAO,EACtB,QAAQ,WAAW,EACnB,MAAM;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAC3C,kBAAgB,KACf,SAmIF,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,eAAe,OAAO,EACtB,oBAAoB,OAAO,EAC3B,uBAAuB,OAAO,EAC9B,mBAAmB,iBAAiB,KACnC,SA0BF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,eAAe,OAAO,EACtB,QAAQ,aAAa,EACrB,oBAAoB,OAAO,EAC3B,mBAAmB,iBAAiB,EACpC,kBAAgB,KACf,SAiBF,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,MAAM,WAAW,GAAG,UAAU,GAAG,QAAQ,EAAE,QAAQ,YAAY,KAAG,kBAqD1G,CAAC"}