@fmsim/board 2.0.0-beta.99 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/custom-elements.json +2692 -2085
  2. package/dist/src/board-i18n.d.ts +37 -0
  3. package/dist/src/board-i18n.js +121 -0
  4. package/dist/src/board-i18n.js.map +1 -0
  5. package/dist/src/config/flow-replay.d.ts +14 -0
  6. package/dist/src/config/flow-replay.js +20 -0
  7. package/dist/src/config/flow-replay.js.map +1 -0
  8. package/dist/src/index.d.ts +2 -0
  9. package/dist/src/index.js +2 -0
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/layers/mcs-mouse-event-handler.js +21 -4
  12. package/dist/src/layers/mcs-mouse-event-handler.js.map +1 -1
  13. package/dist/src/layers/movement-layer.d.ts +5 -2
  14. package/dist/src/layers/movement-layer.js +19 -2
  15. package/dist/src/layers/movement-layer.js.map +1 -1
  16. package/dist/src/modeller/bulk-create-dialog.d.ts +12 -1
  17. package/dist/src/modeller/bulk-create-dialog.js +67 -3
  18. package/dist/src/modeller/bulk-create-dialog.js.map +1 -1
  19. package/dist/src/modeller/bulk-create.d.ts +6 -0
  20. package/dist/src/modeller/bulk-create.js +3 -1
  21. package/dist/src/modeller/bulk-create.js.map +1 -1
  22. package/dist/src/modeller/component-toolbar/component-toolbar.d.ts +6 -0
  23. package/dist/src/modeller/component-toolbar/component-toolbar.js +18 -2
  24. package/dist/src/modeller/component-toolbar/component-toolbar.js.map +1 -1
  25. package/dist/src/modeller/edit-toolbar.js +10 -1
  26. package/dist/src/modeller/edit-toolbar.js.map +1 -1
  27. package/dist/src/modeller/property-sidebar/effects/effects.js +3 -2
  28. package/dist/src/modeller/property-sidebar/effects/effects.js.map +1 -1
  29. package/dist/src/modeller/property-sidebar/inspector/inspector-controller.d.ts +9 -1
  30. package/dist/src/modeller/property-sidebar/inspector/inspector-controller.js +34 -4
  31. package/dist/src/modeller/property-sidebar/inspector/inspector-controller.js.map +1 -1
  32. package/dist/src/modeller/property-sidebar/inspector/inspector-group-view.d.ts +2 -0
  33. package/dist/src/modeller/property-sidebar/inspector/inspector-group-view.js +23 -4
  34. package/dist/src/modeller/property-sidebar/inspector/inspector-group-view.js.map +1 -1
  35. package/dist/src/modeller/property-sidebar/inspector/inspector.js +28 -5
  36. package/dist/src/modeller/property-sidebar/inspector/inspector.js.map +1 -1
  37. package/dist/src/modeller/property-sidebar/shapes/ox-input-entity-id.js +12 -3
  38. package/dist/src/modeller/property-sidebar/shapes/ox-input-entity-id.js.map +1 -1
  39. package/dist/src/modeller/property-sidebar/shapes/shapes.js +40 -24
  40. package/dist/src/modeller/property-sidebar/shapes/shapes.js.map +1 -1
  41. package/dist/src/modeller/property-sidebar/specifics/parent-object.d.ts +29 -0
  42. package/dist/src/modeller/property-sidebar/specifics/parent-object.js +74 -0
  43. package/dist/src/modeller/property-sidebar/specifics/parent-object.js.map +1 -0
  44. package/dist/src/modeller/property-sidebar/specifics/specifics.d.ts +4 -2
  45. package/dist/src/modeller/property-sidebar/specifics/specifics.js +13 -31
  46. package/dist/src/modeller/property-sidebar/specifics/specifics.js.map +1 -1
  47. package/dist/src/ox-board-modeller.js +9 -2
  48. package/dist/src/ox-board-modeller.js.map +1 -1
  49. package/dist/src/ox-board-viewer.js +16 -6
  50. package/dist/src/ox-board-viewer.js.map +1 -1
  51. package/dist/src/ox-editor-board-selector.js +4 -2
  52. package/dist/src/ox-editor-board-selector.js.map +1 -1
  53. package/dist/src/ox-playback-controls.d.ts +9 -0
  54. package/dist/src/ox-playback-controls.js +24 -0
  55. package/dist/src/ox-playback-controls.js.map +1 -1
  56. package/dist/src/scene-monitor-renderer.d.ts +10 -0
  57. package/dist/src/scene-monitor-renderer.js +226 -0
  58. package/dist/src/scene-monitor-renderer.js.map +1 -0
  59. package/dist/src/selector/ox-board-selector.js +2 -1
  60. package/dist/src/selector/ox-board-selector.js.map +1 -1
  61. package/dist/tsconfig.tsbuildinfo +1 -1
  62. package/package.json +15 -15
