@things-factory/figure-ui 10.1.5 โ†’ 10.1.7

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 (79) hide show
  1. package/client/graphql/index.ts +36 -3
  2. package/client/modeller/figure-animations.ts +712 -0
  3. package/client/modeller/figure-ask.ts +5 -5
  4. package/client/modeller/figure-canvas.ts +1 -1
  5. package/client/modeller/figure-capabilities.ts +372 -0
  6. package/client/modeller/figure-history-panel.ts +171 -18
  7. package/client/modeller/figure-inspector.ts +439 -76
  8. package/client/modeller/figure-parts.ts +15 -15
  9. package/client/modeller/figure-preview.ts +2 -2
  10. package/client/modeller/figure-report.ts +102 -37
  11. package/client/modeller/figure-settings.ts +20 -20
  12. package/client/modeller/figure-side.ts +91 -15
  13. package/client/modeller/figure-source.test.ts +15 -1
  14. package/client/modeller/figure-source.ts +31 -15
  15. package/client/modeller/figure-thumbnail.ts +49 -4
  16. package/client/modeller/maturity.ts +10 -10
  17. package/client/pages/figure-list-page.ts +204 -66
  18. package/client/pages/figure-modeller-page.ts +158 -42
  19. package/client/types.ts +31 -0
  20. package/client/viewparts/figure-thumb.ts +250 -0
  21. package/dist-client/graphql/index.d.ts +8 -1
  22. package/dist-client/graphql/index.js +33 -3
  23. package/dist-client/graphql/index.js.map +1 -1
  24. package/dist-client/modeller/figure-animations.d.ts +93 -0
  25. package/dist-client/modeller/figure-animations.js +655 -0
  26. package/dist-client/modeller/figure-animations.js.map +1 -0
  27. package/dist-client/modeller/figure-ask.js +5 -5
  28. package/dist-client/modeller/figure-ask.js.map +1 -1
  29. package/dist-client/modeller/figure-canvas.js +1 -1
  30. package/dist-client/modeller/figure-canvas.js.map +1 -1
  31. package/dist-client/modeller/figure-capabilities.d.ts +42 -0
  32. package/dist-client/modeller/figure-capabilities.js +344 -0
  33. package/dist-client/modeller/figure-capabilities.js.map +1 -0
  34. package/dist-client/modeller/figure-history-panel.d.ts +15 -1
  35. package/dist-client/modeller/figure-history-panel.js +165 -18
  36. package/dist-client/modeller/figure-history-panel.js.map +1 -1
  37. package/dist-client/modeller/figure-inspector.d.ts +98 -0
  38. package/dist-client/modeller/figure-inspector.js +425 -75
  39. package/dist-client/modeller/figure-inspector.js.map +1 -1
  40. package/dist-client/modeller/figure-parts.js +15 -15
  41. package/dist-client/modeller/figure-parts.js.map +1 -1
  42. package/dist-client/modeller/figure-preview.js +2 -2
  43. package/dist-client/modeller/figure-preview.js.map +1 -1
  44. package/dist-client/modeller/figure-report.d.ts +18 -1
  45. package/dist-client/modeller/figure-report.js +105 -37
  46. package/dist-client/modeller/figure-report.js.map +1 -1
  47. package/dist-client/modeller/figure-settings.js +19 -19
  48. package/dist-client/modeller/figure-settings.js.map +1 -1
  49. package/dist-client/modeller/figure-side.d.ts +24 -0
  50. package/dist-client/modeller/figure-side.js +94 -14
  51. package/dist-client/modeller/figure-side.js.map +1 -1
  52. package/dist-client/modeller/figure-source.d.ts +15 -8
  53. package/dist-client/modeller/figure-source.js +16 -7
  54. package/dist-client/modeller/figure-source.js.map +1 -1
  55. package/dist-client/modeller/figure-thumbnail.js +40 -4
  56. package/dist-client/modeller/figure-thumbnail.js.map +1 -1
  57. package/dist-client/modeller/maturity.js +10 -10
  58. package/dist-client/modeller/maturity.js.map +1 -1
  59. package/dist-client/pages/figure-list-page.d.ts +11 -4
  60. package/dist-client/pages/figure-list-page.js +201 -63
  61. package/dist-client/pages/figure-list-page.js.map +1 -1
  62. package/dist-client/pages/figure-modeller-page.d.ts +33 -0
  63. package/dist-client/pages/figure-modeller-page.js +156 -42
  64. package/dist-client/pages/figure-modeller-page.js.map +1 -1
  65. package/dist-client/tsconfig.tsbuildinfo +1 -1
  66. package/dist-client/types.d.ts +29 -0
  67. package/dist-client/types.js.map +1 -1
  68. package/dist-client/viewparts/figure-thumb.d.ts +29 -0
  69. package/dist-client/viewparts/figure-thumb.js +242 -0
  70. package/dist-client/viewparts/figure-thumb.js.map +1 -0
  71. package/dist-server/tsconfig.tsbuildinfo +1 -1
  72. package/package.json +6 -5
  73. package/test/i18n-prefix-guard.test.ts +171 -0
  74. package/test/korean-register-guard.test.ts +83 -0
  75. package/translations/en.json +351 -264
  76. package/translations/ja.json +276 -264
  77. package/translations/ko.json +351 -264
  78. package/translations/ms.json +276 -264
  79. package/translations/zh.json +276 -264
