@rcarls/rc-virtual-canvas 0.4.2 → 0.6.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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @rcarls/rc-virtual-canvas
2
2
 
3
+ ## 0.6.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 57370e4: Align component metadata, aggregate framework typings, development-time native-child
8
+ validation, controlled menu state, package declarations, and public documentation before the
9
+ next release.
10
+
11
+ ## 0.5.0
12
+
3
13
  ## 0.4.2
4
14
 
5
15
  ## 0.4.1
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # `@rcarls/rc-virtual-canvas`
2
2
 
3
+ <!-- markdownlint-disable MD013 -->
4
+
3
5
  Scrollable virtual canvas for rendering large coordinate-space content.
4
6
 
5
7
  Docs: [https://richardcarls.github.io/rc-webcomponents/components/rc-virtual-canvas](https://richardcarls.github.io/rc-webcomponents/components/rc-virtual-canvas).
@@ -19,8 +21,8 @@ npm install @rcarls/rc-virtual-canvas
19
21
  ## Import
20
22
 
21
23
  ```js
22
- import '@rcarls/rc-virtual-canvas'; // side-effect: registers <rc-virtual-canvas>
23
- import { RCVirtualCanvas } from '@rcarls/rc-virtual-canvas'; // named class export
24
+ import '@rcarls/rc-virtual-canvas'; // side-effect: registers <rc-virtual-canvas>
25
+ import { RCVirtualCanvas } from '@rcarls/rc-virtual-canvas'; // named class export
24
26
  ```
25
27
 
26
28
  ---
@@ -56,7 +58,7 @@ total size of your virtual content. On each `rc-virtual-canvas-render` event, us
56
58
  ```
57
59
 
58
60
  The canvas element should match the component's rendered size (set via CSS). The virtual
59
- content is larger scrolling is handled by an absolutely-positioned transparent `<div>`
61
+ content is larger; scrolling is handled by an absolutely positioned transparent `<div>`
60
62
  that triggers native scroll events.
61
63
 
62
64
  ---
@@ -65,65 +67,65 @@ that triggers native scroll events.
65
67
 
66
68
  ### Properties / attributes
67
69
 
68
- | Property | Attribute | Type | Default | Description |
69
- |---|---|---|---|---|
70
- | `contentWidth` | `content-width` | `number` | `0` | Total pixel width of the virtual content |
71
- | `contentHeight` | `content-height` | `number` | `0` | Total pixel height of the virtual content |
72
- | `autoResizeCanvas` | `auto-resize-canvas` | `boolean` | `true` | Keeps the slotted canvas backing store aligned to the measured viewport |
73
- | `renderMode` | `render-mode` | `'continuous' \| 'viewport-change' \| 'manual'` | `'continuous'` | Controls when render events are dispatched |
74
- | `imageRendering` | `image-rendering` | `'auto' \| 'crisp-edges' \| 'pixelated'` | `'auto'` | Convenience value applied to the slotted canvas via `image-rendering` |
70
+ | Property | Attribute | Type | Default | Description |
71
+ | ------------------ | -------------------- | ----------------------------------------------- | -------------- | ----------------------------------------------------------------------- |
72
+ | `contentWidth` | `content-width` | `number` | `0` | Total pixel width of the virtual content |
73
+ | `contentHeight` | `content-height` | `number` | `0` | Total pixel height of the virtual content |
74
+ | `autoResizeCanvas` | `auto-resize-canvas` | `boolean` | `true` | Keeps the slotted canvas backing store aligned to the measured viewport |
75
+ | `renderMode` | `render-mode` | `'continuous' \| 'viewport-change' \| 'manual'` | `'continuous'` | Controls when render events are dispatched |
76
+ | `imageRendering` | `image-rendering` | `'auto' \| 'crisp-edges' \| 'pixelated'` | `'auto'` | Convenience value applied to the slotted canvas via `image-rendering` |
75
77
 
76
78
  ### Read-only properties
77
79
 
78
- | Property | Type | Description |
79
- |---|---|---|
80
+ | Property | Type | Description |
81
+ | -------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------- |
80
82
  | `canvasScaleX` | `number` | Ratio of canvas backing-store pixels to CSS pixels along the x-axis (≈ `devicePixelRatio` when `autoResizeCanvas` is `true`) |
81
- | `canvasScaleY` | `number` | Ratio of canvas backing-store pixels to CSS pixels along the y-axis |
83
+ | `canvasScaleY` | `number` | Ratio of canvas backing-store pixels to CSS pixels along the y-axis |
82
84
 
83
85
  ### Methods
84
86
 
85
- | Method | Description |
86
- |---|---|
87
- | `getViewRect()` | Returns an immutable snapshot of the current viewport rectangle |
88
- | `scrollToContent(x, y, options?)` | Scrolls so the content coordinate is at the viewport origin |
89
- | `centerOnContent(x, y, options?)` | Scrolls so the content coordinate is centered in the viewport |
87
+ | Method | Description |
88
+ | ----------------------------------- | ------------------------------------------------------------------------------------------------ |
89
+ | `getViewRect()` | Returns an immutable snapshot of the current viewport rectangle |
90
+ | `scrollToContent(x, y, options?)` | Scrolls so the content coordinate is at the viewport origin |
91
+ | `centerOnContent(x, y, options?)` | Scrolls so the content coordinate is centered in the viewport |
90
92
  | `clientToContent(clientX, clientY)` | Converts browser client coordinates to content coordinates using the current backing-store scale |
91
- | `contentToClient(x, y)` | Converts content coordinates back to browser client coordinates |
92
- | `requestRender(reason?)` | Queues a render event; required when `renderMode` is `'manual'` |
93
+ | `contentToClient(x, y)` | Converts content coordinates back to browser client coordinates |
94
+ | `requestRender(reason?)` | Queues a render event; required when `renderMode` is `'manual'` |
93
95
 
94
96
  ### CSS custom properties
95
97
 
96
- | Property | Default | Description |
97
- |---|---|---|
98
- | `--rc-virtual-canvas-image-rendering` | `auto` | Fallback styling hook for the slotted canvas `image-rendering` value |
98
+ | Property | Default | Description |
99
+ | ------------------------------------- | ------- | -------------------------------------------------------------------- |
100
+ | `--rc-virtual-canvas-image-rendering` | `auto` | Fallback styling hook for the slotted canvas `image-rendering` value |
99
101
 
100
102
  ### CSS parts
101
103
 
102
- | Part | Description |
103
- |---|---|
104
- | `scroller` | Internal scroll container that owns the virtual content scroll range |
105
- | `overlay` | Viewport-positioned overlay container rendered inside the scroll container |
104
+ | Part | Description |
105
+ | ---------- | -------------------------------------------------------------------------- |
106
+ | `scroller` | Internal scroll container that owns the virtual content scroll range |
107
+ | `overlay` | Viewport-positioned overlay container rendered inside the scroll container |
106
108
 
107
109
  ### Slots
108
110
 
109
- | Slot | Description |
110
- |---|---|
111
- | *(default)* | A single `<canvas>` element. Non-canvas slotted elements are ignored by the component but rendered. |
112
- | `overlay` | Optional viewport-positioned content rendered over the canvas inside the scroll container. |
111
+ | Slot | Description |
112
+ | ----------- | --------------------------------------------------------------------------------------------------- |
113
+ | _(default)_ | A single `<canvas>` element. Non-canvas slotted elements are ignored by the component but rendered. |
114
+ | `overlay` | Optional viewport-positioned content rendered over the canvas inside the scroll container. |
113
115
 
114
116
  ### Events
115
117
 
116
- | Event | Bubbles | Cancelable | Detail | When |
117
- |---|---|---|---|---|
118
- | `rc-virtual-canvas-render` | Yes (composed) | No | `{ time: DOMHighResTimeStamp, reason: RenderReason, viewRect: ViewRect, contentRect: ViewRect }` | When the active render mode schedules a frame and a canvas is slotted |
118
+ | Event | Bubbles | Cancelable | Detail | When |
119
+ | -------------------------- | -------------- | ---------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------- |
120
+ | `rc-virtual-canvas-render` | Yes (composed) | No | `{ time: DOMHighResTimeStamp, reason: RenderReason, viewRect: ViewRect, contentRect: ViewRect }` | When the active render mode schedules a frame and a canvas is slotted |
119
121
 
120
122
  **`ViewRect` shape:**
121
123
 
122
124
  ```ts
123
125
  type ViewRect = {
124
- x: number; // Scroll offset — the x origin of the visible window in content space
125
- y: number; // Scroll offset — the y origin of the visible window in content space
126
- width: number; // Visible width in device pixels (from ResizeObserver devicePixelContentBoxSize)
126
+ x: number; // Scroll offset — the x origin of the visible window in content space
127
+ y: number; // Scroll offset — the y origin of the visible window in content space
128
+ width: number; // Visible width in device pixels (from ResizeObserver devicePixelContentBoxSize)
127
129
  height: number; // Visible height in device pixels
128
130
  };
129
131
  ```
@@ -134,11 +136,11 @@ type ViewRect = {
134
136
 
135
137
  **Render modes:**
136
138
 
137
- | Mode | Behavior |
138
- |---|---|
139
- | `'continuous'` | Dispatches on every animation frame while connected and a canvas is slotted |
139
+ | Mode | Behavior |
140
+ | ------------------- | ----------------------------------------------------------------------------- |
141
+ | `'continuous'` | Dispatches on every animation frame while connected and a canvas is slotted |
140
142
  | `'viewport-change'` | Dispatches after scroll, resize, content-size changes, and canvas replacement |
141
- | `'manual'` | Dispatches only after `requestRender()` |
143
+ | `'manual'` | Dispatches only after `requestRender()` |
142
144
 
143
145
  ---
144
146
 
@@ -172,7 +174,7 @@ vc.addEventListener('pointerdown', (event) => {
172
174
 
173
175
  ## Accessibility
174
176
 
175
- `rc-virtual-canvas` is a rendering surface. A `<canvas>` element has no inherent semantics it is a bitmap, not a document. If your canvas renders interactive or informational content, you are responsible for providing supplemental accessibility:
177
+ `rc-virtual-canvas` is a rendering surface. A `<canvas>` element has no inherent semantics; it is a bitmap, not a document. If your canvas renders interactive or informational content, you are responsible for providing supplemental accessibility:
176
178
 
177
179
  - Add an accessible `<div>` or `<table>` alternative outside the canvas with the same information (hidden visually with `clip-path` or similar, not `display: none`).
178
180
  - Use `aria-label` or `aria-labelledby` on the `<canvas>` to describe what it shows.
@@ -182,7 +184,7 @@ vc.addEventListener('pointerdown', (event) => {
182
184
 
183
185
  ## Browser support
184
186
 
185
- | Feature | Requirement |
186
- |---|---|
187
- | Core | Chrome 67+, Firefox 63+, Safari 12.1+ (Web Components) |
187
+ | Feature | Requirement |
188
+ | ---------------------------- | ---------------------------------------------------------------------------------- |
189
+ | Core | Chrome 67+, Firefox 63+, Safari 12.1+ (Web Components) |
188
190
  | Device-pixel-accurate sizing | Chrome 84+, Firefox 93+, Safari 15.4+ (ResizeObserver `devicePixelContentBoxSize`) |
@@ -35,7 +35,7 @@
35
35
  "name": "*",
36
36
  "declaration": {
37
37
  "name": "*",
38
- "module": "src/rc-virtual-canvas"
38
+ "module": "src/rc-virtual-canvas.js"
39
39
  }
40
40
  }
41
41
  ]
@@ -1,5 +1,5 @@
1
1
  import { css as _, LitElement as p, html as g } from "lit";
2
- import { property as h, query as u, state as d } from "lit/decorators.js";
2
+ import { property as h, query as u, state as l } from "lit/decorators.js";
3
3
  import { styleMap as b } from "lit/directives/style-map.js";
4
4
  const w = _`
5
5
  *,
@@ -70,9 +70,9 @@ const w = _`
70
70
  image-rendering: var(--rc-virtual-canvas-image-rendering, auto);
71
71
  }
72
72
  `;
73
- var R = Object.defineProperty, m = Object.getOwnPropertyDescriptor, o = (r, t, e, i) => {
74
- for (var s = i > 1 ? void 0 : i ? m(t, e) : t, a = r.length - 1, l; a >= 0; a--)
75
- (l = r[a]) && (s = (i ? l(t, e, s) : l(s)) || s);
73
+ var R = Object.defineProperty, f = Object.getOwnPropertyDescriptor, o = (r, t, e, i) => {
74
+ for (var s = i > 1 ? void 0 : i ? f(t, e) : t, a = r.length - 1, d; a >= 0; a--)
75
+ (d = r[a]) && (s = (i ? d(t, e, s) : d(s)) || s);
76
76
  return i && s && R(t, e, s), s;
77
77
  };
78
78
  function c(r) {
@@ -106,6 +106,8 @@ const v = class v extends p {
106
106
  }
107
107
  });
108
108
  }