@@ -0,0 +1,37 @@
1
+ /**
2
+ * 보드명 다국어의 "현재 언어" 단일 출처.
3
+ *
4
+ * 임베디드(MCS/LV) 환경에서는 호스트가 세션 스토리지 `lv_server_lang` 으로 현재 사용자 언어를
5
+ * 알려주므로 그 값을 권위로 삼는다. `i18next.language` 는 이 앱 자체의 i18n 언어라 호스트 언어와
6
+ * 어긋날 수 있어(보드명만 다른 언어로 표시되는 문제) 쓰지 않는다. `lv_server_lang` 이 없는 단독
7
+ * 실행 등에서만 `i18next.language` 로 폴백한다.
8
+ */
9
+ export declare function getCurrentLang(): string;
10
+ /** MCS 세션 캐시 ifactI18nObj 의 키 = 지원 언어 목록. 없으면 현재 언어만. */
11
+ export declare function getSupportedLanguages(): string[];
12
+ /**
13
+ * 언어 코드를 사람이 읽기 쉬운 이름으로 변환한다(표시는 현재 UI 언어).
14
+ * Intl.DisplayNames 로 'en'→English, 'en-US'→American English, 'zh_CN'→Chinese(China) 처럼
15
+ * 같은 언어의 여러 로케일도 구분되게 표기한다. 비표준/해석 불가 코드(예: 'ua')는 코드 그대로.
16
+ */
17
+ export declare function languageLabel(code: string): string;
18
+ /** nameI18n(JSON 문자열 또는 객체)을 언어→이름 맵으로 파싱. */
19
+ export declare function parseNameI18n(nameI18n: any): Record<string, string>;
20
+ /** 채워진 항목만 남긴 맵을 JSON 문자열로. 비어 있으면 undefined(저장 안 함). */
21
+ export declare function stringifyNameI18n(map: Record<string, string>): string | undefined;
22
+ /**
23
+ * 언어 맵에서 lang 에 해당하는 값을 관대하게 찾는다. 없으면 ''.
24
+ * 1) 정확 일치 2) 구분자 정규화(zh-CN↔zh_CN) 3) 베이스 언어(en-US→en) 4) 키 베이스 일치
25
+ */
26
+ export declare function pickLangValue(map: Record<string, string>, lang: string): string;
27
+ /**
28
+ * 보드명 표시/리스팅의 단일 진입점.
29
+ *
30
+ * 언어 해석은 이제 백엔드(fmb-service)가 담당한다 — 요청 언어(X-Lang=lv_server_lang)로 계산한
31
+ * `displayName` 을 응답에 실어 주므로, 표시 측은 그 값을 그대로 쓰고(없으면 대표명 name 폴백)
32
+ * 클라이언트에서 nameI18n 맵을 다시 해석하지 않는다. (nameI18n/pickLangValue 는 편집 폼 전용.)
33
+ */
34
+ export declare function resolveBoardName(board: {
35
+ name?: string;
36
+ displayName?: string;
37
+ } | null | undefined): string;
@@ -0,0 +1,121 @@
1
+ /**
2
+ * 보드명 다국어 유틸 (공유).
3
+ *
4
+ * 서버는 보드의 대표명(name) + 전체 다국어 맵(nameI18n JSON)만 내려주고, "현재 언어로 무엇을
5
+ * 보여줄지"는 클라이언트가 정한다. 보드명을 화면에 표시/리스팅하는 모든 곳에서 resolveBoardName 을
6
+ * 사용해야 일관되게 현재 언어 이름(없으면 대표명)으로 표시된다.
7
+ *
8
+ * @fmsim/board 에 두어 board/fmsim-restful 등 모든 클라이언트 컴포넌트가 공유한다.
9
+ */
10
+ import { i18next } from '@operato/i18n';
11
+ /**
12
+ * 보드명 다국어의 "현재 언어" 단일 출처.
13
+ *
14
+ * 임베디드(MCS/LV) 환경에서는 호스트가 세션 스토리지 `lv_server_lang` 으로 현재 사용자 언어를
15
+ * 알려주므로 그 값을 권위로 삼는다. `i18next.language` 는 이 앱 자체의 i18n 언어라 호스트 언어와
16
+ * 어긋날 수 있어(보드명만 다른 언어로 표시되는 문제) 쓰지 않는다. `lv_server_lang` 이 없는 단독
17
+ * 실행 등에서만 `i18next.language` 로 폴백한다.
18
+ */
19
+ export function getCurrentLang() {
20
+ try {
21
+ const lv = sessionStorage.getItem('lv_server_lang');
22
+ if (lv && lv.trim())
23
+ return lv.trim();
24
+ }
25
+ catch (_a) {
26
+ /* sessionStorage 접근 불가 시 폴백 */
27
+ }
28
+ return i18next.language || '';
29
+ }
30
+ /** MCS 세션 캐시 ifactI18nObj 의 키 = 지원 언어 목록. 없으면 현재 언어만. */
31
+ export function getSupportedLanguages() {
32
+ try {
33
+ const raw = sessionStorage.getItem('ifactI18nObj');
34
+ if (raw) {
35
+ const keys = Object.keys(JSON.parse(raw) || {});
36
+ if (keys.length)
37
+ return keys;
38
+ }
39
+ }
40
+ catch (_a) {
41
+ /* 파싱 실패 시 폴백 */
42
+ }
43
+ const cur = getCurrentLang();
44
+ return cur ? [cur] : [];
45
+ }
46
+ /**
47
+ * 언어 코드를 사람이 읽기 쉬운 이름으로 변환한다(표시는 현재 UI 언어).
48
+ * Intl.DisplayNames 로 'en'→English, 'en-US'→American English, 'zh_CN'→Chinese(China) 처럼
49
+ * 같은 언어의 여러 로케일도 구분되게 표기한다. 비표준/해석 불가 코드(예: 'ua')는 코드 그대로.
50
+ */
51
+ export function languageLabel(code) {
52
+ const c = (code || '').trim();
53
+ if (!c)
54
+ return '';
55
+ try {
56
+ const dn = new Intl.DisplayNames([getCurrentLang() || 'en'], { type: 'language' });
57
+ const name = dn.of(c.replace(/_/g, '-'));
58
+ if (name && name.toLowerCase() !== c.toLowerCase())
59
+ return name;
60
+ }
61
+ catch (_a) {
62
+ /* 비표준 코드 등 → 코드 그대로 */
63
+ }
64
+ return c;
65
+ }
66
+ /** nameI18n(JSON 문자열 또는 객체)을 언어→이름 맵으로 파싱. */
67
+ export function parseNameI18n(nameI18n) {
68
+ if (!nameI18n)
69
+ return {};
70
+ if (typeof nameI18n === 'object')
71
+ return { ...nameI18n };
72
+ try {
73
+ return JSON.parse(nameI18n) || {};
74
+ }
75
+ catch (_a) {
76
+ return {};
77
+ }
78
+ }
79
+ /** 채워진 항목만 남긴 맵을 JSON 문자열로. 비어 있으면 undefined(저장 안 함). */
80
+ export function stringifyNameI18n(map) {
81
+ const cleaned = {};
82
+ for (const [k, v] of Object.entries(map || {})) {
83
+ if (v != null && String(v).trim() !== '')
84
+ cleaned[k] = String(v);
85
+ }
86
+ return Object.keys(cleaned).length ? JSON.stringify(cleaned) : undefined;
87
+ }
88
+ /**
89
+ * 언어 맵에서 lang 에 해당하는 값을 관대하게 찾는다. 없으면 ''.
90
+ * 1) 정확 일치 2) 구분자 정규화(zh-CN↔zh_CN) 3) 베이스 언어(en-US→en) 4) 키 베이스 일치
91
+ */
92
+ export function pickLangValue(map, lang) {
93
+ if (!lang || !map)
94
+ return '';
95
+ if (map[lang])
96
+ return map[lang];
97
+ const under = lang.replace(/-/g, '_');
98
+ if (map[under])
99
+ return map[under];
100
+ const dash = lang.replace(/_/g, '-');
101
+ if (map[dash])
102
+ return map[dash];
103
+ const base = lang.split(/[-_]/)[0];
104
+ if (map[base])
105
+ return map[base];
106
+ const hit = Object.keys(map).find(k => k.split(/[-_]/)[0] === base);
107
+ return (hit && map[hit]) || '';
108
+ }
109
+ /**
110
+ * 보드명 표시/리스팅의 단일 진입점.
111
+ *
112
+ * 언어 해석은 이제 백엔드(fmb-service)가 담당한다 — 요청 언어(X-Lang=lv_server_lang)로 계산한
113
+ * `displayName` 을 응답에 실어 주므로, 표시 측은 그 값을 그대로 쓰고(없으면 대표명 name 폴백)
114
+ * 클라이언트에서 nameI18n 맵을 다시 해석하지 않는다. (nameI18n/pickLangValue 는 편집 폼 전용.)
115
+ */
116
+ export function resolveBoardName(board) {
117
+ if (!board)
118
+ return '';
119
+ return board.displayName || board.name || '';
120
+ }
121
+ //# sourceMappingURL=board-i18n.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"board-i18n.js","sourceRoot":"","sources":["../../src/board-i18n.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * 보드명 다국어 유틸 (공유).\n *\n * 서버는 보드의 대표명(name) + 전체 다국어 맵(nameI18n JSON)만 내려주고, \"현재 언어로 무엇을\n * 보여줄지\"는 클라이언트가 정한다. 보드명을 화면에 표시/리스팅하는 모든 곳에서 resolveBoardName 을\n * 사용해야 일관되게 현재 언어 이름(없으면 대표명)으로 표시된다.\n *\n * @fmsim/board 에 두어 board/fmsim-restful 등 모든 클라이언트 컴포넌트가 공유한다.\n */\nimport { i18next } from '@operato/i18n'\n\n/**\n * 보드명 다국어의 \"현재 언어\" 단일 출처.\n *\n * 임베디드(MCS/LV) 환경에서는 호스트가 세션 스토리지 `lv_server_lang` 으로 현재 사용자 언어를\n * 알려주므로 그 값을 권위로 삼는다. `i18next.language` 는 이 앱 자체의 i18n 언어라 호스트 언어와\n * 어긋날 수 있어(보드명만 다른 언어로 표시되는 문제) 쓰지 않는다. `lv_server_lang` 이 없는 단독\n * 실행 등에서만 `i18next.language` 로 폴백한다.\n */\nexport function getCurrentLang(): string {\n try {\n const lv = sessionStorage.getItem('lv_server_lang')\n if (lv && lv.trim()) return lv.trim()\n } catch {\n /* sessionStorage 접근 불가 시 폴백 */\n }\n return i18next.language || ''\n}\n\n/** MCS 세션 캐시 ifactI18nObj 의 키 = 지원 언어 목록. 없으면 현재 언어만. */\nexport function getSupportedLanguages(): string[] {\n try {\n const raw = sessionStorage.getItem('ifactI18nObj')\n if (raw) {\n const keys = Object.keys(JSON.parse(raw) || {})\n if (keys.length) return keys\n }\n } catch {\n /* 파싱 실패 시 폴백 */\n }\n const cur = getCurrentLang()\n return cur ? [cur] : []\n}\n\n/**\n * 언어 코드를 사람이 읽기 쉬운 이름으로 변환한다(표시는 현재 UI 언어).\n * Intl.DisplayNames 로 'en'→English, 'en-US'→American English, 'zh_CN'→Chinese(China) 처럼\n * 같은 언어의 여러 로케일도 구분되게 표기한다. 비표준/해석 불가 코드(예: 'ua')는 코드 그대로.\n */\nexport function languageLabel(code: string): string {\n const c = (code || '').trim()\n if (!c) return ''\n try {\n const dn = new (Intl as any).DisplayNames([getCurrentLang() || 'en'], { type: 'language' })\n const name = dn.of(c.replace(/_/g, '-'))\n if (name && name.toLowerCase() !== c.toLowerCase()) return name\n } catch {\n /* 비표준 코드 등 → 코드 그대로 */\n }\n return c\n}\n\n/** nameI18n(JSON 문자열 또는 객체)을 언어→이름 맵으로 파싱. */\nexport function parseNameI18n(nameI18n: any): Record<string, string> {\n if (!nameI18n) return {}\n if (typeof nameI18n === 'object') return { ...nameI18n }\n try {\n return JSON.parse(nameI18n) || {}\n } catch {\n return {}\n }\n}\n\n/** 채워진 항목만 남긴 맵을 JSON 문자열로. 비어 있으면 undefined(저장 안 함). */\nexport function stringifyNameI18n(map: Record<string, string>): string | undefined {\n const cleaned: Record<string, string> = {}\n for (const [k, v] of Object.entries(map || {})) {\n if (v != null && String(v).trim() !== '') cleaned[k] = String(v)\n }\n return Object.keys(cleaned).length ? JSON.stringify(cleaned) : undefined\n}\n\n/**\n * 언어 맵에서 lang 에 해당하는 값을 관대하게 찾는다. 없으면 ''.\n * 1) 정확 일치 2) 구분자 정규화(zh-CN↔zh_CN) 3) 베이스 언어(en-US→en) 4) 키 베이스 일치\n */\nexport function pickLangValue(map: Record<string, string>, lang: string): string {\n if (!lang || !map) return ''\n if (map[lang]) return map[lang]\n const under = lang.replace(/-/g, '_')\n if (map[under]) return map[under]\n const dash = lang.replace(/_/g, '-')\n if (map[dash]) return map[dash]\n const base = lang.split(/[-_]/)[0]\n if (map[base]) return map[base]\n const hit = Object.keys(map).find(k => k.split(/[-_]/)[0] === base)\n return (hit && map[hit]) || ''\n}\n\n/**\n * 보드명 표시/리스팅의 단일 진입점.\n *\n * 언어 해석은 이제 백엔드(fmb-service)가 담당한다 — 요청 언어(X-Lang=lv_server_lang)로 계산한\n * `displayName` 을 응답에 실어 주므로, 표시 측은 그 값을 그대로 쓰고(없으면 대표명 name 폴백)\n * 클라이언트에서 nameI18n 맵을 다시 해석하지 않는다. (nameI18n/pickLangValue 는 편집 폼 전용.)\n */\nexport function resolveBoardName(\n board: { name?: string; displayName?: string } | null | undefined\n): string {\n if (!board) return ''\n return board.displayName || board.name || ''\n}\n"]}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Flow-Replay(플레이백 = 과거 흐름 재생) 기능 ON/OFF 전역 설정.
3
+ *
4
+ * 3D 기능(things-scene 의 setThreedEnabled/isThreedEnabled)과 같은 방식이지만,
5
+ * 플레이백은 전적으로 fmsim(board) 안의 기능이라 엔진 전역이 아니라 fmsim 전역으로 둔다.
6
+ * 부트스트랩이 <things-app flow-replay-enabled="false"> 를 딱 한 번 읽어 여기에 밀어넣고,
7
+ * 뷰어(ox-board-viewer)가 이 값을 참조해 재생 FAB·시작 경로를 게이팅한다.
8
+ *
9
+ * 판정 규칙은 3D 와 동일한 opt-out: 명시적으로 "false" 일 때만 비활성, 그 외 전부 활성(기본 ON).
10
+ */
11
+ /** Flow-Replay(플레이백) 전역 활성 여부 설정. 부트스트랩에서 한 번 호출. */
12
+ export declare function setFlowReplayEnabled(enabled: boolean): void;
13
+ /** Flow-Replay(플레이백) 전역 활성 여부. 기본 true(활성). */
14
+ export declare function isFlowReplayEnabled(): boolean;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Flow-Replay(플레이백 = 과거 흐름 재생) 기능 ON/OFF 전역 설정.
3
+ *
4
+ * 3D 기능(things-scene 의 setThreedEnabled/isThreedEnabled)과 같은 방식이지만,
5
+ * 플레이백은 전적으로 fmsim(board) 안의 기능이라 엔진 전역이 아니라 fmsim 전역으로 둔다.
6
+ * 부트스트랩이 <things-app flow-replay-enabled="false"> 를 딱 한 번 읽어 여기에 밀어넣고,
7
+ * 뷰어(ox-board-viewer)가 이 값을 참조해 재생 FAB·시작 경로를 게이팅한다.
8
+ *
9
+ * 판정 규칙은 3D 와 동일한 opt-out: 명시적으로 "false" 일 때만 비활성, 그 외 전부 활성(기본 ON).
10
+ */
11
+ let _flowReplayEnabled = true;
12
+ /** Flow-Replay(플레이백) 전역 활성 여부 설정. 부트스트랩에서 한 번 호출. */
13
+ export function setFlowReplayEnabled(enabled) {
14
+ _flowReplayEnabled = enabled;
15
+ }
16
+ /** Flow-Replay(플레이백) 전역 활성 여부. 기본 true(활성). */
17
+ export function isFlowReplayEnabled() {
18
+ return _flowReplayEnabled;
19
+ }
20
+ //# sourceMappingURL=flow-replay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow-replay.js","sourceRoot":"","sources":["../../../src/config/flow-replay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,IAAI,kBAAkB,GAAG,IAAI,CAAA;AAE7B,qDAAqD;AACrD,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,kBAAkB,GAAG,OAAO,CAAA;AAC9B,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,mBAAmB;IACjC,OAAO,kBAAkB,CAAA;AAC3B,CAAC","sourcesContent":["/**\n * Flow-Replay(플레이백 = 과거 흐름 재생) 기능 ON/OFF 전역 설정.\n *\n * 3D 기능(things-scene 의 setThreedEnabled/isThreedEnabled)과 같은 방식이지만,\n * 플레이백은 전적으로 fmsim(board) 안의 기능이라 엔진 전역이 아니라 fmsim 전역으로 둔다.\n * 부트스트랩이 <things-app flow-replay-enabled=\"false\"> 를 딱 한 번 읽어 여기에 밀어넣고,\n * 뷰어(ox-board-viewer)가 이 값을 참조해 재생 FAB·시작 경로를 게이팅한다.\n *\n * 판정 규칙은 3D 와 동일한 opt-out: 명시적으로 \"false\" 일 때만 비활성, 그 외 전부 활성(기본 ON).\n */\n\nlet _flowReplayEnabled = true\n\n/** Flow-Replay(플레이백) 전역 활성 여부 설정. 부트스트랩에서 한 번 호출. */\nexport function setFlowReplayEnabled(enabled: boolean): void {\n _flowReplayEnabled = enabled\n}\n\n/** Flow-Replay(플레이백) 전역 활성 여부. 기본 true(활성). */\nexport function isFlowReplayEnabled(): boolean {\n return _flowReplayEnabled\n}\n"]}
@@ -1,4 +1,6 @@
1
1
  export * from './types.js';
2
+ export { setFlowReplayEnabled, isFlowReplayEnabled } from './config/flow-replay.js';
3
+ export { resolveBoardName, parseNameI18n, stringifyNameI18n, pickLangValue, getSupportedLanguages, languageLabel, getCurrentLang } from './board-i18n.js';
2
4
  export { registerDefaultGroups } from './component/register-default-groups.js';
3
5
  export { DataStorage } from './data-storage/data-storage.js';
4
6
  export { PlaybackEngine } from './playback/playback-engine.js';
package/dist/src/index.js CHANGED
@@ -1,4 +1,6 @@
1
1
  export * from './types.js';
2
+ export { setFlowReplayEnabled, isFlowReplayEnabled } from './config/flow-replay.js';
3
+ export { resolveBoardName, parseNameI18n, stringifyNameI18n, pickLangValue, getSupportedLanguages, languageLabel, getCurrentLang } from './board-i18n.js';
2
4
  export { registerDefaultGroups } from './component/register-default-groups.js';
3
5
  export { DataStorage } from './data-storage/data-storage.js';