@@ -0,0 +1,250 @@
1
+ import '@material/web/icon/icon.js'
2
+
3
+ import { css, html, LitElement } from 'lit'
4
+ import { customElement, property } from 'lit/decorators.js'
5
+
6
+ import { i18next, localize } from '@operato/i18n'
7
+ import { getPathInfo } from '@operato/utils'
8
+
9
+ import type { Figure } from '../types.js'
10
+
11
+ /**
12
+ * ๊ทธ๋ฆผ์„ ๋ถ€๋ฅด๋Š” ์ฃผ์†Œ.
13
+ *
14
+ * **base64 ๋ฅผ ๋ชฉ๋ก ์‘๋‹ต์— ์‹ค์–ด ์˜ค์ง€ ์•Š๋Š”๋‹ค.** data URL ์€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์บ์‹œํ•  ์ˆ˜ ์—†์–ด, ์นดํƒˆ๋กœ๊ทธ๋ฅผ
15
+ * ์—ด ๋•Œ๋งˆ๋‹ค ๊ทธ๋ฆผ ์ „๋ถ€๊ฐ€ ๋‹ค์‹œ ์˜จ๋‹ค([ํ™•์ธํ•จ] ํ‘œ๋ณธ 14๊ฐœ 227KB). ์ฃผ์†Œ๋กœ ๋ถ€๋ฅด๋ฉด ์บ์‹œ๊ฐ€ ๋˜๊ณ , ํŒ์„
16
+ * ๊ฐ€๋ฆฌ๋Š” `v` ๊ฐ€ ๋ฐ”๋€ ๊ฒƒ๋งŒ ๋‹ค์‹œ ๋ฐ›๋Š”๋‹ค. ๋‚ด์ฃผ๋Š” ์ž๋ฆฌ๋Š” `figure-thumbnail-router` ๋‹ค.
17
+ *
18
+ * ๋„๋ฉ”์ธ ์กฐ๊ฐ(`/domain/{subdomain}`)์€ ์…ธ์ด ์“ฐ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ํ•จ์ˆ˜๋กœ ์ฝ๋Š”๋‹ค โ€” ํ™”๋ฉด์ด ์ฃผ์†Œ๋ฅผ
19
+ * ์†์œผ๋กœ ์งœ๋งž์ถ”๋ฉด ๋„๋ฉ”์ธ์ด ๋ฐ”๋€Œ๋Š” ๋ฐฐ์น˜์—์„œ ์กฐ์šฉํžˆ ํ‹€๋ฆฐ๋‹ค.
20
+ */
21
+ function thumbnailSrc(figure: Figure): string | undefined {
22
+ if (!figure.thumbnailUpdatedAt) {
23
+ return undefined
24
+ }
25
+
26
+ const { contextPath } = getPathInfo(location.pathname)
27
+ const stamp = new Date(figure.thumbnailUpdatedAt).getTime()
28
+
29
+ return `${contextPath}/figure-thumbnail/${figure.id}?v=${stamp}`
30
+ }
31
+
32
+ /**
33
+ * ์นด๋“œ์˜ ๊ทธ๋ฆผ ์นธ.
34
+ *
35
+ * ## ์™œ ์ปดํฌ๋„ŒํŠธ์ธ๊ฐ€
36
+ *
37
+ * ์นดํƒˆ๋กœ๊ทธ๋Š” `ox-grist` ์˜ CARD ๋ชจ๋“œ๋กœ ๊ทธ๋ฆฐ๋‹ค. ๊ฒฉ์ž์—๊ฒŒ ๊ทธ๋ฆผ ์นธ์€ ์ปฌ๋Ÿผ ํ•˜๋‚˜์ด๊ณ , ๊ทธ ์นธ์„ ๊ทธ๋ฆฌ๋Š”
38
+ * ๊ฒƒ์€ ์ปฌ๋Ÿผ์˜ `record.renderer` ๋‹ค. ๊ทธ๋ฆผ ์œ„์— ์–นํžˆ๋Š” ๊ฒƒ๋“ค(์ดˆ์•ˆ ํ‘œ์‹œ, ์‚ญ์ œ)์€ **๊ทธ๋ฆผ ์นธ ์•ˆ์—**
39
+ * ์žˆ์–ด์•ผ ํ•˜๋ฏ€๋กœ renderer ๊ฐ€ ๊ทธ๋ ค์•ผ ํ•˜๋Š”๋ฐ, renderer ์˜ ๊ฒฐ๊ณผ๋Š” `ox-card-field` ์˜ shadow root
40
+ * ์•ˆ์œผ๋กœ ๋“ค์–ด๊ฐ„๋‹ค โ€” ํ™”๋ฉด์˜ `static styles` ๊ฐ€ ๋‹ฟ์ง€ ์•Š๊ณ , ์ธ๋ผ์ธ style ๋กœ๋Š” `:hover` ๋ฅผ ์“ธ ์ˆ˜ ์—†๋‹ค.
41
+ *
42
+ * ๊ทธ๋ž˜์„œ ๊ทธ๋ฆผ ์นธ๋งŒ ์ปดํฌ๋„ŒํŠธ๋กœ ๋‘”๋‹ค. ์ž๊ธฐ ์Šคํƒ€์ผ์„ ๊ฐ–๊ณ  ์žˆ์œผ๋‹ˆ hover ๋„ ํ…Œ๋งˆ๋„ ์ •์ƒ์œผ๋กœ ๋ˆ๋‹ค.
43
+ * ๊ฒฉ์ž๋กœ ์˜ฎ๊ธฐ๊ธฐ ์ „ ์†์œผ๋กœ ๋งŒ๋“ค์—ˆ๋˜ ์นด๋“œ์˜ ์œ„์ชฝ ์ ˆ๋ฐ˜์ด ๊ทธ๋Œ€๋กœ ์ด ์ž๋ฆฌ๋‹ค.
44
+ *
45
+ * ## ์‚ญ์ œ๊ฐ€ ์™œ ์—ฌ๊ธฐ ์žˆ๋‚˜
46
+ *
47
+ * ๊ฒฉ์ž์˜ gutter ์ค„์— ๋‘๋ฉด ์นด๋“œ ์•„๋ž˜์— ๋‹จ์ถ” ์ค„์ด ํ•˜๋‚˜ ์ƒ๊ธด๋‹ค. ๊ฐ์ถฐ๋„ ์ž๋ฆฌ๊ฐ€ ๋‚จ๊ณ , ์ž๋ฆฌ๋ฅผ ์—†์• ๋ฉด
48
+ * ๋ˆŒ๋ฆด ๊ณณ์ด ์‚ฌ๋ผ์ง„๋‹ค. ๋˜๋Œ๋ฆด ์ˆ˜ ์—†๋Š” ์กฐ์ž‘์€ **๊ณ ๋ฅด๋Š” ๋ˆˆ๊ธธ์— ๊ฑธ๋ฆฌ์ง€ ์•Š์•„์•ผ** ํ•˜๋ฏ€๋กœ ๊ทธ๋ฆผ ์˜ค๋ฅธ์ชฝ
49
+ * ์œ„, ์†์ด ๊ฐ”์„ ๋•Œ๋งŒ ๋‚˜์˜ค๋Š” ์ž๋ฆฌ์— ๋‘”๋‹ค.
50
+ */
51
+ @customElement('figure-thumb')
52
+ export class FigureThumb extends localize(i18next)(LitElement) {
53
+ static styles = css`
54
+ :host {
55
+ position: relative;
56
+ display: block;
57
+ width: 100%;
58
+ height: 100%;
59
+ overflow: hidden;
60
+ }
61
+
62
+ img {
63
+ display: block;
64
+ width: 100%;
65
+ height: 100%;
66
+ /* ํ˜•์ƒ์„ ์ž๋ฅด์ง€ ์•Š๋Š”๋‹ค โ€” ๊ธด ๊ฒƒ(์ปจ๋ฒ ์ด์–ด)๊ณผ ๋†’์€ ๊ฒƒ(์‹œ๊ทธ๋„ํƒ€์›Œ)์ด ํ•œ ์ค„์— ์„ ๋‹ค */
67
+ object-fit: contain;
68
+ }
69
+
70
+ /* ์•„์ง ๊ทธ๋ฆผ์ด ์—†๋Š” ๊ฒƒ์„ ๋นˆ ์‚ฌ๊ฐํ˜•์œผ๋กœ ๋‘์ง€ ์•Š๋Š”๋‹ค โ€” ์™œ ์—†๋Š”์ง€ ๋งํ•œ๋‹ค */
71
+ div[empty] {
72
+ display: flex;
73
+ flex-direction: column;
74
+ align-items: center;
75
+ justify-content: center;
76
+ gap: var(--spacing-tiny, 4px);
77
+ width: 100%;
78
+ height: 100%;
79
+ font: var(--label-font, inherit);
80
+ font-size: 0.7rem;
81
+ color: var(--md-sys-color-outline);
82
+ }
83
+ div[empty] md-icon {
84
+ --md-icon-size: 26px;
85
+ color: var(--md-sys-color-outline-variant);
86
+ }
87
+
88
+ /*
89
+ ์ดˆ์•ˆ ํ‘œ์‹œ.
90
+
91
+ ๋ฐœํ–‰๋œ ๊ฒƒ์—๋Š” ์•„๋ฌด ๋ง๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค โ€” ์นดํƒˆ๋กœ๊ทธ์— ์žˆ๋Š” ๊ฒƒ์€ ๋Œ€๊ฐœ ๋ฐœํ–‰๋œ ๊ฒƒ์ด๋ผ, ์นด๋“œ๋งˆ๋‹ค
92
+ ใ€Œ๋ฐœํ–‰๋จใ€์ด ๋ถ™์œผ๋ฉด ์•„๋ฌด๊ฒƒ๋„ ๊ฐ€๋ฅด์ง€ ์•Š๊ณ  ์ž๋ฆฌ๋งŒ ๋จน๋Š”๋‹ค. ์ดˆ์•ˆ๋งŒ ๋งํ•˜๋ฉด ์ด ํ‘œ์‹œ๊ฐ€ ์žˆ๋Š” ์นด๋“œ๊ฐ€
93
+ ๊ณง ใ€Œ์•„์ง ์“ฐ๋ฉด ์•ˆ ๋˜๋Š” ๊ฒƒใ€์ด ๋œ๋‹ค.
94
+ */
95
+ span[draft] {
96
+ position: absolute;
97
+ top: 6px;
98
+ left: 6px;
99
+ padding: 1px 7px;
100
+ font: var(--label-font, inherit);
101
+ font-size: 0.68rem;
102
+ line-height: 1.5;
103
+ color: var(--md-sys-color-on-secondary-container);
104
+ background-color: var(--md-sys-color-secondary-container);
105
+ border-radius: 4px;
106
+ }
107
+
108
+ /*
109
+ ํƒœ๊ทธ โ€” **๊ทธ๋ฆผ ์œ„์— ์–น๋Š”๋‹ค.**
110
+
111
+ ์นด๋“œ ๋ณธ๋ฌธ์— ํ•œ ์ค„๋กœ ๋‘์—ˆ๋”๋‹ˆ ํƒœ๊ทธ๊ฐ€ ์žˆ๋Š” ์นด๋“œ๋งŒ ๊ทธ๋งŒํผ ๋†’์•„์ ธ ๊ฒฉ์ž๊ฐ€ ๋“ค์ญ‰๋‚ ์ญ‰ํ•ด์กŒ๋‹ค.
112
+ ํƒœ๊ทธ๋Š” ๋„ํ˜•๋งˆ๋‹ค ๊ฐœ์ˆ˜๊ฐ€ ๋‹ค๋ฅด๋ฏ€๋กœ ๋ณธ๋ฌธ์— ๋‘๋Š” ํ•œ ์ด ๋ฌธ์ œ๊ฐ€ ๋‚จ๋Š”๋‹ค. ๊ทธ๋ฆผ ์œ„๋Š” ์ด๋ฏธ ์ž๋ฆฌ๊ฐ€
113
+ ์žกํ˜€ ์žˆ๊ณ (์ดˆ์•ˆ ํ‘œ์‹œยท์‚ญ์ œ), ์–น์–ด๋„ ์นด๋“œ ๋†’์ด๊ฐ€ ๋ณ€ํ•˜์ง€ ์•Š๋Š”๋‹ค.
114
+
115
+ ์•„๋ž˜์ชฝ์— ๋‘”๋‹ค โ€” ์œ„๋Š” ์ดˆ์•ˆ ํ‘œ์‹œ์™€ ์‚ญ์ œ ๋‹จ์ถ”๊ฐ€ ์“ด๋‹ค.
116
+
117
+ **ํˆฌ๋ช…ํ•œ ์•Œ์•ฝ์ด๋‹ค.** ๋ฉด์„ ๊ฝ‰ ์ฑ„์šฐ๋ฉด ๊ทธ๋ฆผ ์œ„์— ํฐ ๋ ๊ฐ€ ์ƒ๊ฒจ ํ˜•์ƒ์„ ๊ฐ€๋ฆฐ๋‹ค โ€” ์นดํƒˆ๋กœ๊ทธ์—์„œ
118
+ ๋จผ์ € ๋ณด์•„์•ผ ํ•˜๋Š” ๊ฒƒ์€ ํ˜•์ƒ์ด๋‹ค. ๊ทธ๋ž˜์„œ ๋ฐ”ํƒ•์€ ๊ฑฐ์˜ ๋น„์šฐ๊ณ , ์ฝํžˆ๋Š” ๊ฒƒ์€ ๋’ค๋ฅผ ํ๋ฆฌ๋Š” ๊ฒƒ๊ณผ
119
+ ์‹ค๋‚ฑ ํ…Œ๋‘๋ฆฌ๊ฐ€ ๋งก๋Š”๋‹ค. ํ๋ฆผ์ด ์•ˆ ๋˜๋Š” ํ™˜๊ฒฝ์—์„œ๋„ ํ…Œ๋‘๋ฆฌ๊ฐ€ ๋‚จ์•„ ๊ธ€์ž๊ฐ€ ํ˜•์ƒ์— ๋ฌปํžˆ์ง€ ์•Š๋Š”๋‹ค.
120
+ */
121
+ div[tags] {
122
+ position: absolute;
123
+ right: 6px;
124
+ bottom: 6px;
125
+ left: 6px;
126
+ display: flex;
127
+ flex-wrap: wrap-reverse;
128
+ justify-content: flex-end;
129
+ gap: 3px;
130
+ /* ํƒœ๊ทธ๊ฐ€ ๋งŽ์•„๋„ ๊ทธ๋ฆผ์„ ๋ฎ์ง€ ์•Š๋Š”๋‹ค โ€” ๋„˜์น˜๋Š” ๊ฒƒ์€ ์œ„๋กœ ์ž˜๋ฆฐ๋‹ค */
131
+ max-height: 44px;
132
+ overflow: hidden;
133
+ /* ์•Œ์•ฝ ์‚ฌ์ด์˜ ๋นˆ ์ž๋ฆฌ๋Š” ๊ทธ๋ฆผ์ด ๋ฐ›๋Š”๋‹ค โ€” ๊ฑฐ๊ธฐ์„œ ๋ˆ„๋ฅด๋ฉด ์ €์ž‘๋ฉด์ด ์—ด๋ฆฐ๋‹ค */
134
+ pointer-events: none;
135
+ }
136
+ /*
137
+ **์•Œ์•ฝ์€ ๋ˆ„๋ฅผ ์ˆ˜ ์žˆ๋‹ค.** ๋ˆ„๋ฅด๋ฉด ๊ทธ ํƒœ๊ทธ๋กœ ๋ชฉ๋ก์„ ๊ฑฐ๋ฅธ๋‹ค.
138
+
139
+ ํƒœ๊ทธ๋ฅผ ๋ˆˆ์— ๋ณด์ด๊ฒŒ ํ•œ ๋‹ค์Œ์˜ ๋ฌผ์Œ์€ ใ€Œ๊ทธ๋ž˜์„œ ์ด๊ฑธ๋กœ ๋ญ˜ ํ•˜๋‚˜ใ€๋‹ค. ๊ฐ™์€ ํƒœ๊ทธ๊ฐ€ ๋ถ™์€ ๊ฒƒ์„
140
+ ๋ณด๋ ค๊ณ  ํƒœ๊ทธ๋ฅผ ๋ˆˆ์œผ๋กœ ์ฝ์–ด ๊ฒ€์ƒ‰์ฐฝ์— ์˜ฎ๊ฒจ ์ ๊ฒŒ ๋‘๋ฉด, ๋ณด์—ฌ ์ค€ ๋œป์ด ์ ˆ๋ฐ˜๋งŒ ์‚ฐ๋‹ค.
141
+
142
+ ์นด๋“œ ์ž์ฒด๊ฐ€ ์ €์ž‘๋ฉด์„ ์—ฌ๋Š” ์ž๋ฆฌ์ด๋ฏ€๋กœ ์•Œ์•ฝ์—์„œ ๊ทธ ํด๋ฆญ์„ ๋ฉˆ์ถ˜๋‹ค โ€” ์•ˆ ๋ฉˆ์ถ”๋ฉด ํƒœ๊ทธ๋ฅผ ๋ˆ„๋ฅธ
143
+ ์‚ฌ๋žŒ์ด ํŽธ์ง‘๊ธฐ๋กœ ๋Œ๋ ค๊ฐ„๋‹ค.
144
+ */
145
+ div[tags] button {
146
+ pointer-events: auto;
147
+ cursor: pointer;
148
+ padding: 0 7px;
149
+ font: var(--label-font, inherit);
150
+ font-size: 0.66rem;
151
+ line-height: 1.7;
152
+ color: var(--md-sys-color-on-surface-variant, var(--md-sys-color-on-surface));
153
+ background-color: color-mix(in srgb, var(--md-sys-color-surface, #fff) 34%, transparent);
154
+ border: 1px solid color-mix(in srgb, var(--md-sys-color-outline, #888) 42%, transparent);
155
+ backdrop-filter: blur(4px);
156
+ border-radius: 999em;
157
+ white-space: nowrap;
158
+ }
159
+ div[tags] button:hover,
160
+ div[tags] button:focus-visible {
161
+ color: var(--md-sys-color-on-surface);
162
+ background-color: color-mix(in srgb, var(--md-sys-color-surface, #fff) 72%, transparent);
163
+ border-color: var(--md-sys-color-primary);
164
+ outline: none;
165
+ }
166
+
167
+ button[remove] {
168
+ position: absolute;
169
+ top: 5px;
170
+ right: 5px;
171
+ display: flex;
172
+ align-items: center;
173
+ justify-content: center;
174
+ padding: 3px;
175
+ color: var(--md-sys-color-on-surface-variant, var(--md-sys-color-on-surface));
176
+ /* ๊ทธ๋ฆผ์ด ๋ฐ์„ ์ˆ˜๋„ ์–ด๋‘์šธ ์ˆ˜๋„ ์žˆ๋‹ค โ€” ์˜…์€ ๋ฉด์„ ๊น”์•„ ์•„์ด์ฝ˜์ด ์–ด๋””์„œ๋‚˜ ์ฝํžˆ๊ฒŒ ํ•œ๋‹ค */
177
+ background-color: color-mix(in srgb, var(--md-sys-color-surface, #fff) 82%, transparent);
178
+ border: none;
179
+ border-radius: 4px;
180
+ cursor: pointer;
181
+ opacity: 0;
182
+ transition: opacity 0.12s ease-out;
183
+ }
184
+ button[remove] md-icon {
185
+ --md-icon-size: 18px;
186
+ }
187
+ :host(:hover) button[remove],
188
+ button[remove]:focus-visible {
189
+ opacity: 1;
190
+ }
191
+ button[remove]:hover {
192
+ color: var(--md-sys-color-on-error, #fff);
193
+ background-color: var(--md-sys-color-error);
194
+ }
195
+ `
196
+
197
+ @property({ type: Object }) figure!: Figure
198
+
199
+ render() {
200
+ const figure = this.figure
201
+ if (!figure) {
202
+ return html``
203
+ }
204
+
205
+ const src = thumbnailSrc(figure)
206
+
207
+ return html`
208
+ ${src
209
+ ? html`<img src=${src} alt=${figure.name || ''} loading="lazy" />`
210
+ : html`
211
+ <div empty>
212
+ <md-icon>deployed_code</md-icon>
213
+ ${i18next.t('figure.text.thumbnail-not-made-yet')}
214
+ </div>
215
+ `}
216
+ ${figure.state === 'released' ? '' : html`<span draft>${i18next.t('figure.label.draft')}</span>`}
217
+ ${figure.tags?.length
218
+ ? html`<div tags>
219
+ ${figure.tags.map(
220
+ tag => html`
221
+ <button
222
+ title=${i18next.t('figure.text.find-by-this-tag')}
223
+ @click=${(e: Event) => {
224
+ e.stopPropagation()
225
+ this.dispatchEvent(
226
+ new CustomEvent('search-tag', { detail: { tag }, bubbles: true, composed: true })
227
+ )
228
+ }}
229
+ >
230
+ ${tag}
231
+ </button>
232
+ `
233
+ )}
234
+ </div>`
235
+ : ''}
236
+
237
+ <button
238
+ remove
239
+ title=${i18next.t('figure.button.delete-figure')}
240
+ @click=${(e: Event) => {
241
+ /* ์นด๋“œ ํด๋ฆญ(=์ €์ž‘๋ฉด ์—ด๊ธฐ)๊นŒ์ง€ ์˜ฌ๋ผ๊ฐ€์ง€ ์•Š๊ฒŒ ์—ฌ๊ธฐ์„œ ๋ฉˆ์ถ˜๋‹ค */
242
+ e.stopPropagation()
243
+ this.dispatchEvent(new CustomEvent('remove'))
244
+ }}
245
+ >
246
+ <md-icon>delete</md-icon>
247
+ </button>
248
+ `
249
+ }
250
+ }
@@ -1,4 +1,4 @@
1
- import type { Figure, FigureFinding, FigureListResult, FigurePatch, FigureProposal, FigureVersion, NewFigure } from '../types.js';
1
+ import type { Figure, FigureFinding, FigureInspection, FigureListResult, FigurePatch, FigureProposal, FigureVersion, NewFigure } from '../types.js';
2
2
  /**
3
3
  * ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜จ๋‹ค.
4
4
  *
@@ -57,5 +57,12 @@ export declare function proposeFigure(request: {
57
57
  export declare function releaseFigure(id: string, comment?: string): Promise<Figure>;
58
58
  /** ์˜› ํŒ์„ ์ดˆ์•ˆ์œผ๋กœ ๋˜์‚ด๋ฆฐ๋‹ค. ์ •๋ณธยท์†์„ฑยท๊ทธ๋ฆผ์ด ๋Œ์•„์˜ค๊ณ  ์ด๋ฆ„ยท์„ค๋ช…์€ ๊ทธ๋Œ€๋กœ๋‹ค. */
