@fmsim/board 2.0.0-beta.8 → 2.0.0-beta.82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/custom-elements.json +6273 -3458
  2. package/demo/index-modeller.html +1 -1
  3. package/demo/index-player.html +2 -2
  4. package/demo/index-viewer.html +2 -2
  5. package/demo/index.html +2 -2
  6. package/dist/src/component/etc.js +35 -0
  7. package/dist/src/component/etc.js.map +1 -1
  8. package/dist/src/component/index.d.ts +1 -0
  9. package/dist/src/component/index.js +1 -0
  10. package/dist/src/component/index.js.map +1 -1
  11. package/dist/src/component/restful-property-editor-backdrop-faces.d.ts +50 -0
  12. package/dist/src/component/restful-property-editor-backdrop-faces.js +524 -0
  13. package/dist/src/component/restful-property-editor-backdrop-faces.js.map +1 -0
  14. package/dist/src/data-storage/board-model-cache.d.ts +13 -0
  15. package/dist/src/data-storage/board-model-cache.js +66 -0
  16. package/dist/src/data-storage/board-model-cache.js.map +1 -0
  17. package/dist/src/index.d.ts +3 -0
  18. package/dist/src/index.js +2 -0
  19. package/dist/src/index.js.map +1 -1
  20. package/dist/src/layers/mcs-mouse-event-handler.js +36 -26
  21. package/dist/src/layers/mcs-mouse-event-handler.js.map +1 -1
  22. package/dist/src/layers/movement-layer.d.ts +4 -4
  23. package/dist/src/layers/movement-layer.js +16 -8
  24. package/dist/src/layers/movement-layer.js.map +1 -1
  25. package/dist/src/modeller/bulk-create-dialog.d.ts +51 -0
  26. package/dist/src/modeller/bulk-create-dialog.js +531 -0
  27. package/dist/src/modeller/bulk-create-dialog.js.map +1 -0
  28. package/dist/src/modeller/bulk-create.d.ts +101 -0
  29. package/dist/src/modeller/bulk-create.js +199 -0
  30. package/dist/src/modeller/bulk-create.js.map +1 -0
  31. package/dist/src/modeller/component-toolbar/component-menu.d.ts +1 -1
  32. package/dist/src/modeller/component-toolbar/component-toolbar.d.ts +1 -1
  33. package/dist/src/modeller/edit-toolbar-style.js +43 -3
  34. package/dist/src/modeller/edit-toolbar-style.js.map +1 -1
  35. package/dist/src/modeller/edit-toolbar.d.ts +13 -0
  36. package/dist/src/modeller/edit-toolbar.js +168 -7
  37. package/dist/src/modeller/edit-toolbar.js.map +1 -1
  38. package/dist/src/modeller/property-sidebar/abstract-property.js +10 -2
  39. package/dist/src/modeller/property-sidebar/abstract-property.js.map +1 -1
  40. package/dist/src/modeller/property-sidebar/data-binding/data-binding.d.ts +1 -1
  41. package/dist/src/modeller/property-sidebar/effects/effects.d.ts +1 -1
  42. package/dist/src/modeller/property-sidebar/effects/property-event.d.ts +1 -1
  43. package/dist/src/modeller/property-sidebar/property-sidebar.d.ts +1 -1
  44. package/dist/src/modeller/property-sidebar/shapes/shapes.js +31 -0
  45. package/dist/src/modeller/property-sidebar/shapes/shapes.js.map +1 -1
  46. package/dist/src/modeller/property-sidebar/specifics/specifics.d.ts +2 -1
  47. package/dist/src/modeller/property-sidebar/specifics/specifics.js +10 -0
  48. package/dist/src/modeller/property-sidebar/specifics/specifics.js.map +1 -1
  49. package/dist/src/modeller/property-sidebar/styles/styles.d.ts +1 -1
  50. package/dist/src/modeller/scene-viewer/ox-scene-layer.d.ts +4 -3
  51. package/dist/src/modeller/scene-viewer/ox-scene-layer.js +2 -1
  52. package/dist/src/modeller/scene-viewer/ox-scene-layer.js.map +1 -1
  53. package/dist/src/modeller/scene-viewer/ox-scene-viewer.d.ts +2 -1
  54. package/dist/src/modeller/scene-viewer/ox-scene-viewer.js +5 -1
  55. package/dist/src/modeller/scene-viewer/ox-scene-viewer.js.map +1 -1
  56. package/dist/src/ox-board-component-info.d.ts +1 -0
  57. package/dist/src/ox-board-component-info.js +5 -1
  58. package/dist/src/ox-board-component-info.js.map +1 -1
  59. package/dist/src/ox-board-list.js +2 -2
  60. package/dist/src/ox-board-list.js.map +1 -1
  61. package/dist/src/ox-board-modeller.d.ts +6 -3
  62. package/dist/src/ox-board-modeller.js +13 -1
  63. package/dist/src/ox-board-modeller.js.map +1 -1
  64. package/dist/src/ox-board-viewer.d.ts +113 -13
  65. package/dist/src/ox-board-viewer.js +753 -98
  66. package/dist/src/ox-board-viewer.js.map +1 -1
  67. package/dist/src/ox-editor-board-selector.d.ts +3 -0
  68. package/dist/src/ox-editor-board-selector.js +38 -9
  69. package/dist/src/ox-editor-board-selector.js.map +1 -1
  70. package/dist/src/ox-playback-controls.d.ts +157 -0
  71. package/dist/src/ox-playback-controls.js +1089 -0
  72. package/dist/src/ox-playback-controls.js.map +1 -0
  73. package/dist/src/playback/carrier-tracking-store.d.ts +51 -0
  74. package/dist/src/playback/carrier-tracking-store.js +115 -0
  75. package/dist/src/playback/carrier-tracking-store.js.map +1 -0
  76. package/dist/src/playback/playback-engine.d.ts +106 -0
  77. package/dist/src/playback/playback-engine.js +395 -0
  78. package/dist/src/playback/playback-engine.js.map +1 -0
  79. package/dist/src/selector/board-creation-popup.js +2 -2
  80. package/dist/src/selector/board-creation-popup.js.map +1 -1
  81. package/dist/src/selector/board-thumbnail-card.js +6 -6
  82. package/dist/src/selector/board-thumbnail-card.js.map +1 -1
  83. package/dist/src/selector/ox-board-creation-card.js +2 -2
  84. package/dist/src/selector/ox-board-creation-card.js.map +1 -1
  85. package/dist/src/selector/ox-board-selector.js +21 -10
  86. package/dist/src/selector/ox-board-selector.js.map +1 -1
  87. package/dist/tsconfig.tsbuildinfo +1 -1
  88. package/icons/components/text.png +0 -0
  89. package/icons/fab/mode-2d.svg +25 -0
  90. package/icons/fab/mode-3d.svg +25 -0
  91. package/icons/fab/playback-play.svg +49 -0
  92. package/icons/fab/playback-stop.svg +50 -0
  93. package/icons/icon-htoolbar.png +0 -0
  94. package/package.json +8 -4
@@ -5,8 +5,54 @@ import { __decorate } from "tslib";
5
5
  import { html, LitElement } from 'lit';
6
6
  import { property, state } from 'lit/decorators.js';
7
7
  import { copyToClipboard, isMacOS } from '@operato/utils';
8
+ import { OxPopup } from '@operato/popup';
8
9
  import { style } from './edit-toolbar-style';
10
+ import './bulk-create-dialog.js';
9
11
  const MACOS = isMacOS();