4
6
  export { PlaybackEngine } from './playback/playback-engine.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAE1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAA;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAA;AAGrE,cAAc,sBAAsB,CAAA;AACpC,cAAc,wBAAwB,CAAA;AACtC,cAAc,oBAAoB,CAAA;AAElC,cAAc,sBAAsB,CAAA","sourcesContent":["export * from './types.js'\n\nexport { registerDefaultGroups } from './component/register-default-groups.js'\nexport { DataStorage } from './data-storage/data-storage.js'\nexport { PlaybackEngine } from './playback/playback-engine.js'\nexport { BoardModelCache } from './data-storage/board-model-cache.js'\nexport type { CachedBoard } from './data-storage/board-model-cache.js'\n\nexport * from './ox-board-viewer.js'\nexport * from './ox-board-modeller.js'\nexport * from './ox-board-list.js'\n\nexport * from './component/index.js'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAE1B,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AACnF,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,qBAAqB,EACrB,aAAa,EACb,cAAc,EACf,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAA;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAA;AAGrE,cAAc,sBAAsB,CAAA;AACpC,cAAc,wBAAwB,CAAA;AACtC,cAAc,oBAAoB,CAAA;AAElC,cAAc,sBAAsB,CAAA","sourcesContent":["export * from './types.js'\n\nexport { setFlowReplayEnabled, isFlowReplayEnabled } from './config/flow-replay.js'\nexport {\n resolveBoardName,\n parseNameI18n,\n stringifyNameI18n,\n pickLangValue,\n getSupportedLanguages,\n languageLabel,\n getCurrentLang\n} from './board-i18n.js'\nexport { registerDefaultGroups } from './component/register-default-groups.js'\nexport { DataStorage } from './data-storage/data-storage.js'\nexport { PlaybackEngine } from './playback/playback-engine.js'\nexport { BoardModelCache } from './data-storage/board-model-cache.js'\nexport type { CachedBoard } from './data-storage/board-model-cache.js'\n\nexport * from './ox-board-viewer.js'\nexport * from './ox-board-modeller.js'\nexport * from './ox-board-list.js'\n\nexport * from './component/index.js'\n"]}
@@ -1,6 +1,6 @@
1
1
  import { EventMap } from '@hatiolab/things-scene';
2
2
  function dispatchFetchLvModelDataByMouseEvent(type, event, target) {
3
- var _a;
3
+ var _a, _b, _c;
4
4
  // 플레이백 모드 — 함수 자체를 실행하지 않음.
5
5
  // 1) 외부 모니터링 fetchLvModelDataByMouseEvent window 이벤트 차단
6
6
  // 2) realTarget 반환 차단 → onclick 의 후속 clickComponent dispatch 가
@@ -9,6 +9,10 @@ function dispatchFetchLvModelDataByMouseEvent(type, event, target) {
9
9
  if ((_a = target === null || target === void 0 ? void 0 : target.root) === null || _a === void 0 ? void 0 : _a.playbackMode)
10
10
  return undefined;
11
11
  const parent = target.parentObject;
12
+ // CapacityBar(Stocker/Zone) 처럼 세그먼트 게이지를 그리는 컴포넌트는, carrier/abnormal
13
+ // 모드에서 클릭된 세그먼트(Full/Empty/EmptyEmpty/Normal/Abnormal)를 함께 실어 보낸다.
14
+ // capacity 모드·비세그먼트 컴포넌트는 undefined → 필드 미포함.
15
+ const segment = (_c = (_b = target).segmentAtEvent) === null || _c === void 0 ? void 0 : _c.call(_b, event);
12
16
  if (target.getState('id')) {
13
17
  window.dispatchEvent(new CustomEvent('fetchLvModelDataByMouseEvent', {
14
18
  detail: {
@@ -24,20 +28,33 @@ function dispatchFetchLvModelDataByMouseEvent(type, event, target) {
24
28
  }
25
29
  : null
26
30
  },
27
- data: target.data
31
+ data: target.data,
32
+ ...(segment ? { segment } : {})
28
33
  }
29
34
  }
30
35
  }));
31
36
  return parent || target;
32
37
  }
