kritzel-stencil 0.3.24 → 0.3.26
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/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/kritzel-active-users_45.cjs.entry.js +60 -36
- package/dist/cjs/{schema.constants-D8JoUfNc.js → schema.constants-CPz_o--2.js} +271 -101
- package/dist/collection/classes/handlers/line-handle.handler.js +59 -52
- package/dist/collection/classes/handlers/move.handler.js +2 -0
- package/dist/collection/classes/handlers/rotation.handler.js +18 -6
- package/dist/collection/classes/managers/anchor.manager.js +112 -38
- package/dist/collection/classes/managers/clipboard.manager.js +7 -0
- package/dist/collection/classes/objects/selection-group.class.js +80 -5
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +50 -34
- package/dist/collection/configs/default-engine-config.js +1 -0
- package/dist/collection/constants/version.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/kritzel-controls.js +1 -1
- package/dist/components/kritzel-editor.js +1 -1
- package/dist/components/kritzel-engine.js +1 -1
- package/dist/components/kritzel-settings.js +1 -1
- package/dist/components/kritzel-tool-config.js +1 -1
- package/dist/components/p-B0VgBZUT.js +9 -0
- package/dist/components/{p-Bz_zj6dQ.js → p-BAhZcKRe.js} +1 -1
- package/dist/components/{p-Dw-t1qQc.js → p-DKxt_AjI.js} +1 -1
- package/dist/components/{p-B5XGjTLd.js → p-DRncK1E6.js} +1 -1
- package/dist/components/{p-DNDt6O6A.js → p-DUo2M5uM.js} +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/kritzel-active-users_45.entry.js +60 -36
- package/dist/esm/{schema.constants-B3IqnD8l.js → schema.constants-C9ZX7hQv.js} +271 -101
- package/dist/stencil/index.esm.js +1 -1
- package/dist/stencil/p-71271db1.entry.js +9 -0
- package/dist/stencil/{p-B3IqnD8l.js → p-C9ZX7hQv.js} +1 -1
- package/dist/stencil/stencil.esm.js +1 -1
- package/dist/types/classes/handlers/line-handle.handler.d.ts +1 -0
- package/dist/types/classes/handlers/rotation.handler.d.ts +4 -0
- package/dist/types/classes/managers/anchor.manager.d.ts +39 -3
- package/dist/types/classes/objects/selection-group.class.d.ts +8 -1
- package/dist/types/constants/version.d.ts +1 -1
- package/dist/types/interfaces/anchor.interface.d.ts +12 -2
- package/dist/types/interfaces/engine-state.interface.d.ts +2 -1
- package/package.json +1 -1
- package/dist/components/p-on11Z8cZ.js +0 -9
- package/dist/stencil/p-63bc234f.entry.js +0 -9
|
@@ -39,6 +39,8 @@ export class KritzelSelectionGroup extends KritzelBaseObject {
|
|
|
39
39
|
_lastChildPersistTime = 0;
|
|
40
40
|
/** Minimum interval (ms) between child Yjs persists during drag */
|
|
41
41
|
static CHILD_PERSIST_THROTTLE_MS = 100;
|
|
42
|
+
/** Ignore tiny floating-point diffs when comparing refreshed bounds */
|
|
43
|
+
static DIMENSION_EPSILON = 0.001;
|
|
42
44
|
/**
|
|
43
45
|
* Gets the array of object IDs contained in this selection group.
|
|
44
46
|
* @returns Array of string IDs for the selected objects
|
|
@@ -412,6 +414,30 @@ export class KritzelSelectionGroup extends KritzelBaseObject {
|
|
|
412
414
|
}
|
|
413
415
|
});
|
|
414
416
|
}
|
|
417
|
+
/**
|
|
418
|
+
* Returns true when the selection contains a line anchored to an object
|
|
419
|
+
* that is not part of this selection group.
|
|
420
|
+
*/
|
|
421
|
+
hasExternalAnchoredLineConnections(cachedObjects) {
|
|
422
|
+
const children = cachedObjects ?? this.objects;
|
|
423
|
+
if (children.length === 0) {
|
|
424
|
+
return false;
|
|
425
|
+
}
|
|
426
|
+
const selectedIds = new Set(children.map(child => child.id));
|
|
427
|
+
for (const child of children) {
|
|
428
|
+
if (!KritzelClassHelper.isInstanceOf(child, 'KritzelLine')) {
|
|
429
|
+
continue;
|
|
430
|
+
}
|
|
431
|
+
const line = child;
|
|
432
|
+
if (line.startAnchor && !selectedIds.has(line.startAnchor.objectId)) {
|
|
433
|
+
return true;
|
|
434
|
+
}
|
|
435
|
+
if (line.endAnchor && !selectedIds.has(line.endAnchor.objectId)) {
|
|
436
|
+
return true;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
return false;
|
|
440
|
+
}
|
|
415
441
|
/**
|
|
416
442
|
* Resizes the selection group and scales all contained objects proportionally.
|
|
417
443
|
* Uses snapshot values to avoid compounding errors during continuous drag operations.
|
|
@@ -504,8 +530,13 @@ export class KritzelSelectionGroup extends KritzelBaseObject {
|
|
|
504
530
|
*/
|
|
505
531
|
rotate(value) {
|
|
506
532
|
this.rotation = value;
|
|
507
|
-
|
|
508
|
-
|
|
533
|
+
// Use the snapshot center as the rotation pivot rather than the live center.
|
|
534
|
+
// refreshObjectDimensions() below can grow the box when an anchored line is pinned
|
|
535
|
+
// to an external object; keeping the pivot fixed prevents the children from drifting.
|
|
536
|
+
const snapshotTotalWidth = this.snapshotWidth + this.padding * 2;
|
|
537
|
+
const snapshotTotalHeight = this.snapshotHeight + this.padding * 2;
|
|
538
|
+
const centerX = this.snapshotTranslateX + snapshotTotalWidth / 2 / this.scale;
|
|
539
|
+
const centerY = this.snapshotTranslateY + snapshotTotalHeight / 2 / this.scale;
|
|
509
540
|
const angle = value - this.snapshotRotation;
|
|
510
541
|
const cos = Math.cos(angle);
|
|
511
542
|
const sin = Math.sin(angle);
|
|
@@ -527,6 +558,31 @@ export class KritzelSelectionGroup extends KritzelBaseObject {
|
|
|
527
558
|
child.translateY = centerY + rotatedY - child.totalHeight / 2 / child.scale;
|
|
528
559
|
child.rotate(childCount === 1 ? value : unchangedSnapshot.rotation + angle);
|
|
529
560
|
}
|
|
561
|
+
// Re-sync any anchored lines so their stored geometry follows the rotated objects
|
|
562
|
+
// (including lines anchored to an object outside this selection), then grow the
|
|
563
|
+
// selection box to enclose the reshaped lines. Rotation sets state.isRotating
|
|
564
|
+
// rather than state.isDragging, so the refresh must be triggered explicitly here.
|
|
565
|
+
const anchorTargetIds = new Set();
|
|
566
|
+
for (const child of children) {
|
|
567
|
+
anchorTargetIds.add(child.id);
|
|
568
|
+
if (KritzelClassHelper.isInstanceOf(child, 'KritzelLine')) {
|
|
569
|
+
const line = child;
|
|
570
|
+
if (line.startAnchor)
|
|
571
|
+
anchorTargetIds.add(line.startAnchor.objectId);
|
|
572
|
+
if (line.endAnchor)
|
|
573
|
+
anchorTargetIds.add(line.endAnchor.objectId);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
let hasAnchoredLines = false;
|
|
577
|
+
for (const targetId of anchorTargetIds) {
|
|
578
|
+
if (this._core.anchorManager.getLinesAnchoredTo(targetId).length > 0) {
|
|
579
|
+
hasAnchoredLines = true;
|
|
580
|
+
this._core.anchorManager.updateAnchorsForObject(targetId);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
if (hasAnchoredLines) {
|
|
584
|
+
this.refreshObjectDimensions(children);
|
|
585
|
+
}
|
|
530
586
|
});
|
|
531
587
|
}
|
|
532
588
|
/**
|
|
@@ -556,6 +612,16 @@ export class KritzelSelectionGroup extends KritzelBaseObject {
|
|
|
556
612
|
* @param skipPersist If true, only updates local state without persisting to Yjs (used during undo/redo)
|
|
557
613
|
*/
|
|
558
614
|
refreshObjectDimensions(cachedObjects, skipPersist = false) {
|
|
615
|
+
const previous = {
|
|
616
|
+
minX: this.minX,
|
|
617
|
+
minY: this.minY,
|
|
618
|
+
maxX: this.maxX,
|
|
619
|
+
maxY: this.maxY,
|
|
620
|
+
width: this.width,
|
|
621
|
+
height: this.height,
|
|
622
|
+
translateX: this.translateX,
|
|
623
|
+
translateY: this.translateY,
|
|
624
|
+
};
|
|
559
625
|
const children = cachedObjects ?? this.objects;
|
|
560
626
|
if (children.length === 1) {
|
|
561
627
|
const obj = children[0];
|
|
@@ -609,9 +675,18 @@ export class KritzelSelectionGroup extends KritzelBaseObject {
|
|
|
609
675
|
this.translateX = cx - (this.width / this.scale + 2 * this.padding) / 2;
|
|
610
676
|
this.translateY = cy - (this.height / this.scale + 2 * this.padding) / 2;
|
|
611
677
|
}
|
|
612
|
-
|
|
678
|
+
const hasChanged = Math.abs(this.minX - previous.minX) > KritzelSelectionGroup.DIMENSION_EPSILON ||
|
|
679
|
+
Math.abs(this.minY - previous.minY) > KritzelSelectionGroup.DIMENSION_EPSILON ||
|
|
680
|
+
Math.abs(this.maxX - previous.maxX) > KritzelSelectionGroup.DIMENSION_EPSILON ||
|
|
681
|
+
Math.abs(this.maxY - previous.maxY) > KritzelSelectionGroup.DIMENSION_EPSILON ||
|
|
682
|
+
Math.abs(this.width - previous.width) > KritzelSelectionGroup.DIMENSION_EPSILON ||
|
|
683
|
+
Math.abs(this.height - previous.height) > KritzelSelectionGroup.DIMENSION_EPSILON ||
|
|
684
|
+
Math.abs(this.translateX - previous.translateX) > KritzelSelectionGroup.DIMENSION_EPSILON ||
|
|
685
|
+
Math.abs(this.translateY - previous.translateY) > KritzelSelectionGroup.DIMENSION_EPSILON;
|
|
686
|
+
if (!skipPersist && hasChanged) {
|
|
613
687
|
this._core.store.objects.update(this);
|
|
614
688
|
}
|
|
689
|
+
return hasChanged;
|
|
615
690
|
}
|
|
616
691
|
/**
|
|
617
692
|
* Calculates the horizontal offset from the group's center to an object's center using snapshot data.
|
|
@@ -621,7 +696,7 @@ export class KritzelSelectionGroup extends KritzelBaseObject {
|
|
|
621
696
|
*/
|
|
622
697
|
getOffsetXToCenterFromSnapshot(snapshot) {
|
|
623
698
|
const objCenterX = snapshot.translateX + snapshot.totalWidth / snapshot.scale / 2;
|
|
624
|
-
const groupCenterX = this.
|
|
699
|
+
const groupCenterX = this.snapshotTranslateX + (this.snapshotWidth + this.padding * 2) / this.scale / 2;
|
|
625
700
|
return objCenterX - groupCenterX;
|
|
626
701
|
}
|
|
627
702
|
/**
|
|
@@ -632,7 +707,7 @@ export class KritzelSelectionGroup extends KritzelBaseObject {
|
|
|
632
707
|
*/
|
|
633
708
|
getOffsetYToCenterFromSnapshot(snapshot) {
|
|
634
709
|
const objCenterY = snapshot.translateY + snapshot.totalHeight / snapshot.scale / 2;
|
|
635
|
-
const groupCenterY = this.
|
|
710
|
+
const groupCenterY = this.snapshotTranslateY + (this.snapshotHeight + this.padding * 2) / this.scale / 2;
|
|
636
711
|
return objCenterY - groupCenterY;
|
|
637
712
|
}
|
|
638
713
|
/**
|
|
@@ -2155,7 +2155,11 @@ export class KritzelEngine {
|
|
|
2155
2155
|
transform: object?.transformationMatrix,
|
|
2156
2156
|
transformOrigin: 'top left',
|
|
2157
2157
|
position: 'absolute',
|
|
2158
|
-
|
|
2158
|
+
// The object wrapper establishes its own stacking context (transform + z-index),
|
|
2159
|
+
// so the selection-line handles inside it cannot escape above the snap/anchor
|
|
2160
|
+
// layers (z-index 9999/9998) rendered later at the origin level. Lift the
|
|
2161
|
+
// selected line's wrapper above those layers so its handles always paint on top.
|
|
2162
|
+
zIndex: this.core.displaySelectionLineUI(object) ? '10001' : object.zIndex.toString(),
|
|
2159
2163
|
pointerEvents: getObjectWrapperPointerEvents(object),
|
|
2160
2164
|
} }, KritzelClassHelper.isInstanceOf(object, 'KritzelPath') && (h("svg", { ref: el => el && object.mount(el), xmlns: "http://www.w3.org/2000/svg", style: {
|
|
2161
2165
|
height: object?.totalHeight + 'px',
|
|
@@ -2359,10 +2363,21 @@ export class KritzelEngine {
|
|
|
2359
2363
|
}
|
|
2360
2364
|
const selectionBorderColor = remoteUserColor ?? (KritzelColorHelper.resolveThemeColor(object.borderColor, currentTheme) || 'var(--kritzel-selection-border-color, #007AFF)');
|
|
2361
2365
|
const selectionHandleStrokeColor = remoteUserColor ?? 'var(--kritzel-selection-handle-stroke-color, #007AFF)';
|
|
2366
|
+
const lineObject = object;
|
|
2367
|
+
const activeSnapCandidate = this.core.store.state.snapCandidate;
|
|
2368
|
+
const previewSnapCandidate = this.core.store.state.snapPreviewCandidate;
|
|
2369
|
+
const isStartHandleSnapped = lineObject.startAnchor != null;
|
|
2370
|
+
const isEndHandleSnapped = lineObject.endAnchor != null;
|
|
2371
|
+
const highlightedSnapCandidate = activeSnapCandidate ?? previewSnapCandidate;
|
|
2372
|
+
const isStartHandleSnapPreview = highlightedSnapCandidate?.endpoint === 'start';
|
|
2373
|
+
const isEndHandleSnapPreview = highlightedSnapCandidate?.endpoint === 'end';
|
|
2374
|
+
const isStartHandleHighlighted = isStartHandleSnapped || isStartHandleSnapPreview;
|
|
2375
|
+
const isEndHandleHighlighted = isEndHandleSnapped || isEndHandleSnapPreview;
|
|
2376
|
+
const selectionOverlayZIndex = this.core.displaySelectionLineUI(object) ? '10000' : (object.zIndex + 1).toString();
|
|
2362
2377
|
const handleScale = object.scale ?? 1;
|
|
2363
2378
|
const { canRenderResizeHandles, canRenderRotationHandle } = this.getSelectionHandleCapabilities(object);
|
|
2364
2379
|
return (h("svg", { xmlns: "http://www.w3.org/2000/svg", style: {
|
|
2365
|
-
zIndex:
|
|
2380
|
+
zIndex: selectionOverlayZIndex,
|
|
2366
2381
|
height: object?.totalHeight.toString(),
|
|
2367
2382
|
width: object?.totalWidth.toString(),
|
|
2368
2383
|
left: '0',
|
|
@@ -2453,7 +2468,7 @@ export class KritzelEngine {
|
|
|
2453
2468
|
strokeLinecap: 'round',
|
|
2454
2469
|
fill: 'none',
|
|
2455
2470
|
} })), !this.isSelecting && !isRemoteSelection && (h("g", { class: "selection-line-handles", style: { pointerEvents: 'auto' } }, h("circle", { class: "selection-line-handle start", cx: object.startX - object.x, cy: object.startY - object.y, r: `${((baseHandleSize - 1) * object.scale) / this.core.store.state?.scale}`, style: {
|
|
2456
|
-
fill: 'var(--kritzel-selection-handle-color, #000000)',
|
|
2471
|
+
fill: isStartHandleHighlighted ? selectionHandleStrokeColor : 'var(--kritzel-selection-handle-color, #000000)',
|
|
2457
2472
|
stroke: selectionHandleStrokeColor,
|
|
2458
2473
|
strokeWidth: `calc(2px * ${object.scale} / ${this.core.store.state?.scale})`,
|
|
2459
2474
|
paintOrder: 'fill',
|
|
@@ -2477,7 +2492,7 @@ export class KritzelEngine {
|
|
|
2477
2492
|
fill: 'transparent',
|
|
2478
2493
|
paintOrder: 'fill',
|
|
2479
2494
|
} }), h("circle", { class: "selection-line-handle end", cx: object.endX - object.x, cy: object.endY - object.y, r: `${((baseHandleSize - 1) * object.scale) / this.core.store.state?.scale}`, style: {
|
|
2480
|
-
fill: 'var(--kritzel-selection-handle-color, #000000)',
|
|
2495
|
+
fill: isEndHandleHighlighted ? selectionHandleStrokeColor : 'var(--kritzel-selection-handle-color, #000000)',
|
|
2481
2496
|
stroke: selectionHandleStrokeColor,
|
|
2482
2497
|
strokeWidth: `calc(2px * ${object.scale} / ${this.core.store.state?.scale})`,
|
|
2483
2498
|
paintOrder: 'fill',
|
|
@@ -2487,6 +2502,36 @@ export class KritzelEngine {
|
|
|
2487
2502
|
} })))))));
|
|
2488
2503
|
})()));
|
|
2489
2504
|
}), (() => {
|
|
2505
|
+
const data = this.core.anchorManager.getSnapIndicatorRenderData() ?? this.core.anchorManager.getSnapPreviewRenderData();
|
|
2506
|
+
if (!data)
|
|
2507
|
+
return null;
|
|
2508
|
+
const isActiveSnap = this.core.anchorManager.getSnapIndicatorRenderData() != null;
|
|
2509
|
+
return (h("svg", { xmlns: "http://www.w3.org/2000/svg", class: "snap-indicator", style: {
|
|
2510
|
+
position: 'absolute',
|
|
2511
|
+
left: '0',
|
|
2512
|
+
top: '0',
|
|
2513
|
+
width: '1px',
|
|
2514
|
+
height: '1px',
|
|
2515
|
+
pointerEvents: 'none',
|
|
2516
|
+
zIndex: '9999',
|
|
2517
|
+
overflow: 'visible',
|
|
2518
|
+
} }, h("g", null, data.snapLinePath ? (h("path", { d: data.snapLinePath, fill: "none", style: {
|
|
2519
|
+
stroke: isActiveSnap ? 'var(--kritzel-snap-line-stroke, rgba(0, 0, 0, 0.2))' : 'var(--kritzel-snap-line-stroke, rgba(0, 0, 0, 0.12))',
|
|
2520
|
+
strokeWidth: data.lineStrokeWidth,
|
|
2521
|
+
strokeDasharray: data.dashArray,
|
|
2522
|
+
strokeLinecap: 'round',
|
|
2523
|
+
} })) : (data.edgeX !== undefined &&
|
|
2524
|
+
data.edgeY !== undefined && (h("line", { x1: data.edgeX, y1: data.edgeY, x2: data.centerX, y2: data.centerY, style: {
|
|
2525
|
+
stroke: isActiveSnap ? 'var(--kritzel-snap-line-stroke, rgba(0, 0, 0, 0.2))' : 'var(--kritzel-snap-line-stroke, rgba(0, 0, 0, 0.12))',
|
|
2526
|
+
strokeWidth: data.lineStrokeWidth,
|
|
2527
|
+
strokeDasharray: data.dashArray,
|
|
2528
|
+
strokeLinecap: 'round',
|
|
2529
|
+
} }))), h("circle", { cx: data.centerX, cy: data.centerY, r: data.indicatorRadius, style: {
|
|
2530
|
+
fill: isActiveSnap ? 'var(--kritzel-snap-indicator-fill, rgba(59, 130, 246, 0.3))' : 'rgba(59, 130, 246, 0.18)',
|
|
2531
|
+
stroke: isActiveSnap ? 'var(--kritzel-snap-indicator-stroke, #007bff)' : 'rgba(59, 130, 246, 0.5)',
|
|
2532
|
+
strokeWidth: data.indicatorStrokeWidth,
|
|
2533
|
+
} }))));
|
|
2534
|
+
})(), (() => {
|
|
2490
2535
|
const data = this.core.anchorManager.getAnchorLinesRenderData();
|
|
2491
2536
|
if (!data)
|
|
2492
2537
|
return null;
|
|
@@ -2511,7 +2556,7 @@ export class KritzelEngine {
|
|
|
2511
2556
|
strokeDasharray: data.dashArray,
|
|
2512
2557
|
strokeLinecap: 'round',
|
|
2513
2558
|
} })), h("circle", { cx: data.startAnchorViz.centerX, cy: data.startAnchorViz.centerY, r: data.indicatorRadius, style: {
|
|
2514
|
-
fill: 'var(--kritzel-snap-indicator-fill, rgba(
|
|
2559
|
+
fill: 'var(--kritzel-snap-indicator-fill, rgba(59, 130, 246, 0.3))',
|
|
2515
2560
|
stroke: 'var(--kritzel-snap-indicator-stroke, #007bff)',
|
|
2516
2561
|
strokeWidth: data.indicatorStrokeWidth,
|
|
2517
2562
|
} }))), data.endAnchorViz && (h("g", { class: "anchor-line-end" }, data.endAnchorViz.pathD ? (h("path", { d: data.endAnchorViz.pathD, style: {
|
|
@@ -2530,35 +2575,6 @@ export class KritzelEngine {
|
|
|
2530
2575
|
stroke: 'var(--kritzel-snap-indicator-stroke, #007bff)',
|
|
2531
2576
|
strokeWidth: data.indicatorStrokeWidth,
|
|
2532
2577
|
} })))));
|
|
2533
|
-
})(), (() => {
|
|
2534
|
-
const data = this.core.anchorManager.getSnapIndicatorRenderData();
|
|
2535
|
-
if (!data)
|
|
2536
|
-
return null;
|
|
2537
|
-
return (h("svg", { xmlns: "http://www.w3.org/2000/svg", class: "snap-indicator", style: {
|
|
2538
|
-
position: 'absolute',
|
|
2539
|
-
left: '0',
|
|
2540
|
-
top: '0',
|
|
2541
|
-
width: '1px',
|
|
2542
|
-
height: '1px',
|
|
2543
|
-
pointerEvents: 'none',
|
|
2544
|
-
zIndex: '9999',
|
|
2545
|
-
overflow: 'visible',
|
|
2546
|
-
} }, h("g", null, data.snapLinePath ? (h("path", { d: data.snapLinePath, fill: "none", style: {
|
|
2547
|
-
stroke: 'var(--kritzel-snap-line-stroke, rgba(0, 0, 0, 0.2))',
|
|
2548
|
-
strokeWidth: data.lineStrokeWidth,
|
|
2549
|
-
strokeDasharray: data.dashArray,
|
|
2550
|
-
strokeLinecap: 'round',
|
|
2551
|
-
} })) : (data.edgeX !== undefined &&
|
|
2552
|
-
data.edgeY !== undefined && (h("line", { x1: data.edgeX, y1: data.edgeY, x2: data.centerX, y2: data.centerY, style: {
|
|
2553
|
-
stroke: 'var(--kritzel-snap-line-stroke, rgba(0, 0, 0, 0.2))',
|
|
2554
|
-
strokeWidth: data.lineStrokeWidth,
|
|
2555
|
-
strokeDasharray: data.dashArray,
|
|
2556
|
-
strokeLinecap: 'round',
|
|
2557
|
-
} }))), h("circle", { cx: data.centerX, cy: data.centerY, r: data.indicatorRadius, style: {
|
|
2558
|
-
fill: 'var(--kritzel-snap-indicator-fill, rgba(59, 130, 246, 0.3))',
|
|
2559
|
-
stroke: 'var(--kritzel-snap-indicator-stroke, #007bff)',
|
|
2560
|
-
strokeWidth: data.indicatorStrokeWidth,
|
|
2561
|
-
} }))));
|
|
2562
2578
|
})()), this.core.store.state.isContextMenuVisible && (h("kritzel-context-menu", { class: "context-menu", ref: el => (this.contextMenuElement = el ?? null), items: this.core.store.state.contextMenuItems, objects: this.core.store.selectionGroup?.objects || [], style: {
|
|
2563
2579
|
position: 'absolute',
|
|
2564
2580
|
left: `${this.core.store.state.contextMenuX}px`,
|
package/dist/components/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{g as getAssetPath,r as render,s as setAssetPath,a as setNonce,b as setPlatformOptions}from"./p-B43upypT.js";export{K as KritzelBaseObject,b as KritzelLine,a as KritzelPath}from"./p-BNu3Akp5.js";export{A as AssetNotFoundError,I as IndexedDBAssetProvider,g as KritzelAssetResolver,d as KritzelBaseTool,b as KritzelGroup,a as KritzelImage,f as KritzelSelectionTool,c as KritzelShape,K as KritzelText,e as KritzelTextTool,S as ShapeType}from"./p-B5XGjTLd.js";export{A as APP_STATE_MIGRATIONS,D as DE_LOCALE,E as EN_LOCALE,F as FR_LOCALE,k as KritzelAlignment,g as KritzelAnchorManager,a as KritzelBrushTool,f as KritzelCursorHelper,K as KritzelCustomElement,j as KritzelCustomElementRendererRegistry,c as KritzelEraserTool,d as KritzelImageTool,i as KritzelLicenseManager,b as KritzelLineTool,h as KritzelLocalizationManager,e as KritzelShapeTool,W as WORKSPACE_MIGRATIONS,r as runMigrations}from"./p-on11Z8cZ.js";import*as t from"yjs";import{IndexeddbPersistence as n}from"y-indexeddb";import{WebsocketProvider as o}from"y-websocket";import{H as m,a as u}from"./kritzel-editor.js";export{d as DEFAULT_ASSET_STORAGE_CONFIG,D as DEFAULT_BRUSH_CONFIG,c as DEFAULT_LINE_TOOL_CONFIG,b as DEFAULT_TEXT_CONFIG,KritzelEditor,defineCustomElement as defineCustomElementKritzelEditor}from"./kritzel-editor.js";export{K as KritzelWorkspace,W as WORKSPACE_EXPORT_VERSION}from"./p-DhMlShij.js";export{K as KritzelThemeManager,d as darkTheme,l as lightTheme}from"./p-CpzicliK.js";export{C as CURRENT_APP_STATE_SCHEMA_VERSION,a as CURRENT_WORKSPACE_SCHEMA_VERSION}from"./p-CW-VyJgK.js";export{KritzelActiveUsers,defineCustomElement as defineCustomElementKritzelActiveUsers}from"./kritzel-active-users.js";export{KritzelAvatar,defineCustomElement as defineCustomElementKritzelAvatar}from"./kritzel-avatar.js";export{KritzelAwarenessCursors,defineCustomElement as defineCustomElementKritzelAwarenessCursors}from"./kritzel-awareness-cursors.js";export{KritzelBackToContent,defineCustomElement as defineCustomElementKritzelBackToContent}from"./kritzel-back-to-content.js";export{KritzelBrushStyle,defineCustomElement as defineCustomElementKritzelBrushStyle}from"./kritzel-brush-style.js";export{KritzelButton,defineCustomElement as defineCustomElementKritzelButton}from"./kritzel-button.js";export{KritzelColor,defineCustomElement as defineCustomElementKritzelColor}from"./kritzel-color.js";export{KritzelColorPalette,defineCustomElement as defineCustomElementKritzelColorPalette}from"./kritzel-color-palette.js";export{KritzelContextMenu,defineCustomElement as defineCustomElementKritzelContextMenu}from"./kritzel-context-menu.js";export{KritzelControls,defineCustomElement as defineCustomElementKritzelControls}from"./kritzel-controls.js";export{KritzelCurrentUser,defineCustomElement as defineCustomElementKritzelCurrentUser}from"./kritzel-current-user.js";export{KritzelCurrentUserDialog,defineCustomElement as defineCustomElementKritzelCurrentUserDialog}from"./kritzel-current-user-dialog.js";export{KritzelCursorTrail,defineCustomElement as defineCustomElementKritzelCursorTrail}from"./kritzel-cursor-trail.js";export{KritzelDialog,defineCustomElement as defineCustomElementKritzelDialog}from"./kritzel-dialog.js";export{KritzelDropdown,defineCustomElement as defineCustomElementKritzelDropdown}from"./kritzel-dropdown.js";export{KritzelEngine,defineCustomElement as defineCustomElementKritzelEngine}from"./kritzel-engine.js";export{KritzelExport,defineCustomElement as defineCustomElementKritzelExport}from"./kritzel-export.js";export{KritzelFont,defineCustomElement as defineCustomElementKritzelFont}from"./kritzel-font.js";export{KritzelFontFamily,defineCustomElement as defineCustomElementKritzelFontFamily}from"./kritzel-font-family.js";export{KritzelFontSize,defineCustomElement as defineCustomElementKritzelFontSize}from"./kritzel-font-size.js";export{KritzelIcon,defineCustomElement as defineCustomElementKritzelIcon}from"./kritzel-icon.js";export{KritzelInput,defineCustomElement as defineCustomElementKritzelInput}from"./kritzel-input.js";export{KritzelLineEndings,defineCustomElement as defineCustomElementKritzelLineEndings}from"./kritzel-line-endings.js";export{KritzelLoginDialog,defineCustomElement as defineCustomElementKritzelLoginDialog}from"./kritzel-login-dialog.js";export{KritzelMasterDetail,defineCustomElement as defineCustomElementKritzelMasterDetail}from"./kritzel-master-detail.js";export{KritzelMenu,defineCustomElement as defineCustomElementKritzelMenu}from"./kritzel-menu.js";export{KritzelMenuItem,defineCustomElement as defineCustomElementKritzelMenuItem}from"./kritzel-menu-item.js";export{KritzelMoreMenu,defineCustomElement as defineCustomElementKritzelMoreMenu}from"./kritzel-more-menu.js";export{KritzelNotificationCard,defineCustomElement as defineCustomElementKritzelNotificationCard}from"./kritzel-notification-card.js";export{KritzelNumericInput,defineCustomElement as defineCustomElementKritzelNumericInput}from"./kritzel-numeric-input.js";export{KritzelOpacitySlider,defineCustomElement as defineCustomElementKritzelOpacitySlider}from"./kritzel-opacity-slider.js";export{KritzelPillTabs,defineCustomElement as defineCustomElementKritzelPillTabs}from"./kritzel-pill-tabs.js";export{KritzelPortal,defineCustomElement as defineCustomElementKritzelPortal}from"./kritzel-portal.js";export{KritzelSettings,defineCustomElement as defineCustomElementKritzelSettings}from"./kritzel-settings.js";export{KritzelShapeFill,defineCustomElement as defineCustomElementKritzelShapeFill}from"./kritzel-shape-fill.js";export{KritzelShareDialog,defineCustomElement as defineCustomElementKritzelShareDialog}from"./kritzel-share-dialog.js";export{KritzelSlideToggle,defineCustomElement as defineCustomElementKritzelSlideToggle}from"./kritzel-slide-toggle.js";export{KritzelSplitButton,defineCustomElement as defineCustomElementKritzelSplitButton}from"./kritzel-split-button.js";export{KritzelStrokeSize,defineCustomElement as defineCustomElementKritzelStrokeSize}from"./kritzel-stroke-size.js";export{KritzelToolConfig,defineCustomElement as defineCustomElementKritzelToolConfig}from"./kritzel-tool-config.js";export{KritzelTooltip,defineCustomElement as defineCustomElementKritzelTooltip}from"./kritzel-tooltip.js";export{KritzelUtilityPanel,defineCustomElement as defineCustomElementKritzelUtilityPanel}from"./kritzel-utility-panel.js";export{KritzelWatermark,defineCustomElement as defineCustomElementKritzelWatermark}from"./kritzel-watermark.js";export{KritzelWorkspaceManager,defineCustomElement as defineCustomElementKritzelWorkspaceManager}from"./kritzel-workspace-manager.js";export{KritzelZoomPanel,defineCustomElement as defineCustomElementKritzelZoomPanel}from"./kritzel-zoom-panel.js";const z=Math.floor,p=127,y=Number.MAX_SAFE_INTEGER;class w{constructor(){this.cpos=0,this.cbuf=new Uint8Array(100),this.bufs=[]}}const x=()=>new w,T=e=>{const t=new Uint8Array((e=>{let t=e.cpos;for(let s=0;s<e.bufs.length;s++)t+=e.bufs[s].length;return t})(e));let s=0;for(let i=0;i<e.bufs.length;i++){const n=e.bufs[i];t.set(n,s),s+=n.length}return t.set(new Uint8Array(e.cbuf.buffer,0,e.cpos),s),t},P=(e,t)=>{const s=e.cbuf.length;e.cpos===s&&(e.bufs.push(e.cbuf),e.cbuf=new Uint8Array(2*s),e.cpos=0),e.cbuf[e.cpos++]=t},v=(e,t)=>{for(;t>p;)P(e,128|p&t),t=z(t/128);P(e,p&t)},M=(e,t)=>{v(e,t.byteLength),((e,t)=>{const s=e.cbuf.length,i=e.cpos,n=((e,t)=>e<t?e:t)(s-i,t.length),o=t.length-n;e.cbuf.set(t.subarray(0,n),i),e.cpos+=n,o>0&&(e.bufs.push(e.cbuf),e.cbuf=new Uint8Array(((e,t)=>e>t?e:t)(2*s,o)),e.cbuf.set(t.subarray(n)),e.cpos=o)})(e,t)},U=e=>Error(e),_=U("Unexpected end of array"),O=U("Integer out of Range");class L{constructor(e){this.arr=e,this.pos=0}}const R=e=>((e,t)=>{const s=new Uint8Array(e.arr.buffer,e.pos+e.arr.byteOffset,t);return e.pos+=t,s})(e,$(e)),$=e=>{let t=0,s=1;const i=e.arr.length;for(;e.pos<i;){const i=e.arr[e.pos++];if(t+=(i&p)*s,s*=128,i<128)return t;if(t>y)throw O}throw _};class B{type="local";doc;channel;_synced=!1;constructor(e,t,s){this.doc=t,this.channel=new BroadcastChannel(e),this.channel.onmessage=e=>{this.handleMessage(e.data)},this.doc.on("update",this.handleDocUpdate),this.broadcastSync(),setTimeout((()=>{this._synced=!0}),100),s?.quiet||console.info("BroadcastChannel Provider initialized: "+e)}handleDocUpdate=(e,t)=>{if(t!==this){const t=x();v(t,0),M(t,e),this.channel.postMessage(T(t))}};handleMessage(e){const s=(e=>new L(e))(new Uint8Array(e));switch($(s)){case 0:const e=R(s);t.applyUpdate(this.doc,e,this);break;case 1:this.broadcastSync();break;case 2:const i=R(s),n=t.encodeStateAsUpdate(this.doc,i);if(n.length>0){const e=x();v(e,0),M(e,n),this.channel.postMessage(T(e))}}}broadcastSync(){const e=x();v(e,2),M(e,t.encodeStateVector(this.doc)),this.channel.postMessage(T(e))}async connect(){if(!this._synced)return new Promise((e=>{const t=()=>{this._synced?e():setTimeout(t,50)};t()}))}disconnect(){}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.doc.off("update",this.handleDocUpdate),this.channel.close()}}const N=new Map;class H{type="local";doc;cacheKey;isConnected=!1;constructor(e,t,s){this.doc=t,this.cacheKey=s?.name??e}handleUpdate=(e,s)=>{s!==this&&N.set(this.cacheKey,t.encodeStateAsUpdate(this.doc))};async connect(){if(this.isConnected)return;const e=N.get(this.cacheKey);e&&t.applyUpdate(this.doc,e,this),this.doc.on("update",this.handleUpdate),this.isConnected=!0}disconnect(){this.isConnected=!1}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.doc.off("update",this.handleUpdate),this.isConnected=!1}static clear(e){void 0!==e?N.delete(e):N.clear()}}class G{type="local";provider;isConnected=!1;constructor(e,t,s){this.provider=new n(s?.name||e,t)}async connect(){if(!this.isConnected)return new Promise((e=>{this.provider.on("synced",(()=>{this.isConnected=!0,e()}))}))}disconnect(){this.isConnected=!1}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.provider&&this.provider.destroy(),this.isConnected=!1}}class V{type="network";provider;isConnected=!1;_quiet=!1;get awareness(){return this.provider.awareness}constructor(e,t,s){const i=s?.url||"ws://localhost:1234",n=s?.roomName||e;this.provider=new o(i,n,t,{params:s?.params,protocols:s?.protocols,WebSocketPolyfill:s?.WebSocketPolyfill,awareness:s?.awareness,maxBackoffTime:s?.maxBackoffTime,disableBc:!0}),this._quiet=s?.quiet??!1,this.setupEventListeners(),this._quiet||console.info(`WebSocket Provider initialized: ${i}/${n}`)}static with(e){return{create:(t,s,i)=>{const n=i?{...e,...i}:e;return new V(t,s,n)}}}setupEventListeners(){this.provider.on("status",(({status:e})=>{"connected"===e?(this.isConnected=!0,this._quiet||console.info("WebSocket connected")):"disconnected"===e&&(this.isConnected=!1,this._quiet||console.info("WebSocket disconnected"))})),this.provider.on("sync",(e=>{e&&!this._quiet&&console.info("WebSocket synced")}))}async connect(){if(!this.isConnected)return new Promise(((e,t)=>{const s=setTimeout((()=>{t(Error("WebSocket connection timeout"))}),1e4),i=({status:t})=>{"connected"===t&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,e())};this.provider.on("status",i),this.provider.wsconnected&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,e())}))}disconnect(){this.provider&&this.provider.disconnect(),this.isConnected=!1}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.provider&&this.provider.destroy(),this.isConnected=!1}}class Z{type="network";provider;isConnected=!1;isSynced=!1;usesSharedSocket=!1;isDestroyed=!1;connectTimeout=null;pendingConnectReject=null;connectionTimeoutMs;_connectionStatus="disconnected";visibilityHandler=null;onlineHandler=null;get awareness(){return this.provider.awareness}get connectionStatus(){return this._connectionStatus}static sharedWebSocketProvider=null;constructor(e,t,s){const i=s?.name||e,n=s?.url||"ws://localhost:1234";this.connectionTimeoutMs=s?.connectionTimeout??1e4;const o=s?.websocketProvider||Z.sharedWebSocketProvider,r={};void 0!==s?.delay&&(r.delay=s.delay),void 0!==s?.factor&&(r.factor=s.factor),void 0!==s?.maxAttempts&&(r.maxAttempts=s.maxAttempts),void 0!==s?.minDelay&&(r.minDelay=s.minDelay),void 0!==s?.maxDelay&&(r.maxDelay=s.maxDelay);const l=()=>{this.isDestroyed||(this.isConnected=!0,this._connectionStatus="connected",s?.quiet||console.info("Hocuspocus connected: "+i),s?.onConnect&&s.onConnect())},a=()=>{this.isDestroyed||(this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected",s?.quiet||console.info("Hocuspocus disconnected: "+i),s?.onDisconnect&&s.onDisconnect())},c=()=>{this.isDestroyed||(this.isSynced=!0,this._connectionStatus="synced",s?.quiet||console.info("Hocuspocus synced: "+i),s?.onSynced&&s.onSynced())},d=e=>{this.isDestroyed||("connecting"===e.status&&(this._connectionStatus="connecting"),s?.onStatus&&s.onStatus(e))};if(o){this.usesSharedSocket=!0;const e={websocketProvider:o,name:i,document:t,token:s?.token||null,onStatus:d,onConnect:l,onDisconnect:a,onSynced:c,...r};void 0!==s?.forceSyncInterval&&(e.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(e.onAuthenticationFailed=s.onAuthenticationFailed),this.provider=new m(e),this.provider.attach(),s?.quiet||console.info("Hocuspocus Provider initialized (multiplexed): "+i)}else{this.usesSharedSocket=!1;const e={url:n,name:i,document:t,token:s?.token||null,autoConnect:!1,onStatus:d,onConnect:l,onDisconnect:a,onSynced:c,...r};void 0!==s?.forceSyncInterval&&(e.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(e.onAuthenticationFailed=s.onAuthenticationFailed),s?.WebSocketPolyfill&&(e.WebSocketPolyfill=s.WebSocketPolyfill),this.provider=new m(e),s?.quiet||console.info(`Hocuspocus Provider initialized: ${n}/${i}`)}this.setupBrowserEventListeners()}setupBrowserEventListeners(){"undefined"!=typeof document&&(this.visibilityHandler=()=>{"visible"!==document.visibilityState||this.isConnected||this.isDestroyed||this.provider.connect()},document.addEventListener("visibilitychange",this.visibilityHandler)),"undefined"!=typeof window&&(this.onlineHandler=()=>{this.isConnected||this.isDestroyed||this.provider.connect()},window.addEventListener("online",this.onlineHandler))}removeBrowserEventListeners(){this.visibilityHandler&&"undefined"!=typeof document&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null),this.onlineHandler&&"undefined"!=typeof window&&(window.removeEventListener("online",this.onlineHandler),this.onlineHandler=null)}static createSharedWebSocket(e){if(Z.sharedWebSocketProvider)return console.warn("Shared WebSocket already exists. Returning existing instance."),Z.sharedWebSocketProvider;const t={url:e.url};return e.WebSocketPolyfill&&(t.WebSocketPolyfill=e.WebSocketPolyfill),e.onConnect&&(t.onConnect=e.onConnect),e.onDisconnect&&(t.onDisconnect=e.onDisconnect),e.onStatus&&(t.onStatus=e.onStatus),Z.sharedWebSocketProvider=new u(t),console.info("Shared Hocuspocus WebSocket created: "+e.url),Z.sharedWebSocketProvider}static destroySharedWebSocket(){Z.sharedWebSocketProvider&&(Z.sharedWebSocketProvider.destroy(),Z.sharedWebSocketProvider=null,console.info("Shared Hocuspocus WebSocket destroyed"))}static getSharedWebSocket(){return Z.sharedWebSocketProvider}static with(e){return{create:(t,s,i)=>{const n=i?{...e,...i}:e;return new Z(t,s,n)}}}async connect(){if(!this.isSynced&&!this.isDestroyed)return this._connectionStatus="connecting",new Promise(((e,t)=>{this.pendingConnectReject=t,this.connectTimeout=setTimeout((()=>{this.pendingConnectReject=null,this.connectTimeout=null,t(Error("Hocuspocus connection timeout"))}),this.connectionTimeoutMs);const s=()=>{this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject=null,this.provider.off("synced",s),this.isDestroyed||e()};if(this.provider.on("synced",s),this.provider.isSynced)return this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject=null,this.provider.off("synced",s),void e();this.isConnected||this.usesSharedSocket||this.provider.connect()}))}async reconnect(){return this.disconnect(),this.connect()}disconnect(){this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject&&(this.pendingConnectReject=null),this.provider&&(this.usesSharedSocket?this.provider.detach():this.provider.disconnect()),this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected"}destroy(){this.isDestroyed=!0,this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject&&(this.pendingConnectReject=null),this.removeBrowserEventListeners(),this.provider&&this.provider.destroy(),this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected"}}class X{type="remote";name="HttpAssetProvider";_options;constructor(e){this._options=e}static with(e){return{create:()=>new X(e)}}async init(){this._options.quiet||console.info("HttpAssetProvider initialized")}destroy(){}canResolve(e){return!0}async put(e,t){const s=t.id??this.generateUuid(),i={...t,id:s},n=await(this._options.headers?.())??{},o=await this._options.uploadUrl(i),r=this._options.upload??this.defaultUpload;return{id:(await r(o,e,i,n)).id??s,kind:t.kind??"file",mimeType:t.mimeType,size:e.size,createdAt:Date.now(),width:t.width,height:t.height,durationMs:t.durationMs,originalFilename:t.originalFilename}}async resolve(e){return this._options.resolveUrl(e)}async fetch(e){const t=await this._options.resolveUrl(e),s=await(this._options.headers?.())??{},i=await fetch(t,{headers:s});if(!i.ok)throw Error(`[HttpAssetProvider] Failed to fetch asset ${e}: ${i.status} ${i.statusText}`);return i.blob()}async delete(e){if(!this._options.deleteUrl)return;const t=await this._options.deleteUrl(e),s=await(this._options.headers?.())??{},i=await fetch(t,{method:"DELETE",headers:s});if(!i.ok)throw Error(`[HttpAssetProvider] Failed to delete asset ${e}: ${i.status} ${i.statusText}`);this._options.quiet||console.info("HttpAssetProvider: deleted asset "+e)}defaultUpload=async(e,t,s,i)=>{const n=new FormData;n.append("metadata",JSON.stringify(s)),n.append("file",t,s.originalFilename||`${s.id}.${this.extensionFromMime(s.mimeType)}`);const o=await fetch(e,{method:"POST",headers:i,body:n});if(!o.ok)throw Error(`[HttpAssetProvider] Upload failed: ${o.status} ${o.statusText}`);return(o.headers.get("content-type")||"").includes("application/json")?await o.json():{}};extensionFromMime(e){const t=e.indexOf("/");return t>=0?e.slice(t+1):"bin"}generateUuid(){if("undefined"!=typeof crypto&&"function"==typeof crypto.randomUUID)return crypto.randomUUID();const e=crypto.getRandomValues(new Uint8Array(16));e[6]=15&e[6]|64,e[8]=63&e[8]|128;const t=Array.from(e,(e=>e.toString(16).padStart(2,"0"))).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}}class J{type="remote";name="PresignedAssetProvider";_options;constructor(e){this._options=e}static with(e){return{create:()=>new J(e)}}async init(){this._options.quiet||console.info("PresignedAssetProvider initialized")}destroy(){}canResolve(e){return!0}async put(e,t){const s=await this._options.getUploadDescriptor(t),i=s.method??"PUT",n={...s.headers??{}};let o;if(n["Content-Type"]||n["content-type"]||(n["Content-Type"]=t.mimeType),"POST"===i&&s.fields){const t=new FormData;for(const[e,i]of Object.entries(s.fields))t.append(e,i);t.append("file",e),o=t,delete n["Content-Type"],delete n["content-type"]}else o=e;const r=await fetch(s.url,{method:i,headers:n,body:o});if(!r.ok)throw Error(`[PresignedAssetProvider] Upload failed: ${r.status} ${r.statusText}`);return{id:s.id,kind:t.kind??"file",mimeType:t.mimeType,size:e.size,createdAt:Date.now(),width:t.width,height:t.height,durationMs:t.durationMs,originalFilename:t.originalFilename}}async resolve(e){return this._options.getDownloadUrl(e)}async fetch(e){const t=await this._options.getDownloadUrl(e),s=await fetch(t);if(!s.ok)throw Error(`[PresignedAssetProvider] Failed to fetch asset ${e}: ${s.status} ${s.statusText}`);return s.blob()}async delete(e){this._options.deleteAsset&&(await this._options.deleteAsset(e),this._options.quiet||console.info("PresignedAssetProvider: deleted asset "+e))}}export{B as BroadcastSyncProvider,Z as HocuspocusSyncProvider,X as HttpAssetProvider,H as InMemorySyncProvider,G as IndexedDBSyncProvider,J as PresignedAssetProvider,V as WebSocketSyncProvider}
|
|
1
|
+
export{g as getAssetPath,r as render,s as setAssetPath,a as setNonce,b as setPlatformOptions}from"./p-B43upypT.js";export{K as KritzelBaseObject,b as KritzelLine,a as KritzelPath}from"./p-BNu3Akp5.js";export{A as AssetNotFoundError,I as IndexedDBAssetProvider,g as KritzelAssetResolver,d as KritzelBaseTool,b as KritzelGroup,a as KritzelImage,f as KritzelSelectionTool,c as KritzelShape,K as KritzelText,e as KritzelTextTool,S as ShapeType}from"./p-DRncK1E6.js";export{A as APP_STATE_MIGRATIONS,D as DE_LOCALE,E as EN_LOCALE,F as FR_LOCALE,k as KritzelAlignment,g as KritzelAnchorManager,a as KritzelBrushTool,f as KritzelCursorHelper,K as KritzelCustomElement,j as KritzelCustomElementRendererRegistry,c as KritzelEraserTool,d as KritzelImageTool,i as KritzelLicenseManager,b as KritzelLineTool,h as KritzelLocalizationManager,e as KritzelShapeTool,W as WORKSPACE_MIGRATIONS,r as runMigrations}from"./p-B0VgBZUT.js";import*as t from"yjs";import{IndexeddbPersistence as n}from"y-indexeddb";import{WebsocketProvider as o}from"y-websocket";import{H as m,a as u}from"./kritzel-editor.js";export{d as DEFAULT_ASSET_STORAGE_CONFIG,D as DEFAULT_BRUSH_CONFIG,c as DEFAULT_LINE_TOOL_CONFIG,b as DEFAULT_TEXT_CONFIG,KritzelEditor,defineCustomElement as defineCustomElementKritzelEditor}from"./kritzel-editor.js";export{K as KritzelWorkspace,W as WORKSPACE_EXPORT_VERSION}from"./p-DhMlShij.js";export{K as KritzelThemeManager,d as darkTheme,l as lightTheme}from"./p-CpzicliK.js";export{C as CURRENT_APP_STATE_SCHEMA_VERSION,a as CURRENT_WORKSPACE_SCHEMA_VERSION}from"./p-CW-VyJgK.js";export{KritzelActiveUsers,defineCustomElement as defineCustomElementKritzelActiveUsers}from"./kritzel-active-users.js";export{KritzelAvatar,defineCustomElement as defineCustomElementKritzelAvatar}from"./kritzel-avatar.js";export{KritzelAwarenessCursors,defineCustomElement as defineCustomElementKritzelAwarenessCursors}from"./kritzel-awareness-cursors.js";export{KritzelBackToContent,defineCustomElement as defineCustomElementKritzelBackToContent}from"./kritzel-back-to-content.js";export{KritzelBrushStyle,defineCustomElement as defineCustomElementKritzelBrushStyle}from"./kritzel-brush-style.js";export{KritzelButton,defineCustomElement as defineCustomElementKritzelButton}from"./kritzel-button.js";export{KritzelColor,defineCustomElement as defineCustomElementKritzelColor}from"./kritzel-color.js";export{KritzelColorPalette,defineCustomElement as defineCustomElementKritzelColorPalette}from"./kritzel-color-palette.js";export{KritzelContextMenu,defineCustomElement as defineCustomElementKritzelContextMenu}from"./kritzel-context-menu.js";export{KritzelControls,defineCustomElement as defineCustomElementKritzelControls}from"./kritzel-controls.js";export{KritzelCurrentUser,defineCustomElement as defineCustomElementKritzelCurrentUser}from"./kritzel-current-user.js";export{KritzelCurrentUserDialog,defineCustomElement as defineCustomElementKritzelCurrentUserDialog}from"./kritzel-current-user-dialog.js";export{KritzelCursorTrail,defineCustomElement as defineCustomElementKritzelCursorTrail}from"./kritzel-cursor-trail.js";export{KritzelDialog,defineCustomElement as defineCustomElementKritzelDialog}from"./kritzel-dialog.js";export{KritzelDropdown,defineCustomElement as defineCustomElementKritzelDropdown}from"./kritzel-dropdown.js";export{KritzelEngine,defineCustomElement as defineCustomElementKritzelEngine}from"./kritzel-engine.js";export{KritzelExport,defineCustomElement as defineCustomElementKritzelExport}from"./kritzel-export.js";export{KritzelFont,defineCustomElement as defineCustomElementKritzelFont}from"./kritzel-font.js";export{KritzelFontFamily,defineCustomElement as defineCustomElementKritzelFontFamily}from"./kritzel-font-family.js";export{KritzelFontSize,defineCustomElement as defineCustomElementKritzelFontSize}from"./kritzel-font-size.js";export{KritzelIcon,defineCustomElement as defineCustomElementKritzelIcon}from"./kritzel-icon.js";export{KritzelInput,defineCustomElement as defineCustomElementKritzelInput}from"./kritzel-input.js";export{KritzelLineEndings,defineCustomElement as defineCustomElementKritzelLineEndings}from"./kritzel-line-endings.js";export{KritzelLoginDialog,defineCustomElement as defineCustomElementKritzelLoginDialog}from"./kritzel-login-dialog.js";export{KritzelMasterDetail,defineCustomElement as defineCustomElementKritzelMasterDetail}from"./kritzel-master-detail.js";export{KritzelMenu,defineCustomElement as defineCustomElementKritzelMenu}from"./kritzel-menu.js";export{KritzelMenuItem,defineCustomElement as defineCustomElementKritzelMenuItem}from"./kritzel-menu-item.js";export{KritzelMoreMenu,defineCustomElement as defineCustomElementKritzelMoreMenu}from"./kritzel-more-menu.js";export{KritzelNotificationCard,defineCustomElement as defineCustomElementKritzelNotificationCard}from"./kritzel-notification-card.js";export{KritzelNumericInput,defineCustomElement as defineCustomElementKritzelNumericInput}from"./kritzel-numeric-input.js";export{KritzelOpacitySlider,defineCustomElement as defineCustomElementKritzelOpacitySlider}from"./kritzel-opacity-slider.js";export{KritzelPillTabs,defineCustomElement as defineCustomElementKritzelPillTabs}from"./kritzel-pill-tabs.js";export{KritzelPortal,defineCustomElement as defineCustomElementKritzelPortal}from"./kritzel-portal.js";export{KritzelSettings,defineCustomElement as defineCustomElementKritzelSettings}from"./kritzel-settings.js";export{KritzelShapeFill,defineCustomElement as defineCustomElementKritzelShapeFill}from"./kritzel-shape-fill.js";export{KritzelShareDialog,defineCustomElement as defineCustomElementKritzelShareDialog}from"./kritzel-share-dialog.js";export{KritzelSlideToggle,defineCustomElement as defineCustomElementKritzelSlideToggle}from"./kritzel-slide-toggle.js";export{KritzelSplitButton,defineCustomElement as defineCustomElementKritzelSplitButton}from"./kritzel-split-button.js";export{KritzelStrokeSize,defineCustomElement as defineCustomElementKritzelStrokeSize}from"./kritzel-stroke-size.js";export{KritzelToolConfig,defineCustomElement as defineCustomElementKritzelToolConfig}from"./kritzel-tool-config.js";export{KritzelTooltip,defineCustomElement as defineCustomElementKritzelTooltip}from"./kritzel-tooltip.js";export{KritzelUtilityPanel,defineCustomElement as defineCustomElementKritzelUtilityPanel}from"./kritzel-utility-panel.js";export{KritzelWatermark,defineCustomElement as defineCustomElementKritzelWatermark}from"./kritzel-watermark.js";export{KritzelWorkspaceManager,defineCustomElement as defineCustomElementKritzelWorkspaceManager}from"./kritzel-workspace-manager.js";export{KritzelZoomPanel,defineCustomElement as defineCustomElementKritzelZoomPanel}from"./kritzel-zoom-panel.js";const z=Math.floor,p=127,y=Number.MAX_SAFE_INTEGER;class w{constructor(){this.cpos=0,this.cbuf=new Uint8Array(100),this.bufs=[]}}const x=()=>new w,T=e=>{const t=new Uint8Array((e=>{let t=e.cpos;for(let s=0;s<e.bufs.length;s++)t+=e.bufs[s].length;return t})(e));let s=0;for(let i=0;i<e.bufs.length;i++){const n=e.bufs[i];t.set(n,s),s+=n.length}return t.set(new Uint8Array(e.cbuf.buffer,0,e.cpos),s),t},P=(e,t)=>{const s=e.cbuf.length;e.cpos===s&&(e.bufs.push(e.cbuf),e.cbuf=new Uint8Array(2*s),e.cpos=0),e.cbuf[e.cpos++]=t},v=(e,t)=>{for(;t>p;)P(e,128|p&t),t=z(t/128);P(e,p&t)},U=(e,t)=>{v(e,t.byteLength),((e,t)=>{const s=e.cbuf.length,i=e.cpos,n=((e,t)=>e<t?e:t)(s-i,t.length),o=t.length-n;e.cbuf.set(t.subarray(0,n),i),e.cpos+=n,o>0&&(e.bufs.push(e.cbuf),e.cbuf=new Uint8Array(((e,t)=>e>t?e:t)(2*s,o)),e.cbuf.set(t.subarray(n)),e.cpos=o)})(e,t)},M=e=>Error(e),_=M("Unexpected end of array"),O=M("Integer out of Range");class R{constructor(e){this.arr=e,this.pos=0}}const L=e=>((e,t)=>{const s=new Uint8Array(e.arr.buffer,e.pos+e.arr.byteOffset,t);return e.pos+=t,s})(e,$(e)),$=e=>{let t=0,s=1;const i=e.arr.length;for(;e.pos<i;){const i=e.arr[e.pos++];if(t+=(i&p)*s,s*=128,i<128)return t;if(t>y)throw O}throw _};class B{type="local";doc;channel;_synced=!1;constructor(e,t,s){this.doc=t,this.channel=new BroadcastChannel(e),this.channel.onmessage=e=>{this.handleMessage(e.data)},this.doc.on("update",this.handleDocUpdate),this.broadcastSync(),setTimeout((()=>{this._synced=!0}),100),s?.quiet||console.info("BroadcastChannel Provider initialized: "+e)}handleDocUpdate=(e,t)=>{if(t!==this){const t=x();v(t,0),U(t,e),this.channel.postMessage(T(t))}};handleMessage(e){const s=(e=>new R(e))(new Uint8Array(e));switch($(s)){case 0:const e=L(s);t.applyUpdate(this.doc,e,this);break;case 1:this.broadcastSync();break;case 2:const i=L(s),n=t.encodeStateAsUpdate(this.doc,i);if(n.length>0){const e=x();v(e,0),U(e,n),this.channel.postMessage(T(e))}}}broadcastSync(){const e=x();v(e,2),U(e,t.encodeStateVector(this.doc)),this.channel.postMessage(T(e))}async connect(){if(!this._synced)return new Promise((e=>{const t=()=>{this._synced?e():setTimeout(t,50)};t()}))}disconnect(){}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.doc.off("update",this.handleDocUpdate),this.channel.close()}}const N=new Map;class H{type="local";doc;cacheKey;isConnected=!1;constructor(e,t,s){this.doc=t,this.cacheKey=s?.name??e}handleUpdate=(e,s)=>{s!==this&&N.set(this.cacheKey,t.encodeStateAsUpdate(this.doc))};async connect(){if(this.isConnected)return;const e=N.get(this.cacheKey);e&&t.applyUpdate(this.doc,e,this),this.doc.on("update",this.handleUpdate),this.isConnected=!0}disconnect(){this.isConnected=!1}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.doc.off("update",this.handleUpdate),this.isConnected=!1}static clear(e){void 0!==e?N.delete(e):N.clear()}}class G{type="local";provider;isConnected=!1;constructor(e,t,s){this.provider=new n(s?.name||e,t)}async connect(){if(!this.isConnected)return new Promise((e=>{this.provider.on("synced",(()=>{this.isConnected=!0,e()}))}))}disconnect(){this.isConnected=!1}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.provider&&this.provider.destroy(),this.isConnected=!1}}class V{type="network";provider;isConnected=!1;_quiet=!1;get awareness(){return this.provider.awareness}constructor(e,t,s){const i=s?.url||"ws://localhost:1234",n=s?.roomName||e;this.provider=new o(i,n,t,{params:s?.params,protocols:s?.protocols,WebSocketPolyfill:s?.WebSocketPolyfill,awareness:s?.awareness,maxBackoffTime:s?.maxBackoffTime,disableBc:!0}),this._quiet=s?.quiet??!1,this.setupEventListeners(),this._quiet||console.info(`WebSocket Provider initialized: ${i}/${n}`)}static with(e){return{create:(t,s,i)=>{const n=i?{...e,...i}:e;return new V(t,s,n)}}}setupEventListeners(){this.provider.on("status",(({status:e})=>{"connected"===e?(this.isConnected=!0,this._quiet||console.info("WebSocket connected")):"disconnected"===e&&(this.isConnected=!1,this._quiet||console.info("WebSocket disconnected"))})),this.provider.on("sync",(e=>{e&&!this._quiet&&console.info("WebSocket synced")}))}async connect(){if(!this.isConnected)return new Promise(((e,t)=>{const s=setTimeout((()=>{t(Error("WebSocket connection timeout"))}),1e4),i=({status:t})=>{"connected"===t&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,e())};this.provider.on("status",i),this.provider.wsconnected&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,e())}))}disconnect(){this.provider&&this.provider.disconnect(),this.isConnected=!1}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.provider&&this.provider.destroy(),this.isConnected=!1}}class Z{type="network";provider;isConnected=!1;isSynced=!1;usesSharedSocket=!1;isDestroyed=!1;connectTimeout=null;pendingConnectReject=null;connectionTimeoutMs;_connectionStatus="disconnected";visibilityHandler=null;onlineHandler=null;get awareness(){return this.provider.awareness}get connectionStatus(){return this._connectionStatus}static sharedWebSocketProvider=null;constructor(e,t,s){const i=s?.name||e,n=s?.url||"ws://localhost:1234";this.connectionTimeoutMs=s?.connectionTimeout??1e4;const o=s?.websocketProvider||Z.sharedWebSocketProvider,r={};void 0!==s?.delay&&(r.delay=s.delay),void 0!==s?.factor&&(r.factor=s.factor),void 0!==s?.maxAttempts&&(r.maxAttempts=s.maxAttempts),void 0!==s?.minDelay&&(r.minDelay=s.minDelay),void 0!==s?.maxDelay&&(r.maxDelay=s.maxDelay);const l=()=>{this.isDestroyed||(this.isConnected=!0,this._connectionStatus="connected",s?.quiet||console.info("Hocuspocus connected: "+i),s?.onConnect&&s.onConnect())},a=()=>{this.isDestroyed||(this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected",s?.quiet||console.info("Hocuspocus disconnected: "+i),s?.onDisconnect&&s.onDisconnect())},c=()=>{this.isDestroyed||(this.isSynced=!0,this._connectionStatus="synced",s?.quiet||console.info("Hocuspocus synced: "+i),s?.onSynced&&s.onSynced())},d=e=>{this.isDestroyed||("connecting"===e.status&&(this._connectionStatus="connecting"),s?.onStatus&&s.onStatus(e))};if(o){this.usesSharedSocket=!0;const e={websocketProvider:o,name:i,document:t,token:s?.token||null,onStatus:d,onConnect:l,onDisconnect:a,onSynced:c,...r};void 0!==s?.forceSyncInterval&&(e.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(e.onAuthenticationFailed=s.onAuthenticationFailed),this.provider=new m(e),this.provider.attach(),s?.quiet||console.info("Hocuspocus Provider initialized (multiplexed): "+i)}else{this.usesSharedSocket=!1;const e={url:n,name:i,document:t,token:s?.token||null,autoConnect:!1,onStatus:d,onConnect:l,onDisconnect:a,onSynced:c,...r};void 0!==s?.forceSyncInterval&&(e.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(e.onAuthenticationFailed=s.onAuthenticationFailed),s?.WebSocketPolyfill&&(e.WebSocketPolyfill=s.WebSocketPolyfill),this.provider=new m(e),s?.quiet||console.info(`Hocuspocus Provider initialized: ${n}/${i}`)}this.setupBrowserEventListeners()}setupBrowserEventListeners(){"undefined"!=typeof document&&(this.visibilityHandler=()=>{"visible"!==document.visibilityState||this.isConnected||this.isDestroyed||this.provider.connect()},document.addEventListener("visibilitychange",this.visibilityHandler)),"undefined"!=typeof window&&(this.onlineHandler=()=>{this.isConnected||this.isDestroyed||this.provider.connect()},window.addEventListener("online",this.onlineHandler))}removeBrowserEventListeners(){this.visibilityHandler&&"undefined"!=typeof document&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null),this.onlineHandler&&"undefined"!=typeof window&&(window.removeEventListener("online",this.onlineHandler),this.onlineHandler=null)}static createSharedWebSocket(e){if(Z.sharedWebSocketProvider)return console.warn("Shared WebSocket already exists. Returning existing instance."),Z.sharedWebSocketProvider;const t={url:e.url};return e.WebSocketPolyfill&&(t.WebSocketPolyfill=e.WebSocketPolyfill),e.onConnect&&(t.onConnect=e.onConnect),e.onDisconnect&&(t.onDisconnect=e.onDisconnect),e.onStatus&&(t.onStatus=e.onStatus),Z.sharedWebSocketProvider=new u(t),console.info("Shared Hocuspocus WebSocket created: "+e.url),Z.sharedWebSocketProvider}static destroySharedWebSocket(){Z.sharedWebSocketProvider&&(Z.sharedWebSocketProvider.destroy(),Z.sharedWebSocketProvider=null,console.info("Shared Hocuspocus WebSocket destroyed"))}static getSharedWebSocket(){return Z.sharedWebSocketProvider}static with(e){return{create:(t,s,i)=>{const n=i?{...e,...i}:e;return new Z(t,s,n)}}}async connect(){if(!this.isSynced&&!this.isDestroyed)return this._connectionStatus="connecting",new Promise(((e,t)=>{this.pendingConnectReject=t,this.connectTimeout=setTimeout((()=>{this.pendingConnectReject=null,this.connectTimeout=null,t(Error("Hocuspocus connection timeout"))}),this.connectionTimeoutMs);const s=()=>{this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject=null,this.provider.off("synced",s),this.isDestroyed||e()};if(this.provider.on("synced",s),this.provider.isSynced)return this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject=null,this.provider.off("synced",s),void e();this.isConnected||this.usesSharedSocket||this.provider.connect()}))}async reconnect(){return this.disconnect(),this.connect()}disconnect(){this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject&&(this.pendingConnectReject=null),this.provider&&(this.usesSharedSocket?this.provider.detach():this.provider.disconnect()),this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected"}destroy(){this.isDestroyed=!0,this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject&&(this.pendingConnectReject=null),this.removeBrowserEventListeners(),this.provider&&this.provider.destroy(),this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected"}}class J{type="remote";name="HttpAssetProvider";_options;constructor(e){this._options=e}static with(e){return{create:()=>new J(e)}}async init(){this._options.quiet||console.info("HttpAssetProvider initialized")}destroy(){}canResolve(e){return!0}async put(e,t){const s=t.id??this.generateUuid(),i={...t,id:s},n=await(this._options.headers?.())??{},o=await this._options.uploadUrl(i),r=this._options.upload??this.defaultUpload;return{id:(await r(o,e,i,n)).id??s,kind:t.kind??"file",mimeType:t.mimeType,size:e.size,createdAt:Date.now(),width:t.width,height:t.height,durationMs:t.durationMs,originalFilename:t.originalFilename}}async resolve(e){return this._options.resolveUrl(e)}async fetch(e){const t=await this._options.resolveUrl(e),s=await(this._options.headers?.())??{},i=await fetch(t,{headers:s});if(!i.ok)throw Error(`[HttpAssetProvider] Failed to fetch asset ${e}: ${i.status} ${i.statusText}`);return i.blob()}async delete(e){if(!this._options.deleteUrl)return;const t=await this._options.deleteUrl(e),s=await(this._options.headers?.())??{},i=await fetch(t,{method:"DELETE",headers:s});if(!i.ok)throw Error(`[HttpAssetProvider] Failed to delete asset ${e}: ${i.status} ${i.statusText}`);this._options.quiet||console.info("HttpAssetProvider: deleted asset "+e)}defaultUpload=async(e,t,s,i)=>{const n=new FormData;n.append("metadata",JSON.stringify(s)),n.append("file",t,s.originalFilename||`${s.id}.${this.extensionFromMime(s.mimeType)}`);const o=await fetch(e,{method:"POST",headers:i,body:n});if(!o.ok)throw Error(`[HttpAssetProvider] Upload failed: ${o.status} ${o.statusText}`);return(o.headers.get("content-type")||"").includes("application/json")?await o.json():{}};extensionFromMime(e){const t=e.indexOf("/");return t>=0?e.slice(t+1):"bin"}generateUuid(){if("undefined"!=typeof crypto&&"function"==typeof crypto.randomUUID)return crypto.randomUUID();const e=crypto.getRandomValues(new Uint8Array(16));e[6]=15&e[6]|64,e[8]=63&e[8]|128;const t=Array.from(e,(e=>e.toString(16).padStart(2,"0"))).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}}class X{type="remote";name="PresignedAssetProvider";_options;constructor(e){this._options=e}static with(e){return{create:()=>new X(e)}}async init(){this._options.quiet||console.info("PresignedAssetProvider initialized")}destroy(){}canResolve(e){return!0}async put(e,t){const s=await this._options.getUploadDescriptor(t),i=s.method??"PUT",n={...s.headers??{}};let o;if(n["Content-Type"]||n["content-type"]||(n["Content-Type"]=t.mimeType),"POST"===i&&s.fields){const t=new FormData;for(const[e,i]of Object.entries(s.fields))t.append(e,i);t.append("file",e),o=t,delete n["Content-Type"],delete n["content-type"]}else o=e;const r=await fetch(s.url,{method:i,headers:n,body:o});if(!r.ok)throw Error(`[PresignedAssetProvider] Upload failed: ${r.status} ${r.statusText}`);return{id:s.id,kind:t.kind??"file",mimeType:t.mimeType,size:e.size,createdAt:Date.now(),width:t.width,height:t.height,durationMs:t.durationMs,originalFilename:t.originalFilename}}async resolve(e){return this._options.getDownloadUrl(e)}async fetch(e){const t=await this._options.getDownloadUrl(e),s=await fetch(t);if(!s.ok)throw Error(`[PresignedAssetProvider] Failed to fetch asset ${e}: ${s.status} ${s.statusText}`);return s.blob()}async delete(e){this._options.deleteAsset&&(await this._options.deleteAsset(e),this._options.quiet||console.info("PresignedAssetProvider: deleted asset "+e))}}export{B as BroadcastSyncProvider,Z as HocuspocusSyncProvider,J as HttpAssetProvider,H as InMemorySyncProvider,G as IndexedDBSyncProvider,X as PresignedAssetProvider,V as WebSocketSyncProvider}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{K as o,d as s}from"./p-
|
|
1
|
+
import{K as o,d as s}from"./p-DKxt_AjI.js";const t=o,p=s;export{t as KritzelControls,p as defineCustomElement}
|