59
59
  export declare function revertFigureVersion(id: string, version: number): Promise<SaveResult>;
60
+ /**
61
+ * ๋ฐœํ–‰ํ•ด๋„ ๋˜๋‚˜ โ€” **๋ˆ„๋ฅด๊ธฐ ์ „์—** ๋ฌป๋Š”๋‹ค.
62
+ *
63
+ * ๋ง‰๋Š” ๊ฒƒ์€ ์„œ๋ฒ„์˜ `releaseFigure` ์ด๊ณ  ์ด๊ฒƒ์€ ์ด์œ ๋ฅผ ๋ฏธ๋ฆฌ ๋ณด์—ฌ ์ฃผ๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด๋‹ค. ํ—ˆ๊ฐ€์ฆ์ด
64
+ * ์•„๋‹ˆ๋ฏ€๋กœ ์ด ๋‹ต์ด ํ†ต๊ณผ๋ผ ํ•ด๋„ ๋ฐœํ–‰์€ ๋‹ค์‹œ ํŒ์ •์„ ๋ฐ›๋Š”๋‹ค.
65
+ */
66
+ export declare function inspectFigure(id: string): Promise<FigureInspection>;
60
67
  /** ๋ฐœํ–‰๋œ ํŒ๋“ค โ€” ์ตœ๊ทผ ๊ฒƒ๋ถ€ํ„ฐ ์—ด ๊ฐœ. */