33
38
  else if (parent && parent.getState('id')) {
39
+ // 클릭된 컴포넌트(target)가 자기 id 없이 id 보유 부모(Machine 등) 안에 배치된 경우 —
40
+ // 예: id 미지정 StockerCapacityBar / ZoneCapacityBar. 이때도 model 은 *실제 클릭된
41
+ // 컴포넌트* 를 실어 model.type 이 자신의 타입이 되게 한다(부모 타입 stocker 로 치환 금지).
42
+ // target 은 자기 id 가 없으므로, 주소가 되는 부모 id/type 은 parentObject 로 실어 위
43
+ // 분기(target 이 id 를 가진 경우)와 payload 형태를 동일하게 맞춘다.
34
44
  window.dispatchEvent(new CustomEvent('fetchLvModelDataByMouseEvent', {
35
45
  detail: {
36
46
  value: {
37
47
  type,
38
48
  event,
39
- model: parent.state,
40
- data: parent.data
49
+ model: {
50
+ ...target.state,
51
+ parentObject: {
52
+ id: parent.get('id'),
53
+ type: parent.get('type')
54
+ }
55
+ },
56
+ data: target.data,
57
+ ...(segment ? { segment } : {})
41
58
  }
42
59
  }
43
60
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"mcs-mouse-event-handler.js","sourceRoot":"","sources":["../../../src/layers/mcs-mouse-event-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAE5D,SAAS,oCAAoC,CAC3C,IAAoC,EACpC,KAAiB,EACjB,MAAgD;;IAEhD,4BAA4B;IAC5B,0DAA0D;IAC1D,iEAAiE;IACjE,iEAAiE;IACjE,sDAAsD;IACtD,IAAI,MAAC,MAAc,aAAd,MAAM,uBAAN,MAAM,CAAU,IAAI,0CAAE,YAAY;QAAE,OAAO,SAAS,CAAA;IAEzD,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAA;IAElC,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,aAAa,CAClB,IAAI,WAAW,CAAC,8BAA8B,EAAE;YAC9C,MAAM,EAAE;gBACN,KAAK,EAAE;oBACL,IAAI;oBACJ,KAAK;oBACL,KAAK,EAAE;wBACL,GAAG,MAAM,CAAC,KAAK;wBACf,YAAY,EAAE,MAAM;4BAClB,CAAC,CAAC;gCACE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;gCACpB,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;6BACzB;4BACH,CAAC,CAAC,IAAI;qBACT;oBACD,IAAI,EAAE,MAAM,CAAC,IAAI;iBAClB;aACF;SACF,CAAC,CACH,CAAA;QAED,OAAO,MAAM,IAAI,MAAM,CAAA;IACzB,CAAC;SAAM,IAAI,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,MAAM,CAAC,aAAa,CAClB,IAAI,WAAW,CAAC,8BAA8B,EAAE;YAC9C,MAAM,EAAE;gBACN,KAAK,EAAE;oBACL,IAAI;oBACJ,KAAK;oBACL,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,IAAI,EAAE,MAAM,CAAC,IAAI;iBAClB;aACF;SACF,CAAC,CACH,CAAA;QAED,OAAO,MAAM,CAAA;IACf,CAAC;AACH,CAAC;AAED,wDAAwD;AACxD,+BAA+B;AAE/B,4BAA4B;AAE5B,iEAAiE;AACjE,IAAI;AAEJ,SAAS,OAAO,CAAC,KAAiB,EAAE,IAAS;IAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;IAE1B,KAAK,CAAC,eAAe,EAAE,CAAA;IAEvB,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,MAAM,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;YACvC,MAAM,UAAU,GAAG,oCAAoC,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;YAE/E,MAAM,CAAC,aAAa,CAClB,IAAI,WAAW,CAAC,gBAAgB,EAAE;gBAChC,MAAM,EAAE,UAAU,IAAI,MAAM;aAC7B,CAAC,CACH,CAAA;QACH,CAAC;IACH,CAAC,EAAE,GAAG,CAAC,CAAA;AACT,CAAC;AAED,SAAS,UAAU,CAAC,KAAiB,EAAE,IAAS;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;IAE1B,UAAU,CAAC,GAAG,EAAE;QACd,MAAM,CAAC,YAAY,GAAG,EAAE,CAAA;IAC1B,CAAC,EAAE,GAAG,CAAC,CAAA;IAEP,KAAK,CAAC,eAAe,EAAE,CAAA;IAEvB,MAAM,CAAC,YAAY,GAAG,UAAU,CAAA;IAEhC,oCAAoC,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;AACjE,CAAC;AAED,QAAQ,CAAC,QAAQ,CAAC,mBAAmB,EAAE;IACrC,aAAa,EAAE;QACb,OAAO,EAAE;YACP,6CAA6C;YAC7C,KAAK,EAAE,OAAO;YACd,QAAQ,EAAE,UAAU;SACrB;KACF;CACF,CAAC,CAAA","sourcesContent":["import { Component, EventMap } from '@hatiolab/things-scene'\n\nfunction dispatchFetchLvModelDataByMouseEvent(\n type: 'hover' | 'click' | 'dblclick',\n event: MouseEvent,\n target: Component & { parentObject?: Component }\n): Component | undefined {\n // 플레이백 모드 — 함수 자체를 실행하지 않음.\n // 1) 외부 모니터링 fetchLvModelDataByMouseEvent window 이벤트 차단\n // 2) realTarget 반환 차단 → onclick 의 후속 clickComponent dispatch 가\n // realTarget = undefined 로 흘러 popup 등 후속 backend 호출 경로도 비활성\n // (popup 의 detailInfo() 가드와 더불어 백엔드 요청을 차단하는 1차 게이트.)\n if ((target as any)?.root?.playbackMode) return undefined\n\n const parent = target.parentObject\n\n if (target.getState('id')) {\n window.dispatchEvent(\n new CustomEvent('fetchLvModelDataByMouseEvent', {\n detail: {\n value: {\n type,\n event,\n model: {\n ...target.state,\n parentObject: parent\n ? {\n id: parent.get('id'),\n type: parent.get('type')\n }\n : null\n },\n data: target.data\n }\n }\n })\n )\n\n return parent || target\n } else if (parent && parent.getState('id')) {\n window.dispatchEvent(\n new CustomEvent('fetchLvModelDataByMouseEvent', {\n detail: {\n value: {\n type,\n event,\n model: parent.state,\n data: parent.data\n }\n }\n })\n )\n\n return parent\n }\n}\n\n// function onmouseenter(event: MouseEvent, hint: any) {\n// const target = hint.origin\n\n// event.stopPropagation()\n\n// dispatchFetchLvModelDataByMouseEvent('hover', event, target)\n// }\n\nfunction onclick(event: MouseEvent, hint: any) {\n const target = hint.origin\n\n event.stopPropagation()\n\n setTimeout(() => {\n if (target.currentEvent !== 'dblclick') {\n const realTarget = dispatchFetchLvModelDataByMouseEvent('click', event, target)\n\n window.dispatchEvent(\n new CustomEvent('clickComponent', {\n detail: realTarget || target\n })\n )\n }\n }, 300)\n}\n\nfunction ondblclick(event: MouseEvent, hint: any) {\n const target = hint.origin\n\n setTimeout(() => {\n target.currentEvent = ''\n }, 500)\n\n event.stopPropagation()\n\n target.currentEvent = 'dblclick'\n\n dispatchFetchLvModelDataByMouseEvent('dblclick', event, target)\n}\n\nEventMap.register('mcs-event-handler', {\n 'model-layer': {\n '(all)': {\n // mouseenter: onmouseenter, /* 사용되지 않고 있음 */\n click: onclick,\n dblclick: ondblclick\n }\n }\n})\n"]}
1
+ {"version":3,"file":"mcs-mouse-event-handler.js","sourceRoot":"","sources":["../../../src/layers/mcs-mouse-event-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventMap } from '@hatiolab/things-scene'\n\nfunction dispatchFetchLvModelDataByMouseEvent(\n type: 'hover' | 'click' | 'dblclick',\n event: MouseEvent,\n target: Component & { parentObject?: Component }\n): Component | undefined {\n // 플레이백 모드 — 함수 자체를 실행하지 않음.\n // 1) 외부 모니터링 fetchLvModelDataByMouseEvent window 이벤트 차단\n // 2) realTarget 반환 차단 → onclick 의 후속 clickComponent dispatch 가\n // realTarget = undefined 로 흘러 popup 등 후속 backend 호출 경로도 비활성\n // (popup 의 detailInfo() 가드와 더불어 백엔드 요청을 차단하는 1차 게이트.)\n if ((target as any)?.root?.playbackMode) return undefined\n\n const parent = target.parentObject\n\n // CapacityBar(Stocker/Zone) 처럼 세그먼트 게이지를 그리는 컴포넌트는, carrier/abnormal\n // 모드에서 클릭된 세그먼트(Full/Empty/EmptyEmpty/Normal/Abnormal)를 함께 실어 보낸다.\n // capacity 모드·비세그먼트 컴포넌트는 undefined → 필드 미포함.\n const segment = (target as any).segmentAtEvent?.(event)\n\n if (target.getState('id')) {\n window.dispatchEvent(\n new CustomEvent('fetchLvModelDataByMouseEvent', {\n detail: {\n value: {\n type,\n event,\n model: {\n ...target.state,\n parentObject: parent\n ? {\n id: parent.get('id'),\n type: parent.get('type')\n }\n : null\n },\n data: target.data,\n ...(segment ? { segment } : {})\n }\n }\n })\n )\n\n return parent || target\n } else if (parent && parent.getState('id')) {\n // 클릭된 컴포넌트(target)가 자기 id 없이 id 보유 부모(Machine 등) 안에 배치된 경우 —\n // 예: id 미지정 StockerCapacityBar / ZoneCapacityBar. 이때도 model 은 *실제 클릭된\n // 컴포넌트* 를 실어 model.type 이 자신의 타입이 되게 한다(부모 타입 stocker 로 치환 금지).\n // target 은 자기 id 가 없으므로, 주소가 되는 부모 id/type 은 parentObject 로 실어 위\n // 분기(target 이 id 를 가진 경우)와 payload 형태를 동일하게 맞춘다.\n window.dispatchEvent(\n new CustomEvent('fetchLvModelDataByMouseEvent', {\n detail: {\n value: {\n type,\n event,\n model: {\n ...target.state,\n parentObject: {\n id: parent.get('id'),\n type: parent.get('type')\n }\n },\n data: target.data,\n ...(segment ? { segment } : {})\n }\n }\n })\n )\n\n return parent\n }\n}\n\n// function onmouseenter(event: MouseEvent, hint: any) {\n// const target = hint.origin\n\n// event.stopPropagation()\n\n// dispatchFetchLvModelDataByMouseEvent('hover', event, target)\n// }\n\nfunction onclick(event: MouseEvent, hint: any) {\n const target = hint.origin\n\n event.stopPropagation()\n\n setTimeout(() => {\n if (target.currentEvent !== 'dblclick') {\n const realTarget = dispatchFetchLvModelDataByMouseEvent('click', event, target)\n\n window.dispatchEvent(\n new CustomEvent('clickComponent', {\n detail: realTarget || target\n })\n )\n }\n }, 300)\n}\n\nfunction ondblclick(event: MouseEvent, hint: any) {\n const target = hint.origin\n\n setTimeout(() => {\n target.currentEvent = ''\n }, 500)\n\n event.stopPropagation()\n\n target.currentEvent = 'dblclick'\n\n dispatchFetchLvModelDataByMouseEvent('dblclick', event, target)\n}\n\nEventMap.register('mcs-event-handler', {\n 'model-layer': {\n '(all)': {\n // mouseenter: onmouseenter, /* 사용되지 않고 있음 */\n click: onclick,\n dblclick: ondblclick\n }\n }\n})\n"]}
@@ -1,7 +1,7 @@
1
1
  import { Component, Layer, POINT } from '@hatiolab/things-scene';
2
2
  export type PathType = 'COMMAND' | 'JOB';
3
3
  export type PathStatus = 'NORMAL' | 'DELAY' | 'ALTER' | 'WARN';
4
- export type TipType = 'none' | 'arrow' | 'open-arrow' | 'sharp-arrow' | 'diamond' | 'oval';
4
+ export type TipType = 'none' | 'arrow' | 'open-arrow' | 'sharp-arrow' | 'diamond' | 'oval' | 'cross';
5
5
  export type TipSize = 'size1' | 'size2' | 'size3' | 'size4' | 'size5' | 'size6' | 'size7' | 'size8' | 'size9';
6
6
  export type LineDash = 'solid' | 'round-dot' | 'square-dot' | 'dash' | 'dash-dot' | 'long-dash' | 'long-dash-dot' | 'long-dash-dot-dot';
7
7
  export type Point = {
@@ -30,7 +30,10 @@ export type PATH = {
30
30
  dstUnit: string;
31
31
  pathType: PathType;
32
32
  status: PathStatus;
33
- transportCnt: number;
33
+ /** 강조 대상 개수(신규 이름). 미지정 시 label 자동 생성에 사용. */
34
+ highlightTarget?: number;
35
+ /** @deprecated `highlightTarget` 로 개명됨. 하위호환을 위해 유지 — 읽을 때 highlightTarget 이 없으면 이 값을 사용. */
36
+ transportCnt?: number;
34
37
  label: string;
35
38
  styles?: PathStyles;
36
39
  };
@@ -9,6 +9,15 @@ const MOVEMENT_STYLES = {
9
9
  };
10
10
  const WING_FACTOR = Math.sqrt(3);
11
11
  const LINEWIDTH = 2;
12
+ /**
13
+ * highlightTarget(신규) 를 우선 사용하고, 없으면 transportCnt(deprecated) 로 폴백해
14
+ * 자동 라벨 문자열을 만든다(2 초과일 때만 개수 표시). 하위호환 단일 소스.
15
+ */
16
+ function autoHighlightLabel(path) {
17
+ var _a, _b;
18
+ const count = Number((_b = (_a = path.highlightTarget) !== null && _a !== void 0 ? _a : path.transportCnt) !== null && _b !== void 0 ? _b : 0);
19
+ return count > 1 ? String(count) : '';
20
+ }
12
21
  let MovementLayer = class MovementLayer extends Layer {
13
22
  constructor() {
14
23
  super(...arguments);
@@ -160,7 +169,7 @@ let MovementLayer = class MovementLayer extends Layer {
160
169
  dest.transcoordS2C(destCenter.x, destCenter.y, root)
161
170
  ];
162
171
  ctx.beginPath();
163
- this.drawArrow(ctx, srcPos, destPos, path.pathType, path.status, path.label || (Number(path.transportCnt || 0) > 1 ? String(path.transportCnt) : ''), path.styles);
172
+ this.drawArrow(ctx, srcPos, destPos, path.pathType, path.status, path.label || autoHighlightLabel(path), path.styles);
164
173
  ctx.stroke();
165
174
  });
166
175
  ctx.restore();
@@ -185,7 +194,7 @@ let MovementLayer = class MovementLayer extends Layer {
185
194
  beginSize: (_m = (_l = path.styles) === null || _l === void 0 ? void 0 : _l.beginSize) !== null && _m !== void 0 ? _m : 'size2',
186
195
  end: (_p = (_o = path.styles) === null || _o === void 0 ? void 0 : _o.end) !== null && _p !== void 0 ? _p : 'arrow',
187
196
  endSize: (_r = (_q = path.styles) === null || _q === void 0 ? void 0 : _q.endSize) !== null && _r !== void 0 ? _r : 'size2',
188
- label: path.label || (Number(path.transportCnt || 0) > 1 ? String(path.transportCnt) : '')
197
+ label: path.label || autoHighlightLabel(path)
189
198
  });
190
199
  });
191
200
  }
@@ -278,6 +287,14 @@ function drawTip(ctx, p1, p2, lineWidth, type, size) {
278
287
  ctx.lineTo(WING_FACTOR * size.X + lineWidth, size.Y);
279
288
  ctx.stroke();
280
289
  break;
290
+ case 'cross':
291
+ /* X 표시 — 두 대각선 stroke (tip 지점 중심, 선 방향 기준 회전) */
292
+ ctx.moveTo(-size.X, -size.Y);
293
+ ctx.lineTo(size.X, size.Y);
294
+ ctx.moveTo(-size.X, size.Y);
295
+ ctx.lineTo(size.X, -size.Y);
296
+ ctx.stroke();
297
+ break;
281
298
  default:
282
299
  break;
283
300
  }
@@ -1 +1 @@
1
- {"version":3,"file":"movement-layer.js","sourceRoot":"","sources":["../../../src/layers/movement-layer.ts"],"names":[],"mappings":"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","sourcesContent":["import isUndefined from 'lodash-es/isUndefined'\nimport { Component, Layer, POINT, sceneComponent } from '@hatiolab/things-scene'\n\nconst MOVEMENT_STYLES: { [key: string]: string[] } = {\n NORMAL /* NORMAL_TRANSPORT*/: ['#00B05033', '#00B050'],\n DELAY /* DELAYED_TRANSPORT*/: ['#FF000033', '#FF0000'],\n ALTER /* ALTER_TRANSPORT*/: ['#76717133', '#767171'],\n WARN /* WARN_TRANSPORT*/: ['#AAAA0033', '#AAAA00']\n}\n\nexport type PathType = 'COMMAND' | 'JOB'\n\nexport type PathStatus = 'NORMAL' | 'DELAY' | 'ALTER' | 'WARN'\n\nexport type TipType = 'none' | 'arrow' | 'open-arrow' | 'sharp-arrow' | 'diamond' | 'oval'\n\nexport type TipSize = 'size1' | 'size2' | 'size3' | 'size4' | 'size5' | 'size6' | 'size7' | 'size8' | 'size9'\n\nexport type LineDash =\n | 'solid'\n | 'round-dot'\n | 'square-dot'\n | 'dash'\n | 'dash-dot'\n | 'long-dash'\n | 'long-dash-dot'\n | 'long-dash-dot-dot'\n\nexport type Point = {\n x: number\n y: number\n}\n\nexport type Path = Point[]\n\nexport type PathStyles = {\n strokeStyle?: string | string[]\n alpha?: number\n lineWidth?: number\n lineDash?: LineDash\n lineCap?: CanvasLineCap\n lineJoin?: CanvasLineJoin\n begin?: TipType\n beginSize?: TipSize\n end?: TipType\n endSize?: TipSize\n}\n\nexport type PATH = {\n srcMachine: string\n srcZone: string\n srcUnit: string\n dstMachine: string\n dstZone: string\n dstUnit: string\n pathType: PathType\n status: PathStatus\n transportCnt: number\n label: string\n styles?: PathStyles\n}\n\nexport type MOVEMENT = PATH[]\n\nconst WING_FACTOR = Math.sqrt(3)\nconst LINEWIDTH = 2\n\n@sceneComponent('movement-layer')\nexport default class MovementLayer extends Layer {\n drawInstructionHandler = (e: Event) => {\n // 플레이백 중에는 외부 모니터링이 보내는 실시간 반송 정보를 무시 —\n // fmbShowMovement 와 동일한 이유. drawInstruction 은 movement-layer 가 직접\n // 청취하는 별도 경로라 viewer 의 fmbShowMovement 가드를 우회한다.\n if ((this.root as any)?.playbackMode) return\n\n this.data = (e as CustomEvent).detail\n }\n\n clickComponentHandler = (e: Event) => {\n const component = (e as CustomEvent).detail\n const { type } = component.state\n\n if (type == 'model-layer') {\n this.data = [] /* clear */\n return\n }\n }\n\n onchangeTarget = (_after: Record<string, any>, _before: Record<string, any>): void => {\n this.invalidate()\n }\n\n async ready() {\n window.removeEventListener('drawInstruction', this.drawInstructionHandler)\n window.removeEventListener('clickComponent', this.clickComponentHandler)\n\n window.addEventListener('drawInstruction', this.drawInstructionHandler)\n window.addEventListener('clickComponent', this.clickComponentHandler)\n }\n\n dispose() {\n window.removeEventListener('drawInstruction', this.drawInstructionHandler)\n window.removeEventListener('clickComponent', this.clickComponentHandler)\n\n this.clearMonitoringTargets()\n\n // 3D 화살표 정리\n const rootModel = this.root?.rootModel as any\n rootModel?.clearArrows3D?.()\n\n super.dispose && super.dispose()\n }\n\n get pointerEvents() {\n return 'none'\n }\n\n // base Layer/Component 가 capturable 을 property 로 선언 → getter override 시\n // TS2611. things-scene mixin 의 declare const X_base 패턴이 accessor 를 object\n // property 로 평탄화해 발생. field 초기화로 우회하면 useDefineForClassFields:false\n // 환경에서 런타임 setter 부재로 throw — getter override 가 정도.\n // @ts-ignore TS2611\n get capturable() {\n return false\n }\n\n drawArrow(\n ctx: CanvasRenderingContext2D,\n p1: POINT,\n p2: POINT,\n pathType: PathType,\n pathStatus: PathStatus,\n label: string,\n styles?: PathStyles\n ) {\n var { begin = 'none', end = 'arrow', lineWidth = LINEWIDTH, strokeStyle } = styles || {}\n\n if (strokeStyle && !Array.isArray(strokeStyle)) {\n ctx.strokeStyle = strokeStyle\n ctx.fillStyle = strokeStyle\n } else {\n const gradient = ctx.createLinearGradient(p1.x, p1.y, p2.x, p2.y)\n ;((strokeStyle as string[]) || MOVEMENT_STYLES[pathStatus] || []).forEach((color, idx) =>\n gradient.addColorStop(idx, color)\n )\n\n ctx.strokeStyle = gradient\n ctx.fillStyle = gradient\n }\n\n drawEndTips(ctx, [p1, p2], styles)\n ctx.stroke()\n ctx.fill()\n\n ctx.beginPath()\n\n var beginPos = getTipNeckPos(begin, lineWidth, p1, p2)\n var endPos = getTipNeckPos(end, lineWidth, p2, p1)\n\n ctx.moveTo(beginPos.x, beginPos.y)\n ctx.lineTo(endPos.x, endPos.y)\n\n stroke(ctx, {\n lineDash: pathType == 'COMMAND' ? 'dash' : 'solid',\n ...styles\n })\n\n ctx.beginPath()\n ctx.setLineDash([]) // reset line dash\n\n if (label) {\n const fontSize = 14\n const fontFamily = 'Arial'\n\n ctx.font = `bold ${fontSize}px ${fontFamily}`\n\n const textWidth = ctx.measureText(label).width\n\n const [x, y] = [(p1.x + p2.x) / 2 - textWidth / 2, (p1.y + p2.y) / 2]\n ctx.fillRect(x - 3, y - fontSize / 2 - 2, textWidth + 6, fontSize + 4)\n\n ctx.fillStyle = 'white'\n ctx.fillText(label, x, y + fontSize / 2 - 1)\n }\n }\n\n findSourceAndTarget(path: PATH): [Component?, Component?] {\n const root = this.root\n var src, dest\n\n for (const name of [path.srcUnit, path.srcZone, path.srcMachine].filter(Boolean)) {\n src = root.findById?.(name)\n if (src) {\n break\n }\n }\n\n for (const name of [path.dstUnit, path.dstZone, path.dstMachine].filter(Boolean)) {\n dest = root.findById?.(name)\n if (dest) {\n break\n }\n }\n\n return [src, dest]\n }\n\n private monitoringTargets: Component[] = []\n private clearMonitoringTargets() {\n this.monitoringTargets.forEach(target => {\n target.off('change', this.onchangeTarget)\n })\n\n this.monitoringTargets = []\n }\n\n private addMonitoringTarget(targets: Component[]) {\n targets.forEach(target => {\n if (this.monitoringTargets.includes(target)) {\n return\n }\n\n this.monitoringTargets.push(target)\n target.on('change', this.onchangeTarget)\n })\n }\n\n render(ctx: CanvasRenderingContext2D) {\n const root = this.root\n const rootModel = root.rootModel as any\n const movement =\n this.data instanceof Array\n ? (this.data as MOVEMENT)\n : this.data && typeof this.data === 'object'\n ? [this.data]\n : []\n\n this.clearMonitoringTargets()\n\n if (rootModel?.is3dMode) {\n this.render3D(movement, rootModel)\n return\n }\n\n // 3D 화살표가 남아있으면 정리\n rootModel?.clearArrows3D?.()\n\n ctx.save()\n\n movement.forEach(path => {\n const [src, dest] = this.findSourceAndTarget(path)\n if (!src || !dest) {\n return\n }\n\n this.addMonitoringTarget([src, dest])\n\n const [srcCenter, destCenter] = [src.center, dest.center]\n const [srcPos, destPos] = [\n src.transcoordS2C(srcCenter.x, srcCenter.y, root),\n dest.transcoordS2C(destCenter.x, destCenter.y, root)\n ]\n\n ctx.beginPath()\n\n this.drawArrow(\n ctx,\n srcPos,\n destPos,\n path.pathType,\n path.status,\n path.label || (Number(path.transportCnt || 0) > 1 ? String(path.transportCnt) : ''),\n path.styles\n )\n\n ctx.stroke()\n })\n\n ctx.restore()\n }\n\n private render3D(movement: MOVEMENT, rootModel: any) {\n // 이전 화살표 정리\n rootModel.clearArrows3D()\n\n movement.forEach((path, i) => {\n const [src, dest] = this.findSourceAndTarget(path)\n if (!src || !dest) {\n return\n }\n\n this.addMonitoringTarget([src, dest])\n\n const defaultColors = MOVEMENT_STYLES[path.status] || MOVEMENT_STYLES.NORMAL\n\n rootModel.addArrow3D(\n `movement-${i}`,\n src,\n dest,\n {\n strokeStyle: path.styles?.strokeStyle ?? defaultColors,\n alpha: path.styles?.alpha ?? 0.8,\n lineWidth: path.styles?.lineWidth ?? 2,\n lineDash: path.styles?.lineDash ?? (path.pathType === 'COMMAND' ? 'dash' : 'solid'),\n begin: path.styles?.begin ?? 'none',\n beginSize: path.styles?.beginSize ?? 'size2',\n end: path.styles?.end ?? 'arrow',\n endSize: path.styles?.endSize ?? 'size2',\n label: path.label || (Number(path.transportCnt || 0) > 1 ? String(path.transportCnt) : '')\n }\n )\n })\n }\n\n get eventMap() {\n return {\n 'model-layer': {\n '(self)': {\n change: this.onchangeModelLayer\n }\n }\n }\n }\n\n onchangeModelLayer(after: Record<string, any>, _before: Record<string, any>, _hint: any) {\n if (after.scale || after.translate) {\n this.invalidate()\n }\n }\n\n onchangeData(_after: Record<string, any>, _before: Record<string, any>): void {\n this.invalidate()\n }\n}\n\nfunction getTipNeckPos(tipType: TipType, lineWidth: number, p1: Point, p2: Point) {\n if (tipType.slice(-5) != 'arrow') return p1\n\n var theta = Math.atan2(p2.y - p1.y, p2.x - p1.x)\n var diff = lineWidth * 1.5\n\n return {\n x: p1.x + Math.cos(theta) * diff,\n y: p1.y + Math.sin(theta) * diff\n }\n}\n\nfunction drawEndTips(ctx: CanvasRenderingContext2D, path: Path, style?: PathStyles) {\n var {\n lineWidth = LINEWIDTH,\n lineCap,\n alpha = 1,\n begin = 'none',\n end = 'arrow',\n beginSize = 'size2',\n endSize = 'size2'\n } = style || {}\n\n if (begin != 'none' || end != 'none') {\n lineWidth = Number(lineWidth) || LINEWIDTH\n\n if (!isUndefined(lineCap)) ctx.lineCap = lineCap\n if (!isUndefined(lineWidth)) ctx.lineWidth = lineWidth\n if (!isUndefined(alpha)) ctx.globalAlpha *= alpha\n\n // 선 그리기.\n if (begin != 'none') drawTip(ctx, path[0], path[1], lineWidth, begin, tipSize(beginSize, lineWidth))\n if (end != 'none') {\n let length = path.length\n drawTip(ctx, path[length - 1], path[length - 2], lineWidth, end, tipSize(endSize, lineWidth))\n }\n }\n}\n\nfunction drawTip(\n ctx: CanvasRenderingContext2D,\n p1: Point,\n p2: Point,\n lineWidth: number,\n type: TipType,\n size: { X: number; Y: number }\n) {\n var { x, y } = p1\n var theta = Math.atan2(p2.y - y, p2.x - x)\n\n ctx.beginPath()\n\n ctx.translate(x, y)\n ctx.rotate(theta)\n\n switch (type) {\n case 'oval':\n ctx.ellipse(0, 0, size.X, size.Y, 0, 0, 2 * Math.PI)\n ctx.fill()\n // ctx.scale(1, 1 / arc_scale_y)\n break\n case 'diamond':\n ctx.moveTo(-size.X, 0)\n ctx.lineTo(0, -size.Y)\n ctx.lineTo(size.X, 0)\n ctx.lineTo(0, size.Y)\n ctx.fill()\n break\n case 'arrow':\n ctx.moveTo(0, 0)\n ctx.lineTo(WING_FACTOR * size.X, -size.Y)\n ctx.lineTo(WING_FACTOR * size.X, size.Y)\n ctx.fill()\n break\n case 'sharp-arrow':\n ctx.moveTo(0, 0)\n ctx.lineTo(WING_FACTOR * size.X, -size.Y)\n ctx.lineTo(-size.X / 1.5 + WING_FACTOR * size.X, 0)\n ctx.lineTo(WING_FACTOR * size.X, size.Y)\n ctx.fill()\n break\n case 'open-arrow':\n ctx.moveTo(WING_FACTOR * size.X + lineWidth, -size.Y)\n ctx.lineTo(lineWidth, 0)\n ctx.lineTo(WING_FACTOR * size.X + lineWidth, size.Y)\n ctx.stroke()\n break\n default:\n break\n }\n\n ctx.rotate(-theta)\n ctx.translate(-x, -y)\n\n ctx.closePath()\n}\n\nfunction tipSize(size: TipSize, lineWidth: number) {\n let length: { X: number; Y: number } = { X: lineWidth * 1.5, Y: lineWidth * 1.5 }\n lineWidth = lineWidth * 1.2\n\n switch (size) {\n case 'size1':\n length.X = lineWidth\n length.Y = lineWidth\n break\n case 'size2':\n length.X = lineWidth * 1.5\n length.Y = lineWidth\n break\n case 'size3':\n length.X = lineWidth * 2\n length.Y = lineWidth\n break\n case 'size4':\n length.X = lineWidth\n length.Y = lineWidth * 1.5\n break\n case 'size5':\n length.X = lineWidth * 1.5\n length.Y = lineWidth * 1.5\n break\n case 'size6':\n length.X = lineWidth * 2\n length.Y = lineWidth * 1.5\n break\n case 'size7':\n length.X = lineWidth\n length.Y = lineWidth * 2\n break\n case 'size8':\n length.X = lineWidth * 1.5\n length.Y = lineWidth * 2\n break\n case 'size9':\n length.X = lineWidth * 2\n length.Y = lineWidth * 2\n break\n default:\n length.X = lineWidth * 1.5\n length.Y = lineWidth * 1.5\n break\n }\n return length\n}\n\nfunction stroke(ctx: CanvasRenderingContext2D, styles?: PathStyles) {\n var { lineDash: lineDashType = 'solid', lineWidth = 2, lineCap, lineJoin, alpha } = styles || {}\n\n if (lineCap) ctx.lineCap = lineCap\n\n let lineDash = [0, 0]\n\n if (lineDash) {\n var isRound = lineCap == 'round'\n\n switch (lineDashType) {\n case 'solid':\n lineDash = [0, 0]\n break\n case 'round-dot':\n if (isRound) lineDash = [0, lineWidth * 2]\n else lineDash = [lineWidth, lineWidth]\n break\n case 'square-dot':\n if (isRound) lineDash = [lineWidth, lineWidth * 2]\n else lineDash = [lineWidth * 2, lineWidth]\n break\n case 'dash':\n if (isRound) lineDash = [lineWidth * 3, lineWidth * 2.5]\n else lineDash = [lineWidth * 4, lineWidth * 1.5]\n break\n case 'dash-dot':\n if (isRound) lineDash = [lineWidth * 3, lineWidth * 3, 0, lineWidth * 3]\n else lineDash = [lineWidth * 4, lineWidth * 2, lineWidth, lineWidth * 2]\n break\n case 'long-dash':\n if (isRound) lineDash = [lineWidth * 5, lineWidth * 4]\n else lineDash = [lineWidth * 6, lineWidth * 3]\n break\n case 'long-dash-dot':\n if (isRound) lineDash = [lineWidth * 5, lineWidth * 3, 0, lineWidth * 3]\n else lineDash = [lineWidth * 6, lineWidth * 2, lineWidth, lineWidth * 2]\n break\n case 'long-dash-dot-dot':\n if (isRound) lineDash = [lineWidth * 5, lineWidth * 2, 0, lineWidth * 2, 0, lineWidth * 2]\n else lineDash = [lineWidth * 6, lineWidth, lineWidth, lineWidth, lineWidth, lineWidth]\n break\n }\n ctx.setLineDash(lineDash)\n }\n\n if (!isUndefined(alpha)) ctx.globalAlpha *= alpha\n if (!isUndefined(lineJoin)) ctx.lineJoin = lineJoin\n\n ctx.stroke()\n}\n"]}
1
+ {"version":3,"file":"movement-layer.js","sourceRoot":"","sources":["../../../src/layers/movement-layer.ts"],"names":[],"mappings":";AAAA,OAAO,WAAW,MAAM,uBAAuB,CAAA;AAC/C,OAAO,EAAa,KAAK,EAAS,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAEhF,MAAM,eAAe,GAAgC;IACnD,MAAM,CAAC,qBAAqB,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC;IACtD,KAAK,CAAC,sBAAsB,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC;IACtD,KAAK,CAAC,oBAAoB,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC;IACpD,IAAI,CAAC,mBAAmB,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC;CACnD,CAAA;AA2DD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAChC,MAAM,SAAS,GAAG,CAAC,CAAA;AAEnB;;;GAGG;AACH,SAAS,kBAAkB,CAAC,IAAU;;IACpC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAA,MAAA,IAAI,CAAC,eAAe,mCAAI,IAAI,CAAC,YAAY,mCAAI,CAAC,CAAC,CAAA;IACpE,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AACvC,CAAC;AAGc,IAAM,aAAa,GAAnB,MAAM,aAAc,SAAQ,KAAK;IAAjC;;QACb,2BAAsB,GAAG,CAAC,CAAQ,EAAE,EAAE;;YACpC,wCAAwC;YACxC,kEAAkE;YAClE,iDAAiD;YACjD,IAAI,MAAC,IAAI,CAAC,IAAY,0CAAE,YAAY;gBAAE,OAAM;YAE5C,IAAI,CAAC,IAAI,GAAI,CAAiB,CAAC,MAAM,CAAA;QACvC,CAAC,CAAA;QAED,0BAAqB,GAAG,CAAC,CAAQ,EAAE,EAAE;YACnC,MAAM,SAAS,GAAI,CAAiB,CAAC,MAAM,CAAA;YAC3C,MAAM,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC,KAAK,CAAA;YAEhC,IAAI,IAAI,IAAI,aAAa,EAAE,CAAC;gBAC1B,IAAI,CAAC,IAAI,GAAG,EAAE,CAAA,CAAC,WAAW;gBAC1B,OAAM;YACR,CAAC;QACH,CAAC,CAAA;QAED,mBAAc,GAAG,CAAC,MAA2B,EAAE,OAA4B,EAAQ,EAAE;YACnF,IAAI,CAAC,UAAU,EAAE,CAAA;QACnB,CAAC,CAAA;QAqHO,sBAAiB,GAAgB,EAAE,CAAA;IA8H7C,CAAC;IAjPC,KAAK,CAAC,KAAK;QACT,MAAM,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,IAAI,CAAC,sBAAsB,CAAC,CAAA;QAC1E,MAAM,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAA;QAExE,MAAM,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,IAAI,CAAC,sBAAsB,CAAC,CAAA;QACvE,MAAM,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAA;IACvE,CAAC;IAED,OAAO;;QACL,MAAM,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,IAAI,CAAC,sBAAsB,CAAC,CAAA;QAC1E,MAAM,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAA;QAExE,IAAI,CAAC,sBAAsB,EAAE,CAAA;QAE7B,YAAY;QACZ,MAAM,SAAS,GAAG,MAAA,IAAI,CAAC,IAAI,0CAAE,SAAgB,CAAA;QAC7C,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,aAAa,yDAAI,CAAA;QAE5B,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE,CAAA;IAClC,CAAC;IAED,IAAI,aAAa;QACf,OAAO,MAAM,CAAA;IACf,CAAC;IAED,wEAAwE;IACxE,0EAA0E;IAC1E,oEAAoE;IACpE,oDAAoD;IACpD,oBAAoB;IACpB,IAAI,UAAU;QACZ,OAAO,KAAK,CAAA;IACd,CAAC;IAED,SAAS,CACP,GAA6B,EAC7B,EAAS,EACT,EAAS,EACT,QAAkB,EAClB,UAAsB,EACtB,KAAa,EACb,MAAmB;QAEnB,IAAI,EAAE,KAAK,GAAG,MAAM,EAAE,GAAG,GAAG,OAAO,EAAE,SAAS,GAAG,SAAS,EAAE,WAAW,EAAE,GAAG,MAAM,IAAI,EAAE,CAAA;QAExF,IAAI,WAAW,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/C,GAAG,CAAC,WAAW,GAAG,WAAW,CAAA;YAC7B,GAAG,CAAC,SAAS,GAAG,WAAW,CAAA;QAC7B,CAAC;aAAM,CAAC;YACN,MAAM,QAAQ,GAAG,GAAG,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAChE;YAAA,CAAE,WAAwB,IAAI,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CACvF,QAAQ,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,CAClC,CAAA;YAED,GAAG,CAAC,WAAW,GAAG,QAAQ,CAAA;YAC1B,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAA;QAC1B,CAAC;QAED,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,CAAC,CAAA;QAClC,GAAG,CAAC,MAAM,EAAE,CAAA;QACZ,GAAG,CAAC,IAAI,EAAE,CAAA;QAEV,GAAG,CAAC,SAAS,EAAE,CAAA;QAEf,IAAI,QAAQ,GAAG,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QACtD,IAAI,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QAElD,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;QAClC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;QAE9B,MAAM,CAAC,GAAG,EAAE;YACV,QAAQ,EAAE,QAAQ,IAAI,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;YAClD,GAAG,MAAM;SACV,CAAC,CAAA;QAEF,GAAG,CAAC,SAAS,EAAE,CAAA;QACf,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA,CAAC,kBAAkB;QAEtC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,QAAQ,GAAG,EAAE,CAAA;YACnB,MAAM,UAAU,GAAG,OAAO,CAAA;YAE1B,GAAG,CAAC,IAAI,GAAG,QAAQ,QAAQ,MAAM,UAAU,EAAE,CAAA;YAE7C,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,KAAK,CAAA;YAE9C,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YACrE,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,GAAG,CAAC,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAA;YAEtE,GAAG,CAAC,SAAS,GAAG,OAAO,CAAA;YACvB,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;QAC9C,CAAC;IACH,CAAC;IAED,mBAAmB,CAAC,IAAU;;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QACtB,IAAI,GAAG,EAAE,IAAI,CAAA;QAEb,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACjF,GAAG,GAAG,MAAA,IAAI,CAAC,QAAQ,qDAAG,IAAI,CAAC,CAAA;YAC3B,IAAI,GAAG,EAAE,CAAC;gBACR,MAAK;YACP,CAAC;QACH,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACjF,IAAI,GAAG,MAAA,IAAI,CAAC,QAAQ,qDAAG,IAAI,CAAC,CAAA;YAC5B,IAAI,IAAI,EAAE,CAAC;gBACT,MAAK;YACP,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACpB,CAAC;IAGO,sBAAsB;QAC5B,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACtC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;QAC3C,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAA;IAC7B,CAAC;IAEO,mBAAmB,CAAC,OAAoB;QAC9C,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACvB,IAAI,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5C,OAAM;YACR,CAAC;YAED,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YACnC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;QAC1C,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,MAAM,CAAC,GAA6B;;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QACtB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAgB,CAAA;QACvC,MAAM,QAAQ,GACZ,IAAI,CAAC,IAAI,YAAY,KAAK;YACxB,CAAC,CAAE,IAAI,CAAC,IAAiB;YACzB,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;gBAC1C,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;gBACb,CAAC,CAAC,EAAE,CAAA;QAEV,IAAI,CAAC,sBAAsB,EAAE,CAAA;QAE7B,IAAI,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,QAAQ,EAAE,CAAC;YACxB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;YAClC,OAAM;QACR,CAAC;QAED,mBAAmB;QACnB,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,aAAa,yDAAI,CAAA;QAE5B,GAAG,CAAC,IAAI,EAAE,CAAA;QAEV,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACtB,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAA;YAClD,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;gBAClB,OAAM;YACR,CAAC;YAED,IAAI,CAAC,mBAAmB,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAA;YAErC,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;YACzD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;gBACxB,GAAG,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC;gBACjD,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC;aACrD,CAAA;YAED,GAAG,CAAC,SAAS,EAAE,CAAA;YAEf,IAAI,CAAC,SAAS,CACZ,GAAG,EACH,MAAM,EACN,OAAO,EACP,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,KAAK,IAAI,kBAAkB,CAAC,IAAI,CAAC,EACtC,IAAI,CAAC,MAAM,CACZ,CAAA;YAED,GAAG,CAAC,MAAM,EAAE,CAAA;QACd,CAAC,CAAC,CAAA;QAEF,GAAG,CAAC,OAAO,EAAE,CAAA;IACf,CAAC;IAEO,QAAQ,CAAC,QAAkB,EAAE,SAAc;QACjD,YAAY;QACZ,SAAS,CAAC,aAAa,EAAE,CAAA;QAEzB,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;;YAC3B,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAA;YAClD,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;gBAClB,OAAM;YACR,CAAC;YAED,IAAI,CAAC,mBAAmB,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAA;YAErC,MAAM,aAAa,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,eAAe,CAAC,MAAM,CAAA;YAE5E,SAAS,CAAC,UAAU,CAClB,YAAY,CAAC,EAAE,EACf,GAAG,EACH,IAAI,EACJ;gBACE,WAAW,EAAE,MAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,WAAW,mCAAI,aAAa;gBACtD,KAAK,EAAE,MAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,KAAK,mCAAI,GAAG;gBAChC,SAAS,EAAE,MAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,SAAS,mCAAI,CAAC;gBACtC,QAAQ,EAAE,MAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,QAAQ,mCAAI,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;gBACnF,KAAK,EAAE,MAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,KAAK,mCAAI,MAAM;gBACnC,SAAS,EAAE,MAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,SAAS,mCAAI,OAAO;gBAC5C,GAAG,EAAE,MAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,GAAG,mCAAI,OAAO;gBAChC,OAAO,EAAE,MAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,OAAO,mCAAI,OAAO;gBACxC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,kBAAkB,CAAC,IAAI,CAAC;aAC9C,CACF,CAAA;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,QAAQ;QACV,OAAO;YACL,aAAa,EAAE;gBACb,QAAQ,EAAE;oBACR,MAAM,EAAE,IAAI,CAAC,kBAAkB;iBAChC;aACF;SACF,CAAA;IACH,CAAC;IAED,kBAAkB,CAAC,KAA0B,EAAE,OAA4B,EAAE,KAAU;QACrF,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACnC,IAAI,CAAC,UAAU,EAAE,CAAA;QACnB,CAAC;IACH,CAAC;IAED,YAAY,CAAC,MAA2B,EAAE,OAA4B;QACpE,IAAI,CAAC,UAAU,EAAE,CAAA;IACnB,CAAC;CACF,CAAA;AAzQoB,aAAa;IADjC,cAAc,CAAC,gBAAgB,CAAC;GACZ,aAAa,CAyQjC;eAzQoB,aAAa;AA2QlC,SAAS,aAAa,CAAC,OAAgB,EAAE,SAAiB,EAAE,EAAS,EAAE,EAAS;IAC9E,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO;QAAE,OAAO,EAAE,CAAA;IAE3C,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;IAChD,IAAI,IAAI,GAAG,SAAS,GAAG,GAAG,CAAA;IAE1B,OAAO;QACL,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI;QAChC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI;KACjC,CAAA;AACH,CAAC;AAED,SAAS,WAAW,CAAC,GAA6B,EAAE,IAAU,EAAE,KAAkB;IAChF,IAAI,EACF,SAAS,GAAG,SAAS,EACrB,OAAO,EACP,KAAK,GAAG,CAAC,EACT,KAAK,GAAG,MAAM,EACd,GAAG,GAAG,OAAO,EACb,SAAS,GAAG,OAAO,EACnB,OAAO,GAAG,OAAO,EAClB,GAAG,KAAK,IAAI,EAAE,CAAA;IAEf,IAAI,KAAK,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,EAAE,CAAC;QACrC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,SAAS,CAAA;QAE1C,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;YAAE,GAAG,CAAC,OAAO,GAAG,OAAO,CAAA;QAChD,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC;YAAE,GAAG,CAAC,SAAS,GAAG,SAAS,CAAA;QACtD,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;YAAE,GAAG,CAAC,WAAW,IAAI,KAAK,CAAA;QAEjD,SAAS;QACT,IAAI,KAAK,IAAI,MAAM;YAAE,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAA;QACpG,IAAI,GAAG,IAAI,MAAM,EAAE,CAAC;YAClB,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;YACxB,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAA;QAC/F,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CACd,GAA6B,EAC7B,EAAS,EACT,EAAS,EACT,SAAiB,EACjB,IAAa,EACb,IAA8B;IAE9B,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAA;IACjB,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IAE1C,GAAG,CAAC,SAAS,EAAE,CAAA;IAEf,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACnB,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAEjB,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,MAAM;YACT,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAA;YACpD,GAAG,CAAC,IAAI,EAAE,CAAA;YACV,gCAAgC;YAChC,MAAK;QACP,KAAK,SAAS;YACZ,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;YACtB,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACtB,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;YACrB,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;YACrB,GAAG,CAAC,IAAI,EAAE,CAAA;YACV,MAAK;QACP,KAAK,OAAO;YACV,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;YAChB,GAAG,CAAC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACzC,GAAG,CAAC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;YACxC,GAAG,CAAC,IAAI,EAAE,CAAA;YACV,MAAK;QACP,KAAK,aAAa;YAChB,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;YAChB,GAAG,CAAC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACzC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,GAAG,WAAW,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;YACnD,GAAG,CAAC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;YACxC,GAAG,CAAC,IAAI,EAAE,CAAA;YACV,MAAK;QACP,KAAK,YAAY;YACf,GAAG,CAAC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,GAAG,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACrD,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;YACxB,GAAG,CAAC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,GAAG,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;YACpD,GAAG,CAAC,MAAM,EAAE,CAAA;YACZ,MAAK;QACP,KAAK,OAAO;YACV,iDAAiD;YACjD,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAC5B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;YAC1B,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;YAC3B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAC3B,GAAG,CAAC,MAAM,EAAE,CAAA;YACZ,MAAK;QACP;YACE,MAAK;IACT,CAAC;IAED,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAA;IAClB,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAErB,GAAG,CAAC,SAAS,EAAE,CAAA;AACjB,CAAC;AAED,SAAS,OAAO,CAAC,IAAa,EAAE,SAAiB;IAC/C,IAAI,MAAM,GAA6B,EAAE,CAAC,EAAE,SAAS,GAAG,GAAG,EAAE,CAAC,EAAE,SAAS,GAAG,GAAG,EAAE,CAAA;IACjF,SAAS,GAAG,SAAS,GAAG,GAAG,CAAA;IAE3B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,OAAO;YACV,MAAM,CAAC,CAAC,GAAG,SAAS,CAAA;YACpB,MAAM,CAAC,CAAC,GAAG,SAAS,CAAA;YACpB,MAAK;QACP,KAAK,OAAO;YACV,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,GAAG,CAAA;YAC1B,MAAM,CAAC,CAAC,GAAG,SAAS,CAAA;YACpB,MAAK;QACP,KAAK,OAAO;YACV,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,CAAA;YACxB,MAAM,CAAC,CAAC,GAAG,SAAS,CAAA;YACpB,MAAK;QACP,KAAK,OAAO;YACV,MAAM,CAAC,CAAC,GAAG,SAAS,CAAA;YACpB,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,GAAG,CAAA;YAC1B,MAAK;QACP,KAAK,OAAO;YACV,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,GAAG,CAAA;YAC1B,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,GAAG,CAAA;YAC1B,MAAK;QACP,KAAK,OAAO;YACV,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,CAAA;YACxB,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,GAAG,CAAA;YAC1B,MAAK;QACP,KAAK,OAAO;YACV,MAAM,CAAC,CAAC,GAAG,SAAS,CAAA;YACpB,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,CAAA;YACxB,MAAK;QACP,KAAK,OAAO;YACV,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,GAAG,CAAA;YAC1B,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,CAAA;YACxB,MAAK;QACP,KAAK,OAAO;YACV,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,CAAA;YACxB,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,CAAA;YACxB,MAAK;QACP;YACE,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,GAAG,CAAA;YAC1B,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,GAAG,CAAA;YAC1B,MAAK;IACT,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,MAAM,CAAC,GAA6B,EAAE,MAAmB;IAChE,IAAI,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,EAAE,SAAS,GAAG,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,EAAE,CAAA;IAEhG,IAAI,OAAO;QAAE,GAAG,CAAC,OAAO,GAAG,OAAO,CAAA;IAElC,IAAI,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAErB,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,OAAO,GAAG,OAAO,IAAI,OAAO,CAAA;QAEhC,QAAQ,YAAY,EAAE,CAAC;YACrB,KAAK,OAAO;gBACV,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;gBACjB,MAAK;YACP,KAAK,WAAW;gBACd,IAAI,OAAO;oBAAE,QAAQ,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,CAAA;;oBACrC,QAAQ,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;gBACtC,MAAK;YACP,KAAK,YAAY;gBACf,IAAI,OAAO;oBAAE,QAAQ,GAAG,CAAC,SAAS,EAAE,SAAS,GAAG,CAAC,CAAC,CAAA;;oBAC7C,QAAQ,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,SAAS,CAAC,CAAA;gBAC1C,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO;oBAAE,QAAQ,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC,CAAA;;oBACnD,QAAQ,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC,CAAA;gBAChD,MAAK;YACP,KAAK,UAAU;gBACb,IAAI,OAAO;oBAAE,QAAQ,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,CAAA;;oBACnE,QAAQ,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,EAAE,SAAS,EAAE,SAAS,GAAG,CAAC,CAAC,CAAA;gBACxE,MAAK;YACP,KAAK,WAAW;gBACd,IAAI,OAAO;oBAAE,QAAQ,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,CAAA;;oBACjD,QAAQ,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,CAAA;gBAC9C,MAAK;YACP,KAAK,eAAe;gBAClB,IAAI,OAAO;oBAAE,QAAQ,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,CAAA;;oBACnE,QAAQ,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,EAAE,SAAS,EAAE,SAAS,GAAG,CAAC,CAAC,CAAA;gBACxE,MAAK;YACP,KAAK,mBAAmB;gBACtB,IAAI,OAAO;oBAAE,QAAQ,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,CAAA;;oBACrF,QAAQ,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAA;gBACtF,MAAK;QACT,CAAC;QACD,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAA;IAC3B,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;QAAE,GAAG,CAAC,WAAW,IAAI,KAAK,CAAA;IACjD,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;QAAE,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAEnD,GAAG,CAAC,MAAM,EAAE,CAAA;AACd,CAAC","sourcesContent":["import isUndefined from 'lodash-es/isUndefined'\nimport { Component, Layer, POINT, sceneComponent } from '@hatiolab/things-scene'\n\nconst MOVEMENT_STYLES: { [key: string]: string[] } = {\n NORMAL /* NORMAL_TRANSPORT*/: ['#00B05033', '#00B050'],\n DELAY /* DELAYED_TRANSPORT*/: ['#FF000033', '#FF0000'],\n ALTER /* ALTER_TRANSPORT*/: ['#76717133', '#767171'],\n WARN /* WARN_TRANSPORT*/: ['#AAAA0033', '#AAAA00']\n}\n\nexport type PathType = 'COMMAND' | 'JOB'\n\nexport type PathStatus = 'NORMAL' | 'DELAY' | 'ALTER' | 'WARN'\n\nexport type TipType = 'none' | 'arrow' | 'open-arrow' | 'sharp-arrow' | 'diamond' | 'oval' | 'cross'\n\nexport type TipSize = 'size1' | 'size2' | 'size3' | 'size4' | 'size5' | 'size6' | 'size7' | 'size8' | 'size9'\n\nexport type LineDash =\n | 'solid'\n | 'round-dot'\n | 'square-dot'\n | 'dash'\n | 'dash-dot'\n | 'long-dash'\n | 'long-dash-dot'\n | 'long-dash-dot-dot'\n\nexport type Point = {\n x: number\n y: number\n}\n\nexport type Path = Point[]\n\nexport type PathStyles = {\n strokeStyle?: string | string[]\n alpha?: number\n lineWidth?: number\n lineDash?: LineDash\n lineCap?: CanvasLineCap\n lineJoin?: CanvasLineJoin\n begin?: TipType\n beginSize?: TipSize\n end?: TipType\n endSize?: TipSize\n}\n\nexport type PATH = {\n srcMachine: string\n srcZone: string\n srcUnit: string\n dstMachine: string\n dstZone: string\n dstUnit: string\n pathType: PathType\n status: PathStatus\n /** 강조 대상 개수(신규 이름). 미지정 시 label 자동 생성에 사용. */\n highlightTarget?: number\n /** @deprecated `highlightTarget` 로 개명됨. 하위호환을 위해 유지 — 읽을 때 highlightTarget 이 없으면 이 값을 사용. */\n transportCnt?: number\n label: string\n styles?: PathStyles\n}\n\nexport type MOVEMENT = PATH[]\n\nconst WING_FACTOR = Math.sqrt(3)\nconst LINEWIDTH = 2\n\n/**\n * highlightTarget(신규) 를 우선 사용하고, 없으면 transportCnt(deprecated) 로 폴백해\n * 자동 라벨 문자열을 만든다(2 초과일 때만 개수 표시). 하위호환 단일 소스.\n */\nfunction autoHighlightLabel(path: PATH): string {\n const count = Number(path.highlightTarget ?? path.transportCnt ?? 0)\n return count > 1 ? String(count) : ''\n}\n\n@sceneComponent('movement-layer')\nexport default class MovementLayer extends Layer {\n drawInstructionHandler = (e: Event) => {\n // 플레이백 중에는 외부 모니터링이 보내는 실시간 반송 정보를 무시 —\n // fmbShowMovement 와 동일한 이유. drawInstruction 은 movement-layer 가 직접\n // 청취하는 별도 경로라 viewer 의 fmbShowMovement 가드를 우회한다.\n if ((this.root as any)?.playbackMode) return\n\n this.data = (e as CustomEvent).detail\n }\n\n clickComponentHandler = (e: Event) => {\n const component = (e as CustomEvent).detail\n const { type } = component.state\n\n if (type == 'model-layer') {\n this.data = [] /* clear */\n return\n }\n }\n\n onchangeTarget = (_after: Record<string, any>, _before: Record<string, any>): void => {\n this.invalidate()\n }\n\n async ready() {\n window.removeEventListener('drawInstruction', this.drawInstructionHandler)\n window.removeEventListener('clickComponent', this.clickComponentHandler)\n\n window.addEventListener('drawInstruction', this.drawInstructionHandler)\n window.addEventListener('clickComponent', this.clickComponentHandler)\n }\n\n dispose() {\n window.removeEventListener('drawInstruction', this.drawInstructionHandler)\n window.removeEventListener('clickComponent', this.clickComponentHandler)\n\n this.clearMonitoringTargets()\n\n // 3D 화살표 정리\n const rootModel = this.root?.rootModel as any\n rootModel?.clearArrows3D?.()\n\n super.dispose && super.dispose()\n }\n\n get pointerEvents() {\n return 'none'\n }\n\n // base Layer/Component 가 capturable 을 property 로 선언 → getter override 시\n // TS2611. things-scene mixin 의 declare const X_base 패턴이 accessor 를 object\n // property 로 평탄화해 발생. field 초기화로 우회하면 useDefineForClassFields:false\n // 환경에서 런타임 setter 부재로 throw — getter override 가 정도.\n // @ts-ignore TS2611\n get capturable() {\n return false\n }\n\n drawArrow(\n ctx: CanvasRenderingContext2D,\n p1: POINT,\n p2: POINT,\n pathType: PathType,\n pathStatus: PathStatus,\n label: string,\n styles?: PathStyles\n ) {\n var { begin = 'none', end = 'arrow', lineWidth = LINEWIDTH, strokeStyle } = styles || {}\n\n if (strokeStyle && !Array.isArray(strokeStyle)) {\n ctx.strokeStyle = strokeStyle\n ctx.fillStyle = strokeStyle\n } else {\n const gradient = ctx.createLinearGradient(p1.x, p1.y, p2.x, p2.y)\n ;((strokeStyle as string[]) || MOVEMENT_STYLES[pathStatus] || []).forEach((color, idx) =>\n gradient.addColorStop(idx, color)\n )\n\n ctx.strokeStyle = gradient\n ctx.fillStyle = gradient\n }\n\n drawEndTips(ctx, [p1, p2], styles)\n ctx.stroke()\n ctx.fill()\n\n ctx.beginPath()\n\n var beginPos = getTipNeckPos(begin, lineWidth, p1, p2)\n var endPos = getTipNeckPos(end, lineWidth, p2, p1)\n\n ctx.moveTo(beginPos.x, beginPos.y)\n ctx.lineTo(endPos.x, endPos.y)\n\n stroke(ctx, {\n lineDash: pathType == 'COMMAND' ? 'dash' : 'solid',\n ...styles\n })\n\n ctx.beginPath()\n ctx.setLineDash([]) // reset line dash\n\n if (label) {\n const fontSize = 14\n const fontFamily = 'Arial'\n\n ctx.font = `bold ${fontSize}px ${fontFamily}`\n\n const textWidth = ctx.measureText(label).width\n\n const [x, y] = [(p1.x + p2.x) / 2 - textWidth / 2, (p1.y + p2.y) / 2]\n ctx.fillRect(x - 3, y - fontSize / 2 - 2, textWidth + 6, fontSize + 4)\n\n ctx.fillStyle = 'white'\n ctx.fillText(label, x, y + fontSize / 2 - 1)\n }\n }\n\n findSourceAndTarget(path: PATH): [Component?, Component?] {\n const root = this.root\n var src, dest\n\n for (const name of [path.srcUnit, path.srcZone, path.srcMachine].filter(Boolean)) {\n src = root.findById?.(name)\n if (src) {\n break\n }\n }\n\n for (const name of [path.dstUnit, path.dstZone, path.dstMachine].filter(Boolean)) {\n dest = root.findById?.(name)\n if (dest) {\n break\n }\n }\n\n return [src, dest]\n }\n\n private monitoringTargets: Component[] = []\n private clearMonitoringTargets() {\n this.monitoringTargets.forEach(target => {\n target.off('change', this.onchangeTarget)\n })\n\n this.monitoringTargets = []\n }\n\n private addMonitoringTarget(targets: Component[]) {\n targets.forEach(target => {\n if (this.monitoringTargets.includes(target)) {\n return\n }\n\n this.monitoringTargets.push(target)\n target.on('change', this.onchangeTarget)\n })\n }\n\n render(ctx: CanvasRenderingContext2D) {\n const root = this.root\n const rootModel = root.rootModel as any\n const movement =\n this.data instanceof Array\n ? (this.data as MOVEMENT)\n : this.data && typeof this.data === 'object'\n ? [this.data]\n : []\n\n this.clearMonitoringTargets()\n\n if (rootModel?.is3dMode) {\n this.render3D(movement, rootModel)\n return\n }\n\n // 3D 화살표가 남아있으면 정리\n rootModel?.clearArrows3D?.()\n\n ctx.save()\n\n movement.forEach(path => {\n const [src, dest] = this.findSourceAndTarget(path)\n if (!src || !dest) {\n return\n }\n\n this.addMonitoringTarget([src, dest])\n\n const [srcCenter, destCenter] = [src.center, dest.center]\n const [srcPos, destPos] = [\n src.transcoordS2C(srcCenter.x, srcCenter.y, root),\n dest.transcoordS2C(destCenter.x, destCenter.y, root)\n ]\n\n ctx.beginPath()\n\n this.drawArrow(\n ctx,\n srcPos,\n destPos,\n path.pathType,\n path.status,\n path.label || autoHighlightLabel(path),\n path.styles\n )\n\n ctx.stroke()\n })\n\n ctx.restore()\n }\n\n private render3D(movement: MOVEMENT, rootModel: any) {\n // 이전 화살표 정리\n rootModel.clearArrows3D()\n\n movement.forEach((path, i) => {\n const [src, dest] = this.findSourceAndTarget(path)\n if (!src || !dest) {\n return\n }\n\n this.addMonitoringTarget([src, dest])\n\n const defaultColors = MOVEMENT_STYLES[path.status] || MOVEMENT_STYLES.NORMAL\n\n rootModel.addArrow3D(\n `movement-${i}`,\n src,\n dest,\n {\n strokeStyle: path.styles?.strokeStyle ?? defaultColors,\n alpha: path.styles?.alpha ?? 0.8,\n lineWidth: path.styles?.lineWidth ?? 2,\n lineDash: path.styles?.lineDash ?? (path.pathType === 'COMMAND' ? 'dash' : 'solid'),\n begin: path.styles?.begin ?? 'none',\n beginSize: path.styles?.beginSize ?? 'size2',\n end: path.styles?.end ?? 'arrow',\n endSize: path.styles?.endSize ?? 'size2',\n label: path.label || autoHighlightLabel(path)\n }\n )\n })\n }\n\n get eventMap() {\n return {\n 'model-layer': {\n '(self)': {\n change: this.onchangeModelLayer\n }\n }\n }\n }\n\n onchangeModelLayer(after: Record<string, any>, _before: Record<string, any>, _hint: any) {\n if (after.scale || after.translate) {\n this.invalidate()\n }\n }\n\n onchangeData(_after: Record<string, any>, _before: Record<string, any>): void {\n this.invalidate()\n }\n}\n\nfunction getTipNeckPos(tipType: TipType, lineWidth: number, p1: Point, p2: Point) {\n if (tipType.slice(-5) != 'arrow') return p1\n\n var theta = Math.atan2(p2.y - p1.y, p2.x - p1.x)\n var diff = lineWidth * 1.5\n\n return {\n x: p1.x + Math.cos(theta) * diff,\n y: p1.y + Math.sin(theta) * diff\n }\n}\n\nfunction drawEndTips(ctx: CanvasRenderingContext2D, path: Path, style?: PathStyles) {\n var {\n lineWidth = LINEWIDTH,\n lineCap,\n alpha = 1,\n begin = 'none',\n end = 'arrow',\n beginSize = 'size2',\n endSize = 'size2'\n } = style || {}\n\n if (begin != 'none' || end != 'none') {\n lineWidth = Number(lineWidth) || LINEWIDTH\n\n if (!isUndefined(lineCap)) ctx.lineCap = lineCap\n if (!isUndefined(lineWidth)) ctx.lineWidth = lineWidth\n if (!isUndefined(alpha)) ctx.globalAlpha *= alpha\n\n // 선 그리기.\n if (begin != 'none') drawTip(ctx, path[0], path[1], lineWidth, begin, tipSize(beginSize, lineWidth))\n if (end != 'none') {\n let length = path.length\n drawTip(ctx, path[length - 1], path[length - 2], lineWidth, end, tipSize(endSize, lineWidth))\n }\n }\n}\n\nfunction drawTip(\n ctx: CanvasRenderingContext2D,\n p1: Point,\n p2: Point,\n lineWidth: number,\n type: TipType,\n size: { X: number; Y: number }\n) {\n var { x, y } = p1\n var theta = Math.atan2(p2.y - y, p2.x - x)\n\n ctx.beginPath()\n\n ctx.translate(x, y)\n ctx.rotate(theta)\n\n switch (type) {\n case 'oval':\n ctx.ellipse(0, 0, size.X, size.Y, 0, 0, 2 * Math.PI)\n ctx.fill()\n // ctx.scale(1, 1 / arc_scale_y)\n break\n case 'diamond':\n ctx.moveTo(-size.X, 0)\n ctx.lineTo(0, -size.Y)\n ctx.lineTo(size.X, 0)\n ctx.lineTo(0, size.Y)\n ctx.fill()\n break\n case 'arrow':\n ctx.moveTo(0, 0)\n ctx.lineTo(WING_FACTOR * size.X, -size.Y)\n ctx.lineTo(WING_FACTOR * size.X, size.Y)\n ctx.fill()\n break\n case 'sharp-arrow':\n ctx.moveTo(0, 0)\n ctx.lineTo(WING_FACTOR * size.X, -size.Y)\n ctx.lineTo(-size.X / 1.5 + WING_FACTOR * size.X, 0)\n ctx.lineTo(WING_FACTOR * size.X, size.Y)\n ctx.fill()\n break\n case 'open-arrow':\n ctx.moveTo(WING_FACTOR * size.X + lineWidth, -size.Y)\n ctx.lineTo(lineWidth, 0)\n ctx.lineTo(WING_FACTOR * size.X + lineWidth, size.Y)\n ctx.stroke()\n break\n case 'cross':\n /* X 표시 — 두 대각선 stroke (tip 지점 중심, 선 방향 기준 회전) */\n ctx.moveTo(-size.X, -size.Y)\n ctx.lineTo(size.X, size.Y)\n ctx.moveTo(-size.X, size.Y)\n ctx.lineTo(size.X, -size.Y)\n ctx.stroke()\n break\n default:\n break\n }\n\n ctx.rotate(-theta)\n ctx.translate(-x, -y)\n\n ctx.closePath()\n}\n\nfunction tipSize(size: TipSize, lineWidth: number) {\n let length: { X: number; Y: number } = { X: lineWidth * 1.5, Y: lineWidth * 1.5 }\n lineWidth = lineWidth * 1.2\n\n switch (size) {\n case 'size1':\n length.X = lineWidth\n length.Y = lineWidth\n break\n case 'size2':\n length.X = lineWidth * 1.5\n length.Y = lineWidth\n break\n case 'size3':\n length.X = lineWidth * 2\n length.Y = lineWidth\n break\n case 'size4':\n length.X = lineWidth\n length.Y = lineWidth * 1.5\n break\n case 'size5':\n length.X = lineWidth * 1.5\n length.Y = lineWidth * 1.5\n break\n case 'size6':\n length.X = lineWidth * 2\n length.Y = lineWidth * 1.5\n break\n case 'size7':\n length.X = lineWidth\n length.Y = lineWidth * 2\n break\n case 'size8':\n length.X = lineWidth * 1.5\n length.Y = lineWidth * 2\n break\n case 'size9':\n length.X = lineWidth * 2\n length.Y = lineWidth * 2\n break\n default:\n length.X = lineWidth * 1.5\n length.Y = lineWidth * 1.5\n break\n }\n return length\n}\n\nfunction stroke(ctx: CanvasRenderingContext2D, styles?: PathStyles) {\n var { lineDash: lineDashType = 'solid', lineWidth = 2, lineCap, lineJoin, alpha } = styles || {}\n\n if (lineCap) ctx.lineCap = lineCap\n\n let lineDash = [0, 0]\n\n if (lineDash) {\n var isRound = lineCap == 'round'\n\n switch (lineDashType) {\n case 'solid':\n lineDash = [0, 0]\n break\n case 'round-dot':\n if (isRound) lineDash = [0, lineWidth * 2]\n else lineDash = [lineWidth, lineWidth]\n break\n case 'square-dot':\n if (isRound) lineDash = [lineWidth, lineWidth * 2]\n else lineDash = [lineWidth * 2, lineWidth]\n break\n case 'dash':\n if (isRound) lineDash = [lineWidth * 3, lineWidth * 2.5]\n else lineDash = [lineWidth * 4, lineWidth * 1.5]\n break\n case 'dash-dot':\n if (isRound) lineDash = [lineWidth * 3, lineWidth * 3, 0, lineWidth * 3]\n else lineDash = [lineWidth * 4, lineWidth * 2, lineWidth, lineWidth * 2]\n break\n case 'long-dash':\n if (isRound) lineDash = [lineWidth * 5, lineWidth * 4]\n else lineDash = [lineWidth * 6, lineWidth * 3]\n break\n case 'long-dash-dot':\n if (isRound) lineDash = [lineWidth * 5, lineWidth * 3, 0, lineWidth * 3]\n else lineDash = [lineWidth * 6, lineWidth * 2, lineWidth, lineWidth * 2]\n break\n case 'long-dash-dot-dot':\n if (isRound) lineDash = [lineWidth * 5, lineWidth * 2, 0, lineWidth * 2, 0, lineWidth * 2]\n else lineDash = [lineWidth * 6, lineWidth, lineWidth, lineWidth, lineWidth, lineWidth]\n break\n }\n ctx.setLineDash(lineDash)\n }\n\n if (!isUndefined(alpha)) ctx.globalAlpha *= alpha\n if (!isUndefined(lineJoin)) ctx.lineJoin = lineJoin\n\n ctx.stroke()\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  import { LitElement } from 'lit';
2
+ import { OxInputEntityId } from './property-sidebar/shapes/ox-input-entity-id';
2
3
  import { generateBulkComponents, type Area } from './bulk-create.js';
3
4
  export type ConflictPolicy = 'skip' | 'duplicate';
4
5
  export interface BulkCreateDialogProps {
@@ -13,14 +14,23 @@ export interface BulkCreateDialogProps {
13
14
  /** 취소 / 닫기 콜백. */
14
15
  onCancel?: () => void;
15
16
  }
16
- export declare class BulkCreateDialog extends LitElement {
17
+ declare const BulkCreateDialog_base: typeof LitElement & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types.js").ScopedElementsHost>;
18
+ export declare class BulkCreateDialog extends BulkCreateDialog_base {
19
+ static get scopedElements(): {
20
+ 'ox-input-entity-id': typeof OxInputEntityId;
21
+ };
17
22
  static styles: import("lit").CSSResult;
18
23
  template: Record<string, any>;
19
24
  initialArea: Area;
20
25
  existingIds: Set<string>;
21
26
  onConfirm: BulkCreateDialogProps['onConfirm'];
22
27
  onCancel?: BulkCreateDialogProps['onCancel'];
28
+ /** parentObject 필드 노출 여부 (template 이 ParentObjectMixin 컴포넌트일 때). */
29
+ hasParentObject: boolean;
30
+ /** parentObject 후보 id 리스트 (template 타입 기준, toolbar 에서 계산해 주입). */
31
+ parentObjectItems: string[];
23
32
  private pattern;
33
+ private parentObjectId;
24
34
  private count;
25
35
  private rows;
26
36
  private cols;
@@ -49,3 +59,4 @@ declare global {
49
59
  'bulk-create-dialog': BulkCreateDialog;
50
60
  }
51
61
  }
62
+ export {};