109
+ firstUpdated() {
110
+ }
109
111
  set contentWidth(t) {
110
112
  const e = this._contentWidth;
111
113
  this._contentWidth = t, this._contentRect.width = this._contentWidth, this.requestUpdate("contentWidth", e), this._scheduleRender("viewport-change");
@@ -404,15 +406,15 @@ o([
404
406
  u("#placeholder", !0)
405
407
  ], n.prototype, "_$placeholder", 2);
406
408
  o([
407
- d()
409
+ l()
408
410
  ], n.prototype, "_$canvas", 2);
409
411
  o([
410
- d()
412
+ l()
411
413
  ], n.prototype, "_viewRect", 2);
412
414
  o([
413
- d()
415
+ l()
414
416
  ], n.prototype, "_contentRect", 2);
415
417
  export {
416
418
  n as R
417
419
  };
418
- //# sourceMappingURL=rc-virtual-canvas-BSpF0tcY.js.map
420
+ //# sourceMappingURL=rc-virtual-canvas-BBZvxU4D.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rc-virtual-canvas-BBZvxU4D.js","sources":["../src/rc-virtual-canvas.styles.ts","../src/rc-virtual-canvas.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const virtualCanvasStyles = css`\n *,\n *::before,\n *::after {\n box-sizing: border-box;\n }\n\n :host {\n position: relative;\n display: block;\n width: max-content;\n line-height: 0; /* remove extra space under slotted <canvas> element(s) */\n }\n\n :host([hidden]) {\n display: none;\n }\n\n #root {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n\n overflow: auto;\n scrollbar-width: var(--rc-virtual-canvas-scrollbar-width, thin);\n }\n\n #root::-webkit-scrollbar {\n width: var(--rc-virtual-canvas-scrollbar-size, auto);\n height: var(--rc-virtual-canvas-scrollbar-size, auto);\n }\n\n #root::-webkit-scrollbar-thumb {\n background: var(--rc-virtual-canvas-scrollbar-thumb-background, ButtonFace);\n }\n\n #root::-webkit-scrollbar-button {\n background: var(--rc-virtual-canvas-scrollbar-button-background, ButtonFace);\n }\n\n #root::-webkit-scrollbar-track {\n background: var(--rc-virtual-canvas-scrollbar-track-background, Canvas);\n }\n\n #placeholder {\n pointer-events: none;\n }\n\n #overlay {\n position: sticky;\n left: 0;\n top: 0;\n z-index: 1;\n display: block;\n width: 100%;\n height: 0;\n pointer-events: none;\n }\n\n ::slotted([slot='overlay']) {\n pointer-events: auto;\n }\n\n ::slotted(canvas) {\n image-rendering: var(--rc-virtual-canvas-image-rendering, auto);\n }\n`;\n\nexport default virtualCanvasStyles;\n","import { LitElement, html } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { styleMap } from 'lit/directives/style-map.js';\n\nimport virtualCanvasStyles from './rc-virtual-canvas.styles.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-virtual-canvas': RCVirtualCanvas;\n }\n\n interface HTMLElementEventMap {\n 'rc-virtual-canvas-render': CustomEvent<RCVirtualCanvasRenderInit>;\n 'rc-virtual-canvas-pointer': CustomEvent<RCVirtualCanvasPointerInit>;\n }\n}\n\n/**\n * Scrollable virtual canvas for rendering large coordinate-space content.\n *\n * `x` and `y` are scroll offsets in CSS pixels; `width` and `height` are the canvas\n * backing-store dimensions in device pixels (DPR-accurate when `autoResizeCanvas` is `true`).\n */\nexport type RCVirtualCanvasViewRect = Readonly<{\n /** Scroll offset x in content space (CSS px) */\n x: number;\n\n /** Scroll offset y in content space (CSS px) */\n y: number;\n\n /** Visible width in device pixels */\n width: number;\n\n /** Visible height in device pixels */\n height: number;\n}>;\n\n/** Controls when `rc-virtual-canvas-render` events are dispatched */\nexport type RCVirtualCanvasRenderMode = 'continuous' | 'viewport-change' | 'manual';\n\n/** Identifies what triggered a render event */\nexport type RCVirtualCanvasRenderReason = 'animation-frame' | 'viewport-change' | 'manual';\n\n/** Content-space coordinate pair returned by coordinate-conversion methods */\nexport type RCVirtualCanvasPoint = Readonly<{\n /** Content space x coordinate in CSS pixels */\n x: number;\n\n /** Content space y coordinate in CSS pixels */\n y: number;\n}>;\n\n/**\n * Detail shape for `rc-virtual-canvas-pointer` events.\n *\n * Carries the source event's coordinates in both browser-client and content space,\n * along with all modifier key state.\n */\nexport type RCVirtualCanvasPointerInit = {\n /** DOM event type (e.g. `'pointerdown'`, `'click'`) */\n type: string;\n\n /** Browser client x coordinate from the source event */\n clientX: number;\n\n /** Browser client y coordinate from the source event */\n clientY: number;\n\n /** Content x coordinate mapped through the current backing-store scale */\n contentX: number;\n\n /** Content y coordinate mapped through the current backing-store scale */\n contentY: number;\n\n /** Frozen viewport snapshot at the moment the pointer event fired */\n viewRect: RCVirtualCanvasViewRect;\n\n /** Mouse button index from the source event */\n button: number;\n\n /** Active button bitmask from the source event */\n buttons: number;\n\n /** Whether the Alt key was held */\n altKey: boolean;\n\n /** Whether the Ctrl key was held */\n ctrlKey: boolean;\n\n /** Whether the Shift key was held */\n shiftKey: boolean;\n\n /** Whether the Meta key was held */\n metaKey: boolean;\n\n /** The original DOM event that produced this detail */\n sourceEvent: PointerEvent | MouseEvent;\n};\n\n/** CSS `image-rendering` value applied to the slotted canvas */\nexport type RCVirtualCanvasImageRendering = 'auto' | 'crisp-edges' | 'pixelated';\n\n/** Detail shape for `rc-virtual-canvas-render` events */\nexport type RCVirtualCanvasRenderInit = {\n /** High-resolution timestamp from `requestAnimationFrame` */\n time: DOMHighResTimeStamp;\n\n /** What triggered this render */\n reason: RCVirtualCanvasRenderReason;\n\n /** Frozen snapshot of the viewport for this frame */\n viewRect: RCVirtualCanvasViewRect;\n\n /** Frozen snapshot of the full content bounds for this frame */\n contentRect: RCVirtualCanvasViewRect;\n};\n\nfunction createRectSnapshot(rect: RCVirtualCanvasViewRect) {\n return Object.freeze({\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n });\n}\n\n/**\n * A scrollable virtual canvas component.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-virtual-canvas rc-virtual-canvas docs}\n *\n * @slot - The HTMLCanvasElement\n * @slot overlay - Optional viewport-positioned content rendered inside the\n * scroll container above the canvas.\n *\n * @fires rc-virtual-canvas-render - Fires with viewport data when the canvas should redraw.\n * @fires rc-virtual-canvas-pointer - Fires pointer/mouse input mapped to virtual content coordinates.\n *\n * @csspart scroller - Internal scroll container that owns the virtual content scroll range.\n * @csspart overlay - Viewport-positioned overlay container rendered inside the scroll container.\n *\n * @attr content-width - Total pixel width of the virtual content.\n * @attr content-height - Total pixel height of the virtual content.\n * @attr auto-resize-canvas - Keep the slotted canvas backing store aligned to the viewport.\n * @attr render-mode - Controls when render events are dispatched.\n * @attr image-rendering - Convenience `image-rendering` value applied to the slotted canvas.\n *\n * @cssprop [--rc-virtual-canvas-scrollbar-width=thin] - `scrollbar-width` of the internal\n * scroll container.\n * @cssprop [--rc-virtual-canvas-scrollbar-size=auto] - WebKit scrollbar thickness.\n * @cssprop [--rc-virtual-canvas-scrollbar-thumb-background=ButtonFace] - WebKit scrollbar\n * thumb color.\n * @cssprop [--rc-virtual-canvas-scrollbar-button-background=ButtonFace] - WebKit scrollbar\n * button color.\n * @cssprop [--rc-virtual-canvas-scrollbar-track-background=Canvas] - WebKit scrollbar\n * track color.\n * @cssprop [--rc-virtual-canvas-image-rendering=auto] - `image-rendering` applied to the\n * slotted canvas; kept in sync with the `imageRendering` property.\n */\nexport class RCVirtualCanvas extends LitElement {\n static styles = [virtualCanvasStyles];\n\n protected _rafHandle: number = 0;\n protected _pendingRenderReason?: RCVirtualCanvasRenderReason;\n\n protected override firstUpdated(): void {\n if (import.meta.env.DEV && !this.querySelector(':scope > canvas')) {\n console.warn(\n '[rc-virtual-canvas] No direct child <canvas> found. Place a native <canvas> inside <rc-virtual-canvas>.',\n this,\n );\n }\n }\n\n protected readonly _handledPointerEvents = new WeakSet<Event>();\n\n // Stored bound reference so the same closure is used for scheduling and\n // cancellation — `bind()` returns a new function every call.\n protected readonly _boundUpdate = (time: DOMHighResTimeStamp) => this._update(time);\n\n protected readonly _boundPointerEvent = (event: PointerEvent | MouseEvent) =>\n this._onPointerEvent(event);\n\n /** Pixel width of the virtual content */\n @property({ type: Number, attribute: 'content-width' })\n set contentWidth(val: number) {\n const oldValue = this._contentWidth;\n\n this._contentWidth = val;\n\n this._contentRect.width = this._contentWidth;\n this.requestUpdate('contentWidth', oldValue);\n this._scheduleRender('viewport-change');\n }\n\n get contentWidth() {\n return this._contentWidth;\n }\n\n private _contentWidth: number = 0;\n\n /** Pixel height of the virtual content */\n @property({ type: Number, attribute: 'content-height' })\n set contentHeight(val: number) {\n const oldValue = this._contentHeight;\n\n this._contentHeight = val;\n\n this._contentRect.height = this._contentHeight;\n this.requestUpdate('contentHeight', oldValue);\n this._scheduleRender('viewport-change');\n }\n\n get contentHeight() {\n return this._contentHeight;\n }\n\n private _contentHeight: number = 0;\n\n /** When true, keep the slotted canvas backing store aligned to the viewport. */\n @property({ attribute: 'auto-resize-canvas', type: Boolean })\n autoResizeCanvas: boolean = true;\n\n /** Controls when render events are dispatched. */\n @property({ attribute: 'render-mode' })\n renderMode: RCVirtualCanvasRenderMode = 'continuous';\n\n /** Convenience image-rendering value applied to the slotted canvas. */\n @property({ attribute: 'image-rendering' })\n imageRendering: RCVirtualCanvasImageRendering = 'auto';\n\n /** Shadow DOM scroll container that owns pointer interaction and native scrolling */\n @query('#root', true)\n protected _$root!: HTMLDivElement;\n\n /** Absolutely-positioned div that establishes the virtual scroll range */\n @query('#placeholder', true)\n protected _$placeholder!: HTMLDivElement;\n\n /** Currently-tracked slotted canvas element; `null` when no canvas is slotted */\n @state()\n protected _$canvas: HTMLCanvasElement | null = null;\n\n /** Mutable current-frame viewport geometry; call `getViewRect()` for a frozen snapshot */\n @state()\n protected _viewRect = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n };\n\n /** Mutable content bounds; updated when `contentWidth` or `contentHeight` change */\n @state()\n protected _contentRect = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n };\n\n /** Watches the slotted canvas for DPR-accurate dimension changes */\n protected _resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => {\n for (const entry of entries) {\n const devicePixelBoxSize = Array.isArray(entry.devicePixelContentBoxSize)\n ? entry.devicePixelContentBoxSize[0]\n : entry.devicePixelContentBoxSize;\n\n this._viewRect.width = this._getMeasuredCanvasWidth(\n devicePixelBoxSize?.inlineSize ??\n Math.round(entry.contentRect.width * window.devicePixelRatio),\n );\n\n this._viewRect.height = this._getMeasuredCanvasHeight(\n devicePixelBoxSize?.blockSize ??\n Math.round(entry.contentRect.height * window.devicePixelRatio),\n );\n\n this._syncCanvasBackingStore();\n this._scheduleRender('viewport-change');\n }\n });\n\n /** Reads scroll position from the root container and schedules a render */\n protected _onScroll() {\n this._viewRect.x = this._$root.scrollLeft;\n this._viewRect.y = this._$root.scrollTop;\n\n this._scheduleRender('viewport-change');\n }\n\n /** Replaces canvas tracking and re-registers the resize observer when slot content changes */\n protected _onSlotChange(e: Event) {\n this._resizeObserver.disconnect();\n\n this._$canvas =\n (e.currentTarget as HTMLSlotElement)\n .assignedElements()\n .filter((el) => el instanceof HTMLCanvasElement)[0] ?? null;\n\n if (this._$canvas != null) {\n this._viewRect = {\n x: this._$root.scrollLeft ?? 0,\n y: this._$root.scrollTop ?? 0,\n width: this._getMeasuredCanvasWidth(this._$canvas.clientWidth),\n height: this._getMeasuredCanvasHeight(this._$canvas.clientHeight),\n };\n\n this._syncCanvasBackingStore();\n this._observeCanvasResize(this._$canvas);\n\n this._scheduleRender('viewport-change');\n }\n }\n\n /** Observes canvas size with DPR-accurate boxes when the browser supports them */\n protected _observeCanvasResize($canvas: HTMLCanvasElement) {\n try {\n this._resizeObserver.observe($canvas, {\n box: 'device-pixel-content-box',\n });\n } catch (error) {\n if (!(error instanceof TypeError)) {\n throw error;\n }\n\n this._resizeObserver.observe($canvas);\n }\n }\n\n /**\n * Returns a frozen snapshot of the current viewport rectangle.\n *\n * Safe to keep between frames — the returned object will not be mutated\n * by future scroll or resize work.\n */\n getViewRect() {\n return createRectSnapshot(this._viewRect);\n }\n\n /**\n * Scrolls so the content coordinate is at the viewport origin.\n *\n * @param x - Content x coordinate in CSS pixels\n * @param y - Content y coordinate in CSS pixels\n * @param options - Native scroll options passed to scrollTo\n */\n scrollToContent(x: number, y: number, options: ScrollOptions = {}) {\n this._$root.scrollTo({\n ...options,\n left: x,\n top: y,\n });\n\n this._viewRect.x = this._$root.scrollLeft;\n this._viewRect.y = this._$root.scrollTop;\n this._scheduleRender('viewport-change');\n }\n\n /**\n * Scrolls so the content coordinate is centered in the viewport.\n *\n * @param x - Content x coordinate in CSS pixels\n * @param y - Content y coordinate in CSS pixels\n * @param options - Native scroll options passed to scrollTo\n */\n centerOnContent(x: number, y: number, options: ScrollOptions = {}) {\n this.scrollToContent(\n x - this._$root.clientWidth * 0.5,\n y - this._$root.clientHeight * 0.5,\n options,\n );\n }\n\n /**\n * Converts browser client coordinates to content coordinates using the current\n * backing-store scale.\n *\n * @param clientX - Browser client x coordinate (e.g. from a pointer event)\n * @param clientY - Browser client y coordinate\n *\n * @example\n * vc.addEventListener('pointerdown', (e) => {\n * const { x, y } = vc.clientToContent(e.clientX, e.clientY);\n * placeMarkerAt(x, y);\n * });\n */\n clientToContent(clientX: number, clientY: number) {\n const canvasRect = this._getCanvasClientRect();\n const scaleX = this._getViewportScaleX(canvasRect);\n const scaleY = this._getViewportScaleY(canvasRect);\n\n return Object.freeze({\n x: this._viewRect.x + (clientX - canvasRect.left) * scaleX,\n y: this._viewRect.y + (clientY - canvasRect.top) * scaleY,\n });\n }\n\n /**\n * Converts content coordinates back to browser client coordinates.\n *\n * @param x - Content x coordinate in CSS pixels\n * @param y - Content y coordinate in CSS pixels\n *\n * @example\n * const { x, y } = vc.contentToClient(contentX, contentY);\n * tooltip.style.left = `${x}px`;\n * tooltip.style.top = `${y}px`;\n */\n contentToClient(x: number, y: number) {\n const canvasRect = this._getCanvasClientRect();\n const scaleX = this._getViewportScaleX(canvasRect);\n const scaleY = this._getViewportScaleY(canvasRect);\n\n return Object.freeze({\n x: canvasRect.left + (x - this._viewRect.x) / scaleX,\n y: canvasRect.top + (y - this._viewRect.y) / scaleY,\n });\n }\n\n /**\n * Queues a render event on the next animation frame.\n *\n * Required when `renderMode` is `'manual'`. In other modes the component\n * schedules renders automatically; calling this with reason `'animation-frame'`\n * is a no-op when `renderMode` is `'viewport-change'`.\n *\n * @param reason - Render reason reported in the event detail\n */\n requestRender(reason: RCVirtualCanvasRenderReason = 'manual') {\n this._scheduleRender(reason);\n }\n\n /**\n * Ratio of canvas backing-store pixels to CSS pixels along the x-axis.\n *\n * Equals `devicePixelRatio` when `autoResizeCanvas` is `true`. Use as the x-scale\n * factor in `ctx.scale()` to draw at CSS pixel resolution.\n *\n * @example\n * vc.addEventListener('rc-virtual-canvas-render', ({ detail: { viewRect } }) => {\n * ctx.save();\n * ctx.scale(vc.canvasScaleX, vc.canvasScaleY);\n * drawScene(ctx, viewRect);\n * ctx.restore();\n * });\n */\n get canvasScaleX(): number {\n const canvasRect = this._getCanvasClientRect();\n\n return this._getViewportScaleX(canvasRect);\n }\n\n /**\n * Ratio of canvas backing-store pixels to CSS pixels along the y-axis.\n *\n * Equals `devicePixelRatio` when `autoResizeCanvas` is `true`. Use as the y-scale\n * factor in `ctx.scale()` to draw at CSS pixel resolution.\n */\n get canvasScaleY(): number {\n const canvasRect = this._getCanvasClientRect();\n\n return this._getViewportScaleY(canvasRect);\n }\n\n /** Maps pointer and mouse events to content coordinates and dispatches `rc-virtual-canvas-pointer` */\n protected _onPointerEvent(event: PointerEvent | MouseEvent) {\n if (this._handledPointerEvents.has(event)) {\n return;\n }\n\n if (this._isOverlayEvent(event)) {\n return;\n }\n\n this._handledPointerEvents.add(event);\n\n const contentPoint = this.clientToContent(event.clientX, event.clientY);\n\n const shouldContinue = this.dispatchEvent(\n new CustomEvent<RCVirtualCanvasPointerInit>('rc-virtual-canvas-pointer', {\n bubbles: true,\n composed: true,\n cancelable: true,\n detail: {\n type: event.type,\n clientX: event.clientX,\n clientY: event.clientY,\n contentX: contentPoint.x,\n contentY: contentPoint.y,\n viewRect: createRectSnapshot(this._viewRect),\n button: event.button,\n buttons: event.buttons,\n altKey: event.altKey,\n ctrlKey: event.ctrlKey,\n shiftKey: event.shiftKey,\n metaKey: event.metaKey,\n sourceEvent: event,\n },\n }),\n );\n\n if (!shouldContinue) {\n event.preventDefault();\n }\n }\n\n protected _isOverlayEvent(event: Event): boolean {\n return event\n .composedPath()\n .some(($node) => $node instanceof HTMLSlotElement && $node.name === 'overlay');\n }\n\n /**\n * RAF callback. Dispatches `rc-virtual-canvas-render` and re-schedules in continuous mode.\n *\n * @param time - High-resolution timestamp from `requestAnimationFrame`\n */\n protected _update(time: DOMHighResTimeStamp) {\n this._rafHandle = 0;\n\n if (!this.isConnected || this._$canvas == null) {\n return;\n }\n\n const reason =\n this._pendingRenderReason ??\n (this.renderMode === 'continuous' ? 'animation-frame' : 'manual');\n\n this._pendingRenderReason = undefined;\n\n this.dispatchEvent(\n new CustomEvent<RCVirtualCanvasRenderInit>('rc-virtual-canvas-render', {\n bubbles: true,\n composed: true,\n detail: {\n time,\n reason,\n viewRect: createRectSnapshot(this._viewRect),\n contentRect: createRectSnapshot(this._contentRect),\n },\n }),\n );\n\n if (this.renderMode === 'continuous') {\n this._scheduleRender('animation-frame');\n }\n }\n\n /** Registers pointer event listeners and starts rendering in continuous mode */\n override connectedCallback() {\n super.connectedCallback();\n\n this.addEventListener('pointerdown', this._boundPointerEvent);\n this.addEventListener('pointermove', this._boundPointerEvent);\n this.addEventListener('pointerup', this._boundPointerEvent);\n this.addEventListener('click', this._boundPointerEvent);\n this.addEventListener('dblclick', this._boundPointerEvent);\n this.addEventListener('contextmenu', this._boundPointerEvent);\n\n if (this._rafHandle) {\n cancelAnimationFrame(this._rafHandle);\n this._rafHandle = 0;\n }\n\n if (this.renderMode === 'continuous') {\n this._scheduleRender('animation-frame');\n }\n }\n\n /** Cancels any pending animation frame, disconnects the resize observer, and removes pointer listeners */\n override disconnectedCallback() {\n super.disconnectedCallback();\n\n cancelAnimationFrame(this._rafHandle);\n this._rafHandle = 0;\n this._resizeObserver.disconnect();\n\n this.removeEventListener('pointerdown', this._boundPointerEvent);\n this.removeEventListener('pointermove', this._boundPointerEvent);\n this.removeEventListener('pointerup', this._boundPointerEvent);\n this.removeEventListener('click', this._boundPointerEvent);\n this.removeEventListener('dblclick', this._boundPointerEvent);\n this.removeEventListener('contextmenu', this._boundPointerEvent);\n }\n\n /** Reacts to `renderMode`, `autoResizeCanvas`, and `imageRendering` property changes */\n protected override updated(changed: Map<string, unknown>) {\n if (changed.has('renderMode')) {\n if (this.renderMode === 'continuous') {\n this._scheduleRender('animation-frame');\n } else if (this._pendingRenderReason === 'animation-frame') {\n if (this._rafHandle) {\n cancelAnimationFrame(this._rafHandle);\n\n this._rafHandle = 0;\n }\n\n this._pendingRenderReason = undefined;\n } else if (this.renderMode === 'viewport-change') {\n this._scheduleRender('viewport-change');\n }\n }\n\n if (changed.has('autoResizeCanvas')) {\n this._syncCanvasBackingStore();\n }\n\n if (changed.has('imageRendering')) {\n this.style.setProperty('--rc-virtual-canvas-image-rendering', this.imageRendering);\n }\n }\n\n protected _scheduleRender(reason: RCVirtualCanvasRenderReason) {\n if (this.renderMode === 'manual' && reason !== 'manual') {\n return;\n }\n\n if (this.renderMode === 'viewport-change' && reason === 'animation-frame') {\n return;\n }\n\n this._pendingRenderReason = reason;\n\n if (!this.isConnected || this._rafHandle) {\n return;\n }\n\n this._rafHandle = window.requestAnimationFrame(this._boundUpdate);\n }\n\n protected _syncCanvasBackingStore() {\n if (!this.autoResizeCanvas || this._$canvas == null) {\n return;\n }\n\n const width = Math.max(0, Math.round(this._viewRect.width));\n const height = Math.max(0, Math.round(this._viewRect.height));\n\n if (this._$canvas.width !== width) {\n this._$canvas.width = width;\n }\n\n if (this._$canvas.height !== height) {\n this._$canvas.height = height;\n }\n }\n\n protected _getCanvasClientRect() {\n if (this._$canvas == null) {\n return this.getBoundingClientRect();\n }\n\n return this._$canvas.getBoundingClientRect();\n }\n\n protected _getMeasuredCanvasWidth(fallbackWidth: number) {\n if (!this.autoResizeCanvas && this._$canvas && this._$canvas.width > 0) {\n return this._$canvas.width;\n }\n\n return fallbackWidth;\n }\n\n protected _getMeasuredCanvasHeight(fallbackHeight: number) {\n if (!this.autoResizeCanvas && this._$canvas && this._$canvas.height > 0) {\n return this._$canvas.height;\n }\n\n return fallbackHeight;\n }\n\n protected _getViewportScaleX(canvasRect: DOMRect) {\n return canvasRect.width > 0 ? this._viewRect.width / canvasRect.width : 1;\n }\n\n protected _getViewportScaleY(canvasRect: DOMRect) {\n return canvasRect.height > 0 ? this._viewRect.height / canvasRect.height : 1;\n }\n\n render() {\n return html`\n <div\n id=\"root\"\n part=\"scroller\"\n @scroll=${this._onScroll}\n @pointerdown=${this._onPointerEvent}\n @pointermove=${this._onPointerEvent}\n @pointerup=${this._onPointerEvent}\n @click=${this._onPointerEvent}\n @dblclick=${this._onPointerEvent}\n @contextmenu=${this._onPointerEvent}\n >\n <div id=\"overlay\" part=\"overlay\">\n <slot name=\"overlay\"></slot>\n </div>\n\n <div\n id=\"placeholder\"\n style=${styleMap({\n width: `${this.contentWidth}px`,\n height: `${this.contentHeight}px`,\n })}\n ></div>\n </div>\n\n <slot @slotchange=${this._onSlotChange}></slot>\n `;\n }\n}\n\nexport default RCVirtualCanvas;\n"],"names":["virtualCanvasStyles","css","createRectSnapshot","rect","_RCVirtualCanvas","LitElement","time","event","entries","entry","devicePixelBoxSize","val","oldValue","e","el","$canvas","error","x","y","options","clientX","clientY","canvasRect","scaleX","scaleY","reason","contentPoint","$node","changed","width","height","fallbackWidth","fallbackHeight","html","styleMap","RCVirtualCanvas","__decorateClass","property","query","state"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { R as a } from "./rc-virtual-canvas-BSpF0tcY.js";
1
+ import { R as a } from "./rc-virtual-canvas-BBZvxU4D.js";
2
2
  customElements.get("rc-virtual-canvas") || customElements.define("rc-virtual-canvas", a);
3
3
  export {
4
4
  a as RCVirtualCanvas
@@ -1 +1 @@
1
- {"version":3,"file":"rc-virtual-canvas-define.js","sources":["../src/define.ts"],"sourcesContent":["import { RCVirtualCanvas } from './index.js';\n\ncustomElements.get('rc-virtual-canvas') || customElements.define('rc-virtual-canvas', RCVirtualCanvas);\n\nexport * from './index.js';\n"],"names":["RCVirtualCanvas"],"mappings":";AAEA,eAAe,IAAI,mBAAmB,KAAK,eAAe,OAAO,qBAAqBA,CAAe;"}
1
+ {"version":3,"file":"rc-virtual-canvas-define.js","sources":["../src/define.ts"],"sourcesContent":["import { RCVirtualCanvas } from './index.js';\n\ncustomElements.get('rc-virtual-canvas') ||\n customElements.define('rc-virtual-canvas', RCVirtualCanvas);\n\nexport * from './index.js';\n"],"names":["RCVirtualCanvas"],"mappings":";AAEA,eAAe,IAAI,mBAAmB,KACpC,eAAe,OAAO,qBAAqBA,CAAe;"}
@@ -1,4 +1,4 @@
1
- import { R as o } from "./rc-virtual-canvas-BSpF0tcY.js";
1
+ import { R as o } from "./rc-virtual-canvas-BBZvxU4D.js";
2
2
  export {
3
3
  o as RCVirtualCanvas
4
4
  };
@@ -1 +1 @@
1
- export * from './rc-virtual-canvas';
1
+ export * from './rc-virtual-canvas.js';
@@ -119,6 +119,7 @@ export declare class RCVirtualCanvas extends LitElement {
119
119
  static styles: import('lit').CSSResult[];
120
120
  protected _rafHandle: number;
121
121
  protected _pendingRenderReason?: RCVirtualCanvasRenderReason;
122
+ protected firstUpdated(): void;
122
123
  protected readonly _handledPointerEvents: WeakSet<Event>;
123
124
  protected readonly _boundUpdate: (time: DOMHighResTimeStamp) => void;
124
125
  protected readonly _boundPointerEvent: (event: PointerEvent | MouseEvent) => void;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.4.2",
6
+ "version": "0.6.0",
7
7
  "description": "Scrollable virtual canvas for rendering large coordinate-space content.",
8
8
  "repository": {
9
9
  "type": "git",
@@ -1 +0,0 @@
1
- {"version":3,"file":"rc-virtual-canvas-BSpF0tcY.js","sources":["../src/rc-virtual-canvas.styles.ts","../src/rc-virtual-canvas.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const virtualCanvasStyles = css`\n *,\n *::before,\n *::after {\n box-sizing: border-box;\n }\n\n :host {\n position: relative;\n display: block;\n width: max-content;\n line-height: 0; /* remove extra space under slotted <canvas> element(s) */\n }\n\n :host([hidden]) {\n display: none;\n }\n\n #root {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n\n overflow: auto;\n scrollbar-width: var(--rc-virtual-canvas-scrollbar-width, thin);\n }\n\n #root::-webkit-scrollbar {\n width: var(--rc-virtual-canvas-scrollbar-size, auto);\n height: var(--rc-virtual-canvas-scrollbar-size, auto);\n }\n\n #root::-webkit-scrollbar-thumb {\n background: var(--rc-virtual-canvas-scrollbar-thumb-background, ButtonFace);\n }\n\n #root::-webkit-scrollbar-button {\n background: var(--rc-virtual-canvas-scrollbar-button-background, ButtonFace);\n }\n\n #root::-webkit-scrollbar-track {\n background: var(--rc-virtual-canvas-scrollbar-track-background, Canvas);\n }\n\n #placeholder {\n pointer-events: none;\n }\n\n #overlay {\n position: sticky;\n left: 0;\n top: 0;\n z-index: 1;\n display: block;\n width: 100%;\n height: 0;\n pointer-events: none;\n }\n\n ::slotted([slot='overlay']) {\n pointer-events: auto;\n }\n\n ::slotted(canvas) {\n image-rendering: var(--rc-virtual-canvas-image-rendering, auto);\n }\n`;\n\nexport default virtualCanvasStyles;\n","import { LitElement, html } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { styleMap } from 'lit/directives/style-map.js';\n\nimport virtualCanvasStyles from './rc-virtual-canvas.styles';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-virtual-canvas': RCVirtualCanvas;\n }\n\n interface HTMLElementEventMap {\n 'rc-virtual-canvas-render': CustomEvent<RCVirtualCanvasRenderInit>;\n 'rc-virtual-canvas-pointer': CustomEvent<RCVirtualCanvasPointerInit>;\n }\n}\n\n/**\n * Scrollable virtual canvas for rendering large coordinate-space content.\n *\n * `x` and `y` are scroll offsets in CSS pixels; `width` and `height` are the canvas\n * backing-store dimensions in device pixels (DPR-accurate when `autoResizeCanvas` is `true`).\n */\nexport type RCVirtualCanvasViewRect = Readonly<{\n /** Scroll offset x in content space (CSS px) */\n x: number;\n\n /** Scroll offset y in content space (CSS px) */\n y: number;\n\n /** Visible width in device pixels */\n width: number;\n\n /** Visible height in device pixels */\n height: number;\n}>;\n\n/** Controls when `rc-virtual-canvas-render` events are dispatched */\nexport type RCVirtualCanvasRenderMode = 'continuous' | 'viewport-change' | 'manual';\n\n/** Identifies what triggered a render event */\nexport type RCVirtualCanvasRenderReason = 'animation-frame' | 'viewport-change' | 'manual';\n\n/** Content-space coordinate pair returned by coordinate-conversion methods */\nexport type RCVirtualCanvasPoint = Readonly<{\n /** Content space x coordinate in CSS pixels */\n x: number;\n\n /** Content space y coordinate in CSS pixels */\n y: number;\n}>;\n\n/**\n * Detail shape for `rc-virtual-canvas-pointer` events.\n *\n * Carries the source event's coordinates in both browser-client and content space,\n * along with all modifier key state.\n */\nexport type RCVirtualCanvasPointerInit = {\n /** DOM event type (e.g. `'pointerdown'`, `'click'`) */\n type: string;\n\n /** Browser client x coordinate from the source event */\n clientX: number;\n\n /** Browser client y coordinate from the source event */\n clientY: number;\n\n /** Content x coordinate mapped through the current backing-store scale */\n contentX: number;\n\n /** Content y coordinate mapped through the current backing-store scale */\n contentY: number;\n\n /** Frozen viewport snapshot at the moment the pointer event fired */\n viewRect: RCVirtualCanvasViewRect;\n\n /** Mouse button index from the source event */\n button: number;\n\n /** Active button bitmask from the source event */\n buttons: number;\n\n /** Whether the Alt key was held */\n altKey: boolean;\n\n /** Whether the Ctrl key was held */\n ctrlKey: boolean;\n\n /** Whether the Shift key was held */\n shiftKey: boolean;\n\n /** Whether the Meta key was held */\n metaKey: boolean;\n\n /** The original DOM event that produced this detail */\n sourceEvent: PointerEvent | MouseEvent;\n};\n\n/** CSS `image-rendering` value applied to the slotted canvas */\nexport type RCVirtualCanvasImageRendering = 'auto' | 'crisp-edges' | 'pixelated';\n\n/** Detail shape for `rc-virtual-canvas-render` events */\nexport type RCVirtualCanvasRenderInit = {\n /** High-resolution timestamp from `requestAnimationFrame` */\n time: DOMHighResTimeStamp;\n\n /** What triggered this render */\n reason: RCVirtualCanvasRenderReason;\n\n /** Frozen snapshot of the viewport for this frame */\n viewRect: RCVirtualCanvasViewRect;\n\n /** Frozen snapshot of the full content bounds for this frame */\n contentRect: RCVirtualCanvasViewRect;\n};\n\nfunction createRectSnapshot(rect: RCVirtualCanvasViewRect) {\n return Object.freeze({\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n });\n}\n\n/**\n * A scrollable virtual canvas component.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-virtual-canvas rc-virtual-canvas docs}\n *\n * @slot - The HTMLCanvasElement\n * @slot overlay - Optional viewport-positioned content rendered inside the\n * scroll container above the canvas.\n *\n * @fires rc-virtual-canvas-render - Fires with viewport data when the canvas should redraw.\n * @fires rc-virtual-canvas-pointer - Fires pointer/mouse input mapped to virtual content coordinates.\n *\n * @csspart scroller - Internal scroll container that owns the virtual content scroll range.\n * @csspart overlay - Viewport-positioned overlay container rendered inside the scroll container.\n *\n * @attr content-width - Total pixel width of the virtual content.\n * @attr content-height - Total pixel height of the virtual content.\n * @attr auto-resize-canvas - Keep the slotted canvas backing store aligned to the viewport.\n * @attr render-mode - Controls when render events are dispatched.\n * @attr image-rendering - Convenience `image-rendering` value applied to the slotted canvas.\n *\n * @cssprop [--rc-virtual-canvas-scrollbar-width=thin] - `scrollbar-width` of the internal\n * scroll container.\n * @cssprop [--rc-virtual-canvas-scrollbar-size=auto] - WebKit scrollbar thickness.\n * @cssprop [--rc-virtual-canvas-scrollbar-thumb-background=ButtonFace] - WebKit scrollbar\n * thumb color.\n * @cssprop [--rc-virtual-canvas-scrollbar-button-background=ButtonFace] - WebKit scrollbar\n * button color.\n * @cssprop [--rc-virtual-canvas-scrollbar-track-background=Canvas] - WebKit scrollbar\n * track color.\n * @cssprop [--rc-virtual-canvas-image-rendering=auto] - `image-rendering` applied to the\n * slotted canvas; kept in sync with the `imageRendering` property.\n */\nexport class RCVirtualCanvas extends LitElement {\n static styles = [virtualCanvasStyles];\n\n protected _rafHandle: number = 0;\n protected _pendingRenderReason?: RCVirtualCanvasRenderReason;\n protected readonly _handledPointerEvents = new WeakSet<Event>();\n\n // Stored bound reference so the same closure is used for scheduling and\n // cancellation — `bind()` returns a new function every call.\n protected readonly _boundUpdate = (time: DOMHighResTimeStamp) => this._update(time);\n\n protected readonly _boundPointerEvent = (event: PointerEvent | MouseEvent) =>\n this._onPointerEvent(event);\n\n /** Pixel width of the virtual content */\n @property({ type: Number, attribute: 'content-width' })\n set contentWidth(val: number) {\n const oldValue = this._contentWidth;\n\n this._contentWidth = val;\n\n this._contentRect.width = this._contentWidth;\n this.requestUpdate('contentWidth', oldValue);\n this._scheduleRender('viewport-change');\n }\n get contentWidth() {\n return this._contentWidth;\n }\n private _contentWidth: number = 0;\n\n /** Pixel height of the virtual content */\n @property({ type: Number, attribute: 'content-height' })\n set contentHeight(val: number) {\n const oldValue = this._contentHeight;\n\n this._contentHeight = val;\n\n this._contentRect.height = this._contentHeight;\n this.requestUpdate('contentHeight', oldValue);\n this._scheduleRender('viewport-change');\n }\n get contentHeight() {\n return this._contentHeight;\n }\n private _contentHeight: number = 0;\n\n /** When true, keep the slotted canvas backing store aligned to the viewport. */\n @property({ attribute: 'auto-resize-canvas', type: Boolean })\n autoResizeCanvas: boolean = true;\n\n /** Controls when render events are dispatched. */\n @property({ attribute: 'render-mode' })\n renderMode: RCVirtualCanvasRenderMode = 'continuous';\n\n /** Convenience image-rendering value applied to the slotted canvas. */\n @property({ attribute: 'image-rendering' })\n imageRendering: RCVirtualCanvasImageRendering = 'auto';\n\n /** Shadow DOM scroll container that owns pointer interaction and native scrolling */\n @query('#root', true)\n protected _$root!: HTMLDivElement;\n\n /** Absolutely-positioned div that establishes the virtual scroll range */\n @query('#placeholder', true)\n protected _$placeholder!: HTMLDivElement;\n\n /** Currently-tracked slotted canvas element; `null` when no canvas is slotted */\n @state()\n protected _$canvas: HTMLCanvasElement | null = null;\n\n /** Mutable current-frame viewport geometry; call `getViewRect()` for a frozen snapshot */\n @state()\n protected _viewRect = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n };\n\n /** Mutable content bounds; updated when `contentWidth` or `contentHeight` change */\n @state()\n protected _contentRect = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n };\n\n /** Watches the slotted canvas for DPR-accurate dimension changes */\n protected _resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => {\n for (const entry of entries) {\n const devicePixelBoxSize = Array.isArray(entry.devicePixelContentBoxSize)\n ? entry.devicePixelContentBoxSize[0]\n : entry.devicePixelContentBoxSize;\n\n this._viewRect.width = this._getMeasuredCanvasWidth(\n devicePixelBoxSize?.inlineSize ??\n Math.round(entry.contentRect.width * window.devicePixelRatio),\n );\n\n this._viewRect.height = this._getMeasuredCanvasHeight(\n devicePixelBoxSize?.blockSize ??\n Math.round(entry.contentRect.height * window.devicePixelRatio),\n );\n\n this._syncCanvasBackingStore();\n this._scheduleRender('viewport-change');\n }\n });\n\n /** Reads scroll position from the root container and schedules a render */\n protected _onScroll() {\n this._viewRect.x = this._$root.scrollLeft;\n this._viewRect.y = this._$root.scrollTop;\n\n this._scheduleRender('viewport-change');\n }\n\n /** Replaces canvas tracking and re-registers the resize observer when slot content changes */\n protected _onSlotChange(e: Event) {\n this._resizeObserver.disconnect();\n\n this._$canvas =\n (e.currentTarget as HTMLSlotElement)\n .assignedElements()\n .filter((el) => el instanceof HTMLCanvasElement)\n [0] ?? null;\n\n if (this._$canvas != null) {\n this._viewRect = {\n x: this._$root.scrollLeft ?? 0,\n y: this._$root.scrollTop ?? 0,\n width: this._getMeasuredCanvasWidth(this._$canvas.clientWidth),\n height: this._getMeasuredCanvasHeight(this._$canvas.clientHeight),\n };\n\n this._syncCanvasBackingStore();\n this._observeCanvasResize(this._$canvas);\n\n this._scheduleRender('viewport-change');\n }\n }\n\n /** Observes canvas size with DPR-accurate boxes when the browser supports them */\n protected _observeCanvasResize($canvas: HTMLCanvasElement) {\n try {\n this._resizeObserver.observe($canvas, {\n box: 'device-pixel-content-box',\n });\n } catch (error) {\n if (!(error instanceof TypeError)) {\n throw error;\n }\n\n this._resizeObserver.observe($canvas);\n }\n }\n\n /**\n * Returns a frozen snapshot of the current viewport rectangle.\n *\n * Safe to keep between frames — the returned object will not be mutated\n * by future scroll or resize work.\n */\n getViewRect() {\n return createRectSnapshot(this._viewRect);\n }\n\n /**\n * Scrolls so the content coordinate is at the viewport origin.\n *\n * @param x - Content x coordinate in CSS pixels\n * @param y - Content y coordinate in CSS pixels\n * @param options - Native scroll options passed to scrollTo\n */\n scrollToContent(x: number, y: number, options: ScrollOptions = {}) {\n this._$root.scrollTo({\n ...options,\n left: x,\n top: y,\n });\n\n this._viewRect.x = this._$root.scrollLeft;\n this._viewRect.y = this._$root.scrollTop;\n this._scheduleRender('viewport-change');\n }\n\n /**\n * Scrolls so the content coordinate is centered in the viewport.\n *\n * @param x - Content x coordinate in CSS pixels\n * @param y - Content y coordinate in CSS pixels\n * @param options - Native scroll options passed to scrollTo\n */\n centerOnContent(x: number, y: number, options: ScrollOptions = {}) {\n this.scrollToContent(\n x - this._$root.clientWidth * 0.5,\n y - this._$root.clientHeight * 0.5,\n options,\n );\n }\n\n /**\n * Converts browser client coordinates to content coordinates using the current\n * backing-store scale.\n *\n * @param clientX - Browser client x coordinate (e.g. from a pointer event)\n * @param clientY - Browser client y coordinate\n *\n * @example\n * vc.addEventListener('pointerdown', (e) => {\n * const { x, y } = vc.clientToContent(e.clientX, e.clientY);\n * placeMarkerAt(x, y);\n * });\n */\n clientToContent(clientX: number, clientY: number) {\n const canvasRect = this._getCanvasClientRect();\n const scaleX = this._getViewportScaleX(canvasRect);\n const scaleY = this._getViewportScaleY(canvasRect);\n\n return Object.freeze({\n x: this._viewRect.x + (clientX - canvasRect.left) * scaleX,\n y: this._viewRect.y + (clientY - canvasRect.top) * scaleY,\n });\n }\n\n /**\n * Converts content coordinates back to browser client coordinates.\n *\n * @param x - Content x coordinate in CSS pixels\n * @param y - Content y coordinate in CSS pixels\n *\n * @example\n * const { x, y } = vc.contentToClient(contentX, contentY);\n * tooltip.style.left = `${x}px`;\n * tooltip.style.top = `${y}px`;\n */\n contentToClient(x: number, y: number) {\n const canvasRect = this._getCanvasClientRect();\n const scaleX = this._getViewportScaleX(canvasRect);\n const scaleY = this._getViewportScaleY(canvasRect);\n\n return Object.freeze({\n x: canvasRect.left + (x - this._viewRect.x) / scaleX,\n y: canvasRect.top + (y - this._viewRect.y) / scaleY,\n });\n }\n\n /**\n * Queues a render event on the next animation frame.\n *\n * Required when `renderMode` is `'manual'`. In other modes the component\n * schedules renders automatically; calling this with reason `'animation-frame'`\n * is a no-op when `renderMode` is `'viewport-change'`.\n *\n * @param reason - Render reason reported in the event detail\n */\n requestRender(reason: RCVirtualCanvasRenderReason = 'manual') {\n this._scheduleRender(reason);\n }\n\n /**\n * Ratio of canvas backing-store pixels to CSS pixels along the x-axis.\n *\n * Equals `devicePixelRatio` when `autoResizeCanvas` is `true`. Use as the x-scale\n * factor in `ctx.scale()` to draw at CSS pixel resolution.\n *\n * @example\n * vc.addEventListener('rc-virtual-canvas-render', ({ detail: { viewRect } }) => {\n * ctx.save();\n * ctx.scale(vc.canvasScaleX, vc.canvasScaleY);\n * drawScene(ctx, viewRect);\n * ctx.restore();\n * });\n */\n get canvasScaleX(): number {\n const canvasRect = this._getCanvasClientRect();\n\n return this._getViewportScaleX(canvasRect);\n }\n\n /**\n * Ratio of canvas backing-store pixels to CSS pixels along the y-axis.\n *\n * Equals `devicePixelRatio` when `autoResizeCanvas` is `true`. Use as the y-scale\n * factor in `ctx.scale()` to draw at CSS pixel resolution.\n */\n get canvasScaleY(): number {\n const canvasRect = this._getCanvasClientRect();\n\n return this._getViewportScaleY(canvasRect);\n }\n\n /** Maps pointer and mouse events to content coordinates and dispatches `rc-virtual-canvas-pointer` */\n protected _onPointerEvent(event: PointerEvent | MouseEvent) {\n if (this._handledPointerEvents.has(event)) {\n return;\n }\n\n if (this._isOverlayEvent(event)) {\n return;\n }\n\n this._handledPointerEvents.add(event);\n\n const contentPoint = this.clientToContent(event.clientX, event.clientY);\n\n const shouldContinue = this.dispatchEvent(\n new CustomEvent<RCVirtualCanvasPointerInit>('rc-virtual-canvas-pointer', {\n bubbles: true,\n composed: true,\n cancelable: true,\n detail: {\n type: event.type,\n clientX: event.clientX,\n clientY: event.clientY,\n contentX: contentPoint.x,\n contentY: contentPoint.y,\n viewRect: createRectSnapshot(this._viewRect),\n button: event.button,\n buttons: event.buttons,\n altKey: event.altKey,\n ctrlKey: event.ctrlKey,\n shiftKey: event.shiftKey,\n metaKey: event.metaKey,\n sourceEvent: event,\n },\n }),\n );\n\n if (!shouldContinue) event.preventDefault();\n }\n\n protected _isOverlayEvent(event: Event): boolean {\n return event\n .composedPath()\n .some(($node) => $node instanceof HTMLSlotElement && $node.name === 'overlay');\n }\n\n /**\n * RAF callback. Dispatches `rc-virtual-canvas-render` and re-schedules in continuous mode.\n *\n * @param time - High-resolution timestamp from `requestAnimationFrame`\n */\n protected _update(time: DOMHighResTimeStamp) {\n this._rafHandle = 0;\n\n if (!this.isConnected || this._$canvas == null) {\n return;\n }\n\n const reason =\n this._pendingRenderReason ??\n (this.renderMode === 'continuous' ? 'animation-frame' : 'manual');\n\n this._pendingRenderReason = undefined;\n\n this.dispatchEvent(\n new CustomEvent<RCVirtualCanvasRenderInit>('rc-virtual-canvas-render', {\n bubbles: true,\n composed: true,\n detail: {\n time,\n reason,\n viewRect: createRectSnapshot(this._viewRect),\n contentRect: createRectSnapshot(this._contentRect),\n },\n }),\n );\n\n if (this.renderMode === 'continuous') {\n this._scheduleRender('animation-frame');\n }\n }\n\n /** Registers pointer event listeners and starts rendering in continuous mode */\n override connectedCallback() {\n super.connectedCallback();\n\n this.addEventListener('pointerdown', this._boundPointerEvent);\n this.addEventListener('pointermove', this._boundPointerEvent);\n this.addEventListener('pointerup', this._boundPointerEvent);\n this.addEventListener('click', this._boundPointerEvent);\n this.addEventListener('dblclick', this._boundPointerEvent);\n this.addEventListener('contextmenu', this._boundPointerEvent);\n\n if (this._rafHandle) {\n cancelAnimationFrame(this._rafHandle);\n this._rafHandle = 0;\n }\n\n if (this.renderMode === 'continuous') {\n this._scheduleRender('animation-frame');\n }\n }\n\n /** Cancels any pending animation frame, disconnects the resize observer, and removes pointer listeners */\n override disconnectedCallback() {\n super.disconnectedCallback();\n\n cancelAnimationFrame(this._rafHandle);\n this._rafHandle = 0;\n this._resizeObserver.disconnect();\n\n this.removeEventListener('pointerdown', this._boundPointerEvent);\n this.removeEventListener('pointermove', this._boundPointerEvent);\n this.removeEventListener('pointerup', this._boundPointerEvent);\n this.removeEventListener('click', this._boundPointerEvent);\n this.removeEventListener('dblclick', this._boundPointerEvent);\n this.removeEventListener('contextmenu', this._boundPointerEvent);\n }\n\n /** Reacts to `renderMode`, `autoResizeCanvas`, and `imageRendering` property changes */\n protected override updated(changed: Map<string, unknown>) {\n if (changed.has('renderMode')) {\n if (this.renderMode === 'continuous') {\n this._scheduleRender('animation-frame');\n } else if (this._pendingRenderReason === 'animation-frame') {\n if (this._rafHandle) {\n cancelAnimationFrame(this._rafHandle);\n\n this._rafHandle = 0;\n }\n\n this._pendingRenderReason = undefined;\n } else if (this.renderMode === 'viewport-change') {\n this._scheduleRender('viewport-change');\n }\n }\n\n if (changed.has('autoResizeCanvas')) {\n this._syncCanvasBackingStore();\n }\n\n if (changed.has('imageRendering')) {\n this.style.setProperty('--rc-virtual-canvas-image-rendering', this.imageRendering);\n }\n }\n\n protected _scheduleRender(reason: RCVirtualCanvasRenderReason) {\n if (this.renderMode === 'manual' && reason !== 'manual') {\n return;\n }\n\n if (this.renderMode === 'viewport-change' && reason === 'animation-frame') {\n return;\n }\n\n this._pendingRenderReason = reason;\n\n if (!this.isConnected || this._rafHandle) {\n return;\n }\n\n this._rafHandle = window.requestAnimationFrame(this._boundUpdate);\n }\n\n protected _syncCanvasBackingStore() {\n if (!this.autoResizeCanvas || this._$canvas == null) {\n return;\n }\n\n const width = Math.max(0, Math.round(this._viewRect.width));\n const height = Math.max(0, Math.round(this._viewRect.height));\n\n if (this._$canvas.width !== width) {\n this._$canvas.width = width;\n }\n\n if (this._$canvas.height !== height) {\n this._$canvas.height = height;\n }\n }\n\n protected _getCanvasClientRect() {\n if (this._$canvas == null) {\n return this.getBoundingClientRect();\n }\n\n return this._$canvas.getBoundingClientRect();\n }\n\n protected _getMeasuredCanvasWidth(fallbackWidth: number) {\n if (!this.autoResizeCanvas && this._$canvas && this._$canvas.width > 0) {\n return this._$canvas.width;\n }\n\n return fallbackWidth;\n }\n\n protected _getMeasuredCanvasHeight(fallbackHeight: number) {\n if (!this.autoResizeCanvas && this._$canvas && this._$canvas.height > 0) {\n return this._$canvas.height;\n }\n\n return fallbackHeight;\n }\n\n protected _getViewportScaleX(canvasRect: DOMRect) {\n return canvasRect.width > 0 ? this._viewRect.width / canvasRect.width : 1;\n }\n\n protected _getViewportScaleY(canvasRect: DOMRect) {\n return canvasRect.height > 0 ? this._viewRect.height / canvasRect.height : 1;\n }\n\n render() {\n return html`\n <div\n id=\"root\"\n part=\"scroller\"\n @scroll=${this._onScroll}\n @pointerdown=${this._onPointerEvent}\n @pointermove=${this._onPointerEvent}\n @pointerup=${this._onPointerEvent}\n @click=${this._onPointerEvent}\n @dblclick=${this._onPointerEvent}\n @contextmenu=${this._onPointerEvent}\n >\n <div id=\"overlay\" part=\"overlay\">\n <slot name=\"overlay\"></slot>\n </div>\n\n <div\n id=\"placeholder\"\n style=${styleMap({\n width: `${this.contentWidth}px`,\n height: `${this.contentHeight}px`,\n })}\n ></div>\n </div>\n\n <slot @slotchange=${this._onSlotChange}></slot>\n `;\n }\n}\n\nexport default RCVirtualCanvas;\n"],"names":["virtualCanvasStyles","css","createRectSnapshot","rect","_RCVirtualCanvas","LitElement","time","event","entries","entry","devicePixelBoxSize","val","oldValue","e","el","$canvas","error","x","y","options","clientX","clientY","canvasRect","scaleX","scaleY","reason","contentPoint","$node","changed","width","height","fallbackWidth","fallbackHeight","html","styleMap","RCVirtualCanvas","__decorateClass","property","query","state"],"mappings":";;;AAEO,MAAMA,IAAsBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACmHnC,SAASC,EAAmBC,GAA+B;AACzD,SAAO,OAAO,OAAO;AAAA,IACnB,GAAGA,EAAK;AAAA,IACR,GAAGA,EAAK;AAAA,IACR,OAAOA,EAAK;AAAA,IACZ,QAAQA,EAAK;AAAA,EAAA,CACd;AACH;AAmCO,MAAMC,IAAN,MAAMA,UAAwBC,EAAW;AAAA,EAAzC,cAAA;AAAA,UAAA,GAAA,SAAA,GAGL,KAAU,aAAqB,GAE/B,KAAmB,4CAA4B,QAAA,GAI/C,KAAmB,eAAe,CAACC,MAA8B,KAAK,QAAQA,CAAI,GAElF,KAAmB,qBAAqB,CAACC,MACvC,KAAK,gBAAgBA,CAAK,GAgB5B,KAAQ,gBAAwB,GAgBhC,KAAQ,iBAAyB,GAIjC,KAAA,mBAA4B,IAI5B,KAAA,aAAwC,cAIxC,KAAA,iBAAgD,QAYhD,KAAU,WAAqC,MAI/C,KAAU,YAAY;AAAA,MACpB,GAAG;AAAA,MACH,GAAG;AAAA,MACH,OAAO;AAAA,MACP,QAAQ;AAAA,IAAA,GAKV,KAAU,eAAe;AAAA,MACvB,GAAG;AAAA,MACH,GAAG;AAAA,MACH,OAAO;AAAA,MACP,QAAQ;AAAA,IAAA,GAIV,KAAU,kBAAkB,IAAI,eAAe,CAACC,MAAmC;AACjF,iBAAWC,KAASD,GAAS;AAC3B,cAAME,IAAqB,MAAM,QAAQD,EAAM,yBAAyB,IACpEA,EAAM,0BAA0B,CAAC,IACjCA,EAAM;AAEV,aAAK,UAAU,QAAQ,KAAK;AAAA,UAC1BC,GAAoB,cAClB,KAAK,MAAMD,EAAM,YAAY,QAAQ,OAAO,gBAAgB;AAAA,QAAA,GAGhE,KAAK,UAAU,SAAS,KAAK;AAAA,UAC3BC,GAAoB,aAClB,KAAK,MAAMD,EAAM,YAAY,SAAS,OAAO,gBAAgB;AAAA,QAAA,GAGjE,KAAK,wBAAA,GACL,KAAK,gBAAgB,iBAAiB;AAAA,MACxC;AAAA,IACF,CAAC;AAAA,EAAA;AAAA,EA5FD,IAAI,aAAaE,GAAa;AAC5B,UAAMC,IAAW,KAAK;AAEtB,SAAK,gBAAgBD,GAErB,KAAK,aAAa,QAAQ,KAAK,eAC/B,KAAK,cAAc,gBAAgBC,CAAQ,GAC3C,KAAK,gBAAgB,iBAAiB;AAAA,EACxC;AAAA,EACA,IAAI,eAAe;AACjB,WAAO,KAAK;AAAA,EACd;AAAA,EAKA,IAAI,cAAcD,GAAa;AAC7B,UAAMC,IAAW,KAAK;AAEtB,SAAK,iBAAiBD,GAEtB,KAAK,aAAa,SAAS,KAAK,gBAChC,KAAK,cAAc,iBAAiBC,CAAQ,GAC5C,KAAK,gBAAgB,iBAAiB;AAAA,EACxC;AAAA,EACA,IAAI,gBAAgB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAoEU,YAAY;AACpB,SAAK,UAAU,IAAI,KAAK,OAAO,YAC/B,KAAK,UAAU,IAAI,KAAK,OAAO,WAE/B,KAAK,gBAAgB,iBAAiB;AAAA,EACxC;AAAA;AAAA,EAGU,cAAcC,GAAU;AAChC,SAAK,gBAAgB,WAAA,GAErB,KAAK,WACFA,EAAE,cACA,iBAAA,EACA,OAAO,CAACC,MAAOA,aAAc,iBAAiB,EAC9C,CAAC,KAAK,MAEP,KAAK,YAAY,SACnB,KAAK,YAAY;AAAA,MACf,GAAG,KAAK,OAAO,cAAc;AAAA,MAC7B,GAAG,KAAK,OAAO,aAAa;AAAA,MAC5B,OAAO,KAAK,wBAAwB,KAAK,SAAS,WAAW;AAAA,MAC7D,QAAQ,KAAK,yBAAyB,KAAK,SAAS,YAAY;AAAA,IAAA,GAGlE,KAAK,wBAAA,GACL,KAAK,qBAAqB,KAAK,QAAQ,GAEvC,KAAK,gBAAgB,iBAAiB;AAAA,EAE1C;AAAA;AAAA,EAGU,qBAAqBC,GAA4B;AACzD,QAAI;AACF,WAAK,gBAAgB,QAAQA,GAAS;AAAA,QACpC,KAAK;AAAA,MAAA,CACN;AAAA,IACH,SAASC,GAAO;AACd,UAAI,EAAEA,aAAiB;AACrB,cAAMA;AAGR,WAAK,gBAAgB,QAAQD,CAAO;AAAA,IACtC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,cAAc;AACZ,WAAOb,EAAmB,KAAK,SAAS;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,gBAAgBe,GAAWC,GAAWC,IAAyB,CAAA,GAAI;AACjE,SAAK,OAAO,SAAS;AAAA,MACnB,GAAGA;AAAA,MACH,MAAMF;AAAA,MACN,KAAKC;AAAA,IAAA,CACN,GAED,KAAK,UAAU,IAAI,KAAK,OAAO,YAC/B,KAAK,UAAU,IAAI,KAAK,OAAO,WAC/B,KAAK,gBAAgB,iBAAiB;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,gBAAgBD,GAAWC,GAAWC,IAAyB,CAAA,GAAI;AACjE,SAAK;AAAA,MACHF,IAAI,KAAK,OAAO,cAAc;AAAA,MAC9BC,IAAI,KAAK,OAAO,eAAe;AAAA,MAC/BC;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,gBAAgBC,GAAiBC,GAAiB;AAChD,UAAMC,IAAa,KAAK,qBAAA,GAClBC,IAAS,KAAK,mBAAmBD,CAAU,GAC3CE,IAAS,KAAK,mBAAmBF,CAAU;AAEjD,WAAO,OAAO,OAAO;AAAA,MACnB,GAAG,KAAK,UAAU,KAAKF,IAAUE,EAAW,QAAQC;AAAA,MACpD,GAAG,KAAK,UAAU,KAAKF,IAAUC,EAAW,OAAOE;AAAA,IAAA,CACpD;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,gBAAgBP,GAAWC,GAAW;AACpC,UAAMI,IAAa,KAAK,qBAAA,GAClBC,IAAS,KAAK,mBAAmBD,CAAU,GAC3CE,IAAS,KAAK,mBAAmBF,CAAU;AAEjD,WAAO,OAAO,OAAO;AAAA,MACnB,GAAGA,EAAW,QAAQL,IAAI,KAAK,UAAU,KAAKM;AAAA,MAC9C,GAAGD,EAAW,OAAOJ,IAAI,KAAK,UAAU,KAAKM;AAAA,IAAA,CAC9C;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,cAAcC,IAAsC,UAAU;AAC5D,SAAK,gBAAgBA,CAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,IAAI,eAAuB;AACzB,UAAMH,IAAa,KAAK,qBAAA;AAExB,WAAO,KAAK,mBAAmBA,CAAU;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,eAAuB;AACzB,UAAMA,IAAa,KAAK,qBAAA;AAExB,WAAO,KAAK,mBAAmBA,CAAU;AAAA,EAC3C;AAAA;AAAA,EAGU,gBAAgBf,GAAkC;AAK1D,QAJI,KAAK,sBAAsB,IAAIA,CAAK,KAIpC,KAAK,gBAAgBA,CAAK;AAC5B;AAGF,SAAK,sBAAsB,IAAIA,CAAK;AAEpC,UAAMmB,IAAe,KAAK,gBAAgBnB,EAAM,SAASA,EAAM,OAAO;AAyBtE,IAvBuB,KAAK;AAAA,MAC1B,IAAI,YAAwC,6BAA6B;AAAA,QACvE,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,QAAQ;AAAA,UACN,MAAMA,EAAM;AAAA,UACZ,SAASA,EAAM;AAAA,UACf,SAASA,EAAM;AAAA,UACf,UAAUmB,EAAa;AAAA,UACvB,UAAUA,EAAa;AAAA,UACvB,UAAUxB,EAAmB,KAAK,SAAS;AAAA,UAC3C,QAAQK,EAAM;AAAA,UACd,SAASA,EAAM;AAAA,UACf,QAAQA,EAAM;AAAA,UACd,SAASA,EAAM;AAAA,UACf,UAAUA,EAAM;AAAA,UAChB,SAASA,EAAM;AAAA,UACf,aAAaA;AAAA,QAAA;AAAA,MACf,CACD;AAAA,IAAA,KAGkBA,EAAM,eAAA;AAAA,EAC7B;AAAA,EAEU,gBAAgBA,GAAuB;AAC/C,WAAOA,EACJ,eACA,KAAK,CAACoB,MAAUA,aAAiB,mBAAmBA,EAAM,SAAS,SAAS;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOU,QAAQrB,GAA2B;AAG3C,QAFA,KAAK,aAAa,GAEd,CAAC,KAAK,eAAe,KAAK,YAAY;AACxC;AAGF,UAAMmB,IACJ,KAAK,yBACJ,KAAK,eAAe,eAAe,oBAAoB;AAE1D,SAAK,uBAAuB,QAE5B,KAAK;AAAA,MACH,IAAI,YAAuC,4BAA4B;AAAA,QACrE,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,UACN,MAAAnB;AAAA,UACA,QAAAmB;AAAA,UACA,UAAUvB,EAAmB,KAAK,SAAS;AAAA,UAC3C,aAAaA,EAAmB,KAAK,YAAY;AAAA,QAAA;AAAA,MACnD,CACD;AAAA,IAAA,GAGC,KAAK,eAAe,gBACtB,KAAK,gBAAgB,iBAAiB;AAAA,EAE1C;AAAA;AAAA,EAGS,oBAAoB;AAC3B,UAAM,kBAAA,GAEN,KAAK,iBAAiB,eAAe,KAAK,kBAAkB,GAC5D,KAAK,iBAAiB,eAAe,KAAK,kBAAkB,GAC5D,KAAK,iBAAiB,aAAa,KAAK,kBAAkB,GAC1D,KAAK,iBAAiB,SAAS,KAAK,kBAAkB,GACtD,KAAK,iBAAiB,YAAY,KAAK,kBAAkB,GACzD,KAAK,iBAAiB,eAAe,KAAK,kBAAkB,GAExD,KAAK,eACP,qBAAqB,KAAK,UAAU,GACpC,KAAK,aAAa,IAGhB,KAAK,eAAe,gBACtB,KAAK,gBAAgB,iBAAiB;AAAA,EAE1C;AAAA;AAAA,EAGS,uBAAuB;AAC9B,UAAM,qBAAA,GAEN,qBAAqB,KAAK,UAAU,GACpC,KAAK,aAAa,GAClB,KAAK,gBAAgB,WAAA,GAErB,KAAK,oBAAoB,eAAe,KAAK,kBAAkB,GAC/D,KAAK,oBAAoB,eAAe,KAAK,kBAAkB,GAC/D,KAAK,oBAAoB,aAAa,KAAK,kBAAkB,GAC7D,KAAK,oBAAoB,SAAS,KAAK,kBAAkB,GACzD,KAAK,oBAAoB,YAAY,KAAK,kBAAkB,GAC5D,KAAK,oBAAoB,eAAe,KAAK,kBAAkB;AAAA,EACjE;AAAA;AAAA,EAGmB,QAAQ0B,GAA+B;AACxD,IAAIA,EAAQ,IAAI,YAAY,MACtB,KAAK,eAAe,eACtB,KAAK,gBAAgB,iBAAiB,IAC7B,KAAK,yBAAyB,qBACnC,KAAK,eACP,qBAAqB,KAAK,UAAU,GAEpC,KAAK,aAAa,IAGpB,KAAK,uBAAuB,UACnB,KAAK,eAAe,qBAC7B,KAAK,gBAAgB,iBAAiB,IAItCA,EAAQ,IAAI,kBAAkB,KAChC,KAAK,wBAAA,GAGHA,EAAQ,IAAI,gBAAgB,KAC9B,KAAK,MAAM,YAAY,uCAAuC,KAAK,cAAc;AAAA,EAErF;AAAA,EAEU,gBAAgBH,GAAqC;AAC7D,IAAI,KAAK,eAAe,YAAYA,MAAW,YAI3C,KAAK,eAAe,qBAAqBA,MAAW,sBAIxD,KAAK,uBAAuBA,GAExB,GAAC,KAAK,eAAe,KAAK,gBAI9B,KAAK,aAAa,OAAO,sBAAsB,KAAK,YAAY;AAAA,EAClE;AAAA,EAEU,0BAA0B;AAClC,QAAI,CAAC,KAAK,oBAAoB,KAAK,YAAY;AAC7C;AAGF,UAAMI,IAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC,GACpDC,IAAS,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,UAAU,MAAM,CAAC;AAE5D,IAAI,KAAK,SAAS,UAAUD,MAC1B,KAAK,SAAS,QAAQA,IAGpB,KAAK,SAAS,WAAWC,MAC3B,KAAK,SAAS,SAASA;AAAA,EAE3B;AAAA,EAEU,uBAAuB;AAC/B,WAAI,KAAK,YAAY,OACZ,KAAK,sBAAA,IAGP,KAAK,SAAS,sBAAA;AAAA,EACvB;AAAA,EAEU,wBAAwBC,GAAuB;AACvD,WAAI,CAAC,KAAK,oBAAoB,KAAK,YAAY,KAAK,SAAS,QAAQ,IAC5D,KAAK,SAAS,QAGhBA;AAAA,EACT;AAAA,EAEU,yBAAyBC,GAAwB;AACzD,WAAI,CAAC,KAAK,oBAAoB,KAAK,YAAY,KAAK,SAAS,SAAS,IAC7D,KAAK,SAAS,SAGhBA;AAAA,EACT;AAAA,EAEU,mBAAmBV,GAAqB;AAChD,WAAOA,EAAW,QAAQ,IAAI,KAAK,UAAU,QAAQA,EAAW,QAAQ;AAAA,EAC1E;AAAA,EAEU,mBAAmBA,GAAqB;AAChD,WAAOA,EAAW,SAAS,IAAI,KAAK,UAAU,SAASA,EAAW,SAAS;AAAA,EAC7E;AAAA,EAEA,SAAS;AACP,WAAOW;AAAA;AAAA;AAAA;AAAA,kBAIO,KAAK,SAAS;AAAA,uBACT,KAAK,eAAe;AAAA,uBACpB,KAAK,eAAe;AAAA,qBACtB,KAAK,eAAe;AAAA,iBACxB,KAAK,eAAe;AAAA,oBACjB,KAAK,eAAe;AAAA,uBACjB,KAAK,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAQzBC,EAAS;AAAA,MACf,OAAO,GAAG,KAAK,YAAY;AAAA,MAC3B,QAAQ,GAAG,KAAK,aAAa;AAAA,IAAA,CAC9B,CAAC;AAAA;AAAA;AAAA;AAAA,0BAIc,KAAK,aAAa;AAAA;AAAA,EAE1C;AACF;AAthBE9B,EAAO,SAAS,CAACJ,CAAmB;AAD/B,IAAMmC,IAAN/B;AAgBDgC,EAAA;AAAA,EADHC,EAAS,EAAE,MAAM,QAAQ,WAAW,iBAAiB;AAAA,GAf3CF,EAgBP,WAAA,gBAAA,CAAA;AAgBAC,EAAA;AAAA,EADHC,EAAS,EAAE,MAAM,QAAQ,WAAW,kBAAkB;AAAA,GA/B5CF,EAgCP,WAAA,iBAAA,CAAA;AAgBJC,EAAA;AAAA,EADCC,EAAS,EAAE,WAAW,sBAAsB,MAAM,SAAS;AAAA,GA/CjDF,EAgDX,WAAA,oBAAA,CAAA;AAIAC,EAAA;AAAA,EADCC,EAAS,EAAE,WAAW,cAAA,CAAe;AAAA,GAnD3BF,EAoDX,WAAA,cAAA,CAAA;AAIAC,EAAA;AAAA,EADCC,EAAS,EAAE,WAAW,kBAAA,CAAmB;AAAA,GAvD/BF,EAwDX,WAAA,kBAAA,CAAA;AAIUC,EAAA;AAAA,EADTE,EAAM,SAAS,EAAI;AAAA,GA3DTH,EA4DD,WAAA,UAAA,CAAA;AAIAC,EAAA;AAAA,EADTE,EAAM,gBAAgB,EAAI;AAAA,GA/DhBH,EAgED,WAAA,iBAAA,CAAA;AAIAC,EAAA;AAAA,EADTG,EAAA;AAAM,GAnEIJ,EAoED,WAAA,YAAA,CAAA;AAIAC,EAAA;AAAA,EADTG,EAAA;AAAM,GAvEIJ,EAwED,WAAA,aAAA,CAAA;AASAC,EAAA;AAAA,EADTG,EAAA;AAAM,GAhFIJ,EAiFD,WAAA,gBAAA,CAAA;"}
File without changes