61
68
  export declare function fetchFigureVersions(id: string): Promise<FigureVersion[]>;
@@ -23,8 +23,10 @@ function unwrap(response, field) {
23
23
  /**
24
24
  * ๋ชฉ๋ก์— ํ•„์š”ํ•œ ํ•„๋“œ๋งŒ ๊ฐ€์ ธ์˜จ๋‹ค โ€” `source` ๋Š” ๋ฌด๊ฒ๊ณ  ๋ชฉ๋ก์—์„œ ์“ฐ์ง€ ์•Š๋Š”๋‹ค.
25
25
  *
26
- * `score`ยท`triangles` ๋ฅผ ํ•จ๊ป˜ ๋ฐ›๋Š” ์ด์œ ๋Š” ์นด๋“œ์— ๊ทธ๊ฒƒ์„ ๋ณด์—ฌ ์ฃผ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ €์ž‘์ž๊ฐ€
27
- * ๋ชฉ๋ก์—์„œ ใ€Œ์ด Figure ๊ฐ€ ๋ฌด๊ฑฐ์šด๊ฐ€ใ€๋ฅผ ๋ฐ”๋กœ ์•Œ์•„์•ผ ํ•œ๋‹ค.
26
+ * **`thumbnail` ๋„ ์—ฌ๊ธฐ ์—†๋‹ค.** base64 ๋ฌธ์ž์—ด์ด๋ผ ๋ชฉ๋ก ์‘๋‹ต์— ์‹ค์œผ๋ฉด ์นดํƒˆ๋กœ๊ทธ๋ฅผ ์—ด ๋•Œ๋งˆ๋‹ค ๊ทธ๋ฆผ
27
+ * ์ „๋ถ€๊ฐ€ ๋‹ค์‹œ ์˜ค๊ณ (ํ‘œ๋ณธ 14๊ฐœ 227KB), data URL ์€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์บ์‹œํ•˜์ง€ ๋ชปํ•œ๋‹ค. ๊ทธ๋ฆผ์€ ์ฃผ์†Œ๋กœ
28
+ * ๋ถ€๋ฅธ๋‹ค(`figure-thumbnail` ๋ผ์šฐํŠธ). ๋Œ€์‹  `thumbnailUpdatedAt` ์„ ๋ฐ›๋Š”๋‹ค โ€” ๊ทธ๋ฆผ์ด ์žˆ๋‚˜ ์—†๋‚˜๋ฅผ
29
+ * ๊ทธ๊ฒƒ์œผ๋กœ ์•Œ๊ณ , ํŒ์„ ๊ฐ€๋ฆฌ๋Š” ๊ฐ’์œผ๋กœ๋„ ์“ด๋‹ค.
28
30
  */
29
31
  const FIGURE_LIST_FIELDS = `
30
32
  id
@@ -32,12 +34,12 @@ const FIGURE_LIST_FIELDS = `
32
34
  name
33
35
  description
34
36
  category
37
+ tags
35
38
  state
36
39
  version
37
40
  score
38
41
  triangles
39
42
  groups
40
- thumbnail
41
43
  thumbnailUpdatedAt
42
44
  updatedAt
43
45
  updater { id name }
@@ -209,6 +211,34 @@ export async function revertFigureVersion(id, version) {
209
211
  });
210
212
  return unwrap(response, 'revertFigureVersion');
211
213
  }
214
+ /**
215
+ * ๋ฐœํ–‰ํ•ด๋„ ๋˜๋‚˜ โ€” **๋ˆ„๋ฅด๊ธฐ ์ „์—** ๋ฌป๋Š”๋‹ค.
216
+ *
217
+ * ๋ง‰๋Š” ๊ฒƒ์€ ์„œ๋ฒ„์˜ `releaseFigure` ์ด๊ณ  ์ด๊ฒƒ์€ ์ด์œ ๋ฅผ ๋ฏธ๋ฆฌ ๋ณด์—ฌ ์ฃผ๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด๋‹ค. ํ—ˆ๊ฐ€์ฆ์ด
218
+ * ์•„๋‹ˆ๋ฏ€๋กœ ์ด ๋‹ต์ด ํ†ต๊ณผ๋ผ ํ•ด๋„ ๋ฐœํ–‰์€ ๋‹ค์‹œ ํŒ์ •์„ ๋ฐ›๋Š”๋‹ค.
219
+ */
220
+ export async function inspectFigure(id) {
221
+ const response = await client.query({
222
+ query: gql `
223
+ query InspectFigure($id: String!) {
224
+ inspectFigure(id: $id) {
225
+ blocked
226
+ findings {
227
+ code
228
+ message
229
+ why
230
+ how
231
+ at
232
+ blocking
233
+ }
234
+ }
235
+ }
236
+ `,
237
+ variables: { id },
238
+ fetchPolicy: 'network-only'
239
+ });
240
+ return unwrap(response, 'inspectFigure');
241
+ }
212
242
  /** ๋ฐœํ–‰๋œ ํŒ๋“ค โ€” ์ตœ๊ทผ ๊ฒƒ๋ถ€ํ„ฐ ์—ด ๊ฐœ. */
