@imagineio/configurator-sdk 0.1.0-beta.1

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 (246) hide show
  1. package/LICENSE.md +294 -0
  2. package/README.md +103 -0
  3. package/dist/00a41227ff.js +1 -0
  4. package/dist/00ab3dcbb5.js +1 -0
  5. package/dist/01a664fa9f.css +51 -0
  6. package/dist/04746bff9a.js +1 -0
  7. package/dist/04931f795e.js +1 -0
  8. package/dist/05973a4da2.js +3 -0
  9. package/dist/061b81ad81.js +1 -0
  10. package/dist/066fc9aa40.js +1 -0
  11. package/dist/09c4973968.js +1 -0
  12. package/dist/0a35b2c5f4.js +1 -0
  13. package/dist/0af28430ab.js +1 -0
  14. package/dist/0e2dedae0d.js +1 -0
  15. package/dist/0f7c8345a8.js +1 -0
  16. package/dist/12b8165d6d.js +1 -0
  17. package/dist/1458417bdb.js +1 -0
  18. package/dist/14c83bc57a.js +1 -0
  19. package/dist/15d6bec3b5.css +150 -0
  20. package/dist/16a399703e.js +1 -0
  21. package/dist/17876f4322.css +114 -0
  22. package/dist/1870fc037b.js +1 -0
  23. package/dist/1a2629800a.css +196 -0
  24. package/dist/1e243363f6.js +1 -0
  25. package/dist/1fac915f8b.js +1 -0
  26. package/dist/1fff100656.js +1 -0
  27. package/dist/205827c5c8.js +1 -0
  28. package/dist/20b0104576.js +1 -0
  29. package/dist/2239b22616.js +1 -0
  30. package/dist/22bd38ddcf.js +1 -0
  31. package/dist/239b619005.css +1849 -0
  32. package/dist/23dc0ccf32.js +1 -0
  33. package/dist/26155bf68c.js +1 -0
  34. package/dist/2774152dd2.js +1 -0
  35. package/dist/27fee7007f.js +1 -0
  36. package/dist/281cf952fa.js +1 -0
  37. package/dist/28a9d58274.js +1 -0
  38. package/dist/28d887bf8a.js +1 -0
  39. package/dist/28df2aa12f.js +1 -0
  40. package/dist/297e653adf.js +1 -0
  41. package/dist/2990ba64d6.js +1 -0
  42. package/dist/2b6aa27f6d.js +1 -0
  43. package/dist/2c7c1bcef1.js +1 -0
  44. package/dist/2cab5c5c23.js +1 -0
  45. package/dist/2cafe3274b.js +1 -0
  46. package/dist/2e366d7386.js +1 -0
  47. package/dist/2f8cc8b292.js +1 -0
  48. package/dist/30be653f00.css +110 -0
  49. package/dist/31ea036f5c.js +1 -0
  50. package/dist/32861ea2b0.js +1 -0
  51. package/dist/33fa2c8ca2.js +1 -0
  52. package/dist/35d8449ed8.js +1 -0
  53. package/dist/3656ffa1b8.js +1 -0
  54. package/dist/367a479d3a.js +1 -0
  55. package/dist/371ed78aa2.js +1 -0
  56. package/dist/37596ace72.js +1 -0
  57. package/dist/37addc7fb3.js +1 -0
  58. package/dist/388cadacbd.js +1 -0
  59. package/dist/39a62ef7b8.js +1 -0
  60. package/dist/3bbcee0334.js +1 -0
  61. package/dist/3c916f744f.js +1 -0
  62. package/dist/3f37665dd1.js +1 -0
  63. package/dist/3fb3ab6757.js +1 -0
  64. package/dist/40d6aeb28c.js +1 -0
  65. package/dist/41ed5985ad.js +1 -0
  66. package/dist/431a2d8618.js +1 -0
  67. package/dist/44a229099f.js +1 -0
  68. package/dist/4741e5d07d.css +263 -0
  69. package/dist/4910c07ca8.css +411 -0
  70. package/dist/4a99ddb3fd.js +1 -0
  71. package/dist/4aa671f9f6.js +1 -0
  72. package/dist/4b8958aa4c.js +1 -0
  73. package/dist/4ba4f544b9.js +1 -0
  74. package/dist/4c24338793.js +1 -0
  75. package/dist/4d7a0d1897.js +1 -0
  76. package/dist/4e1db1e3b0.js +1 -0
  77. package/dist/4e7d0a0d4a.js +1 -0
  78. package/dist/51b23203e5.css +1447 -0
  79. package/dist/52436e0169.js +1 -0
  80. package/dist/54413c1eae.js +1 -0
  81. package/dist/54f0fcf38b.js +1 -0
  82. package/dist/55ab45ada4.css +370 -0
  83. package/dist/561dc3f1ab.js +1 -0
  84. package/dist/58e6419ba8.js +1 -0
  85. package/dist/5c9fd9201c.js +1 -0
  86. package/dist/5d05e8982e.js +1 -0
  87. package/dist/5d5e8a9c58.js +3 -0
  88. package/dist/5e4f2349ff.js +1 -0
  89. package/dist/609e5e5d28.js +1 -0
  90. package/dist/60d697292c.js +1 -0
  91. package/dist/61e0c0c9b5.js +1 -0
  92. package/dist/631a9f7fac.js +1 -0
  93. package/dist/64e9020b49.js +1 -0
  94. package/dist/66c461dc2c.js +1 -0
  95. package/dist/672404d987.js +1 -0
  96. package/dist/67f6338a4a.js +1 -0
  97. package/dist/6855e6a3b1.js +1 -0
  98. package/dist/6b0a81e4f8.js +1 -0
  99. package/dist/6ba86aa3b8.js +1 -0
  100. package/dist/6bff84d27e.js +1 -0
  101. package/dist/6c0a2572dd.js +1 -0
  102. package/dist/6d238282c1.js +1 -0
  103. package/dist/6e2595aa36.js +1 -0
  104. package/dist/6f9ae59d6c.js +1 -0
  105. package/dist/70dd811d74.js +1 -0
  106. package/dist/710c1ab641.js +1 -0
  107. package/dist/7206ce49c6.js +1 -0
  108. package/dist/7281d77ed9.js +1 -0
  109. package/dist/73f7d65985.js +1 -0
  110. package/dist/776277593f.js +1 -0
  111. package/dist/79a397bb92.js +1 -0
  112. package/dist/7a748aae59.js +1 -0
  113. package/dist/7bfb0ecfbb.css +572 -0
  114. package/dist/7bfcd0a517.js +1 -0
  115. package/dist/7d9ddaeb47.js +1 -0
  116. package/dist/7f833bc5af.js +1 -0
  117. package/dist/811b403d43.js +1 -0
  118. package/dist/817d930a49.js +1 -0
  119. package/dist/81802759ca.js +1 -0
  120. package/dist/81eb433604.js +1 -0
  121. package/dist/82a8a4bc35.js +1 -0
  122. package/dist/85af90fade.js +1 -0
  123. package/dist/872c4302e0.js +1 -0
  124. package/dist/87bb469216.js +1 -0
  125. package/dist/87dcc12b65.js +1 -0
  126. package/dist/87f511c4a8.js +1 -0
  127. package/dist/88251d6671.js +1 -0
  128. package/dist/882bc739c8.js +1 -0
  129. package/dist/89ab18ebc5.js +1 -0
  130. package/dist/8a22e8944f.css +563 -0
  131. package/dist/8a3a57c008.js +1 -0
  132. package/dist/8ade32d067.js +1 -0
  133. package/dist/8bf6d26ad6.css +233 -0
  134. package/dist/8c27edda0f.js +1 -0
  135. package/dist/8db8655f21.js +24 -0
  136. package/dist/8f60e5059a.js +1 -0
  137. package/dist/91707f5ca0.css +78 -0
  138. package/dist/921bf270dd.js +20 -0
  139. package/dist/9326c23506.js +1 -0
  140. package/dist/94a0a79c65.js +1 -0
  141. package/dist/9526094bb7.js +1 -0
  142. package/dist/9544661159.js +1 -0
  143. package/dist/95a44ebec2.js +1 -0
  144. package/dist/970313b92b.js +1 -0
  145. package/dist/9794652102.js +1 -0
  146. package/dist/983cbed22c.js +1 -0
  147. package/dist/9840b9ce12.js +1 -0
  148. package/dist/98f3644031.js +1 -0
  149. package/dist/992778075d.css +353 -0
  150. package/dist/9c6c598569.js +1 -0
  151. package/dist/9f474b5d1a.js +1 -0
  152. package/dist/a0f71d0bf5.js +1 -0
  153. package/dist/a3c983d431.js +1 -0
  154. package/dist/a3f18e76fe.js +1 -0
  155. package/dist/a493e9aa8f.js +1 -0
  156. package/dist/a77b15c0d6.js +1 -0
  157. package/dist/a811c90bd5.js +1 -0
  158. package/dist/a822c5e4f2.js +1 -0
  159. package/dist/aaa0e82d7f.css +69 -0
  160. package/dist/ab6c80484f.js +1 -0
  161. package/dist/ae96f219e3.js +1 -0
  162. package/dist/b11b38869d.css +427 -0
  163. package/dist/b1349d5a21.js +4 -0
  164. package/dist/b14379d31b.css +151 -0
  165. package/dist/b3efb26fd7.js +1 -0
  166. package/dist/b59b0dde17.js +1 -0
  167. package/dist/b5c372377f.js +1 -0
  168. package/dist/b976df09ec.js +1 -0
  169. package/dist/baeaed46c9.js +1 -0
  170. package/dist/bb719febc6.js +1 -0
  171. package/dist/bcd44b4040.js +1 -0
  172. package/dist/bdc4e4c5b9.css +209 -0
  173. package/dist/bdec200d00.js +1 -0
  174. package/dist/be0cfe2236.js +1 -0
  175. package/dist/be337ddda5.js +1 -0
  176. package/dist/c12c112c6f.js +1 -0
  177. package/dist/c2a14a77ae.js +1 -0
  178. package/dist/c3b8f1973b.js +1 -0
  179. package/dist/c44d37da7a.js +1 -0
  180. package/dist/c4790179f1.js +1 -0
  181. package/dist/c5e990946e.js +1 -0
  182. package/dist/c71892453b.js +1 -0
  183. package/dist/c9a1656c62.js +1 -0
  184. package/dist/ca497b066c.js +1 -0
  185. package/dist/cdb4a0f7b3.js +3 -0
  186. package/dist/ce663020e4.js +60 -0
  187. package/dist/cec035efb1.js +1 -0
  188. package/dist/d0f9681634.js +1 -0
  189. package/dist/d118c2e7ba.js +1 -0
  190. package/dist/d20718159b.js +3 -0
  191. package/dist/d30f1f506e.js +1 -0
  192. package/dist/d3cd7f1bc1.js +1 -0
  193. package/dist/d4378d9afa.js +1 -0
  194. package/dist/d464da28a5.js +1 -0
  195. package/dist/d566d3874b.js +1 -0
  196. package/dist/d617bbb9f5.js +26 -0
  197. package/dist/d65f32e004.js +1 -0
  198. package/dist/d6851ea979.js +1 -0
  199. package/dist/d7c9500ba9.js +1 -0
  200. package/dist/d803155241.js +1 -0
  201. package/dist/d903df4e0d.js +1 -0
  202. package/dist/d94df858ea.js +1 -0
  203. package/dist/da7b5f450d.js +1 -0
  204. package/dist/daa11edd01.js +1 -0
  205. package/dist/db4afd43c9.js +1 -0
  206. package/dist/dbd5ba1d07.js +1 -0
  207. package/dist/dc2a1a0e13.js +1 -0
  208. package/dist/dc812f3e14.js +1 -0
  209. package/dist/dcbf419090.css +122 -0
  210. package/dist/dcdba78ddf.js +1 -0
  211. package/dist/de408c4516.js +1 -0
  212. package/dist/e1cd279733.js +1 -0
  213. package/dist/e379e0039b.js +1 -0
  214. package/dist/e4fe0551fd.js +1 -0
  215. package/dist/e6eed481cc.css +28 -0
  216. package/dist/e75f1e5992.js +1 -0
  217. package/dist/ea8577d22b.js +1 -0
  218. package/dist/ec4a34fc80.css +313 -0
  219. package/dist/ed6a54cdf6.js +1 -0
  220. package/dist/ee242c0099.js +1 -0
  221. package/dist/ee9b9fd7d1.js +1 -0
  222. package/dist/f0c3d8a28a.js +1 -0
  223. package/dist/f11a45a150.js +1 -0
  224. package/dist/f1b3b2622a.js +1 -0
  225. package/dist/f7b4a178e3.js +1 -0
  226. package/dist/f89d7cd931.js +1 -0
  227. package/dist/f8cb80a93c.js +1 -0
  228. package/dist/f8fec86f10.js +1 -0
  229. package/dist/fbd844f2d1.js +1 -0
  230. package/dist/fe235d7160.js +1 -0
  231. package/dist/fe58a84b85.js +1 -0
  232. package/dist/fe68b361ba.js +1 -0
  233. package/dist/ff5b3d17e2.js +1 -0
  234. package/dist/styles/globals.css +442 -0
  235. package/dist/styles/themes.css +532 -0
  236. package/dist/styles/variables.css +299 -0
  237. package/package.json +68 -0
  238. package/static/assets/draco/README.md +32 -0
  239. package/static/assets/draco/draco_decoder.js +34 -0
  240. package/static/assets/draco/draco_decoder.wasm +0 -0
  241. package/static/assets/draco/draco_encoder.js +35 -0
  242. package/static/assets/draco/draco_encoder.wasm +0 -0
  243. package/static/assets/draco/draco_encoder_wrapper.js +98 -0
  244. package/static/assets/draco/draco_wasm_wrapper.js +117 -0
  245. package/static/favicon.svg +28 -0
  246. package/static/version.txt +1 -0