12
+ /**
13
+ * 컴포넌트 model JSON 만으로 type-aware bounding box (width, height) 추출.
14
+ *
15
+ * things-scene 의 component.bounds 는 *path 의 bounding box* 인데, model JSON 만
16
+ * 으로는 path 를 그릴 수 없으므로 type-specific 필드를 직접 본다.
17
+ * - width/height 명시 (Rect, Container 등) → 그대로
18
+ * - rx/ry (Ellipse 등) → 2*rx, 2*ry
19
+ * - points 배열 (Line, Polygon 등) → 점들의 bounding box
20
+ * - 그 외 → 50x50 fallback
21
+ *
22
+ * bulk-paste 가 영역 안에 N 개 복제할 때 *원본 크기를 보존* 하기 위해 사용.
23
+ */
24
+ function deriveBoundsFromModel(model) {
25
+ if (typeof model.width === 'number' && typeof model.height === 'number') {
26
+ return { width: model.width, height: model.height };
27
+ }
28
+ if (typeof model.rx === 'number' && typeof model.ry === 'number') {
29
+ return { width: 2 * Math.abs(model.rx), height: 2 * Math.abs(model.ry) };
30
+ }
31
+ if (Array.isArray(model.points) && model.points.length > 0) {
32
+ let minX = Infinity;
33
+ let maxX = -Infinity;
34
+ let minY = Infinity;
35
+ let maxY = -Infinity;
36
+ for (const p of model.points) {
37
+ if (typeof (p === null || p === void 0 ? void 0 : p.x) === 'number') {
38
+ if (p.x < minX)
39
+ minX = p.x;
40
+ if (p.x > maxX)
41
+ maxX = p.x;
42
+ }
43
+ if (typeof (p === null || p === void 0 ? void 0 : p.y) === 'number') {
44
+ if (p.y < minY)
45
+ minY = p.y;
46
+ if (p.y > maxY)
47
+ maxY = p.y;
48
+ }
49
+ }
50
+ if (isFinite(minX) && isFinite(maxX) && isFinite(minY) && isFinite(maxY)) {
51
+ return { width: maxX - minX, height: maxY - minY };
52
+ }
53
+ }
54
+ return { width: 50, height: 50 };
55
+ }
10
56
  export class EditToolbar extends LitElement {
11
57
  constructor() {
12
58
  super(...arguments);
@@ -246,7 +292,13 @@ export class EditToolbar extends LitElement {
246
292
  this.onTapCut();
247
293
  break;
248
294
  case 'KeyV':
249
- if (ctrlKey && !shiftKey) {
295
+ if (ctrlKey && shiftKey && !altKey) {
296
+ // Ctrl+Shift+V = Bulk Paste (Paste Special 컨벤션) — 클립보드의
297
+ // 단일 컴포넌트를 N개로 일괄 붙여넣기.
298
+ this.onBulkPaste();
299
+ defaultPrevent = true;
300
+ }
301
+ else if (ctrlKey && !shiftKey) {
250
302
  this.onTapPaste();
251
303
  defaultPrevent = false;
252
304
  }
@@ -266,21 +318,35 @@ export class EditToolbar extends LitElement {
266
318
  this.onTapUngroup();
267
319
  }
268
320
  break;
269
- case 'KeyF':
321
+ case 'BracketRight':
322
+ // Ctrl+] = Bring Forward, Ctrl+Shift+] = Bring to Front
323
+ // (Photoshop / Illustrator 표준 컨벤션)
270
324
  if (this._dimension === '2d') {
271
- if (ctrlKey && !shiftKey)
325
+ if (ctrlKey && !shiftKey) {
272
326
  (_a = this.scene) === null || _a === void 0 ? void 0 : _a.zorder('forward');
273
- else if (ctrlKey && shiftKey)
327
+ defaultPrevent = true;
328
+ }
329
+ else if (ctrlKey && shiftKey) {
274
330
  (_b = this.scene) === null || _b === void 0 ? void 0 : _b.zorder('front');
331
+ defaultPrevent = true;
332
+ }
275
333
  }
276
334
  break;
277
- case 'KeyB':
335
+ case 'BracketLeft':
336
+ // Ctrl+[ = Send Backward, Ctrl+Shift+[ = Send to Back
278
337
  if (this._dimension === '2d') {
279
- if (ctrlKey && !shiftKey)
338
+ if (ctrlKey && !shiftKey) {
280
339
  (_c = this.scene) === null || _c === void 0 ? void 0 : _c.zorder('backward');
281
- else if (ctrlKey && shiftKey)
340
+ defaultPrevent = true;
341
+ }
342
+ else if (ctrlKey && shiftKey) {
282
343
  (_d = this.scene) === null || _d === void 0 ? void 0 : _d.zorder('back');
344
+ defaultPrevent = true;
345
+ }
283
346
  }
347
+ break;
348
+ case 'KeyB':
349
+ // zorder 는 BracketLeft 로 이동. KeyB 의 Alt+Shift+B = align bottom 만 유지.
284
350
  if (altKey && shiftKey)
285
351
  this.onTapAlign('bottom');
286
352
  break;
@@ -458,6 +524,101 @@ export class EditToolbar extends LitElement {
458
524
  var _a;
459
525
  (_a = this.scene) === null || _a === void 0 ? void 0 : _a.remove();
460
526
  }
527
+ /**
528
+ * 멀티 컴포넌트 일괄 붙여넣기 — Ctrl+Shift+V 진입점.
529
+ *
530
+ * 흐름:
531
+ * 1. 클립보드 (this.cliped) 검증 — *단일* 컴포넌트만 허용
532
+ * 2. scene.startBulkCreateMode → AddLayer 가 캔버스 위에 드래그 박스 그림
533
+ * 3. 사용자가 영역 드래그 → Promise resolve({area, template})
534
+ * ESC/취소 → Promise resolve(null)
535
+ * 4. 영역이 결정되면 dialog 오픈
536
+ */
537
+ async onBulkPaste() {
538
+ var _a;
539
+ if (!this.cliped) {
540
+ console.warn('bulk-paste: 먼저 Ctrl+C 로 컴포넌트를 복사하세요.');
541
+ return;
542
+ }
543
+ let parsed;
544
+ try {
545
+ parsed = JSON.parse(this.cliped);
546
+ }
547
+ catch (e) {
548
+ console.warn('bulk-paste: 클립보드 파싱 실패', e);
549
+ return;
550
+ }
551
+ if (!Array.isArray(parsed) || parsed.length === 0) {
552
+ console.warn('bulk-paste: 클립보드 비어있음');
553
+ return;
554
+ }
555
+ if (parsed.length > 1) {
556
+ console.warn('bulk-paste: 단일 컴포넌트만 일괄 붙여넣기 가능. 다중은 일반 paste 사용.');
557
+ return;
558
+ }
559
+ const template = parsed[0];
560
+ // bulk 모드 임을 시각 구분하기 위해 파란 점선 (일반 add 의 검정과 색만 차별).
561
+ const result = await ((_a = this.scene) === null || _a === void 0 ? void 0 : _a.startBulkCreateMode(template, { boxStrokeStyle: '#2964c2' }));
562
+ if (result) {
563
+ this._openBulkCreateDialog(template, result.area);
564
+ }
565
+ }
566
+ _openBulkCreateDialog(template, initialArea) {
567
+ var _a;
568
+ const dialogEl = document.createElement('bulk-create-dialog');
569
+ dialogEl.template = template;
570
+ dialogEl.initialArea = initialArea;
571
+ // 충돌 검사용 — scene 의 모든 컴포넌트 id 수집.
572
+ // (scene.ids 는 indexMap 기반인데 fmsim 의 일부 컴포넌트는 indexMap 미등록
573
+ // 되는 케이스가 있어 직접 컴포넌트 트리 walk.)
574
+ const existingIds = new Set();
575
+ const collectIds = (comp) => {
576
+ var _a, _b, _c;
577
+ if (!comp)
578
+ return;
579
+ const id = (_b = (_a = comp === null || comp === void 0 ? void 0 : comp.state) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : (_c = comp === null || comp === void 0 ? void 0 : comp.model) === null || _c === void 0 ? void 0 : _c.id;
580
+ if (typeof id === 'string' && id)
581
+ existingIds.add(id);
582
+ const children = comp.components || [];
583
+ for (const c of children)
584
+ collectIds(c);
585
+ };
586
+ const root = (_a = this.scene) === null || _a === void 0 ? void 0 : _a.root;
587
+ if (root)
588
+ collectIds(root);
589
+ dialogEl.existingIds = existingIds;
590
+ dialogEl.onConfirm = (models) => {
591
+ const scene = this.scene;
592
+ if (!scene || !models.length) {
593
+ popup === null || popup === void 0 ? void 0 : popup.close();
594
+ return;
595
+ }
596
+ // cliped 의 template model 자체에서 type-aware bounds 추출. things-scene 의
597
+ // component.bounds (= path bounding box) 와 동일 결과를 model JSON 의
598
+ // type-specific 필드 (width/height, rx/ry, points) 만으로 계산.
599
+ const bounds = deriveBoundsFromModel(template);
600
+ scene.undoableChange(() => {
601
+ for (const m of models) {
602
+ const cx = m.left + m.width / 2;
603
+ const cy = m.top + m.height / 2;
604
+ scene.add(m, {
605
+ left: cx - bounds.width / 2,
606
+ top: cy - bounds.height / 2,
607
+ width: bounds.width,
608
+ height: bounds.height
609
+ });
610
+ }
611
+ });
612
+ popup === null || popup === void 0 ? void 0 : popup.close();
613
+ };
614
+ dialogEl.onCancel = () => {
615
+ popup === null || popup === void 0 ? void 0 : popup.close();
616
+ };
617
+ const popup = OxPopup.open({
618
+ template: dialogEl,
619
+ backdrop: true
620
+ });
621
+ }
461
622
  onTapSelectAll() {
462
623
  var _a;
463
624
  (_a = this.scene) === null || _a === void 0 ? void 0 : _a.select('(child)');
@@ -1 +1 @@
1
- {"version":3,"file":"edit-toolbar.js","sourceRoot":"","sources":["../../../src/modeller/edit-toolbar.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { html, LitElement, PropertyValues } from 'lit'\nimport { property, state } from 'lit/decorators.js'\n\nimport { Component, Scene } from '@hatiolab/things-scene'\nimport { copyToClipboard, isMacOS } from '@operato/utils'\n\nimport { style } from './edit-toolbar-style'\n\nconst MACOS = isMacOS()\n\nexport class EditToolbar extends LitElement {\n static styles = [style]\n\n @property({ type: Object }) scene?: Scene\n @property({ type: Array }) selected: any[] = []\n @property({ type: Boolean }) hideProperty: boolean = false\n\n @state() private _dimension: '2d' | '3d' | null = null\n @state() private _gizmoAttached = false\n\n private cliped?: string\n\n firstUpdated() {\n this.addEventListener('mousewheel', this.onWheelEvent.bind(this) as EventListener, false)\n\n // 툴바 버튼 클릭 후 씬으로 포커스를 돌려서 키보드 단축키가 계속 작동하도록 한다\n this.addEventListener('click', () => {\n ;(this.scene?.root as any)?.element?.focus()\n })\n\n window.addEventListener('paste', (e: Event) => {\n try {\n this.cliped = (e as ClipboardEvent).clipboardData?.getData('text/plain')\n } catch (e) {\n console.error('model paste failed', e)\n }\n })\n // 모든 버튼은 템플릿 @click 디렉티브로 바인딩 — 조건부 렌더링 시에도 정상 작동\n }\n\n updated(changes: PropertyValues<this>) {\n changes.has('scene') && this.onSceneChanged(this.scene, changes.get('scene') as Scene)\n changes.has('selected') && this.onSelectedChanged(this.selected, changes.get('selected') as Component[])\n }\n\n render() {\n return html`\n <div tools>\n <span><slot></slot></span>\n\n ${this.hasEmptySlot() ? html`` : html`<span class=\"vline\"></span>`}\n\n <span button id=\"undo\" title=\"undo (${this.getShortcutString('cmd', 'z')})\" @click=${this.onTapUndo}> </span>\n <span button id=\"redo\" title=\"redo (${this.getShortcutString('cmd', 'shift', 'z')})\" @click=${this.onTapRedo}> </span>\n\n <span class=\"vline\"></span>\n\n <span button id=\"style-copy\" title=\"style copy (${this.getShortcutString('cmd', '1')})\" @click=${this.onStartStylePasteMode}> </span>\n <span button id=\"databind-copy\" title=\"databind copy (${this.getShortcutString('cmd', '2')})\" @click=${this.onStartDatabindPasteMode}> </span>\n\n <span class=\"vline\"></span>\n\n <span button id=\"cut\" title=\"cut (${this.getShortcutString('cmd', 'x')})\" @click=${this.onTapCut}> </span>\n <span button id=\"copy\" title=\"copy (${this.getShortcutString('cmd', 'c')})\" @click=${this.onTapCopy}> </span>\n <span button id=\"paste\" title=\"paste (${this.getShortcutString('cmd', 'v')})\" @click=${this.onTapPaste}> </span>\n <span button id=\"delete\"\n title=\"delete (${this.getShortcutString('backspace')}, ${this.getShortcutString('delete')})\"\n @click=${this.onTapDelete}> </span>\n\n <span class=\"vline\"></span>\n\n <span button data-align=\"left\" id=\"align-left\"\n title=\"align left (${this.getShortcutString('alt', 'shift', 'l')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"center\" id=\"align-center\"\n title=\"align center (${this.getShortcutString('alt', 'shift', 'c')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"right\" id=\"align-right\"\n title=\"align right (${this.getShortcutString('alt', 'shift', 'r')})\" @click=${this.onTapAlign}> </span>\n\n <span button data-align=\"top\" id=\"align-top\"\n title=\"align top (${this.getShortcutString('alt', 'shift', 't')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"middle\" id=\"align-middle\"\n title=\"align middle (${this.getShortcutString('alt', 'shift', 'm')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"bottom\" id=\"align-bottom\"\n title=\"align bottom (${this.getShortcutString('alt', 'shift', 'b')})\" @click=${this.onTapAlign}> </span>\n\n <span button data-distribute=\"HORIZONTAL\" id=\"distribute-horizontal\"\n title=\"distribute horizontally (${this.getShortcutString('alt', 'shift', 'h')})\" @click=${this.onTapDistribute}> </span>\n <span button data-distribute=\"VERTICAL\" id=\"distribute-vertical\"\n title=\"distribute vertically (${this.getShortcutString('alt', 'shift', 'v')})\" @click=${this.onTapDistribute}> </span>\n\n ${this._dimension === '3d'\n ? html`\n <span class=\"vline\"></span>\n\n <span button data-align=\"z-front\" id=\"align-z-front\" title=\"align Z front\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"z-middle\" id=\"align-z-middle\" title=\"align Z middle\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"z-back\" id=\"align-z-back\" title=\"align Z back\" @click=${this.onTapAlign}> </span>\n <span button data-distribute=\"Z\" id=\"distribute-z\" title=\"distribute Z\" @click=${this.onTapDistribute}> </span>\n `\n : this._dimension === '2d'\n ? html`\n <span class=\"vline\"></span>\n\n <span button id=\"front\" data-zorder=\"front\"\n title=\"bring to front (${this.getShortcutString('cmd', 'shift', 'f')})\" @click=${this.onTapZorder}> </span>\n <span button id=\"back\" data-zorder=\"back\"\n title=\"send to back (${this.getShortcutString('cmd', 'shift', 'b')})\" @click=${this.onTapZorder}> </span>\n <span button id=\"forward\" data-zorder=\"forward\"\n title=\"bring forward (${this.getShortcutString('cmd', 'f')})\" @click=${this.onTapZorder}> </span>\n <span button id=\"backward\" data-zorder=\"backward\"\n title=\"send backward (${this.getShortcutString('cmd', 'b')})\" @click=${this.onTapZorder}> </span>\n `\n : ''}\n\n ${this._dimension === '2d' ? html`\n <span class=\"vline\"></span>\n\n <span button id=\"group\" title=\"group (${this.getShortcutString('cmd', 'g')})\" @click=${this.onTapGroup}> </span>\n <span button id=\"ungroup\" title=\"ungroup (${this.getShortcutString('cmd', 'shift', 'g')})\" @click=${this.onTapUngroup}> </span>\n ` : this._dimension === '3d' ? html`\n <span class=\"vline\"></span>\n\n <span button class=\"gizmo-btn\" data-gizmo=\"translate\" title=\"Move (W)\"\n @click=${() => this._setGizmoMode('translate')}>\n <svg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <line x1=\"10\" y1=\"2\" x2=\"10\" y2=\"18\"/><line x1=\"2\" y1=\"10\" x2=\"18\" y2=\"10\"/>\n <polyline points=\"10,2 7.5,5\"/><polyline points=\"10,2 12.5,5\"/>\n <polyline points=\"18,10 15,7.5\"/><polyline points=\"18,10 15,12.5\"/>\n <polyline points=\"10,18 7.5,15\"/><polyline points=\"10,18 12.5,15\"/>\n <polyline points=\"2,10 5,7.5\"/><polyline points=\"2,10 5,12.5\"/>\n </svg>\n </span>\n <span button class=\"gizmo-btn\" data-gizmo=\"rotate\" title=\"Rotate (E)\"\n @click=${() => this._setGizmoMode('rotate')}>\n <svg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <path d=\"M14.5 3.5A7 7 0 1 0 17 10\"/>\n <polyline points=\"14,1 15,3.5 12.5,4.5\"/>\n </svg>\n </span>\n <span button class=\"gizmo-btn\" data-gizmo=\"scale\" title=\"Scale (R)\"\n @click=${() => this._setGizmoMode('scale')}>\n <svg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <line x1=\"4\" y1=\"16\" x2=\"16\" y2=\"4\"/>\n <rect x=\"2\" y=\"13\" width=\"4\" height=\"4\" rx=\"0.5\" fill=\"currentColor\"/>\n <rect x=\"14\" y=\"2\" width=\"4\" height=\"4\" rx=\"0.5\" fill=\"currentColor\"/>\n </svg>\n </span>\n ` : ''}\n\n <span class=\"vline\"></span>\n\n <span button id=\"font-increase\" title=\"increase font size\" @click=${this.onTapFontIncrease}></span>\n <span button id=\"font-decrease\" title=\"decrease font size\" style=\"scale: 0.7;\" @click=${this.onTapFontDecrease}></span>\n\n <span class=\"vline\"></span>\n <span>(v${process.env['APP-VERSION']})</span>\n <span padding></span>\n\n <span button id=\"fit-scene\" title=\"fit scene (${this.getShortcutString('cmd', 'd')})\" @click=${this.onTapFitScene}> </span>\n\n <span class=\"vline\"></span>\n\n <span button id=\"preview\" title=\"preview (${this.getShortcutString('ctrl', 'p')})\" @click=${this.onTapPreview}> </span>\n\n <span button id=\"fullscreen\" title=\"fullscreen (${this.getShortcutString('f11')})\" @click=${this.onTapFullscreen}> </span>\n\n <span button id=\"toggle-property\"\n title=\"toggle property panel (${this.getShortcutString('cmd', 'h')})\"\n toggles=\"true\" @click=${this.onTapToggle}> </span>\n </div>\n `\n }\n\n hasEmptySlot() {\n const slot = this.renderRoot.querySelector('slot') as HTMLSlotElement\n return slot?.assignedNodes().length === 0\n }\n\n onWheelEvent(e: Event) {\n var delta = Math.max(-1, Math.min(1, (e as WheelEvent).deltaY || -(e as WheelEvent).detail))\n this.scrollLeft -= delta * 40\n\n e.preventDefault()\n }\n\n getSymbol(key: string) {\n var symbol\n switch (key) {\n case 'cmd':\n case 'ctrl':\n symbol = MACOS ? '⌘' : 'Ctrl'\n break\n case 'shift':\n symbol = MACOS ? '⇧' : 'Shift'\n break\n case 'alt':\n case 'option':\n symbol = MACOS ? '⌥' : 'Alt'\n break\n case 'backspace':\n symbol = MACOS ? '⌫' : 'BackSpace'\n break\n case 'delete':\n symbol = MACOS ? '⌦' : 'Del'\n break\n default:\n symbol = key.toUpperCase()\n break\n }\n\n return symbol\n }\n\n private getShortcutString(...keys: string[]) {\n var symbols = []\n for (var i = 0; i < arguments.length; i++) {\n symbols.push(this.getSymbol(arguments[i]))\n }\n\n return symbols.join(MACOS ? '' : '+')\n }\n\n onShortcut(e: KeyboardEvent) {\n if (MACOS) var ctrlKey = e.metaKey\n else var ctrlKey = e.ctrlKey\n\n var altKey = e.altKey\n var shiftKey = e.shiftKey\n\n var defaultPrevent = ctrlKey || altKey\n\n switch (e.code) {\n case 'KeyZ':\n if (ctrlKey && !shiftKey) this.onTapUndo()\n else if (ctrlKey && shiftKey) this.onTapRedo()\n break\n case 'KeyY':\n if (ctrlKey && !shiftKey) this.onTapRedo()\n break\n case 'Digit1':\n if (ctrlKey) this.onStartStylePasteMode()\n break\n case 'Digit2':\n if (ctrlKey) this.onStartDatabindPasteMode()\n break\n case 'KeyC':\n if (ctrlKey && !shiftKey) this.onTapCopy()\n else if (altKey && shiftKey) this.onTapAlign('center')\n break\n case 'KeyX':\n if (ctrlKey && !shiftKey) this.onTapCut()\n break\n case 'KeyV':\n if (ctrlKey && !shiftKey) {\n this.onTapPaste()\n defaultPrevent = false\n } else if (altKey && shiftKey) this.onTapDistribute('VERTICAL')\n break\n case 'Delete':\n case 'Backspace':\n this.onTapDelete()\n defaultPrevent = true\n break\n case 'KeyG':\n if (this._dimension === '2d') {\n if (ctrlKey && !shiftKey) this.onTapGroup()\n else if (ctrlKey && shiftKey) this.onTapUngroup()\n }\n break\n case 'KeyF':\n if (this._dimension === '2d') {\n if (ctrlKey && !shiftKey) this.scene?.zorder('forward')\n else if (ctrlKey && shiftKey) this.scene?.zorder('front')\n }\n break\n case 'KeyB':\n if (this._dimension === '2d') {\n if (ctrlKey && !shiftKey) this.scene?.zorder('backward')\n else if (ctrlKey && shiftKey) this.scene?.zorder('back')\n }\n if (altKey && shiftKey) this.onTapAlign('bottom')\n break\n case 'KeyH':\n if (ctrlKey && !shiftKey) this.onTapToggle()\n else if (altKey && shiftKey) this.onTapDistribute('HORIZONTAL')\n break\n case 'F11':\n this.onTapFullscreen()\n defaultPrevent = true\n break\n case 'KeyP':\n if (ctrlKey) {\n this.onTapPreview()\n defaultPrevent = true\n }\n break\n case 'KeyA':\n if (ctrlKey) this.onTapSelectAll()\n break\n case 'KeyL':\n if (altKey && shiftKey) this.onTapAlign('left')\n break\n case 'KeyR':\n if (altKey && shiftKey) this.onTapAlign('right')\n break\n case 'KeyM':\n if (altKey && shiftKey) this.onTapAlign('middle')\n break\n case 'KeyT':\n if (altKey && shiftKey) this.onTapAlign('top')\n break\n case 'KeyD':\n if (ctrlKey) {\n this.onTapFitScene()\n defaultPrevent = true\n }\n break\n case 'KeyE':\n if (ctrlKey && shiftKey) this.onTapDownloadModel()\n break\n\n case 'Escape':\n this.scene?.stopStylePasteMode()\n this.scene?.stopDatabindPasteMode()\n defaultPrevent = true\n break\n\n default:\n return false\n }\n\n if (defaultPrevent) e.preventDefault()\n return true\n }\n\n private _setDisabled(id: string, disabled: boolean) {\n const el = this.renderRoot.querySelector(`#${id}`)\n disabled ? el?.setAttribute('disabled', '') : el?.removeAttribute('disabled')\n }\n\n onExecute(command: string, undoable: boolean, redoable: boolean) {\n this._setDisabled('undo', !undoable)\n this._setDisabled('redo', !redoable)\n }\n\n onUndo(undoable: boolean, redoable: boolean) {\n this._setDisabled('undo', !undoable)\n this._setDisabled('redo', !redoable)\n }\n\n onRedo(undoable: boolean, redoable: boolean) {\n this._setDisabled('undo', !undoable)\n this._setDisabled('redo', !redoable)\n }\n\n onSceneChanged(after?: Scene, before?: Scene) {\n if (before) {\n before.off('execute', this.onExecute, this)\n before.off('undo', this.onUndo, this)\n before.off('redo', this.onRedo, this)\n before.off('dimension', this._onDimensionChanged, this)\n before.off('gizmoattach', this._onGizmoAttachChanged, this)\n }\n\n if (after) {\n after.on('execute', this.onExecute, this)\n after.on('undo', this.onUndo, this)\n after.on('redo', this.onRedo, this)\n after.on('dimension', this._onDimensionChanged, this)\n after.on('gizmoattach', this._onGizmoAttachChanged, this)\n\n // scene 설정 시 현재 dimension을 즉시 반영 (초기 이벤트를 놓친 경우 대비)\n const threed = (after as any).model_layer?.model?.threed\n this._dimension = threed ? '3d' : '2d'\n }\n }\n\n private _onDimensionChanged(dimension: '2d' | '3d') {\n this._dimension = dimension\n }\n\n private _onGizmoAttachChanged(isAttached: boolean) {\n this._gizmoAttached = isAttached\n }\n\n private _setGizmoMode(mode: 'translate' | 'rotate' | 'scale') {\n ;(this.scene?.root as any)?.setGizmoMode(mode)\n }\n\n onSelectedChanged(after: Component[], before: Component[]) {\n var hasSelection = after.length > 0\n var alignable = after.length > 1\n\n // 선택 필요 버튼\n ;['style-copy', 'databind-copy', 'cut', 'copy', 'delete'].forEach(id =>\n this._setDisabled(id, !hasSelection)\n )\n\n // 정렬 버튼\n this.renderRoot.querySelectorAll('[data-align]').forEach(el =>\n alignable ? el.removeAttribute('disabled') : el.setAttribute('disabled', '')\n )\n\n if (this._dimension === '2d') {\n var movable = after.length === 1\n\n /* forward, backward 이동은 한 컴포넌트만 가능하다. */\n this._setDisabled('forward', !movable)\n this._setDisabled('backward', !movable)\n\n /* 여러 컴포넌트는 front, back 이동이 가능하다. */\n this._setDisabled('front', !(alignable || movable))\n this._setDisabled('back', !(alignable || movable))\n }\n\n // 분배 버튼\n this.renderRoot.querySelectorAll('[data-distribute]').forEach(el =>\n alignable ? el.removeAttribute('disabled') : el.setAttribute('disabled', '')\n )\n\n if (this._dimension === '3d') {\n this.renderRoot.querySelectorAll('.gizmo-btn').forEach(btn => {\n hasSelection ? btn.removeAttribute('disabled') : btn.setAttribute('disabled', '')\n })\n }\n }\n\n onTapUndo() {\n this.scene?.undo()\n }\n\n onTapRedo() {\n this.scene?.redo()\n }\n\n onStartStylePasteMode() {\n if (this.selected?.length !== 1) return\n if (this.selected[0] === this.scene?.root) return\n this.scene?.startStylePasteMode()\n }\n\n onStartDatabindPasteMode() {\n if (this.selected?.length !== 1) return\n if (this.selected[0] === this.scene?.root) return\n this.scene?.startDatabindPasteMode()\n }\n\n onTapCut() {\n this.scene?.cut()\n }\n\n async onTapCopy() {\n var copied = this.scene?.copy()\n\n if (!copied) return\n\n await copyToClipboard(copied)\n this.cliped = copied\n }\n\n onTapPaste() {\n setTimeout(() => {\n this.cliped && this.scene?.paste(this.cliped)\n }, 100)\n }\n\n onTapDelete() {\n this.scene?.remove()\n }\n\n onTapSelectAll() {\n this.scene?.select('(child)')\n }\n\n onTapFontIncrease(e: TouchEvent) {\n var selected = this.scene?.selected\n if (!selected || !selected.length) {\n return\n }\n\n this.scene?.undoableChange(function () {\n selected!.forEach(function (component: Component) {\n var fontSize = component.get('fontSize')\n\n if (!fontSize) fontSize = '15'\n\n if (fontSize) {\n var size = parseInt(fontSize)\n component.set('fontSize', size + 1)\n }\n })\n })\n }\n\n onTapFontDecrease(e: TouchEvent) {\n var selected = this.scene?.selected\n\n if (!selected || !selected.length) {\n return\n }\n\n this.scene?.undoableChange(function () {\n selected!.forEach(function (component: Component) {\n var fontSize = component.get('fontSize')\n\n if (!fontSize) fontSize = '15'\n\n if (fontSize) {\n var size = parseInt(fontSize)\n if (size > 1) component.set('fontSize', size - 1)\n }\n })\n })\n }\n\n onTapAlign(e: TouchEvent | string) {\n if (!this.scene) return\n\n var selected = this.scene.selected\n\n var align = typeof e === 'string' ? e : (e.target as HTMLElement).getAttribute('data-align')\n if (!align) {\n return\n }\n\n if (selected.length <= 1) {\n this.scene.place(align)\n } else {\n this.scene.align(align)\n }\n }\n\n onTapZorder(e: TouchEvent | string) {\n if (!this.scene) return\n\n var selected = this.scene.selected\n if (selected.length < 1) return\n\n var zorder = typeof e === 'string' ? e : (e.target as HTMLElement).getAttribute('data-zorder')\n\n zorder && this.scene.zorder(zorder)\n }\n\n onTapGroup() {\n this.scene && this.scene.group()\n }\n\n onTapUngroup() {\n this.scene && this.scene.ungroup()\n }\n\n onTapFullscreen() {\n this.dispatchEvent(new CustomEvent('modeller-fullscreen'))\n }\n\n onTapToggle() {\n this.hideProperty = !this.hideProperty\n this.dispatchEvent(\n new CustomEvent('hide-property-changed', {\n bubbles: true,\n composed: true,\n detail: { value: this.hideProperty }\n })\n )\n }\n\n onTapFitScene() {\n if (this.scene) {\n this.scene.resize()\n this.scene.fit('ratio')\n }\n }\n\n onTapPreview() {\n this.dispatchEvent(new CustomEvent('open-preview'))\n }\n\n onTapDownloadModel() {\n this.dispatchEvent(new CustomEvent('download-model'))\n }\n\n onTapDistribute(e: TouchEvent | string) {\n if (!this.scene) return\n\n var selected = this.scene.selected\n if (selected.length <= 1) {\n return\n }\n\n var distribute = typeof e === 'string' ? e : (e.target as HTMLElement)!.getAttribute('data-distribute')\n\n distribute && this.scene.distribute(distribute)\n }\n}\n"]}
1
+ {"version":3,"file":"edit-toolbar.js","sourceRoot":"","sources":["../../../src/modeller/edit-toolbar.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,EAAE,IAAI,EAAE,UAAU,EAAkB,MAAM,KAAK,CAAA;AACtD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAGnD,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAExC,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC5C,OAAO,yBAAyB,CAAA;AAGhC,MAAM,KAAK,GAAG,OAAO,EAAE,CAAA;AAEvB;;;;;;;;;;;GAWG;AACH,SAAS,qBAAqB,CAAC,KAA0B;IACvD,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAA;IACrD,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;QACjE,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAA;IAC1E,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3D,IAAI,IAAI,GAAG,QAAQ,CAAA;QACnB,IAAI,IAAI,GAAG,CAAC,QAAQ,CAAA;QACpB,IAAI,IAAI,GAAG,QAAQ,CAAA;QACnB,IAAI,IAAI,GAAG,CAAC,QAAQ,CAAA;QACpB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YAC7B,IAAI,OAAO,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,CAAC,CAAA,KAAK,QAAQ,EAAE,CAAC;gBAC7B,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI;oBAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAA;gBAC1B,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI;oBAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAA;YAC5B,CAAC;YACD,IAAI,OAAO,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,CAAC,CAAA,KAAK,QAAQ,EAAE,CAAC;gBAC7B,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI;oBAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAA;gBAC1B,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI;oBAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAA;YAC5B,CAAC;QACH,CAAC;QACD,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACzE,OAAO,EAAE,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,CAAA;QACpD,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;AAClC,CAAC;AAED,MAAM,OAAO,WAAY,SAAQ,UAAU;IAA3C;;QAI6B,aAAQ,GAAU,EAAE,CAAA;QAClB,iBAAY,GAAY,KAAK,CAAA;QAEzC,eAAU,GAAuB,IAAI,CAAA;QACrC,mBAAc,GAAG,KAAK,CAAA;IAirBzC,CAAC;IA7qBC,YAAY;QACV,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAkB,EAAE,KAAK,CAAC,CAAA;QAEzF,+CAA+C;QAC/C,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;;YAClC,CAAC;YAAA,MAAA,MAAC,MAAA,IAAI,CAAC,KAAK,0CAAE,IAAY,0CAAE,OAAO,0CAAE,KAAK,EAAE,CAAA;QAC9C,CAAC,CAAC,CAAA;QAEF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAQ,EAAE,EAAE;;YAC5C,IAAI,CAAC;gBACH,IAAI,CAAC,MAAM,GAAG,MAAC,CAAoB,CAAC,aAAa,0CAAE,OAAO,CAAC,YAAY,CAAC,CAAA;YAC1E,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAA;YACxC,CAAC;QACH,CAAC,CAAC,CAAA;QACF,kDAAkD;IACpD,CAAC;IAED,OAAO,CAAC,OAA6B;QACnC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAU,CAAC,CAAA;QACtF,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,CAAgB,CAAC,CAAA;IAC1G,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAA;;;;UAIL,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA,6BAA6B;;8CAE5B,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,SAAS;8CAC7D,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,SAAS;;;;0DAI1D,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,qBAAqB;gEACnE,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,wBAAwB;;;;4CAIhG,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,QAAQ;8CAC1D,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,SAAS;gDAC3D,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,UAAU;;2BAEnF,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC;mBAChF,IAAI,CAAC,WAAW;;;;;+BAKJ,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,UAAU;;iCAErE,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,UAAU;;gCAExE,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,UAAU;;;8BAGzE,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,UAAU;;iCAEpE,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,UAAU;;iCAEvE,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,UAAU;;;4CAG5D,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,eAAe;;0CAE9E,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,eAAe;;UAE5G,IAAI,CAAC,UAAU,KAAK,IAAI;YACxB,CAAC,CAAC,IAAI,CAAA;;;kGAGkF,IAAI,CAAC,UAAU;qGACZ,IAAI,CAAC,UAAU;+FACrB,IAAI,CAAC,UAAU;+FACf,IAAI,CAAC,eAAe;aACtG;YACH,CAAC,CAAC,IAAI,CAAC,UAAU,KAAK,IAAI;gBACxB,CAAC,CAAC,IAAI,CAAA;;;;2CAIyB,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,WAAW;;yCAE1E,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,WAAW;;0CAEvE,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,WAAW;;0CAE/D,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,WAAW;eAC1F;gBACH,CAAC,CAAC,EAAE;;UAEN,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;;;kDAGS,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,UAAU;sDAC1D,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,YAAY;SACtH,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;;;;qBAItB,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC;;;;;;;;;;qBAUrC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC;;;;;;;qBAOlC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;;;;;;;SAO7C,CAAC,CAAC,CAAC,EAAE;;;;4EAI8D,IAAI,CAAC,iBAAiB;gGACF,IAAI,CAAC,iBAAiB;;;kBAGpG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;;;wDAGY,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,aAAa;;;;oDAIrE,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,YAAY;;0DAE3D,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,eAAe;;;0CAG9E,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC;kCAC1C,IAAI,CAAC,WAAW;;KAE7C,CAAA;IACH,CAAC;IAED,YAAY;QACV,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,MAAM,CAAoB,CAAA;QACrE,OAAO,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,aAAa,GAAG,MAAM,MAAK,CAAC,CAAA;IAC3C,CAAC;IAED,YAAY,CAAC,CAAQ;QACnB,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAG,CAAgB,CAAC,MAAM,IAAI,CAAE,CAAgB,CAAC,MAAM,CAAC,CAAC,CAAA;QAC5F,IAAI,CAAC,UAAU,IAAI,KAAK,GAAG,EAAE,CAAA;QAE7B,CAAC,CAAC,cAAc,EAAE,CAAA;IACpB,CAAC;IAED,SAAS,CAAC,GAAW;QACnB,IAAI,MAAM,CAAA;QACV,QAAQ,GAAG,EAAE,CAAC;YACZ,KAAK,KAAK,CAAC;YACX,KAAK,MAAM;gBACT,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAA;gBAC7B,MAAK;YACP,KAAK,OAAO;gBACV,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAA;gBAC9B,MAAK;YACP,KAAK,KAAK,CAAC;YACX,KAAK,QAAQ;gBACX,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAA;gBAC5B,MAAK;YACP,KAAK,WAAW;gBACd,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAA;gBAClC,MAAK;YACP,KAAK,QAAQ;gBACX,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAA;gBAC5B,MAAK;YACP;gBACE,MAAM,GAAG,GAAG,CAAC,WAAW,EAAE,CAAA;gBAC1B,MAAK;QACT,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC;IAEO,iBAAiB,CAAC,GAAG,IAAc;QACzC,IAAI,OAAO,GAAG,EAAE,CAAA;QAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAC5C,CAAC;QAED,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IACvC,CAAC;IAED,UAAU,CAAC,CAAgB;;QACzB,IAAI,KAAK;YAAE,IAAI,OAAO,GAAG,CAAC,CAAC,OAAO,CAAA;;YAC7B,IAAI,OAAO,GAAG,CAAC,CAAC,OAAO,CAAA;QAE5B,IAAI,MAAM,GAAG,CAAC,CAAC,MAAM,CAAA;QACrB,IAAI,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAA;QAEzB,IAAI,cAAc,GAAG,OAAO,IAAI,MAAM,CAAA;QAEtC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,MAAM;gBACT,IAAI,OAAO,IAAI,CAAC,QAAQ;oBAAE,IAAI,CAAC,SAAS,EAAE,CAAA;qBACrC,IAAI,OAAO,IAAI,QAAQ;oBAAE,IAAI,CAAC,SAAS,EAAE,CAAA;gBAC9C,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,IAAI,CAAC,QAAQ;oBAAE,IAAI,CAAC,SAAS,EAAE,CAAA;gBAC1C,MAAK;YACP,KAAK,QAAQ;gBACX,IAAI,OAAO;oBAAE,IAAI,CAAC,qBAAqB,EAAE,CAAA;gBACzC,MAAK;YACP,KAAK,QAAQ;gBACX,IAAI,OAAO;oBAAE,IAAI,CAAC,wBAAwB,EAAE,CAAA;gBAC5C,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,IAAI,CAAC,QAAQ;oBAAE,IAAI,CAAC,SAAS,EAAE,CAAA;qBACrC,IAAI,MAAM,IAAI,QAAQ;oBAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;gBACtD,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,IAAI,CAAC,QAAQ;oBAAE,IAAI,CAAC,QAAQ,EAAE,CAAA;gBACzC,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,IAAI,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;oBACnC,wDAAwD;oBACxD,wBAAwB;oBACxB,IAAI,CAAC,WAAW,EAAE,CAAA;oBAClB,cAAc,GAAG,IAAI,CAAA;gBACvB,CAAC;qBAAM,IAAI,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAChC,IAAI,CAAC,UAAU,EAAE,CAAA;oBACjB,cAAc,GAAG,KAAK,CAAA;gBACxB,CAAC;qBAAM,IAAI,MAAM,IAAI,QAAQ;oBAAE,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAA;gBAC/D,MAAK;YACP,KAAK,QAAQ,CAAC;YACd,KAAK,WAAW;gBACd,IAAI,CAAC,WAAW,EAAE,CAAA;gBAClB,cAAc,GAAG,IAAI,CAAA;gBACrB,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;oBAC7B,IAAI,OAAO,IAAI,CAAC,QAAQ;wBAAE,IAAI,CAAC,UAAU,EAAE,CAAA;yBACtC,IAAI,OAAO,IAAI,QAAQ;wBAAE,IAAI,CAAC,YAAY,EAAE,CAAA;gBACnD,CAAC;gBACD,MAAK;YACP,KAAK,cAAc;gBACjB,wDAAwD;gBACxD,mCAAmC;gBACnC,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;oBAC7B,IAAI,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;wBACzB,MAAA,IAAI,CAAC,KAAK,0CAAE,MAAM,CAAC,SAAS,CAAC,CAAA;wBAC7B,cAAc,GAAG,IAAI,CAAA;oBACvB,CAAC;yBAAM,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;wBAC/B,MAAA,IAAI,CAAC,KAAK,0CAAE,MAAM,CAAC,OAAO,CAAC,CAAA;wBAC3B,cAAc,GAAG,IAAI,CAAA;oBACvB,CAAC;gBACH,CAAC;gBACD,MAAK;YACP,KAAK,aAAa;gBAChB,sDAAsD;gBACtD,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;oBAC7B,IAAI,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;wBACzB,MAAA,IAAI,CAAC,KAAK,0CAAE,MAAM,CAAC,UAAU,CAAC,CAAA;wBAC9B,cAAc,GAAG,IAAI,CAAA;oBACvB,CAAC;yBAAM,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;wBAC/B,MAAA,IAAI,CAAC,KAAK,0CAAE,MAAM,CAAC,MAAM,CAAC,CAAA;wBAC1B,cAAc,GAAG,IAAI,CAAA;oBACvB,CAAC;gBACH,CAAC;gBACD,MAAK;YACP,KAAK,MAAM;gBACT,qEAAqE;gBACrE,IAAI,MAAM,IAAI,QAAQ;oBAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;gBACjD,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,IAAI,CAAC,QAAQ;oBAAE,IAAI,CAAC,WAAW,EAAE,CAAA;qBACvC,IAAI,MAAM,IAAI,QAAQ;oBAAE,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAA;gBAC/D,MAAK;YACP,KAAK,KAAK;gBACR,IAAI,CAAC,eAAe,EAAE,CAAA;gBACtB,cAAc,GAAG,IAAI,CAAA;gBACrB,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,EAAE,CAAC;oBACZ,IAAI,CAAC,YAAY,EAAE,CAAA;oBACnB,cAAc,GAAG,IAAI,CAAA;gBACvB,CAAC;gBACD,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO;oBAAE,IAAI,CAAC,cAAc,EAAE,CAAA;gBAClC,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,MAAM,IAAI,QAAQ;oBAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;gBAC/C,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,MAAM,IAAI,QAAQ;oBAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;gBAChD,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,MAAM,IAAI,QAAQ;oBAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;gBACjD,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,MAAM,IAAI,QAAQ;oBAAE,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;gBAC9C,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,EAAE,CAAC;oBACZ,IAAI,CAAC,aAAa,EAAE,CAAA;oBACpB,cAAc,GAAG,IAAI,CAAA;gBACvB,CAAC;gBACD,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,IAAI,QAAQ;oBAAE,IAAI,CAAC,kBAAkB,EAAE,CAAA;gBAClD,MAAK;YAEP,KAAK,QAAQ;gBACX,MAAA,IAAI,CAAC,KAAK,0CAAE,kBAAkB,EAAE,CAAA;gBAChC,MAAA,IAAI,CAAC,KAAK,0CAAE,qBAAqB,EAAE,CAAA;gBACnC,cAAc,GAAG,IAAI,CAAA;gBACrB,MAAK;YAEP;gBACE,OAAO,KAAK,CAAA;QAChB,CAAC;QAED,IAAI,cAAc;YAAE,CAAC,CAAC,cAAc,EAAE,CAAA;QACtC,OAAO,IAAI,CAAA;IACb,CAAC;IAEO,YAAY,CAAC,EAAU,EAAE,QAAiB;QAChD,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QAClD,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAF,EAAE,uBAAF,EAAE,CAAE,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,aAAF,EAAE,uBAAF,EAAE,CAAE,eAAe,CAAC,UAAU,CAAC,CAAA;IAC/E,CAAC;IAED,SAAS,CAAC,OAAe,EAAE,QAAiB,EAAE,QAAiB;QAC7D,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAA;QACpC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAA;IACtC,CAAC;IAED,MAAM,CAAC,QAAiB,EAAE,QAAiB;QACzC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAA;QACpC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAA;IACtC,CAAC;IAED,MAAM,CAAC,QAAiB,EAAE,QAAiB;QACzC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAA;QACpC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAA;IACtC,CAAC;IAED,cAAc,CAAC,KAAa,EAAE,MAAc;;QAC1C,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;YAC3C,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;YACrC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;YACrC,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAA;YACvD,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAA;QAC7D,CAAC;QAED,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;YACzC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;YACnC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;YACnC,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAA;YACrD,KAAK,CAAC,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAA;YAEzD,oDAAoD;YACpD,MAAM,MAAM,GAAG,MAAA,MAAC,KAAa,CAAC,WAAW,0CAAE,KAAK,0CAAE,MAAM,CAAA;YACxD,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;QACxC,CAAC;IACH,CAAC;IAEO,mBAAmB,CAAC,SAAsB;QAChD,IAAI,CAAC,UAAU,GAAG,SAAS,CAAA;IAC7B,CAAC;IAEO,qBAAqB,CAAC,UAAmB;QAC/C,IAAI,CAAC,cAAc,GAAG,UAAU,CAAA;IAClC,CAAC;IAEO,aAAa,CAAC,IAAsC;;QAC1D,CAAC;QAAA,MAAC,MAAA,IAAI,CAAC,KAAK,0CAAE,IAAY,0CAAE,YAAY,CAAC,IAAI,CAAC,CAAA;IAChD,CAAC;IAED,iBAAiB,CAAC,KAAkB,EAAE,MAAmB;QACvD,IAAI,YAAY,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;QACnC,IAAI,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAG/B;QAAA,CAAC,YAAY,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CACrE,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CACrC,CAAA;QAED,QAAQ;QACR,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAC5D,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC,CAC7E,CAAA;QAED,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC7B,IAAI,OAAO,GAAG,KAAK,CAAC,MAAM,KAAK,CAAC,CAAA;YAEhC,yCAAyC;YACzC,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAA;YACtC,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,CAAA;YAEvC,oCAAoC;YACpC,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,IAAI,OAAO,CAAC,CAAC,CAAA;YACnD,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,IAAI,OAAO,CAAC,CAAC,CAAA;QACpD,CAAC;QAED,QAAQ;QACR,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CACjE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC,CAC7E,CAAA;QAED,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC7B,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBAC3D,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;YACnF,CAAC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,SAAS;;QACP,MAAA,IAAI,CAAC,KAAK,0CAAE,IAAI,EAAE,CAAA;IACpB,CAAC;IAED,SAAS;;QACP,MAAA,IAAI,CAAC,KAAK,0CAAE,IAAI,EAAE,CAAA;IACpB,CAAC;IAED,qBAAqB;;QACnB,IAAI,CAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,MAAM,MAAK,CAAC;YAAE,OAAM;QACvC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAK,MAAA,IAAI,CAAC,KAAK,0CAAE,IAAI,CAAA;YAAE,OAAM;QACjD,MAAA,IAAI,CAAC,KAAK,0CAAE,mBAAmB,EAAE,CAAA;IACnC,CAAC;IAED,wBAAwB;;QACtB,IAAI,CAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,MAAM,MAAK,CAAC;YAAE,OAAM;QACvC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAK,MAAA,IAAI,CAAC,KAAK,0CAAE,IAAI,CAAA;YAAE,OAAM;QACjD,MAAA,IAAI,CAAC,KAAK,0CAAE,sBAAsB,EAAE,CAAA;IACtC,CAAC;IAED,QAAQ;;QACN,MAAA,IAAI,CAAC,KAAK,0CAAE,GAAG,EAAE,CAAA;IACnB,CAAC;IAED,KAAK,CAAC,SAAS;;QACb,IAAI,MAAM,GAAG,MAAA,IAAI,CAAC,KAAK,0CAAE,IAAI,EAAE,CAAA;QAE/B,IAAI,CAAC,MAAM;YAAE,OAAM;QAEnB,MAAM,eAAe,CAAC,MAAM,CAAC,CAAA;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED,UAAU;QACR,UAAU,CAAC,GAAG,EAAE;;YACd,IAAI,CAAC,MAAM,KAAI,MAAA,IAAI,CAAC,KAAK,0CAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA,CAAA;QAC/C,CAAC,EAAE,GAAG,CAAC,CAAA;IACT,CAAC;IAED,WAAW;;QACT,MAAA,IAAI,CAAC,KAAK,0CAAE,MAAM,EAAE,CAAA;IACtB,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,WAAW;;QACf,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAA;YACpD,OAAM;QACR,CAAC;QACD,IAAI,MAAa,CAAA;QACjB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAClC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,CAAC,CAAA;YACzC,OAAM;QACR,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClD,OAAO,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAA;YACrC,OAAM;QACR,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAA;YACjE,OAAM;QACR,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;QAC1B,oDAAoD;QACpD,MAAM,MAAM,GAAG,MAAM,CAAA,MAAA,IAAI,CAAC,KAAK,0CAAE,mBAAmB,CAAC,QAAQ,EAAE,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC,CAAA,CAAA;QAC7F,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,qBAAqB,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QACnD,CAAC;IACH,CAAC;IAEO,qBAAqB,CAC3B,QAA6B,EAC7B,WAAyE;;QAEzE,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,oBAAoB,CAAqB,CAAA;QACjF,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAA;QAC5B,QAAQ,CAAC,WAAW,GAAG,WAAW,CAAA;QAClC,kCAAkC;QAClC,2DAA2D;QAC3D,gCAAgC;QAChC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAA;QACrC,MAAM,UAAU,GAAG,CAAC,IAAS,EAAE,EAAE;;YAC/B,IAAI,CAAC,IAAI;gBAAE,OAAM;YACjB,MAAM,EAAE,GAAG,MAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,KAAK,0CAAE,EAAE,mCAAI,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,KAAK,0CAAE,EAAE,CAAA;YAC7C,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE;gBAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,IAAI,EAAE,CAAA;YACtC,KAAK,MAAM,CAAC,IAAI,QAAQ;gBAAE,UAAU,CAAC,CAAC,CAAC,CAAA;QACzC,CAAC,CAAA;QACD,MAAM,IAAI,GAAG,MAAC,IAAI,CAAC,KAAa,0CAAE,IAAI,CAAA;QACtC,IAAI,IAAI;YAAE,UAAU,CAAC,IAAI,CAAC,CAAA;QAC1B,QAAQ,CAAC,WAAW,GAAG,WAAW,CAAA;QAClC,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE,EAAE;YAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;YACxB,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBAC7B,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,KAAK,EAAE,CAAA;gBACd,OAAM;YACR,CAAC;YACD,oEAAoE;YACpE,+DAA+D;YAC/D,yDAAyD;YACzD,MAAM,MAAM,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAA;YAC9C,KAAK,CAAC,cAAc,CAAC,GAAG,EAAE;gBACxB,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;oBACvB,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAA;oBAC/B,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAA;oBAC/B,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE;wBACX,IAAI,EAAE,EAAE,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC;wBAC3B,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC;wBAC3B,KAAK,EAAE,MAAM,CAAC,KAAK;wBACnB,MAAM,EAAE,MAAM,CAAC,MAAM;qBACtB,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC,CAAC,CAAA;YACF,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,KAAK,EAAE,CAAA;QAChB,CAAC,CAAA;QACD,QAAQ,CAAC,QAAQ,GAAG,GAAG,EAAE;YACvB,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,KAAK,EAAE,CAAA;QAChB,CAAC,CAAA;QACD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;YACzB,QAAQ,EAAE,QAAQ;YAClB,QAAQ,EAAE,IAAI;SACf,CAAC,CAAA;IACJ,CAAC;IAED,cAAc;;QACZ,MAAA,IAAI,CAAC,KAAK,0CAAE,MAAM,CAAC,SAAS,CAAC,CAAA;IAC/B,CAAC;IAED,iBAAiB,CAAC,CAAa;;QAC7B,IAAI,QAAQ,GAAG,MAAA,IAAI,CAAC,KAAK,0CAAE,QAAQ,CAAA;QACnC,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YAClC,OAAM;QACR,CAAC;QAED,MAAA,IAAI,CAAC,KAAK,0CAAE,cAAc,CAAC;YACzB,QAAS,CAAC,OAAO,CAAC,UAAU,SAAoB;gBAC9C,IAAI,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;gBAExC,IAAI,CAAC,QAAQ;oBAAE,QAAQ,GAAG,IAAI,CAAA;gBAE9B,IAAI,QAAQ,EAAE,CAAC;oBACb,IAAI,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAA;oBAC7B,SAAS,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,GAAG,CAAC,CAAC,CAAA;gBACrC,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,iBAAiB,CAAC,CAAa;;QAC7B,IAAI,QAAQ,GAAG,MAAA,IAAI,CAAC,KAAK,0CAAE,QAAQ,CAAA;QAEnC,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YAClC,OAAM;QACR,CAAC;QAED,MAAA,IAAI,CAAC,KAAK,0CAAE,cAAc,CAAC;YACzB,QAAS,CAAC,OAAO,CAAC,UAAU,SAAoB;gBAC9C,IAAI,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;gBAExC,IAAI,CAAC,QAAQ;oBAAE,QAAQ,GAAG,IAAI,CAAA;gBAE9B,IAAI,QAAQ,EAAE,CAAC;oBACb,IAAI,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAA;oBAC7B,IAAI,IAAI,GAAG,CAAC;wBAAE,SAAS,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,GAAG,CAAC,CAAC,CAAA;gBACnD,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,UAAU,CAAC,CAAsB;QAC/B,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAM;QAEvB,IAAI,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAA;QAElC,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,MAAsB,CAAC,YAAY,CAAC,YAAY,CAAC,CAAA;QAC5F,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAM;QACR,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACzB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACzB,CAAC;IACH,CAAC;IAED,WAAW,CAAC,CAAsB;QAChC,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAM;QAEvB,IAAI,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAA;QAClC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,OAAM;QAE/B,IAAI,MAAM,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,MAAsB,CAAC,YAAY,CAAC,aAAa,CAAC,CAAA;QAE9F,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACrC,CAAC;IAED,UAAU;QACR,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;IAClC,CAAC;IAED,YAAY;QACV,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAA;IACpC,CAAC;IAED,eAAe;QACb,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,qBAAqB,CAAC,CAAC,CAAA;IAC5D,CAAC;IAED,WAAW;QACT,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC,YAAY,CAAA;QACtC,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,uBAAuB,EAAE;YACvC,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE;SACrC,CAAC,CACH,CAAA;IACH,CAAC;IAED,aAAa;QACX,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAA;YACnB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACzB,CAAC;IACH,CAAC;IAED,YAAY;QACV,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,cAAc,CAAC,CAAC,CAAA;IACrD,CAAC;IAED,kBAAkB;QAChB,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,gBAAgB,CAAC,CAAC,CAAA;IACvD,CAAC;IAED,eAAe,CAAC,CAAsB;QACpC,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAM;QAEvB,IAAI,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAA;QAClC,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACzB,OAAM;QACR,CAAC;QAED,IAAI,UAAU,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,MAAuB,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAA;QAEvG,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,CAAA;IACjD,CAAC;;AAvrBM,kBAAM,GAAG,CAAC,KAAK,CAAC,AAAV,CAAU;AAEK;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0CAAc;AACd;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;6CAAqB;AAClB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;iDAA8B;AAEzC;IAAhB,KAAK,EAAE;+CAA8C;AACrC;IAAhB,KAAK,EAAE;mDAA+B","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { html, LitElement, PropertyValues } from 'lit'\nimport { property, state } from 'lit/decorators.js'\n\nimport { Component, Scene } from '@hatiolab/things-scene'\nimport { copyToClipboard, isMacOS } from '@operato/utils'\nimport { OxPopup } from '@operato/popup'\n\nimport { style } from './edit-toolbar-style'\nimport './bulk-create-dialog.js'\nimport type { BulkCreateDialog } from './bulk-create-dialog.js'\n\nconst MACOS = isMacOS()\n\n/**\n * 컴포넌트 model JSON 만으로 type-aware bounding box (width, height) 추출.\n *\n * things-scene 의 component.bounds 는 *path 의 bounding box* 인데, model JSON 만\n * 으로는 path 를 그릴 수 없으므로 type-specific 필드를 직접 본다.\n * - width/height 명시 (Rect, Container 등) → 그대로\n * - rx/ry (Ellipse 등) → 2*rx, 2*ry\n * - points 배열 (Line, Polygon 등) → 점들의 bounding box\n * - 그 외 → 50x50 fallback\n *\n * bulk-paste 가 영역 안에 N 개 복제할 때 *원본 크기를 보존* 하기 위해 사용.\n */\nfunction deriveBoundsFromModel(model: Record<string, any>): { width: number; height: number } {\n if (typeof model.width === 'number' && typeof model.height === 'number') {\n return { width: model.width, height: model.height }\n }\n if (typeof model.rx === 'number' && typeof model.ry === 'number') {\n return { width: 2 * Math.abs(model.rx), height: 2 * Math.abs(model.ry) }\n }\n if (Array.isArray(model.points) && model.points.length > 0) {\n let minX = Infinity\n let maxX = -Infinity\n let minY = Infinity\n let maxY = -Infinity\n for (const p of model.points) {\n if (typeof p?.x === 'number') {\n if (p.x < minX) minX = p.x\n if (p.x > maxX) maxX = p.x\n }\n if (typeof p?.y === 'number') {\n if (p.y < minY) minY = p.y\n if (p.y > maxY) maxY = p.y\n }\n }\n if (isFinite(minX) && isFinite(maxX) && isFinite(minY) && isFinite(maxY)) {\n return { width: maxX - minX, height: maxY - minY }\n }\n }\n return { width: 50, height: 50 }\n}\n\nexport class EditToolbar extends LitElement {\n static styles = [style]\n\n @property({ type: Object }) scene?: Scene\n @property({ type: Array }) selected: any[] = []\n @property({ type: Boolean }) hideProperty: boolean = false\n\n @state() private _dimension: '2d' | '3d' | null = null\n @state() private _gizmoAttached = false\n\n private cliped?: string\n\n firstUpdated() {\n this.addEventListener('mousewheel', this.onWheelEvent.bind(this) as EventListener, false)\n\n // 툴바 버튼 클릭 후 씬으로 포커스를 돌려서 키보드 단축키가 계속 작동하도록 한다\n this.addEventListener('click', () => {\n ;(this.scene?.root as any)?.element?.focus()\n })\n\n window.addEventListener('paste', (e: Event) => {\n try {\n this.cliped = (e as ClipboardEvent).clipboardData?.getData('text/plain')\n } catch (e) {\n console.error('model paste failed', e)\n }\n })\n // 모든 버튼은 템플릿 @click 디렉티브로 바인딩 — 조건부 렌더링 시에도 정상 작동\n }\n\n updated(changes: PropertyValues<this>) {\n changes.has('scene') && this.onSceneChanged(this.scene, changes.get('scene') as Scene)\n changes.has('selected') && this.onSelectedChanged(this.selected, changes.get('selected') as Component[])\n }\n\n render() {\n return html`\n <div tools>\n <span><slot></slot></span>\n\n ${this.hasEmptySlot() ? html`` : html`<span class=\"vline\"></span>`}\n\n <span button id=\"undo\" title=\"undo (${this.getShortcutString('cmd', 'z')})\" @click=${this.onTapUndo}> </span>\n <span button id=\"redo\" title=\"redo (${this.getShortcutString('cmd', 'shift', 'z')})\" @click=${this.onTapRedo}> </span>\n\n <span class=\"vline\"></span>\n\n <span button id=\"style-copy\" title=\"style copy (${this.getShortcutString('cmd', '1')})\" @click=${this.onStartStylePasteMode}> </span>\n <span button id=\"databind-copy\" title=\"databind copy (${this.getShortcutString('cmd', '2')})\" @click=${this.onStartDatabindPasteMode}> </span>\n\n <span class=\"vline\"></span>\n\n <span button id=\"cut\" title=\"cut (${this.getShortcutString('cmd', 'x')})\" @click=${this.onTapCut}> </span>\n <span button id=\"copy\" title=\"copy (${this.getShortcutString('cmd', 'c')})\" @click=${this.onTapCopy}> </span>\n <span button id=\"paste\" title=\"paste (${this.getShortcutString('cmd', 'v')})\" @click=${this.onTapPaste}> </span>\n <span button id=\"delete\"\n title=\"delete (${this.getShortcutString('backspace')}, ${this.getShortcutString('delete')})\"\n @click=${this.onTapDelete}> </span>\n\n <span class=\"vline\"></span>\n\n <span button data-align=\"left\" id=\"align-left\"\n title=\"align left (${this.getShortcutString('alt', 'shift', 'l')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"center\" id=\"align-center\"\n title=\"align center (${this.getShortcutString('alt', 'shift', 'c')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"right\" id=\"align-right\"\n title=\"align right (${this.getShortcutString('alt', 'shift', 'r')})\" @click=${this.onTapAlign}> </span>\n\n <span button data-align=\"top\" id=\"align-top\"\n title=\"align top (${this.getShortcutString('alt', 'shift', 't')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"middle\" id=\"align-middle\"\n title=\"align middle (${this.getShortcutString('alt', 'shift', 'm')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"bottom\" id=\"align-bottom\"\n title=\"align bottom (${this.getShortcutString('alt', 'shift', 'b')})\" @click=${this.onTapAlign}> </span>\n\n <span button data-distribute=\"HORIZONTAL\" id=\"distribute-horizontal\"\n title=\"distribute horizontally (${this.getShortcutString('alt', 'shift', 'h')})\" @click=${this.onTapDistribute}> </span>\n <span button data-distribute=\"VERTICAL\" id=\"distribute-vertical\"\n title=\"distribute vertically (${this.getShortcutString('alt', 'shift', 'v')})\" @click=${this.onTapDistribute}> </span>\n\n ${this._dimension === '3d'\n ? html`\n <span class=\"vline\"></span>\n\n <span button data-align=\"z-front\" id=\"align-z-front\" title=\"align Z front\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"z-middle\" id=\"align-z-middle\" title=\"align Z middle\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"z-back\" id=\"align-z-back\" title=\"align Z back\" @click=${this.onTapAlign}> </span>\n <span button data-distribute=\"Z\" id=\"distribute-z\" title=\"distribute Z\" @click=${this.onTapDistribute}> </span>\n `\n : this._dimension === '2d'\n ? html`\n <span class=\"vline\"></span>\n\n <span button id=\"front\" data-zorder=\"front\"\n title=\"bring to front (${this.getShortcutString('cmd', 'shift', 'f')})\" @click=${this.onTapZorder}> </span>\n <span button id=\"back\" data-zorder=\"back\"\n title=\"send to back (${this.getShortcutString('cmd', 'shift', 'b')})\" @click=${this.onTapZorder}> </span>\n <span button id=\"forward\" data-zorder=\"forward\"\n title=\"bring forward (${this.getShortcutString('cmd', 'f')})\" @click=${this.onTapZorder}> </span>\n <span button id=\"backward\" data-zorder=\"backward\"\n title=\"send backward (${this.getShortcutString('cmd', 'b')})\" @click=${this.onTapZorder}> </span>\n `\n : ''}\n\n ${this._dimension === '2d' ? html`\n <span class=\"vline\"></span>\n\n <span button id=\"group\" title=\"group (${this.getShortcutString('cmd', 'g')})\" @click=${this.onTapGroup}> </span>\n <span button id=\"ungroup\" title=\"ungroup (${this.getShortcutString('cmd', 'shift', 'g')})\" @click=${this.onTapUngroup}> </span>\n ` : this._dimension === '3d' ? html`\n <span class=\"vline\"></span>\n\n <span button class=\"gizmo-btn\" data-gizmo=\"translate\" title=\"Move (W)\"\n @click=${() => this._setGizmoMode('translate')}>\n <svg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <line x1=\"10\" y1=\"2\" x2=\"10\" y2=\"18\"/><line x1=\"2\" y1=\"10\" x2=\"18\" y2=\"10\"/>\n <polyline points=\"10,2 7.5,5\"/><polyline points=\"10,2 12.5,5\"/>\n <polyline points=\"18,10 15,7.5\"/><polyline points=\"18,10 15,12.5\"/>\n <polyline points=\"10,18 7.5,15\"/><polyline points=\"10,18 12.5,15\"/>\n <polyline points=\"2,10 5,7.5\"/><polyline points=\"2,10 5,12.5\"/>\n </svg>\n </span>\n <span button class=\"gizmo-btn\" data-gizmo=\"rotate\" title=\"Rotate (E)\"\n @click=${() => this._setGizmoMode('rotate')}>\n <svg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <path d=\"M14.5 3.5A7 7 0 1 0 17 10\"/>\n <polyline points=\"14,1 15,3.5 12.5,4.5\"/>\n </svg>\n </span>\n <span button class=\"gizmo-btn\" data-gizmo=\"scale\" title=\"Scale (R)\"\n @click=${() => this._setGizmoMode('scale')}>\n <svg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <line x1=\"4\" y1=\"16\" x2=\"16\" y2=\"4\"/>\n <rect x=\"2\" y=\"13\" width=\"4\" height=\"4\" rx=\"0.5\" fill=\"currentColor\"/>\n <rect x=\"14\" y=\"2\" width=\"4\" height=\"4\" rx=\"0.5\" fill=\"currentColor\"/>\n </svg>\n </span>\n ` : ''}\n\n <span class=\"vline\"></span>\n\n <span button id=\"font-increase\" title=\"increase font size\" @click=${this.onTapFontIncrease}></span>\n <span button id=\"font-decrease\" title=\"decrease font size\" style=\"scale: 0.7;\" @click=${this.onTapFontDecrease}></span>\n\n <span class=\"vline\"></span>\n <span>(v${process.env['APP-VERSION']})</span>\n <span padding></span>\n\n <span button id=\"fit-scene\" title=\"fit scene (${this.getShortcutString('cmd', 'd')})\" @click=${this.onTapFitScene}> </span>\n\n <span class=\"vline\"></span>\n\n <span button id=\"preview\" title=\"preview (${this.getShortcutString('ctrl', 'p')})\" @click=${this.onTapPreview}> </span>\n\n <span button id=\"fullscreen\" title=\"fullscreen (${this.getShortcutString('f11')})\" @click=${this.onTapFullscreen}> </span>\n\n <span button id=\"toggle-property\"\n title=\"toggle property panel (${this.getShortcutString('cmd', 'h')})\"\n toggles=\"true\" @click=${this.onTapToggle}> </span>\n </div>\n `\n }\n\n hasEmptySlot() {\n const slot = this.renderRoot.querySelector('slot') as HTMLSlotElement\n return slot?.assignedNodes().length === 0\n }\n\n onWheelEvent(e: Event) {\n var delta = Math.max(-1, Math.min(1, (e as WheelEvent).deltaY || -(e as WheelEvent).detail))\n this.scrollLeft -= delta * 40\n\n e.preventDefault()\n }\n\n getSymbol(key: string) {\n var symbol\n switch (key) {\n case 'cmd':\n case 'ctrl':\n symbol = MACOS ? '⌘' : 'Ctrl'\n break\n case 'shift':\n symbol = MACOS ? '⇧' : 'Shift'\n break\n case 'alt':\n case 'option':\n symbol = MACOS ? '⌥' : 'Alt'\n break\n case 'backspace':\n symbol = MACOS ? '⌫' : 'BackSpace'\n break\n case 'delete':\n symbol = MACOS ? '⌦' : 'Del'\n break\n default:\n symbol = key.toUpperCase()\n break\n }\n\n return symbol\n }\n\n private getShortcutString(...keys: string[]) {\n var symbols = []\n for (var i = 0; i < arguments.length; i++) {\n symbols.push(this.getSymbol(arguments[i]))\n }\n\n return symbols.join(MACOS ? '' : '+')\n }\n\n onShortcut(e: KeyboardEvent) {\n if (MACOS) var ctrlKey = e.metaKey\n else var ctrlKey = e.ctrlKey\n\n var altKey = e.altKey\n var shiftKey = e.shiftKey\n\n var defaultPrevent = ctrlKey || altKey\n\n switch (e.code) {\n case 'KeyZ':\n if (ctrlKey && !shiftKey) this.onTapUndo()\n else if (ctrlKey && shiftKey) this.onTapRedo()\n break\n case 'KeyY':\n if (ctrlKey && !shiftKey) this.onTapRedo()\n break\n case 'Digit1':\n if (ctrlKey) this.onStartStylePasteMode()\n break\n case 'Digit2':\n if (ctrlKey) this.onStartDatabindPasteMode()\n break\n case 'KeyC':\n if (ctrlKey && !shiftKey) this.onTapCopy()\n else if (altKey && shiftKey) this.onTapAlign('center')\n break\n case 'KeyX':\n if (ctrlKey && !shiftKey) this.onTapCut()\n break\n case 'KeyV':\n if (ctrlKey && shiftKey && !altKey) {\n // Ctrl+Shift+V = Bulk Paste (Paste Special 컨벤션) — 클립보드의\n // 단일 컴포넌트를 N개로 일괄 붙여넣기.\n this.onBulkPaste()\n defaultPrevent = true\n } else if (ctrlKey && !shiftKey) {\n this.onTapPaste()\n defaultPrevent = false\n } else if (altKey && shiftKey) this.onTapDistribute('VERTICAL')\n break\n case 'Delete':\n case 'Backspace':\n this.onTapDelete()\n defaultPrevent = true\n break\n case 'KeyG':\n if (this._dimension === '2d') {\n if (ctrlKey && !shiftKey) this.onTapGroup()\n else if (ctrlKey && shiftKey) this.onTapUngroup()\n }\n break\n case 'BracketRight':\n // Ctrl+] = Bring Forward, Ctrl+Shift+] = Bring to Front\n // (Photoshop / Illustrator 표준 컨벤션)\n if (this._dimension === '2d') {\n if (ctrlKey && !shiftKey) {\n this.scene?.zorder('forward')\n defaultPrevent = true\n } else if (ctrlKey && shiftKey) {\n this.scene?.zorder('front')\n defaultPrevent = true\n }\n }\n break\n case 'BracketLeft':\n // Ctrl+[ = Send Backward, Ctrl+Shift+[ = Send to Back\n if (this._dimension === '2d') {\n if (ctrlKey && !shiftKey) {\n this.scene?.zorder('backward')\n defaultPrevent = true\n } else if (ctrlKey && shiftKey) {\n this.scene?.zorder('back')\n defaultPrevent = true\n }\n }\n break\n case 'KeyB':\n // zorder 는 BracketLeft 로 이동. KeyB 의 Alt+Shift+B = align bottom 만 유지.\n if (altKey && shiftKey) this.onTapAlign('bottom')\n break\n case 'KeyH':\n if (ctrlKey && !shiftKey) this.onTapToggle()\n else if (altKey && shiftKey) this.onTapDistribute('HORIZONTAL')\n break\n case 'F11':\n this.onTapFullscreen()\n defaultPrevent = true\n break\n case 'KeyP':\n if (ctrlKey) {\n this.onTapPreview()\n defaultPrevent = true\n }\n break\n case 'KeyA':\n if (ctrlKey) this.onTapSelectAll()\n break\n case 'KeyL':\n if (altKey && shiftKey) this.onTapAlign('left')\n break\n case 'KeyR':\n if (altKey && shiftKey) this.onTapAlign('right')\n break\n case 'KeyM':\n if (altKey && shiftKey) this.onTapAlign('middle')\n break\n case 'KeyT':\n if (altKey && shiftKey) this.onTapAlign('top')\n break\n case 'KeyD':\n if (ctrlKey) {\n this.onTapFitScene()\n defaultPrevent = true\n }\n break\n case 'KeyE':\n if (ctrlKey && shiftKey) this.onTapDownloadModel()\n break\n\n case 'Escape':\n this.scene?.stopStylePasteMode()\n this.scene?.stopDatabindPasteMode()\n defaultPrevent = true\n break\n\n default:\n return false\n }\n\n if (defaultPrevent) e.preventDefault()\n return true\n }\n\n private _setDisabled(id: string, disabled: boolean) {\n const el = this.renderRoot.querySelector(`#${id}`)\n disabled ? el?.setAttribute('disabled', '') : el?.removeAttribute('disabled')\n }\n\n onExecute(command: string, undoable: boolean, redoable: boolean) {\n this._setDisabled('undo', !undoable)\n this._setDisabled('redo', !redoable)\n }\n\n onUndo(undoable: boolean, redoable: boolean) {\n this._setDisabled('undo', !undoable)\n this._setDisabled('redo', !redoable)\n }\n\n onRedo(undoable: boolean, redoable: boolean) {\n this._setDisabled('undo', !undoable)\n this._setDisabled('redo', !redoable)\n }\n\n onSceneChanged(after?: Scene, before?: Scene) {\n if (before) {\n before.off('execute', this.onExecute, this)\n before.off('undo', this.onUndo, this)\n before.off('redo', this.onRedo, this)\n before.off('dimension', this._onDimensionChanged, this)\n before.off('gizmoattach', this._onGizmoAttachChanged, this)\n }\n\n if (after) {\n after.on('execute', this.onExecute, this)\n after.on('undo', this.onUndo, this)\n after.on('redo', this.onRedo, this)\n after.on('dimension', this._onDimensionChanged, this)\n after.on('gizmoattach', this._onGizmoAttachChanged, this)\n\n // scene 설정 시 현재 dimension을 즉시 반영 (초기 이벤트를 놓친 경우 대비)\n const threed = (after as any).model_layer?.model?.threed\n this._dimension = threed ? '3d' : '2d'\n }\n }\n\n private _onDimensionChanged(dimension: '2d' | '3d') {\n this._dimension = dimension\n }\n\n private _onGizmoAttachChanged(isAttached: boolean) {\n this._gizmoAttached = isAttached\n }\n\n private _setGizmoMode(mode: 'translate' | 'rotate' | 'scale') {\n ;(this.scene?.root as any)?.setGizmoMode(mode)\n }\n\n onSelectedChanged(after: Component[], before: Component[]) {\n var hasSelection = after.length > 0\n var alignable = after.length > 1\n\n // 선택 필요 버튼\n ;['style-copy', 'databind-copy', 'cut', 'copy', 'delete'].forEach(id =>\n this._setDisabled(id, !hasSelection)\n )\n\n // 정렬 버튼\n this.renderRoot.querySelectorAll('[data-align]').forEach(el =>\n alignable ? el.removeAttribute('disabled') : el.setAttribute('disabled', '')\n )\n\n if (this._dimension === '2d') {\n var movable = after.length === 1\n\n /* forward, backward 이동은 한 컴포넌트만 가능하다. */\n this._setDisabled('forward', !movable)\n this._setDisabled('backward', !movable)\n\n /* 여러 컴포넌트는 front, back 이동이 가능하다. */\n this._setDisabled('front', !(alignable || movable))\n this._setDisabled('back', !(alignable || movable))\n }\n\n // 분배 버튼\n this.renderRoot.querySelectorAll('[data-distribute]').forEach(el =>\n alignable ? el.removeAttribute('disabled') : el.setAttribute('disabled', '')\n )\n\n if (this._dimension === '3d') {\n this.renderRoot.querySelectorAll('.gizmo-btn').forEach(btn => {\n hasSelection ? btn.removeAttribute('disabled') : btn.setAttribute('disabled', '')\n })\n }\n }\n\n onTapUndo() {\n this.scene?.undo()\n }\n\n onTapRedo() {\n this.scene?.redo()\n }\n\n onStartStylePasteMode() {\n if (this.selected?.length !== 1) return\n if (this.selected[0] === this.scene?.root) return\n this.scene?.startStylePasteMode()\n }\n\n onStartDatabindPasteMode() {\n if (this.selected?.length !== 1) return\n if (this.selected[0] === this.scene?.root) return\n this.scene?.startDatabindPasteMode()\n }\n\n onTapCut() {\n this.scene?.cut()\n }\n\n async onTapCopy() {\n var copied = this.scene?.copy()\n\n if (!copied) return\n\n await copyToClipboard(copied)\n this.cliped = copied\n }\n\n onTapPaste() {\n setTimeout(() => {\n this.cliped && this.scene?.paste(this.cliped)\n }, 100)\n }\n\n onTapDelete() {\n this.scene?.remove()\n }\n\n /**\n * 멀티 컴포넌트 일괄 붙여넣기 — Ctrl+Shift+V 진입점.\n *\n * 흐름:\n * 1. 클립보드 (this.cliped) 검증 — *단일* 컴포넌트만 허용\n * 2. scene.startBulkCreateMode → AddLayer 가 캔버스 위에 드래그 박스 그림\n * 3. 사용자가 영역 드래그 → Promise resolve({area, template})\n * ESC/취소 → Promise resolve(null)\n * 4. 영역이 결정되면 dialog 오픈\n */\n async onBulkPaste() {\n if (!this.cliped) {\n console.warn('bulk-paste: 먼저 Ctrl+C 로 컴포넌트를 복사하세요.')\n return\n }\n let parsed: any[]\n try {\n parsed = JSON.parse(this.cliped)\n } catch (e) {\n console.warn('bulk-paste: 클립보드 파싱 실패', e)\n return\n }\n if (!Array.isArray(parsed) || parsed.length === 0) {\n console.warn('bulk-paste: 클립보드 비어있음')\n return\n }\n if (parsed.length > 1) {\n console.warn('bulk-paste: 단일 컴포넌트만 일괄 붙여넣기 가능. 다중은 일반 paste 사용.')\n return\n }\n\n const template = parsed[0]\n // bulk 모드 임을 시각 구분하기 위해 파란 점선 (일반 add 의 검정과 색만 차별).\n const result = await this.scene?.startBulkCreateMode(template, { boxStrokeStyle: '#2964c2' })\n if (result) {\n this._openBulkCreateDialog(template, result.area)\n }\n }\n\n private _openBulkCreateDialog(\n template: Record<string, any>,\n initialArea: { left: number; top: number; width: number; height: number }\n ) {\n const dialogEl = document.createElement('bulk-create-dialog') as BulkCreateDialog\n dialogEl.template = template\n dialogEl.initialArea = initialArea\n // 충돌 검사용 — scene 의 모든 컴포넌트 id 수집.\n // (scene.ids 는 indexMap 기반인데 fmsim 의 일부 컴포넌트는 indexMap 미등록\n // 되는 케이스가 있어 직접 컴포넌트 트리 walk.)\n const existingIds = new Set<string>()\n const collectIds = (comp: any) => {\n if (!comp) return\n const id = comp?.state?.id ?? comp?.model?.id\n if (typeof id === 'string' && id) existingIds.add(id)\n const children = comp.components || []\n for (const c of children) collectIds(c)\n }\n const root = (this.scene as any)?.root\n if (root) collectIds(root)\n dialogEl.existingIds = existingIds\n dialogEl.onConfirm = (models) => {\n const scene = this.scene\n if (!scene || !models.length) {\n popup?.close()\n return\n }\n // cliped 의 template model 자체에서 type-aware bounds 추출. things-scene 의\n // component.bounds (= path bounding box) 와 동일 결과를 model JSON 의\n // type-specific 필드 (width/height, rx/ry, points) 만으로 계산.\n const bounds = deriveBoundsFromModel(template)\n scene.undoableChange(() => {\n for (const m of models) {\n const cx = m.left + m.width / 2\n const cy = m.top + m.height / 2\n scene.add(m, {\n left: cx - bounds.width / 2,\n top: cy - bounds.height / 2,\n width: bounds.width,\n height: bounds.height\n })\n }\n })\n popup?.close()\n }\n dialogEl.onCancel = () => {\n popup?.close()\n }\n const popup = OxPopup.open({\n template: dialogEl,\n backdrop: true\n })\n }\n\n onTapSelectAll() {\n this.scene?.select('(child)')\n }\n\n onTapFontIncrease(e: TouchEvent) {\n var selected = this.scene?.selected\n if (!selected || !selected.length) {\n return\n }\n\n this.scene?.undoableChange(function () {\n selected!.forEach(function (component: Component) {\n var fontSize = component.get('fontSize')\n\n if (!fontSize) fontSize = '15'\n\n if (fontSize) {\n var size = parseInt(fontSize)\n component.set('fontSize', size + 1)\n }\n })\n })\n }\n\n onTapFontDecrease(e: TouchEvent) {\n var selected = this.scene?.selected\n\n if (!selected || !selected.length) {\n return\n }\n\n this.scene?.undoableChange(function () {\n selected!.forEach(function (component: Component) {\n var fontSize = component.get('fontSize')\n\n if (!fontSize) fontSize = '15'\n\n if (fontSize) {\n var size = parseInt(fontSize)\n if (size > 1) component.set('fontSize', size - 1)\n }\n })\n })\n }\n\n onTapAlign(e: TouchEvent | string) {\n if (!this.scene) return\n\n var selected = this.scene.selected\n\n var align = typeof e === 'string' ? e : (e.target as HTMLElement).getAttribute('data-align')\n if (!align) {\n return\n }\n\n if (selected.length <= 1) {\n this.scene.place(align)\n } else {\n this.scene.align(align)\n }\n }\n\n onTapZorder(e: TouchEvent | string) {\n if (!this.scene) return\n\n var selected = this.scene.selected\n if (selected.length < 1) return\n\n var zorder = typeof e === 'string' ? e : (e.target as HTMLElement).getAttribute('data-zorder')\n\n zorder && this.scene.zorder(zorder)\n }\n\n onTapGroup() {\n this.scene && this.scene.group()\n }\n\n onTapUngroup() {\n this.scene && this.scene.ungroup()\n }\n\n onTapFullscreen() {\n this.dispatchEvent(new CustomEvent('modeller-fullscreen'))\n }\n\n onTapToggle() {\n this.hideProperty = !this.hideProperty\n this.dispatchEvent(\n new CustomEvent('hide-property-changed', {\n bubbles: true,\n composed: true,\n detail: { value: this.hideProperty }\n })\n )\n }\n\n onTapFitScene() {\n if (this.scene) {\n this.scene.resize()\n this.scene.fit('ratio')\n }\n }\n\n onTapPreview() {\n this.dispatchEvent(new CustomEvent('open-preview'))\n }\n\n onTapDownloadModel() {\n this.dispatchEvent(new CustomEvent('download-model'))\n }\n\n onTapDistribute(e: TouchEvent | string) {\n if (!this.scene) return\n\n var selected = this.scene.selected\n if (selected.length <= 1) {\n return\n }\n\n var distribute = typeof e === 'string' ? e : (e.target as HTMLElement)!.getAttribute('data-distribute')\n\n distribute && this.scene.distribute(distribute)\n }\n}\n"]}
@@ -23,9 +23,17 @@ export class AbstractProperty extends LitElement {
23
23
  case 'checkbox':
24
24
  value = element.checked;
25
25
  break;
26
- case 'number':
27
- value = Number(element.valueAsNumber);
26
+ case 'number': {
27
+ // Empty or invalid numeric input (e.g. user cleared the field)
28
+ // produces NaN via `valueAsNumber`. Persisting NaN poisons every
29
+ // downstream Math.* call and eventually surfaces as
30
+ // "BufferGeometry computeBoundingSphere: radius is NaN".
31
+ // Emit `undefined` so the component falls back to its default
32
+ // (e.g. Placeable's defaultDepth = operation - floor).
33
+ const n = element.valueAsNumber;
34
+ value = Number.isFinite(n) ? n : undefined;
28
35
  break;
36
+ }
29
37
  case 'text':
30
38
  value = String(element.value);
31
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"abstract-property.js","sourceRoot":"","sources":["../../../../src/modeller/property-sidebar/abstract-property.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAEhC,MAAM,OAAO,gBAAiB,SAAQ,UAAU;IAC9C,YAAY;QACV,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC5E,CAAC;IAED,cAAc,CAAC,CAAQ;QACrB,IAAI,OAAO,GAAG,CAAC,CAAC,MAAqB,CAAA;QACrC,IAAI,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA;QAE3C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAM;QACR,CAAC;QAED,IAAI,KAAK,GAAG,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAA;QAElD,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACtC,CAAC;IAED,wBAAwB,CAAC,OAAoB;QAC3C,IAAI,KAAK,CAAA;QAET,QAAQ,OAAO,CAAC,OAAO,EAAE,CAAC;YACxB,KAAK,OAAO;gBACV,QAAS,OAAe,CAAC,IAAI,EAAE,CAAC;oBAC9B,KAAK,UAAU;wBACb,KAAK,GAAI,OAAe,CAAC,OAAO,CAAA;wBAChC,MAAK;oBACP,KAAK,QAAQ;wBACX,KAAK,GAAG,MAAM,CAAE,OAAe,CAAC,aAAa,CAAC,CAAA;wBAC9C,MAAK;oBACP,KAAK,MAAM;wBACT,KAAK,GAAG,MAAM,CAAE,OAAe,CAAC,KAAK,CAAC,CAAA;gBAC1C,CAAC;gBACD,MAAK;YAEP,KAAK,cAAc;gBACjB,KAAK,GAAI,OAAe,CAAC,MAAM,CAAA;gBAC/B,MAAK;YAEP,KAAK,eAAe;gBAClB,KAAK,GAAI,OAAe,CAAC,QAAQ,CAAA;gBACjC,MAAK;YAEP;gBACE,KAAK,GAAI,OAAe,CAAC,KAAK,CAAA;gBAC9B,MAAK;QACT,CAAC;QAED,OAAO,KAAK,CAAA;IACd,CAAC;IAED,mBAAmB,CAAC,GAAW,EAAE,KAAU;QACzC,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,iBAAiB,EAAE;YACjC,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE;gBACN,CAAC,GAAG,CAAC,EAAE,KAAK;aACb;SACF,CAAC,CACH,CAAA;IACH,CAAC;CACF","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { LitElement } from 'lit'\n\nexport class AbstractProperty extends LitElement {\n firstUpdated() {\n this.renderRoot.addEventListener('change', this._onValueChange.bind(this))\n }\n\n _onValueChange(e: Event) {\n var element = e.target as HTMLElement\n var key = element.getAttribute('value-key')\n\n if (!key) {\n return\n }\n\n var value = this._getValueFromEventTarget(element)\n\n this._onAfterValueChange(key, value)\n }\n\n _getValueFromEventTarget(element: HTMLElement) {\n var value\n\n switch (element.tagName) {\n case 'INPUT':\n switch ((element as any).type) {\n case 'checkbox':\n value = (element as any).checked\n break\n case 'number':\n value = Number((element as any).valueAsNumber)\n break\n case 'text':\n value = String((element as any).value)\n }\n break\n\n case 'PAPER-BUTTON':\n value = (element as any).active\n break\n\n case 'PAPER-LISTBOX':\n value = (element as any).selected\n break\n\n default:\n value = (element as any).value\n break\n }\n\n return value\n }\n\n _onAfterValueChange(key: string, value: any) {\n this.dispatchEvent(\n new CustomEvent('property-change', {\n bubbles: true,\n composed: true,\n detail: {\n [key]: value\n }\n })\n )\n }\n}\n"]}
1
+ {"version":3,"file":"abstract-property.js","sourceRoot":"","sources":["../../../../src/modeller/property-sidebar/abstract-property.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAEhC,MAAM,OAAO,gBAAiB,SAAQ,UAAU;IAC9C,YAAY;QACV,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC5E,CAAC;IAED,cAAc,CAAC,CAAQ;QACrB,IAAI,OAAO,GAAG,CAAC,CAAC,MAAqB,CAAA;QACrC,IAAI,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA;QAE3C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAM;QACR,CAAC;QAED,IAAI,KAAK,GAAG,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAA;QAElD,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACtC,CAAC;IAED,wBAAwB,CAAC,OAAoB;QAC3C,IAAI,KAAK,CAAA;QAET,QAAQ,OAAO,CAAC,OAAO,EAAE,CAAC;YACxB,KAAK,OAAO;gBACV,QAAS,OAAe,CAAC,IAAI,EAAE,CAAC;oBAC9B,KAAK,UAAU;wBACb,KAAK,GAAI,OAAe,CAAC,OAAO,CAAA;wBAChC,MAAK;oBACP,KAAK,QAAQ,CAAC,CAAC,CAAC;wBACd,+DAA+D;wBAC/D,iEAAiE;wBACjE,oDAAoD;wBACpD,yDAAyD;wBACzD,8DAA8D;wBAC9D,uDAAuD;wBACvD,MAAM,CAAC,GAAI,OAAe,CAAC,aAAa,CAAA;wBACxC,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;wBAC1C,MAAK;oBACP,CAAC;oBACD,KAAK,MAAM;wBACT,KAAK,GAAG,MAAM,CAAE,OAAe,CAAC,KAAK,CAAC,CAAA;gBAC1C,CAAC;gBACD,MAAK;YAEP,KAAK,cAAc;gBACjB,KAAK,GAAI,OAAe,CAAC,MAAM,CAAA;gBAC/B,MAAK;YAEP,KAAK,eAAe;gBAClB,KAAK,GAAI,OAAe,CAAC,QAAQ,CAAA;gBACjC,MAAK;YAEP;gBACE,KAAK,GAAI,OAAe,CAAC,KAAK,CAAA;gBAC9B,MAAK;QACT,CAAC;QAED,OAAO,KAAK,CAAA;IACd,CAAC;IAED,mBAAmB,CAAC,GAAW,EAAE,KAAU;QACzC,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,iBAAiB,EAAE;YACjC,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE;gBACN,CAAC,GAAG,CAAC,EAAE,KAAK;aACb;SACF,CAAC,CACH,CAAA;IACH,CAAC;CACF","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { LitElement } from 'lit'\n\nexport class AbstractProperty extends LitElement {\n firstUpdated() {\n this.renderRoot.addEventListener('change', this._onValueChange.bind(this))\n }\n\n _onValueChange(e: Event) {\n var element = e.target as HTMLElement\n var key = element.getAttribute('value-key')\n\n if (!key) {\n return\n }\n\n var value = this._getValueFromEventTarget(element)\n\n this._onAfterValueChange(key, value)\n }\n\n _getValueFromEventTarget(element: HTMLElement) {\n var value\n\n switch (element.tagName) {\n case 'INPUT':\n switch ((element as any).type) {\n case 'checkbox':\n value = (element as any).checked\n break\n case 'number': {\n // Empty or invalid numeric input (e.g. user cleared the field)\n // produces NaN via `valueAsNumber`. Persisting NaN poisons every\n // downstream Math.* call and eventually surfaces as\n // \"BufferGeometry computeBoundingSphere: radius is NaN\".\n // Emit `undefined` so the component falls back to its default\n // (e.g. Placeable's defaultDepth = operation - floor).\n const n = (element as any).valueAsNumber\n value = Number.isFinite(n) ? n : undefined\n break\n }\n case 'text':\n value = String((element as any).value)\n }\n break\n\n case 'PAPER-BUTTON':\n value = (element as any).active\n break\n\n case 'PAPER-LISTBOX':\n value = (element as any).selected\n break\n\n default:\n value = (element as any).value\n break\n }\n\n return value\n }\n\n _onAfterValueChange(key: string, value: any) {\n this.dispatchEvent(\n new CustomEvent('property-change', {\n bubbles: true,\n composed: true,\n detail: {\n [key]: value\n }\n })\n )\n }\n}\n"]}
@@ -9,7 +9,7 @@ import { PropertyValues } from 'lit';
9
9
  import { Properties, Scene } from '@hatiolab/things-scene';
10
10
  import { AbstractProperty } from '../abstract-property.js';
11
11
  import { DataBindingMapper } from './data-binding-mapper.js';
12
- declare const PropertyDataBinding_base: typeof AbstractProperty & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types/src/types.js").ScopedElementsHost>;
12
+ declare const PropertyDataBinding_base: typeof AbstractProperty & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types.js").ScopedElementsHost>;
13
13
  export declare class PropertyDataBinding extends PropertyDataBinding_base {
14
14
  static styles: import("lit").CSSResult[];
15
15
  value?: Properties;
@@ -6,7 +6,7 @@ import { Component, Properties, Scene } from '@hatiolab/things-scene';
6
6
  import { AbstractProperty } from '../abstract-property.js';
7
7
  import { PropertyEvent } from './property-event.js';
8
8
  import { PropertyShadow } from './property-shadow.js';
9
- declare const PropertyEffects_base: typeof AbstractProperty & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types/src/types.js").ScopedElementsHost>;
9
+ declare const PropertyEffects_base: typeof AbstractProperty & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types.js").ScopedElementsHost>;
10
10
  export declare class PropertyEffects extends PropertyEffects_base {
11
11
  static styles: import("lit").CSSResult[];
12
12
  value?: Properties;
@@ -4,7 +4,7 @@
4
4
  import { LitElement } from 'lit';
5
5
  import { Properties, Scene } from '@hatiolab/things-scene';
6
6
  import { PropertyEventTap } from './property-event-tap';
7
- declare const PropertyEvent_base: typeof LitElement & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types/src/types").ScopedElementsHost>;
7
+ declare const PropertyEvent_base: typeof LitElement & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types.js").ScopedElementsHost>;
8
8
  export declare class PropertyEvent extends PropertyEvent_base {
9
9
  static styles: import("lit").CSSResult[];
10
10
  value?: Properties;
@@ -10,7 +10,7 @@ import { SceneInspector } from './inspector/inspector';
10
10
  import { PropertyShapes } from './shapes/shapes.js';
11
11
  import { PropertySpecific } from './specifics/specifics.js';
12
12
  import { PropertyStyles } from './styles/styles.js';
13
- declare const PropertySidebar_base: typeof LitElement & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types/src/types.js").ScopedElementsHost>;
13
+ declare const PropertySidebar_base: typeof LitElement & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types.js").ScopedElementsHost>;
14
14
  export declare class PropertySidebar extends PropertySidebar_base {
15
15
  static styles: import("lit").CSSResult[];
16
16
  scene: Scene | null;
@@ -22,6 +22,7 @@ export class PropertyShapes extends AbstractProperty {
22
22
  this.renderRoot.addEventListener('change', this._onValueChange.bind(this));
23
23
  }
24
24
  render() {
25
+ var _a, _b;
25
26
  const value = this.value || {};
26
27
  const { width, height } = this.bounds || {};
27
28
  return html `
@@ -85,6 +86,12 @@ export class PropertyShapes extends AbstractProperty {
85
86
  ${this.selected.length && this.selected[0].isRootModel()
86
87
  ? html ``
87
88
  : html `
89
+ <label class="depth"> <ox-i18n msgid="label.depth">depth</ox-i18n> </label>
90
+ <input type="number" value-key="depth" .value=${String((_a = value.depth) !== null && _a !== void 0 ? _a : '')} placeholder="auto" />
91
+
92
+ <label class="zPos"> <ox-i18n msgid="label.zPos">zPos</ox-i18n> </label>
93
+ <input type="number" value-key="zPos" .value=${String((_b = value.zPos) !== null && _b !== void 0 ? _b : '')} placeholder="auto" />
94
+
88
95
  <label class="rotate"> <ox-i18n msgid="label.rotate">rotate</ox-i18n> </label>
89
96
  <ox-input-angle value-key="rotation" .value=${value.rotation}> </ox-input-angle>
90
97
  `}
@@ -176,6 +183,26 @@ export class PropertyShapes extends AbstractProperty {
176
183
  <option value="width">width</option>
177
184
  <option value="height">height</option>
178
185
  </select>
186
+
187
+ <div class="checkbox-row">
188
+ <input
189
+ id="cb-threed"
190
+ type="checkbox"
191
+ value-key="threed"
192
+ .checked=${!!value.threed}
193
+ />
194
+ <label for="cb-threed"><ox-i18n msgid="label.start-in-3d">Start in 3D</ox-i18n></label>
195
+ </div>
196
+
197
+ <div class="checkbox-row">
198
+ <input
199
+ id="cb-floor-constraint"
200
+ type="checkbox"
201
+ value-key="cameraFloorConstraint"
202
+ .checked=${!!value.cameraFloorConstraint}
203
+ />
204
+ <label for="cb-floor-constraint"><ox-i18n msgid="label.keep-above-ground">Keep Above Ground</ox-i18n></label>
205
+ </div>
179
206
  </div>
180
207
  </fieldset>
181
208
  `
@@ -266,6 +293,10 @@ PropertyShapes.styles = [
266
293
  background: var(--url-icon-properties-label) 7px -900px no-repeat;
267
294
  }
268
295
 
296
+ .icon-label .checkbox-row label {
297
+ background: none;
298
+ }
299
+
269
300
  .icon-label label.width {
270
301
  background-position: 7px -96px;
271
302
  }