213
243
  export async function fetchFigureVersions(id) {
214
244
  const response = await client.query({
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../client/graphql/index.ts"],"names":[],"mappings":"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","sourcesContent":["import gql from 'graphql-tag'\nimport { client } from '@operato/graphql'\n\nimport type {\n Figure,\n FigureFinding,\n FigureListResult,\n FigurePatch,\n FigureProposal,\n FigureVersion,\n NewFigure\n} from '../types.js'\n\n/**\n * ์‘๋‹ต์—์„œ ๊ฐ’์„ ๊บผ๋‚ธ๋‹ค. **์„œ๋ฒ„๊ฐ€ ๋งํ•œ ์‚ฌ์œ ๋ฅผ ๊ทธ๋Œ€๋กœ ์˜ฌ๋ฆฐ๋‹ค.**\n *\n * ์ „์—๋Š” `response.data.figures` ์ฒ˜๋Ÿผ ๋ฐ”๋กœ ๊บผ๋ƒˆ๋‹ค. ์„œ๋ฒ„๊ฐ€ ์˜ค๋ฅ˜๋ฅผ ๋Œ๋ ค์ฃผ๋ฉด `data` ๊ฐ€\n * ์—†์œผ๋ฏ€๋กœ `Cannot read properties of undefined (reading 'figures')` ๊ฐ€ ๋‚ฌ๊ณ , ํ™”๋ฉด์—๋Š”\n * ๊ทธ ๋ฌธ์žฅ์ด ๊ทธ๋Œ€๋กœ ๋–ด๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์ž๊ธฐ๊ฐ€ ๋ฌด์—‡์„ ์ž˜๋ชปํ–ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค โ€” ์‹ค์ œ๋กœ AI\n * ์š”์ฒญ์—์„œ ๊ทธ๋ ‡๊ฒŒ ๋‚ฌ๋‹ค.\n *\n * ๊ฐ’์ด `null` ์ธ ๊ฒƒ์€ ์˜ค๋ฅ˜๊ฐ€ ์•„๋‹ˆ๋‹ค. ์ง€์šด ๊ฒƒ์„ ๋ฌผ์—ˆ์„ ๋•Œ์ฒ˜๋Ÿผ ์—†๋Š” ๊ฒƒ์ด ๋‹ต์ธ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.\n * ์—ฌ๊ธฐ์„œ ๋ง‰๋Š” ๊ฒƒ์€ **`data` ์ž์ฒด๊ฐ€ ์—†๋Š” ๊ฒƒ**์ด๋‹ค.\n */\nfunction unwrap<T>(response: { data?: Record<string, unknown>; errors?: readonly { message: string }[] }, field: string): T {\n const said = response.errors?.[0]?.message\n if (said) throw new Error(said)\n\n if (!response.data) {\n throw new Error(`์„œ๋ฒ„๊ฐ€ ${field} ๋ฅผ ๋Œ๋ ค์ฃผ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.`)\n }\n\n return response.data[field] as T\n}\n\n\n/**\n * ๋ชฉ๋ก์— ํ•„์š”ํ•œ ํ•„๋“œ๋งŒ ๊ฐ€์ ธ์˜จ๋‹ค โ€” `source` ๋Š” ๋ฌด๊ฒ๊ณ  ๋ชฉ๋ก์—์„œ ์“ฐ์ง€ ์•Š๋Š”๋‹ค.\n *\n * `score`ยท`triangles` ๋ฅผ ํ•จ๊ป˜ ๋ฐ›๋Š” ์ด์œ ๋Š” ์นด๋“œ์— ๊ทธ๊ฒƒ์„ ๋ณด์—ฌ ์ฃผ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ €์ž‘์ž๊ฐ€\n * ๋ชฉ๋ก์—์„œ ใ€Œ์ด Figure ๊ฐ€ ๋ฌด๊ฑฐ์šด๊ฐ€ใ€๋ฅผ ๋ฐ”๋กœ ์•Œ์•„์•ผ ํ•œ๋‹ค.\n */\nconst FIGURE_LIST_FIELDS = `\n id\n type\n name\n description\n category\n state\n version\n score\n triangles\n groups\n thumbnail\n thumbnailUpdatedAt\n updatedAt\n updater { id name }\n`\n\n/**\n * ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜จ๋‹ค.\n *\n * ๊ฑธ๋Ÿฌ ๋ณด๊ธฐยท์ •๋ ฌยท์ชฝ ๋‚˜๋ˆ„๊ธฐ๋ฅผ **๊ทธ๋Œ€๋กœ ๋„˜๊ธด๋‹ค.** ํ™”๋ฉด์ด `search`ยท`state` ๊ฐ™์€ ์ด๋ฆ„์„ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด\n * filter ๋กœ ์˜ฎ๊ธฐ๋˜ ๊ฒƒ์„ ๊ทธ๋งŒ๋‘์—ˆ๋‹ค โ€” ๊ทธ ์ด๋ฆ„๋“ค์€ ๊ฒฉ์ž(ox-grist)๊ฐ€ ์ด๋ฏธ ์ปฌ๋Ÿผ ์„ค์ •์—์„œ ๋งŒ๋“ค์–ด ์ฃผ๊ณ ,\n * ์ค‘๊ฐ„์— ํ•œ ๋ฒŒ ๋” ๋‘๋ฉด ๊ฒฉ์ž๊ฐ€ ์•„๋Š” ์กฐ๊ฑด๊ณผ ์„œ๋ฒ„์— ๊ฐ€๋Š” ์กฐ๊ฑด์ด ์–ด๊ธ‹๋‚œ๋‹ค.\n */\nexport async function fetchFigureList(params: {\n page?: number\n limit?: number\n filters?: unknown[]\n sortings?: { name: string; desc?: boolean }[]\n}): Promise<FigureListResult> {\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n figures(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items { ${FIGURE_LIST_FIELDS} }\n total\n }\n }\n `,\n variables: {\n filters: params.filters ?? [],\n pagination: { page: params.page ?? 1, limit: params.limit ?? 30 },\n sortings: params.sortings?.length ? params.sortings : [{ name: 'updatedAt', desc: true }]\n },\n fetchPolicy: 'network-only'\n })\n\n return unwrap<FigureListResult>(response, 'figures')\n}\n\n/** ์ €์ž‘๋ฉด์— ํ•„์š”ํ•œ ์ „๋ถ€ โ€” `source` ๋ฅผ ํฌํ•จํ•œ๋‹ค. */\nexport async function fetchFigure(id: string): Promise<Figure> {\n const response = await client.query({\n query: gql`\n query ($id: String!) {\n figure(id: $id) {\n ${FIGURE_LIST_FIELDS}\n source\n properties\n }\n }\n `,\n variables: { id },\n fetchPolicy: 'network-only'\n })\n\n return unwrap<Figure>(response, 'figure')\n}\n\n/**\n * ์ด๋ฏธ ์“ฐ์ด๊ณ  ์žˆ๋Š” ํƒ€์ž… ์ด๋ฆ„.\n *\n * `type` ์€ ๋งŒ๋“  ๋’ค์— ๊ณ ์น  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ **๋งŒ๋“ค๊ธฐ ์ „์—** ์•Œ๋ ค ์ค˜์•ผ ํ•œ๋‹ค. ์ €์žฅ์„ ๋ˆŒ๋Ÿฌ\n * ๊ฑฐ์ ˆ๋‹นํ•˜๊ณ  ๋‚˜์„œ ์•„๋Š” ๊ฒƒ์€ ๋Šฆ๋‹ค.\n */\nexport async function fetchFigureTypeNames(): Promise<string[]> {\n const response = await client.query({\n query: gql`\n query {\n figureTypeNames\n }\n `,\n fetchPolicy: 'network-only'\n })\n\n return unwrap<string[] | null>(response, 'figureTypeNames') ?? []\n}\n\nexport interface SaveResult {\n figure: Figure\n /** ๋ง‰์ง€ ์•Š๋Š” ๋ฐœ๊ฒฌ. ์ €์žฅ์€ ๋์ง€๋งŒ ํ™”๋ฉด์ด ๋ณด์—ฌ ์ค˜์•ผ ํ•œ๋‹ค. */\n violations: FigureFinding[]\n}\n\nexport async function createFigure(figure: NewFigure): Promise<SaveResult> {\n const response = await client.mutate({\n mutation: gql`\n mutation ($figure: NewFigure!) {\n createFigure(figure: $figure) {\n figure { ${FIGURE_LIST_FIELDS} source }\n violations { code message at }\n }\n }\n `,\n variables: { figure }\n })\n\n return unwrap<SaveResult>(response, 'createFigure')\n}\n\nexport async function updateFigure(id: string, patch: FigurePatch): Promise<SaveResult> {\n const response = await client.mutate({\n mutation: gql`\n mutation ($id: String!, $patch: FigurePatch!) {\n updateFigure(id: $id, patch: $patch) {\n figure { ${FIGURE_LIST_FIELDS} source }\n violations { code message at }\n }\n }\n `,\n variables: { id, patch }\n })\n\n return unwrap<SaveResult>(response, 'updateFigure')\n}\n\nexport async function deleteFigure(id: string): Promise<boolean> {\n const response = await client.mutate({\n mutation: gql`\n mutation ($id: String!) {\n deleteFigure(id: $id)\n }\n `,\n variables: { id }\n })\n\n return unwrap<boolean>(response, 'deleteFigure')\n}\n\n/**\n * ์ €์ž‘ ๋ณด์กฐ์—๊ฒŒ ํ›„๋ณด๋ฅผ ์‹œํ‚จ๋‹ค.\n *\n * ํŒ”๋ ˆํŠธ๋ฅผ **ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณด๋‚ธ๋‹ค.** ์„œ๋ฒ„๋Š” ํŒ”๋ ˆํŠธ๋ฅผ ๋ชจ๋ฅธ๋‹ค โ€” things-scene ์ด ๊ฐ–๊ณ \n * ์žˆ๋Š”๋ฐ ๊ทธ ํŒจํ‚ค์ง€์˜ node ์กฐ๊ฑด์€ ํŒ”๋ ˆํŠธ๊ฐ€ ์—†๋Š” ๋ฒˆ๋“ค๋กœ ๊ฐ„๋‹ค. ๊ทธ๋ฆฌ๋Š” ์ชฝ์ด ์–ด๋–ค ํ† ํฐ์„\n * ํ’€ ์ˆ˜ ์žˆ๋Š”์ง€ ์•„๋Š” ์œ ์ผํ•œ ์ž๋ฆฌ์ด๋ฏ€๋กœ ๊ทธ์ชฝ์ด ๋ณด๋‚ธ๋‹ค.\n *\n * ๋Œ์•„์˜ค๋Š” ๊ฒƒ์€ **ํ›„๋ณด**๋‹ค. ์ €์žฅ๋˜์ง€ ์•Š์•˜๋‹ค โ€” ์ €์ž‘์ž๊ฐ€ ๋ฐ›์•„์•ผ ์ •๋ณธ์ด ๋œ๋‹ค.\n */\nexport async function proposeFigure(request: {\n prompt: string\n base?: string\n type?: string\n palette: string[]\n image?: File\n}): Promise<FigureProposal> {\n const response = await client.mutate({\n mutation: gql`\n mutation ProposeFigure($request: ProposeRequest!) {\n proposeFigure(request: $request) {\n source\n score\n grade\n triangles\n groups\n attempts\n violations {\n code\n message\n }\n }\n }\n `,\n variables: { request }\n })\n\n return unwrap<FigureProposal>(response, 'proposeFigure')\n}\n\n/**\n * ๋ฐœํ–‰ํ•œ๋‹ค โ€” ํŒ ๋ฒˆํ˜ธ๊ฐ€ ์˜ค๋ฅด๊ณ , ๊ทธ ์ˆœ๊ฐ„์ด ํŒ๋ณธ์œผ๋กœ ๋‚จ๋Š”๋‹ค.\n *\n * ์ด๋ฏธ ๋ฐœํ–‰๋œ ๊ฒƒ์„ ๋‹ค์‹œ ๋ฐœํ–‰ํ•˜๋ฉด ์„œ๋ฒ„๊ฐ€ ๊ฑฐ์ ˆํ•œ๋‹ค. ๊ณ ์ณ์„œ ๋‹ค์‹œ ๋‚ด๋ ค๋ฉด ์ €์žฅ์ด ๋จผ์ €์ด๊ณ , ์ €์žฅ์€\n * ๋ฐœํ–‰์„ ํ‘ผ๋‹ค(์ดˆ์•ˆ์œผ๋กœ ๋Œ์•„์˜จ๋‹ค).\n */\nexport async function releaseFigure(id: string, comment?: string): Promise<Figure> {\n const response = await client.mutate({\n mutation: gql`\n mutation ReleaseFigure($id: String!, $comment: String) {\n releaseFigure(id: $id, comment: $comment) {\n id\n version\n state\n updatedAt\n }\n }\n `,\n variables: { id, comment }\n })\n\n return unwrap<Figure>(response, 'releaseFigure')\n}\n\n/** ์˜› ํŒ์„ ์ดˆ์•ˆ์œผ๋กœ ๋˜์‚ด๋ฆฐ๋‹ค. ์ •๋ณธยท์†์„ฑยท๊ทธ๋ฆผ์ด ๋Œ์•„์˜ค๊ณ  ์ด๋ฆ„ยท์„ค๋ช…์€ ๊ทธ๋Œ€๋กœ๋‹ค. */\nexport async function revertFigureVersion(id: string, version: number): Promise<SaveResult> {\n const response = await client.mutate({\n mutation: gql`\n mutation RevertFigureVersion($id: String!, $version: Float!) {\n revertFigureVersion(id: $id, version: $version) {\n figure { ${FIGURE_LIST_FIELDS} source }\n violations { code message at }\n }\n }\n `,\n variables: { id, version }\n })\n\n return unwrap<SaveResult>(response, 'revertFigureVersion')\n}\n\n/** ๋ฐœํ–‰๋œ ํŒ๋“ค โ€” ์ตœ๊ทผ ๊ฒƒ๋ถ€ํ„ฐ ์—ด ๊ฐœ. */\nexport async function fetchFigureVersions(id: string): Promise<FigureVersion[]> {\n const response = await client.query({\n query: gql`\n query FigureVersions($id: String!) {\n figureVersions(id: $id) {\n version\n comment\n state\n updatedAt\n updater { id name }\n score\n triangles\n groups\n }\n }\n `,\n variables: { id },\n fetchPolicy: 'network-only'\n })\n\n return unwrap<FigureVersion[]>(response, 'figureVersions') ?? []\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../client/graphql/index.ts"],"names":[],"mappings":"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","sourcesContent":["import gql from 'graphql-tag'\nimport { client } from '@operato/graphql'\n\nimport type {\n Figure,\n FigureFinding,\n FigureInspection,\n FigureListResult,\n FigurePatch,\n FigureProposal,\n FigureVersion,\n NewFigure\n} from '../types.js'\n\n/**\n * ์‘๋‹ต์—์„œ ๊ฐ’์„ ๊บผ๋‚ธ๋‹ค. **์„œ๋ฒ„๊ฐ€ ๋งํ•œ ์‚ฌ์œ ๋ฅผ ๊ทธ๋Œ€๋กœ ์˜ฌ๋ฆฐ๋‹ค.**\n *\n * ์ „์—๋Š” `response.data.figures` ์ฒ˜๋Ÿผ ๋ฐ”๋กœ ๊บผ๋ƒˆ๋‹ค. ์„œ๋ฒ„๊ฐ€ ์˜ค๋ฅ˜๋ฅผ ๋Œ๋ ค์ฃผ๋ฉด `data` ๊ฐ€\n * ์—†์œผ๋ฏ€๋กœ `Cannot read properties of undefined (reading 'figures')` ๊ฐ€ ๋‚ฌ๊ณ , ํ™”๋ฉด์—๋Š”\n * ๊ทธ ๋ฌธ์žฅ์ด ๊ทธ๋Œ€๋กœ ๋–ด๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์ž๊ธฐ๊ฐ€ ๋ฌด์—‡์„ ์ž˜๋ชปํ–ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค โ€” ์‹ค์ œ๋กœ AI\n * ์š”์ฒญ์—์„œ ๊ทธ๋ ‡๊ฒŒ ๋‚ฌ๋‹ค.\n *\n * ๊ฐ’์ด `null` ์ธ ๊ฒƒ์€ ์˜ค๋ฅ˜๊ฐ€ ์•„๋‹ˆ๋‹ค. ์ง€์šด ๊ฒƒ์„ ๋ฌผ์—ˆ์„ ๋•Œ์ฒ˜๋Ÿผ ์—†๋Š” ๊ฒƒ์ด ๋‹ต์ธ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.\n * ์—ฌ๊ธฐ์„œ ๋ง‰๋Š” ๊ฒƒ์€ **`data` ์ž์ฒด๊ฐ€ ์—†๋Š” ๊ฒƒ**์ด๋‹ค.\n */\nfunction unwrap<T>(response: { data?: Record<string, unknown>; errors?: readonly { message: string }[] }, field: string): T {\n const said = response.errors?.[0]?.message\n if (said) throw new Error(said)\n\n if (!response.data) {\n throw new Error(`์„œ๋ฒ„๊ฐ€ ${field} ๋ฅผ ๋Œ๋ ค์ฃผ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.`)\n }\n\n return response.data[field] as T\n}\n\n\n/**\n * ๋ชฉ๋ก์— ํ•„์š”ํ•œ ํ•„๋“œ๋งŒ ๊ฐ€์ ธ์˜จ๋‹ค โ€” `source` ๋Š” ๋ฌด๊ฒ๊ณ  ๋ชฉ๋ก์—์„œ ์“ฐ์ง€ ์•Š๋Š”๋‹ค.\n *\n * **`thumbnail` ๋„ ์—ฌ๊ธฐ ์—†๋‹ค.** base64 ๋ฌธ์ž์—ด์ด๋ผ ๋ชฉ๋ก ์‘๋‹ต์— ์‹ค์œผ๋ฉด ์นดํƒˆ๋กœ๊ทธ๋ฅผ ์—ด ๋•Œ๋งˆ๋‹ค ๊ทธ๋ฆผ\n * ์ „๋ถ€๊ฐ€ ๋‹ค์‹œ ์˜ค๊ณ (ํ‘œ๋ณธ 14๊ฐœ 227KB), data URL ์€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์บ์‹œํ•˜์ง€ ๋ชปํ•œ๋‹ค. ๊ทธ๋ฆผ์€ ์ฃผ์†Œ๋กœ\n * ๋ถ€๋ฅธ๋‹ค(`figure-thumbnail` ๋ผ์šฐํŠธ). ๋Œ€์‹  `thumbnailUpdatedAt` ์„ ๋ฐ›๋Š”๋‹ค โ€” ๊ทธ๋ฆผ์ด ์žˆ๋‚˜ ์—†๋‚˜๋ฅผ\n * ๊ทธ๊ฒƒ์œผ๋กœ ์•Œ๊ณ , ํŒ์„ ๊ฐ€๋ฆฌ๋Š” ๊ฐ’์œผ๋กœ๋„ ์“ด๋‹ค.\n */\nconst FIGURE_LIST_FIELDS = `\n id\n type\n name\n description\n category\n tags\n state\n version\n score\n triangles\n groups\n thumbnailUpdatedAt\n updatedAt\n updater { id name }\n`\n\n/**\n * ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜จ๋‹ค.\n *\n * ๊ฑธ๋Ÿฌ ๋ณด๊ธฐยท์ •๋ ฌยท์ชฝ ๋‚˜๋ˆ„๊ธฐ๋ฅผ **๊ทธ๋Œ€๋กœ ๋„˜๊ธด๋‹ค.** ํ™”๋ฉด์ด `search`ยท`state` ๊ฐ™์€ ์ด๋ฆ„์„ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด\n * filter ๋กœ ์˜ฎ๊ธฐ๋˜ ๊ฒƒ์„ ๊ทธ๋งŒ๋‘์—ˆ๋‹ค โ€” ๊ทธ ์ด๋ฆ„๋“ค์€ ๊ฒฉ์ž(ox-grist)๊ฐ€ ์ด๋ฏธ ์ปฌ๋Ÿผ ์„ค์ •์—์„œ ๋งŒ๋“ค์–ด ์ฃผ๊ณ ,\n * ์ค‘๊ฐ„์— ํ•œ ๋ฒŒ ๋” ๋‘๋ฉด ๊ฒฉ์ž๊ฐ€ ์•„๋Š” ์กฐ๊ฑด๊ณผ ์„œ๋ฒ„์— ๊ฐ€๋Š” ์กฐ๊ฑด์ด ์–ด๊ธ‹๋‚œ๋‹ค.\n */\nexport async function fetchFigureList(params: {\n page?: number\n limit?: number\n filters?: unknown[]\n sortings?: { name: string; desc?: boolean }[]\n}): Promise<FigureListResult> {\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n figures(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items { ${FIGURE_LIST_FIELDS} }\n total\n }\n }\n `,\n variables: {\n filters: params.filters ?? [],\n pagination: { page: params.page ?? 1, limit: params.limit ?? 30 },\n sortings: params.sortings?.length ? params.sortings : [{ name: 'updatedAt', desc: true }]\n },\n fetchPolicy: 'network-only'\n })\n\n return unwrap<FigureListResult>(response, 'figures')\n}\n\n/** ์ €์ž‘๋ฉด์— ํ•„์š”ํ•œ ์ „๋ถ€ โ€” `source` ๋ฅผ ํฌํ•จํ•œ๋‹ค. */\nexport async function fetchFigure(id: string): Promise<Figure> {\n const response = await client.query({\n query: gql`\n query ($id: String!) {\n figure(id: $id) {\n ${FIGURE_LIST_FIELDS}\n source\n properties\n }\n }\n `,\n variables: { id },\n fetchPolicy: 'network-only'\n })\n\n return unwrap<Figure>(response, 'figure')\n}\n\n/**\n * ์ด๋ฏธ ์“ฐ์ด๊ณ  ์žˆ๋Š” ํƒ€์ž… ์ด๋ฆ„.\n *\n * `type` ์€ ๋งŒ๋“  ๋’ค์— ๊ณ ์น  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ **๋งŒ๋“ค๊ธฐ ์ „์—** ์•Œ๋ ค ์ค˜์•ผ ํ•œ๋‹ค. ์ €์žฅ์„ ๋ˆŒ๋Ÿฌ\n * ๊ฑฐ์ ˆ๋‹นํ•˜๊ณ  ๋‚˜์„œ ์•„๋Š” ๊ฒƒ์€ ๋Šฆ๋‹ค.\n */\nexport async function fetchFigureTypeNames(): Promise<string[]> {\n const response = await client.query({\n query: gql`\n query {\n figureTypeNames\n }\n `,\n fetchPolicy: 'network-only'\n })\n\n return unwrap<string[] | null>(response, 'figureTypeNames') ?? []\n}\n\nexport interface SaveResult {\n figure: Figure\n /** ๋ง‰์ง€ ์•Š๋Š” ๋ฐœ๊ฒฌ. ์ €์žฅ์€ ๋์ง€๋งŒ ํ™”๋ฉด์ด ๋ณด์—ฌ ์ค˜์•ผ ํ•œ๋‹ค. */\n violations: FigureFinding[]\n}\n\nexport async function createFigure(figure: NewFigure): Promise<SaveResult> {\n const response = await client.mutate({\n mutation: gql`\n mutation ($figure: NewFigure!) {\n createFigure(figure: $figure) {\n figure { ${FIGURE_LIST_FIELDS} source }\n violations { code message at }\n }\n }\n `,\n variables: { figure }\n })\n\n return unwrap<SaveResult>(response, 'createFigure')\n}\n\nexport async function updateFigure(id: string, patch: FigurePatch): Promise<SaveResult> {\n const response = await client.mutate({\n mutation: gql`\n mutation ($id: String!, $patch: FigurePatch!) {\n updateFigure(id: $id, patch: $patch) {\n figure { ${FIGURE_LIST_FIELDS} source }\n violations { code message at }\n }\n }\n `,\n variables: { id, patch }\n })\n\n return unwrap<SaveResult>(response, 'updateFigure')\n}\n\nexport async function deleteFigure(id: string): Promise<boolean> {\n const response = await client.mutate({\n mutation: gql`\n mutation ($id: String!) {\n deleteFigure(id: $id)\n }\n `,\n variables: { id }\n })\n\n return unwrap<boolean>(response, 'deleteFigure')\n}\n\n/**\n * ์ €์ž‘ ๋ณด์กฐ์—๊ฒŒ ํ›„๋ณด๋ฅผ ์‹œํ‚จ๋‹ค.\n *\n * ํŒ”๋ ˆํŠธ๋ฅผ **ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณด๋‚ธ๋‹ค.** ์„œ๋ฒ„๋Š” ํŒ”๋ ˆํŠธ๋ฅผ ๋ชจ๋ฅธ๋‹ค โ€” things-scene ์ด ๊ฐ–๊ณ \n * ์žˆ๋Š”๋ฐ ๊ทธ ํŒจํ‚ค์ง€์˜ node ์กฐ๊ฑด์€ ํŒ”๋ ˆํŠธ๊ฐ€ ์—†๋Š” ๋ฒˆ๋“ค๋กœ ๊ฐ„๋‹ค. ๊ทธ๋ฆฌ๋Š” ์ชฝ์ด ์–ด๋–ค ํ† ํฐ์„\n * ํ’€ ์ˆ˜ ์žˆ๋Š”์ง€ ์•„๋Š” ์œ ์ผํ•œ ์ž๋ฆฌ์ด๋ฏ€๋กœ ๊ทธ์ชฝ์ด ๋ณด๋‚ธ๋‹ค.\n *\n * ๋Œ์•„์˜ค๋Š” ๊ฒƒ์€ **ํ›„๋ณด**๋‹ค. ์ €์žฅ๋˜์ง€ ์•Š์•˜๋‹ค โ€” ์ €์ž‘์ž๊ฐ€ ๋ฐ›์•„์•ผ ์ •๋ณธ์ด ๋œ๋‹ค.\n */\nexport async function proposeFigure(request: {\n prompt: string\n base?: string\n type?: string\n palette: string[]\n image?: File\n}): Promise<FigureProposal> {\n const response = await client.mutate({\n mutation: gql`\n mutation ProposeFigure($request: ProposeRequest!) {\n proposeFigure(request: $request) {\n source\n score\n grade\n triangles\n groups\n attempts\n violations {\n code\n message\n }\n }\n }\n `,\n variables: { request }\n })\n\n return unwrap<FigureProposal>(response, 'proposeFigure')\n}\n\n/**\n * ๋ฐœํ–‰ํ•œ๋‹ค โ€” ํŒ ๋ฒˆํ˜ธ๊ฐ€ ์˜ค๋ฅด๊ณ , ๊ทธ ์ˆœ๊ฐ„์ด ํŒ๋ณธ์œผ๋กœ ๋‚จ๋Š”๋‹ค.\n *\n * ์ด๋ฏธ ๋ฐœํ–‰๋œ ๊ฒƒ์„ ๋‹ค์‹œ ๋ฐœํ–‰ํ•˜๋ฉด ์„œ๋ฒ„๊ฐ€ ๊ฑฐ์ ˆํ•œ๋‹ค. ๊ณ ์ณ์„œ ๋‹ค์‹œ ๋‚ด๋ ค๋ฉด ์ €์žฅ์ด ๋จผ์ €์ด๊ณ , ์ €์žฅ์€\n * ๋ฐœํ–‰์„ ํ‘ผ๋‹ค(์ดˆ์•ˆ์œผ๋กœ ๋Œ์•„์˜จ๋‹ค).\n */\nexport async function releaseFigure(id: string, comment?: string): Promise<Figure> {\n const response = await client.mutate({\n mutation: gql`\n mutation ReleaseFigure($id: String!, $comment: String) {\n releaseFigure(id: $id, comment: $comment) {\n id\n version\n state\n updatedAt\n }\n }\n `,\n variables: { id, comment }\n })\n\n return unwrap<Figure>(response, 'releaseFigure')\n}\n\n/** ์˜› ํŒ์„ ์ดˆ์•ˆ์œผ๋กœ ๋˜์‚ด๋ฆฐ๋‹ค. ์ •๋ณธยท์†์„ฑยท๊ทธ๋ฆผ์ด ๋Œ์•„์˜ค๊ณ  ์ด๋ฆ„ยท์„ค๋ช…์€ ๊ทธ๋Œ€๋กœ๋‹ค. */\nexport async function revertFigureVersion(id: string, version: number): Promise<SaveResult> {\n const response = await client.mutate({\n mutation: gql`\n mutation RevertFigureVersion($id: String!, $version: Float!) {\n revertFigureVersion(id: $id, version: $version) {\n figure { ${FIGURE_LIST_FIELDS} source }\n violations { code message at }\n }\n }\n `,\n variables: { id, version }\n })\n\n return unwrap<SaveResult>(response, 'revertFigureVersion')\n}\n\n/**\n * ๋ฐœํ–‰ํ•ด๋„ ๋˜๋‚˜ โ€” **๋ˆ„๋ฅด๊ธฐ ์ „์—** ๋ฌป๋Š”๋‹ค.\n *\n * ๋ง‰๋Š” ๊ฒƒ์€ ์„œ๋ฒ„์˜ `releaseFigure` ์ด๊ณ  ์ด๊ฒƒ์€ ์ด์œ ๋ฅผ ๋ฏธ๋ฆฌ ๋ณด์—ฌ ์ฃผ๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด๋‹ค. ํ—ˆ๊ฐ€์ฆ์ด\n * ์•„๋‹ˆ๋ฏ€๋กœ ์ด ๋‹ต์ด ํ†ต๊ณผ๋ผ ํ•ด๋„ ๋ฐœํ–‰์€ ๋‹ค์‹œ ํŒ์ •์„ ๋ฐ›๋Š”๋‹ค.\n */\nexport async function inspectFigure(id: string): Promise<FigureInspection> {\n const response = await client.query({\n query: gql`\n query InspectFigure($id: String!) {\n inspectFigure(id: $id) {\n blocked\n findings {\n code\n message\n why\n how\n at\n blocking\n }\n }\n }\n `,\n variables: { id },\n fetchPolicy: 'network-only'\n })\n\n return unwrap<FigureInspection>(response, 'inspectFigure')\n}\n\n/** ๋ฐœํ–‰๋œ ํŒ๋“ค โ€” ์ตœ๊ทผ ๊ฒƒ๋ถ€ํ„ฐ ์—ด ๊ฐœ. */\nexport async function fetchFigureVersions(id: string): Promise<FigureVersion[]> {\n const response = await client.query({\n query: gql`\n query FigureVersions($id: String!) {\n figureVersions(id: $id) {\n version\n comment\n state\n updatedAt\n updater { id name }\n score\n triangles\n groups\n }\n }\n `,\n variables: { id },\n fetchPolicy: 'network-only'\n })\n\n return unwrap<FigureVersion[]>(response, 'figureVersions') ?? []\n}\n"]}
@@ -0,0 +1,93 @@
1
+ import { LitElement, type TemplateResult } from 'lit';
2
+ import type { BoardModel, PartModel } from './figure-source.js';
3
+ declare const FigureAnimations_base: (new (...args: any[]) => LitElement) & typeof LitElement;
4
+ export declare class FigureAnimations extends FigureAnimations_base {
5
+ static styles: import("lit").CSSResult[];
6
+ board?: BoardModel;
7
+ parts: PartModel[];
8
+ /** ํŽผ์ณ ๋‘” clip. ์ด๋ฆ„์ด ์•„๋‹ˆ๋ผ ์ž๋ฆฌ๋กœ ์žก๋Š”๋‹ค โ€” ์ด๋ฆ„์€ ํŽธ์ง‘ ์ค‘์— ๋ฐ”๋€๋‹ค. */
9
+ private open;
10
+ private get clips();
11
+ /** ๋ถ€ํ’ˆ ์ด๋ฆ„ โ€” ์ฑ„๋„์ด ์ด๊ฒƒ์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค. */
12
+ private get partNames();
13
+ /**
14
+ * ๋ช‡ ๋ถ€ํ’ˆ์ด ์›€์ง์ด๋‚˜ โ€” ์ฑ„๋„์ด ๊ฐ€๋ฆฌํ‚ค๋Š” **์„œ๋กœ ๋‹ค๋ฅธ ๋ถ€ํ’ˆ**์˜ ์ˆ˜.
15
+ *
16
+ * clip ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋‹ค. ํ•œ ๋ถ€ํ’ˆ์„ ์„ธ clip ์ด ์›€์ง์—ฌ๋„ ๊ทธ ๋ถ€ํ’ˆ ํ•˜๋‚˜๊ฐ€ ๋‹จ๋… ๋ฌถ์Œ์ด ๋  ๋ฟ์ด๋‹ค.
17
+ * ์ฒญ์‚ฌ์ง„์ด ๋ฌถ์Œ์„ ๊ฐ€๋ฅด๋Š” ๊ธฐ์ค€๊ณผ ๊ฐ™์€ ์…ˆ์ด์–ด์•ผ ํ™”๋ฉด์˜ ์ˆ˜์™€ ํŒ์ •์˜ ์ˆ˜๊ฐ€ ๋งž๋Š”๋‹ค.
18
+ */
19
+ private get movingParts();
20
+ render(): TemplateResult;
21
+ /**
22
+ * ๋นˆ ํ™”๋ฉด โ€” **์ด ํƒญ์ด ๋ฌด์—‡์ธ์ง€ ๊ฐ€๋ฅด์น˜๋Š” ์ž๋ฆฌ๋‹ค.**
23
+ *
24
+ * ใ€Œclip ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”ใ€๋ผ๊ณ ๋งŒ ์“ฐ๋ฉด ์ฒ˜์Œ ์—ฌ๋Š” ์‚ฌ๋žŒ์€ clip ์ด ๋ฌด์—‡์ธ์ง€ ๋ชจ๋ฅธ ์ฑ„ ๋‹จ์ถ”๋ฅผ ๋ˆ„๋ฅธ๋‹ค.
25
+ * ๊ทธ๋ž˜์„œ ๋ฌด์—‡์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”์ง€ ์˜ˆ๋ฅผ ๋“ค๊ณ , ๊ทธ๊ฒƒ์ด ์–ด๋–ป๊ฒŒ ์›€์ง์ด๋Š”์ง€(์‚ฌ์‹ค์ด ๋“ค์–ด์˜จ๋‹ค)๋ฅผ ์ ๋Š”๋‹ค.
26
+ */
27
+ private renderEmpty;
28
+ private renderClips;
29
+ private renderClip;
30
+ private renderChannels;
31
+ /**
32
+ * ์ฑ„๋„ ํ•˜๋‚˜ โ€” ์–ด๋А ๋ถ€ํ’ˆ์˜ ์–ด๋А ์†์„ฑ์„ ์›€์ง์ด๋‚˜.
33
+ *
34
+ * ์—†๋Š” ๋ถ€ํ’ˆ์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ฑ„๋„์€ ๋ถ‰๊ฒŒ ๋‚ธ๋‹ค. ๋ถ€ํ’ˆ ์ด๋ฆ„์„ ๋ฐ”๊พธ๋ฉด ๊ทธ ์ˆœ๊ฐ„ ์ด๋ ‡๊ฒŒ ๋˜๋Š”๋ฐ,
35
+ * ๊ฒ€์ฆ์€ ์ €์žฅํ•  ๋•Œ ๋งํ•˜๊ณ  ์—ฌ๊ธฐ์„œ๋Š” **๊ทธ ์ž๋ฆฌ์—์„œ** ๋ณด์—ฌ ์ค€๋‹ค.
36
+ */
37
+ private renderChannel;
38
+ /**
39
+ * ํšŒ์ „ ์ค‘์‹ฌ โ€” **`rotation` ์—์„œ๋งŒ ๋œป์ด ์žˆ๋‹ค.**
40
+ *
41
+ * ๊ทธ๋ž˜์„œ ๊ฒฝ๋กœ๊ฐ€ rotation ์ผ ๋•Œ๋งŒ ๋‚ธ๋‹ค. ์–ธ์ œ๋‚˜ ๋‚ด๋ฉด ์ €์ž‘์ž๊ฐ€ ์˜ฎ๊น€ยท๋ฐฐ์œจ์—๋„ ์ ๊ณ , ๊ฒ€์ฆ์ด
42
+ * ์ €์žฅํ•  ๋•Œ ใ€Œ์“ฐ์ด์ง€ ์•Š๋Š”๋‹คใ€๊ณ  ์•Œ๋ฆฐ๋‹ค. ์•ˆ ๋ณด์ด๋ฉด ์ ์„ ์ผ์ด ์—†๋‹ค.
43
+ */
44
+ private renderPivot;
45
+ /**
46
+ * ํ‚คํ”„๋ ˆ์ž„ ํ‘œ.
47
+ *
48
+ * **๋‘˜ ๋ฏธ๋งŒ์œผ๋กœ ๋ชป ๋‚ด๋ ค๊ฐ„๋‹ค.** ํ•˜๋‚˜๋ฟ์ด๋ฉด ์›€์ง์ด๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ž์„ธ ํ•˜๋‚˜์ด๊ณ , ํ˜•์‹์ด
49
+ * ์˜ค๋ฅ˜๋กœ ๋ง‰๋Š”๋‹ค. ์ €์žฅํ•˜๊ณ  ๋‚˜์„œ ์•Œ๋ ค ์ฃผ๋Š” ๊ฒƒ๋ณด๋‹ค ์ง€์šฐ๋Š” ๋‹จ์ถ”๋ฅผ ์ฃฝ์ด๋Š” ๊ฒƒ์ด ๋‚ซ๋‹ค.
50
+ *
51
+ * ์‹œ๊ฐ์ด ์˜ค๋ฆ„์ฐจ์ˆœ์ด์–ด์•ผ ํ•˜๋Š” ๊ฒƒ๋„ ํ˜•์‹์˜ ๊ทœ์น™์ด๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ์–ด๊ธ‹๋‚œ ์ค„์„ ๋ถ‰๊ฒŒ ๋‚ด๊ณ  ๊ฐ’์„
52
+ * ๊ณ ์น˜์ง€๋Š” ์•Š๋Š”๋‹ค โ€” ์ €์ž‘์ž๊ฐ€ 3 ์„ 1 ๋กœ ๊ณ ์น˜๋˜ ์ค‘์ผ ์ˆ˜ ์žˆ๋‹ค.
53
+ */
54
+ private renderKeys;
55
+ /**
56
+ * ์›€์ง์ด๋Š” ๋ถ€ํ’ˆ ์˜ˆ์‚ฐ.
57
+ *
58
+ * **๋„˜์–ด๋„ ๋ง‰์ง€ ์•Š๋Š”๋‹ค.** ์›€์ง์ด๋Š” ๋ถ€ํ’ˆ์€ ์ €๋งˆ๋‹ค ๋‹จ๋… ๋ฌถ์Œ์ด๋ผ draw call ์ด ๋Š˜๊ณ  ํ”„๋ ˆ์ž„๋งˆ๋‹ค
59
+ * ๊ฐฑ์‹ ์ด ๋Š”๋‹ค โ€” ๊ทธ ๋Œ€๊ฐ€๊ฐ€ ์ˆ˜๋กœ ๋ณด์ด๋ฉด ์ €์ž‘์ž๊ฐ€ ์•„๋‚€๋‹ค. ๋žœ๋“œ๋งˆํฌ ์„ค๋น„ ํ•˜๋‚˜๋Š” ์ •๊ตํ•ด๋„ ๋˜๊ณ ,
60
+ * ๊ทธ ๊ฐ’์ด ๋„๋ฉด ์˜ˆ์‚ฐ์— ๋“œ๋Ÿฌ๋‚˜๋ฉด ๋œ๋‹ค.
61
+ */
62
+ private renderBudget;
63
+ /**
64
+ * ๋ณด๋“œ์— ์‹ค์–ด ์˜ฌ๋ ค๋ณด๋‚ธ๋‹ค.
65
+ *
66
+ * `animations` ๋Š” ๋„ํ˜• ์ „์ฒด์˜ ๊ฒƒ์ด๋ฏ€๋กœ ๋ถ€ํ’ˆ ํŽธ์ง‘(`update-part`)์ด ์•„๋‹ˆ๋ผ `update-board` ๋กœ
67
+ * ๊ฐ„๋‹ค. ๋นˆ ๋ฐฐ์—ด์€ ์นธ์„ ์ง€์šด๋‹ค โ€” clip ์„ ๋‹ค ์ง€์šด ๋„ํ˜•์€ `animations: []` ๊ฐ€ ์•„๋‹ˆ๋ผ ์—†๋Š” ๊ฒƒ์ด๋‹ค.
68
+ */
69
+ private tell;
70
+ private patchClip;
71
+ private patchChannel;
72
+ private addClip;
73
+ private renameClip;
74
+ private setDrive;
75
+ private removeClip;
76
+ private addChannel;
77
+ private setChannel;
78
+ /**
79
+ * ๊ฒฝ๋กœ๋ฅผ ๋ฐ”๊พผ๋‹ค โ€” **๊ฐ’๊นŒ์ง€ ํ•จ๊ป˜ ์˜ฎ๊ธด๋‹ค.**
80
+ *
81
+ * ์˜ฎ๊น€ยทํšŒ์ „์˜ 0 ์€ ใ€Œ์ œ์ž๋ฆฌใ€์ธ๋ฐ ๋ฐฐ์œจ์˜ 0 ์€ **๋ถ€ํ’ˆ์„ ์ง€์šด๋‹ค.** ๊ฒฝ๋กœ๋งŒ ๋ฐ”๊พธ๊ณ  ๊ฐ’์„ ๊ทธ๋Œ€๋กœ
82
+ * ๋‘๋ฉด ์ €์ž‘์ž๋Š” ๋ถ€ํ’ˆ์ด ์‚ฌ๋ผ์ง„ ๊ฒƒ์„ ๋ณด๊ณ  ๋„๊ตฌ๊ฐ€ ๊ณ ์žฅ ๋‚œ ์ค„ ์•ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์˜ฎ๊น€ยทํšŒ์ „ โ†” ๋ฐฐ์œจ์„
83
+ * ๊ฑด๋„ ๋•Œ ์‹œ์ž‘๊ฐ’์„ ๊ทธ ๊ฒฝ๋กœ์˜ ์ œ์ž๋ฆฌ๋กœ ๋˜๋Œ๋ฆฐ๋‹ค. ์‹œ๊ฐ์€ ์ง€ํ‚จ๋‹ค โ€” ์ €์ž‘์ž๊ฐ€ ์ง  ๋ฐ•์ž๋‹ค.
84
+ */
85
+ private setPath;
86
+ private removeChannel;
87
+ /** ๋งˆ์ง€๋ง‰ ํ‚ค์—์„œ 1 ์ดˆ ๋’ค. ๊ฐ’์€ ๊ทธ ํ‚ค๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฐ›๋Š”๋‹ค โ€” ๋ถ™์—ฌ ๋†“๊ณ  ๊ณ ์น˜๋Š” ๊ฒƒ์ด ์งœ๊ธฐ ์‰ฝ๋‹ค. */
88
+ private addKey;
89
+ private setKey;
90
+ /** ๋‘˜ ๋ฏธ๋งŒ์œผ๋กœ ๋‚ด๋ ค๊ฐ€์ง€ ์•Š๋Š”๋‹ค โ€” ๋‹จ์ถ”๊ฐ€ ์ด๋ฏธ ์ฃฝ์–ด ์žˆ์ง€๋งŒ ๋ฐ–์—์„œ ๋ถˆ๋ฆด ์ˆ˜ ์žˆ๋‹ค. */
91
+ private removeKey;
92
+ }
93
+ export {};