@@ -0,0 +1,313 @@
1
+ @layer sdk-base, vendor, sdk;
2
+ @layer sdk {
3
+ /* Floating header toolbar - top right of canvas */
4
+ .header {
5
+ display: flex;
6
+ align-items: center;
7
+ gap: 10px;
8
+ position: absolute;
9
+ top: 12px;
10
+ right: 12px;
11
+ z-index: 15;
12
+ }
13
+
14
+ /* Toolbar group (2D, layers, fullscreen) */
15
+ .header__toolbar {
16
+ display: flex;
17
+ align-items: center;
18
+ gap: 2px;
19
+ padding: 3px;
20
+ background: rgba(255, 255, 255, 0.95);
21
+ border-radius: 8px;
22
+ box-shadow: 0 0 40px 0 rgba(0, 0, 0, 0.12);
23
+ }
24
+
25
+ .header__toolbar-btn {
26
+ position: relative;
27
+ display: flex;
28
+ align-items: center;
29
+ justify-content: center;
30
+ width: 32px;
31
+ height: 32px;
32
+ border: none;
33
+ background: transparent;
34
+ border-radius: 4px;
35
+ cursor: pointer;
36
+ color: var(--text-secondary, #666);
37
+ transition: all 0.15s ease;
38
+ }
39
+
40
+ /* CSS tooltip for toolbar buttons */
41
+ .header__toolbar-btn[data-tooltip]::after {
42
+ content: attr(data-tooltip);
43
+ position: absolute;
44
+ top: 100%;
45
+ left: 50%;
46
+ transform: translateX(-50%);
47
+ margin-top: 6px;
48
+ padding: 4px 8px;
49
+ background: rgba(0, 0, 0, 0.8);
50
+ color: var(--bg-primary, #fff);
51
+ font-size: 11px;
52
+ font-weight: 500;
53
+ white-space: nowrap;
54
+ border-radius: 4px;
55
+ opacity: 0;
56
+ visibility: hidden;
57
+ pointer-events: none;
58
+ transition: opacity 0.15s ease, visibility 0.15s ease;
59
+ z-index: 100;
60
+ }
61
+
62
+ .header__toolbar-btn[data-tooltip]:hover::after {
63
+ opacity: 1;
64
+ visibility: visible;
65
+ }
66
+
67
+ .header__toolbar-btn:hover {
68
+ background: rgba(0, 0, 0, 0.06);
69
+ color: var(--text-primary, #333);
70
+ }
71
+
72
+ .header__toolbar-btn--active {
73
+ background: var(--bg-primary, #fff);
74
+ color: var(--color-brand-primary);
75
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
76
+ }
77
+
78
+ /* Guide tooltip — always visible, points user to wall toggle */
79
+ .header__toolbar-btn--guide {
80
+ animation: wall-guide-pulse 1.5s ease-in-out infinite;
81
+ }
82
+
83
+ .header__toolbar-btn[data-guide]::before {
84
+ content: attr(data-guide);
85
+ position: absolute;
86
+ top: 100%;
87
+ left: 50%;
88
+ transform: translateX(-50%);
89
+ margin-top: 8px;
90
+ padding: 6px 12px;
91
+ background: var(--color-brand-primary, var(--color-info, #2563eb));
92
+ color: var(--bg-primary, #fff);
93
+ font-size: 12px;
94
+ font-weight: 500;
95
+ white-space: nowrap;
96
+ border-radius: 6px;
97
+ z-index: 1000;
98
+ pointer-events: none;
99
+ opacity: 1;
100
+ visibility: visible;
101
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
102
+ }
103
+
104
+ /* Small arrow pointing up from the guide tooltip — override data-tooltip ::after */
105
+ .header__toolbar-btn[data-guide][data-tooltip]::after {
106
+ content: '';
107
+ position: absolute;
108
+ top: 100%;
109
+ left: 50%;
110
+ transform: translateX(-50%);
111
+ margin-top: 2px;
112
+ padding: 0;
113
+ background: transparent;
114
+ border: 6px solid transparent;
115
+ border-bottom-color: var(--color-brand-primary, var(--color-info, #2563eb));
116
+ border-radius: 0;
117
+ box-shadow: none;
118
+ opacity: 1;
119
+ visibility: visible;
120
+ z-index: 1001;
121
+ font-size: 0;
122
+ width: 0;
123
+ height: 0;
124
+ }
125
+
126
+ @keyframes wall-guide-pulse {
127
+ 0%, 100% { box-shadow: 0 0 0 0 rgba(37, 99, 235, 0.4); }
128
+ 50% { box-shadow: 0 0 0 6px rgba(37, 99, 235, 0); }
129
+ }
130
+
131
+ .header__toolbar-btn svg {
132
+ width: 18px;
133
+ height: 18px;
134
+ }
135
+
136
+ .header__toolbar-label {
137
+ font-size: 12px;
138
+ font-weight: 600;
139
+ letter-spacing: 0.3px;
140
+ }
141
+
142
+ /* Thin vertical divider between toolbar groups */
143
+ .header__toolbar-divider {
144
+ width: 1px;
145
+ height: 18px;
146
+ background: rgba(0, 0, 0, 0.12);
147
+ margin: 0 2px;
148
+ }
149
+
150
+ .header__generate-btn {
151
+ display: flex;
152
+ align-items: center;
153
+ justify-content: center;
154
+ gap: 6px;
155
+ padding: 8px 20px;
156
+ height: 36px;
157
+ background: var(--color-primary, var(--color-brand-primary, #EC4E0B));
158
+ color: var(--text-inverse, #FBFBFB);
159
+ border: 1px solid transparent;
160
+ border-radius: var(--btn-border-radius, 8px);
161
+ font-size: 13px;
162
+ font-weight: 500;
163
+ cursor: pointer;
164
+ transition: background 0.15s ease;
165
+ box-shadow: var(--btn-shadow, 0 0 40px 0 rgba(0, 0, 0, 0.12));
166
+ }
167
+
168
+ .header__generate-btn:hover {
169
+ background: var(--color-primary-dark, #D44509);
170
+ }
171
+
172
+ /* Theme buttonStyle="outline" — render the primary action button as an outline. */
173
+ :root[data-button-style="outline"] .header__generate-btn {
174
+ background: transparent;
175
+ color: var(--color-primary, var(--color-brand-primary, #EC4E0B));
176
+ border-color: var(--color-primary, var(--color-brand-primary, #EC4E0B));
177
+ }
178
+ :root[data-button-style="outline"] .header__generate-btn:hover {
179
+ background: var(--color-primary, var(--color-brand-primary, #EC4E0B));
180
+ color: var(--text-inverse, #FBFBFB);
181
+ }
182
+
183
+ .header__generate-btn:disabled {
184
+ opacity: 0.8;
185
+ cursor: not-allowed;
186
+ }
187
+
188
+ /* Save button — secondary action, sits beside Generate Assets */
189
+ .header__save-btn {
190
+ display: flex;
191
+ align-items: center;
192
+ justify-content: center;
193
+ gap: 6px;
194
+ padding: 8px 16px;
195
+ height: 36px;
196
+ background: #FBFBFB;
197
+ color: #1f1f1f;
198
+ border: 1px solid var(--border-color, #d8d8d8);
199
+ border-radius: var(--btn-border-radius, 8px);
200
+ font-size: 13px;
201
+ font-weight: 500;
202
+ cursor: pointer;
203
+ transition: background 0.15s ease, border-color 0.15s ease;
204
+ box-shadow: var(--btn-shadow, 0 0 40px 0 rgba(0, 0, 0, 0.08));
205
+ }
206
+
207
+ .header__save-btn:hover {
208
+ background: var(--bg-secondary, #f0f0f0);
209
+ border-color: #c0c0c0;
210
+ }
211
+
212
+ .header__save-btn:disabled {
213
+ cursor: not-allowed;
214
+ }
215
+
216
+ .header__save-btn .save-btn__icon {
217
+ width: 16px;
218
+ height: 16px;
219
+ }
220
+
221
+ @media (max-width: 767px) {
222
+ .header__save-btn {
223
+ padding: 0 12px;
224
+ height: 28px;
225
+ font-size: 11px;
226
+ font-weight: 600;
227
+ gap: 5px;
228
+ border-radius: 14px;
229
+ box-shadow: none;
230
+ }
231
+
232
+ .header__save-btn .save-btn__icon {
233
+ width: 14px;
234
+ height: 14px;
235
+ }
236
+ }
237
+
238
+
239
+ /* Tablet (768-1023px) */
240
+ @media (max-width: 1023px) and (min-width: 768px) {
241
+ .header {
242
+ top: 10px;
243
+ right: 10px;
244
+ gap: 6px;
245
+ }
246
+
247
+ .header__toolbar-btn {
248
+ width: 30px;
249
+ height: 30px;
250
+ }
251
+
252
+ .header__generate-btn {
253
+ padding: 6px 16px;
254
+ height: 34px;
255
+ font-size: 12px;
256
+ }
257
+ }
258
+
259
+ /* Mobile (<=767px) */
260
+ @media (max-width: 767px) {
261
+ .header {
262
+ top: 8px;
263
+ right: 8px;
264
+ gap: 4px;
265
+ }
266
+
267
+ .header__toolbar {
268
+ gap: 0;
269
+ padding: 2px;
270
+ }
271
+
272
+ .header__toolbar-btn {
273
+ width: 28px;
274
+ height: 28px;
275
+ }
276
+
277
+ .header__toolbar-btn svg {
278
+ width: 16px;
279
+ height: 16px;
280
+ }
281
+
282
+ .header__toolbar-label {
283
+ font-size: 10px;
284
+ }
285
+
286
+ .header__generate-btn {
287
+ padding: 0 12px;
288
+ height: 28px;
289
+ font-size: 11px;
290
+ font-weight: 600;
291
+ gap: 5px;
292
+ background: linear-gradient(135deg, var(--color-primary, var(--color-brand-primary, #EC4E0B)) 0%, var(--color-primary-dark, #d4430a) 100%);
293
+ border-radius: 14px;
294
+ letter-spacing: 0.2px;
295
+ box-shadow: none;
296
+ }
297
+
298
+ .header__generate-btn:hover {
299
+ background: linear-gradient(135deg, var(--color-primary-dark, #d4430a) 0%, var(--color-primary-dark, #bf3c08) 100%);
300
+ box-shadow: 0 3px 12px rgba(236, 78, 11, 0.4);
301
+ }
302
+
303
+ .header__generate-btn:active {
304
+ transform: scale(0.97);
305
+ }
306
+
307
+ .header__generate-btn:disabled {
308
+ opacity: 0.7;
309
+ box-shadow: none;
310
+ }
311
+ }
312
+
313
+ }
@@ -0,0 +1 @@
1
+ import{jsx as o,jsxs as u}from"react/jsx-runtime";import{memo as L,useEffect as N,useState as D}from"react";import{useLabels as y}from"./28d887bf8a.js";import S from"./d0f9681634.js";import{useUIRegion as b}from"./9840b9ce12.js";import{SlotHost as k}from"./73f7d65985.js";import{ChevronLeft as R,ChevronRight as C,PlusIcon as $,DuplicateIcon as w,DeleteIcon as A}from"./c5e990946e.js";import"./8bf6d26ad6.css";function v(r,t,l=!1){const i=Number(r)||0;try{const a=new Intl.NumberFormat(void 0,{style:"currency",currency:t||"USD",maximumFractionDigits:0}).format(Math.abs(i));return l&&i!==0?`${i>0?"+":"\u2212"}${a}`:a}catch{return`${t||""} ${i.toLocaleString()}`.trim()}}function c({className:r,onClick:t,tooltip:l,disabled:i,children:a}){return u("button",{className:r,onClick:t,children:[a,o("span",{className:`selection-options-panel__tooltip${i?" selection-options-panel__tooltip--warning":""}`,children:l})]})}const M=L(function({actions:t,priceInfo:l}){const{guiVisible:i,isLayoutLoading:a,isMobile:_,isOn:s}=S(),f=b("panels"),g=b("selection"),d=y(),[h,P]=D(!1);if(N(()=>{const e=()=>P(!!document.fullscreenElement);return document.addEventListener("fullscreenchange",e),document.addEventListener("webkitfullscreenchange",e),()=>{document.removeEventListener("fullscreenchange",e),document.removeEventListener("webkitfullscreenchange",e)}},[]),!t||!i||!f||!g)return null;const n=t.disabledActions||{},p=n.add?.disabled?n.add:!_&&h?{disabled:!0,reason:"Exit fullscreen to add a product"}:null;return o("div",{className:"selection-panel-overlay",style:a?{opacity:.5,pointerEvents:"none"}:void 0,children:u("div",{className:"selection-options-panel",onPointerDown:e=>e.stopPropagation(),onClick:e=>e.stopPropagation(),children:[s("panelPrice")&&l&&u("div",{className:"selection-options-panel__price",tabIndex:0,children:[o("span",{className:"selection-options-panel__price-value",children:v(l.unitPrice,l.currency)}),Array.isArray(l.adjustments)&&l.adjustments.length>0&&o("div",{className:"selection-options-panel__price-breakdown",children:l.adjustments.map((e,m)=>u("div",{className:"selection-options-panel__price-row",children:[o("span",{className:"selection-options-panel__price-label",children:e.label??e.name??e.optionName??e.option_name??(m===0?"Base":"Option")}),o("span",{className:"selection-options-panel__price-amount",children:v(e.amount??e.price??e.contribution??e.value??0,l.currency,m>0)})]},m))})]}),s("panelMoveLeft")&&o(c,{className:`selection-options-panel__btn${n.moveLeft?.disabled?" selection-options-panel__btn--disabled":""}`,onClick:e=>{e.stopPropagation(),n.moveLeft?.disabled||t.onMoveLeft()},tooltip:n.moveLeft?.disabled?n.moveLeft.reason:d("panel.moveLeft","Move Left"),disabled:n.moveLeft?.disabled,children:o(R,{})}),s("panelMoveRight")&&o(c,{className:`selection-options-panel__btn${n.moveRight?.disabled?" selection-options-panel__btn--disabled":""}`,onClick:e=>{e.stopPropagation(),n.moveRight?.disabled||t.onMoveRight()},tooltip:n.moveRight?.disabled?n.moveRight.reason:d("panel.moveRight","Move Right"),disabled:n.moveRight?.disabled,children:o(C,{})}),s("panelAdd")&&t.onAdd&&o(c,{className:`selection-options-panel__btn${p?.disabled?" selection-options-panel__btn--disabled":""}`,onClick:e=>{e.stopPropagation(),p?.disabled||t.onAdd()},tooltip:p?.disabled?p.reason:d("panel.add","Add"),disabled:p?.disabled,children:o($,{})}),s("panelDuplicate")&&t.onDuplicate&&o(c,{className:`selection-options-panel__btn${n.duplicate?.disabled?" selection-options-panel__btn--disabled":""}`,onClick:e=>{e.stopPropagation(),n.duplicate?.disabled||t.onDuplicate()},tooltip:n.duplicate?.disabled?n.duplicate.reason:d("panel.duplicate","Duplicate"),disabled:n.duplicate?.disabled,children:o(w,{})}),s("panelDelete")&&t.onDelete&&o(c,{className:`selection-options-panel__btn selection-options-panel__btn--delete${n.delete?.disabled?" selection-options-panel__btn--disabled":""}`,onClick:e=>{e.stopPropagation(),n.delete?.disabled||t.onDelete()},tooltip:n.delete?.disabled?n.delete.reason:d("panel.delete","Delete"),disabled:n.delete?.disabled,children:o(A,{})}),o(k,{name:"selection-panel",ctx:{placementId:t?.placementId??t?.targetId??null,actions:t}})]})})});var U=M;export{U as default};
@@ -0,0 +1 @@
1
+ const l={defaultDoorProduct:"product_single_door_18",defaultBaseHostProduct:"product_double_door_24",defaultTallHostProduct:"product_tall_single_door_15",defaultWallCornerProduct:"product_wall_corner_easy_reach_30",defaultOvenBaseProduct:"product_base_oven_cabinet_24"};function u(o){if(!(!o||typeof o!="object"))for(const t of Object.keys(l))o[t]!=null&&o[t]!==""&&(l[t]=o[t])}var e=l;export{e as default,u as loadDomainDefaults};
@@ -0,0 +1 @@
1
+ class l{generateShareableConfig(e){const{productInstances:t,instanceSelections:r,sceneSelections:n,activeSceneConfigId:o,activeChannelId:c}=e,s={v:1,sc:o,ch:c,p:[],s:{}};for(const[i,a]of Object.entries(t))s.p.push({i,p:a.productId,c:a.configurationId});for(const[i,a]of Object.entries(r))Object.keys(a).length>0&&(s.s[i]=a);return Object.keys(n).length>0&&(s.ss=n),s}encodeConfig(e){try{const t=JSON.stringify(e);return btoa(encodeURIComponent(t))}catch{return null}}decodeConfig(e){try{const t=decodeURIComponent(atob(e));return JSON.parse(t)}catch{return null}}generateShareUrl(e){const t=this.generateShareableConfig(e),r=this.encodeConfig(t);if(!r)return null;const n=new URL(window.location.origin);return n.searchParams.set("config",r),n.toString()}parseUrlConfig(){const t=new URL(window.location.href).searchParams.get("config");return t?this.decodeConfig(t):null}async copyShareUrl(e){const t=this.generateShareUrl(e);if(!t)throw new Error("Failed to generate share URL");return await navigator.clipboard.writeText(t),t}clearUrlConfig(){const e=new URL(window.location.href);e.searchParams.delete("config"),window.history.replaceState({},"",e.toString())}restoreFromConfig(e,t){if(!e||e.v!==1)return!1;const{configurationGraphStore:r,sceneConfigStore:n}=t;try{if(e.ch&&r.getState().setActiveChannel(e.ch),e.s)for(const[o,c]of Object.entries(e.s))for(const[s,i]of Object.entries(c))n.getState().setFeatureSelection(o,s,i,!0);if(e.ss)for(const[o,c]of Object.entries(e.ss))n.getState().setSceneSelection(o,c);return!0}catch{return!1}}}const f=new l;var u=f;export{l as ShareService,u as default};
@@ -0,0 +1 @@
1
+ function i(){if(typeof window>"u")return{domain:null,url:null};const r=window.location;let o=!1;try{o=window.parent!==window}catch{o=!0}if(!o)return{domain:r?.hostname||null,url:r?.href||null};let e=null,t=null;try{const n=window.parent.location.href;n&&(e=n,t=new URL(n).hostname)}catch{}if(!e&&typeof document<"u"&&document.referrer)try{const n=new URL(document.referrer);e=n.href,t=n.hostname}catch{}if(!t)try{const n=r?.ancestorOrigins;if(n&&n.length){const l=n[n.length-1]||n[0];l&&(t=new URL(l).hostname,e=e||l)}}catch{}return{domain:t||null,url:e||null}}export{i as resolveParentPage};
@@ -0,0 +1 @@
1
+ import{useEffect as r}from"react";import{whenConfiguratorLicenceSettled as a}from"./3bbcee0334.js";let o=null;async function l(){if(await a())try{const n=await fetch("/version.txt",{cache:"no-store"});if(!n.ok)return;const e=(await n.text()).trim();if(!e||e.includes("<"))return;window.APP_VERSION=e;let t=null;try{t=localStorage.getItem("APP_VERSION")?.trim()||null}catch{}if(t===e)return;try{localStorage.setItem("APP_VERSION",e)}catch{}if(!t)return;"caches"in window?window.caches.keys().then(i=>Promise.all(i.map(c=>caches.delete(c)))).finally(()=>{window.location.replace(window.location.href)}):window.location.replace(window.location.href)}catch{}}function s(){r(()=>{o||(o=l())},[])}export{s as default};
@@ -0,0 +1 @@
1
+ import{jsx as u,jsxs as y}from"react/jsx-runtime";import{registerSlot as p}from"./73f7d65985.js";import{runAction as b}from"./09c4973968.js";import m from"./8f60e5059a.js";function B(a={}){const{slot:e,label:o,onClick:n,action:i,icon:r,variant:s="default",title:f}=a;if(!e||!o&&!r)return()=>{};if(typeof n!="function"&&typeof i!="string")return()=>{};function c({ctx:t}){const l=m(d=>d.isLayoutLoading);return y("button",{type:"button",className:`sdk-btn${s==="primary"?" sdk-btn--primary":""}`,"data-host-button":o||i||"",onClick:()=>{if(typeof n=="function"){n(t);return}b(i,t)},disabled:l,title:f,children:[r&&u(r,{}),o]})}return p(e,t=>u(c,{ctx:t}))}export{B as registerButton};
@@ -0,0 +1 @@
1
+ import{GLTFExporter as L}from"three/examples/jsm/exporters/GLTFExporter.js";import{WebIO as B,Logger as E}from"@gltf-transform/core";import{KHRDracoMeshCompression as v}from"@gltf-transform/extensions";import{getMediaBaseUrl as C,getArViewerBase as O}from"./9544661159.js";import{presignArModel as I}from"./79a397bb92.js";const W=C(),x="model/gltf-binary";async function _(r,{onUploadProgress:o}={}){const t=await I({contentType:x,fileSize:r.size});if(!t?.upload_url||!t?.fields)throw new Error("AR upload could not be signed");if(t.max_size&&r.size>t.max_size)throw new Error(`This model is ${(r.size/1048576).toFixed(1)} MB, over the ${Math.round(t.max_size/1048576)} MB limit for AR.`);const a=new FormData;for(const[n,c]of Object.entries(t.fields))a.append(n,c);return a.append("file",r,"model.glb"),await new Promise((n,c)=>{const l=new XMLHttpRequest;l.open(t.method||"POST",t.upload_url,!0),l.withCredentials=!1,o&&l.upload.addEventListener("progress",i=>{i.lengthComputable&&o({progress:i.loaded/i.total})}),l.onload=()=>{if(l.status>=200&&l.status<300){n(!0);return}c(new Error(l.status===400?"The model was rejected by storage \u2014 it is larger than declared, or not a GLB.":`AR upload failed (${l.status})`))},l.onerror=()=>c(new Error("AR upload network error")),l.send(a)}),t.public_url}async function U(r,o=1024){if(!r||!r.image)return r;const t=r.image;if(t.width<=o&&t.height<=o&&r.repeat.x<=1&&r.repeat.y<=1)return r;const a=document.createElement("canvas"),n=a.getContext("2d",{alpha:!1,willReadFrequently:!1}),c=r.repeat.x||1,l=r.repeat.y||1;let i=t.width,m=t.height;const d=i/m;i>m?i>o&&(i=o,m=i/d):m>o&&(m=o,i=m*d);let h=i*c,g=m*l;const y=o;if(h>y||g>y){const u=Math.min(y/h,y/g);h=Math.floor(h*u),g=Math.floor(g*u),i=Math.floor(i*u),m=Math.floor(m*u)}a.width=h,a.height=g;const R=n.createPattern(t,"repeat");return n.fillStyle=R,n.save(),n.scale(i/t.width,m/t.height),n.fillRect(0,0,a.width*(t.width/i),a.height*(t.height/m)),n.restore(),new Promise(u=>{let f=!1;a.toBlob(e=>{if(!e){f=!0,u(r);return}const s=URL.createObjectURL(e),p=new Image;p.onload=()=>{if(f)return;f=!0;const w=r.clone();w.image=p,w.needsUpdate=!0,URL.revokeObjectURL(s),u(w)},p.onerror=()=>{f||(f=!0,URL.revokeObjectURL(s),u(r))},setTimeout(()=>{f||(f=!0,URL.revokeObjectURL(s),u(r))},5e3),p.src=s},"image/jpeg")})}function b(r){return r instanceof HTMLImageElement||r instanceof HTMLCanvasElement||r instanceof ImageBitmap||r instanceof HTMLVideoElement||typeof OffscreenCanvas<"u"&&r instanceof OffscreenCanvas||typeof SVGImageElement<"u"&&r instanceof SVGImageElement}function D(r){const o=r.image;if(!o||b(o))return!1;const t=o.width,a=o.height;if(!t||!a)return!0;const n=document.createElement("canvas");n.width=t,n.height=a;const c=n.getContext("2d");if(o instanceof ImageData)c.putImageData(o,0,0);else if(o.data&&ArrayBuffer.isView(o.data)){const l=t*a*4,i=new Uint8ClampedArray(l);for(let m=0;m<l;m++)i[m]=Math.min(255,Math.max(0,o.data[m]*(o.data instanceof Float32Array?255:1)));c.putImageData(new ImageData(i,t,a),0,0)}else return!0;return r.image=n,r.needsUpdate=!0,!1}function P(r){for(const o of Object.keys(r)){const t=r[o];t&&t.isTexture&&t.image&&D(t)&&(r[o]=null)}}function F(r){r.updateMatrixWorld(!0);const o=[];r.traverse(t=>{t.isMesh&&t.geometry&&t.matrixWorld.determinant()<0&&o.push(t)});for(const t of o){if(t.geometry=t.geometry.clone(),t.geometry.applyMatrix4(t.matrixWorld),t.geometry.index){const a=t.geometry.index.array;for(let n=0;n<a.length;n+=3){const c=a[n];a[n]=a[n+2],a[n+2]=c}t.geometry.index.needsUpdate=!0}t.removeFromParent(),t.position.set(0,0,0),t.rotation.set(0,0,0),t.scale.set(1,1,1),t.updateMatrix(),r.add(t)}}async function H({model:r,callBack:o}){const t=r.clone(),a=[];t.traverse(e=>{(e.isTransformControls||e.isHelper||e.isGridHelper||e.isAxesHelper||e.isPolarGridHelper)&&a.push(e)}),a.forEach(e=>e.removeFromParent()),F(t);const n=[];t.traverse(e=>{if(e.name==="scene-room"){n.push(e);return}if(e.name==="scene-dimensions"){n.push(e);return}if(e.isMesh&&e.geometry?.type==="PlaneGeometry"){n.push(e);return}if(e.isMesh&&e.geometry?.type==="CircleGeometry"){n.push(e);return}if(e.isMesh&&e.name==="wall"){n.push(e);return}if(e.isMesh&&e.material?.type==="MeshBasicMaterial"){n.push(e);return}if(e.isLineSegments||e.isLine){n.push(e);return}if(e.isLight||e.isCamera){n.push(e);return}}),n.forEach(e=>e.removeFromParent());const c={};t.traverse(e=>{if(e.isMesh&&e.material){let s=c[e.material.uuid];s||(s=e.material.clone(),c[e.material.uuid]=s),s.emissive&&(s.emissive.setHex(0),s.emissiveIntensity=0),e.material=s}});const l=[],i=[];t.traverse(e=>{if(e.isMesh){if(e.geometry?.type==="PlaneGeometry"||e.name==="wall"){n.push(e);return}if(e.material){let s=c[e.material.uuid];s||(s=e.material.clone(),c[e.material.uuid]=s,l.push(s)),e.material=s}}}),n.forEach(e=>e.removeFromParent()),l.forEach(e=>P(e));const m=["map","normalMap","roughnessMap","metalnessMap","aoMap","emissiveMap"],d=new Map,h=e=>{if(d.has(e))return d.get(e);const s=U(e,512);return d.set(e,s),s};l.forEach(e=>{m.forEach(s=>{e[s]&&i.push(h(e[s]).then(p=>{e[s]=p}))})});const g=4;for(let e=0;e<i.length;e+=g)await Promise.all(i.slice(e,e+g));const y=new L,R={binary:!0,embedImages:!0},u=console.warn;console.warn=(...e)=>{(typeof e[0]=="string"?e[0]:"").startsWith("THREE.GLTFExporter:")||u.apply(console,e)};const f=()=>{console.warn!==u&&(console.warn=u)};return new Promise((e,s)=>{y.parse(t,async function(p){f();try{const w=new B().setLogger(new E(E.Verbosity.ERROR)).registerExtensions([v]).registerDependencies({"draco3d.encoder":await window.DracoEncoderModule(),"draco3d.decoder":await window.DracoDecoderModule()}),M=await w.readBinary(new Uint8Array(p));M.setLogger(new E(E.Verbosity.ERROR)),M.createExtension(v).setRequired(!0).setEncoderOptions({method:v.EncoderMethod.EDGEBREAKER,encodeSpeed:5,decodeSpeed:5,quantizationBits:{POSITION:14,NORMAL:10,COLOR:8,TEX_COORD:12,GENERIC:12}});const T=await w.writeBinary(M),A=new Blob([T],{type:"application/octet-stream"});o?.(A),e()}catch{const M=new Blob([p],{type:"application/octet-stream"});o?.(M),e()}},function(p){f(),s(p)},R)}).finally(f)}async function $({scene:r,onProgress:o,onComplete:t,onError:a}){try{o?.(5),await H({model:r,callBack:async n=>{try{o?.(30);const c=await _(n,{onUploadProgress:m=>{const d=40+Math.min(m.progress*50,50);o?.(Math.round(d))}});o?.(92);const i=`${(O()||`${window.location.origin}/ar-viewer`).replace(/\/+$/,"")}?data=${encodeURIComponent(c)}`;o?.(100),t?.(i,{publicUrl:c})}catch(c){a?.(G(c))}}})}catch(n){a?.(n.message||"Failed to export 3D model")}}function G(r){const o=r?.status;return r?.code==="EMBED_NOT_LICENSED"?r.detail||"This configurator is not licensed to run on this website.":o===403?"This configurator is in read-only mode, so AR models cannot be uploaded.":o===401?"AR upload was not authorised \u2014 the session credential is missing or expired.":o===429?"Too many AR models were prepared just now. Please wait a minute and try again.":o===400?r.detail||"The AR model was rejected \u2014 check the file size and format.":r?.message||"Failed to upload AR model"}export{x as AR_CONTENT_TYPE,W as S3_BUCKET_PREFIX_URL,H as exportModel,$ as generateARModel,_ as uploadArModel};
@@ -0,0 +1 @@
1
+ import{Fragment as H,jsx as e,jsxs as s}from"react/jsx-runtime";import{useLabels as re}from"./28d887bf8a.js";import{useState as oe,useEffect as ce,useCallback as y,useRef as fe,useMemo as ye}from"react";import F from"./8f60e5059a.js";import c from"./3f37665dd1.js";import we from"./d94df858ea.js";import Se from"./872c4302e0.js";import{generateImage as ze,generationErrorMessage as He}from"./d7c9500ba9.js";import{refreshAiQuota as Ve,aiQuotaBlock as Ae}from"./2f8cc8b292.js";import{CARD_LOAD_RETRIES as Ke}from"./0e2dedae0d.js";import{captureAndWarm as We}from"./0e2dedae0d.js";import{generateARModel as Ce}from"./f7b4a178e3.js";import{getR3FState as Re}from"./e1cd279733.js";import ke from"./9c6c598569.js";import de,{deriveSceneFeatures as xe}from"./be337ddda5.js";import{FEATURE_ROLES as Pe,FEATURE_TYPES as Ie,getSelectionByRole as Ee,getSelectionByType as Te}from"./f8cb80a93c.js";import{CloseIcon as De,ImageIcon as Le,EyeIcon as qe,DownloadIcon as me,RegenerateIcon as T,ExternalLinkIcon as Ze,CopyIcon as Je,CheckIcon as Xe,FileIcon as _e,ARIcon as ea,ErrorIcon as ue,ChevronLeft as aa,ChevronRight as sa}from"./c5e990946e.js";import{QRCodeSVG as ta}from"qrcode.react";import"./51b23203e5.css";const ra={"silo-front":"silo_front","lifestyle-1":"lifestyle_1","lifestyle-2":"lifestyle_2"};function oa(){const r=re(),u=F(a=>a.modalOpen),v=F(a=>a.activeModal),l=F(a=>a.closeModal),m=u&&v==="generateAssets",b=c(a=>a.assets),A=c(a=>a.isGenerating),n=c(a=>a.generateAll),N=c(a=>a.retryAsset),d=c(a=>a.aiQuota),C=c(a=>a.resetAssets),p=c(a=>a.uploadStatus),$=c(a=>a.uploadProgress),P=c(a=>a.aiGenerationStatus),D=c(a=>a.pipelineMessage),R=fe(!1),O="pdp-grid",U=p==="in_progress"||P==="in_progress",k=(p==="complete"||p==="idle")&&P==="complete",V=p==="error"||P==="error",I=we(a=>a.sceneSelections),w=Se(a=>a.options),K=F(a=>a.hostStyles),W=F(a=>a.hostMaterials),Z=ye(()=>{const a=[],t=ke.getState().activeSceneConfigId,o=xe(de.getState().sceneConfigurations?.[t]),i=Te(I,o,Ie.LAYOUT);i&&w[i]&&a.push(w[i].name);const h=Ee(I,o,Pe.DOOR_STYLE),g=h&&w[h]?.name||"",M=g?[g]:[];for(const E of Object.values(K))if(E){const f=Object.values(w).find(z=>z.value===E)?.name;f&&!M.includes(f)&&M.push(f)}M.length&&a.push(M.join(", "));const Y=Ee(I,o,Pe.PIECE_FINISH),se=Y&&w[Y]?.name||"",G=se?[se]:[];for(const E of Object.values(W))if(E){const f=Object.values(w).find(z=>z.value===E)?.name;f&&!G.includes(f)&&G.push(f)}return G.length&&a.push(G.join(", ")),a},[I,w,K,W]);ce(()=>{if(m&&!R.current){R.current=!0;const{uploadStatus:a,aiGenerationStatus:t,assets:o}=c.getState();if(!(a!=="idle"||t!=="idle"||o.some(h=>h.status!=="idle"))){const h=setTimeout(()=>n(),300);return()=>clearTimeout(h)}}m||(R.current=!1)},[m,n]);const[S,x]=oe(null),_=ye(()=>b.filter(a=>a.status==="complete"&&a.url&&(a.type==="silo"||a.type==="lifestyle")),[b]),L=S!==null&&_[S]||null,Q=y(()=>{l()},[l]);ce(()=>{if(!m)return;const a=t=>{t.key==="Escape"&&(S!==null?x(null):Q()),S!==null&&_.length>1&&(t.key==="ArrowRight"&&x(o=>(o+1)%_.length),t.key==="ArrowLeft"&&x(o=>(o-1+_.length)%_.length))};return document.addEventListener("keydown",a),document.body.style.overflow="hidden",()=>{document.removeEventListener("keydown",a),document.body.style.overflow=""}},[m,Q,S,_.length]);const Me=y(a=>{if(navigator.clipboard)navigator.clipboard.writeText(a);else{const t=document.createElement("textarea");t.value=a,t.style.cssText="position:fixed;top:0;left:0;opacity:0;pointer-events:none",document.body.appendChild(t),t.focus(),t.select();try{document.execCommand("copy")}catch{}document.body.removeChild(t)}},[]),ne=y(()=>{C(),setTimeout(()=>{const a=c.getState();a.setPipelineMessage("Generating Content"),a.setAiGenerationStatus("in_progress"),n();const t=Re()?.scene??null;if(t){const{updateAsset:o}=c.getState();o("ar-viewer",{status:"generating",progress:0,error:null}),Ce({scene:t,onProgress:i=>o("ar-viewer",{progress:i}),onComplete:i=>o("ar-viewer",{status:"complete",progress:100,url:i}),onError:i=>o("ar-viewer",{status:"error",progress:0,error:i||"AR generation failed"})})}},100)},[C,n]),Ge=y(()=>{const a=Re()?.scene??null;if(!a)return;const{updateAsset:t}=c.getState();t("ar-viewer",{status:"generating",progress:0,error:null}),Ce({scene:a,onProgress:o=>t("ar-viewer",{progress:o}),onComplete:o=>t("ar-viewer",{status:"complete",progress:100,url:o}),onError:o=>t("ar-viewer",{status:"error",error:o||"AR generation failed"})})},[]),Fe=y((a,t)=>{const o=_.findIndex(i=>i.url===a);x(o>=0?o:0)},[_]),ge=y(async(a,t)=>{try{const i=await(await fetch(a)).blob(),h=URL.createObjectURL(i),g=document.createElement("a");g.href=h,g.download=`${t.replace(/[^a-zA-Z0-9]/g,"_")}.jpg`,document.body.appendChild(g),g.click(),document.body.removeChild(g),URL.revokeObjectURL(h)}catch{window.open(a,"_blank")}},[]),$e=y(async a=>{const t=ra[a];if(!t)return;const o=await Ve();if(c.getState().setAiQuota(o),Ae(o))return;const{updateAsset:i,startSlowProgress:h}=c.getState();i(a,{status:"generating",progress:0,url:null,dataUrl:null,error:null}),h(a);try{const{_assetGenParams:g,uploadedImageUrl:M}=c.getState(),Y=g?.[a],se=we.getState().sceneSelections,G=ke.getState().activeSceneConfigId,E=xe(de.getState().sceneConfigurations?.[G]),te=Te(se,E,Ie.LAYOUT),f=te?Se.getState().options[te]:null,z=Y?{...Y,allowedAngles:[t]}:{productName:"Product",productDescription:"Create an image. Professional product photograph of the exact product from the reference image. Preserve the exact shape, color, texture, and proportions. Soft diffused studio lighting, clean crisp edges.",imageUrl:M||"",allowedAngles:[t],size:"1K",layoutType:f?.value||"l_shaped",layoutName:f?.name||"L-Shaped"},ie=await ze({...z,assetId:a,systemId:de.getState().systemId??null}),le=ie?.images?.[0]?.url;if(!le)throw new Error("Regeneration returned no image URL");const Ye=await We(le);i(a,{status:"complete",progress:100,url:le,dataUrl:Ye}),ie.quota&&c.getState().setAiQuota(ie.quota)}catch(g){i(a,{status:"error",error:He(g,"Regeneration failed. Try again.")})}},[]),pe=b.filter(a=>a.type==="silo"||a.type==="lifestyle"),ve=!!Ae(d),Oe=pe.some(a=>a.status==="complete"||a.status==="generating"),B=pe.filter(a=>a.status!=="blocked"),be=!!d&&!Oe&&(ve||d.remaining===0)||B.length===0,Ue=B.length<pe.length,Qe=be?"02":"03",Be=b.find(a=>a.type==="ar"),q=b.find(a=>a.type==="pdf"),j=b.filter(a=>a.status!=="idle"),J=j.length,Ne=j.filter(a=>a.status==="complete").length,X=j.filter(a=>a.status==="error").length,je=j.filter(a=>a.status==="blocked").length,ee=Ne+X+je===J&&J>0,ae=J>0?Math.round(j.reduce((a,t)=>a+(t.status==="blocked"?100:t.progress),0)/J):0,he=p==="idle"&&P==="in_progress"?ae:p==="idle"?0:Math.round(p==="in_progress"?$*.3:30+ae*.7);return m?e("div",{className:"pdp-overlay",onClick:Q,children:s("div",{className:"pdp-container",onClick:a=>a.stopPropagation(),role:"dialog","aria-modal":"true",children:[s("div",{className:"pdp-topbar",children:[s("div",{className:"pdp-topbar__left",children:[r("assets.source","From Configuration")?e("span",{className:"pdp-topbar__source",children:r("assets.source","From Configuration")}):null,Z.map((a,t)=>{const o=a.split(", "),i=o.length>2;return s("span",{className:"pdp-topbar__crumb",children:[e("span",{className:"pdp-topbar__sep"}),i?`${o[0]}, ${o[1]}...`:a,i&&e("span",{className:"pdp-topbar__crumb-tip",children:a})]},t)})]}),s("div",{className:"pdp-topbar__right",children:[U&&s("div",{className:"pdp-topbar__progress",children:[s("div",{className:"pdp-topbar__progress-ring",children:[s("svg",{viewBox:"0 0 36 36",children:[e("circle",{className:"pdp-topbar__ring-bg",cx:"18",cy:"18",r:"15.9"}),e("circle",{className:"pdp-topbar__ring-fill",cx:"18",cy:"18",r:"15.9",strokeDasharray:`${he} 100`})]}),s("span",{className:"pdp-topbar__ring-text",children:[he,"%"]})]}),e("span",{className:"pdp-topbar__progress-label",children:D})]}),V&&!U&&e("span",{className:"pdp-topbar__status pdp-topbar__status--warn",children:D}),k&&!ee&&s("div",{className:"pdp-topbar__progress",children:[s("div",{className:"pdp-topbar__progress-ring",children:[s("svg",{viewBox:"0 0 36 36",children:[e("circle",{className:"pdp-topbar__ring-bg",cx:"18",cy:"18",r:"15.9"}),e("circle",{className:"pdp-topbar__ring-fill",cx:"18",cy:"18",r:"15.9",strokeDasharray:`${ae} 100`})]}),s("span",{className:"pdp-topbar__ring-text",children:[ae,"%"]})]}),e("span",{className:"pdp-topbar__progress-label",children:A?r("assets.generating","Generating assets..."):r("assets.preparing","Preparing...")})]}),k&&ee&&X===0&&s(H,{children:[s("span",{className:"pdp-topbar__status pdp-topbar__status--done",children:[e("span",{className:"pdp-topbar__status-dot"}),r("assets.allReady","All assets ready")]}),s("button",{className:"pdp-topbar__regenerate",onClick:ne,children:[e(T,{className:"pdp-btn__icon"}),r("assets.regenerateAll","Regenerate All")]})]}),k&&ee&&X>0&&s(H,{children:[s("span",{className:"pdp-topbar__status pdp-topbar__status--warn",children:[Ne," ready \xB7 ",X," failed"]}),s("button",{className:"pdp-topbar__regenerate",onClick:ne,children:[e(T,{className:"pdp-btn__icon"}),r("assets.regenerateAll","Regenerate All")]})]}),e("button",{className:"pdp-topbar__close",onClick:Q,"aria-label":"Close",children:e(De,{})})]})]}),s("div",{className:"pdp-scroll",children:[s("section",{className:"pdp-hero",children:[e("div",{className:"pdp-hero__accent"}),s("div",{className:"pdp-hero__content",children:[s("div",{className:"pdp-hero__text",children:[e("span",{className:"pdp-section-num",children:"01"}),s("h1",{className:"pdp-hero__title",children:[r("assets.hero.title1","Specification &"),e("br",{}),r("assets.hero.title2","Sales Document")]}),e("p",{className:"pdp-hero__desc",children:"Complete specification document with bill of materials, pricing breakdown, and detailed product information \u2014 ready for client presentation."}),s("div",{className:"pdp-hero__actions",children:[q?.status==="complete"&&s(H,{children:[s("a",{className:"pdp-btn pdp-btn--primary pdp-btn--lg",href:q.url,target:"_blank",rel:"noopener noreferrer",children:[e(qe,{className:"pdp-btn__icon"}),"View PDF"]}),s("a",{className:"pdp-btn pdp-btn--outline pdp-btn--lg",href:q.url,download:"specification.pdf",children:[e(me,{className:"pdp-btn__icon"}),"Download"]})]}),q?.status==="error"&&s("button",{className:"pdp-btn pdp-btn--outline pdp-btn--lg",onClick:()=>N(q.id),children:[e(T,{className:"pdp-btn__icon"}),"Retry Generation"]})]})]}),e("div",{className:"pdp-hero__preview",children:e(na,{asset:q})})]})]}),!be&&s("section",{className:"pdp-section","data-part":"assets/imagery",children:[s("div",{className:"pdp-section__header",children:[s("div",{className:"pdp-section__header-text",children:[e("span",{className:"pdp-section-num",children:"02"}),r("assets.imagery.title","Product Imagery")?e("h2",{className:"pdp-section__title",children:r("assets.imagery.title","Product Imagery")}):null,e("p",{className:"pdp-section__desc",children:Ue?r("assets.imagery.descShort","Photorealistic imagery of your configuration, ready for catalog, e-commerce and presentations."):r("assets.imagery.desc","A clean product shot for catalog and e-commerce, and two photorealistic room scenes showing your configuration in aspirational settings.")})]}),s("div",{className:"pdp-section__badge",children:[e("span",{className:"pdp-section__badge-num",children:B.filter(a=>a.status==="complete").length}),s("span",{className:"pdp-section__badge-of",children:["/",B.length]})]})]}),e("div",{className:`${O} pdp-grid--imagery`,children:B.map((a,t)=>e(pa,{asset:a,onRetry:N,onPreview:Fe,onDownload:ge,onRegenerate:$e,regenerateDisabled:ve,index:t},a.id))})]}),s("section",{className:"pdp-section",children:[e("div",{className:"pdp-section__header",children:s("div",{className:"pdp-section__header-text",children:[e("span",{className:"pdp-section-num",children:Qe}),r("assets.ar.title","AR")?e("h2",{className:"pdp-section__title",children:r("assets.ar.title","AR")}):null,e("p",{className:"pdp-section__desc",children:r("assets.ar.desc","View your configuration in augmented reality \u2014 share with clients to preview at scale in their space.")})]})}),e(ia,{asset:Be,onRetry:Ge,onCopy:Me})]}),s("div",{className:"pdp-footer",children:[ee&&s("button",{className:"pdp-btn pdp-btn--ghost",onClick:ne,children:[e(T,{className:"pdp-btn__icon"}),r("assets.regenerateAll","Regenerate All")]}),e("button",{className:"pdp-btn pdp-btn--primary",onClick:Q,children:r("assets.back","Back to Configurator")})]})]}),L&&s("div",{className:"pdp-lightbox",onClick:()=>x(null),children:[_.length>1&&e("button",{className:"pdp-lightbox__arrow pdp-lightbox__arrow--left",onClick:a=>{a.stopPropagation(),x(t=>(t-1+_.length)%_.length)},"aria-label":"Previous image",children:e(aa,{})}),s("div",{className:"pdp-lightbox__content",onClick:a=>a.stopPropagation(),children:[e("button",{className:"pdp-lightbox__close",onClick:()=>x(null),"aria-label":"Close preview",children:e(De,{})}),e("img",{src:L.url,alt:L.label,className:"pdp-lightbox__img"}),s("div",{className:"pdp-lightbox__bar",children:[e("span",{className:"pdp-lightbox__label",children:L.label}),e("div",{className:"pdp-lightbox__actions",children:s("button",{className:"pdp-btn pdp-btn--outline",onClick:()=>ge(L.url,L.label),children:[e(me,{className:"pdp-btn__icon"}),"Download"]})})]})]}),_.length>1&&e("button",{className:"pdp-lightbox__arrow pdp-lightbox__arrow--right",onClick:a=>{a.stopPropagation(),x(t=>(t+1)%_.length)},"aria-label":"Next image",children:e(sa,{})})]})]})}):null}function na({asset:r}){const u=re();if(!r)return e("div",{className:"pdp-preview pdp-preview--empty",children:e(_e,{className:"pdp-preview__icon"})});const{status:v,progress:l,label:m}=r;return s("div",{className:`pdp-preview pdp-preview--${v}`,children:[v==="idle"&&s("div",{className:"pdp-preview__inner",children:[e(_e,{className:"pdp-preview__icon"}),u("assets.queued","Queued")?e("span",{className:"pdp-preview__text",children:u("assets.queued","Queued")}):null]}),v==="generating"&&s("div",{className:"pdp-preview__inner pdp-preview__inner--active",children:[s("div",{className:"pdp-preview__loader",children:[s("svg",{viewBox:"0 0 50 50",className:"pdp-preview__circular",children:[e("circle",{cx:"25",cy:"25",r:"20",className:"pdp-preview__circular-bg"}),e("circle",{cx:"25",cy:"25",r:"20",className:"pdp-preview__circular-fill",strokeDasharray:`${l*1.26} 126`})]}),s("span",{className:"pdp-preview__loader-pct",children:[l,"%"]})]}),u("assets.generatingDoc","Generating document...")?e("span",{className:"pdp-preview__text",children:u("assets.generatingDoc","Generating document...")}):null]}),v==="complete"&&s("div",{className:"pdp-preview__doc",children:[s("div",{className:"pdp-preview__doc-page",children:[e("div",{className:"pdp-preview__doc-line pdp-preview__doc-line--title"}),e("div",{className:"pdp-preview__doc-line"}),e("div",{className:"pdp-preview__doc-line"}),e("div",{className:"pdp-preview__doc-line pdp-preview__doc-line--short"}),e("div",{className:"pdp-preview__doc-divider"}),e("div",{className:"pdp-preview__doc-line"}),e("div",{className:"pdp-preview__doc-line pdp-preview__doc-line--short"})]}),s("div",{className:"pdp-preview__doc-info",children:[e(_e,{className:"pdp-preview__doc-icon"}),e("span",{className:"pdp-preview__doc-label",children:m}),e("span",{className:"pdp-preview__doc-type",children:"PDF"})]})]}),v==="error"&&s("div",{className:"pdp-preview__inner pdp-preview__inner--error",children:[e(ue,{className:"pdp-preview__icon pdp-preview__icon--error"}),u("assets.failed","Generation failed")?e("span",{className:"pdp-preview__text pdp-preview__text--error",children:u("assets.failed","Generation failed")}):null]})]})}function pa({asset:r,onRetry:u,onPreview:v,onDownload:l,onRegenerate:m,regenerateDisabled:b=!1,index:A}){const n=re(),{id:N,status:d,progress:C,url:p,label:$}=r,[P,D]=oe(!1),[R,O]=oe(0),U=fe(null),k=c(S=>S.updateAsset);ce(()=>{p!==U.current&&(U.current=p,O(0),p||D(!1))},[p]);const V=d==="generating",I=d==="complete"&&!!p,w=y(()=>{D(!0)},[]),K=y(()=>{if(R<Ke){setTimeout(()=>O(S=>S+1),600*(R+1));return}k(N,{status:"error",progress:0,error:n("assets.imageNotDisplayed","Image could not be displayed."),loadFailed:!0})},[N,R,k,n]),W=y(()=>{O(0),D(!1),k(N,{status:"complete",progress:100,error:null,loadFailed:!1})},[N,k]),Z=d==="error"&&!!r.loadFailed&&!!p;return s("div",{className:`pdp-card pdp-card--${I?"complete":d}`,style:{animationDelay:`${A*80}ms`},children:[s("div",{className:"pdp-card__visual",children:[d==="idle"&&e("div",{className:"pdp-card__placeholder",children:e(Le,{className:"pdp-card__ph-icon"})}),V&&!P&&s("div",{className:"pdp-card__placeholder pdp-card__placeholder--active",children:[e("div",{className:"pdp-card__ring",children:s("svg",{viewBox:"0 0 44 44",children:[e("circle",{cx:"22",cy:"22",r:"18",className:"pdp-card__ring-bg"}),e("circle",{cx:"22",cy:"22",r:"18",className:"pdp-card__ring-fill",strokeDasharray:`${C*1.13} 113`})]})}),n("assets.processing","Processing")?e("span",{className:"pdp-card__status-badge",children:n("assets.processing","Processing")}):null]}),I&&s(H,{children:[e("img",{src:p,alt:"",className:"pdp-card__img",onLoad:w,onError:K},`${p}|${R}`),s("div",{className:"pdp-card__overlay",children:[e("button",{className:"pdp-card__action",title:"Preview",onClick:()=>v(p,$),children:e(qe,{})}),e("button",{className:"pdp-card__action",title:"Download",onClick:()=>l(p,$),children:e(me,{})}),e("button",{className:"pdp-card__action",title:"Regenerate",onClick:()=>m(N),disabled:b,children:e(T,{})})]})]}),d==="blocked"&&s("div",{className:"pdp-card__placeholder pdp-card__placeholder--blocked",role:"img",title:n("assets.unavailableTooltip","This image isn't available for this design"),"aria-label":n("assets.unavailableTooltip","This image isn't available for this design"),children:[e(Le,{className:"pdp-card__ph-icon pdp-card__ph-icon--blocked","aria-hidden":"true"}),e("span",{className:"pdp-card__status-badge pdp-card__status-badge--blocked",children:n("assets.unavailableBadge","Unavailable")})]}),d==="error"&&s("div",{className:"pdp-card__placeholder pdp-card__placeholder--error",children:[e(ue,{className:"pdp-card__ph-icon pdp-card__ph-icon--error"}),n("assets.failedBadge","Failed")?e("span",{className:"pdp-card__status-badge pdp-card__status-badge--error",children:n("assets.failedBadge","Failed")}):null]}),V&&!P&&e("div",{className:"pdp-card__progress",children:e("div",{className:"pdp-card__progress-fill",style:{width:`${C}%`}})})]}),s("div",{className:"pdp-card__footer",children:[e("span",{className:"pdp-card__label",children:$}),s("span",{className:"pdp-card__state",children:[d==="generating"&&`Processing ${Math.round(C)}%`,d==="idle"&&"Queued",d==="error"&&(r.error||"Failed")]}),d==="error"&&s("button",{className:"pdp-card__retry",onClick:()=>Z?W():u(r.id),children:[e(T,{className:"pdp-card__retry-icon"})," ",Z?n("assets.reload","Reload"):n("assets.retry","Retry")]})]})]})}function ia({asset:r,onRetry:u,onCopy:v}){const l=re(),[m,b]=oe(!1),A=F(p=>p.isMobile);if(!r)return null;const{status:n,progress:N,error:d}=r,C=p=>{v(p),b(!0),setTimeout(()=>b(!1),3e3)};return s("div",{className:`pdp-ar pdp-ar--${n}`,children:[!(A&&n==="complete")&&e("div",{className:"pdp-ar__qr-area",children:n==="complete"&&r.url?s("div",{className:"pdp-ar__qr",children:[e(ta,{value:r.url,size:120,level:"M",bgColor:"transparent",fgColor:"#1a1a1a"}),l("assets.ar.scan","Scan to view in AR")?e("span",{className:"pdp-ar__qr-label",children:l("assets.ar.scan","Scan to view in AR")}):null]}):n==="generating"?s("div",{className:"pdp-ar__qr-placeholder",children:[e("div",{className:"pdp-ar__qr-skeleton",children:e("div",{className:"pdp-ar__qr-dots"})}),l("assets.ar.generatingModel","Generating model...")?e("span",{className:"pdp-ar__qr-label",children:l("assets.ar.generatingModel","Generating model...")}):null]}):n==="error"?e("div",{className:"pdp-ar__qr-placeholder pdp-ar__qr-placeholder--error",children:e(ue,{className:"pdp-ar__qr-icon"})}):s("div",{className:"pdp-ar__qr-placeholder",children:[e(ea,{className:"pdp-ar__qr-icon"}),l("assets.queued","Queued")?e("span",{className:"pdp-ar__qr-label",children:l("assets.queued","Queued")}):null]})}),s("div",{className:"pdp-ar__body",children:[s("div",{className:"pdp-ar__info",children:[e("span",{className:"pdp-ar__label",children:r.label}),n==="idle"&&(l("assets.ar.queued","Queued for generation")?e("span",{className:"pdp-ar__sub",children:l("assets.ar.queued","Queued for generation")}):null),n==="generating"&&s("span",{className:"pdp-ar__sub",children:["Exporting 3D model... ",N,"%"]}),n==="complete"&&(l("assets.ar.ready","Ready to view in AR")?e("span",{className:"pdp-ar__sub pdp-ar__sub--done",children:l("assets.ar.ready","Ready to view in AR")}):null),n==="error"&&e("span",{className:"pdp-ar__sub pdp-ar__sub--error",children:d}),n==="complete"&&!A&&e("p",{className:"pdp-ar__hint",children:"Scan the QR code with a mobile device to launch the AR experience, or use the button below."}),n==="complete"&&A&&e("p",{className:"pdp-ar__hint",children:l("assets.ar.tapHint","Tap the button below to view your configuration in augmented reality.")})]}),s("div",{className:"pdp-ar__actions",children:[n==="complete"&&s(H,{children:[A&&s("a",{className:"pdp-btn pdp-btn--primary",href:r.url,target:"_blank",rel:"noopener noreferrer",children:[e(Ze,{className:"pdp-btn__icon"}),"Launch AR"]}),s("button",{className:`pdp-btn pdp-btn--ghost ${m?"pdp-btn--copied":""}`,onClick:()=>C(r.url),title:"Copy link",children:[m?e(Xe,{className:"pdp-btn__icon"}):e(Je,{className:"pdp-btn__icon"}),m?"Copied":"Copy"]})]}),n==="error"&&s("button",{className:"pdp-btn pdp-btn--outline",onClick:()=>u(r.id),children:[e(T,{className:"pdp-btn__icon"})," Retry"]})]})]}),n==="generating"&&e("div",{className:"pdp-ar__bar",children:e("div",{className:"pdp-ar__bar-fill",style:{width:`${N}%`}})})]})}var Pa=oa;export{Pa as default};
@@ -0,0 +1 @@
1
+ const s=Object.freeze({PIECE_FINISH:"piece_finish",SURFACE_FINISH:"surface_finish",HARDWARE_FINISH:"hardware_finish",DOOR_STYLE:"door_style",HANDLE_TYPE:"handle_type",FRAME_SIZE:"frame_size"}),_=Object.freeze({LAYOUT:"layout_change",FREE_PIECE:"load_new_product",HOSTED_PRODUCTS:"appliance_selection",FINISH:"finish_change",PRODUCT:"product_change"});function c(n){return n?n.role??n.metadata?.role??null:null}function p(n,r){if(!(!Array.isArray(n)||!r))return n.find(t=>c(t)===r)}function a(n,r){if(!(!Array.isArray(n)||!r))return n.find(t=>t?.type===r)}function y(n,r){return!Array.isArray(n)||!r?[]:n.filter(t=>t?.type===r)}function u(n,r){if(!n||!r)return;const t=[r.id,r.feature_id].filter(i=>i!=null);for(const i of t){if(n[i]!=null)return n[i];if(n[String(i)]!=null)return n[String(i)]}}function E(n,r,t){return u(n,p(r,t))}function A(n,r,t){return u(n,a(r,t))}function T(n,r,{on:t,tier:i=null}){if(!n||!r)return null;const o=(Array.isArray(n.options)?n.options:[]).map(e=>typeof e=="object"&&e!==null?e.id??e.optionId??e.option_id:e).map(e=>r[e]??r[String(e)]).filter(Boolean);if(!t)return o.find(e=>e.value===null)?.id??null;const l=o.filter(e=>e.value!==null);if(i!=null){const e=l.find(d=>d.tier===i);if(e)return e.id}return l[0]?.id??null}function S(n,r){const t={};if(!Array.isArray(r))return t;for(const i of r){const f=c(i);if(!f)continue;const o=u(n,i);o!=null&&(t[f]=o)}return t}function R(n,r){const t={};if(!n||typeof n!="object")return t;for(const[i,f]of Object.entries(n)){const o=p(r,i);o&&f!=null&&(t[o.id]=f)}return t}export{s as FEATURE_ROLES,_ as FEATURE_TYPES,c as featureRole,p as findFeatureByRole,a as findFeatureByType,y as findFeaturesByType,E as getSelectionByRole,A as getSelectionByType,u as getSelectionFor,T as pickToggleOption,R as roleSelectionsToFeatureIds,S as selectionsByRole};
@@ -0,0 +1 @@
1
+ import{jsPDF as lt}from"jspdf";import rt from"qrcode";import{getQuoteDocument as st}from"./12b8165d6d.js";const nt="#D4A853",K="#FBF5E8";let R=nt,it=K;const _="#1a1a1a",G="#555555",N="#999999",Z="#e5e5e5";function ot(t){const a=/^#?([0-9a-f]{6})$/i.exec(String(t||"").trim());if(!a)return K;const r=parseInt(a[1],16),m=g=>Math.round(g+(255-g)*.92),c=m(r>>16&255),h=m(r>>8&255),L=m(r&255);return`#${((1<<24)+(c<<16)+(h<<8)+L).toString(16).slice(1)}`}function ut(t){const a=t?.accent,r=typeof a=="string"&&/^#[0-9a-f]{6}$/i.test(a.trim());R=r?a.trim():nt,it=r?ot(R):K}async function ft(t){if(!t||typeof t!="string")return null;try{if(t.startsWith("data:image/"))return t;const a=await fetch(t,{mode:"cors"});if(!a.ok)return null;const r=await a.blob();return String(r.type).startsWith("image/")?await new Promise(m=>{const c=new FileReader;c.onload=()=>m(c.result),c.onerror=()=>m(null),c.readAsDataURL(r)}):null}catch{return null}}function D(t,a="USD"){if(t==null||!Number.isFinite(t))return"\u2014";try{return new Intl.NumberFormat("en-US",{style:"currency",currency:a}).format(t)}catch{return`$${t.toFixed(2)}`}}function M(t){const a=typeof t=="number"?t:t!=null?Number(t):null;return Number.isFinite(a)?a:null}const H="\xB7 ",d=t=>String(t??"").trim().toLowerCase();function yt(t,a="",r=null){const m=new Map;for(const h of t)h.value!=null&&(m.has(h.value)||m.set(h.value,[]),m.get(h.value).push(h.slotKey));const c=[];for(const[h,L]of m){const g=r?r(h):"";L.length>1?c.push(`${H}${h}${a} \xD7${L.length}${g}`):c.push(`${H}${h}${a}${g}`)}return c}const I=210,z=297,e=18,U=I-e*2,B=(t,a)=>t.setFillColor(a),o=(t,a)=>t.setTextColor(a),j=(t,a)=>t.setDrawColor(a),f=(t,a,r)=>{t.setFont("helvetica",a),t.setFontSize(r)};function X(t,a,r,m,c,h){B(t,"#ffffff"),t.rect(0,0,I,22,"F"),f(t,"bold",11),o(t,_),t.text(a,e,13),f(t,"normal",8),o(t,N),t.text(`Page ${r} of ${m}`,I-e,13,{align:"right"}),t.text(`${c} \xB7 ${h}`,I-e,18,{align:"right"}),j(t,R),t.setLineWidth(.5),t.line(e,22,I-e,22),t.setLineWidth(.2)}function v(t,a,r){f(t,"normal",7),o(t,N),t.text(`Generated ${r} \xB7 ${a}`,e,z-8)}function mt(t,{title:a,summary:r,lifestyleImages:m,refNum:c,date:h,currency:L,spec:g,logo:y}){if(B(t,R),t.rect(0,0,I,4,"F"),y)try{const T=t.getImageProperties(y),n=Math.min(14,T.height/T.width*40),x=T.width/T.height*n;t.addImage(y,T.fileType||"PNG",I-e-x,20,x,n,void 0,"FAST")}catch{}f(t,"bold",8),o(t,R),t.text("BILL OF MATERIALS",e,32,{charSpace:.8}),f(t,"bold",26),o(t,_);const s=t.splitTextToSize(String(a||""),U);t.text(s,e,44);const S=44+(s.length-1)*11;j(t,R),t.setLineWidth(.6),t.line(e,S+6,e+28,S+6),t.setLineWidth(.2),f(t,"normal",8),o(t,N),t.text(`${h} \xB7 Ref ${c}`,e,S+14);let u=S+14;const b=[g?.company?`From ${g.company}`:null,g?.customer?`For ${g.customer}`:null].filter(Boolean);b.length&&(u+=6,f(t,"normal",9),o(t,G),t.text(b.join(" \xB7 "),e,u));const i=m?.perspective||m?.front||m?.side;let p=u+8;if(i){const T=U,n=110;try{const x=t.getImageProperties(i),$=x?.width>0&&x?.height>0?x.width/x.height:null;let C=T,E=n;$&&(E=T/$,E>n&&(E=n,C=n*$));const k=e+(T-C)/2,Y=x?.fileType||(i.startsWith("data:image/png")?"PNG":"JPEG");t.addImage(i,Y,k,p,C,E,void 0,"FAST"),p+=E+8}catch{}}const F=[{label:"Line Items",value:String(r?.lineItems??r?.totalUnique??0)},{label:"Units",value:String(r?.totalItems??0)},{label:"Total",value:D(r?.grandTotal,L)}],A=(U-8)/3,w=22;F.forEach((T,n)=>{const x=e+n*(A+4);B(t,"#fafafa"),j(t,Z),t.roundedRect(x,p,A,w,2,2,"FD"),f(t,"normal",8),o(t,N),t.text(T.label,x+4,p+8),f(t,"bold",16),o(t,_),t.text(T.value,x+4,p+18)}),p+=w+10;const W=[g?.notes?{label:"Notes",body:g.notes}:null,g?.terms?{label:"Terms",body:g.terms}:null].filter(Boolean);for(const T of W){if(p>z-30)break;f(t,"bold",8),o(t,R),t.text(T.label.toUpperCase(),e,p,{charSpace:.6}),p+=5,f(t,"normal",8),o(t,G);const n=t.splitTextToSize(String(T.body),U);for(const x of n){if(p>z-16)break;t.text(x,e,p),p+=4}p+=4}v(t,c,h)}function gt(t,{groups:a,refNum:r,date:m,title:c,totalPages:h,startPage:L,currency:g,spec:y}){let s=L;const S=[];let u=0;for(const b of a){t.addPage(),X(t,c,s,h,r,m);let i=30;f(t,"bold",16),o(t,_),t.text(b.name,e,i),i+=3,j(t,R),t.setLineWidth(.8),t.line(e,i,e+40,i),t.setLineWidth(.2),i+=6,f(t,"normal",8),o(t,N);{const n=b.items.filter($=>!$._isAggregate),x=b.items.length-n.length;t.text(`${n.length} unique \xB7 ${n.reduce(($,C)=>$+(C.qty||1),0)} total`+(x?` \xB7 ${x} option${x===1?"":"s"}`:""),e,i)}i+=8;const p={num:e,name:e+9,qty:e+112,unit:e+130,total:e+158},F=96;B(t,"#f5f5f5"),t.rect(e-2,i-4,U+4,8,"F"),f(t,"bold",8),o(t,G),t.text("#",p.num,i+1),t.text("ITEM",p.name,i+1),t.text("QTY",p.qty,i+1),t.text("UNIT PRICE",p.unit,i+1),t.text("TOTAL",p.total,i+1),i+=8;let A=0,w=0,W=0;for(const n of b.items){const x=i,$=[];n._isFinish?$.push(n.valueLabel||"\u2014"):($.push(n._isHostPiece?`\xBB ${n.name||"\u2014"}`:n.name||"\u2014"),n.productGraphName&&n.productGraphName!==n.name&&n.productGraphName!==b.name&&$.push(`Family: ${n.productGraphName}`),n._isHostPiece&&n._includedWith&&$.push(`${M(n.unitPrice)!=null?"For":"Included with"}: ${n._includedWith}`));const C=l=>l==null||l===0?`: ${D(0,g)}`:`: ${l>0?"+":"\u2212"}${D(Math.abs(l),g)}`,E=new Map;if(Array.isArray(n.adjustments))for(const l of n.adjustments)E.set(d(l.label||l.name||l.source||"Option"),M(l.amount));const k=new Set,Y=l=>{const P=d(l);return E.has(P)?(k.add(P),C(E.get(P))):""};if(y?.showSceneSelections!==!1&&Array.isArray(n.namedSelections))for(const l of n.namedSelections)$.push(`${H}${l.setName}: ${l.optionName}${Y(l.optionName)}`);if(!n._isFinish){const l=M(n.basePrice),P=M(n.unitPrice);l!=null&&l!==0&&P!=null&&Math.abs(P-l)>.005&&$.push(`${H}Base price: ${D(l,g)}`)}if(Array.isArray(n.adjustments)&&n.adjustments.length>0)for(const l of n.adjustments){const P=M(l.amount);if(!P)continue;const O=l.label||l.name||l.source||"Option";if(k.has(d(O)))continue;const et=l.optionSetLabel??l.option_set_label??l.optionSetName??l.setName??null;$.push(`${H}${et?`${et}: `:""}${O}${C(P)}`)}const Q=[];for(let l=0;l<$.length;l++){f(t,"normal",l===0?9:8);const P=t.splitTextToSize(String($[l]),F);for(let O=0;O<P.length;O++)Q.push({text:P[O],first:l===0})}const V=Math.max(8,Q.length*4+3);i+V>z-15&&(v(t,r,m),t.addPage(),s+=1,X(t,c,s,h,r,m),i=30,f(t,"italic",9),o(t,N),t.text(`${b.name} (continued)`,e,i),i+=8),b.items.indexOf(n)%2===0&&(B(t,"#fbfbfb"),t.rect(e-2,i-3,U+4,V,"F")),A+=1,f(t,"normal",8),o(t,N),t.text(String(A),p.num,i+2),f(t,"bold",10),o(t,_),t.text(`\xD7${n.qty??1}`,p.qty,i+2);for(let l=0;l<Q.length;l++){const P=Q[l];f(t,"normal",P.first?9:8),o(t,P.first?_:G),t.text(P.text,p.name,i+2+l*4)}o(t,G);const at=n.qty??1,q=M(n.unitPrice)??M(n.basePrice),J=M(n.lineTotal)??(q!=null?q*at:null);J!=null&&(w+=J,W+=1),f(t,"normal",8),o(t,G);const tt=n._isHostPiece&&q==null;t.text(tt?"Included":D(q,g),p.unit,i+2),f(t,q!=null?"bold":"normal",8),o(t,_),t.text(tt?"Included":D(J,g),p.total,i+2),i+=V,j(t,Z),t.setLineWidth(.1),t.line(e,i-1,I-e,i-1),b.items[b.items.length-1]}i+=2,B(t,it),t.rect(e-2,i-3,U+4,9,"F"),f(t,"bold",9),o(t,_);const T=a.length===1;t.text(T?"GRAND TOTAL":`${b.name} subtotal`,e,i+3),o(t,_),t.text(b._informationalPricing?"Included in item prices":W>0?D(w,g):"Pending",I-e,i+3,{align:"right"}),S.push({name:b.name,subtotal:w,pricedItems:W,informational:!!b._informationalPricing,itemCount:b._kind==="aggregate"?b.items.length:b.items.reduce((n,x)=>n+(x.qty||1),0)}),W>0&&!b._informationalPricing&&(u+=w),v(t,r,m),s+=1}return{nextPage:s,perGroupTotals:S,grandTotal:u}}function ht(t,{perGroupTotals:a,grandTotal:r,title:m,refNum:c,date:h,pageIndex:L,totalPages:g,currency:y}){t.addPage(),X(t,m,L,g,c,h),f(t,"bold",16),o(t,_),t.text("Pricing Summary",e,36),j(t,R),t.setLineWidth(.8),t.line(e,39,e+50,39),t.setLineWidth(.2);let s=52;B(t,"#f5f5f5"),t.rect(e-2,s-4,U+4,8,"F"),f(t,"bold",8),o(t,G),t.text("GROUP",e,s+1),t.text("ITEMS",e+100,s+1),t.text("SUBTOTAL",I-e,s+1,{align:"right"}),s+=10;for(const u of a)f(t,"normal",10),o(t,_),t.text(u.name,e,s),o(t,G),t.text(String(u.itemCount),e+100,s),f(t,u.pricedItems>0&&!u.informational?"bold":"normal",10),o(t,u.pricedItems>0&&!u.informational?_:N),t.text(u.informational?"Included":u.pricedItems>0?D(u.subtotal,y):"Pending",I-e,s,{align:"right"}),s+=7,j(t,Z),t.setLineWidth(.1),t.line(e,s-2,I-e,s-2);s+=4,B(t,R),t.rect(e-2,s-3,U+4,12,"F"),f(t,"bold",12),o(t,"#ffffff"),t.text("GRAND TOTAL",e,s+5),t.text(r>0?D(r,y):"Pricing pending",I-e,s+5,{align:"right"}),a.some(u=>u.pricedItems>0)||(s+=16,f(t,"italic",8),o(t,N),t.text("Backend has not populated basePrice on the variants for this system yet.",e,s),t.text("Prices will appear here automatically once the catalog is priced.",e,s+5)),v(t,c,h)}async function pt(t,{shareUrl:a,arUrl:r,refNum:m,date:c,title:h,pageIndex:L,totalPages:g,arLabel:y}){t.addPage(),X(t,h,L,g,m,c);const s=[a?{url:a,label:"Reopen & Edit This Design"}:null,r?{url:r,label:y||"AR View"}:null].filter(Boolean);f(t,"bold",16),o(t,_),t.text(s.length===2?"Reopen & AR View":a?"Reopen & Edit":"AR View",e,36);let S=46;const u=s.length===2?U/2-4:U,b=async(i,p,F)=>{if(i)try{const A=await rt.toDataURL(i,{margin:1,width:400}),w=60;t.addImage(A,"PNG",F+(u-w)/2,S,w,w),f(t,"bold",10),o(t,_),t.text(p,F+u/2,S+w+6,{align:"center"})}catch{}};for(let i=0;i<s.length;i+=1)await b(s[i].url,s[i].label,e+i*(u+8));v(t,m,c)}async function Tt(t){const{title:a="Configuration Summary",groups:r=[],summary:m={},lifestyleImages:c={},shareUrl:h=null,arUrl:L=null,currency:g="USD"}=t||{},y=st();ut(y);const s=await ft(y?.logoUrl),S=y?.title??a,u=new lt({orientation:"portrait",unit:"mm",format:"a4"}),b=new Date().toLocaleDateString("en-US",y?.dateFormat??{year:"numeric",month:"long",day:"numeric"}),i=new Date().getFullYear(),p=(()=>{try{const C=String(h||"").match(/([0-9a-f]{8})[0-9a-f-]*\/?$/i);return C?C[1].toUpperCase():null}catch{return null}})(),F=y?.reference??`BOM-${i}-${p||Date.now().toString(36).toUpperCase().slice(-5)}`,A=y?.arQr===!1?null:L,w=typeof u.putTotalPages=="function"?"{total_pages}":"\u2014";mt(u,{title:S,summary:m,lifestyleImages:c,refNum:F,date:b,currency:g,spec:y,logo:s});const{nextPage:W,perGroupTotals:T,grandTotal:n}=gt(u,{groups:r,refNum:F,date:b,title:S,totalPages:w,startPage:2,currency:g,spec:y});let x=W;T.length>1&&(ht(u,{perGroupTotals:T,grandTotal:n,title:S,refNum:F,date:b,pageIndex:W,totalPages:w,currency:g}),x=W+1),(h||A)&&await pt(u,{shareUrl:h,arUrl:A,refNum:F,date:b,title:S,pageIndex:x,totalPages:w,arLabel:y?.arQrLabel}),typeof u.putTotalPages=="function"&&u.putTotalPages("{total_pages}");const $=u.output("blob");return URL.createObjectURL($)}export{Tt as generateGenericBomPdf};
@@ -0,0 +1 @@
1
+ import{shouldBlockRequest as y,requestBlockedError as S}from"./631a9f7fac.js";import{authHeaders as v,isAuthFailure as w,reportAuthFailure as b,reportForbidden as k,getChannelId as p}from"./431a2d8618.js";import{ensureSessionToken as m,hasTokenProvider as E}from"./33fa2c8ca2.js";import{applyRequestInterceptors as O,applyResponseInterceptors as P,performRequest as T}from"./a3f18e76fe.js";import{getApiBaseUrl as C}from"./8ade32d067.js";import{assertLicensed as A}from"./fe235d7160.js";function g(e={}){const o=p();return o!=null?{...e,channelId:o}:e}async function d(e,o,{signal:i}={},a=!1){if(await A(e),y(e))throw S(e);await m();const r=O({path:e,url:`${C()}${e}`,method:"POST",headers:{"Content-Type":"application/json",...v(e)},body:o,init:void 0}),f=Date.now(),n=await T(r,c=>fetch(c.url,{method:"POST",headers:c.headers,body:JSON.stringify(c.body),signal:i}));if(w(n)){if(!a&&E())return await m({force:!0}),d(e,o,{signal:i},!0);await b(n,{url:e,method:"POST"})}n.status===403&&await k(n,{url:e,method:"POST"});let t=null;try{t=await n.json()}catch{t=null}const u=P({status:n.status,ok:n.ok,data:t||{},duration:Date.now()-f},r);return{status:u.status,ok:u.ok,data:u.data||{}}}async function j({systemId:e,presetId:o}={}){const{status:i,ok:a,data:r}=await d("/api/v1/configurations/initial/",g({systemId:e,...o!=null?{presetId:o}:{}}));if(!a)throw new Error(`initial configuration failed: ${i}`);return r}async function q({systemId:e,catalogVersion:o,state:i,mutation:a,idempotencyKey:r},{signal:f}={}){const{status:n,data:t}=await d("/api/v1/configurations/evaluate/",g({systemId:e,catalogVersion:o,state:i,mutation:a,...r?{idempotencyKey:r}:{}}),{signal:f}),u=new Set(["CONSTRAINT_NOT_IMPLEMENTED","STALE_SELECTION"]),c=s=>s&&typeof s=="object"?s.code??s.type:s,h=(t.warnings??[]).filter(s=>!u.has(String(c(s)??"").toUpperCase())),l=t.errorResponse&&typeof t.errorResponse=="object"?t.errorResponse:t;return{status:n,applied:n===200,rejected:n===422,staleCatalog:n===409||t.refetchCatalog===!0,blockingMutation:(l.blockingMutation??t.blockingMutation)===!0,code:l.code??t.code??null,system:t.system??null,pricing:t.pricing??null,resolvedState:t.resolvedState??null,optionVisibility:t.optionVisibility??null,optionSetVisibility:t.optionSetVisibility??null,optionAvailability:t.optionAvailability??null,defaultOptionOverrides:t.defaultOptionOverrides??null,fired:t.fired??[],removedPlacements:t.removedPlacements??null,addedPlacements:t.addedPlacements??null,messages:t.messages??l.messages??[],events:t.events??[],customEffects:t.customEffects??t.custom_effects??[],customDiagnostics:t.customDiagnostics??t.custom_diagnostics??l.customDiagnostics??[],errors:l.errors??t.errors??[],warnings:h,catalogVersion:t.catalogVersion??o??null,refetchCatalog:t.refetchCatalog===!0||n===409,previousState:l.previousState??t.previousState??null,schemaVersion:t.schemaVersion??null}}async function M(e){if(!Array.isArray(e)||e.length===0)return null;const o=p(),i={...o!=null?{channel:o}:{},items:e};try{const{ok:a,data:r}=await d("/api/v1/pricing/calculate/",i);return a?r:null}catch{return null}}export{M as calculatePricing,q as evaluateConfiguration,j as fetchInitialConfiguration};
@@ -0,0 +1 @@
1
+ import{checkConfiguratorLicence as r,getConfiguratorBlockedMessage as s}from"./3bbcee0334.js";const o="/api/v1/configurator/status/";class n extends Error{constructor(e){super(e||"This configurator is not licensed to run on this website."),this.name="ConfiguratorUnlicensedError",this.code="EMBED_NOT_LICENSED",this.status=403}}function i(t){const e=/[?&]systemId=([^&#]+)/.exec(t)||/\/systems\/([^/?#]+)\//.exec(t);return e?decodeURIComponent(e[1]):null}async function u(t=""){if(typeof t=="string"&&t.includes(o))return;let e=!0;try{e=await r({systemId:i(t)})}catch{e=!0}if(!e)throw new n(s())}export{n as ConfiguratorUnlicensedError,u as assertLicensed};
@@ -0,0 +1 @@
1
+ import{setAiChatRuntimeRefused as a}from"./87f511c4a8.js";import{ensureSessionToken as c}from"./33fa2c8ca2.js";import{copilotAuthHeaders as l}from"./431a2d8618.js";import{getApiBaseUrl as s}from"./8ade32d067.js";import{BAKED_COPILOT_API_URL as r}from"./a811c90bd5.js";function f(){try{return import.meta&&import.meta.env&&import.meta.env.VITE_COPILOT_API_URL||""}catch{return""}}let i=(typeof r=="string"&&r?r:"")||f();function d(t){typeof t=="string"&&(i=t)}function g(){return i}function n(){const t=(i||"").replace(/\/+$/,"");if(t)return t;const o=(s()||"").replace(/\/+$/,"");return o?`${o}/frontend`:""}function u(){const t=n();return t?`${t}/copilotkit`:"/copilotkit"}function U(){const t=n();return t?`${t}/warmup`:"/warmup"}async function _(t=8e3){if(typeof fetch!="function")return!1;try{await c()}catch{}const o=new AbortController,p=setTimeout(()=>o.abort(),t);try{const e=await fetch(u(),{method:"POST",signal:o.signal,headers:{"Content-Type":"application/json",...l()},body:JSON.stringify({method:"info"})});return e.status===401||e.status===403?(a(),!1):!!e}catch{return!1}finally{clearTimeout(p)}}export{_ as checkCopilotAvailability,g as getCopilotApiUrl,u as getCopilotRuntimeUrl,U as getCopilotWarmupUrl,d as setCopilotApiUrl};
@@ -0,0 +1 @@
1
+ import{jsx as s,jsxs as N}from"react/jsx-runtime";import"./b14379d31b.css";function r({children:a,variant:l="primary",size:b="medium",disabled:p=!1,loading:t=!1,fullWidth:_=!1,icon:n=null,iconPosition:e="left",onClick:f,type:u="button",className:m="",...o}){const c=["btn",`btn--${l}`,`btn--${b}`,_&&"btn--full-width",t&&"btn--loading",n&&!a&&"btn--icon-only",m].filter(Boolean).join(" ");return N("button",{type:u,className:c,disabled:p||t,onClick:f,...o,children:[t&&s("span",{className:"btn__spinner"}),n&&e==="left"&&!t&&s("span",{className:"btn__icon btn__icon--left",children:n}),a&&s("span",{className:"btn__text",children:a}),n&&e==="right"&&!t&&s("span",{className:"btn__icon btn__icon--right",children:n})]})}var y=r;export{y as default};
@@ -0,0 +1 @@
1
+ import{default as t}from"./872c4302e0.js";import{default as a,deriveSceneFeatures as s}from"./be337ddda5.js";import{default as f}from"./9c6c598569.js";import{default as n,registerSelectionReconciler as c}from"./d94df858ea.js";import{default as d}from"./8f60e5059a.js";import{default as i,captureSceneState as m,restoreSceneState as x}from"./1fac915f8b.js";export{m as captureSceneState,s as deriveSceneFeatures,c as registerSelectionReconciler,x as restoreSceneState,a as useConfigurationGraphStore,t as useObjectGraphStore,n as useSceneConfigStore,f as useSceneGraphStore,d as useUIStore,i as useUndoRedoStore};