@oh-just-another/renderer-canvas 0.57.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 +18 -0
- package/LICENSE +21 -0
- package/README.md +36 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/canvas-target.d.ts +83 -0
- package/dist/canvas-target.d.ts.map +1 -0
- package/dist/canvas-target.js +208 -0
- package/dist/canvas-target.js.map +1 -0
- package/dist/canvas-text-shaper.d.ts +11 -0
- package/dist/canvas-text-shaper.d.ts.map +1 -0
- package/dist/canvas-text-shaper.js +56 -0
- package/dist/canvas-text-shaper.js.map +1 -0
- package/dist/constants.d.ts +52 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +52 -0
- package/dist/constants.js.map +1 -0
- package/dist/hi-dpi.d.ts +26 -0
- package/dist/hi-dpi.d.ts.map +1 -0
- package/dist/hi-dpi.js +62 -0
- package/dist/hi-dpi.js.map +1 -0
- package/dist/image-source.d.ts +3 -0
- package/dist/image-source.d.ts.map +1 -0
- package/dist/image-source.js +65 -0
- package/dist/image-source.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/layered-canvas.d.ts +46 -0
- package/dist/layered-canvas.d.ts.map +1 -0
- package/dist/layered-canvas.js +95 -0
- package/dist/layered-canvas.js.map +1 -0
- package/dist/layered-surface.d.ts +75 -0
- package/dist/layered-surface.d.ts.map +1 -0
- package/dist/layered-surface.js +262 -0
- package/dist/layered-surface.js.map +1 -0
- package/dist/offscreen.d.ts +30 -0
- package/dist/offscreen.d.ts.map +1 -0
- package/dist/offscreen.js +50 -0
- package/dist/offscreen.js.map +1 -0
- package/dist/recording-target.d.ts +203 -0
- package/dist/recording-target.d.ts.map +1 -0
- package/dist/recording-target.js +260 -0
- package/dist/recording-target.js.map +1 -0
- package/dist/render-worker.d.ts +2 -0
- package/dist/render-worker.d.ts.map +1 -0
- package/dist/render-worker.js +112 -0
- package/dist/render-worker.js.map +1 -0
- package/dist/tile-compositor.d.ts +44 -0
- package/dist/tile-compositor.d.ts.map +1 -0
- package/dist/tile-compositor.js +110 -0
- package/dist/tile-compositor.js.map +1 -0
- package/dist/webgl2-color.d.ts +13 -0
- package/dist/webgl2-color.d.ts.map +1 -0
- package/dist/webgl2-color.js +26 -0
- package/dist/webgl2-color.js.map +1 -0
- package/dist/webgl2-curve.d.ts +46 -0
- package/dist/webgl2-curve.d.ts.map +1 -0
- package/dist/webgl2-curve.js +162 -0
- package/dist/webgl2-curve.js.map +1 -0
- package/dist/webgl2-ellipse.d.ts +52 -0
- package/dist/webgl2-ellipse.d.ts.map +1 -0
- package/dist/webgl2-ellipse.js +171 -0
- package/dist/webgl2-ellipse.js.map +1 -0
- package/dist/webgl2-msdf-text.d.ts +84 -0
- package/dist/webgl2-msdf-text.d.ts.map +1 -0
- package/dist/webgl2-msdf-text.js +306 -0
- package/dist/webgl2-msdf-text.js.map +1 -0
- package/dist/webgl2-stroke.d.ts +52 -0
- package/dist/webgl2-stroke.d.ts.map +1 -0
- package/dist/webgl2-stroke.js +318 -0
- package/dist/webgl2-stroke.js.map +1 -0
- package/dist/webgl2-target.d.ts +311 -0
- package/dist/webgl2-target.d.ts.map +1 -0
- package/dist/webgl2-target.js +1368 -0
- package/dist/webgl2-target.js.map +1 -0
- package/dist/webgpu-detect.d.ts +30 -0
- package/dist/webgpu-detect.d.ts.map +1 -0
- package/dist/webgpu-detect.js +74 -0
- package/dist/webgpu-detect.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maximum miter overshoot, in units of stroke width. Past this the
|
|
3
|
+
* miter falls back to a bevel — matches Canvas2D's `miterLimit` default
|
|
4
|
+
* of 10 and SVG's spec default.
|
|
5
|
+
*/
|
|
6
|
+
const MITER_LIMIT = 10;
|
|
7
|
+
/** Round-join / round-cap fan segments per pi radians. 12 keeps each
|
|
8
|
+
* segment ≈ 15°, smooth at any sensible zoom. */
|
|
9
|
+
const ROUND_SEGMENTS_PER_PI = 12;
|
|
10
|
+
/** Asserts a polyline index is in range (loop bounds guarantee it). */
|
|
11
|
+
const req = (v) => {
|
|
12
|
+
if (v === undefined)
|
|
13
|
+
throw new Error("packages/renderer-canvas: polyline index out of range");
|
|
14
|
+
return v;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Module-level scratch buffers — reused across every
|
|
18
|
+
* `drawPolylineStroke` invocation so the hot path allocates zero
|
|
19
|
+
* `Float32Array`s per frame after warmup.
|
|
20
|
+
*
|
|
21
|
+
* Safe because WebGL is single-threaded and `drawPolylineStroke` is
|
|
22
|
+
* called serially from `WebGL2Target.stroke()`; multiple canvases on
|
|
23
|
+
* the same page share these buffers, which is fine.
|
|
24
|
+
*
|
|
25
|
+
* Initial caps cover a typical small stroke (≤32 segments) without a
|
|
26
|
+
* grow. `ensureNCapacity` / `ensureTrisCapacity` upsize to the next
|
|
27
|
+
* power of 2 on demand; capacity only ratchets up.
|
|
28
|
+
*/
|
|
29
|
+
let scratchNx = new Float32Array(64);
|
|
30
|
+
let scratchNy = new Float32Array(64);
|
|
31
|
+
let scratchTris = new Float32Array(1024);
|
|
32
|
+
let scratchTrisLen = 0;
|
|
33
|
+
const ensureNCapacity = (n) => {
|
|
34
|
+
if (scratchNx.length >= n)
|
|
35
|
+
return;
|
|
36
|
+
let cap = scratchNx.length;
|
|
37
|
+
while (cap < n)
|
|
38
|
+
cap *= 2;
|
|
39
|
+
scratchNx = new Float32Array(cap);
|
|
40
|
+
scratchNy = new Float32Array(cap);
|
|
41
|
+
};
|
|
42
|
+
const ensureTrisCapacity = (n) => {
|
|
43
|
+
if (scratchTris.length >= n)
|
|
44
|
+
return;
|
|
45
|
+
let cap = scratchTris.length;
|
|
46
|
+
while (cap < n)
|
|
47
|
+
cap *= 2;
|
|
48
|
+
const next = new Float32Array(cap);
|
|
49
|
+
// Carry over any values already pushed before the grow.
|
|
50
|
+
next.set(scratchTris.subarray(0, scratchTrisLen));
|
|
51
|
+
scratchTris = next;
|
|
52
|
+
};
|
|
53
|
+
const trisPush = (x, y) => {
|
|
54
|
+
if (scratchTrisLen + 2 > scratchTris.length) {
|
|
55
|
+
ensureTrisCapacity(scratchTrisLen + 2);
|
|
56
|
+
}
|
|
57
|
+
scratchTris[scratchTrisLen++] = x;
|
|
58
|
+
scratchTris[scratchTrisLen++] = y;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Compute one miter offset at the hinge between two unit normals.
|
|
62
|
+
* Returns `{ ox, oy }` along the bisector, clamped to MITER_LIMIT.
|
|
63
|
+
* Exported so `webgl2-target.ts` can reuse it for closed-polyline seam
|
|
64
|
+
* vertices.
|
|
65
|
+
*/
|
|
66
|
+
export const miterOffset = (n1x, n1y, n2x, n2y, half) => {
|
|
67
|
+
let bx = n1x + n2x;
|
|
68
|
+
let by = n1y + n2y;
|
|
69
|
+
const blen = Math.hypot(bx, by);
|
|
70
|
+
if (blen < 1e-6) {
|
|
71
|
+
return { ox: n1x * half, oy: n1y * half };
|
|
72
|
+
}
|
|
73
|
+
bx /= blen;
|
|
74
|
+
by /= blen;
|
|
75
|
+
const cos = bx * n1x + by * n1y;
|
|
76
|
+
const miterLen = cos > 1e-6 ? half / cos : half;
|
|
77
|
+
const clamped = Math.min(miterLen, half * MITER_LIMIT);
|
|
78
|
+
return { ox: bx * clamped, oy: by * clamped };
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Build the stroke geometry for a polyline + style, upload to the
|
|
82
|
+
* caller's dynamic VBO, and draw. Identity uTransform — vertices are
|
|
83
|
+
* pre-projected into clip space here.
|
|
84
|
+
*
|
|
85
|
+
* The caller passes its solid program + cached `aPos` attribute
|
|
86
|
+
* location + its dynamic VBO. This function binds & sets up the
|
|
87
|
+
* attribute itself so it's self-contained — no implicit dependency on
|
|
88
|
+
* the previous draw's GL state.
|
|
89
|
+
*/
|
|
90
|
+
export const drawPolylineStroke = (gl, polyline, style, transform, size, program, uTransformLoc, uColorLoc, uOpacityLoc, dynamicVbo, aPosLoc, identityMat3) => {
|
|
91
|
+
if (style.width <= 0 || polyline.length < 2)
|
|
92
|
+
return;
|
|
93
|
+
const half = style.width / 2;
|
|
94
|
+
const segCount = polyline.length - 1;
|
|
95
|
+
// Reuse the module-level scratch nx/ny buffers — grow on demand.
|
|
96
|
+
ensureNCapacity(segCount);
|
|
97
|
+
const nx = scratchNx;
|
|
98
|
+
const ny = scratchNy;
|
|
99
|
+
for (let i = 0; i < segCount; i++) {
|
|
100
|
+
const a = req(polyline[i]);
|
|
101
|
+
const b = req(polyline[i + 1]);
|
|
102
|
+
const dx = b.x - a.x;
|
|
103
|
+
const dy = b.y - a.y;
|
|
104
|
+
const len = Math.hypot(dx, dy) || 1;
|
|
105
|
+
nx[i] = -dy / len;
|
|
106
|
+
ny[i] = dx / len;
|
|
107
|
+
}
|
|
108
|
+
const first = req(polyline[0]);
|
|
109
|
+
const last = req(polyline[polyline.length - 1]);
|
|
110
|
+
const closed = polyline.length >= 3 && first.x === last.x && first.y === last.y;
|
|
111
|
+
// Reset the scratch vertex stream length — world-space (x, y) pairs
|
|
112
|
+
// are pushed into `scratchTris` via `trisPush`, then projected
|
|
113
|
+
// in-place to clip space before the bufferData call.
|
|
114
|
+
scratchTrisLen = 0;
|
|
115
|
+
const push = trisPush;
|
|
116
|
+
// Render the segment band between vertex i and i+1 as two triangles.
|
|
117
|
+
// Both endpoints use the same side-offset; join geometry stitches the
|
|
118
|
+
// next segment on.
|
|
119
|
+
const band = (ax, ay, anx, any, bx, by, bnx, bny) => {
|
|
120
|
+
// Vertices:
|
|
121
|
+
// A_left = (ax + anx, ay + any)
|
|
122
|
+
// A_right = (ax - anx, ay - any)
|
|
123
|
+
// B_left = (bx + bnx, by + bny)
|
|
124
|
+
// B_right = (bx - bnx, by - bny)
|
|
125
|
+
push(ax + anx, ay + any);
|
|
126
|
+
push(ax - anx, ay - any);
|
|
127
|
+
push(bx + bnx, by + bny);
|
|
128
|
+
push(bx + bnx, by + bny);
|
|
129
|
+
push(ax - anx, ay - any);
|
|
130
|
+
push(bx - bnx, by - bny);
|
|
131
|
+
};
|
|
132
|
+
// Per-segment side offsets (the polyline endpoint offset, no
|
|
133
|
+
// bisector — joins add their own geometry between adjacent bands).
|
|
134
|
+
const segLeft = (i) => ({ ox: req(nx[i]) * half, oy: req(ny[i]) * half });
|
|
135
|
+
// Emit the rect bands for every segment.
|
|
136
|
+
for (let i = 0; i < segCount; i++) {
|
|
137
|
+
const a = req(polyline[i]);
|
|
138
|
+
const b = req(polyline[i + 1]);
|
|
139
|
+
const o = segLeft(i);
|
|
140
|
+
band(a.x, a.y, o.ox, o.oy, b.x, b.y, o.ox, o.oy);
|
|
141
|
+
}
|
|
142
|
+
// Emit join geometry at every interior vertex (and at the seam for
|
|
143
|
+
// closed polylines).
|
|
144
|
+
const emitJoin = (vertexX, vertexY, n1x, n1y, n2x, n2y) => {
|
|
145
|
+
if (style.join === "miter") {
|
|
146
|
+
const { ox, oy } = miterOffset(n1x, n1y, n2x, n2y, half);
|
|
147
|
+
// Outside-of-bend wedge: tip = vertex + offset on outer side.
|
|
148
|
+
// Outer side comes from the cross-product sign.
|
|
149
|
+
const cross = n1x * n2y - n1y * n2x;
|
|
150
|
+
if (Math.abs(cross) < 1e-9)
|
|
151
|
+
return; // colinear — no join needed
|
|
152
|
+
// Outer normal direction = cross < 0 → +offset; cross > 0 → -offset.
|
|
153
|
+
const sign = cross < 0 ? 1 : -1;
|
|
154
|
+
const outerTipX = vertexX + sign * ox;
|
|
155
|
+
const outerTipY = vertexY + sign * oy;
|
|
156
|
+
const innerNormal1X = sign * n1x * half;
|
|
157
|
+
const innerNormal1Y = sign * n1y * half;
|
|
158
|
+
const innerNormal2X = sign * n2x * half;
|
|
159
|
+
const innerNormal2Y = sign * n2y * half;
|
|
160
|
+
// Triangle: vertex, end of seg-1 outer-side, miter tip.
|
|
161
|
+
push(vertexX, vertexY);
|
|
162
|
+
push(vertexX + innerNormal1X, vertexY + innerNormal1Y);
|
|
163
|
+
push(outerTipX, outerTipY);
|
|
164
|
+
// Triangle: vertex, miter tip, start of seg-2 outer-side.
|
|
165
|
+
push(vertexX, vertexY);
|
|
166
|
+
push(outerTipX, outerTipY);
|
|
167
|
+
push(vertexX + innerNormal2X, vertexY + innerNormal2Y);
|
|
168
|
+
}
|
|
169
|
+
else if (style.join === "bevel") {
|
|
170
|
+
const cross = n1x * n2y - n1y * n2x;
|
|
171
|
+
if (Math.abs(cross) < 1e-9)
|
|
172
|
+
return;
|
|
173
|
+
const sign = cross < 0 ? 1 : -1;
|
|
174
|
+
const a1x = vertexX + sign * n1x * half;
|
|
175
|
+
const a1y = vertexY + sign * n1y * half;
|
|
176
|
+
const a2x = vertexX + sign * n2x * half;
|
|
177
|
+
const a2y = vertexY + sign * n2y * half;
|
|
178
|
+
// Single triangle fills the bevel gap.
|
|
179
|
+
push(vertexX, vertexY);
|
|
180
|
+
push(a1x, a1y);
|
|
181
|
+
push(a2x, a2y);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
// round join: fan triangles between the two outer-side offsets.
|
|
185
|
+
const cross = n1x * n2y - n1y * n2x;
|
|
186
|
+
if (Math.abs(cross) < 1e-9)
|
|
187
|
+
return;
|
|
188
|
+
const sign = cross < 0 ? 1 : -1;
|
|
189
|
+
const startAngle = Math.atan2(sign * n1y, sign * n1x);
|
|
190
|
+
const endAngle = Math.atan2(sign * n2y, sign * n2x);
|
|
191
|
+
// Pick the shortest angular sweep.
|
|
192
|
+
let delta = endAngle - startAngle;
|
|
193
|
+
while (delta > Math.PI)
|
|
194
|
+
delta -= 2 * Math.PI;
|
|
195
|
+
while (delta < -Math.PI)
|
|
196
|
+
delta += 2 * Math.PI;
|
|
197
|
+
const segs = Math.max(2, Math.ceil((Math.abs(delta) / Math.PI) * ROUND_SEGMENTS_PER_PI));
|
|
198
|
+
let prevX = vertexX + Math.cos(startAngle) * half;
|
|
199
|
+
let prevY = vertexY + Math.sin(startAngle) * half;
|
|
200
|
+
for (let s = 1; s <= segs; s++) {
|
|
201
|
+
const t = s / segs;
|
|
202
|
+
const angle = startAngle + delta * t;
|
|
203
|
+
const x = vertexX + Math.cos(angle) * half;
|
|
204
|
+
const y = vertexY + Math.sin(angle) * half;
|
|
205
|
+
push(vertexX, vertexY);
|
|
206
|
+
push(prevX, prevY);
|
|
207
|
+
push(x, y);
|
|
208
|
+
prevX = x;
|
|
209
|
+
prevY = y;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
for (let i = 1; i < segCount; i++) {
|
|
214
|
+
const p = req(polyline[i]);
|
|
215
|
+
emitJoin(p.x, p.y, req(nx[i - 1]), req(ny[i - 1]), req(nx[i]), req(ny[i]));
|
|
216
|
+
}
|
|
217
|
+
if (closed) {
|
|
218
|
+
const p = req(polyline[0]);
|
|
219
|
+
emitJoin(p.x, p.y, req(nx[segCount - 1]), req(ny[segCount - 1]), req(nx[0]), req(ny[0]));
|
|
220
|
+
}
|
|
221
|
+
// Caps on open polylines (closed shapes don't have caps).
|
|
222
|
+
if (!closed) {
|
|
223
|
+
const capFirst = req(polyline[0]);
|
|
224
|
+
const second = req(polyline[1]);
|
|
225
|
+
emitCap(push, capFirst.x, capFirst.y, second.x, second.y, req(nx[0]), req(ny[0]), half, style.cap, true);
|
|
226
|
+
const lastVx = req(polyline[polyline.length - 1]);
|
|
227
|
+
const prevVx = req(polyline[polyline.length - 2]);
|
|
228
|
+
emitCap(push, lastVx.x, lastVx.y, prevVx.x, prevVx.y, req(nx[segCount - 1]), req(ny[segCount - 1]), half, style.cap, false);
|
|
229
|
+
}
|
|
230
|
+
if (scratchTrisLen === 0)
|
|
231
|
+
return;
|
|
232
|
+
// Project all triangle vertices into clip space in-place: read world
|
|
233
|
+
// (x, y) first, then overwrite the same indices with clip-space
|
|
234
|
+
// values.
|
|
235
|
+
const sx = 2 / size.width;
|
|
236
|
+
const sy = -2 / size.height;
|
|
237
|
+
for (let i = 0; i < scratchTrisLen; i += 2) {
|
|
238
|
+
const x = req(scratchTris[i]);
|
|
239
|
+
const y = req(scratchTris[i + 1]);
|
|
240
|
+
const wx = transform.a * x + transform.c * y + transform.e;
|
|
241
|
+
const wy = transform.b * x + transform.d * y + transform.f;
|
|
242
|
+
scratchTris[i] = wx * sx - 1;
|
|
243
|
+
scratchTris[i + 1] = wy * sy + 1;
|
|
244
|
+
}
|
|
245
|
+
gl.useProgram(program);
|
|
246
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, dynamicVbo);
|
|
247
|
+
// subarray gives a view into the live scratch buffer — no copy.
|
|
248
|
+
gl.bufferData(gl.ARRAY_BUFFER, scratchTris.subarray(0, scratchTrisLen), gl.DYNAMIC_DRAW);
|
|
249
|
+
gl.enableVertexAttribArray(aPosLoc);
|
|
250
|
+
gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, false, 0, 0);
|
|
251
|
+
gl.uniformMatrix3fv(uTransformLoc, false, identityMat3);
|
|
252
|
+
gl.uniform3f(uColorLoc, style.color[0], style.color[1], style.color[2]);
|
|
253
|
+
gl.uniform1f(uOpacityLoc, style.opacity);
|
|
254
|
+
gl.drawArrays(gl.TRIANGLES, 0, scratchTrisLen / 2);
|
|
255
|
+
};
|
|
256
|
+
/**
|
|
257
|
+
* Emit a cap at one endpoint of an open polyline. `start` indicates
|
|
258
|
+
* whether this is the leading (first) cap — the outward tangent
|
|
259
|
+
* direction reverses for the trailing cap.
|
|
260
|
+
* `butt` → nothing (the rect band already squared off the end).
|
|
261
|
+
* `square` → extend the rect band by `half` along the tangent.
|
|
262
|
+
* `round` → half-circle fan.
|
|
263
|
+
*/
|
|
264
|
+
const emitCap = (push, vx, vy, otherX, otherY, nrmX, nrmY, half, cap, start) => {
|
|
265
|
+
if (cap === "butt")
|
|
266
|
+
return;
|
|
267
|
+
// Outward tangent direction: from vertex away from the polyline's
|
|
268
|
+
// interior. For `start`, it's vertex → -other (extending backward);
|
|
269
|
+
// for the trailing cap, it's vertex → +other (extending forward).
|
|
270
|
+
// Both point away from the next-vertex along the segment direction.
|
|
271
|
+
const dx = otherX - vx;
|
|
272
|
+
const dy = otherY - vy;
|
|
273
|
+
const len = Math.hypot(dx, dy) || 1;
|
|
274
|
+
const tx = -dx / len; // outward tangent
|
|
275
|
+
const ty = -dy / len;
|
|
276
|
+
// `start` cap points outward by reversing; the trailing cap already
|
|
277
|
+
// points outward (other is the previous vertex).
|
|
278
|
+
const sign = start ? 1 : -1;
|
|
279
|
+
const outX = sign * tx;
|
|
280
|
+
const outY = sign * ty;
|
|
281
|
+
if (cap === "square") {
|
|
282
|
+
// Extend the band by `half` along the outward tangent.
|
|
283
|
+
const A = { x: vx + nrmX * half, y: vy + nrmY * half };
|
|
284
|
+
const B = { x: vx - nrmX * half, y: vy - nrmY * half };
|
|
285
|
+
const Aext = { x: A.x + outX * half, y: A.y + outY * half };
|
|
286
|
+
const Bext = { x: B.x + outX * half, y: B.y + outY * half };
|
|
287
|
+
push(A.x, A.y);
|
|
288
|
+
push(Aext.x, Aext.y);
|
|
289
|
+
push(B.x, B.y);
|
|
290
|
+
push(B.x, B.y);
|
|
291
|
+
push(Aext.x, Aext.y);
|
|
292
|
+
push(Bext.x, Bext.y);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
// round cap: half-circle fan starting from +normal, sweeping through
|
|
296
|
+
// the outward tangent, ending at -normal.
|
|
297
|
+
const startAngle = Math.atan2(nrmY, nrmX);
|
|
298
|
+
const segs = ROUND_SEGMENTS_PER_PI;
|
|
299
|
+
// Sweep π radians in the outward direction. The sweep direction
|
|
300
|
+
// (CW vs CCW) depends on which side `out` is relative to the normal —
|
|
301
|
+
// use the cross-product sign.
|
|
302
|
+
const cross = nrmX * outY - nrmY * outX;
|
|
303
|
+
const sweepSign = cross >= 0 ? 1 : -1;
|
|
304
|
+
let prevX = vx + Math.cos(startAngle) * half;
|
|
305
|
+
let prevY = vy + Math.sin(startAngle) * half;
|
|
306
|
+
for (let s = 1; s <= segs; s++) {
|
|
307
|
+
const t = s / segs;
|
|
308
|
+
const angle = startAngle + sweepSign * Math.PI * t;
|
|
309
|
+
const x = vx + Math.cos(angle) * half;
|
|
310
|
+
const y = vy + Math.sin(angle) * half;
|
|
311
|
+
push(vx, vy);
|
|
312
|
+
push(prevX, prevY);
|
|
313
|
+
push(x, y);
|
|
314
|
+
prevX = x;
|
|
315
|
+
prevY = y;
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
//# sourceMappingURL=webgl2-stroke.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webgl2-stroke.js","sourceRoot":"","sources":["../src/webgl2-stroke.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import type { Bounds, Color, Transform, Vec2 } from "@oh-just-another/types";
|
|
2
|
+
import type { FillRule, LineCap, LineJoin, RenderTarget, TextAlign, TextBaseline } from "@oh-just-another/renderer-core";
|
|
3
|
+
/**
|
|
4
|
+
* WebGL2 RenderTarget. Implements clear, transform/state stack, path
|
|
5
|
+
* primitives (rect / polyline / ellipse / Bezier), fill, stroke, text
|
|
6
|
+
* (MSDF or OffscreenCanvas-bitmap fallback), and image drawing.
|
|
7
|
+
*/
|
|
8
|
+
export declare class WebGL2Target implements RenderTarget {
|
|
9
|
+
private readonly gl;
|
|
10
|
+
private readonly program;
|
|
11
|
+
/**
|
|
12
|
+
* Static unit-quad VBO ([0,0]–[1,1]) — used by every solid-fill rect
|
|
13
|
+
* draw. Filled once in the constructor with `STATIC_DRAW` and never
|
|
14
|
+
* re-written; the rect's world-space placement is done entirely via
|
|
15
|
+
* `uTransform`.
|
|
16
|
+
*/
|
|
17
|
+
private readonly vbo;
|
|
18
|
+
/**
|
|
19
|
+
* Per-frame scratch VBO for polygon / triangle-fan / stroke vertex
|
|
20
|
+
* streams. Re-uploaded each draw with `DYNAMIC_DRAW`. Kept separate
|
|
21
|
+
* from `vbo` so the static unit quad never gets stomped.
|
|
22
|
+
*/
|
|
23
|
+
private readonly dynamicVbo;
|
|
24
|
+
private readonly uTransformLoc;
|
|
25
|
+
private readonly uColorLoc;
|
|
26
|
+
private readonly uOpacityLoc;
|
|
27
|
+
/**
|
|
28
|
+
* Cached attribute location for the solid program. `getAttribLocation`
|
|
29
|
+
* is a string-keyed driver lookup; repeating it per draw is a real
|
|
30
|
+
* per-frame cost on integrated GPUs. Locations are stable once the
|
|
31
|
+
* program is linked, so they're read once in the constructor.
|
|
32
|
+
*/
|
|
33
|
+
private readonly aPosLoc;
|
|
34
|
+
private readonly _size;
|
|
35
|
+
private fillColor;
|
|
36
|
+
private fillAlpha;
|
|
37
|
+
private strokeColor;
|
|
38
|
+
private strokeAlpha;
|
|
39
|
+
private fillColorString;
|
|
40
|
+
private strokeWidth;
|
|
41
|
+
private lineCap;
|
|
42
|
+
private lineJoin;
|
|
43
|
+
/** Dash pattern in WORLD units (matches Canvas2D, which dashes in the
|
|
44
|
+
* world-space ctx transform). `null` = solid. */
|
|
45
|
+
private dashArray;
|
|
46
|
+
private opacity;
|
|
47
|
+
private currentPath;
|
|
48
|
+
private fontFamily;
|
|
49
|
+
private fontSize;
|
|
50
|
+
private fontWeight;
|
|
51
|
+
private fontStyle;
|
|
52
|
+
private textAlign;
|
|
53
|
+
private textBaseline;
|
|
54
|
+
/**
|
|
55
|
+
* Polyline path being assembled by moveTo / lineTo. Cleared on
|
|
56
|
+
* `beginPath()`; pushed to GPU on `stroke()`.
|
|
57
|
+
*/
|
|
58
|
+
private currentPolyline;
|
|
59
|
+
/**
|
|
60
|
+
* Curve segments collected since the last `beginPath()`. Quadratic
|
|
61
|
+
* and cubic Bezier `*CurveTo` calls push here in addition to pushing
|
|
62
|
+
* the curve endpoint into `currentPolyline` — the polyline forms the
|
|
63
|
+
* polygon hull for `fill()` triangulation, and the curve list adds
|
|
64
|
+
* Loop-Blinn fragment-tested triangles on top so curve regions stay
|
|
65
|
+
* perfectly smooth at any zoom.
|
|
66
|
+
*/
|
|
67
|
+
private currentCurves;
|
|
68
|
+
/**
|
|
69
|
+
* Ellipse parameters set by `ellipse()` — drives the fragment-SDF
|
|
70
|
+
* `EllipsePipeline` on `fill()`. Separate from the polygon path so
|
|
71
|
+
* `fill()` can skip the earcut pipeline entirely for ellipses (1 quad
|
|
72
|
+
* vs 24-512 segments). `stroke()` falls back to building a polyline
|
|
73
|
+
* lazily.
|
|
74
|
+
*/
|
|
75
|
+
private currentEllipse;
|
|
76
|
+
private transform;
|
|
77
|
+
/**
|
|
78
|
+
* save() / restore() snapshot stack. Mirrors Canvas2D's `ctx.save/
|
|
79
|
+
* restore` contract: the full paint + text state is saved, not just
|
|
80
|
+
* the transform — otherwise `opacity` / fill / stroke set inside a
|
|
81
|
+
* save()…restore() block would leak onto everything drawn afterwards.
|
|
82
|
+
* The current PATH is excluded — Canvas2D's save/restore doesn't
|
|
83
|
+
* snapshot the path either.
|
|
84
|
+
*/
|
|
85
|
+
private readonly stack;
|
|
86
|
+
constructor(canvas: HTMLCanvasElement | OffscreenCanvas, width: number, height: number);
|
|
87
|
+
get size(): {
|
|
88
|
+
readonly width: number;
|
|
89
|
+
readonly height: number;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Update the recorded CSS-pixel size after the host resizes the
|
|
93
|
+
* underlying canvas. Callers handle `setupHiDpi` / `gl.viewport`
|
|
94
|
+
* updates on the actual canvas; this keeps the target's `size` getter
|
|
95
|
+
* in sync so downstream renderers see the new dimensions.
|
|
96
|
+
*/
|
|
97
|
+
resize(width: number, height: number): void;
|
|
98
|
+
/**
|
|
99
|
+
* Free the underlying WebGL context immediately. Browsers cap the
|
|
100
|
+
* number of live WebGL contexts per page (~16 in Chrome); without
|
|
101
|
+
* `WEBGL_lose_context`, GC can take a while to collect old surfaces
|
|
102
|
+
* and runtime backend switches quickly hit the cap.
|
|
103
|
+
*/
|
|
104
|
+
dispose(): void;
|
|
105
|
+
setFill(color: Color | null): void;
|
|
106
|
+
setOpacity(alpha: number): void;
|
|
107
|
+
save(): void;
|
|
108
|
+
restore(): void;
|
|
109
|
+
setTransform(t: Transform): void;
|
|
110
|
+
resetTransform(): void;
|
|
111
|
+
translate(dx: number, dy: number): void;
|
|
112
|
+
rotate(radians: number): void;
|
|
113
|
+
scale(sx: number, sy: number): void;
|
|
114
|
+
beginPath(): void;
|
|
115
|
+
rect(x: number, y: number, width: number, height: number): void;
|
|
116
|
+
private readonly _pathRect;
|
|
117
|
+
moveTo(x: number, y: number): void;
|
|
118
|
+
lineTo(x: number, y: number): void;
|
|
119
|
+
closePath(): void;
|
|
120
|
+
/**
|
|
121
|
+
* Stash the analytic ellipse — `fill()` draws it via the fragment-SDF
|
|
122
|
+
* `EllipsePipeline` (1 quad, perfect curve at any zoom). The polyline
|
|
123
|
+
* and polygon path are not populated up front; `stroke()` builds the
|
|
124
|
+
* polyline lazily if it's needed, saving the 24-512 vertex allocation
|
|
125
|
+
* when callers only fill.
|
|
126
|
+
*/
|
|
127
|
+
ellipse(cx: number, cy: number, rx: number, ry: number): void;
|
|
128
|
+
/**
|
|
129
|
+
* Build a polyline approximation of `currentEllipse` for the stroke
|
|
130
|
+
* pipeline. Zoom-adaptive segment count keeps chord-to-arc error
|
|
131
|
+
* sub-pixel at any scale.
|
|
132
|
+
*/
|
|
133
|
+
private buildEllipseStrokePolyline;
|
|
134
|
+
/**
|
|
135
|
+
* Quadratic Bezier. Pushed twice:
|
|
136
|
+
* 1. As a single `CurveSegment` into `currentCurves` for the
|
|
137
|
+
* Loop-Blinn fill pass — a perfect curve edge at any zoom (one
|
|
138
|
+
* fragment-tested triangle, no faceting).
|
|
139
|
+
* 2. As the curve endpoint into `currentPolyline` — keeps the
|
|
140
|
+
* polygon hull intact so `fill()`'s earcut triangulation and
|
|
141
|
+
* `stroke()`'s polyline math both see the chord.
|
|
142
|
+
*
|
|
143
|
+
* Strokes flatten to chord segments via the registered rasterizer
|
|
144
|
+
* (sub-pixel zoom-aware).
|
|
145
|
+
*/
|
|
146
|
+
quadraticCurveTo(cx: number, cy: number, x: number, y: number): void;
|
|
147
|
+
/** Cubic Bezier — same dual-track approach as quadratic. */
|
|
148
|
+
bezierCurveTo(c1x: number, c1y: number, c2x: number, c2y: number, x: number, y: number): void;
|
|
149
|
+
/**
|
|
150
|
+
* World-unit tolerance that maps to ~`SCREEN_TOLERANCE_PX` on screen
|
|
151
|
+
* at the current transform. Used by every curve-flatten call so the
|
|
152
|
+
* polyline density tracks the zoom.
|
|
153
|
+
*/
|
|
154
|
+
private currentFlattenTolerance;
|
|
155
|
+
/**
|
|
156
|
+
* Image rendering — uploads `image` to a freshly-created GL texture
|
|
157
|
+
* on first call, caches it by reference for subsequent frames. Drawn
|
|
158
|
+
* as a textured quad via a dedicated program created lazily on the
|
|
159
|
+
* first image call.
|
|
160
|
+
*/
|
|
161
|
+
drawImage(image: unknown, dx: number, dy: number, dw: number, dh: number, dynamic?: boolean): void;
|
|
162
|
+
/** Lazy image program + its static unit quad+UV VBO. */
|
|
163
|
+
private imageProgram;
|
|
164
|
+
private imageQuadVbo;
|
|
165
|
+
/**
|
|
166
|
+
* `TexImageSource` → uploaded `WebGLTexture` cache. A plain `Map`
|
|
167
|
+
* with LRU eviction + explicit `gl.deleteTexture` (see
|
|
168
|
+
* `evictImageTexturesIfOverCap`) so the GPU texture is released
|
|
169
|
+
* deterministically rather than waiting for GC.
|
|
170
|
+
*
|
|
171
|
+
* `Map` preserves insertion order, so the head is least-recently
|
|
172
|
+
* used. `textureFor` touches a hit by delete + set (moves to tail).
|
|
173
|
+
*/
|
|
174
|
+
private readonly textures;
|
|
175
|
+
private textureFor;
|
|
176
|
+
/**
|
|
177
|
+
* Trim `textures` down to `WEBGL2_IMAGE_TEXTURE_CACHE_CAP` entries by
|
|
178
|
+
* dropping least-recently-used keys and explicitly releasing the GPU
|
|
179
|
+
* texture for each evicted entry.
|
|
180
|
+
*
|
|
181
|
+
* Skips entries also held by `textBitmaps` — those are evicted through
|
|
182
|
+
* `evictTextBitmapsIfOverCap` instead, which already deletes the
|
|
183
|
+
* texture. Skipping here keeps the two cache layers from
|
|
184
|
+
* double-`gl.deleteTexture`'ing the same handle.
|
|
185
|
+
*/
|
|
186
|
+
private evictImageTexturesIfOverCap;
|
|
187
|
+
fill(_rule?: FillRule): void;
|
|
188
|
+
private curvePipeline;
|
|
189
|
+
private ellipsePipeline;
|
|
190
|
+
/**
|
|
191
|
+
* Triangulate the polygon via earcut and emit one TRIANGLES draw.
|
|
192
|
+
* Vertices are pre-projected into clip space so the program's
|
|
193
|
+
* `uTransform` stays identity. Falls back to a triangle-fan when
|
|
194
|
+
* earcut returns an empty index list (degenerate self-intersecting
|
|
195
|
+
* polygon).
|
|
196
|
+
*/
|
|
197
|
+
private fillPolygonEarcut;
|
|
198
|
+
private indexBuffer;
|
|
199
|
+
/**
|
|
200
|
+
* Convex / fallback path — triangle fan from polyline[0]. Renders
|
|
201
|
+
* convex polygons correctly; concave ones get a wrong silhouette (the
|
|
202
|
+
* earcut path handles those instead).
|
|
203
|
+
*/
|
|
204
|
+
private drawTriangleFan;
|
|
205
|
+
/**
|
|
206
|
+
* Clear the canvas. With no `bounds` does a full backbuffer wipe; with
|
|
207
|
+
* `bounds` wipes only the rectangle the editor's dirty-rect pass
|
|
208
|
+
* identified. Honouring `bounds` is mandatory — when the scene
|
|
209
|
+
* reference doesn't change, the editor sends a zero-area dirty rect
|
|
210
|
+
* and expects the previous frame to survive untouched.
|
|
211
|
+
* `preserveDrawingBuffer: true` carries the persistent frame across
|
|
212
|
+
* composites.
|
|
213
|
+
*
|
|
214
|
+
* For bounded clears the implementation flips on a scissor box so the
|
|
215
|
+
* clear is confined to the dirty rect, mirroring Canvas2D's
|
|
216
|
+
* partial-clear semantics. The scissor box is in DPR-bitmap pixels
|
|
217
|
+
* with bottom-left origin (GL convention), translated from the
|
|
218
|
+
* caller's top-left CSS-pixel rect.
|
|
219
|
+
*/
|
|
220
|
+
clear(bounds?: Bounds): void;
|
|
221
|
+
setStroke(color: Color | null): void;
|
|
222
|
+
setStrokeWidth(width: number): void;
|
|
223
|
+
stroke(): void;
|
|
224
|
+
setLineCap(cap: LineCap): void;
|
|
225
|
+
setLineJoin(join: LineJoin): void;
|
|
226
|
+
setDashArray(dash: readonly number[] | null): void;
|
|
227
|
+
setFont(family: string, size: number, options?: {
|
|
228
|
+
weight?: "normal" | "bold";
|
|
229
|
+
style?: "normal" | "italic";
|
|
230
|
+
}): void;
|
|
231
|
+
setTextAlign(align: TextAlign): void;
|
|
232
|
+
setTextBaseline(baseline: TextBaseline): void;
|
|
233
|
+
/**
|
|
234
|
+
* Text rendering with two paths:
|
|
235
|
+
*
|
|
236
|
+
* 1. MSDF (preferred) — when an `MsdfShaper`-compatible TextShaper
|
|
237
|
+
* is registered. Builds per-glyph quads against a shared
|
|
238
|
+
* `GlyphAtlas`, draws them with the bundled MSDF program so
|
|
239
|
+
* letters stay crisp at any zoom (no bitmap re-rasterisation
|
|
240
|
+
* when the user scales the view).
|
|
241
|
+
*
|
|
242
|
+
* 2. OffscreenCanvas fallback — used when no MSDF-capable shaper is
|
|
243
|
+
* registered (older module, Safari without bundled wasm, etc.).
|
|
244
|
+
*/
|
|
245
|
+
fillText(text: string, x: number, y: number, maxWidth?: number): void;
|
|
246
|
+
private msdfPipeline;
|
|
247
|
+
private glyphAtlas;
|
|
248
|
+
private glyphAtlasShaper;
|
|
249
|
+
/**
|
|
250
|
+
* Lazy-acquire the MSDF atlas — only when there's an
|
|
251
|
+
* `MsdfShaper`-compatible TextShaper registered via
|
|
252
|
+
* `setActiveTextShaper`. Held for the lifetime of the WebGL2Target;
|
|
253
|
+
* cleared on dispose.
|
|
254
|
+
*
|
|
255
|
+
* Re-creates the atlas if a different shaper instance gets registered
|
|
256
|
+
* later. Same shaper instance → reuses the existing cache, so
|
|
257
|
+
* steady-state cost is one map lookup.
|
|
258
|
+
*/
|
|
259
|
+
private ensureGlyphAtlas;
|
|
260
|
+
/**
|
|
261
|
+
* MSDF path for `fillText`. Honours textAlign / textBaseline by
|
|
262
|
+
* measuring the string width upfront and shifting the cursor. Width
|
|
263
|
+
* measurement walks the atlas (advance from cached metrics), so it
|
|
264
|
+
* doesn't round-trip the WASM measure().
|
|
265
|
+
*/
|
|
266
|
+
private fillTextMSDF;
|
|
267
|
+
/**
|
|
268
|
+
* Rebind the solid program + static unit-quad VBO + cached aPos
|
|
269
|
+
* pointer. Three GL calls, no allocation, no upload, no string-keyed
|
|
270
|
+
* driver lookup. Called after any draw that switched program or
|
|
271
|
+
* rebound the buffer (image, MSDF text, curves, polygon fill, triangle
|
|
272
|
+
* fan).
|
|
273
|
+
*/
|
|
274
|
+
private restoreSolidProgram;
|
|
275
|
+
measureText(text: string): {
|
|
276
|
+
width: number;
|
|
277
|
+
};
|
|
278
|
+
/** Hidden Canvas2D context for measureText + bitmap rasterisation. */
|
|
279
|
+
private textCtx;
|
|
280
|
+
/**
|
|
281
|
+
* Per-string OffscreenCanvas cache for the fallback text path (no MSDF
|
|
282
|
+
* shaper registered). Keyed by `text|font|color`. Capped via
|
|
283
|
+
* `WEBGL2_TEXT_BITMAP_CACHE_CAP` LRU eviction.
|
|
284
|
+
*
|
|
285
|
+
* `Map` preserves insertion order, so the oldest entry is the iterator
|
|
286
|
+
* head. `rasteriseString` "touches" a hit by delete + set, which moves
|
|
287
|
+
* it to the tail.
|
|
288
|
+
*/
|
|
289
|
+
private readonly textBitmaps;
|
|
290
|
+
private ensureTextCtx;
|
|
291
|
+
private textFontSpec;
|
|
292
|
+
private textMetrics;
|
|
293
|
+
private rasteriseString;
|
|
294
|
+
/**
|
|
295
|
+
* Trim `textBitmaps` down to `WEBGL2_TEXT_BITMAP_CACHE_CAP` entries by
|
|
296
|
+
* dropping least-recently-used keys. For each evicted OffscreenCanvas
|
|
297
|
+
* the associated GPU texture (uploaded lazily via `drawImage` →
|
|
298
|
+
* `textureFor`) is also deleted, otherwise the VRAM stays held until
|
|
299
|
+
* JS GC collects the canvas.
|
|
300
|
+
*/
|
|
301
|
+
private evictTextBitmapsIfOverCap;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Split a polyline into the "on" dash runs for `pattern` ([on, off, on, …]),
|
|
305
|
+
* lengths in the polyline's own (world) units. Walks each segment, toggling
|
|
306
|
+
* on/off as the running distance crosses each pattern element, and emits the
|
|
307
|
+
* point lists of the drawn runs. Used by WebGL2 `stroke()` to render dashed /
|
|
308
|
+
* dotted lines (Canvas2D gets this for free from `ctx.setLineDash`).
|
|
309
|
+
*/
|
|
310
|
+
export declare const dashPolyline: (pts: readonly Vec2[], pattern: readonly number[]) => Vec2[][];
|
|
311
|
+
//# sourceMappingURL=webgl2-target.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webgl2-target.d.ts","sourceRoot":"","sources":["../src/webgl2-target.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,KAAK,EACL,SAAS,EACT,IAAI,EACL,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EACV,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,YAAY,EACb,MAAM,gCAAgC,CAAC;AAexC;;;;GAIG;AACH,qBAAa,YAAa,YAAW,YAAY;IAC/C,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAyB;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAc;IAClC;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAc;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAuB;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;IACnD;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoC;IAE1D,OAAO,CAAC,SAAS,CAAuC;IACxD,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,WAAW,CAAuC;IAC1D,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,QAAQ,CAAqB;IACrC;sDACkD;IAClD,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,WAAW,CAAuB;IAG1C,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,YAAY,CAAuB;IAC3C;;;OAGG;IACH,OAAO,CAAC,eAAe,CAAc;IACrC;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa,CAAsB;IAC3C;;;;;;OAMG;IACH,OAAO,CAAC,cAAc,CAAmE;IACzF,OAAO,CAAC,SAAS,CAA4D;IAC7E;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;gBAE5B,MAAM,EAAE,iBAAiB,GAAG,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IA+EtF,IAAI,IAAI,IAAI;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAE9D;IAED;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAM3C;;;;;OAKG;IACH,OAAO,IAAI,IAAI;IAwCf,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI;IAOlC,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM/B,IAAI,IAAI,IAAI;IAsBZ,OAAO,IAAI,IAAI;IAwBf,YAAY,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI;IAWhC,cAAc,IAAI,IAAI;IAItB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAKvC,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAU7B,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IASnC,SAAS,IAAI,IAAI;IAOjB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAU/D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuC;IAEjE,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAIlC,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAIlC,SAAS,IAAI,IAAI;IAOjB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAM7D;;;;OAIG;IACH,OAAO,CAAC,0BAA0B;IAiBlC;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IA0BpE,4DAA4D;IAC5D,aAAa,CACX,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACR,IAAI;IA6BP;;;;OAIG;IACH,OAAO,CAAC,uBAAuB;IAU/B;;;;;OAKG;IACH,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI;IAgDlG,wDAAwD;IACxD,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,YAAY,CAA4B;IAChD;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmC;IAE5D,OAAO,CAAC,UAAU;IAyDlB;;;;;;;;;OASG;IACH,OAAO,CAAC,2BAA2B;IAqBnC,IAAI,CAAC,KAAK,CAAC,EAAE,QAAQ,GAAG,IAAI;IA4E5B,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,eAAe,CAAgC;IAEvD;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAgFzB,OAAO,CAAC,WAAW,CAA4B;IAE/C;;;;OAIG;IACH,OAAO,CAAC,eAAe;IA0BvB;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IA4B5B,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI;IAMpC,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAInC,MAAM,IAAI,IAAI;IA0Dd,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IAG9B,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI;IAGjC,YAAY,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,GAAG,IAAI;IAGlD,OAAO,CACL,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAA;KAAE,GACpE,IAAI;IAMP,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAGpC,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAI7C;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAoBrE,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,gBAAgB,CAA2B;IAEnD;;;;;;;;;OASG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAyCpB;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;IAM3B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE;IAM5C,sEAAsE;IACtE,OAAO,CAAC,OAAO,CAAyC;IACxD;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsC;IAElE,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,WAAW;IA+BnB,OAAO,CAAC,eAAe;IA6BvB;;;;;;OAMG;IACH,OAAO,CAAC,yBAAyB;CAelC;AA+BD;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,GAAI,KAAK,SAAS,IAAI,EAAE,EAAE,SAAS,SAAS,MAAM,EAAE,KAAG,IAAI,EAAE,EAoCrF,CAAC"}
|