motiondesk-studio 0.0.0-stage → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (506) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +53 -2
  3. package/THIRD_PARTY_NOTICES.md +13 -0
  4. package/app/assets/ai-assistant-DOEK1wrr.js +138 -0
  5. package/app/assets/annual-report-C59pnbh2.js +147 -0
  6. package/app/assets/app-tour-B8525Qt1.js +164 -0
  7. package/app/assets/apps-DwnIwigQ.js +1 -0
  8. package/app/assets/arrows-_CCvumhN.js +1 -0
  9. package/app/assets/auto-CJsCPj1R.js +1 -0
  10. package/app/assets/badges-BPgMBVy0.js +1 -0
  11. package/app/assets/balloon-party-BDWzrF-Z.js +160 -0
  12. package/app/assets/beauty-DgeCsQdf.js +1 -0
  13. package/app/assets/boarding-pass-i17EemsZ.js +192 -0
  14. package/app/assets/business-BQslCr0i.js +1 -0
  15. package/app/assets/business-DfyVziqj.js +1 -0
  16. package/app/assets/catalog-Cdx5nbp0.js +1 -0
  17. package/app/assets/celebration-COCZTKjl.js +1 -0
  18. package/app/assets/celebrations-CkfTGLEK.js +1 -0
  19. package/app/assets/chalk-menu-CQSqwxNP.js +158 -0
  20. package/app/assets/claim-steps-BNFeoYYZ.js +180 -0
  21. package/app/assets/clinic-booking-CvQEpBWn.js +178 -0
  22. package/app/assets/community-BV13F-Wp.js +1 -0
  23. package/app/assets/concert-poster-iUOM-elw.js +189 -0
  24. package/app/assets/course-syllabus-CnM_03XP.js +164 -0
  25. package/app/assets/culture-DpL14_5r.js +1 -0
  26. package/app/assets/cyber-shield-B_6oatye.js +192 -0
  27. package/app/assets/data-DgES5FIF.js +1 -0
  28. package/app/assets/dev-hiring-code-Bg00S1Iz.js +138 -0
  29. package/app/assets/devices-D1500q8F.js +1 -0
  30. package/app/assets/donation-meter-C3wuRmFA.js +164 -0
  31. package/app/assets/editorial-mag-DsTVzQMx.js +180 -0
  32. package/app/assets/education-CGTOg3_0.js +1 -0
  33. package/app/assets/ev-charge-KaMIQd_s.js +218 -0
  34. package/app/assets/event-announce-cLmuvt45.js +147 -0
  35. package/app/assets/events-kZ6HshfK.js +1 -0
  36. package/app/assets/family-De56hVSo.js +1 -0
  37. package/app/assets/fashion-DbGAD96W.js +1 -0
  38. package/app/assets/finance-BUdlKAud.js +1 -0
  39. package/app/assets/finance-growth-CYgFE0RC.js +140 -0
  40. package/app/assets/fitness-rings-streak-Cp7n4zq_.js +141 -0
  41. package/app/assets/flash-sale-Tc0Jw34H.js +143 -0
  42. package/app/assets/flipclock-countdown-BkrU9ZhF.js +153 -0
  43. package/app/assets/floorplan-linedraw-B4ZwEDv3.js +192 -0
  44. package/app/assets/food-CiEyQAd1.js +1 -0
  45. package/app/assets/food-PijmcKM-.js +1 -0
  46. package/app/assets/gaming-DnzPj6Uv.js +1 -0
  47. package/app/assets/glass-product-CsUqplIf.js +139 -0
  48. package/app/assets/glossy-cosmetics-DBb-YonD.js +203 -0
  49. package/app/assets/gold-couture-e6c5nsVY.js +190 -0
  50. package/app/assets/gradient-blobs-Daiu9eFf.js +139 -0
  51. package/app/assets/graduation-day-vdz-kGI1.js +134 -0
  52. package/app/assets/headline-news-ticker-GgZ_nRXK.js +181 -0
  53. package/app/assets/health-CbyTqvSM.js +1 -0
  54. package/app/assets/health-DMeKWmDa.js +1 -0
  55. package/app/assets/hiring-team-Bia3GQaH.js +137 -0
  56. package/app/assets/holiday-greeting-B7TFl0_5.js +144 -0
  57. package/app/assets/holidays-BmXfhKdf.js +1 -0
  58. package/app/assets/hr-2i-f-S-M.js +1 -0
  59. package/app/assets/hyperframes-BM7eWgx2.js +1 -0
  60. package/app/assets/index-BlSoi5FK.css +1 -0
  61. package/app/assets/index-D3rEDfqX.js +290 -0
  62. package/app/assets/index-b2-CMdBrCiU.js +1 -0
  63. package/app/assets/index-b3-egAjkT9z.js +1 -0
  64. package/app/assets/index-b4-Cnj_xde0.js +1 -0
  65. package/app/assets/index-b5-CoZgwX8-.js +1 -0
  66. package/app/assets/iso-product-3d-DQT1lHDq.js +229 -0
  67. package/app/assets/itinerary-map-pins-BTX0ZebL.js +201 -0
  68. package/app/assets/key-handover-DuIj4oKe.js +171 -0
  69. package/app/assets/kids-BNwXKe4O.js +1 -0
  70. package/app/assets/kinetic-launch-D2rSnewM.js +161 -0
  71. package/app/assets/launch-DqkMfeFI.js +1 -0
  72. package/app/assets/legal-Caoeh9dp.js +1 -0
  73. package/app/assets/legal-trust-T01BmIDB.js +186 -0
  74. package/app/assets/level-up-CBXf6nj2.js +205 -0
  75. package/app/assets/logo-sting-Uf0nckUQ.js +106 -0
  76. package/app/assets/manifesto-quote-DCIONyzh.js +120 -0
  77. package/app/assets/match-day-p25bzqbq.js +146 -0
  78. package/app/assets/match-score-CSZ4Tx4B.js +210 -0
  79. package/app/assets/music-hbnVS8dK.js +1 -0
  80. package/app/assets/nature-Bj99iNsv.js +1 -0
  81. package/app/assets/neighborhood-map-BpbZiy-v.js +158 -0
  82. package/app/assets/neon-grid-Bo0xfsL6.js +159 -0
  83. package/app/assets/nonprofit-DK7XI33A.js +1 -0
  84. package/app/assets/objects-DD8bqyWR.js +1 -0
  85. package/app/assets/org-chart-hiring-tGX1UpiJ.js +161 -0
  86. package/app/assets/paper-collage-CK-XODvZ.js +181 -0
  87. package/app/assets/paw-adopt-D5hKgsaL.js +173 -0
  88. package/app/assets/people-l3GsDfAr.js +1 -0
  89. package/app/assets/pets-Dp8EeTjS.js +1 -0
  90. package/app/assets/playful-blocks-BGXW4vra.js +162 -0
  91. package/app/assets/podcast-waveform-promo-D-h_ydpJ.js +182 -0
  92. package/app/assets/premium-Cy680sWT.js +1 -0
  93. package/app/assets/price-grid-DbYGPlJt.js +176 -0
  94. package/app/assets/quote-carousel-bold-D5fpKgSS.js +143 -0
  95. package/app/assets/realestate-BXW-rsfP.js +1 -0
  96. package/app/assets/recipe-ingredients-B_bSw3x_.js +162 -0
  97. package/app/assets/retail-D-XWCWed.js +1 -0
  98. package/app/assets/retro-80s-CCZc9S6x.js +141 -0
  99. package/app/assets/roadmap-timeline-BpbNdfCr.js +164 -0
  100. package/app/assets/saas-dashboard-s-2gR3AN.js +195 -0
  101. package/app/assets/sale-wheel-24h-CsiOja2Z.js +153 -0
  102. package/app/assets/save-the-date-C6O8fH8f.js +141 -0
  103. package/app/assets/seasons-BFYc_klb.js +1 -0
  104. package/app/assets/services-DRPQcCXX.js +1 -0
  105. package/app/assets/shapes-AVMwC-FR.js +1 -0
  106. package/app/assets/social-CNpE0GKG.js +1 -0
  107. package/app/assets/split-wipe-before-after-Lg-NbF0V.js +198 -0
  108. package/app/assets/sports-DyBfpPm5.js +1 -0
  109. package/app/assets/stats-dashboard-CxxFtNfj.js +149 -0
  110. package/app/assets/stickers-J4NDCW2L.js +1 -0
  111. package/app/assets/stock-portfolio-DFpeHEjJ.js +174 -0
  112. package/app/assets/swiss-grid-jfcgySaJ.js +153 -0
  113. package/app/assets/tech-BaRjeFZ0.js +1 -0
  114. package/app/assets/tech-D-xc9pRv.js +1 -0
  115. package/app/assets/transport-Bolufhfq.js +1 -0
  116. package/app/assets/travel-DoqS5vPB.js +1 -0
  117. package/app/assets/travel-route-DUPXi7Qa.js +169 -0
  118. package/app/assets/tutorial-steps-Ep2JeqXu.js +160 -0
  119. package/app/assets/wallet-card-transactions-DtI9Usn9.js +188 -0
  120. package/app/assets/wedding-invite-BhgqMwO7.js +142 -0
  121. package/app/catalog/bank-previews/01-car-choice.webp +0 -0
  122. package/app/catalog/bank-previews/02-holiday-budget.webp +0 -0
  123. package/app/catalog/bank-previews/03-one-click.webp +0 -0
  124. package/app/catalog/bank-previews/04-career-course.webp +0 -0
  125. package/app/catalog/bank-previews/05-home-refresh.webp +0 -0
  126. package/app/catalog/bank-previews/06-summer-plans.webp +0 -0
  127. package/app/catalog/bank-previews/07-car-upgrade.webp +0 -0
  128. package/app/catalog/bank-previews/08-wedding-plan.webp +0 -0
  129. package/app/catalog/bank-previews/09-share-intro.webp +0 -0
  130. package/app/catalog/bank-previews/10-suspicious-message.webp +0 -0
  131. package/app/catalog/bank-previews/11-student-routine.webp +0 -0
  132. package/app/catalog/bank-previews/12-investing-first-step.webp +0 -0
  133. package/app/catalog/bank-previews/13-fomo.webp +0 -0
  134. package/app/catalog/bank-previews/14-market-timing.webp +0 -0
  135. package/app/catalog/bank-previews/15-investing-for-all.webp +0 -0
  136. package/app/catalog/bank-previews/16-two-paths.webp +0 -0
  137. package/app/catalog/bank-previews/17-small-business.webp +0 -0
  138. package/app/catalog/bank-previews/18-travel-forex.webp +0 -0
  139. package/app/catalog/bank-previews/19-mortgage-questions.webp +0 -0
  140. package/app/catalog/bank-previews/20-market-app.webp +0 -0
  141. package/app/catalog/enhanced-v2/01-revenue-quarter/config.motiondesk-config.json +54 -0
  142. package/app/catalog/enhanced-v2/01-revenue-quarter/poster.jpg +0 -0
  143. package/app/catalog/enhanced-v2/01-revenue-quarter/preview.mp4 +0 -0
  144. package/app/catalog/enhanced-v2/01-revenue-quarter/project.motiondesk.json +5127 -0
  145. package/app/catalog/enhanced-v2/02-daily-workout/config.motiondesk-config.json +54 -0
  146. package/app/catalog/enhanced-v2/02-daily-workout/poster.jpg +0 -0
  147. package/app/catalog/enhanced-v2/02-daily-workout/preview.mp4 +0 -0
  148. package/app/catalog/enhanced-v2/02-daily-workout/project.motiondesk.json +5747 -0
  149. package/app/catalog/enhanced-v2/03-italy-trip/config.motiondesk-config.json +44 -0
  150. package/app/catalog/enhanced-v2/03-italy-trip/poster.jpg +0 -0
  151. package/app/catalog/enhanced-v2/03-italy-trip/preview.mp4 +0 -0
  152. package/app/catalog/enhanced-v2/03-italy-trip/project.motiondesk.json +5139 -0
  153. package/app/catalog/enhanced-v2/04-smart-savings/config.motiondesk-config.json +41 -0
  154. package/app/catalog/enhanced-v2/04-smart-savings/poster.jpg +0 -0
  155. package/app/catalog/enhanced-v2/04-smart-savings/preview.mp4 +0 -0
  156. package/app/catalog/enhanced-v2/04-smart-savings/project.motiondesk.json +5322 -0
  157. package/app/catalog/enhanced-v2/05-weekly-challenge/config.motiondesk-config.json +45 -0
  158. package/app/catalog/enhanced-v2/05-weekly-challenge/poster.jpg +0 -0
  159. package/app/catalog/enhanced-v2/05-weekly-challenge/preview.mp4 +0 -0
  160. package/app/catalog/enhanced-v2/05-weekly-challenge/project.motiondesk.json +5442 -0
  161. package/app/catalog/enhanced-v2/06-flash-sale/config.motiondesk-config.json +42 -0
  162. package/app/catalog/enhanced-v2/06-flash-sale/poster.jpg +0 -0
  163. package/app/catalog/enhanced-v2/06-flash-sale/preview.mp4 +0 -0
  164. package/app/catalog/enhanced-v2/06-flash-sale/project.motiondesk.json +5616 -0
  165. package/app/catalog/enhanced-v2/07-flight-savings/config.motiondesk-config.json +43 -0
  166. package/app/catalog/enhanced-v2/07-flight-savings/poster.jpg +0 -0
  167. package/app/catalog/enhanced-v2/07-flight-savings/preview.mp4 +0 -0
  168. package/app/catalog/enhanced-v2/07-flight-savings/project.motiondesk.json +6319 -0
  169. package/app/catalog/enhanced-v2/08-team-dashboard/config.motiondesk-config.json +52 -0
  170. package/app/catalog/enhanced-v2/08-team-dashboard/poster.jpg +0 -0
  171. package/app/catalog/enhanced-v2/08-team-dashboard/preview.mp4 +0 -0
  172. package/app/catalog/enhanced-v2/08-team-dashboard/project.motiondesk.json +5327 -0
  173. package/app/catalog/showcase-v3/11-flow-finance/poster.jpg +0 -0
  174. package/app/catalog/showcase-v3/11-flow-finance/preview.mp4 +0 -0
  175. package/app/catalog/showcase-v3/11-flow-finance/project.motiondesk.json +5690 -0
  176. package/app/catalog/showcase-v3/12-pulse-training/poster.jpg +0 -0
  177. package/app/catalog/showcase-v3/12-pulse-training/preview.mp4 +0 -0
  178. package/app/catalog/showcase-v3/12-pulse-training/project.motiondesk.json +3643 -0
  179. package/app/catalog/showcase-v3/13-orbit-travel/poster.jpg +0 -0
  180. package/app/catalog/showcase-v3/13-orbit-travel/preview.mp4 +0 -0
  181. package/app/catalog/showcase-v3/13-orbit-travel/project.motiondesk.json +3939 -0
  182. package/app/catalog/showcase-v3/14-nova-product/config.motiondesk-config.json +163 -0
  183. package/app/catalog/showcase-v3/14-nova-product/poster.jpg +0 -0
  184. package/app/catalog/showcase-v3/14-nova-product/preview.mp4 +0 -0
  185. package/app/catalog/showcase-v3/14-nova-product/project.motiondesk.json +11196 -0
  186. package/app/catalog/showcase-v3/15-tempo-motion/config.motiondesk-config.json +122 -0
  187. package/app/catalog/showcase-v3/15-tempo-motion/poster.jpg +0 -0
  188. package/app/catalog/showcase-v3/15-tempo-motion/preview.mp4 +0 -0
  189. package/app/catalog/showcase-v3/15-tempo-motion/project.motiondesk.json +7424 -0
  190. package/app/catalog/showcase-v3/16-atlas-journey/config.motiondesk-config.json +132 -0
  191. package/app/catalog/showcase-v3/16-atlas-journey/poster.jpg +0 -0
  192. package/app/catalog/showcase-v3/16-atlas-journey/preview.mp4 +0 -0
  193. package/app/catalog/showcase-v3/16-atlas-journey/project.motiondesk.json +9257 -0
  194. package/app/catalog/showcase-v3/17-revenue-quarter/config.motiondesk-config.json +151 -0
  195. package/app/catalog/showcase-v3/17-revenue-quarter/poster.jpg +0 -0
  196. package/app/catalog/showcase-v3/17-revenue-quarter/preview.mp4 +0 -0
  197. package/app/catalog/showcase-v3/17-revenue-quarter/project.motiondesk.json +10473 -0
  198. package/app/catalog/showcase-v3/18-daily-workout/config.motiondesk-config.json +139 -0
  199. package/app/catalog/showcase-v3/18-daily-workout/poster.jpg +0 -0
  200. package/app/catalog/showcase-v3/18-daily-workout/preview.mp4 +0 -0
  201. package/app/catalog/showcase-v3/18-daily-workout/project.motiondesk.json +8656 -0
  202. package/app/catalog/showcase-v3/19-italy-trip/config.motiondesk-config.json +132 -0
  203. package/app/catalog/showcase-v3/19-italy-trip/poster.jpg +0 -0
  204. package/app/catalog/showcase-v3/19-italy-trip/preview.mp4 +0 -0
  205. package/app/catalog/showcase-v3/19-italy-trip/project.motiondesk.json +9690 -0
  206. package/app/catalog/showcase-v3/20-smart-savings/config.motiondesk-config.json +152 -0
  207. package/app/catalog/showcase-v3/20-smart-savings/poster.jpg +0 -0
  208. package/app/catalog/showcase-v3/20-smart-savings/preview.mp4 +0 -0
  209. package/app/catalog/showcase-v3/20-smart-savings/project.motiondesk.json +9770 -0
  210. package/app/catalog/showcase-v3/21-weekly-challenge/config.motiondesk-config.json +125 -0
  211. package/app/catalog/showcase-v3/21-weekly-challenge/poster.jpg +0 -0
  212. package/app/catalog/showcase-v3/21-weekly-challenge/preview.mp4 +0 -0
  213. package/app/catalog/showcase-v3/21-weekly-challenge/project.motiondesk.json +8404 -0
  214. package/app/catalog/showcase-v3/22-flash-sale/config.motiondesk-config.json +116 -0
  215. package/app/catalog/showcase-v3/22-flash-sale/poster.jpg +0 -0
  216. package/app/catalog/showcase-v3/22-flash-sale/preview.mp4 +0 -0
  217. package/app/catalog/showcase-v3/22-flash-sale/project.motiondesk.json +7482 -0
  218. package/app/catalog/showcase-v3/23-flight-savings/config.motiondesk-config.json +139 -0
  219. package/app/catalog/showcase-v3/23-flight-savings/poster.jpg +0 -0
  220. package/app/catalog/showcase-v3/23-flight-savings/preview.mp4 +0 -0
  221. package/app/catalog/showcase-v3/23-flight-savings/project.motiondesk.json +9205 -0
  222. package/app/catalog/showcase-v3/24-team-dashboard/config.motiondesk-config.json +155 -0
  223. package/app/catalog/showcase-v3/24-team-dashboard/poster.jpg +0 -0
  224. package/app/catalog/showcase-v3/24-team-dashboard/preview.mp4 +0 -0
  225. package/app/catalog/showcase-v3/24-team-dashboard/project.motiondesk.json +10735 -0
  226. package/app/catalog/v4/bank-01-car-choice/config.motiondesk-config.json +86 -0
  227. package/app/catalog/v4/bank-01-car-choice/poster.webp +0 -0
  228. package/app/catalog/v4/bank-01-car-choice/project.motiondesk.json +6962 -0
  229. package/app/catalog/v4/bank-02-holiday-budget/config.motiondesk-config.json +98 -0
  230. package/app/catalog/v4/bank-02-holiday-budget/poster.webp +0 -0
  231. package/app/catalog/v4/bank-02-holiday-budget/project.motiondesk.json +7242 -0
  232. package/app/catalog/v4/bank-03-one-click/config.motiondesk-config.json +97 -0
  233. package/app/catalog/v4/bank-03-one-click/poster.webp +0 -0
  234. package/app/catalog/v4/bank-03-one-click/project.motiondesk.json +6789 -0
  235. package/app/catalog/v4/bank-04-career-course/config.motiondesk-config.json +88 -0
  236. package/app/catalog/v4/bank-04-career-course/poster.webp +0 -0
  237. package/app/catalog/v4/bank-04-career-course/project.motiondesk.json +6514 -0
  238. package/app/catalog/v4/bank-05-five-years-new-word/config.motiondesk-config.json +86 -0
  239. package/app/catalog/v4/bank-05-five-years-new-word/poster.webp +0 -0
  240. package/app/catalog/v4/bank-05-five-years-new-word/project.motiondesk.json +5865 -0
  241. package/app/catalog/v4/bank-06-home-upgrade/config.motiondesk-config.json +88 -0
  242. package/app/catalog/v4/bank-06-home-upgrade/poster.webp +0 -0
  243. package/app/catalog/v4/bank-06-home-upgrade/project.motiondesk.json +7187 -0
  244. package/app/catalog/v4/bank-07-car-upgrade/config.motiondesk-config.json +87 -0
  245. package/app/catalog/v4/bank-07-car-upgrade/poster.webp +0 -0
  246. package/app/catalog/v4/bank-07-car-upgrade/project.motiondesk.json +6018 -0
  247. package/app/catalog/v4/bank-08-summer-dollar/config.motiondesk-config.json +85 -0
  248. package/app/catalog/v4/bank-08-summer-dollar/poster.webp +0 -0
  249. package/app/catalog/v4/bank-08-summer-dollar/project.motiondesk.json +6291 -0
  250. package/app/catalog/v4/bank-09-wedding/config.motiondesk-config.json +88 -0
  251. package/app/catalog/v4/bank-09-wedding/poster.webp +0 -0
  252. package/app/catalog/v4/bank-09-wedding/project.motiondesk.json +6517 -0
  253. package/app/catalog/v4/bank-10-family-dinner-pay/config.motiondesk-config.json +100 -0
  254. package/app/catalog/v4/bank-10-family-dinner-pay/poster.webp +0 -0
  255. package/app/catalog/v4/bank-10-family-dinner-pay/project.motiondesk.json +7053 -0
  256. package/app/catalog/v4/bank-11-youth-pitch-creator/config.motiondesk-config.json +100 -0
  257. package/app/catalog/v4/bank-11-youth-pitch-creator/poster.webp +0 -0
  258. package/app/catalog/v4/bank-11-youth-pitch-creator/project.motiondesk.json +6820 -0
  259. package/app/catalog/v4/bank-12-gift-shares/config.motiondesk-config.json +90 -0
  260. package/app/catalog/v4/bank-12-gift-shares/poster.webp +0 -0
  261. package/app/catalog/v4/bank-12-gift-shares/project.motiondesk.json +6025 -0
  262. package/app/catalog/v4/bank-13-suspicious-call/config.motiondesk-config.json +96 -0
  263. package/app/catalog/v4/bank-13-suspicious-call/poster.webp +0 -0
  264. package/app/catalog/v4/bank-13-suspicious-call/project.motiondesk.json +6734 -0
  265. package/app/catalog/v4/bank-14-urgent-message/config.motiondesk-config.json +89 -0
  266. package/app/catalog/v4/bank-14-urgent-message/poster.webp +0 -0
  267. package/app/catalog/v4/bank-14-urgent-message/project.motiondesk.json +6724 -0
  268. package/app/catalog/v4/bank-15-olympic-excellence/config.motiondesk-config.json +88 -0
  269. package/app/catalog/v4/bank-15-olympic-excellence/poster.webp +0 -0
  270. package/app/catalog/v4/bank-15-olympic-excellence/project.motiondesk.json +6431 -0
  271. package/app/catalog/v4/bank-16-savings-pocket/config.motiondesk-config.json +97 -0
  272. package/app/catalog/v4/bank-16-savings-pocket/poster.webp +0 -0
  273. package/app/catalog/v4/bank-16-savings-pocket/project.motiondesk.json +6628 -0
  274. package/app/catalog/v4/bank-17-students/config.motiondesk-config.json +91 -0
  275. package/app/catalog/v4/bank-17-students/poster.webp +0 -0
  276. package/app/catalog/v4/bank-17-students/project.motiondesk.json +6629 -0
  277. package/app/catalog/v4/bank-18-phone-phobia/config.motiondesk-config.json +86 -0
  278. package/app/catalog/v4/bank-18-phone-phobia/poster.webp +0 -0
  279. package/app/catalog/v4/bank-18-phone-phobia/project.motiondesk.json +6140 -0
  280. package/app/catalog/v4/bank-19-financial-fomo/config.motiondesk-config.json +91 -0
  281. package/app/catalog/v4/bank-19-financial-fomo/poster.webp +0 -0
  282. package/app/catalog/v4/bank-19-financial-fomo/project.motiondesk.json +7189 -0
  283. package/app/catalog/v4/bank-20-start-investing/config.motiondesk-config.json +95 -0
  284. package/app/catalog/v4/bank-20-start-investing/poster.webp +0 -0
  285. package/app/catalog/v4/bank-20-start-investing/project.motiondesk.json +7149 -0
  286. package/app/catalog/v4/bank-21-market-timing/config.motiondesk-config.json +95 -0
  287. package/app/catalog/v4/bank-21-market-timing/poster.webp +0 -0
  288. package/app/catalog/v4/bank-21-market-timing/project.motiondesk.json +6166 -0
  289. package/app/catalog/v4/bank-22-market-vs-realestate/config.motiondesk-config.json +88 -0
  290. package/app/catalog/v4/bank-22-market-vs-realestate/poster.webp +0 -0
  291. package/app/catalog/v4/bank-22-market-vs-realestate/project.motiondesk.json +7698 -0
  292. package/app/catalog/v4/bank-23-investing-for-all/config.motiondesk-config.json +92 -0
  293. package/app/catalog/v4/bank-23-investing-for-all/poster.webp +0 -0
  294. package/app/catalog/v4/bank-23-investing-for-all/project.motiondesk.json +6150 -0
  295. package/app/catalog/v4/bank-24-business-loan/config.motiondesk-config.json +85 -0
  296. package/app/catalog/v4/bank-24-business-loan/poster.webp +0 -0
  297. package/app/catalog/v4/bank-24-business-loan/project.motiondesk.json +6804 -0
  298. package/app/catalog/v4/bank-25-open-door/config.motiondesk-config.json +84 -0
  299. package/app/catalog/v4/bank-25-open-door/poster.webp +0 -0
  300. package/app/catalog/v4/bank-25-open-door/project.motiondesk.json +5976 -0
  301. package/app/catalog/v4/bank-26-first-card-challenge/config.motiondesk-config.json +84 -0
  302. package/app/catalog/v4/bank-26-first-card-challenge/poster.webp +0 -0
  303. package/app/catalog/v4/bank-26-first-card-challenge/project.motiondesk.json +6167 -0
  304. package/app/catalog/v4/bank-27-holiday-trip/config.motiondesk-config.json +85 -0
  305. package/app/catalog/v4/bank-27-holiday-trip/poster.webp +0 -0
  306. package/app/catalog/v4/bank-27-holiday-trip/project.motiondesk.json +6291 -0
  307. package/app/catalog/v4/bank-28-renew-home/config.motiondesk-config.json +87 -0
  308. package/app/catalog/v4/bank-28-renew-home/poster.webp +0 -0
  309. package/app/catalog/v4/bank-28-renew-home/project.motiondesk.json +6489 -0
  310. package/app/catalog/v4/bank-29-fastest-way-to-pay/config.motiondesk-config.json +98 -0
  311. package/app/catalog/v4/bank-29-fastest-way-to-pay/poster.webp +0 -0
  312. package/app/catalog/v4/bank-29-fastest-way-to-pay/project.motiondesk.json +6915 -0
  313. package/app/catalog/v4/bank-30-forex-terminal/config.motiondesk-config.json +103 -0
  314. package/app/catalog/v4/bank-30-forex-terminal/poster.webp +0 -0
  315. package/app/catalog/v4/bank-30-forex-terminal/project.motiondesk.json +6997 -0
  316. package/app/catalog/v4/bank-31-youth-campaign-brief/config.motiondesk-config.json +103 -0
  317. package/app/catalog/v4/bank-31-youth-campaign-brief/poster.webp +0 -0
  318. package/app/catalog/v4/bank-31-youth-campaign-brief/project.motiondesk.json +7136 -0
  319. package/app/catalog/v4/bank-32-dream-vacation/config.motiondesk-config.json +87 -0
  320. package/app/catalog/v4/bank-32-dream-vacation/poster.webp +0 -0
  321. package/app/catalog/v4/bank-32-dream-vacation/project.motiondesk.json +6531 -0
  322. package/app/catalog/v4/bank-33-mortgage-advice/config.motiondesk-config.json +87 -0
  323. package/app/catalog/v4/bank-33-mortgage-advice/poster.webp +0 -0
  324. package/app/catalog/v4/bank-33-mortgage-advice/project.motiondesk.json +6767 -0
  325. package/app/catalog/v4/bank-34-who-are-you-saver/config.motiondesk-config.json +97 -0
  326. package/app/catalog/v4/bank-34-who-are-you-saver/poster.webp +0 -0
  327. package/app/catalog/v4/bank-34-who-are-you-saver/project.motiondesk.json +6309 -0
  328. package/app/catalog/v4/bank-35-strange-calls/config.motiondesk-config.json +85 -0
  329. package/app/catalog/v4/bank-35-strange-calls/poster.webp +0 -0
  330. package/app/catalog/v4/bank-35-strange-calls/project.motiondesk.json +7034 -0
  331. package/app/catalog/v4/bank-36-one-shekel-flight/config.motiondesk-config.json +91 -0
  332. package/app/catalog/v4/bank-36-one-shekel-flight/poster.webp +0 -0
  333. package/app/catalog/v4/bank-36-one-shekel-flight/project.motiondesk.json +6364 -0
  334. package/app/catalog/v4/bank-37-street-quiz-pay/config.motiondesk-config.json +81 -0
  335. package/app/catalog/v4/bank-37-street-quiz-pay/poster.webp +0 -0
  336. package/app/catalog/v4/bank-37-street-quiz-pay/project.motiondesk.json +6466 -0
  337. package/app/catalog/v4/bank-38-pension-compare/config.motiondesk-config.json +92 -0
  338. package/app/catalog/v4/bank-38-pension-compare/poster.webp +0 -0
  339. package/app/catalog/v4/bank-38-pension-compare/project.motiondesk.json +6752 -0
  340. package/app/catalog/v4/bank-39-new-look-app/config.motiondesk-config.json +103 -0
  341. package/app/catalog/v4/bank-39-new-look-app/poster.webp +0 -0
  342. package/app/catalog/v4/bank-39-new-look-app/project.motiondesk.json +6954 -0
  343. package/app/catalog/v4/bank-40-interest-pocket/config.motiondesk-config.json +83 -0
  344. package/app/catalog/v4/bank-40-interest-pocket/poster.webp +0 -0
  345. package/app/catalog/v4/bank-40-interest-pocket/project.motiondesk.json +5783 -0
  346. package/app/catalog/v4/bank-41-young-telenovela/config.motiondesk-config.json +95 -0
  347. package/app/catalog/v4/bank-41-young-telenovela/poster.webp +0 -0
  348. package/app/catalog/v4/bank-41-young-telenovela/project.motiondesk.json +5967 -0
  349. package/app/catalog/v4/bank-42-market-app/config.motiondesk-config.json +103 -0
  350. package/app/catalog/v4/bank-42-market-app/poster.webp +0 -0
  351. package/app/catalog/v4/bank-42-market-app/project.motiondesk.json +6766 -0
  352. package/app/catalog/v4/bank-43-passover-sites/config.motiondesk-config.json +92 -0
  353. package/app/catalog/v4/bank-43-passover-sites/poster.webp +0 -0
  354. package/app/catalog/v4/bank-43-passover-sites/project.motiondesk.json +7173 -0
  355. package/app/catalog/v4/bank-44-end-of-excuses/config.motiondesk-config.json +93 -0
  356. package/app/catalog/v4/bank-44-end-of-excuses/poster.webp +0 -0
  357. package/app/catalog/v4/bank-44-end-of-excuses/project.motiondesk.json +6010 -0
  358. package/app/catalog/v4/bank-45-good-reasons/config.motiondesk-config.json +90 -0
  359. package/app/catalog/v4/bank-45-good-reasons/poster.webp +0 -0
  360. package/app/catalog/v4/bank-45-good-reasons/project.motiondesk.json +7122 -0
  361. package/app/catalog/v4/bank-46-mortgage-hotline/config.motiondesk-config.json +99 -0
  362. package/app/catalog/v4/bank-46-mortgage-hotline/poster.webp +0 -0
  363. package/app/catalog/v4/bank-46-mortgage-hotline/project.motiondesk.json +6923 -0
  364. package/app/catalog/v4/bank-47-financial-growth-center/config.motiondesk-config.json +84 -0
  365. package/app/catalog/v4/bank-47-financial-growth-center/poster.webp +0 -0
  366. package/app/catalog/v4/bank-47-financial-growth-center/project.motiondesk.json +6424 -0
  367. package/app/catalog/v4/bank-48-judo-grand-prix/config.motiondesk-config.json +88 -0
  368. package/app/catalog/v4/bank-48-judo-grand-prix/poster.webp +0 -0
  369. package/app/catalog/v4/bank-48-judo-grand-prix/project.motiondesk.json +6335 -0
  370. package/app/catalog/v4/bank-49-currency-convert/config.motiondesk-config.json +98 -0
  371. package/app/catalog/v4/bank-49-currency-convert/poster.webp +0 -0
  372. package/app/catalog/v4/bank-49-currency-convert/project.motiondesk.json +7036 -0
  373. package/app/catalog/v4/bank-50-salary-young/config.motiondesk-config.json +95 -0
  374. package/app/catalog/v4/bank-50-salary-young/poster.webp +0 -0
  375. package/app/catalog/v4/bank-50-salary-young/project.motiondesk.json +6414 -0
  376. package/app/catalog/v4/v4-onboarding-beats-16x9/config.motiondesk-config.json +162 -0
  377. package/app/catalog/v4/v4-onboarding-beats-16x9/poster.webp +0 -0
  378. package/app/catalog/v4/v4-onboarding-beats-16x9/project.motiondesk.json +9796 -0
  379. package/app/catalog/v4/v4-savings-goal-9x16/config.motiondesk-config.json +151 -0
  380. package/app/catalog/v4/v4-savings-goal-9x16/poster.webp +0 -0
  381. package/app/catalog/v4/v4-savings-goal-9x16/project.motiondesk.json +11847 -0
  382. package/app/catalog/v4/v4-trip-planner-1x1/config.motiondesk-config.json +137 -0
  383. package/app/catalog/v4/v4-trip-planner-1x1/poster.webp +0 -0
  384. package/app/catalog/v4/v4-trip-planner-1x1/project.motiondesk.json +10797 -0
  385. package/app/catalog/v4/v4-wallet-launch-16x9/config.motiondesk-config.json +172 -0
  386. package/app/catalog/v4/v4-wallet-launch-16x9/poster.webp +0 -0
  387. package/app/catalog/v4/v4-wallet-launch-16x9/project.motiondesk.json +14270 -0
  388. package/app/fonts/heebo-hebrew-400-normal.woff2 +0 -0
  389. package/app/fonts/heebo-hebrew-700-normal.woff2 +0 -0
  390. package/app/fonts/heebo-latin-400-normal.woff2 +0 -0
  391. package/app/fonts/heebo-latin-700-normal.woff2 +0 -0
  392. package/app/fonts/motiondesk-symbols.ttf +0 -0
  393. package/app/fonts/noto-sans-math-OFL.txt +93 -0
  394. package/app/index.html +15 -0
  395. package/app/studio-hf/fonts/heebo-hebrew-400-normal.woff2 +0 -0
  396. package/app/studio-hf/fonts/heebo-hebrew-700-normal.woff2 +0 -0
  397. package/app/studio-hf/fonts/heebo-latin-400-normal.woff2 +0 -0
  398. package/app/studio-hf/fonts/heebo-latin-700-normal.woff2 +0 -0
  399. package/app/studio-hf/frame.html +21 -0
  400. package/app/studio-hf/vendor/gsap.min.js +11 -0
  401. package/bin/motiondesk-studio.mjs +244 -0
  402. package/lib/catalog/hyperframes/ai-assistant.html +137 -0
  403. package/lib/catalog/hyperframes/annual-report.html +146 -0
  404. package/lib/catalog/hyperframes/app-tour.html +163 -0
  405. package/lib/catalog/hyperframes/balloon-party.html +159 -0
  406. package/lib/catalog/hyperframes/boarding-pass.html +191 -0
  407. package/lib/catalog/hyperframes/chalk-menu.html +157 -0
  408. package/lib/catalog/hyperframes/claim-steps.html +179 -0
  409. package/lib/catalog/hyperframes/clinic-booking.html +177 -0
  410. package/lib/catalog/hyperframes/concert-poster.html +188 -0
  411. package/lib/catalog/hyperframes/course-syllabus.html +163 -0
  412. package/lib/catalog/hyperframes/cyber-shield.html +191 -0
  413. package/lib/catalog/hyperframes/dev-hiring-code.html +137 -0
  414. package/lib/catalog/hyperframes/donation-meter.html +163 -0
  415. package/lib/catalog/hyperframes/editorial-mag.html +179 -0
  416. package/lib/catalog/hyperframes/ev-charge.html +217 -0
  417. package/lib/catalog/hyperframes/event-announce.html +146 -0
  418. package/lib/catalog/hyperframes/finance-growth.html +139 -0
  419. package/lib/catalog/hyperframes/fitness-rings-streak.html +140 -0
  420. package/lib/catalog/hyperframes/flash-sale.html +142 -0
  421. package/lib/catalog/hyperframes/flipclock-countdown.html +152 -0
  422. package/lib/catalog/hyperframes/floorplan-linedraw.html +191 -0
  423. package/lib/catalog/hyperframes/glass-product.html +138 -0
  424. package/lib/catalog/hyperframes/glossy-cosmetics.html +202 -0
  425. package/lib/catalog/hyperframes/gold-couture.html +189 -0
  426. package/lib/catalog/hyperframes/gradient-blobs.html +138 -0
  427. package/lib/catalog/hyperframes/graduation-day.html +133 -0
  428. package/lib/catalog/hyperframes/headline-news-ticker.html +180 -0
  429. package/lib/catalog/hyperframes/hiring-team.html +136 -0
  430. package/lib/catalog/hyperframes/holiday-greeting.html +143 -0
  431. package/lib/catalog/hyperframes/index-b2.json +194 -0
  432. package/lib/catalog/hyperframes/index-b3.json +194 -0
  433. package/lib/catalog/hyperframes/index-b4.json +162 -0
  434. package/lib/catalog/hyperframes/index-b5.json +130 -0
  435. package/lib/catalog/hyperframes/index.json +322 -0
  436. package/lib/catalog/hyperframes/iso-product-3d.html +228 -0
  437. package/lib/catalog/hyperframes/itinerary-map-pins.html +200 -0
  438. package/lib/catalog/hyperframes/key-handover.html +170 -0
  439. package/lib/catalog/hyperframes/kinetic-launch.html +160 -0
  440. package/lib/catalog/hyperframes/legal-trust.html +185 -0
  441. package/lib/catalog/hyperframes/level-up.html +204 -0
  442. package/lib/catalog/hyperframes/logo-sting.html +105 -0
  443. package/lib/catalog/hyperframes/manifesto-quote.html +119 -0
  444. package/lib/catalog/hyperframes/match-day.html +145 -0
  445. package/lib/catalog/hyperframes/match-score.html +209 -0
  446. package/lib/catalog/hyperframes/neighborhood-map.html +157 -0
  447. package/lib/catalog/hyperframes/neon-grid.html +158 -0
  448. package/lib/catalog/hyperframes/org-chart-hiring.html +160 -0
  449. package/lib/catalog/hyperframes/paper-collage.html +180 -0
  450. package/lib/catalog/hyperframes/paw-adopt.html +172 -0
  451. package/lib/catalog/hyperframes/playful-blocks.html +161 -0
  452. package/lib/catalog/hyperframes/podcast-waveform-promo.html +181 -0
  453. package/lib/catalog/hyperframes/price-grid.html +175 -0
  454. package/lib/catalog/hyperframes/quote-carousel-bold.html +142 -0
  455. package/lib/catalog/hyperframes/recipe-ingredients.html +161 -0
  456. package/lib/catalog/hyperframes/retro-80s.html +140 -0
  457. package/lib/catalog/hyperframes/roadmap-timeline.html +163 -0
  458. package/lib/catalog/hyperframes/saas-dashboard.html +194 -0
  459. package/lib/catalog/hyperframes/sale-wheel-24h.html +152 -0
  460. package/lib/catalog/hyperframes/save-the-date.html +140 -0
  461. package/lib/catalog/hyperframes/split-wipe-before-after.html +197 -0
  462. package/lib/catalog/hyperframes/stats-dashboard.html +148 -0
  463. package/lib/catalog/hyperframes/stock-portfolio.html +173 -0
  464. package/lib/catalog/hyperframes/swiss-grid.html +152 -0
  465. package/lib/catalog/hyperframes/travel-route.html +168 -0
  466. package/lib/catalog/hyperframes/tutorial-steps.html +159 -0
  467. package/lib/catalog/hyperframes/wallet-card-transactions.html +187 -0
  468. package/lib/catalog/hyperframes/wedding-invite.html +141 -0
  469. package/lib/catalog/studio/apps.json +2134 -0
  470. package/lib/catalog/studio/auto.json +2019 -0
  471. package/lib/catalog/studio/beauty.json +1630 -0
  472. package/lib/catalog/studio/business.json +2064 -0
  473. package/lib/catalog/studio/celebrations.json +2142 -0
  474. package/lib/catalog/studio/community.json +1926 -0
  475. package/lib/catalog/studio/culture.json +2156 -0
  476. package/lib/catalog/studio/data.json +1934 -0
  477. package/lib/catalog/studio/education.json +1914 -0
  478. package/lib/catalog/studio/events.json +1921 -0
  479. package/lib/catalog/studio/family.json +2159 -0
  480. package/lib/catalog/studio/fashion.json +1958 -0
  481. package/lib/catalog/studio/finance.json +1922 -0
  482. package/lib/catalog/studio/food.json +2128 -0
  483. package/lib/catalog/studio/gaming.json +1756 -0
  484. package/lib/catalog/studio/health.json +1934 -0
  485. package/lib/catalog/studio/hr.json +1860 -0
  486. package/lib/catalog/studio/kids.json +1697 -0
  487. package/lib/catalog/studio/launch.json +2161 -0
  488. package/lib/catalog/studio/legal.json +1732 -0
  489. package/lib/catalog/studio/music.json +1721 -0
  490. package/lib/catalog/studio/nonprofit.json +1665 -0
  491. package/lib/catalog/studio/pets.json +2196 -0
  492. package/lib/catalog/studio/premium.json +5577 -0
  493. package/lib/catalog/studio/realestate.json +2018 -0
  494. package/lib/catalog/studio/retail.json +1959 -0
  495. package/lib/catalog/studio/services.json +2154 -0
  496. package/lib/catalog/studio/social.json +2004 -0
  497. package/lib/catalog/studio/sports.json +1999 -0
  498. package/lib/catalog/studio/tech.json +2124 -0
  499. package/lib/catalog/studio/travel.json +1966 -0
  500. package/lib/core-v4.cjs +4897 -0
  501. package/lib/core.cjs +4223 -0
  502. package/lib/motion-blur.cjs +36 -0
  503. package/lib/studio.cjs +4419 -0
  504. package/lib/vercel-render.mjs +494 -0
  505. package/lib/vercel-source.cjs +88 -0
  506. package/package.json +16 -4
package/lib/core.cjs ADDED
@@ -0,0 +1,4223 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/core/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ SOURCE_ADAPTER_DEFINITIONS: () => SOURCE_ADAPTER_DEFINITIONS,
24
+ analyzeSource: () => analyzeSource,
25
+ analyzeSourceAdapter: () => analyzeSourceAdapter,
26
+ animateMotif: () => animateMotif,
27
+ annotateSourcePreview: () => annotateSourcePreview,
28
+ applySourceEdits: () => applySourceEdits,
29
+ assertProject: () => assertProject,
30
+ cameraStyle: () => cameraStyle,
31
+ commitProject: () => commitProject,
32
+ compileProjectHtml: () => compileProjectHtml,
33
+ componentTypes: () => componentTypes,
34
+ componentTypesV3: () => componentTypesV3,
35
+ configToProject: () => configToProject,
36
+ configV2ToProject: () => configV2ToProject,
37
+ configV3Backgrounds: () => configV3Backgrounds,
38
+ configV3Cameras: () => configV3Cameras,
39
+ configV3Energies: () => configV3Energies,
40
+ configV3ThemePalettes: () => configV3ThemePalettes,
41
+ configV3Themes: () => configV3Themes,
42
+ configV3ToProject: () => configV3ToProject,
43
+ configV3Transitions: () => configV3Transitions,
44
+ configV3Variants: () => configV3Variants,
45
+ contrastRatio: () => contrastRatio,
46
+ contrastText: () => contrastText,
47
+ createLayer: () => createLayer,
48
+ createMediaRenderPlan: () => createMediaRenderPlan,
49
+ createProject: () => createProject,
50
+ createScene: () => createScene,
51
+ duplicateScene: () => duplicateScene,
52
+ escapeHtml: () => escapeHtml,
53
+ evaluateLayer: () => evaluateLayer,
54
+ flight: () => flight,
55
+ importHtmlSource: () => importHtmlSource,
56
+ importStructuredHtml: () => importStructuredHtml,
57
+ isLocalAsset: () => isLocalAsset,
58
+ layerStyle: () => layerStyle,
59
+ migrateProject: () => migrateProject,
60
+ moveScene: () => moveScene,
61
+ newId: () => newId,
62
+ parseMotionConfig: () => parseMotionConfig,
63
+ parseMotionConfigV2: () => parseMotionConfigV2,
64
+ parseMotionConfigV3: () => parseMotionConfigV3,
65
+ parseProject: () => parseProject,
66
+ point: () => point,
67
+ projectDuration: () => projectDuration,
68
+ projectWarnings: () => projectWarnings,
69
+ pulse: () => pulse,
70
+ rebuildConfigV3Scene: () => rebuildConfigV3Scene,
71
+ removeScene: () => removeScene,
72
+ repeaterLayers: () => repeaterLayers,
73
+ sceneAtTime: () => sceneAtTime,
74
+ sceneStyle: () => sceneStyle,
75
+ serializeProject: () => serializeProject,
76
+ sourceFingerprint: () => sourceFingerprint,
77
+ sourcePreviewHtml: () => sourcePreviewHtml,
78
+ textLineStyle: () => textLineStyle,
79
+ textUnitStyle: () => textUnitStyle,
80
+ updateSourceText: () => updateSourceText,
81
+ upgradeConfigV2ToV3: () => upgradeConfigV2ToV3,
82
+ validateProject: () => validateProject,
83
+ visualThemes: () => visualThemes
84
+ });
85
+ module.exports = __toCommonJS(index_exports);
86
+
87
+ // src/core/motion.ts
88
+ function evaluateLayer(layer2, localTime, context = {}) {
89
+ const clamp = (value) => Math.max(0, Math.min(1, value));
90
+ const ease = (p, name = "smooth", seconds = 1) => {
91
+ const t = Math.max(0, Math.min(1, p));
92
+ if (Array.isArray(name)) {
93
+ const [x1, y1, x2, y2] = name;
94
+ const curve = (u, a, b) => 3 * (1 - u) * (1 - u) * u * a + 3 * (1 - u) * u * u * b + u * u * u;
95
+ let lo = 0, hi = 1;
96
+ for (let i = 0; i < 24; i++) {
97
+ const mid = (lo + hi) / 2;
98
+ if (curve(mid, x1, x2) < t) lo = mid;
99
+ else hi = mid;
100
+ }
101
+ return t === 0 || t === 1 ? t : curve((lo + hi) / 2, y1, y2);
102
+ }
103
+ if (typeof name === "object") {
104
+ const { stiffness: k, damping: c, mass: m } = name, w = Math.sqrt(k / m), z = c / (2 * Math.sqrt(k * m));
105
+ const response = (s) => {
106
+ if (z < 1 - 1e-6) {
107
+ const wd = w * Math.sqrt(1 - z * z);
108
+ return 1 - Math.exp(-z * w * s) * (Math.cos(wd * s) + z * w / wd * Math.sin(wd * s));
109
+ }
110
+ if (z <= 1 + 1e-6) return 1 - Math.exp(-w * s) * (1 + w * s);
111
+ const root = Math.sqrt(z * z - 1), r1 = -w / (z + root), r2 = -w * (z + root);
112
+ return 1 - (r2 * Math.exp(r1 * s) - r1 * Math.exp(r2 * s)) / (r2 - r1);
113
+ };
114
+ const end = response(Math.max(1e-3, seconds));
115
+ return t === 0 || t === 1 ? t : response(t * Math.max(1e-3, seconds)) + (1 - end) * t * t * (3 - 2 * t);
116
+ }
117
+ switch (name) {
118
+ case "hold":
119
+ return t === 1 ? 1 : 0;
120
+ case "linear":
121
+ return t;
122
+ case "ease-in":
123
+ return t * t * t;
124
+ case "ease-out":
125
+ return 1 - (1 - t) ** 3;
126
+ case "ease-in-out":
127
+ return t < 0.5 ? 4 * t ** 3 : 1 - (-2 * t + 2) ** 3 / 2;
128
+ case "back":
129
+ return 1 + 2.70158 * (t - 1) ** 3 + 1.70158 * (t - 1) ** 2;
130
+ case "elastic":
131
+ return t === 0 || t === 1 ? t : 2 ** (-10 * t) * Math.sin((t * 10 - 0.75) * 2 * Math.PI / 3) + 1;
132
+ default:
133
+ return t * t * (3 - 2 * t);
134
+ }
135
+ };
136
+ const elapsed = localTime - layer2.start;
137
+ const hash = (seed, n) => {
138
+ let x = seed ^ n * 374761393 | 0;
139
+ x = Math.imul(x ^ x >>> 13, 1274126177);
140
+ return ((x ^ x >>> 16) >>> 0) / 4294967296;
141
+ };
142
+ const nearestBeat = (t) => context.beats?.length ? context.beats.reduce((a, b) => Math.abs(b - t) < Math.abs(a - t) ? b : a) : t;
143
+ const origin = (context.sceneStart ?? 0) + layer2.start;
144
+ const clipMix = (a, b, u) => {
145
+ if (!a && !b) return void 0;
146
+ const clear = (m) => m.type === "circle" ? { type: "circle", radius: 150, x: m.x, y: m.y } : { type: "inset", top: 0, right: 0, bottom: 0, left: 0 };
147
+ a = a ?? clear(b);
148
+ b = b ?? clear(a);
149
+ if (a.type !== b.type) return u < 1 ? a : b;
150
+ const mix2 = (x, y) => x + (y - x) * clamp(u);
151
+ if (a.type === "circle" && b.type === "circle") return { type: "circle", radius: mix2(a.radius, b.radius), x: mix2(a.x, b.x), y: mix2(a.y, b.y) };
152
+ if (a.type === "inset" && b.type === "inset") return { type: "inset", top: mix2(a.top, b.top), right: mix2(a.right, b.right), bottom: mix2(a.bottom, b.bottom), left: mix2(a.left, b.left) };
153
+ return b;
154
+ };
155
+ const colorMix = (a, b, u) => {
156
+ if (a === void 0 && b === void 0) return void 0;
157
+ a = a ?? b;
158
+ b = b ?? a;
159
+ const expand = (c) => c.length === 4 ? "#" + c.slice(1).split("").map((x) => x + x).join("") : c;
160
+ const aa = expand(a), bb = expand(b);
161
+ return "#" + [1, 3, 5].map((i) => Math.round(parseInt(aa.slice(i, i + 2), 16) + (parseInt(bb.slice(i, i + 2), 16) - parseInt(aa.slice(i, i + 2), 16)) * clamp(u)).toString(16).padStart(2, "0")).join("");
162
+ };
163
+ const formatValue = (value) => (layer2.countPrefix ?? "") + value.toLocaleString("he-IL", { minimumFractionDigits: layer2.countDecimals ?? 0, maximumFractionDigits: layer2.countDecimals ?? 0, useGrouping: layer2.countThousands ?? true }) + (layer2.countSuffix ?? "");
164
+ const duration = Math.max(0.01, layer2.duration);
165
+ const sample = (points, time, timeOrigin = origin) => {
166
+ const t = Math.max(0, time);
167
+ if (context.beats?.length && points.some((p) => p.snapToBeat)) points = points.map((p) => ({ ...p, at: p.snapToBeat ? Math.max(0, nearestBeat(timeOrigin + p.at) - timeOrigin) : p.at })).sort((a, b) => a.at - b.at);
168
+ let left = points[0], right = points[points.length - 1];
169
+ if (t <= left.at) right = left;
170
+ else if (t >= right.at) left = right;
171
+ else for (let i = 0; i < points.length - 1; i++) {
172
+ if (t >= points[i].at && t <= points[i + 1].at) {
173
+ left = points[i];
174
+ right = points[i + 1];
175
+ break;
176
+ }
177
+ }
178
+ const u = left === right ? 0 : ease((t - left.at) / (right.at - left.at), right.easing ?? layer2.easing ?? "smooth", right.at - left.at);
179
+ const mix2 = (a, b) => a + (b - a) * u;
180
+ const extras = {};
181
+ for (const channel of ["blur", "skewX", "skewY", "rotateX", "rotateY", "borderRadius", "letterSpacing", "glow"]) {
182
+ if (left[channel] !== void 0 || right[channel] !== void 0) {
183
+ const fallback = layer2[channel] ?? 0;
184
+ extras[channel] = mix2(left[channel] ?? fallback, right[channel] ?? fallback);
185
+ }
186
+ }
187
+ if (left.color !== void 0 || right.color !== void 0) extras.color = colorMix(left.color ?? layer2.color, right.color ?? layer2.color, u);
188
+ if (left.clip || right.clip) extras.clip = clipMix(left.clip ?? layer2.clip, right.clip ?? layer2.clip, u);
189
+ return {
190
+ ...extras,
191
+ translateX: mix2(left.x, right.x),
192
+ translateY: mix2(left.y, right.y),
193
+ scaleX: mix2(left.scaleX, right.scaleX) * mix2(left.scale ?? 1, right.scale ?? 1),
194
+ scaleY: mix2(left.scaleY, right.scaleY) * mix2(left.scale ?? 1, right.scale ?? 1),
195
+ rotation: mix2(left.rotation, right.rotation),
196
+ opacity: clamp(mix2(left.opacity, right.opacity)),
197
+ reveal: clamp(mix2(left.reveal ?? 1, right.reveal ?? 1)),
198
+ value: left.value === void 0 && right.value === void 0 ? void 0 : mix2(left.value ?? right.value, right.value ?? left.value)
199
+ };
200
+ };
201
+ const frame = { visible: !layer2.hidden && elapsed >= 0 && elapsed < duration, opacity: layer2.opacity, translateX: 0, translateY: 0, scale: 1, scaleX: 1, scaleY: 1, rotation: layer2.rotation, reveal: 1, text: layer2.text ?? "" };
202
+ const entryDuration = Math.min(duration, layer2.motionDuration ?? Math.min(0.7, duration / 2));
203
+ const entryP = ease((elapsed - (layer2.motionDelay ?? 0)) / entryDuration, layer2.easing ?? "smooth", entryDuration);
204
+ if (layer2.type === "repeater") return frame;
205
+ const relative = context.schemaVersion === 3;
206
+ const slideX = relative ? (context.canvas?.width ?? 1920) * 0.12 : 100, slideY = relative ? (context.canvas?.height ?? 1080) * 0.12 : 70;
207
+ const applyPreset = (preset, progress, outgoing = false) => {
208
+ const rest = outgoing ? progress : 1 - progress;
209
+ if (preset === "fade") frame.opacity *= outgoing ? 1 - progress : progress;
210
+ if (preset === "slide-up") {
211
+ frame.translateY += (outgoing ? -slideY : slideY) * rest;
212
+ frame.opacity *= outgoing ? 1 - progress : progress;
213
+ }
214
+ if (preset === "slide-down") {
215
+ frame.translateY += (outgoing ? slideY : -slideY) * rest;
216
+ frame.opacity *= outgoing ? 1 - progress : progress;
217
+ }
218
+ if (preset === "slide-left") {
219
+ frame.translateX += (outgoing ? -slideX : slideX) * rest;
220
+ frame.opacity *= outgoing ? 1 - progress : progress;
221
+ }
222
+ if (preset === "slide-right") {
223
+ frame.translateX += (outgoing ? slideX : -slideX) * rest;
224
+ frame.opacity *= outgoing ? 1 - progress : progress;
225
+ }
226
+ if (preset === "zoom") {
227
+ frame.scale *= outgoing ? 1 + 0.25 * progress : 0.75 + 0.25 * progress;
228
+ frame.opacity *= outgoing ? 1 - progress : progress;
229
+ }
230
+ if (preset === "pop") {
231
+ frame.scale *= outgoing ? 1 - 0.25 * progress : progress === 1 ? 1 : 1 + 2.70158 * (progress - 1) ** 3 + 1.70158 * (progress - 1) ** 2;
232
+ frame.opacity *= outgoing ? 1 - progress : Math.min(1, progress * 4);
233
+ }
234
+ const reveal = outgoing ? 1 - progress : progress;
235
+ if (preset === "mask-up") {
236
+ frame.translateY += (outgoing ? -1 : 1) * layer2.height * 0.35 * rest;
237
+ frame.clip = { type: "inset", top: 0, right: 0, bottom: clamp(1 - reveal) * 100, left: 0 };
238
+ frame.opacity *= clamp(reveal * 4);
239
+ }
240
+ if (preset === "blur-in") {
241
+ frame.blur = (layer2.blur ?? 0) + Math.max(0, rest) * 24;
242
+ frame.opacity *= clamp(reveal);
243
+ frame.scale *= 1 + 0.08 * rest;
244
+ }
245
+ if (preset === "flip-in") {
246
+ frame.rotateY = rest * (outgoing ? -85 : 85);
247
+ frame.opacity *= clamp(reveal * 2);
248
+ }
249
+ if (preset === "scale-pop") {
250
+ const t = clamp(reveal);
251
+ frame.scale *= 1 + 2.70158 * (t - 1) ** 3 + 1.70158 * (t - 1) ** 2;
252
+ frame.opacity *= clamp(t * 4);
253
+ }
254
+ if (preset === "drop") {
255
+ const t = clamp(reveal), landing = Math.sin(Math.PI * clamp((t - 0.6) / 0.4)) * 0.22;
256
+ frame.translateY -= slideY * 2 * (1 - t);
257
+ frame.scaleX *= 1 + landing;
258
+ frame.scaleY *= 1 - landing;
259
+ frame.opacity *= clamp(t * 5);
260
+ }
261
+ };
262
+ applyPreset(layer2.motion, entryP);
263
+ const outDuration = Math.min(duration, layer2.motionOutDuration ?? 0.45);
264
+ if (layer2.motionOut && layer2.motionOut !== "none" && elapsed >= duration - outDuration) {
265
+ const outP = ease((elapsed - duration + outDuration) / outDuration, layer2.easing ?? "smooth", outDuration);
266
+ applyPreset(layer2.motionOut, outP, true);
267
+ }
268
+ if (layer2.motion === "typewriter") {
269
+ const segmenter = typeof Intl.Segmenter === "function" ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : null;
270
+ const chars = segmenter ? Array.from(segmenter.segment(frame.text), (s) => s.segment) : Array.from(frame.text);
271
+ frame.text = chars.slice(0, Math.ceil(chars.length * clamp(entryP))).join("");
272
+ }
273
+ if (layer2.type === "text" && layer2.countTo !== void 0) {
274
+ const start = layer2.countFrom ?? 0;
275
+ frame.value = start + (layer2.countTo - start) * entryP;
276
+ frame.text = layer2.countPrefix !== void 0 || layer2.countDecimals !== void 0 || layer2.countThousands !== void 0 ? formatValue(frame.value) : Math.round(frame.value).toLocaleString("he-IL") + (layer2.countSuffix ?? "");
277
+ }
278
+ if (layer2.keyframes?.length) {
279
+ const pose = sample(layer2.keyframes, elapsed);
280
+ frame.translateX += pose.translateX;
281
+ frame.translateY += pose.translateY;
282
+ frame.scaleX *= pose.scaleX;
283
+ frame.scaleY *= pose.scaleY;
284
+ frame.rotation += pose.rotation;
285
+ frame.opacity *= pose.opacity;
286
+ frame.reveal = pose.reveal;
287
+ for (const channel of ["color", "blur", "skewX", "skewY", "rotateX", "rotateY", "clip", "borderRadius", "letterSpacing", "glow"]) if (pose[channel] !== void 0) Object.assign(frame, { [channel]: pose[channel] });
288
+ if (pose.value !== void 0) frame.value = pose.value;
289
+ if (layer2.type === "text" && pose.value !== void 0) frame.text = layer2.countPrefix !== void 0 || layer2.countDecimals !== void 0 || layer2.countThousands !== void 0 ? formatValue(pose.value) : Math.round(pose.value).toLocaleString("he-IL") + (layer2.countSuffix ?? "");
290
+ }
291
+ if (layer2.type === "text" && layer2.splitText && layer2.splitText !== "none") {
292
+ const segmenter = layer2.splitText === "letter" && typeof Intl.Segmenter === "function" ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : null;
293
+ const units = layer2.splitText === "word" ? frame.text.match(/\S+|\s+/gu) ?? [] : segmenter ? Array.from(segmenter.segment(frame.text), (item) => item.segment) : Array.from(frame.text);
294
+ const count = units.filter((text3) => text3.trim()).length;
295
+ const order = Array.from({ length: count }, (_, i) => i);
296
+ if (layer2.staggerOrder === "end") order.reverse();
297
+ if (layer2.staggerOrder === "center") order.sort((a, b) => Math.abs(a - (count - 1) / 2) - Math.abs(b - (count - 1) / 2) || a - b);
298
+ if (layer2.staggerOrder === "seeded-random") order.sort((a, b) => hash(layer2.staggerSeed ?? 0, a) - hash(layer2.staggerSeed ?? 0, b) || a - b);
299
+ const ranks = Array.from({ length: count }, (_, i) => order.indexOf(i));
300
+ let index = 0;
301
+ frame.textUnits = units.map((text3) => {
302
+ if (!text3.trim()) return { text: text3, opacity: 1, translateX: 0, translateY: 0, scaleX: 1, scaleY: 1, rotation: 0 };
303
+ const unitIndex = index++, rank = ranks[unitIndex];
304
+ let delay = (layer2.motionDelay ?? 0) + rank * (layer2.stagger ?? 0.08);
305
+ if (layer2.staggerToBeats && context.beats?.length) {
306
+ const beats = context.beats.filter((b) => b >= origin + (layer2.motionDelay ?? 0));
307
+ const beatIndex = rank + (layer2.staggerBeatOffset ?? 0);
308
+ delay = (beats[beatIndex] ?? (beats.length ? beats[beats.length - 1] + (beatIndex - beats.length + 1) * (layer2.stagger ?? 0.08) : origin + delay)) - origin;
309
+ }
310
+ const unitTime = elapsed - delay, color = layer2.textUnitColors?.[unitIndex % layer2.textUnitColors.length];
311
+ if (layer2.textUnitKeyframes?.length) return { text: text3, color, ...sample(layer2.textUnitKeyframes, unitTime, origin + delay) };
312
+ const p = ease(unitTime / Math.max(0.08, entryDuration * 0.6), layer2.easing ?? "smooth", Math.max(0.08, entryDuration * 0.6));
313
+ return { text: text3, color, opacity: clamp(p), translateX: 0, translateY: (relative ? (context.canvas?.height ?? 1080) * 0.045 : 28) * (1 - p), scaleX: 1, scaleY: 1, rotation: 0 };
314
+ });
315
+ }
316
+ for (const modifier of layer2.modifiers ?? []) {
317
+ const t = Math.max(0, elapsed), phase = hash(modifier.seed, 0) * Math.PI * 2, w = 2 * Math.PI * modifier.frequency, a = modifier.amplitude;
318
+ if (modifier.type === "float") frame.translateY += a * Math.sin(w * t + phase);
319
+ if (modifier.type === "orbit") {
320
+ frame.translateX += a * Math.cos(w * t + phase);
321
+ frame.translateY += a * Math.sin(w * t + phase);
322
+ }
323
+ if (modifier.type === "spin") frame.rotation += a * modifier.frequency * t;
324
+ if (modifier.type === "wiggle") {
325
+ const noise = (offset) => {
326
+ const at = t * modifier.frequency, i = Math.floor(at), f = at - i, u = f * f * (3 - 2 * f);
327
+ return (hash(modifier.seed, i * 2 + offset) * (1 - u) + hash(modifier.seed, (i + 1) * 2 + offset) * u) * 2 - 1;
328
+ };
329
+ frame.translateX += a * noise(1);
330
+ frame.translateY += a * noise(2);
331
+ }
332
+ }
333
+ if (layer2.revealBinding && context.layers) {
334
+ const source = context.layers.find((l) => l.id === layer2.revealBinding.layerId);
335
+ if (source && source.id !== layer2.id && !source.revealBinding) {
336
+ const value = evaluateLayer(source, localTime, context).value;
337
+ if (value !== void 0) frame.reveal = clamp((value - layer2.revealBinding.from) / (layer2.revealBinding.to - layer2.revealBinding.from));
338
+ }
339
+ }
340
+ frame.opacity = clamp(frame.opacity);
341
+ return frame;
342
+ }
343
+
344
+ // src/core/layer-style.ts
345
+ function textUnitStyle(unit) {
346
+ const result = {
347
+ display: "inline-block",
348
+ flexShrink: 0,
349
+ whiteSpace: "pre",
350
+ opacity: unit.opacity,
351
+ transform: `${unit.rotateX || unit.rotateY ? `perspective(1000px) rotateX(${unit.rotateX ?? 0}deg) rotateY(${unit.rotateY ?? 0}deg) ` : ""}translate(${unit.translateX}px,${unit.translateY}px) rotate(${unit.rotation}deg)${unit.skewX || unit.skewY ? ` skew(${unit.skewX ?? 0}deg,${unit.skewY ?? 0}deg)` : ""} scale(${unit.scaleX},${unit.scaleY})`,
352
+ transformOrigin: "center",
353
+ color: "inherit",
354
+ filter: "none",
355
+ clipPath: "none",
356
+ borderRadius: 0,
357
+ letterSpacing: "inherit"
358
+ };
359
+ if (unit.color) result.color = unit.color;
360
+ if (unit.blur !== void 0 || unit.glow !== void 0) result.filter = `blur(${Math.max(0, unit.blur ?? 0)}px)${unit.glow ? ` drop-shadow(0 0 ${Math.max(0, unit.glow)}px ${unit.color ?? "currentColor"})` : ""}`;
361
+ if (unit.borderRadius !== void 0) result.borderRadius = `${Math.max(0, unit.borderRadius)}px`;
362
+ if (unit.letterSpacing !== void 0) result.letterSpacing = `${unit.letterSpacing}px`;
363
+ if (unit.clip) result.clipPath = unit.clip.type === "inset" ? `inset(${unit.clip.top}% ${unit.clip.right}% ${unit.clip.bottom}% ${unit.clip.left}%)` : `circle(${unit.clip.radius}% at ${unit.clip.x}% ${unit.clip.y}%)`;
364
+ return result;
365
+ }
366
+ function textLineStyle(layer2) {
367
+ const direction = !/[\u0590-\u05ff]/.test(layer2.text ?? "") && /[A-Za-z]/.test(layer2.text ?? "") ? "ltr" : "rtl";
368
+ return {
369
+ display: "flex",
370
+ flexWrap: "wrap",
371
+ width: "100%",
372
+ direction,
373
+ alignItems: "center",
374
+ justifyContent: layer2.textAlign === "center" ? "center" : layer2.textAlign === "right" === (direction === "rtl") ? "flex-start" : "flex-end"
375
+ };
376
+ }
377
+ function layerStyle(layer2, frame) {
378
+ const color = frame.color ?? layer2.color, blur = Math.max(0, frame.blur ?? layer2.blur ?? 0), glow = Math.max(0, frame.glow ?? layer2.glow ?? 0), clip = frame.clip ?? layer2.clip;
379
+ let fontSize = layer2.fontSize;
380
+ if (layer2.textFit === "shrink" && layer2.type === "text") {
381
+ const measure = (size) => {
382
+ const limit = layer2.width / Math.max(1, size * 0.6 + (frame.letterSpacing ?? layer2.letterSpacing ?? 0));
383
+ let lines = 1, count = 0;
384
+ for (const word of (frame.text || "").split(/(\s+)/u)) {
385
+ if (word.includes("\n")) {
386
+ lines += word.split("\n").length - 1;
387
+ count = 0;
388
+ } else {
389
+ const n = Array.from(word).length;
390
+ if (count + n > limit) {
391
+ lines += Math.max(1, Math.floor(n / limit));
392
+ count = n % limit;
393
+ } else count += n;
394
+ }
395
+ }
396
+ return lines * size * (layer2.lineHeight ?? 1.2) <= layer2.height;
397
+ };
398
+ for (let i = 0; i < 80 && !measure(fontSize) && fontSize > 4; i++) fontSize *= 0.95;
399
+ }
400
+ const extra = { clipPath: "none" };
401
+ if (clip) extra.clipPath = clip.type === "inset" ? `inset(${clip.top}% ${clip.right}% ${clip.bottom}% ${clip.left}%)` : `circle(${clip.radius}% at ${clip.x}% ${clip.y}%)`;
402
+ if (layer2.type === "shape" && layer2.revealBinding && !clip) extra.clipPath = `inset(0 ${(1 - frame.reveal) * 100}% 0 0)`;
403
+ if (layer2.type === "repeater" || layer2.textFit) extra.overflow = "visible";
404
+ if (layer2.type === "repeater") {
405
+ extra.filter = "none";
406
+ extra.boxShadow = "none";
407
+ extra.border = "none";
408
+ extra.clipPath = "none";
409
+ if (!frame.visible) extra.display = "none";
410
+ }
411
+ const sx = frame.skewX ?? layer2.skewX ?? 0, sy = frame.skewY ?? layer2.skewY ?? 0, rx = frame.rotateX ?? layer2.rotateX ?? 0, ry = frame.rotateY ?? layer2.rotateY ?? 0;
412
+ const spatial = rx || ry ? `perspective(${layer2.perspective ?? 1e3}px) rotateX(${rx}deg) rotateY(${ry}deg) ` : "";
413
+ return {
414
+ position: "absolute",
415
+ left: `${layer2.x}px`,
416
+ top: `${layer2.y}px`,
417
+ width: `${layer2.width}px`,
418
+ height: `${layer2.height}px`,
419
+ display: "flex",
420
+ alignItems: "center",
421
+ justifyContent: layer2.textAlign === "right" ? "flex-start" : layer2.textAlign === "left" ? "flex-end" : "center",
422
+ direction: "rtl",
423
+ textAlign: layer2.textAlign,
424
+ whiteSpace: "pre-wrap",
425
+ overflowWrap: "anywhere",
426
+ overflow: "hidden",
427
+ color,
428
+ background: layer2.type === "shape" ? color : "transparent",
429
+ fontSize: `${fontSize}px`,
430
+ fontWeight: layer2.fontWeight,
431
+ fontFamily: `"MotionDesk Symbols", ${layer2.fontFamily || "Heebo"}, Heebo, sans-serif`,
432
+ letterSpacing: `${frame.letterSpacing ?? layer2.letterSpacing ?? 0}px`,
433
+ lineHeight: layer2.lineHeight ?? 1.2,
434
+ borderRadius: `${Math.max(0, frame.borderRadius ?? layer2.borderRadius)}px`,
435
+ border: `${layer2.borderWidth ?? 0}px solid ${layer2.borderColor ?? "transparent"}`,
436
+ boxShadow: layer2.shadow ?? "none",
437
+ filter: `blur(${blur}px)${glow ? ` drop-shadow(0 0 ${glow}px ${layer2.glowColor ?? color})` : ""}`,
438
+ mixBlendMode: layer2.blendMode ?? "normal",
439
+ opacity: frame.opacity,
440
+ visibility: frame.visible ? "visible" : "hidden",
441
+ transform: `${spatial}translate(${frame.translateX}px,${frame.translateY}px) rotate(${frame.rotation}deg)${sx || sy ? ` skew(${sx}deg,${sy}deg)` : ""} scale(${frame.scale * frame.scaleX},${frame.scale * frame.scaleY})`,
442
+ transformOrigin: layer2.transformOrigin ?? "center",
443
+ ...extra
444
+ };
445
+ }
446
+
447
+ // src/core/config-v3-schema.ts
448
+ var componentTypesV3 = ["hook", "kinetic", "counter", "cards", "checklist", "compare", "timeline", "bars", "phone", "chat", "map-route", "coins", "confetti", "freeze", "endcard", "quote", "progress", "logo", "line-chart", "donut", "notification-stack", "ui-cursor", "marquee", "big-number"];
449
+ var configV3Variants = ["split", "centered", "stacked"];
450
+ var configV3Energies = ["calm", "normal", "punchy"];
451
+ var configV3Backgrounds = ["solid", "gradient", "grid", "dots", "motif"];
452
+ var configV3Cameras = ["push-in", "drift", "orbit", "none"];
453
+ var configV3Themes = ["summer_ice", "bank_red", "midnight", "warm", "mono", "flow", "pulse", "orbit"];
454
+ var configV3Transitions = ["cut", "fade", "slide", "wipe", "zoom", "push", "iris", "diagonal-wipe", "whip", "zoom-through", "stack"];
455
+ var rootKeys = ["format", "title", "theme", "aspectRatio", "fps", "palette", "seed", "beats", "motionBlur", "scenes"];
456
+ var sceneKeys = ["type", "duration", "title", "subtitle", "label", "product", "cta", "words", "items", "rows", "to", "beat", "ring", "transition", "variant", "energy", "background", "camera", "emphasis", "accent", "value", "from", "prefix", "suffix", "decimals", "thousands", "max", "values"];
457
+ var fail = (path, reason) => {
458
+ throw new Error(`${path}: ${reason}`);
459
+ };
460
+ function record(v, keys, path) {
461
+ if (!v || typeof v !== "object" || Array.isArray(v) || ![Object.prototype, null].includes(Object.getPrototypeOf(v))) return fail(path, "\u05E0\u05D3\u05E8\u05E9 \u05D0\u05D5\u05D1\u05D9\u05D9\u05E7\u05D8");
462
+ const r = v;
463
+ for (const key of Object.keys(r)) if (!keys.includes(key)) fail(`${path}.${key}`, "\u05E9\u05D3\u05D4 \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8");
464
+ return r;
465
+ }
466
+ function number(v, min, max, path, integer = false) {
467
+ if (typeof v !== "number" || !Number.isFinite(v) || v < min || v > max || integer && !Number.isInteger(v)) return fail(path, "\u05DE\u05E1\u05E4\u05E8 \u05DE\u05D7\u05D5\u05E5 \u05DC\u05D8\u05D5\u05D5\u05D7");
468
+ return v;
469
+ }
470
+ function text(v, max, path) {
471
+ if (typeof v !== "string" || !v.trim() || v.length > max || /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/.test(v) || /<\/?[a-z][^>]*>/i.test(v)) return fail(path, `\u05E0\u05D3\u05E8\u05E9 \u05D8\u05E7\u05E1\u05D8 \u05E8\u05D2\u05D9\u05DC \u05D1\u05D0\u05D5\u05E8\u05DA 1\u2013${max}`);
472
+ return v;
473
+ }
474
+ function choice(v, choices, path) {
475
+ if (!choices.includes(v)) return fail(path, "\u05E2\u05E8\u05DA \u05DC\u05D0 \u05E0\u05EA\u05DE\u05DA");
476
+ return v;
477
+ }
478
+ function hex(v, path) {
479
+ if (typeof v !== "string" || !/^#[a-fA-F0-9]{6}$/.test(v)) return fail(path, "\u05E0\u05D3\u05E8\u05E9 \u05E6\u05D1\u05E2 #RRGGBB");
480
+ return v;
481
+ }
482
+ function list(v, min, max, path, read) {
483
+ if (!Array.isArray(v) || v.length < min || v.length > max) return fail(path, `\u05E0\u05D3\u05E8\u05E9\u05D9\u05DD ${min}\u2013${max} \u05E4\u05E8\u05D9\u05D8\u05D9\u05DD`);
484
+ return Array.from(v, (entry, i) => read(entry, `${path}.${i}`));
485
+ }
486
+ function parseMotionConfigV3(input) {
487
+ let encoded;
488
+ try {
489
+ encoded = JSON.stringify(input);
490
+ } catch {
491
+ return fail("config", "\u05E7\u05D5\u05E0\u05E4\u05D9\u05D2\u05D5\u05E8\u05E6\u05D9\u05D4 \u05D0\u05D9\u05E0\u05D4 JSON \u05EA\u05E7\u05D9\u05DF");
492
+ }
493
+ if (!encoded || new TextEncoder().encode(encoded).length > 256 * 1024) return fail("config", "\u05E7\u05D5\u05D1\u05E5 \u05D4\u05D4\u05D2\u05D3\u05E8\u05D5\u05EA \u05D2\u05D3\u05D5\u05DC \u05DE\u05D3\u05D9");
494
+ const r = record(input, rootKeys, "config");
495
+ choice(r.format, ["motiondesk-config/v3"], "format");
496
+ const config = { format: "motiondesk-config/v3", title: r.title === void 0 ? "\u05E1\u05E8\u05D8\u05D5\u05DF Motion \u05D7\u05D3\u05E9" : text(r.title, 120, "title"), theme: choice(r.theme === void 0 ? "bank_red" : r.theme, configV3Themes, "theme"), aspectRatio: choice(r.aspectRatio === void 0 ? "16:9" : r.aspectRatio, ["16:9", "9:16", "1:1"], "aspectRatio"), fps: choice(r.fps === void 0 ? 30 : r.fps, [24, 25, 30, 60], "fps"), seed: number(r.seed === void 0 ? 319 : r.seed, -2147483648, 2147483647, "seed", true), scenes: [] };
497
+ if (r.palette !== void 0) {
498
+ const p = record(r.palette, ["background", "foreground", "accent", "secondary"], "palette");
499
+ config.palette = { background: hex(p.background, "palette.background"), foreground: hex(p.foreground, "palette.foreground"), accent: hex(p.accent, "palette.accent") };
500
+ if (p.secondary !== void 0) config.palette.secondary = hex(p.secondary, "palette.secondary");
501
+ }
502
+ config.scenes = list(r.scenes, 1, 30, "scenes", (raw, path) => {
503
+ const s = record(raw, sceneKeys, path);
504
+ const scene = { type: choice(s.type, componentTypesV3, `${path}.type`), duration: number(s.duration === void 0 ? 4 : s.duration, 0.5, 30, `${path}.duration`), beat: number(s.beat === void 0 ? 0.5 : s.beat, 0.05, 3, `${path}.beat`), variant: choice(s.variant === void 0 ? "split" : s.variant, configV3Variants, `${path}.variant`), energy: choice(s.energy === void 0 ? "normal" : s.energy, configV3Energies, `${path}.energy`), background: choice(s.background === void 0 ? "motif" : s.background, configV3Backgrounds, `${path}.background`), camera: choice(s.camera === void 0 ? "push-in" : s.camera, configV3Cameras, `${path}.camera`) };
505
+ for (const key of ["title", "subtitle", "label", "product", "cta", "emphasis", "prefix", "suffix"]) if (s[key] !== void 0) scene[key] = text(s[key], key === "emphasis" ? 80 : ["prefix", "suffix"].includes(key) ? 24 : 220, `${path}.${key}`);
506
+ for (const key of ["words", "items"]) if (s[key] !== void 0) scene[key] = list(s[key], 1, 20, `${path}.${key}`, (v, p) => text(v, 220, p));
507
+ if (s.rows !== void 0) scene.rows = list(s.rows, 1, 12, `${path}.rows`, (v, p) => list(v, 1, 3, p, (cell, p2) => text(cell, 220, p2)));
508
+ if (scene.type === "bars" && scene.rows && s.values === void 0 && scene.rows.some((row) => row.length < 2 || !Number.isFinite(Number(row[1])))) fail(`${path}.rows`, "\u05E2\u05DE\u05D5\u05D3\u05D5\u05EA \u05D3\u05D5\u05E8\u05E9\u05D5\u05EA \u05EA\u05D5\u05D5\u05D9\u05EA \u05D5\u05E2\u05E8\u05DA \u05DE\u05E1\u05E4\u05E8\u05D9");
509
+ if (s.values !== void 0) scene.values = list(s.values, 2, 20, `${path}.values`, (v, p) => number(v, -1e9, 1e9, p));
510
+ for (const key of ["value", "to", "from"]) if (s[key] !== void 0) scene[key] = number(s[key], -1e9, 1e9, `${path}.${key}`);
511
+ if (s.value !== void 0 && s.to !== void 0 && s.value !== s.to) fail(`${path}.value`, "value \u05D5-to \u05E1\u05D5\u05EA\u05E8\u05D9\u05DD");
512
+ if (scene.value === void 0 && scene.to !== void 0) scene.value = scene.to;
513
+ delete scene.to;
514
+ if (s.max !== void 0) scene.max = number(s.max, Number.MIN_VALUE, 1e9, `${path}.max`);
515
+ if (s.decimals !== void 0) scene.decimals = number(s.decimals, 0, 6, `${path}.decimals`, true);
516
+ for (const key of ["thousands", "ring"]) if (s[key] !== void 0) {
517
+ if (typeof s[key] !== "boolean") fail(`${path}.${key}`, "\u05E0\u05D3\u05E8\u05E9 \u05E2\u05E8\u05DA \u05D1\u05D5\u05DC\u05D9\u05D0\u05E0\u05D9");
518
+ scene[key] = s[key];
519
+ }
520
+ if (s.accent !== void 0) scene.accent = hex(s.accent, `${path}.accent`);
521
+ if (s.transition !== void 0) scene.transition = choice(s.transition, configV3Transitions, `${path}.transition`);
522
+ return scene;
523
+ });
524
+ const duration = config.scenes.reduce((sum, s) => sum + s.duration, 0);
525
+ if (r.beats !== void 0) {
526
+ config.beats = list(r.beats, 0, 1e3, "beats", (v, p) => number(v, 0, duration, p));
527
+ if (config.beats.some((beat, i) => i > 0 && beat <= config.beats[i - 1])) fail("beats", "\u05E0\u05E7\u05D5\u05D3\u05D5\u05EA \u05D4\u05D6\u05DE\u05DF \u05D7\u05D9\u05D9\u05D1\u05D5\u05EA \u05DC\u05E2\u05DC\u05D5\u05EA");
528
+ }
529
+ if (r.motionBlur !== void 0) {
530
+ const b = record(r.motionBlur, ["samples", "shutterAngle"], "motionBlur");
531
+ config.motionBlur = { samples: number(b.samples, 1, 8, "motionBlur.samples", true), shutterAngle: number(b.shutterAngle, 0, 360, "motionBlur.shutterAngle") };
532
+ }
533
+ return config;
534
+ }
535
+
536
+ // src/core/project.ts
537
+ function newId(prefix = "id") {
538
+ return `${prefix}_${globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`}`;
539
+ }
540
+ function createLayer(type = "text", patch = {}) {
541
+ return {
542
+ id: newId("layer"),
543
+ type,
544
+ name: type === "text" ? "\u05D8\u05E7\u05E1\u05D8 \u05D7\u05D3\u05E9" : "\u05E9\u05DB\u05D1\u05D4 \u05D7\u05D3\u05E9\u05D4",
545
+ ...type === "text" ? { text: "\u05D4\u05E1\u05D9\u05E4\u05D5\u05E8 \u05E9\u05DC\u05DA \u05DE\u05EA\u05D7\u05D9\u05DC \u05DB\u05D0\u05DF" } : {},
546
+ x: 120,
547
+ y: 240,
548
+ width: 840,
549
+ height: 220,
550
+ rotation: 0,
551
+ opacity: 1,
552
+ color: "#ffffff",
553
+ fontSize: 72,
554
+ fontWeight: 700,
555
+ fontFamily: "Heebo",
556
+ textAlign: "center",
557
+ borderRadius: 0,
558
+ motion: "fade",
559
+ motionOut: "none",
560
+ motionDuration: 0.7,
561
+ motionDelay: 0,
562
+ motionOutDuration: 0.45,
563
+ easing: "ease-out",
564
+ splitText: "none",
565
+ stagger: 0.08,
566
+ shadow: "none",
567
+ borderColor: "#000000",
568
+ borderWidth: 0,
569
+ letterSpacing: 0,
570
+ lineHeight: 1.2,
571
+ blur: 0,
572
+ blendMode: "normal",
573
+ start: 0,
574
+ duration: 5,
575
+ locked: false,
576
+ hidden: false,
577
+ ...patch
578
+ };
579
+ }
580
+ function createScene(name = "\u05E1\u05E6\u05E0\u05D4 \u05D7\u05D3\u05E9\u05D4", duration = 5) {
581
+ return { id: newId("scene"), name, duration, background: "#111827", layers: [], transition: "cut" };
582
+ }
583
+ function createProject(title = "\u05D4\u05E1\u05E8\u05D8\u05D5\u05DF \u05E9\u05DC\u05D9", options = {}) {
584
+ const now = (/* @__PURE__ */ new Date()).toISOString();
585
+ return {
586
+ schemaVersion: 2,
587
+ id: newId("project"),
588
+ title,
589
+ mode: "authored",
590
+ revision: 0,
591
+ createdAt: now,
592
+ updatedAt: now,
593
+ canvas: { width: 1080, height: 1920, fps: 30 },
594
+ scenes: [createScene("\u05E4\u05EA\u05D9\u05D7\u05D4")],
595
+ assets: [],
596
+ mediaTracks: [],
597
+ ...options
598
+ };
599
+ }
600
+ function projectDuration(project) {
601
+ return Math.max(
602
+ project.scenes.reduce((sum, scene) => sum + scene.duration, 0),
603
+ ...project.mediaTracks.flatMap((track) => track.clips.map((clip) => clip.start + clip.out - clip.in)),
604
+ 0
605
+ );
606
+ }
607
+ function sceneAtTime(project, time) {
608
+ if (!Number.isFinite(time) || time < 0) return null;
609
+ let start = 0;
610
+ for (let index = 0; index < project.scenes.length; index++) {
611
+ const scene = project.scenes[index];
612
+ if (time < start + scene.duration) return { scene, index, localTime: time - start, start };
613
+ start += scene.duration;
614
+ }
615
+ return null;
616
+ }
617
+ function commitProject(project) {
618
+ return { ...project, revision: project.revision + 1, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
619
+ }
620
+ function duplicateScene(project, sceneId) {
621
+ const index = project.scenes.findIndex((scene) => scene.id === sceneId);
622
+ if (index < 0) throw new Error("\u05D4\u05E1\u05E6\u05E0\u05D4 \u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D4");
623
+ const copy = structuredClone(project.scenes[index]);
624
+ copy.id = newId("scene");
625
+ copy.name += " \u2014 \u05E2\u05D5\u05EA\u05E7";
626
+ const replacements = /* @__PURE__ */ new Map();
627
+ const collect = (layer2) => {
628
+ replacements.set(layer2.id, newId("layer"));
629
+ layer2.children?.forEach(collect);
630
+ };
631
+ copy.layers.forEach(collect);
632
+ const reidentify = (layer2) => ({
633
+ ...layer2,
634
+ id: replacements.get(layer2.id),
635
+ ...layer2.revealBinding ? { revealBinding: { ...layer2.revealBinding, layerId: replacements.get(layer2.revealBinding.layerId) ?? layer2.revealBinding.layerId } } : {},
636
+ ...layer2.children ? { children: layer2.children.map(reidentify) } : {}
637
+ });
638
+ copy.layers = copy.layers.map(reidentify);
639
+ const scenes = [...project.scenes];
640
+ scenes.splice(index + 1, 0, copy);
641
+ return commitProject({ ...project, scenes });
642
+ }
643
+ function moveScene(project, sceneId, index) {
644
+ const previous = project.scenes.findIndex((scene2) => scene2.id === sceneId);
645
+ if (previous < 0 || !Number.isInteger(index) || index < 0 || index >= project.scenes.length) throw new Error("\u05DE\u05D9\u05E7\u05D5\u05DD \u05E1\u05E6\u05E0\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF");
646
+ const scenes = [...project.scenes];
647
+ const [scene] = scenes.splice(previous, 1);
648
+ scenes.splice(index, 0, scene);
649
+ return commitProject({ ...project, scenes });
650
+ }
651
+ function removeScene(project, sceneId) {
652
+ if (!project.scenes.some((scene) => scene.id === sceneId)) throw new Error("\u05D4\u05E1\u05E6\u05E0\u05D4 \u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D4");
653
+ if (project.scenes.length < 2) throw new Error("\u05E6\u05E8\u05D9\u05DA \u05DC\u05D4\u05E9\u05D0\u05D9\u05E8 \u05DC\u05E4\u05D7\u05D5\u05EA \u05E1\u05E6\u05E0\u05D4 \u05D0\u05D7\u05EA");
654
+ return commitProject({ ...project, scenes: project.scenes.filter((scene) => scene.id !== sceneId) });
655
+ }
656
+ function isLocalAsset(src) {
657
+ if (/^motiondesk-media:\/\/[a-zA-Z0-9_-]+(?:\/[a-zA-Z0-9_.-]+)?$/.test(src)) return true;
658
+ if (/^data:(?:image\/(?:png|jpeg|webp|gif)|audio\/[a-z0-9.+-]+|video\/[a-z0-9.+-]+|font\/[a-z0-9.+-]+);base64,[A-Za-z0-9+/=]+$/.test(src)) return true;
659
+ return !!src && !/[\x00-\x1f<>"'`?#]/.test(src) && !src.startsWith("/") && !src.startsWith("\\") && !src.includes("\\") && !src.includes(":") && !src.split("/").some((p) => p === ".." || p === "." || !p) && !/%(?:2e|2f|5c)/i.test(src);
660
+ }
661
+ function migrateProject(value) {
662
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("\u05E0\u05D3\u05E8\u05E9 \u05D0\u05D5\u05D1\u05D9\u05D9\u05E7\u05D8 \u05E4\u05E8\u05D5\u05D9\u05E7\u05D8");
663
+ const input = value;
664
+ if (input.schemaVersion === 2 || input.schemaVersion === 3) {
665
+ assertProject(value);
666
+ return value;
667
+ }
668
+ if (input.schemaVersion !== 1) throw new Error("\u05D2\u05E8\u05E1\u05EA \u05E4\u05E8\u05D5\u05D9\u05E7\u05D8 \u05D0\u05D9\u05E0\u05D4 \u05E0\u05EA\u05DE\u05DB\u05EA");
669
+ const migrated = structuredClone(input);
670
+ migrated.schemaVersion = 2;
671
+ const upgrade = (layer2) => ({
672
+ ...layer2,
673
+ motionOut: "none",
674
+ motionDuration: Math.min(0.7, layer2.duration / 2),
675
+ motionDelay: 0,
676
+ motionOutDuration: Math.min(0.45, layer2.duration / 2),
677
+ easing: "smooth",
678
+ splitText: "none",
679
+ stagger: 0.08,
680
+ shadow: "none",
681
+ borderColor: "#000000",
682
+ borderWidth: 0,
683
+ letterSpacing: 0,
684
+ lineHeight: 1.2,
685
+ blur: 0,
686
+ blendMode: "normal",
687
+ ...layer2.children ? { children: layer2.children.map(upgrade) } : {}
688
+ });
689
+ migrated.scenes = migrated.scenes.map((scene) => ({ ...scene, transitionDuration: 0.35, layers: scene.layers.map(upgrade) }));
690
+ assertProject(migrated);
691
+ return migrated;
692
+ }
693
+ function validateProject(value) {
694
+ if (value && typeof value === "object" && value.schemaVersion === 1) {
695
+ try {
696
+ migrateProject(value);
697
+ return [];
698
+ } catch (error) {
699
+ return [{ path: "project", message: String(error instanceof Error ? error.message : error) }];
700
+ }
701
+ }
702
+ const issues = [];
703
+ const fail3 = (path, message) => issues.push({ path, message });
704
+ const record2 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
705
+ if (!record2(value)) return [{ path: "", message: "\u05E0\u05D3\u05E8\u05E9 \u05D0\u05D5\u05D1\u05D9\u05D9\u05E7\u05D8 \u05E4\u05E8\u05D5\u05D9\u05E7\u05D8" }];
706
+ const p = value;
707
+ if (p.schemaVersion !== 2 && p.schemaVersion !== 3) fail3("schemaVersion", "\u05D2\u05E8\u05E1\u05EA \u05E4\u05E8\u05D5\u05D9\u05E7\u05D8 \u05D0\u05D9\u05E0\u05D4 \u05E0\u05EA\u05DE\u05DB\u05EA");
708
+ if (!["authored", "imported-source", "flat-video"].includes(p.mode)) fail3("mode", "\u05DE\u05E6\u05D1 \u05E4\u05E8\u05D5\u05D9\u05E7\u05D8 \u05D0\u05D9\u05E0\u05D5 \u05DE\u05D5\u05DB\u05E8");
709
+ const ids = /* @__PURE__ */ new Set();
710
+ const id = (v, path) => {
711
+ if (typeof v !== "string" || !/^[a-zA-Z0-9_-]{1,100}$/.test(v) || ids.has(v)) fail3(path, "\u05DE\u05D6\u05D4\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF \u05D0\u05D5 \u05DB\u05E4\u05D5\u05DC");
712
+ else ids.add(v);
713
+ };
714
+ const text3 = (v, path, max = 1e5) => {
715
+ if (typeof v !== "string" || v.length > max) fail3(path, "\u05D8\u05E7\u05E1\u05D8 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF");
716
+ };
717
+ const num = (v, path, min, max) => {
718
+ if (typeof v !== "number" || !Number.isFinite(v) || v < min || v > max) fail3(path, "\u05E2\u05E8\u05DA \u05DE\u05E1\u05E4\u05E8\u05D9 \u05DE\u05D7\u05D5\u05E5 \u05DC\u05D8\u05D5\u05D5\u05D7");
719
+ };
720
+ const integer = (v, path, min, max) => {
721
+ num(v, path, min, max);
722
+ if (typeof v === "number" && Number.isFinite(v) && v >= min && v <= max && !Number.isInteger(v)) fail3(path, "\u05E0\u05D3\u05E8\u05E9 \u05DE\u05E1\u05E4\u05E8 \u05E9\u05DC\u05DD");
723
+ };
724
+ const seed = (v, path) => integer(v, path, -2147483648, 2147483647);
725
+ const hex2 = (v, path) => {
726
+ if (typeof v !== "string" || !/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(v)) fail3(path, "\u05E0\u05D3\u05E8\u05E9 \u05E6\u05D1\u05E2 hex");
727
+ };
728
+ const bool = (v, path) => {
729
+ if (typeof v !== "boolean") fail3(path, "\u05E0\u05D3\u05E8\u05E9 \u05E2\u05E8\u05DA \u05D1\u05D5\u05DC\u05D9\u05D0\u05E0\u05D9");
730
+ };
731
+ const known = (v, path, keys) => {
732
+ for (const key of Object.keys(v)) if (!keys.includes(key)) fail3(`${path}.${key}`, "\u05E9\u05D3\u05D4 \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8");
733
+ };
734
+ const easing = (v, path) => {
735
+ if (typeof v === "string") {
736
+ if (!["linear", "smooth", "ease-in", "ease-out", "ease-in-out", "back", "elastic", "hold"].includes(v)) fail3(path, "easing \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8");
737
+ return;
738
+ }
739
+ if (Array.isArray(v)) {
740
+ if (v.length !== 4 || Object.keys(v).some((key) => !/^[0-3]$/.test(key))) {
741
+ fail3(path, "\u05E0\u05D3\u05E8\u05E9\u05D5\u05EA \u05D0\u05E8\u05D1\u05E2 \u05E0\u05E7\u05D5\u05D3\u05D5\u05EA bezier");
742
+ return;
743
+ }
744
+ num(v[0], `${path}.0`, 0, 1);
745
+ num(v[1], `${path}.1`, -4, 4);
746
+ num(v[2], `${path}.2`, 0, 1);
747
+ num(v[3], `${path}.3`, -4, 4);
748
+ return;
749
+ }
750
+ if (record2(v)) {
751
+ known(v, path, ["stiffness", "damping", "mass"]);
752
+ num(v.stiffness, `${path}.stiffness`, 1e-3, 1e4);
753
+ num(v.damping, `${path}.damping`, 1e-3, 1e4);
754
+ num(v.mass, `${path}.mass`, 1e-3, 1e3);
755
+ return;
756
+ }
757
+ fail3(path, "easing \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8");
758
+ };
759
+ const clip = (v, path) => {
760
+ if (!record2(v)) {
761
+ fail3(path, "\u05DE\u05E1\u05DB\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D4");
762
+ return;
763
+ }
764
+ if (v.type === "inset") {
765
+ known(v, path, ["type", "top", "right", "bottom", "left"]);
766
+ for (const key of ["top", "right", "bottom", "left"]) num(v[key], `${path}.${key}`, 0, 100);
767
+ } else if (v.type === "circle") {
768
+ known(v, path, ["type", "radius", "x", "y"]);
769
+ for (const key of ["radius", "x", "y"]) num(v[key], `${path}.${key}`, 0, 100);
770
+ } else fail3(`${path}.type`, "\u05E1\u05D5\u05D2 \u05DE\u05E1\u05DB\u05D4 \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8");
771
+ };
772
+ id(p.id, "id");
773
+ text3(p.title, "title", 500);
774
+ num(p.revision, "revision", 0, Number.MAX_SAFE_INTEGER);
775
+ for (const field of ["createdAt", "updatedAt"]) if (typeof p[field] !== "string" || !Number.isFinite(Date.parse(p[field]))) fail3(field, "\u05EA\u05D0\u05E8\u05D9\u05DA \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF");
776
+ if (!record2(p.canvas)) fail3("canvas", "\u05DE\u05D9\u05D3\u05D5\u05EA \u05D7\u05E1\u05E8\u05D5\u05EA");
777
+ else {
778
+ num(p.canvas.width, "canvas.width", 16, 8192);
779
+ num(p.canvas.height, "canvas.height", 16, 8192);
780
+ num(p.canvas.fps, "canvas.fps", 1, 120);
781
+ }
782
+ const assetIds = /* @__PURE__ */ new Set();
783
+ let expandedLayers = 0;
784
+ if (p.renderSettings !== void 0) {
785
+ if (!record2(p.renderSettings)) fail3("renderSettings", "\u05D4\u05D2\u05D3\u05E8\u05D5\u05EA \u05E8\u05D9\u05E0\u05D3\u05D5\u05E8 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D5\u05EA");
786
+ else {
787
+ known(p.renderSettings, "renderSettings", ["motionBlur"]);
788
+ if (p.renderSettings.motionBlur !== void 0) {
789
+ const blur = p.renderSettings.motionBlur;
790
+ if (!record2(blur)) fail3("renderSettings.motionBlur", "\u05D8\u05E9\u05D8\u05D5\u05E9 \u05EA\u05E0\u05D5\u05E2\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF");
791
+ else {
792
+ known(blur, "renderSettings.motionBlur", ["samples", "shutterAngle"]);
793
+ integer(blur.samples, "renderSettings.motionBlur.samples", 1, 8);
794
+ num(blur.shutterAngle, "renderSettings.motionBlur.shutterAngle", 0, 360);
795
+ }
796
+ }
797
+ }
798
+ }
799
+ if (!Array.isArray(p.assets) || p.assets.length > 1e3) fail3("assets", "\u05E8\u05E9\u05D9\u05DE\u05EA \u05E0\u05DB\u05E1\u05D9\u05DD \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D4");
800
+ else p.assets.forEach((a, i) => {
801
+ const at = `assets.${i}`;
802
+ if (!record2(a)) {
803
+ fail3(at, "\u05E0\u05DB\u05E1 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF");
804
+ return;
805
+ }
806
+ id(a.id, at + ".id");
807
+ assetIds.add(a.id);
808
+ text3(a.name, at + ".name", 1e3);
809
+ text3(a.mime, at + ".mime", 100);
810
+ if (!["image", "video", "audio", "font"].includes(a.kind)) fail3(at + ".kind", "\u05E1\u05D5\u05D2 \u05E0\u05DB\u05E1 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF");
811
+ if (typeof a.src !== "string" || !isLocalAsset(a.src)) fail3(at + ".src", "\u05E0\u05D3\u05E8\u05E9 \u05E0\u05DB\u05E1 \u05DE\u05E7\u05D5\u05DE\u05D9 \u05DC\u05DC\u05D0 \u05E0\u05EA\u05D9\u05D1 \u05D7\u05D9\u05E6\u05D5\u05E0\u05D9");
812
+ if (a.duration !== void 0) num(a.duration, at + ".duration", 0, 86400);
813
+ });
814
+ const motions = ["none", "fade", "slide-up", "slide-left", "slide-right", "slide-down", "zoom", "pop", "typewriter", "mask-up", "blur-in", "drop", "flip-in", "scale-pop"];
815
+ const validateLayer = (l, lt, sceneDuration, siblings, depth = 0) => {
816
+ if (!record2(l)) {
817
+ fail3(lt, "\u05E9\u05DB\u05D1\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D4");
818
+ return;
819
+ }
820
+ if (depth > 4) {
821
+ fail3(lt, "\u05E7\u05D1\u05D5\u05E6\u05D5\u05EA \u05DE\u05E7\u05D5\u05E0\u05E0\u05D5\u05EA \u05E2\u05D3 \u05D0\u05E8\u05D1\u05E2 \u05E8\u05DE\u05D5\u05EA");
822
+ return;
823
+ }
824
+ id(l.id, lt + ".id");
825
+ text3(l.name, lt + ".name", 500);
826
+ if (!["text", "shape", "image", "video", "path", "svg", "group", "repeater"].includes(l.type)) fail3(lt + ".type", "\u05E1\u05D5\u05D2 \u05E9\u05DB\u05D1\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF");
827
+ expandedLayers += l.type === "repeater" && record2(l.repeater) && Number.isInteger(l.repeater.count) && l.repeater.count >= 1 && l.repeater.count <= 200 ? l.repeater.count : 1;
828
+ if (l.type === "text") text3(l.text, lt + ".text");
829
+ if (l.countFrom !== void 0) num(l.countFrom, lt + ".countFrom", -1e9, 1e9);
830
+ if (l.countTo !== void 0) num(l.countTo, lt + ".countTo", -1e9, 1e9);
831
+ if (l.countSuffix !== void 0) text3(l.countSuffix, lt + ".countSuffix", 40);
832
+ if (l.countPrefix !== void 0) text3(l.countPrefix, lt + ".countPrefix", 40);
833
+ if (l.countDecimals !== void 0) integer(l.countDecimals, lt + ".countDecimals", 0, 8);
834
+ if (l.countThousands !== void 0) bool(l.countThousands, lt + ".countThousands");
835
+ for (const prop of ["perspective", "skewX", "skewY", "rotateX", "rotateY", "glow", "depth"]) if (l[prop] !== void 0) {
836
+ const ranges = { perspective: [100, 4e3], skewX: [-85, 85], skewY: [-85, 85], rotateX: [-36e3, 36e3], rotateY: [-36e3, 36e3], glow: [0, 100], depth: [-1, 1] };
837
+ num(l[prop], `${lt}.${prop}`, ranges[prop][0], ranges[prop][1]);
838
+ }
839
+ if (l.glowColor !== void 0) hex2(l.glowColor, lt + ".glowColor");
840
+ if (l.clip !== void 0) clip(l.clip, lt + ".clip");
841
+ if (l.modifiers !== void 0) {
842
+ if (!Array.isArray(l.modifiers) || l.modifiers.length > 16) fail3(lt + ".modifiers", "\u05DE\u05D5\u05D3\u05D9\u05E4\u05D9\u05D9\u05E8\u05D9\u05DD \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D9\u05DD");
843
+ else l.modifiers.forEach((modifier, i) => {
844
+ const mt = `${lt}.modifiers.${i}`;
845
+ if (!record2(modifier)) {
846
+ fail3(mt, "\u05DE\u05D5\u05D3\u05D9\u05E4\u05D9\u05D9\u05E8 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF");
847
+ return;
848
+ }
849
+ known(modifier, mt, ["type", "amplitude", "frequency", "seed"]);
850
+ if (!["float", "wiggle", "orbit", "spin"].includes(modifier.type)) fail3(mt + ".type", "\u05E1\u05D5\u05D2 \u05DE\u05D5\u05D3\u05D9\u05E4\u05D9\u05D9\u05E8 \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8");
851
+ num(modifier.amplitude, mt + ".amplitude", 0, 1e4);
852
+ num(modifier.frequency, mt + ".frequency", 0, 100);
853
+ seed(modifier.seed, mt + ".seed");
854
+ });
855
+ }
856
+ if (l.type === "repeater" && l.repeater === void 0) fail3(lt + ".repeater", "\u05E0\u05D3\u05E8\u05E9\u05D5\u05EA \u05D4\u05D2\u05D3\u05E8\u05D5\u05EA repeater");
857
+ if (l.repeater !== void 0) {
858
+ if (l.type !== "repeater") fail3(lt + ".repeater", "\u05D4\u05D2\u05D3\u05E8\u05D5\u05EA repeater \u05D6\u05DE\u05D9\u05E0\u05D5\u05EA \u05DC\u05E9\u05DB\u05D1\u05EA repeater \u05D1\u05DC\u05D1\u05D3");
859
+ if (!record2(l.repeater)) fail3(lt + ".repeater", "\u05D4\u05D2\u05D3\u05E8\u05D5\u05EA repeater \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D5\u05EA");
860
+ else {
861
+ const rt = lt + ".repeater";
862
+ const r = l.repeater;
863
+ known(r, rt, ["count", "seed", "shape", "offsetX", "offsetY", "rotation", "delay", "jitterX", "jitterY", "jitterRotation", "jitterDelay", "colors"]);
864
+ integer(r.count, rt + ".count", 1, 200);
865
+ seed(r.seed, rt + ".seed");
866
+ if (!["rect", "ellipse", "diamond"].includes(r.shape)) fail3(rt + ".shape", "\u05E6\u05D5\u05E8\u05EA repeater \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8\u05EA");
867
+ for (const prop of ["offsetX", "offsetY", "jitterX", "jitterY"]) if (r[prop] !== void 0) num(r[prop], `${rt}.${prop}`, -32768, 32768);
868
+ for (const prop of ["rotation", "jitterRotation"]) if (r[prop] !== void 0) num(r[prop], `${rt}.${prop}`, -36e3, 36e3);
869
+ for (const prop of ["delay", "jitterDelay"]) if (r[prop] !== void 0) num(r[prop], `${rt}.${prop}`, 0, 3600);
870
+ if (r.offsetX === void 0) num(r.offsetX, rt + ".offsetX", -32768, 32768);
871
+ if (r.offsetY === void 0) num(r.offsetY, rt + ".offsetY", -32768, 32768);
872
+ if (r.rotation === void 0) num(r.rotation, rt + ".rotation", -36e3, 36e3);
873
+ if (r.delay === void 0) num(r.delay, rt + ".delay", 0, 3600);
874
+ if (Number.isFinite(r.count) && Number.isFinite(r.delay) && Number.isFinite(l.duration) && (r.count - 1) * r.delay + (r.jitterDelay ?? 0) >= l.duration) fail3(rt + ".delay", "\u05DB\u05DC \u05D4\u05E2\u05D5\u05EA\u05E7\u05D9\u05DD \u05E6\u05E8\u05D9\u05DB\u05D9\u05DD \u05DC\u05D4\u05EA\u05D7\u05D9\u05DC \u05D1\u05EA\u05D5\u05DA \u05DE\u05E9\u05DA \u05D4\u05E9\u05DB\u05D1\u05D4");
875
+ if (r.colors !== void 0) {
876
+ if (!Array.isArray(r.colors) || r.colors.length > 200) fail3(rt + ".colors", "\u05E6\u05D1\u05E2\u05D9 repeater \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D9\u05DD");
877
+ else r.colors.forEach((color, i) => hex2(color, `${rt}.colors.${i}`));
878
+ }
879
+ }
880
+ }
881
+ if (l.revealBinding !== void 0) {
882
+ const bt = lt + ".revealBinding";
883
+ const binding = l.revealBinding;
884
+ if (!record2(binding)) fail3(bt, "\u05E7\u05D9\u05E9\u05D5\u05E8 reveal \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF");
885
+ else {
886
+ known(binding, bt, ["layerId", "from", "to"]);
887
+ const source = siblings.find((sibling) => record2(sibling) && sibling.id === binding.layerId);
888
+ if (!["path", "svg", "shape"].includes(l.type)) fail3(bt, "\u05E7\u05D9\u05E9\u05D5\u05E8 reveal \u05D6\u05DE\u05D9\u05DF \u05DC\u05E9\u05DB\u05D1\u05EA \u05E6\u05D5\u05E8\u05D4 \u05D0\u05D5 \u05E0\u05EA\u05D9\u05D1 \u05D1\u05DC\u05D1\u05D3");
889
+ if (typeof binding.layerId !== "string" || !source || source === l || !record2(source) || source.revealBinding !== void 0 || !(source.type === "text" && typeof source.countTo === "number" && Number.isFinite(source.countTo)) && !(Array.isArray(source.keyframes) && source.keyframes.some((point2) => record2(point2) && typeof point2.value === "number" && Number.isFinite(point2.value))))
890
+ fail3(bt + ".layerId", "\u05E0\u05D3\u05E8\u05E9 \u05DE\u05E7\u05D5\u05E8 \u05DE\u05E1\u05E4\u05E8\u05D9 \u05D0\u05D7\u05D0\u05D9 \u05DC\u05DC\u05D0 \u05E7\u05D9\u05E9\u05D5\u05E8 \u05E0\u05D5\u05E1\u05E3");
891
+ num(binding.from, bt + ".from", -1e9, 1e9);
892
+ num(binding.to, bt + ".to", -1e9, 1e9);
893
+ if (binding.from === binding.to) fail3(bt + ".to", "\u05E0\u05E7\u05D5\u05D3\u05D5\u05EA \u05EA\u05D7\u05D5\u05DD \u05D7\u05D9\u05D9\u05D1\u05D5\u05EA \u05DC\u05D4\u05D9\u05D5\u05EA \u05E9\u05D5\u05E0\u05D5\u05EA");
894
+ }
895
+ }
896
+ if (l.staggerOrder !== void 0 && !["start", "end", "center", "seeded-random"].includes(l.staggerOrder)) fail3(lt + ".staggerOrder", "\u05E1\u05D3\u05E8 stagger \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8");
897
+ if (l.staggerSeed !== void 0) seed(l.staggerSeed, lt + ".staggerSeed");
898
+ if (l.staggerToBeats !== void 0) bool(l.staggerToBeats, lt + ".staggerToBeats");
899
+ if (l.staggerBeatOffset !== void 0) integer(l.staggerBeatOffset, lt + ".staggerBeatOffset", 0, 1e4);
900
+ if (l.textUnitColors !== void 0) {
901
+ if (l.type !== "text" || !Array.isArray(l.textUnitColors) || l.textUnitColors.length > 1e4) fail3(lt + ".textUnitColors", "\u05E6\u05D1\u05E2\u05D9 \u05D9\u05D7\u05D9\u05D3\u05D5\u05EA \u05D8\u05E7\u05E1\u05D8 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D9\u05DD");
902
+ else l.textUnitColors.forEach((color, i) => hex2(color, `${lt}.textUnitColors.${i}`));
903
+ }
904
+ if (l.textFit !== void 0 && !["shrink", "warn"].includes(l.textFit)) fail3(lt + ".textFit", "\u05D4\u05EA\u05D0\u05DE\u05EA \u05D8\u05E7\u05E1\u05D8 \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8\u05EA");
905
+ if (l.type === "path" || l.type === "svg") {
906
+ if (typeof l.pathData !== "string" || l.pathData.length > 2e4 || !/^[MmLlHhVvCcSsQqTtAaZz0-9eE+\-.,\s]+$/.test(l.pathData)) fail3(lt + ".pathData", "\u05E0\u05D3\u05E8\u05E9 \u05E0\u05EA\u05D9\u05D1 SVG \u05EA\u05E7\u05D9\u05DF \u05DC\u05DC\u05D0 \u05E7\u05D5\u05D3");
907
+ if (l.stroke !== void 0) text3(l.stroke, lt + ".stroke", 100);
908
+ if (l.strokeWidth !== void 0) num(l.strokeWidth, lt + ".strokeWidth", 0, 1e3);
909
+ }
910
+ if (l.type === "group" && (!Array.isArray(l.children) || l.children.length > 200)) fail3(lt + ".children", "\u05E7\u05D1\u05D5\u05E6\u05D4 \u05E6\u05E8\u05D9\u05DB\u05D4 \u05E8\u05E9\u05D9\u05DE\u05EA \u05E9\u05DB\u05D1\u05D5\u05EA");
911
+ if (l.children !== void 0 && l.type !== "group") fail3(lt + ".children", "\u05E8\u05E7 \u05DC\u05E7\u05D1\u05D5\u05E6\u05D4 \u05D9\u05E9 \u05E9\u05DB\u05D1\u05D5\u05EA \u05E4\u05E0\u05D9\u05DE\u05D9\u05D5\u05EA");
912
+ for (const prop of ["x", "y"]) num(l[prop], `${lt}.${prop}`, -32768, 32768);
913
+ for (const prop of ["width", "height"]) num(l[prop], `${lt}.${prop}`, 1, 32768);
914
+ num(l.rotation, lt + ".rotation", -36e3, 36e3);
915
+ num(l.opacity, lt + ".opacity", 0, 1);
916
+ num(l.fontSize, lt + ".fontSize", 1, 2e3);
917
+ num(l.fontWeight, lt + ".fontWeight", 100, 1e3);
918
+ num(l.borderRadius, lt + ".borderRadius", 0, 16e3);
919
+ text3(l.color, lt + ".color", 500);
920
+ text3(l.fontFamily, lt + ".fontFamily", 200);
921
+ if (!["left", "center", "right"].includes(l.textAlign)) fail3(lt + ".textAlign", "\u05D9\u05D9\u05E9\u05D5\u05E8 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF");
922
+ if (!motions.includes(l.motion)) fail3(lt + ".motion", "\u05EA\u05E0\u05D5\u05E2\u05D4 \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8\u05EA");
923
+ if (l.motionOut !== void 0 && !motions.includes(l.motionOut)) fail3(lt + ".motionOut", "\u05EA\u05E0\u05D5\u05E2\u05EA \u05D9\u05E6\u05D9\u05D0\u05D4 \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8\u05EA");
924
+ if (l.easing !== void 0) easing(l.easing, lt + ".easing");
925
+ if (l.splitText !== void 0 && !["none", "word", "letter"].includes(l.splitText)) fail3(lt + ".splitText", "\u05E4\u05D9\u05E6\u05D5\u05DC \u05D8\u05E7\u05E1\u05D8 \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8");
926
+ if (l.transformOrigin !== void 0 && !["center", "left center", "right center", "center top", "center bottom"].includes(l.transformOrigin)) fail3(lt + ".transformOrigin", "\u05E0\u05E7\u05D5\u05D3\u05EA \u05E2\u05D9\u05D2\u05D5\u05DF \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8\u05EA");
927
+ if (l.blendMode !== void 0 && !["normal", "multiply", "screen", "overlay", "darken", "lighten"].includes(l.blendMode)) fail3(lt + ".blendMode", "\u05DE\u05E6\u05D1 \u05E9\u05D9\u05DC\u05D5\u05D1 \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8");
928
+ for (const [prop, min, max] of [["motionDuration", 0.01, 3600], ["motionDelay", 0, 3600], ["motionOutDuration", 0.01, 3600], ["stagger", 0, 5], ["borderWidth", 0, 1e3], ["letterSpacing", -100, 100], ["lineHeight", 0.5, 5], ["blur", 0, 100]]) if (l[prop] !== void 0) num(l[prop], `${lt}.${prop}`, min, max);
929
+ for (const prop of ["shadow", "borderColor"]) if (l[prop] !== void 0) text3(l[prop], `${lt}.${prop}`, 500);
930
+ num(l.start, lt + ".start", 0, sceneDuration);
931
+ num(l.duration, lt + ".duration", 0.01, 3600);
932
+ for (const field of ["keyframes", "textUnitKeyframes"]) if (l[field] !== void 0) {
933
+ if (field === "textUnitKeyframes" && l.type !== "text") fail3(lt + "." + field, "\u05EA\u05E0\u05D5\u05E2\u05EA \u05DE\u05D9\u05DC\u05D9\u05DD \u05D6\u05DE\u05D9\u05E0\u05D4 \u05DC\u05E9\u05DB\u05D1\u05EA \u05D8\u05E7\u05E1\u05D8 \u05D1\u05DC\u05D1\u05D3");
934
+ if (!Array.isArray(l[field]) || l[field].length < 2 || l[field].length > 100) fail3(lt + "." + field, "\u05E0\u05D3\u05E8\u05E9\u05D5\u05EA 2\u2013100 \u05E0\u05E7\u05D5\u05D3\u05D5\u05EA \u05EA\u05E0\u05D5\u05E2\u05D4");
935
+ else {
936
+ let previous = -1;
937
+ l[field].forEach((keyframe, k) => {
938
+ const kt = `${lt}.${field}.${k}`;
939
+ if (!record2(keyframe)) {
940
+ fail3(kt, "\u05E0\u05E7\u05D5\u05D3\u05EA \u05EA\u05E0\u05D5\u05E2\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D4");
941
+ return;
942
+ }
943
+ num(keyframe.at, kt + ".at", 0, l.duration);
944
+ if (typeof keyframe.at === "number" && keyframe.at <= previous) fail3(kt + ".at", "\u05E0\u05E7\u05D5\u05D3\u05D5\u05EA \u05D4\u05D6\u05DE\u05DF \u05D7\u05D9\u05D9\u05D1\u05D5\u05EA \u05DC\u05E2\u05DC\u05D5\u05EA");
945
+ previous = keyframe.at;
946
+ for (const property of ["x", "y"]) num(keyframe[property], kt + "." + property, -32768, 32768);
947
+ for (const property of ["scaleX", "scaleY"]) num(keyframe[property], kt + "." + property, 0, 100);
948
+ if (keyframe.scale !== void 0) num(keyframe.scale, kt + ".scale", 0, 100);
949
+ if (keyframe.easing !== void 0) easing(keyframe.easing, kt + ".easing");
950
+ num(keyframe.rotation, kt + ".rotation", -36e3, 36e3);
951
+ num(keyframe.opacity, kt + ".opacity", 0, 1);
952
+ if (keyframe.value !== void 0) num(keyframe.value, kt + ".value", -1e9, 1e9);
953
+ if (keyframe.reveal !== void 0) num(keyframe.reveal, kt + ".reveal", 0, 1);
954
+ if (keyframe.color !== void 0) hex2(keyframe.color, kt + ".color");
955
+ for (const prop of ["blur", "glow"]) if (keyframe[prop] !== void 0) num(keyframe[prop], `${kt}.${prop}`, 0, 100);
956
+ for (const prop of ["skewX", "skewY"]) if (keyframe[prop] !== void 0) num(keyframe[prop], `${kt}.${prop}`, -85, 85);
957
+ for (const prop of ["rotateX", "rotateY"]) if (keyframe[prop] !== void 0) num(keyframe[prop], `${kt}.${prop}`, -36e3, 36e3);
958
+ if (keyframe.clip !== void 0) clip(keyframe.clip, kt + ".clip");
959
+ if (keyframe.borderRadius !== void 0) num(keyframe.borderRadius, kt + ".borderRadius", 0, 16e3);
960
+ if (keyframe.letterSpacing !== void 0) num(keyframe.letterSpacing, kt + ".letterSpacing", -100, 100);
961
+ if (keyframe.snapToBeat !== void 0) bool(keyframe.snapToBeat, kt + ".snapToBeat");
962
+ });
963
+ }
964
+ }
965
+ if (["keyframes", "textUnitKeyframes"].some((field) => Array.isArray(l[field]) && l[field].some((point2) => record2(point2) && point2.color !== void 0)))
966
+ hex2(l.color, lt + ".color");
967
+ for (const prop of ["hidden", "locked"]) if (typeof l[prop] !== "boolean") fail3(`${lt}.${prop}`, "\u05E0\u05D3\u05E8\u05E9 \u05E2\u05E8\u05DA \u05D1\u05D5\u05DC\u05D9\u05D0\u05E0\u05D9");
968
+ if (l.assetId !== void 0 && !assetIds.has(l.assetId)) fail3(lt + ".assetId", "\u05D4\u05E0\u05DB\u05E1 \u05D7\u05E1\u05E8 \u05D1\u05E4\u05E8\u05D5\u05D9\u05E7\u05D8");
969
+ if (Array.isArray(l.children)) l.children.forEach((child, index) => validateLayer(child, `${lt}.children.${index}`, l.duration, l.children, depth + 1));
970
+ };
971
+ if (!Array.isArray(p.scenes) || p.scenes.length > 1e3 || p.mode === "authored" && !p.scenes.length) fail3("scenes", "\u05E8\u05E9\u05D9\u05DE\u05EA \u05E1\u05E6\u05E0\u05D5\u05EA \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D4");
972
+ else p.scenes.forEach((s, i) => {
973
+ const at = `scenes.${i}`;
974
+ if (!record2(s)) {
975
+ fail3(at, "\u05E1\u05E6\u05E0\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D4");
976
+ return;
977
+ }
978
+ id(s.id, at + ".id");
979
+ text3(s.name, at + ".name", 500);
980
+ text3(s.background, at + ".background", 500);
981
+ num(s.duration, at + ".duration", 0.01, 3600);
982
+ if (!["cut", "fade", "slide", "wipe", "zoom", "push", "iris", "diagonal-wipe", "whip", "zoom-through", "stack"].includes(s.transition)) fail3(at + ".transition", "\u05DE\u05E2\u05D1\u05E8 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF");
983
+ if (s.transitionDuration !== void 0) num(s.transitionDuration, at + ".transitionDuration", 0.01, s.duration);
984
+ if (s.transitionEasing !== void 0) easing(s.transitionEasing, at + ".transitionEasing");
985
+ if (s.configV3 !== void 0) {
986
+ const rt = at + ".configV3";
987
+ if (p.schemaVersion !== 3) fail3(rt, "\u05DE\u05EA\u05DB\u05D5\u05DF v3 \u05D3\u05D5\u05E8\u05E9 \u05E4\u05E8\u05D5\u05D9\u05E7\u05D8 \u05D1\u05D2\u05E8\u05E1\u05D4 3");
988
+ if (!record2(s.configV3) || ![Object.prototype, null].includes(Object.getPrototypeOf(s.configV3))) fail3(rt, "\u05DE\u05EA\u05DB\u05D5\u05DF v3 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF");
989
+ else {
990
+ known(s.configV3, rt, ["config", "sceneIndex"]);
991
+ try {
992
+ const config = parseMotionConfigV3(s.configV3.config);
993
+ integer(s.configV3.sceneIndex, rt + ".sceneIndex", 0, config.scenes.length - 1);
994
+ } catch (error) {
995
+ fail3(rt + ".config", error instanceof Error ? error.message : "\u05DE\u05EA\u05DB\u05D5\u05DF v3 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF");
996
+ }
997
+ }
998
+ }
999
+ if (s.camera !== void 0) {
1000
+ const ct = at + ".camera";
1001
+ if (!record2(s.camera)) fail3(ct, "\u05DE\u05E6\u05DC\u05DE\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D4");
1002
+ else {
1003
+ known(s.camera, ct, ["keyframes"]);
1004
+ if (!Array.isArray(s.camera.keyframes) || s.camera.keyframes.length < 1 || s.camera.keyframes.length > 100) fail3(ct + ".keyframes", "\u05E0\u05E7\u05D5\u05D3\u05D5\u05EA \u05DE\u05E6\u05DC\u05DE\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D5\u05EA");
1005
+ else {
1006
+ let previous = -1;
1007
+ s.camera.keyframes.forEach((frame, k) => {
1008
+ const ft = `${ct}.keyframes.${k}`;
1009
+ if (!record2(frame)) {
1010
+ fail3(ft, "\u05E0\u05E7\u05D5\u05D3\u05EA \u05DE\u05E6\u05DC\u05DE\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D4");
1011
+ return;
1012
+ }
1013
+ known(frame, ft, ["at", "x", "y", "zoom", "rotation", "easing"]);
1014
+ num(frame.at, ft + ".at", 0, s.duration);
1015
+ if (typeof frame.at === "number" && frame.at <= previous) fail3(ft + ".at", "\u05E0\u05E7\u05D5\u05D3\u05D5\u05EA \u05D4\u05D6\u05DE\u05DF \u05D7\u05D9\u05D9\u05D1\u05D5\u05EA \u05DC\u05E2\u05DC\u05D5\u05EA");
1016
+ previous = frame.at;
1017
+ num(frame.x, ft + ".x", -32768, 32768);
1018
+ num(frame.y, ft + ".y", -32768, 32768);
1019
+ num(frame.zoom, ft + ".zoom", 0.01, 100);
1020
+ num(frame.rotation, ft + ".rotation", -36e3, 36e3);
1021
+ if (frame.easing !== void 0) easing(frame.easing, ft + ".easing");
1022
+ });
1023
+ }
1024
+ }
1025
+ }
1026
+ if (!Array.isArray(s.layers) || s.layers.length > 1e3) {
1027
+ fail3(at + ".layers", "\u05E9\u05DB\u05D1\u05D5\u05EA \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D5\u05EA");
1028
+ return;
1029
+ }
1030
+ s.layers.forEach((l, j) => validateLayer(l, `${at}.layers.${j}`, s.duration, s.layers));
1031
+ });
1032
+ if (expandedLayers > 1e4) fail3("scenes", "\u05D9\u05D5\u05EA\u05E8 \u05DE\u05D3\u05D9 \u05E9\u05DB\u05D1\u05D5\u05EA \u05DC\u05D0\u05D7\u05E8 \u05E9\u05DB\u05E4\u05D5\u05DC");
1033
+ if (!Array.isArray(p.mediaTracks) || p.mediaTracks.length > 100) fail3("mediaTracks", "\u05E8\u05E6\u05D5\u05E2\u05D5\u05EA \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D5\u05EA");
1034
+ else p.mediaTracks.forEach((t, i) => {
1035
+ const at = `mediaTracks.${i}`;
1036
+ if (!record2(t)) {
1037
+ fail3(at, "\u05E8\u05E6\u05D5\u05E2\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D4");
1038
+ return;
1039
+ }
1040
+ id(t.id, at + ".id");
1041
+ text3(t.name, at + ".name", 500);
1042
+ if (!["video", "audio"].includes(t.type)) fail3(at + ".type", "\u05E1\u05D5\u05D2 \u05E8\u05E6\u05D5\u05E2\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF");
1043
+ if (typeof t.muted !== "boolean") fail3(at + ".muted", "\u05E0\u05D3\u05E8\u05E9 \u05E2\u05E8\u05DA \u05D1\u05D5\u05DC\u05D9\u05D0\u05E0\u05D9");
1044
+ if (!Array.isArray(t.clips) || t.clips.length > 1e4) {
1045
+ fail3(at + ".clips", "\u05E7\u05DC\u05D9\u05E4\u05D9\u05DD \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D9\u05DD");
1046
+ return;
1047
+ }
1048
+ t.clips.forEach((c, j) => {
1049
+ const ct = `${at}.clips.${j}`;
1050
+ if (!record2(c)) {
1051
+ fail3(ct, "\u05E7\u05DC\u05D9\u05E4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF");
1052
+ return;
1053
+ }
1054
+ id(c.id, ct + ".id");
1055
+ if (!assetIds.has(c.assetId)) fail3(ct + ".assetId", "\u05E0\u05DB\u05E1 \u05D4\u05E7\u05DC\u05D9\u05E4 \u05D7\u05E1\u05E8");
1056
+ num(c.start, ct + ".start", 0, 86400);
1057
+ num(c.in, ct + ".in", 0, 86400);
1058
+ num(c.out, ct + ".out", 0.01, 86400);
1059
+ num(c.volume, ct + ".volume", 0, 4);
1060
+ if (c.out <= c.in) fail3(ct + ".out", "\u05E1\u05D9\u05D5\u05DD \u05D7\u05D9\u05D9\u05D1 \u05DC\u05D4\u05D9\u05D5\u05EA \u05D0\u05D7\u05E8\u05D9 \u05D4\u05D4\u05EA\u05D7\u05DC\u05D4");
1061
+ const asset = Array.isArray(p.assets) ? p.assets.find((a) => a?.id === c.assetId) : void 0;
1062
+ if (asset?.duration !== void 0 && c.out > asset.duration + 1e-3) fail3(ct + ".out", "\u05E1\u05D9\u05D5\u05DD \u05DE\u05E2\u05D1\u05E8 \u05DC\u05D0\u05D5\u05E8\u05DA \u05D4\u05DE\u05E7\u05D5\u05E8");
1063
+ if (typeof c.muted !== "boolean") fail3(ct + ".muted", "\u05E0\u05D3\u05E8\u05E9 \u05E2\u05E8\u05DA \u05D1\u05D5\u05DC\u05D9\u05D0\u05E0\u05D9");
1064
+ });
1065
+ });
1066
+ if (p.beats !== void 0) {
1067
+ if (!Array.isArray(p.beats) || p.beats.length > 1e5) fail3("beats", "\u05E1\u05D9\u05DE\u05D5\u05E0\u05D9 \u05E7\u05E6\u05D1 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D9\u05DD");
1068
+ else {
1069
+ const sceneDuration = Array.isArray(p.scenes) ? p.scenes.reduce((sum, scene) => sum + (record2(scene) && typeof scene.duration === "number" && Number.isFinite(scene.duration) ? scene.duration : 0), 0) : 0;
1070
+ const mediaDuration = Array.isArray(p.mediaTracks) ? p.mediaTracks.reduce((longest, track) => Math.max(longest, record2(track) && Array.isArray(track.clips) ? track.clips.reduce((clipMax, item) => Math.max(clipMax, record2(item) && [item.start, item.in, item.out].every((v) => typeof v === "number" && Number.isFinite(v)) ? item.start + item.out - item.in : 0), 0) : 0), 0) : 0;
1071
+ const duration = Math.max(sceneDuration, mediaDuration, 0);
1072
+ let previous = -1;
1073
+ p.beats.forEach((beat, i) => {
1074
+ num(beat, `beats.${i}`, 0, duration);
1075
+ if (typeof beat === "number" && beat <= previous) fail3(`beats.${i}`, "\u05E1\u05D9\u05DE\u05D5\u05E0\u05D9 \u05E7\u05E6\u05D1 \u05D7\u05D9\u05D9\u05D1\u05D9\u05DD \u05DC\u05E2\u05DC\u05D5\u05EA \u05DC\u05DC\u05D0 \u05DB\u05E4\u05D9\u05DC\u05D5\u05D9\u05D5\u05EA");
1076
+ previous = typeof beat === "number" ? beat : previous;
1077
+ });
1078
+ }
1079
+ }
1080
+ if (p.source !== void 0) {
1081
+ if (!record2(p.source)) fail3("source", "\u05DE\u05E7\u05D5\u05E8 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF");
1082
+ else {
1083
+ if (p.source.sourceUrl !== void 0 && (typeof p.source.sourceUrl !== "string" || p.source.sourceUrl.startsWith("data:") || !isLocalAsset(p.source.sourceUrl))) fail3("source.sourceUrl", "\u05E0\u05D3\u05E8\u05E9 \u05DE\u05D6\u05D4\u05D4 \u05DE\u05E7\u05D5\u05E8 \u05DE\u05E7\u05D5\u05DE\u05D9");
1084
+ text3(p.source.filename, "source.filename", 500);
1085
+ text3(p.source.original, "source.original", 1e7);
1086
+ text3(p.source.current, "source.current", 1e7);
1087
+ if (p.source.execution !== "disabled") fail3("source.execution", "\u05D4\u05E8\u05E6\u05EA \u05DE\u05E7\u05D5\u05E8 \u05D7\u05D9\u05E6\u05D5\u05E0\u05D9 \u05D0\u05D9\u05E0\u05D4 \u05DE\u05D5\u05EA\u05E8\u05EA");
1088
+ if (!["html", "hyperframes"].includes(p.source.detectedEngine)) fail3("source.detectedEngine", "\u05DE\u05E0\u05D5\u05E2 \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8");
1089
+ if (!Array.isArray(p.source.warnings) || !p.source.warnings.every((w) => typeof w === "string")) fail3("source.warnings", "\u05D0\u05D6\u05D4\u05E8\u05D5\u05EA \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D5\u05EA");
1090
+ }
1091
+ }
1092
+ if (p.mode === "imported-source" && !p.source) fail3("source", "\u05DE\u05E7\u05D5\u05E8 \u05D7\u05E1\u05E8");
1093
+ return issues;
1094
+ }
1095
+ function projectWarnings(project) {
1096
+ if (project.schemaVersion !== 3 || !Array.isArray(project.scenes)) return [];
1097
+ const issues = [];
1098
+ const visit = (layers, path, parentHidden = false) => {
1099
+ layers.forEach((layer2, index) => {
1100
+ const at = `${path}.${index}`;
1101
+ const hidden = parentHidden || layer2.hidden;
1102
+ if (!hidden && layer2.type === "text" && layer2.textFit === "shrink" && typeof layer2.text === "string") {
1103
+ const rest = evaluateLayer(layer2, layer2.start + Math.max(0, layer2.duration * 0.8), { schemaVersion: project.schemaVersion, canvas: project.canvas, layers });
1104
+ const fontSize = Number.parseFloat(String(layerStyle(layer2, rest).fontSize));
1105
+ if (rest.visible && Number.isFinite(fontSize) && fontSize < 16)
1106
+ issues.push({ path: `${at}.text`, message: `\u05D4\u05D8\u05E7\u05E1\u05D8 \u201E${layer2.name}\u201D \u05E7\u05D8\u05DF \u05DE\u05BE16 \u05E4\u05D9\u05E7\u05E1\u05DC\u05D9\u05DD \u05DC\u05D0\u05D7\u05E8 \u05D4\u05EA\u05D0\u05DE\u05D4 \u05DC\u05DE\u05E1\u05D2\u05E8\u05EA. \u05E4\u05E6\u05DC \u05D0\u05EA \u05D4\u05EA\u05D5\u05DB\u05DF \u05DC\u05DB\u05DE\u05D4 \u05E1\u05E6\u05E0\u05D5\u05EA \u05D0\u05D5 \u05E7\u05E6\u05E8 \u05D0\u05EA \u05D4\u05E8\u05E9\u05D9\u05DE\u05D4.` });
1107
+ }
1108
+ if (layer2.type === "text" && layer2.textFit !== "shrink" && typeof layer2.text === "string" && Number.isFinite(layer2.width) && layer2.width > 0 && Number.isFinite(layer2.height) && layer2.height > 0 && Number.isFinite(layer2.fontSize) && layer2.fontSize > 0) {
1109
+ const charactersPerLine = Math.max(1, Math.floor(layer2.width / (layer2.fontSize * 0.55)));
1110
+ const requiredLines = layer2.text.split("\n").reduce((lines, part) => lines + Math.max(1, Math.ceil(Array.from(part).length / charactersPerLine)), 0);
1111
+ const lineHeight = typeof layer2.lineHeight === "number" && Number.isFinite(layer2.lineHeight) ? layer2.lineHeight : 1.2;
1112
+ if (requiredLines * layer2.fontSize * lineHeight > layer2.height * 1.05)
1113
+ issues.push({ path: `${at}.text`, message: "\u05D4\u05D8\u05E7\u05E1\u05D8 \u05E2\u05DC\u05D5\u05DC \u05DC\u05D7\u05E8\u05D5\u05D2 \u05DE\u05D2\u05D1\u05D5\u05DC\u05D5\u05EA \u05D4\u05EA\u05D9\u05D1\u05D4" });
1114
+ }
1115
+ if (Array.isArray(layer2.children)) visit(layer2.children, `${at}.children`, hidden);
1116
+ });
1117
+ };
1118
+ project.scenes.forEach((scene, index) => {
1119
+ if (Array.isArray(scene.layers)) visit(scene.layers, `scenes.${index}.layers`);
1120
+ });
1121
+ return issues;
1122
+ }
1123
+ function assertProject(value) {
1124
+ const issues = validateProject(value);
1125
+ if (issues.length) throw new Error(issues.slice(0, 5).map((issue) => `${issue.path}: ${issue.message}`).join("\n"));
1126
+ }
1127
+ function serializeProject(project) {
1128
+ return JSON.stringify(migrateProject(project), null, 2);
1129
+ }
1130
+ function parseProject(json) {
1131
+ if (json.length > 1e8) throw new Error("\u05E7\u05D5\u05D1\u05E5 \u05D4\u05E4\u05E8\u05D5\u05D9\u05E7\u05D8 \u05D2\u05D3\u05D5\u05DC \u05DE\u05D3\u05D9");
1132
+ const value = JSON.parse(json);
1133
+ return migrateProject(value);
1134
+ }
1135
+
1136
+ // src/core/scene-style.ts
1137
+ function sceneStyle(scene, progress, outgoing = false, schemaVersion = 2) {
1138
+ const p = Math.max(0, Math.min(1, progress));
1139
+ const ease = (p2, name = "smooth", seconds = 1) => {
1140
+ const t = Math.max(0, Math.min(1, p2));
1141
+ if (Array.isArray(name)) {
1142
+ const [x1, y1, x2, y2] = name;
1143
+ const curve = (u, a, b) => 3 * (1 - u) * (1 - u) * u * a + 3 * (1 - u) * u * u * b + u * u * u;
1144
+ let lo = 0, hi = 1;
1145
+ for (let i = 0; i < 24; i++) {
1146
+ const mid = (lo + hi) / 2;
1147
+ if (curve(mid, x1, x2) < t) lo = mid;
1148
+ else hi = mid;
1149
+ }
1150
+ return t === 0 || t === 1 ? t : curve((lo + hi) / 2, y1, y2);
1151
+ }
1152
+ if (typeof name === "object") {
1153
+ const { stiffness: k, damping: c, mass: m } = name, w = Math.sqrt(k / m), z = c / (2 * Math.sqrt(k * m));
1154
+ const response = (s) => {
1155
+ if (z < 1 - 1e-6) {
1156
+ const wd = w * Math.sqrt(1 - z * z);
1157
+ return 1 - Math.exp(-z * w * s) * (Math.cos(wd * s) + z * w / wd * Math.sin(wd * s));
1158
+ }
1159
+ if (z <= 1 + 1e-6) return 1 - Math.exp(-w * s) * (1 + w * s);
1160
+ const root = Math.sqrt(z * z - 1), r1 = -w / (z + root), r2 = -w * (z + root);
1161
+ return 1 - (r2 * Math.exp(r1 * s) - r1 * Math.exp(r2 * s)) / (r2 - r1);
1162
+ };
1163
+ const end = response(Math.max(1e-3, seconds));
1164
+ return t === 0 || t === 1 ? t : response(t * Math.max(1e-3, seconds)) + (1 - end) * t * t * (3 - 2 * t);
1165
+ }
1166
+ switch (name) {
1167
+ case "hold":
1168
+ return t === 1 ? 1 : 0;
1169
+ case "linear":
1170
+ return t;
1171
+ case "ease-in":
1172
+ return t * t * t;
1173
+ case "ease-out":
1174
+ return 1 - (1 - t) ** 3;
1175
+ case "ease-in-out":
1176
+ return t < 0.5 ? 4 * t ** 3 : 1 - (-2 * t + 2) ** 3 / 2;
1177
+ case "back":
1178
+ return 1 + 2.70158 * (t - 1) ** 3 + 1.70158 * (t - 1) ** 2;
1179
+ case "elastic":
1180
+ return t === 0 || t === 1 ? t : 2 ** (-10 * t) * Math.sin((t * 10 - 0.75) * 2 * Math.PI / 3) + 1;
1181
+ default:
1182
+ return t * t * (3 - 2 * t);
1183
+ }
1184
+ };
1185
+ const e = scene.transitionEasing ? ease(p, scene.transitionEasing, scene.transitionDuration ?? 0.5) : p * p * (3 - 2 * p);
1186
+ const rich = schemaVersion === 3 || ["iris", "diagonal-wipe", "whip", "zoom-through", "stack"].includes(scene.transition);
1187
+ const result = { opacity: 1, transform: "none", clipPath: "none", filter: "none" };
1188
+ if (outgoing) {
1189
+ if (scene.transition === "push") result.transform = `translateX(${-e * 100}%)`;
1190
+ if (scene.transition === "zoom") {
1191
+ result.transform = `scale(${1 + e * 0.2})`;
1192
+ result.opacity = 1 - e;
1193
+ }
1194
+ if (rich) {
1195
+ if (scene.transition === "fade") result.opacity = 1 - e;
1196
+ if (scene.transition === "slide") result.transform = `translateX(${-e * 30}%)`;
1197
+ if (scene.transition === "wipe") result.clipPath = `inset(0 0 0 ${e * 100}%)`;
1198
+ if (scene.transition === "iris") {
1199
+ result.transform = `scale(${1 - e * 0.08})`;
1200
+ result.opacity = 1 - e;
1201
+ }
1202
+ if (scene.transition === "diagonal-wipe") result.transform = `translate(${-e * 12}%,${e * 8}%)`;
1203
+ if (scene.transition === "whip") {
1204
+ result.transform = `translateX(${-e * 110}%) skewX(${-Math.sin(p * Math.PI) * 12}deg)`;
1205
+ result.filter = `blur(${Math.sin(p * Math.PI) * 18}px)`;
1206
+ }
1207
+ if (scene.transition === "zoom-through") {
1208
+ result.transform = `scale(${1 + e * 2.5})`;
1209
+ result.opacity = 1 - e;
1210
+ }
1211
+ if (scene.transition === "stack") {
1212
+ result.transform = `translateY(${-e * 8}%) scale(${1 - e * 0.12}) rotate(${-e * 5}deg)`;
1213
+ result.opacity = 1 - e * 0.6;
1214
+ }
1215
+ }
1216
+ return result;
1217
+ }
1218
+ if (scene.transition === "fade") result.opacity = e;
1219
+ if (scene.transition === "slide" || scene.transition === "push") result.transform = `translateX(${(1 - e) * 100}%)`;
1220
+ if (scene.transition === "wipe") result.clipPath = `inset(0 ${(1 - e) * 100}% 0 0)`;
1221
+ if (scene.transition === "zoom") {
1222
+ result.opacity = e;
1223
+ result.transform = `scale(${0.8 + e * 0.2})`;
1224
+ }
1225
+ if (scene.transition === "iris") result.clipPath = `circle(${Math.max(0, e) * 75}% at 50% 50%)`;
1226
+ if (scene.transition === "diagonal-wipe") {
1227
+ const x = e * 200;
1228
+ result.clipPath = `polygon(0 0, ${x}% 0, ${x - 100}% 100%, 0 100%)`;
1229
+ }
1230
+ if (scene.transition === "whip") {
1231
+ result.transform = `translateX(${(1 - e) * 110}%) skewX(${Math.sin(p * Math.PI) * 12}deg)`;
1232
+ result.filter = `blur(${Math.sin(p * Math.PI) * 18}px)`;
1233
+ }
1234
+ if (scene.transition === "zoom-through") {
1235
+ result.transform = `scale(${0.3 + e * 0.7})`;
1236
+ result.opacity = Math.max(0, Math.min(1, e));
1237
+ }
1238
+ if (scene.transition === "stack") {
1239
+ result.transform = `translateY(${(1 - e) * 100}%) rotate(${(1 - e) * 8}deg)`;
1240
+ result.opacity = Math.max(0, Math.min(1, e * 2));
1241
+ }
1242
+ if (rich && result.filter === void 0) result.filter = "none";
1243
+ return result;
1244
+ }
1245
+ function cameraStyle(scene, time, canvas, depth = 0) {
1246
+ const points = scene.camera?.keyframes;
1247
+ if (!points?.length) return {};
1248
+ const ease = (p, name = "smooth", seconds = 1) => {
1249
+ const t = Math.max(0, Math.min(1, p));
1250
+ if (Array.isArray(name)) {
1251
+ const [x1, y1, x2, y2] = name;
1252
+ const curve = (u2, a2, b2) => 3 * (1 - u2) * (1 - u2) * u2 * a2 + 3 * (1 - u2) * u2 * u2 * b2 + u2 * u2 * u2;
1253
+ let lo = 0, hi = 1;
1254
+ for (let i = 0; i < 24; i++) {
1255
+ const mid = (lo + hi) / 2;
1256
+ if (curve(mid, x1, x2) < t) lo = mid;
1257
+ else hi = mid;
1258
+ }
1259
+ return t === 0 || t === 1 ? t : curve((lo + hi) / 2, y1, y2);
1260
+ }
1261
+ if (typeof name === "object") {
1262
+ const { stiffness: k, damping: c, mass: m } = name, w = Math.sqrt(k / m), z = c / (2 * Math.sqrt(k * m));
1263
+ const response = (s) => {
1264
+ if (z < 1 - 1e-6) {
1265
+ const wd = w * Math.sqrt(1 - z * z);
1266
+ return 1 - Math.exp(-z * w * s) * (Math.cos(wd * s) + z * w / wd * Math.sin(wd * s));
1267
+ }
1268
+ if (z <= 1 + 1e-6) return 1 - Math.exp(-w * s) * (1 + w * s);
1269
+ const root = Math.sqrt(z * z - 1), r1 = -w / (z + root), r2 = -w * (z + root);
1270
+ return 1 - (r2 * Math.exp(r1 * s) - r1 * Math.exp(r2 * s)) / (r2 - r1);
1271
+ };
1272
+ const end = response(Math.max(1e-3, seconds));
1273
+ return t === 0 || t === 1 ? t : response(t * Math.max(1e-3, seconds)) + (1 - end) * t * t * (3 - 2 * t);
1274
+ }
1275
+ switch (name) {
1276
+ case "hold":
1277
+ return t === 1 ? 1 : 0;
1278
+ case "linear":
1279
+ return t;
1280
+ case "ease-in":
1281
+ return t * t * t;
1282
+ case "ease-out":
1283
+ return 1 - (1 - t) ** 3;
1284
+ case "ease-in-out":
1285
+ return t < 0.5 ? 4 * t ** 3 : 1 - (-2 * t + 2) ** 3 / 2;
1286
+ case "back":
1287
+ return 1 + 2.70158 * (t - 1) ** 3 + 1.70158 * (t - 1) ** 2;
1288
+ case "elastic":
1289
+ return t === 0 || t === 1 ? t : 2 ** (-10 * t) * Math.sin((t * 10 - 0.75) * 2 * Math.PI / 3) + 1;
1290
+ default:
1291
+ return t * t * (3 - 2 * t);
1292
+ }
1293
+ };
1294
+ let a = points[0], b = points[points.length - 1];
1295
+ if (time <= a.at) b = a;
1296
+ else if (time >= b.at) a = b;
1297
+ else for (let i = 0; i < points.length - 1; i++) if (time >= points[i].at && time <= points[i + 1].at) {
1298
+ a = points[i];
1299
+ b = points[i + 1];
1300
+ break;
1301
+ }
1302
+ const u = a === b ? 0 : ease((time - a.at) / (b.at - a.at), b.easing ?? "smooth", b.at - a.at), mix2 = (x2, y2) => x2 + (y2 - x2) * u;
1303
+ const factor = 1 - depth * 0.5;
1304
+ const x = mix2(a.x, b.x) * factor, y = mix2(a.y, b.y) * factor, zoom = Math.max(0.01, mix2(a.zoom, b.zoom)) ** factor, rotation = mix2(a.rotation, b.rotation) * factor;
1305
+ return { position: "absolute", inset: 0, transformOrigin: `${canvas.width / 2}px ${canvas.height / 2}px`, transform: `translate(${x}px,${y}px) rotate(${rotation}deg) scale(${zoom})` };
1306
+ }
1307
+
1308
+ // src/core/source.ts
1309
+ var escapeHtml = (value) => value.replace(/[&<>"']/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" })[c]);
1310
+ function analyzeSource(filename, html) {
1311
+ if (html.length > 1e7) throw new Error("\u05DE\u05E7\u05D5\u05E8 HTML \u05DE\u05D5\u05D2\u05D1\u05DC \u05DC\u05BE10 \u05DE\u05D2\u05D4");
1312
+ if (!/\.html?$/i.test(filename) || !/<(?:!doctype|html|head|body|div|section|main)\b/i.test(html)) throw new Error("\u05E0\u05D3\u05E8\u05E9 \u05E7\u05D5\u05D1\u05E5 HTML \u05EA\u05E7\u05D9\u05DF");
1313
+ const engine = /data-composition-id\s*=|\bhyperframes\b/i.test(html) ? "hyperframes" : "html";
1314
+ const externalReferences = [...new Set(html.match(/(?:https?:)?\/\/[^\s"'<>`)]+/gi) ?? [])];
1315
+ const warnings = ["\u05DE\u05E7\u05D5\u05E8 \u05D7\u05D9\u05E6\u05D5\u05E0\u05D9 \u05E0\u05E9\u05DE\u05E8 \u05DC\u05E2\u05E8\u05D9\u05DB\u05EA \u05E7\u05D5\u05D3; \u05D4\u05E8\u05E6\u05EA JavaScript \u05D5\u05EA\u05E6\u05D5\u05D2\u05EA \u05EA\u05E0\u05D5\u05E2\u05D4 \u05D7\u05E1\u05D5\u05DE\u05D5\u05EA.", "\u05E9\u05D3\u05D5\u05EA \u05D8\u05E7\u05E1\u05D8 \u05DE\u05D6\u05D5\u05D4\u05D9\u05DD \u05E8\u05E7 \u05DC\u05E4\u05D9 \u05DE\u05D6\u05D4\u05D9\u05DD \u05DE\u05E4\u05D5\u05E8\u05E9\u05D9\u05DD. \u05E9\u05D9\u05E0\u05D5\u05D9 \u05D8\u05E7\u05E1\u05D8 \u05D0\u05D9\u05E0\u05D5 \u05DE\u05DE\u05E4\u05D4 \u05D0\u05D5\u05D8\u05D5\u05DE\u05D8\u05D9\u05EA \u05E1\u05E6\u05E0\u05D5\u05EA \u05D5\u05EA\u05E0\u05D5\u05E2\u05D4."];
1316
+ if (externalReferences.length) warnings.push(`\u05E0\u05DE\u05E6\u05D0\u05D5 ${externalReferences.length} \u05D4\u05E4\u05E0\u05D9\u05D5\u05EA \u05D7\u05D9\u05E6\u05D5\u05E0\u05D9\u05D5\u05EA. \u05D9\u05E9 \u05DC\u05D4\u05D7\u05DC\u05D9\u05E4\u05DF \u05D1\u05E0\u05DB\u05E1\u05D9\u05DD \u05DE\u05E7\u05D5\u05DE\u05D9\u05D9\u05DD \u05DC\u05E4\u05E0\u05D9 \u05D4\u05E4\u05E7\u05D4 \u05D1\u05DE\u05E6\u05D1 \u05DE\u05E0\u05D5\u05EA\u05E7.`);
1317
+ if (/<(?:script|iframe|object|embed)\b|\son[a-z]+\s*=/i.test(html)) warnings.push("\u05D4\u05DE\u05E7\u05D5\u05E8 \u05DE\u05DB\u05D9\u05DC \u05EA\u05D5\u05DB\u05DF \u05E4\u05E2\u05D9\u05DC \u05E9\u05DC\u05D0 \u05D9\u05D1\u05D5\u05E6\u05E2 \u05D1\u05D9\u05D9\u05E9\u05D5\u05DD.");
1318
+ const masked = html.replace(/<!--[\s\S]*?-->|<(script|style|textarea|title)\b[^>]*>[\s\S]*?<\/\1\s*>/gi, (match) => " ".repeat(match.length));
1319
+ const textFields = [];
1320
+ const leaf = /<(h[1-6]|p|span|div|button|label|strong|em|a)\b([^<>]*)>([^<>]*)<\/\1\s*>/gi;
1321
+ for (const match of masked.matchAll(leaf)) {
1322
+ const id = /(?:^|\s)id\s*=\s*(["'])([a-zA-Z0-9_-]+)\1/i.exec(match[2]);
1323
+ if (id && match[3].trim()) textFields.push({ id: id[2], tag: match[1], text: decodeText(match[3]) });
1324
+ }
1325
+ const allIds = Array.from(masked.matchAll(/<[a-z][^<>]*?\s+id\s*=\s*(["'])([a-zA-Z0-9_-]+)\1/gi), (match) => match[2]);
1326
+ const unique = textFields.filter((field) => allIds.filter((id) => id === field.id).length === 1);
1327
+ return { mode: "imported-source", structuredEditing: false, sourceEditing: true, videoEditing: false, executablePreview: false, warnings, engine, externalReferences, textFields: unique };
1328
+ }
1329
+ function decodeText(text3) {
1330
+ return text3.replace(/&(#x[\da-f]+|#\d+|amp|lt|gt|quot|apos|nbsp);/gi, (full, entity) => {
1331
+ const named = { amp: "&", lt: "<", gt: ">", quot: '"', apos: "'", nbsp: " " };
1332
+ if (named[entity.toLowerCase()]) return named[entity.toLowerCase()];
1333
+ const point2 = entity.startsWith("#x") ? parseInt(entity.slice(2), 16) : parseInt(entity.slice(1), 10);
1334
+ return point2 > 0 && point2 <= 1114111 ? String.fromCodePoint(point2) : full;
1335
+ });
1336
+ }
1337
+ function importHtmlSource(filename, html) {
1338
+ const report = analyzeSource(filename, html);
1339
+ return {
1340
+ ...createProject(filename.replace(/\.html?$/i, ""), { mode: "imported-source", scenes: [] }),
1341
+ source: { filename, original: html, current: html, detectedEngine: report.engine, execution: "disabled", warnings: report.warnings }
1342
+ };
1343
+ }
1344
+ function updateSourceText(project, id, text3) {
1345
+ if (!project.source) throw new Error("\u05D0\u05D9\u05DF \u05DE\u05E7\u05D5\u05E8 HTML");
1346
+ const report = analyzeSource(project.source.filename, project.source.current);
1347
+ if (!report.textFields.some((field) => field.id === id)) throw new Error("\u05D4\u05E9\u05D3\u05D4 \u05D0\u05D9\u05E0\u05D5 \u05DE\u05D6\u05D5\u05D4\u05D4 \u05D1\u05D0\u05D5\u05E4\u05DF \u05D7\u05D3\u05BE\u05DE\u05E9\u05DE\u05E2\u05D9");
1348
+ const leaf = /<(h[1-6]|p|span|div|button|label|strong|em|a)\b([^<>]*)>([^<>]*)<\/\1\s*>/gi;
1349
+ const masked = project.source.current.replace(/<!--[\s\S]*?-->|<(script|style|textarea|title)\b[^>]*>[\s\S]*?<\/\1\s*>/gi, (match) => " ".repeat(match.length));
1350
+ let current = project.source.current;
1351
+ for (const match of masked.matchAll(leaf)) {
1352
+ const matchId = /(?:^|\s)id\s*=\s*(["'])([a-zA-Z0-9_-]+)\1/i.exec(match[2]);
1353
+ if (matchId?.[2] === id) {
1354
+ const start = match.index + match[0].indexOf(">") + 1;
1355
+ current = current.slice(0, start) + escapeHtml(text3) + current.slice(start + match[3].length);
1356
+ break;
1357
+ }
1358
+ }
1359
+ return commitProject({ ...project, source: { ...project.source, current } });
1360
+ }
1361
+ function sourcePreviewHtml(html) {
1362
+ return `<!doctype html><html dir="rtl"><head><meta charset="utf-8"><meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'"><style>body{background:#101624;color:#ced8e9;font:14px monospace;padding:24px}pre{white-space:pre-wrap;direction:ltr;text-align:left}h2{font:18px Arial}</style></head><body><h2>\u05EA\u05E6\u05D5\u05D2\u05EA \u05DE\u05E7\u05D5\u05E8 \u05D1\u05D8\u05D5\u05D7\u05D4 \u2014 \u05D4\u05E8\u05E6\u05EA \u05E7\u05D5\u05D3 \u05DB\u05D1\u05D5\u05D9\u05D4</h2><pre>${escapeHtml(html)}</pre></body></html>`;
1363
+ }
1364
+
1365
+ // src/core/font-data.ts
1366
+ var heeboFontCss = "@font-face{font-family:Heebo;src:url(data:font/woff2;base64,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) format('woff2');font-weight:400;font-style:normal;unicode-range:U+0000-058F,U+0600-FB1C,U+FB50-10FFFF;}@font-face{font-family:Heebo;src:url(data:font/woff2;base64,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) format('woff2');font-weight:400;font-style:normal;unicode-range:U+0590-05FF,U+FB1D-FB4F;}@font-face{font-family:Heebo;src:url(data:font/woff2;base64,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) format('woff2');font-weight:700;font-style:normal;unicode-range:U+0000-058F,U+0600-FB1C,U+FB50-10FFFF;}@font-face{font-family:Heebo;src:url(data:font/woff2;base64,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) format('woff2');font-weight:700;font-style:normal;unicode-range:U+0590-05FF,U+FB1D-FB4F;}";
1367
+
1368
+ // src/core/symbol-font-data.ts
1369
+ var symbolFontCss = '@font-face{font-family:"MotionDesk Symbols";src:url(data:font/ttf;base64,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) format("truetype");font-weight:400;font-style:normal;unicode-range:U+2190-21FF,U+25A0-25FF,U+2700-27BF;}';
1370
+
1371
+ // src/core/repeater.ts
1372
+ function repeaterLayers(layer2) {
1373
+ const r = layer2.repeater;
1374
+ if (layer2.type !== "repeater" || !r) return [];
1375
+ const random = (i, salt) => {
1376
+ let x = r.seed ^ Math.imul(i + 1, 374761393) ^ Math.imul(salt, 668265263) | 0;
1377
+ x = Math.imul(x ^ x >>> 13, 1274126177);
1378
+ return ((x ^ x >>> 16) >>> 0) / 4294967296;
1379
+ };
1380
+ return Array.from({ length: r.count }, (_, i) => {
1381
+ const delay = i * r.delay + random(i, 4) * (r.jitterDelay ?? 0);
1382
+ const copy = {
1383
+ ...layer2,
1384
+ id: `${layer2.id}_repeat_${i}`,
1385
+ type: "shape",
1386
+ x: i * r.offsetX + (random(i, 1) * 2 - 1) * (r.jitterX ?? 0),
1387
+ y: i * r.offsetY + (random(i, 2) * 2 - 1) * (r.jitterY ?? 0),
1388
+ start: delay,
1389
+ duration: Math.max(0.01, layer2.duration - delay),
1390
+ rotation: i * r.rotation + (random(i, 3) * 2 - 1) * (r.jitterRotation ?? 0) + (r.shape === "diamond" ? 45 : 0),
1391
+ opacity: 1,
1392
+ color: r.colors?.[i % r.colors.length] ?? layer2.color,
1393
+ borderRadius: r.shape === "ellipse" ? Math.max(layer2.width, layer2.height) : layer2.borderRadius
1394
+ };
1395
+ delete copy.repeater;
1396
+ delete copy.depth;
1397
+ delete copy.revealBinding;
1398
+ return copy;
1399
+ });
1400
+ }
1401
+
1402
+ // src/core/compiler.ts
1403
+ function compileProjectHtml(project) {
1404
+ assertProject(project);
1405
+ if (project.mode === "imported-source") throw new Error("\u05DE\u05E7\u05D5\u05E8 \u05D7\u05D9\u05E6\u05D5\u05E0\u05D9 \u05E0\u05D9\u05EA\u05DF \u05DC\u05D9\u05D9\u05E6\u05D0 \u05DB\u05E7\u05D5\u05D3 \u05D1\u05DC\u05D1\u05D3; \u05D4\u05E4\u05E7\u05EA \u05E0\u05D2\u05DF \u05D3\u05D5\u05E8\u05E9\u05EA \u05E4\u05E8\u05D5\u05D9\u05E7\u05D8 \u05DE\u05D5\u05D1\u05E0\u05D4");
1406
+ const json = JSON.stringify(project).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
1407
+ return `<!doctype html>
1408
+ <html lang="he" dir="rtl"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
1409
+ <meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src data: blob: motiondesk-media: 'self'; media-src data: blob: motiondesk-media: 'self'; font-src data: 'self'; connect-src 'none'; base-uri 'none'; form-action 'none'">
1410
+ <title>${escapeHtml(project.title)}</title><style>${heeboFontCss}${symbolFontCss}
1411
+ *{box-sizing:border-box}html,body{margin:0;width:100%;height:100%;overflow:hidden;background:#000}#stage{position:absolute;overflow:hidden;transform-origin:top left;direction:rtl}.scene,.media{position:absolute;inset:0}.layer{position:absolute;display:flex;align-items:center;justify-content:center;white-space:pre-wrap;overflow-wrap:anywhere;overflow:hidden;transform-origin:center}.layer img,.layer video{width:100%;height:100%;object-fit:cover}.media video{width:100%;height:100%;object-fit:contain}.scene{pointer-events:none}
1412
+ </style></head><body><main id="stage" aria-label="${escapeHtml(project.title)}"></main>
1413
+ <script type="application/json" id="motiondesk-project">${json}</script>
1414
+ <script>(()=>{'use strict';
1415
+ const project=JSON.parse(document.getElementById('motiondesk-project').textContent),duration=${projectDuration(project)};
1416
+ const evaluateLayer=${evaluateLayer.toString()};
1417
+ const layerStyle=${layerStyle.toString()};
1418
+ const textUnitStyle=${textUnitStyle.toString()};
1419
+ const textLineStyle=${textLineStyle.toString()};
1420
+ const sceneStyle=${sceneStyle.toString()};
1421
+ const cameraStyle=${cameraStyle.toString()};
1422
+ const repeaterLayers=${repeaterLayers.toString()};
1423
+ const stage=document.getElementById('stage');stage.style.width=project.canvas.width+'px';stage.style.height=project.canvas.height+'px';
1424
+ const assets=new Map(project.assets.map(a=>[a.id,a]));const sceneNodes=[];const mediaNodes=[];
1425
+ function resize(){const scale=Math.min(innerWidth/project.canvas.width,innerHeight/project.canvas.height);stage.style.transform='scale('+scale+')';stage.style.left=(innerWidth-project.canvas.width*scale)/2+'px';stage.style.top=(innerHeight-project.canvas.height*scale)/2+'px'}addEventListener('resize',resize);resize();
1426
+ for(const track of project.mediaTracks){for(const clip of track.clips){const asset=assets.get(clip.assetId);if(!asset)continue;const el=document.createElement(track.type==='video'?'video':'audio');el.src=asset.src;el.preload='auto';el.muted=track.muted||clip.muted;el.volume=Math.min(1,clip.volume);if(track.type==='video'){const wrap=document.createElement('div');wrap.className='media';wrap.append(el);stage.append(wrap)}else{el.hidden=true;stage.append(el)}mediaNodes.push({el,clip,track})}}
1427
+ function addLayer(parent,layer,layers){
1428
+ const node=document.createElement('div');node.className='layer';node.dataset.layerId=layer.id;
1429
+ if(layer.type==='text')node.textContent=layer.text||'';
1430
+ if(layer.type==='path'||layer.type==='svg'){
1431
+ const svg=document.createElementNS('http://www.w3.org/2000/svg','svg');svg.setAttribute('viewBox','0 0 '+layer.width+' '+layer.height);svg.setAttribute('width','100%');svg.setAttribute('height','100%');
1432
+ const path=document.createElementNS('http://www.w3.org/2000/svg','path');path.setAttribute('d',layer.pathData||'');path.setAttribute('fill',layer.type==='svg'?layer.color:'none');path.setAttribute('stroke',layer.stroke||layer.color);path.setAttribute('stroke-width',String(layer.strokeWidth||3));svg.append(path);node.append(svg);
1433
+ }
1434
+ if(layer.type==='image'||layer.type==='video'){const asset=assets.get(layer.assetId);if(asset){const media=document.createElement(layer.type==='image'?'img':'video');media.src=asset.src;if(layer.type==='video'){media.muted=true;media.preload='auto'}node.append(media)}}
1435
+ const entry={layer,node,children:[]};layers.push(entry);parent.append(node);
1436
+ if(layer.type==='group'||layer.type==='repeater')for(const child of layer.type==='repeater'?repeaterLayers(layer):layer.children||[])addLayer(node,child,entry.children);
1437
+ }
1438
+ let sceneStart=0;for(const scene of project.scenes){const el=document.createElement('section');el.className='scene';const layers=[];for(const layer of scene.layers){let parent=el;if(scene.camera){parent=document.createElement('div');parent.dataset.cameraDepth=String(layer.depth||0);el.append(parent);}addLayer(parent,layer,layers);if(scene.camera)layers[layers.length-1].plane=parent;}stage.append(el);sceneNodes.push({scene,el,layers,start:sceneStart});sceneStart+=scene.duration}
1439
+ let time=0,playing=false,last=0,messageRevision=0;
1440
+ function positionMedia(el,target,active){el.style.visibility=active?'visible':'hidden';if(!active){el.pause();return}if(Number.isFinite(el.duration)&&Math.abs(el.currentTime-target)>0.06)el.currentTime=Math.min(target,Math.max(0,el.duration-0.001));if(playing)el.play().catch(()=>{});else el.pause()}
1441
+ function paintLayer(entry,local,context){
1442
+ const {layer,node}=entry;const frame=evaluateLayer(layer,local,context);Object.assign(node.style,layerStyle(layer,frame));
1443
+ if(layer.type==='text'){
1444
+ if(frame.textUnits){
1445
+ if(!entry.textLine){entry.textLine=document.createElement('span');Object.assign(entry.textLine.style,textLineStyle(layer));node.replaceChildren(entry.textLine);}
1446
+ const line=entry.textLine;
1447
+ while(line.children.length>frame.textUnits.length)line.lastChild.remove();
1448
+ frame.textUnits.forEach((unit,index)=>{let span=line.children[index];if(!span){span=document.createElement('span');line.append(span);}if(span.textContent!==unit.text)span.textContent=unit.text;Object.assign(span.style,textUnitStyle(unit));});
1449
+ }
1450
+ else if(node.textContent!==frame.text)node.textContent=frame.text;
1451
+ }
1452
+ const path=node.querySelector(':scope > svg > path');if(path){path.setAttribute('pathLength','1');path.setAttribute('stroke-dasharray','1');path.setAttribute('stroke-dashoffset',String(1-frame.reveal));path.setAttribute('stroke',frame.color||layer.stroke||layer.color);if(layer.type==='svg')path.setAttribute('fill',frame.color||layer.color);}
1453
+ const video=node.querySelector(':scope > video');if(video)positionMedia(video,Math.max(0,local-layer.start),frame.visible);
1454
+ for(const child of entry.children)paintLayer(child,local-layer.start,{...context,sceneStart:context.sceneStart+layer.start,layers:layer.type==='repeater'?entry.children.map(c=>c.layer):layer.children});
1455
+ }
1456
+ function paint(t){
1457
+ time=Math.max(0,Math.min(duration,t));
1458
+ if(project.schemaVersion===3){const index=sceneNodes.findIndex(entry=>time>=entry.start&&time<entry.start+entry.scene.duration);const active=sceneNodes[index];const transitioning=active&&index>0&&active.scene.transition!=='cut'&&time<active.start+Math.min(active.scene.transitionDuration||.5,active.scene.duration/2);stage.style.background=(transitioning?sceneNodes[index-1].scene.background:active?.scene.background)||'#000';}
1459
+ for(let i=0;i<sceneNodes.length;i++){
1460
+ const entry=sceneNodes[i],next=sceneNodes[i+1];
1461
+ const incoming=time>=entry.start&&time<entry.start+entry.scene.duration;
1462
+ const nextDuration=next?Math.min(next.scene.transitionDuration||.5,next.scene.duration/2):0;
1463
+ const outgoing=next&&next.scene.transition!=='cut'&&time>=next.start&&time<next.start+nextDuration;
1464
+ entry.el.style.display=incoming||outgoing?'block':'none';
1465
+ if(!incoming&&!outgoing){for(const video of entry.el.querySelectorAll('video'))video.pause();continue}
1466
+ const local=outgoing?(project.schemaVersion===3?entry.scene.duration-.001:entry.scene.duration-nextDuration+(time-next.start)):time-entry.start;
1467
+ const spec=outgoing?next.scene:entry.scene;
1468
+ const d=outgoing?nextDuration:Math.min(spec.transitionDuration||.5,spec.duration/2);
1469
+ const progress=outgoing?(time-next.start)/d:local/d;
1470
+ Object.assign(entry.el.style,sceneStyle(spec,progress,!!outgoing,project.schemaVersion));
1471
+ entry.el.style.background=entry.scene.background;
1472
+ const context={canvas:project.canvas,schemaVersion:project.schemaVersion,beats:project.beats,sceneStart:entry.start,layers:entry.scene.layers};
1473
+ for(const layer of entry.layers){if(layer.plane)Object.assign(layer.plane.style,cameraStyle(entry.scene,local,project.canvas,layer.layer.depth||0));paintLayer(layer,local,context);}
1474
+ }
1475
+ for(const {el,clip} of mediaNodes)positionMedia(el,clip.in+time-clip.start,time>=clip.start&&time<clip.start+clip.out-clip.in)
1476
+ }
1477
+ async function seek(t){playing=false;paint(t);await Promise.all(Array.from(document.querySelectorAll('video')).filter(v=>v.seeking).map(v=>new Promise(resolve=>{v.addEventListener('seeked',resolve,{once:true});setTimeout(resolve,1500)})));return time}
1478
+ function tick(now){if(playing){paint(time+(now-last)/1000);if(time>=duration){playing=false;for(const el of document.querySelectorAll('video,audio'))el.pause()}}last=now;requestAnimationFrame(tick)}
1479
+ window.__motiondesk={seek,play(){playing=true;last=performance.now()},pause(){playing=false;for(const el of document.querySelectorAll('video,audio'))el.pause()},get time(){return time},duration,project};
1480
+ addEventListener('message',event=>{if(event.source!==parent||event.data?.type!=='motiondesk:seek'||typeof event.data.time!=='number'||!Number.isFinite(event.data.time))return;const revision=++messageRevision;seek(event.data.time).then(()=>{if(revision===messageRevision&&event.data.playing)window.__motiondesk.play()})});
1481
+ window.__motiondeskReady=Promise.all([...Array.from(document.images).map(img=>img.decode().catch(()=>{})),...Array.from(document.querySelectorAll('video,audio')).map(el=>el.readyState>=1?Promise.resolve():new Promise(resolve=>{el.addEventListener('loadedmetadata',resolve,{once:true});el.addEventListener('error',resolve,{once:true});setTimeout(resolve,3000)}))]).then(()=>document.fonts.ready).then(()=>{paint(0);return true});paint(0);requestAnimationFrame(tick);document.addEventListener('keydown',e=>{if(e.code==='Space'){e.preventDefault();playing=!playing}});
1482
+ })();</script></body></html>`;
1483
+ }
1484
+ function importStructuredHtml(html) {
1485
+ const match = /<script\b(?=[^>]*\bid=["']motiondesk-project["'])(?=[^>]*\btype=["']application\/json["'])[^>]*>([\s\S]*?)<\/script\s*>/i.exec(html);
1486
+ if (!match) return null;
1487
+ const parsed = parseProject(match[1]);
1488
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1489
+ return { ...parsed, id: newId("project"), revision: 0, createdAt: now, updatedAt: now };
1490
+ }
1491
+
1492
+ // src/core/media.ts
1493
+ function createMediaRenderPlan(project, options) {
1494
+ assertProject(project);
1495
+ const duration = projectDuration(project);
1496
+ if (duration <= 0) throw new Error("\u05D0\u05D9\u05DF \u05EA\u05D5\u05DB\u05DF \u05DC\u05D4\u05E4\u05E7\u05D4");
1497
+ if (project.mode === "imported-source") throw new Error("\u05DC\u05D0 \u05E0\u05D9\u05EA\u05DF \u05DC\u05D4\u05E4\u05D9\u05E7 \u05DE\u05E7\u05D5\u05E8 \u05D7\u05D9\u05E6\u05D5\u05E0\u05D9 \u05E9\u05D8\u05E8\u05DD \u05DE\u05D5\u05E4\u05D4");
1498
+ if (project.canvas.width % 2 || project.canvas.height % 2) throw new Error("\u05D9\u05E6\u05D5\u05D0 MP4 \u05D3\u05D5\u05E8\u05E9 \u05DE\u05D9\u05D3\u05D5\u05EA \u05D6\u05D5\u05D2\u05D9\u05D5\u05EA");
1499
+ const clips = project.mediaTracks.flatMap((track) => track.clips.map((clip) => ({ track, clip })));
1500
+ const missingAssets = [...new Set(clips.filter(({ clip }) => !options.inputs[clip.assetId]).map(({ clip }) => clip.assetId))];
1501
+ if (missingAssets.length) return { args: [], duration, missingAssets };
1502
+ const num = (value) => Number(value.toFixed(6)).toString();
1503
+ const { width, height, fps } = project.canvas;
1504
+ const args = ["-hide_banner", "-y", "-f", "lavfi", "-i", `color=c=black:s=${width}x${height}:r=${fps}:d=${num(duration)}`];
1505
+ const filters = ["[0:v]format=yuv420p[base0]"];
1506
+ let inputIndex = 1, videoIndex = 0;
1507
+ const audioLabels = [];
1508
+ for (const { track, clip } of clips) {
1509
+ const input = options.inputs[clip.assetId];
1510
+ const idx = inputIndex++;
1511
+ args.push("-i", input.path);
1512
+ const length = clip.out - clip.in;
1513
+ if (track.type === "video") {
1514
+ filters.push(`[${idx}:v]trim=start=${num(clip.in)}:end=${num(clip.out)},setpts=PTS-STARTPTS+${num(clip.start)}/TB,scale=${width}:${height}:force_original_aspect_ratio=decrease,pad=${width}:${height}:(ow-iw)/2:(oh-ih)/2:black,setsar=1,fps=${fps}[v${idx}]`);
1515
+ filters.push(`[base${videoIndex}][v${idx}]overlay=eof_action=pass:enable='gte(t,${num(clip.start)})*lt(t,${num(clip.start + length)})'[base${videoIndex + 1}]`);
1516
+ videoIndex++;
1517
+ }
1518
+ if (!track.muted && !clip.muted && clip.volume > 0 && (track.type === "audio" || input.hasAudio)) {
1519
+ const label = `a${idx}`;
1520
+ const delay = Math.round(clip.start * 1e3);
1521
+ filters.push(`[${idx}:a]atrim=start=${num(clip.in)}:end=${num(clip.out)},asetpts=PTS-STARTPTS,volume=${num(clip.volume)},aresample=48000,adelay=${delay}:all=1[${label}]`);
1522
+ audioLabels.push(`[${label}]`);
1523
+ }
1524
+ }
1525
+ for (const overlay of options.overlays ?? []) {
1526
+ if (![overlay.start, overlay.end, overlay.x, overlay.y, overlay.width, overlay.height].every(Number.isFinite) || overlay.start < 0 || overlay.end <= overlay.start || overlay.width < 1 || overlay.height < 1) throw new Error("\u05E9\u05DB\u05D1\u05EA \u05EA\u05DE\u05D5\u05E0\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D4");
1527
+ const idx = inputIndex++;
1528
+ args.push("-loop", "1", "-i", overlay.path);
1529
+ filters.push(`[${idx}:v]scale=${num(overlay.width)}:${num(overlay.height)},format=rgba[ov${idx}]`);
1530
+ filters.push(`[base${videoIndex}][ov${idx}]overlay=x=${num(overlay.x)}:y=${num(overlay.y)}:eof_action=pass:enable='gte(t,${num(overlay.start)})*lt(t,${num(overlay.end)})'[base${videoIndex + 1}]`);
1531
+ videoIndex++;
1532
+ }
1533
+ if (audioLabels.length) filters.push(`${audioLabels.join("")}amix=inputs=${audioLabels.length}:normalize=0:duration=longest,apad,atrim=duration=${num(duration)}[audio]`);
1534
+ args.push("-filter_complex", filters.join(";"), "-map", `[base${videoIndex}]`);
1535
+ if (audioLabels.length) args.push("-map", "[audio]", "-c:a", "aac", "-b:a", "192k");
1536
+ args.push("-c:v", "libx264", "-preset", "medium", "-crf", "20", "-pix_fmt", "yuv420p", "-r", String(fps), "-t", num(duration), "-movflags", "+faststart", options.output);
1537
+ return { args, duration, missingAssets };
1538
+ }
1539
+
1540
+ // src/core/source-adapter.ts
1541
+ var SOURCE_ADAPTER_DEFINITIONS = [{
1542
+ id: "bank-growth-gsap-v1",
1543
+ compositionId: "bank-growth",
1544
+ sceneIds: ["s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8"],
1545
+ timingProfile: "gsap-bo-bn-v1",
1546
+ literalCalls: [{ name: "caption", argument: 1, encoding: "js-text" }, { name: "chip", argument: 1, encoding: "js-html" }, { name: "el", argument: 3, encoding: "js-html" }, { name: "photo", argument: 1, encoding: "js-asset" }]
1547
+ }];
1548
+ var decode = (s) => s.replace(/&(#x[\da-f]+|#\d+|amp|lt|gt|quot|apos|nbsp);/gi, (full, c) => {
1549
+ const names = { amp: "&", lt: "<", gt: ">", quot: '"', apos: "'", nbsp: " " };
1550
+ if (names[c.toLowerCase()]) return names[c.toLowerCase()];
1551
+ const point2 = c.toLowerCase().startsWith("#x") ? parseInt(c.slice(2), 16) : parseInt(c.slice(1), 10);
1552
+ return point2 > 0 && point2 <= 1114111 ? String.fromCodePoint(point2) : full;
1553
+ });
1554
+ function sourceFingerprint(html) {
1555
+ let hash = 2166136261;
1556
+ for (let i = 0; i < html.length; i++) {
1557
+ hash ^= html.charCodeAt(i);
1558
+ hash = Math.imul(hash, 16777619);
1559
+ }
1560
+ return `${html.length.toString(36)}-${(hash >>> 0).toString(16)}`;
1561
+ }
1562
+ function elements(html) {
1563
+ const result = [], stack = [];
1564
+ const re = /<!--[\s\S]*?-->|<\/?[a-zA-Z][^>"']*(?:(?:"[^"]*"|'[^']*')[^>"']*)*>/g;
1565
+ let m;
1566
+ while (m = re.exec(html)) {
1567
+ if (m[0].startsWith("<!--")) continue;
1568
+ const tag = /^<\/?([a-zA-Z][\w:-]*)/.exec(m[0])[1].toLowerCase();
1569
+ if (m[0].startsWith("</")) {
1570
+ const idx = stack.map((n) => n.tag).lastIndexOf(tag);
1571
+ if (idx >= 0) {
1572
+ for (const node2 of stack.splice(idx)) {
1573
+ node2.contentEnd = m.index;
1574
+ node2.end = re.lastIndex;
1575
+ }
1576
+ }
1577
+ continue;
1578
+ }
1579
+ const node = { tag, start: m.index, end: re.lastIndex, contentStart: re.lastIndex, contentEnd: re.lastIndex, attrs: {}, parent: stack.at(-1) };
1580
+ const attrs = /\s+([\w:-]+)\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/g;
1581
+ for (const attr of m[0].matchAll(attrs)) {
1582
+ const value = attr[2] ?? attr[3] ?? attr[4], offset = attr[0].indexOf("=") + 1;
1583
+ const local = attr[0].slice(offset).search(/\S/);
1584
+ const quote = attr[0][offset + local];
1585
+ const start = m.index + attr.index + offset + local + (quote === '"' || quote === "'" ? 1 : 0);
1586
+ node.attrs[attr[1].toLowerCase()] = { value, start, end: start + value.length };
1587
+ }
1588
+ result.push(node);
1589
+ if (["script", "style", "textarea", "title"].includes(tag)) {
1590
+ const close = new RegExp(`</${tag}\\s*>`, "ig");
1591
+ close.lastIndex = re.lastIndex;
1592
+ const end = close.exec(html);
1593
+ node.contentEnd = end?.index ?? html.length;
1594
+ node.end = end ? close.lastIndex : html.length;
1595
+ re.lastIndex = node.end;
1596
+ } else if (!/\/>$/.test(m[0]) && !["img", "input", "meta", "link", "br", "hr", "source", "area", "base", "embed", "param", "track", "wbr"].includes(tag)) stack.push(node);
1597
+ }
1598
+ return result;
1599
+ }
1600
+ function tokens(code, offset) {
1601
+ const out = [];
1602
+ for (let i = 0; i < code.length; ) {
1603
+ if (/\s/.test(code[i])) {
1604
+ i++;
1605
+ continue;
1606
+ }
1607
+ if (code.startsWith("//", i)) {
1608
+ i = code.indexOf("\n", i + 2);
1609
+ if (i < 0) break;
1610
+ continue;
1611
+ }
1612
+ if (code.startsWith("/*", i)) {
1613
+ const end = code.indexOf("*/", i + 2);
1614
+ i = end < 0 ? code.length : end + 2;
1615
+ continue;
1616
+ }
1617
+ const start = i, quote = code[i];
1618
+ if (quote === '"' || quote === "'" || quote === "`") {
1619
+ i++;
1620
+ let value = "", valid = quote !== "`";
1621
+ while (i < code.length && code[i] !== quote) {
1622
+ if (code[i] === "\\") {
1623
+ i++;
1624
+ const escaped = code[i++];
1625
+ if (escaped === "n") value += "\n";
1626
+ else if (escaped === "r") value += "\r";
1627
+ else if (escaped === "t") value += " ";
1628
+ else if (escaped === "u" && /^[0-9a-fA-F]{4}/.test(code.slice(i))) {
1629
+ value += String.fromCharCode(parseInt(code.slice(i, i + 4), 16));
1630
+ i += 4;
1631
+ } else if (escaped === "x" && /^[0-9a-fA-F]{2}/.test(code.slice(i))) {
1632
+ value += String.fromCharCode(parseInt(code.slice(i, i + 2), 16));
1633
+ i += 2;
1634
+ } else if (["\\", '"', "'"].includes(escaped)) value += escaped;
1635
+ else {
1636
+ valid = false;
1637
+ value += escaped;
1638
+ }
1639
+ } else value += code[i++];
1640
+ }
1641
+ i++;
1642
+ out.push({ kind: valid ? "string" : "other", value, start: offset + start, end: offset + i });
1643
+ continue;
1644
+ }
1645
+ if (/[a-zA-Z_$]/.test(code[i])) {
1646
+ i++;
1647
+ while (i < code.length && /[\w$]/.test(code[i])) i++;
1648
+ out.push({ kind: "word", value: code.slice(start, i), start: offset + start, end: offset + i });
1649
+ continue;
1650
+ }
1651
+ out.push({ kind: "other", value: code[i++], start: offset + start, end: offset + i });
1652
+ }
1653
+ return out;
1654
+ }
1655
+ function literalCallArguments(ts, at) {
1656
+ if (ts[at + 1]?.value !== "(") return null;
1657
+ const args = [[]];
1658
+ let depth = 0;
1659
+ for (let i = at + 2; i < ts.length; i++) {
1660
+ const token = ts[i];
1661
+ if (token.kind !== "string") {
1662
+ if (token.value === ")" && depth === 0) return args;
1663
+ if (["(", "[", "{"].includes(token.value)) depth++;
1664
+ if ([")", "]", "}"].includes(token.value)) depth--;
1665
+ if (token.value === "," && depth === 0) {
1666
+ args.push([]);
1667
+ continue;
1668
+ }
1669
+ }
1670
+ args.at(-1).push(token);
1671
+ }
1672
+ return null;
1673
+ }
1674
+ function discover(html, definitions = SOURCE_ADAPTER_DEFINITIONS) {
1675
+ if (html.length > 1e7) throw new Error("\u05DE\u05E7\u05D5\u05E8 \u05D2\u05D3\u05D5\u05DC \u05DE\u05BE10 \u05DE\u05D2\u05D4 \u05D0\u05D9\u05E0\u05D5 \u05E0\u05EA\u05DE\u05DA");
1676
+ const nodes = elements(html), targets = [];
1677
+ const root = nodes.find((n) => n.attrs["data-composition-id"]);
1678
+ const compositionId = root?.attrs["data-composition-id"].value;
1679
+ const scenes = nodes.filter((n) => /(?:^|\s)scene(?:\s|$)/.test(n.attrs.class?.value ?? "") && n.attrs["data-start"] && n.attrs["data-duration"]).map((n) => ({
1680
+ id: n.attrs.id?.value ?? `scene-${n.start}`,
1681
+ name: n.attrs["data-name"]?.value ?? n.attrs.id?.value ?? "\u05E1\u05E6\u05E0\u05D4",
1682
+ start: Number(n.attrs["data-start"].value),
1683
+ duration: Number(n.attrs["data-duration"].value),
1684
+ timingEditable: false
1685
+ })).filter((s) => Number.isFinite(s.start) && Number.isFinite(s.duration) && s.start >= 0 && s.duration > 0);
1686
+ const warnings = ["\u05D6\u05D9\u05D4\u05D5\u05D9 \u05E1\u05D8\u05D8\u05D9 \u05D0\u05D9\u05E0\u05D5 \u05D0\u05D9\u05E9\u05D5\u05E8 \u05DC\u05D4\u05E8\u05E6\u05EA \u05DE\u05E7\u05D5\u05E8. \u05EA\u05E6\u05D5\u05D2\u05D4 \u05E4\u05E2\u05D9\u05DC\u05D4 \u05D3\u05D5\u05E8\u05E9\u05EA \u05E1\u05D1\u05D9\u05D1\u05EA \u05D1\u05D9\u05D3\u05D5\u05D3 \u05E9\u05DC \u05D4\u05DE\u05D0\u05E8\u05D7."];
1687
+ const scriptText = nodes.filter((n) => n.tag === "script" && !n.attrs.src).map((n) => html.slice(n.contentStart, n.contentEnd)).join("\n");
1688
+ const externalScripts = nodes.filter((n) => n.tag === "script" && n.attrs.src).map((n) => n.attrs.src.value);
1689
+ const engine = externalScripts.some((s) => /(?:hf3d|three-bundle)\.js(?:$|\?)/.test(s)) ? "three-gsap" : /getContext\s*\(|targets\.js/.test(scriptText + " " + externalScripts.join(" ")) ? "canvas-gsap" : /gsap/.test(scriptText + " " + externalScripts.join(" ")) ? "dom-gsap" : "html";
1690
+ const dynamicIds = /* @__PURE__ */ new Set();
1691
+ for (const match of scriptText.matchAll(/(?:const|let|var)\s+([a-zA-Z_$][\w$]*)\s*=\s*(?:document\.)?(?:getElementById|querySelector|q)\s*\(\s*(["'])(#?[a-zA-Z0-9_-]+)\2\s*\)/g)) {
1692
+ const variable = match[1].replace(/[$]/g, "\\$");
1693
+ if (new RegExp("\\b" + variable + "\\.(?:textContent|innerHTML)\\s*=").test(scriptText)) dynamicIds.add(match[3].replace(/^#/, ""));
1694
+ }
1695
+ if (externalScripts.some((s) => /(?:^|\/)city\.js$/.test(s))) dynamicIds.add("cnt");
1696
+ if (engine === "three-gsap") warnings.push("\u05D8\u05E7\u05E1\u05D8 \u05EA\u05DC\u05EA\u05BE\u05DE\u05DE\u05D3 \u05D0\u05D5 \u05D8\u05E7\u05E1\u05D8\u05D5\u05E8\u05D4 \u05E0\u05D9\u05EA\u05E0\u05D9\u05DD \u05DC\u05E2\u05E8\u05D9\u05DB\u05D4 \u05E8\u05E7 \u05DB\u05D0\u05E9\u05E8 \u05D6\u05D5\u05D4\u05EA\u05D4 \u05E7\u05E8\u05D9\u05D0\u05EA \u05E6\u05D9\u05D5\u05E8 \u05DC\u05D9\u05D8\u05E8\u05DC\u05D9\u05EA \u05D1\u05EA\u05D5\u05DA HTML. \u05E7\u05D5\u05D3 \u05D7\u05D9\u05E6\u05D5\u05E0\u05D9 \u05DB\u05D2\u05D5\u05DF city.js \u05D0\u05D9\u05E0\u05D5 \u05DE\u05DE\u05D5\u05E4\u05D4 \u05DC\u05D8\u05D5\u05E4\u05E1.");
1697
+ if (engine === "canvas-gsap") warnings.push("\u05D8\u05E7\u05E1\u05D8\u05D9\u05DD \u05D4\u05DE\u05E6\u05D5\u05D9\u05E8\u05D9\u05DD \u05D1\u05DE\u05E2\u05E8\u05DB\u05D9 \u05E4\u05D9\u05E7\u05E1\u05DC\u05D9\u05DD \u05D0\u05D5 \u05D1\u05E0\u05EA\u05D5\u05E0\u05D9 targets \u05D0\u05D9\u05E0\u05DD \u05DE\u05E9\u05EA\u05E0\u05D9\u05DD \u05D3\u05E8\u05DA \u05E9\u05D3\u05D5\u05EA HTML. \u05E0\u05D3\u05E8\u05E9 \u05DE\u05EA\u05D0\u05DD \u05E6\u05D9\u05D5\u05E8 \u05D9\u05D9\u05E2\u05D5\u05D3\u05D9 \u05E2\u05D1\u05D5\u05E8\u05DD.");
1698
+ const add = (target) => {
1699
+ const existing = targets.find((t) => t.field.id === target.field.id);
1700
+ if (existing) {
1701
+ existing.field.editable = false;
1702
+ existing.field.evidence = "\u05D9\u05D5\u05EA\u05E8 \u05DE\u05D4\u05E6\u05D4\u05E8\u05D4 \u05D0\u05D7\u05EA \u05DE\u05EA\u05D0\u05D9\u05DE\u05D4; \u05E0\u05D3\u05E8\u05E9\u05EA \u05E2\u05E8\u05D9\u05DB\u05EA \u05DE\u05E7\u05D5\u05E8 \u05DE\u05E4\u05D5\u05E8\u05E9\u05EA";
1703
+ } else targets.push(target);
1704
+ };
1705
+ const findScene = (node) => {
1706
+ let current = node;
1707
+ while (current) {
1708
+ if (scenes.some((s) => s.id === current.attrs.id?.value)) return current.attrs.id.value;
1709
+ current = current.parent;
1710
+ }
1711
+ return void 0;
1712
+ };
1713
+ for (const style of nodes.filter((n) => n.tag === "style")) {
1714
+ const css = html.slice(style.contentStart, style.contentEnd);
1715
+ for (const rootStyle of css.matchAll(/:root\s*\{([^{}]*)\}/g)) {
1716
+ const base = style.contentStart + rootStyle.index + rootStyle[0].indexOf("{") + 1;
1717
+ for (const match of rootStyle[1].matchAll(/(--[a-zA-Z][\w-]*)\s*:\s*(#[a-fA-F0-9]{3,8})(?=\s*(?:[;}]|$))/g)) {
1718
+ const start = base + match.index + match[0].lastIndexOf(match[2]);
1719
+ add({ start, end: start + match[2].length, encoding: "css", field: { id: `css:${match[1]}`, label: `\u05E6\u05D1\u05E2 ${match[1]}`, kind: "color", value: match[2], editable: true, evidence: "\u05D4\u05E6\u05D4\u05E8\u05EA CSS \u05DE\u05E4\u05D5\u05E8\u05E9\u05EA \u05D1\u05BE:root; \u05DE\u05E9\u05E4\u05D9\u05E2\u05D4 \u05E2\u05DC \u05E6\u05E8\u05DB\u05E0\u05D9 var \u05E9\u05DC \u05D4\u05DE\u05E9\u05EA\u05E0\u05D4 \u05D1\u05DC\u05D1\u05D3" } });
1720
+ }
1721
+ }
1722
+ }
1723
+ const textTags = ["h1", "h2", "h3", "h4", "h5", "h6", "p", "span", "div", "b", "strong", "em", "label", "button", "bdi", "small", "text", "tspan"];
1724
+ const parentTextLeaves = /* @__PURE__ */ new Map();
1725
+ for (const node of nodes) {
1726
+ if (!node.parent || !textTags.includes(node.tag)) continue;
1727
+ const raw = html.slice(node.contentStart, node.contentEnd);
1728
+ if (raw.trim() && !raw.includes("<")) parentTextLeaves.set(node.parent, (parentTextLeaves.get(node.parent) || 0) + 1);
1729
+ }
1730
+ let domOrdinal = 0;
1731
+ for (const node of nodes) {
1732
+ if (!textTags.includes(node.tag)) continue;
1733
+ const ordinal = ++domOrdinal;
1734
+ const raw = html.slice(node.contentStart, node.contentEnd);
1735
+ if (!raw.trim() || raw.includes("<")) continue;
1736
+ const leading = raw.length - raw.trimStart().length, trailing = raw.length - raw.trimEnd().length;
1737
+ const parentId = node.parent?.attrs.id?.value;
1738
+ const id = node.attrs.id?.value ?? (parentId && parentTextLeaves.get(node.parent) === 1 ? parentId : `leaf-${ordinal}`);
1739
+ let ancestor = node, dynamic = false;
1740
+ while (ancestor) {
1741
+ if (dynamicIds.has(ancestor.attrs.id?.value)) dynamic = true;
1742
+ ancestor = ancestor.parent;
1743
+ }
1744
+ add({ start: node.contentStart + leading, end: node.contentEnd - trailing, encoding: "html", node, field: { id: `dom:${id}:${node.tag}`, label: id === "wordmark" ? "\u05E9\u05DD \u05D4\u05DE\u05D5\u05EA\u05D2" : `\u05D8\u05E7\u05E1\u05D8 ${id}`, kind: "text", value: decode(raw.trim()), editable: !dynamic, sceneId: findScene(node), evidence: dynamic ? "\u05E7\u05D5\u05D3 \u05D4\u05D0\u05E0\u05D9\u05DE\u05E6\u05D9\u05D4 \u05DB\u05D5\u05EA\u05D1 \u05DC\u05D8\u05E7\u05E1\u05D8 \u05D4\u05D6\u05D4 \u05D1\u05D6\u05DE\u05DF \u05E0\u05D9\u05D2\u05D5\u05DF; \u05E2\u05E8\u05D9\u05DB\u05EA \u05D8\u05E7\u05E1\u05D8 HTML \u05E8\u05D0\u05E9\u05D5\u05E0\u05D9 \u05D0\u05D9\u05E0\u05D4 \u05E0\u05EA\u05DE\u05DB\u05EA" : "\u05EA\u05D5\u05DB\u05DF \u05D8\u05E7\u05E1\u05D8 \u05E1\u05D8\u05D8\u05D9 \u05D1\u05D0\u05DC\u05DE\u05E0\u05D8 HTML \u05E7\u05D9\u05D9\u05DD; \u05DE\u05D1\u05E0\u05D4 \u05D4\u05D0\u05DC\u05DE\u05E0\u05D8 \u05E0\u05E9\u05DE\u05E8" } });
1745
+ }
1746
+ let remap;
1747
+ const scriptNodes = nodes.filter((n) => n.tag === "script" && !n.attrs.src);
1748
+ const adapter = definitions.find((d) => d.compositionId === compositionId && scenes.length === d.sceneIds.length && scenes.every((s, i) => s.id === d.sceneIds[i]));
1749
+ if (adapter) {
1750
+ let ordinal = 0;
1751
+ for (const script of scriptNodes) {
1752
+ const code = html.slice(script.contentStart, script.contentEnd), ts = tokens(code, script.contentStart);
1753
+ for (let i = 0; i < ts.length; i++) {
1754
+ const name = ts[i].value;
1755
+ const call = adapter.literalCalls.find((c) => c.name === name);
1756
+ if (ts[i].kind !== "word" || !call || ts[i - 1]?.value === "function") continue;
1757
+ const args = literalCallArguments(ts, i), index = call.argument;
1758
+ if (!args || args[index]?.length !== 1 || args[index][0].kind !== "string") continue;
1759
+ const literal = args[index][0];
1760
+ if (call.encoding === "js-asset" && !literal.value.trim() || call.encoding === "js-html" && /[<>]/.test(literal.value)) continue;
1761
+ const preceding = code.slice(0, ts[i].start - script.contentStart);
1762
+ const sceneCalls = [...preceding.matchAll(/const\s+c\s*=\s*S\s*\(\s*(\d+)\s*\)/g)];
1763
+ const sceneId = sceneCalls.length ? `s${sceneCalls.at(-1)[1]}` : void 0;
1764
+ const kind = call.encoding === "js-asset" ? "asset" : "text";
1765
+ add({ start: literal.start, end: literal.end, encoding: call.encoding, field: { id: `bank:${name}:${++ordinal}`, label: name === "caption" ? `\u05DB\u05EA\u05D5\u05D1\u05D9\u05EA ${sceneId ?? ""}` : name === "photo" ? `\u05EA\u05DE\u05D5\u05E0\u05D4 ${sceneId ?? ""}` : `\u05D8\u05E7\u05E1\u05D8 ${sceneId ?? ""}`, kind, value: call.encoding === "js-html" ? decode(literal.value) : literal.value, editable: true, sceneId, evidence: `\u05D0\u05E8\u05D2\u05D5\u05DE\u05E0\u05D8 \u05DE\u05D7\u05E8\u05D5\u05D6\u05EA \u05DC\u05D9\u05D8\u05E8\u05DC\u05D9 \u05D1\u05E7\u05E8\u05D9\u05D0\u05EA ${name}; \u05D6\u05DE\u05DF \u05D4\u05E7\u05E8\u05D9\u05D0\u05D4 \u05D5\u05DB\u05DC \u05D1\u05D9\u05D8\u05D5\u05D9\u05D9 GSAP \u05E0\u05E9\u05DE\u05E8\u05D9\u05DD` } });
1766
+ }
1767
+ const arrays = /const\s+Bo\s*=\s*(\[[\d\s.,]+\])\s*,\s*Bn\s*=\s*(\[[\d\s.,]+\])/.exec(code);
1768
+ const compact = code.replace(/\s+/g, "");
1769
+ const mapping = /master\.fromTo\(tl,\{time:Bo\[k\]\},\{time:Bo\[k\+1\],duration:Bn\[k\+1\]-Bn\[k\],ease:["']none["'],immediateRender:false\},Bn\[k\]\)/.test(compact);
1770
+ if (adapter.timingProfile === "gsap-bo-bn-v1" && arrays && mapping && compact.includes("window.__remap={Bo,Bn}")) {
1771
+ try {
1772
+ const old = JSON.parse(arrays[1]), boundaries = JSON.parse(arrays[2]);
1773
+ const monotonic = (a) => a.length === adapter.sceneIds.length + 1 && a[0] === 0 && a.every((n, i) => Number.isFinite(n) && (!i || n > a[i - 1]));
1774
+ if (monotonic(old) && monotonic(boundaries) && scenes.every((s, i) => Math.abs(s.start - boundaries[i]) < 1e-3)) {
1775
+ const start = script.contentStart + arrays.index + arrays[0].lastIndexOf(arrays[2]);
1776
+ remap = { range: { start, end: start + arrays[2].length }, boundaries };
1777
+ scenes.forEach((scene, i) => {
1778
+ scene.timingEditable = true;
1779
+ add({ start, end: start + arrays[2].length, encoding: "duration", field: { id: `scene:${scene.id}:duration`, label: `\u05DE\u05E9\u05DA \u05DE\u05E7\u05D8\u05E2 ${scene.id}`, kind: "number", value: Number((boundaries[i + 1] - boundaries[i]).toFixed(6)), sceneId: scene.id, editable: true, evidence: "\u05DE\u05E9\u05DA \u05DE\u05E7\u05D8\u05E2 \u05D1\u05DE\u05E4\u05EA Bn \u05E9\u05DE\u05E0\u05D9\u05E2\u05D4 \u05D1\u05E4\u05D5\u05E2\u05DC \u05D0\u05EA master.fromTo; \u05D7\u05DC\u05D5\u05E0\u05D5\u05EA \u05D7\u05E4\u05D9\u05E4\u05D4 \u05E9\u05DC \u05E1\u05E6\u05E0\u05D5\u05EA \u05E0\u05E9\u05DE\u05E8\u05D9\u05DD" } });
1780
+ });
1781
+ }
1782
+ } catch {
1783
+ }
1784
+ }
1785
+ }
1786
+ }
1787
+ if (!adapter && (engine === "three-gsap" || engine === "canvas-gsap")) {
1788
+ let drawingOrdinal = 0;
1789
+ for (const script of scriptNodes) {
1790
+ const code = html.slice(script.contentStart, script.contentEnd), ts = tokens(code, script.contentStart);
1791
+ const wordHelper = /function\s+word\s*\([^)]*\)\s*\{[^{}]*H\.text\s*\(/.test(code);
1792
+ for (let i = 0; i < ts.length; i++) {
1793
+ const name = ts[i].value;
1794
+ const isGeometry = name === "text" && ts[i - 1]?.value === "." && ts[i - 2]?.value === "H";
1795
+ const isCanvas = name === "fillText" && ts[i - 1]?.value === ".";
1796
+ if (ts[i].kind !== "word" || !(isGeometry || isCanvas || name === "word" && wordHelper) || ts[i - 1]?.value === "function") continue;
1797
+ const args = literalCallArguments(ts, i);
1798
+ if (!args || args[0]?.length !== 1 || args[0][0].kind !== "string") continue;
1799
+ const literal = args[0][0];
1800
+ add({ start: literal.start, end: literal.end, encoding: "js-text", field: { id: `drawing:${name}:${++drawingOrdinal}`, label: isCanvas ? "\u05D8\u05E7\u05E1\u05D8 \u05D1\u05DE\u05E9\u05D8\u05D7 \u05E6\u05D9\u05D5\u05E8" : "\u05D8\u05E7\u05E1\u05D8 \u05EA\u05DC\u05EA\u05BE\u05DE\u05DE\u05D3", kind: "text", value: literal.value, editable: true, evidence: "\u05D0\u05E8\u05D2\u05D5\u05DE\u05E0\u05D8 \u05DE\u05D7\u05E8\u05D5\u05D6\u05EA \u05DE\u05E4\u05D5\u05E8\u05E9 \u05D1\u05E7\u05E8\u05D9\u05D0\u05EA \u05E6\u05D9\u05D5\u05E8; \u05E9\u05D9\u05E0\u05D5\u05D9 \u05D4\u05DE\u05E7\u05D5\u05E8 \u05D1\u05D5\u05E0\u05D4 \u05DE\u05D7\u05D3\u05E9 \u05D0\u05EA \u05D4\u05D2\u05D0\u05D5\u05DE\u05D8\u05E8\u05D9\u05D4 \u05D0\u05D5 \u05D4\u05D8\u05E7\u05E1\u05D8\u05D5\u05E8\u05D4 \u05D1\u05D8\u05E2\u05D9\u05E0\u05D4 \u05D4\u05D1\u05D0\u05D4" } });
1801
+ }
1802
+ }
1803
+ }
1804
+ if (!remap && scenes.length) warnings.push("\u05EA\u05D6\u05DE\u05D5\u05DF \u05D4\u05E1\u05E6\u05E0\u05D5\u05EA \u05D6\u05D5\u05D4\u05D4 \u05DE\u05D4\u05E6\u05D4\u05E8\u05D5\u05EA \u05D1\u05DC\u05D1\u05D3. \u05D0\u05D9\u05DF \u05E9\u05D9\u05E0\u05D5\u05D9 \u05DE\u05E9\u05DA \u05D1\u05D8\u05D5\u05E4\u05E1 \u05DC\u05DC\u05D0 \u05DE\u05D9\u05E4\u05D5\u05D9 \u05DE\u05D0\u05D5\u05DE\u05EA \u05DC\u05DE\u05E0\u05D5\u05E2 \u05D4\u05D0\u05E0\u05D9\u05DE\u05E6\u05D9\u05D4.");
1805
+ if (remap) warnings.push("\u05E9\u05D9\u05E0\u05D5\u05D9 \u05DE\u05E9\u05DA \u05DE\u05E9\u05E0\u05D4 \u05D0\u05EA \u05DE\u05E4\u05EA \u05D4\u05D6\u05DE\u05DF \u05E9\u05DC \u05D4\u05D0\u05E0\u05D9\u05DE\u05E6\u05D9\u05D4. \u05E7\u05D5\u05D1\u05E5 \u05E9\u05DE\u05E2 \u05E7\u05D9\u05D9\u05DD \u05D0\u05D9\u05E0\u05D5 \u05E0\u05DE\u05EA\u05D7 \u05D0\u05D5\u05D8\u05D5\u05DE\u05D8\u05D9\u05EA \u05D5\u05E2\u05DC\u05D5\u05DC \u05DC\u05D3\u05E8\u05D5\u05E9 \u05E2\u05E8\u05D9\u05DB\u05D4 \u05E0\u05E4\u05E8\u05D3\u05EA.");
1806
+ return { nodes, targets, remap, report: { adapterId: adapter?.id ?? (root ? "hyperframes-declared-v1" : "html-static-v1"), fingerprint: sourceFingerprint(html), compositionId, width: Number(root?.attrs["data-width"]?.value) || 1920, height: Number(root?.attrs["data-height"]?.value) || 1080, duration: remap?.boundaries.at(-1) ?? (Number(root?.attrs["data-duration"]?.value) || Math.max(0, ...scenes.map((s) => s.start + s.duration))), scenes, fields: targets.map((t) => t.field), warnings, capabilities: { engine, staticText: targets.some((t) => t.encoding === "html" && t.field.editable), cssColors: targets.some((t) => t.encoding === "css" && t.field.editable), inlineDrawingText: targets.some((t) => t.field.id.startsWith("drawing:")), sceneTiming: !!remap, sourceCode: true, externalCodeMapped: false } } };
1807
+ }
1808
+ function analyzeSourceAdapter(html, definitions = SOURCE_ADAPTER_DEFINITIONS) {
1809
+ return discover(html, definitions).report;
1810
+ }
1811
+ function annotateSourcePreview(html) {
1812
+ const { targets } = discover(html);
1813
+ const markers = targets.filter((target) => target.encoding === "html" && target.field.editable && target.node).map((target) => ({ at: target.node.contentStart - 1, id: target.field.id })).sort((a, b) => b.at - a.at);
1814
+ let preview = html;
1815
+ for (const marker of markers) preview = preview.slice(0, marker.at) + ` data-motiondesk-field="${escapeHtml(marker.id)}"` + preview.slice(marker.at);
1816
+ return preview;
1817
+ }
1818
+ function applySourceEdits(project, edits, expectedFingerprint, definitions = SOURCE_ADAPTER_DEFINITIONS) {
1819
+ if (!project.source) throw new Error("\u05D0\u05D9\u05DF \u05DE\u05E7\u05D5\u05E8 \u05DC\u05E2\u05E8\u05D9\u05DB\u05D4");
1820
+ const html = project.source.current, discovery = discover(html, definitions);
1821
+ if (expectedFingerprint && expectedFingerprint !== discovery.report.fingerprint) throw new Error("\u05D4\u05DE\u05E7\u05D5\u05E8 \u05D4\u05E9\u05EA\u05E0\u05D4 \u05DE\u05D0\u05D6 \u05E4\u05EA\u05D9\u05D7\u05EA \u05D4\u05D8\u05D5\u05E4\u05E1; \u05D9\u05E9 \u05DC\u05E8\u05E2\u05E0\u05DF \u05D0\u05EA \u05D4\u05E9\u05D3\u05D5\u05EA");
1822
+ if (new Set(edits.map((e) => e.fieldId)).size !== edits.length) throw new Error("\u05E9\u05D3\u05D4 \u05E0\u05E9\u05DC\u05D7 \u05D9\u05D5\u05EA\u05E8 \u05DE\u05E4\u05E2\u05DD \u05D0\u05D7\u05EA");
1823
+ const changes = [], durations = /* @__PURE__ */ new Map();
1824
+ for (const edit of edits) {
1825
+ const target = discovery.targets.find((t) => t.field.id === edit.fieldId && t.field.editable);
1826
+ if (!target) throw new Error("\u05E9\u05D3\u05D4 \u05D4\u05DE\u05E7\u05D5\u05E8 \u05D0\u05D9\u05E0\u05D5 \u05E0\u05EA\u05DE\u05DA \u05DC\u05E2\u05E8\u05D9\u05DB\u05D4");
1827
+ if (target.encoding === "duration") {
1828
+ if (typeof edit.value !== "number" || !Number.isFinite(edit.value) || edit.value < 0.1 || edit.value > 3600) throw new Error("\u05DE\u05E9\u05DA \u05D7\u05D9\u05D9\u05D1 \u05DC\u05D4\u05D9\u05D5\u05EA \u05D1\u05D9\u05DF 0.1 \u05DC\u05BE3600 \u05E9\u05E0\u05D9\u05D5\u05EA");
1829
+ durations.set(target.field.sceneId, edit.value);
1830
+ continue;
1831
+ }
1832
+ if (typeof edit.value !== "string" || edit.value.length > 1e4 || edit.value.includes("\0")) throw new Error("\u05E2\u05E8\u05DA \u05D8\u05E7\u05E1\u05D8 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF");
1833
+ let value = edit.value;
1834
+ if (target.encoding === "css" && !/^#(?:[\da-fA-F]{3}|[\da-fA-F]{4}|[\da-fA-F]{6}|[\da-fA-F]{8})$/.test(value)) throw new Error("\u05E0\u05D3\u05E8\u05E9 \u05E6\u05D1\u05E2 HEX \u05EA\u05E7\u05D9\u05DF");
1835
+ if (target.encoding === "js-asset" && (!isLocalAsset(value) || value.includes(":"))) throw new Error("\u05E0\u05D3\u05E8\u05E9 \u05E0\u05EA\u05D9\u05D1 \u05E0\u05DB\u05E1 \u05D9\u05D7\u05E1\u05D9 \u05D1\u05EA\u05D9\u05E7\u05D9\u05D9\u05EA assets");
1836
+ if (target.encoding === "html") {
1837
+ value = escapeHtml(value).replace(/^[ \t\r\n]+|[ \t\r\n]+$/g, (whitespace) => [...whitespace].map((char) => `&#${char.charCodeAt(0)};`).join(""));
1838
+ } else if (target.encoding === "js-html") value = escapeHtml(value);
1839
+ if (target.encoding.startsWith("js-")) value = JSON.stringify(value).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
1840
+ changes.push({ start: target.start, end: target.end, value });
1841
+ }
1842
+ if (durations.size) {
1843
+ if (!discovery.remap) throw new Error("\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0 \u05DE\u05EA\u05D0\u05DD \u05EA\u05D6\u05DE\u05D5\u05DF \u05E4\u05E2\u05D9\u05DC");
1844
+ const old = discovery.remap.boundaries, next = [0];
1845
+ discovery.report.scenes.forEach((scene, i) => next.push(Number((next[i] + (durations.get(scene.id) ?? old[i + 1] - old[i])).toFixed(6))));
1846
+ changes.push({ ...discovery.remap.range, value: JSON.stringify(next) });
1847
+ for (const node of discovery.nodes) {
1848
+ const sceneIndex = discovery.report.scenes.findIndex((scene) => scene.id === node.attrs.id?.value);
1849
+ if (sceneIndex >= 0) {
1850
+ const start = node.attrs["data-start"], duration = node.attrs["data-duration"];
1851
+ if (start) changes.push({ ...start, value: String(next[sceneIndex]) });
1852
+ if (duration) changes.push({ ...duration, value: String(Number((Number(duration.value) + next[sceneIndex + 1] - next[sceneIndex] - (old[sceneIndex + 1] - old[sceneIndex])).toFixed(6))) });
1853
+ } else if (node.attrs["data-duration"] && Math.abs(Number(node.attrs["data-duration"].value) - old.at(-1)) < 1e-3) {
1854
+ changes.push({ ...node.attrs["data-duration"], value: String(next.at(-1)) });
1855
+ }
1856
+ }
1857
+ }
1858
+ changes.sort((a, b) => b.start - a.start);
1859
+ let current = html, previous = html.length;
1860
+ for (const change of changes) {
1861
+ if (change.end > previous) throw new Error("\u05E9\u05D3\u05D5\u05EA \u05D7\u05D5\u05E4\u05E4\u05D9\u05DD; \u05D4\u05E9\u05D9\u05E0\u05D5\u05D9 \u05D1\u05D5\u05D8\u05DC");
1862
+ current = current.slice(0, change.start) + change.value + current.slice(change.end);
1863
+ previous = change.start;
1864
+ }
1865
+ return commitProject({ ...project, source: { ...project.source, current, warnings: discover(current, definitions).report.warnings } });
1866
+ }
1867
+
1868
+ // src/core/motion-library.ts
1869
+ function point(at, x = 0, y = 0, scaleX = 1, scaleY = 1, rotation = 0, opacity = 1) {
1870
+ return { at, x, y, scaleX, scaleY, rotation, opacity };
1871
+ }
1872
+ function flight(duration, delay, fromX = -160, fromY = 0, travelX = 20, travelY = 0, turn = 0) {
1873
+ const enter = Math.max(delay + 0.1, Math.min(duration * 0.42, delay + 0.54));
1874
+ const hold = Math.max(enter + 0.12, duration - 0.48);
1875
+ return [
1876
+ point(0, fromX, fromY, 0.85, 0.85, -turn, 0),
1877
+ ...delay > 0 ? [point(delay, fromX, fromY, 0.85, 0.85, -turn, 0)] : [],
1878
+ point(enter, 0, 0, 1, 1, 0, 1),
1879
+ point(hold, travelX, travelY, 1.02, 1.02, turn, 1),
1880
+ point(duration - 0.02, travelX + 24, travelY - 14, 1.02, 1.02, turn, 0)
1881
+ ];
1882
+ }
1883
+ function pulse(duration, delay = 0) {
1884
+ const enter = Math.max(delay + 0.12, Math.min(duration * 0.4, delay + 0.48));
1885
+ return [
1886
+ point(0, 0, 0, 0.35, 0.35, -15, 0),
1887
+ ...delay > 0 ? [point(delay, 0, 0, 0.35, 0.35, -15, 0)] : [],
1888
+ point(enter, 0, 0, 1, 1, 0, 1),
1889
+ point(Math.max(enter + 0.12, duration * 0.64), 0, -10, 1.07, 1.07, 8, 1),
1890
+ point(duration - 0.02, 0, 0, 0.98, 0.98, -3, 0.94)
1891
+ ];
1892
+ }
1893
+ function animateMotif(ctx, layers) {
1894
+ const d = ctx.scene.duration;
1895
+ const end = d - 0.02;
1896
+ const direction = ctx.index % 2 === 0 ? 1 : -1;
1897
+ const set = (layer2, keys) => {
1898
+ layer2.keyframes = keys;
1899
+ };
1900
+ for (const item of layers) {
1901
+ const name = item.name;
1902
+ if (ctx.theme === "car-road" && /חישור/.test(name)) {
1903
+ set(item, [
1904
+ point(0, -420 * direction, 0, 1, 1, 0, 0),
1905
+ point(0.58, -145 * direction, 0, 1, 1, 160, 1),
1906
+ point(d * 0.55, 0, 0, 1, 1, 460, 1),
1907
+ point(end, 125 * direction, 0, 1, 1, 760, 1)
1908
+ ]);
1909
+ } else if (ctx.theme === "car-road" && /שובל מהירות/.test(name)) {
1910
+ const n = Number(name.match(/\d+/)?.[0] ?? 1);
1911
+ set(item, [
1912
+ point(0, -80, 0, 0.2, 1, 0, 0),
1913
+ point(0.35 + n * 0.12, -80, 0, 0.2, 1, 0, 0),
1914
+ point(0.7 + n * 0.12, 0, 0, 1, 1, 0, 0.85),
1915
+ point(end, -130, 0, 1.35, 1, 0, 0)
1916
+ ]);
1917
+ } else if ((ctx.theme === "car-road" || ctx.theme === "car-garage") && /רכב|גלגל|חלון|גג|פנס/.test(name)) {
1918
+ set(item, [
1919
+ point(0, -420 * direction, 0, 1, 1, 0, 0),
1920
+ point(0.58, -145 * direction, 0),
1921
+ point(d * 0.55, 0, 0),
1922
+ point(end, 125 * direction, 0)
1923
+ ]);
1924
+ } else if (ctx.theme === "car-road" && /סימון כביש/.test(name)) {
1925
+ set(item, [point(0, 190, 0), point(end, -230, 0)]);
1926
+ } else if (ctx.theme === "holiday-table" && /צלחת|מרכז שולחן/.test(name)) {
1927
+ set(item, [
1928
+ point(0, 0, 0, 0.15, 0.15, -45, 0),
1929
+ point(0.7, 0, 0, 0.92, 0.92, 0),
1930
+ point(d * 0.67, 0, 0, 1.06, 1.06, 8),
1931
+ point(end, 0, 0, 1, 1)
1932
+ ]);
1933
+ } else if (ctx.theme === "one-click" && /גל הדף/.test(name)) {
1934
+ set(item, [
1935
+ point(0, 0, 0, 0.08, 0.08, 0, 0),
1936
+ point(0.7, 0, 0, 0.8, 0.8, 0, 1),
1937
+ point(d * 0.65, 0, 0, 1.18, 1.18, 0, 0.65),
1938
+ point(end, 0, 0, 1.4, 1.4, 0, 0)
1939
+ ]);
1940
+ } else if (ctx.theme === "book-steps" && /ספר מדרגה|כריכת ספר/.test(name)) {
1941
+ const n = Number(name.match(/\d+/)?.[0] ?? 1);
1942
+ set(item, [
1943
+ point(0, 0, 270, 1, 1, 0, 0),
1944
+ point(0.28 * n, 0, 270, 1, 1, 0, 0),
1945
+ point(0.28 * n + 0.48, 0, 0),
1946
+ point(end, 0, -38)
1947
+ ]);
1948
+ } else if (ctx.theme === "room-build" && /קיר|חלון|ספה|רגל/.test(name)) {
1949
+ const delay = /קיר/.test(name) ? 0.15 : /חלון/.test(name) ? 0.75 : 1.25;
1950
+ set(item, [
1951
+ point(0, 0, 260, 1, 0.2, 0, 0),
1952
+ point(delay, 0, 260, 1, 0.2, 0, 0),
1953
+ point(delay + 0.55, 0, 0),
1954
+ point(end, 0, -22)
1955
+ ]);
1956
+ } else if ((ctx.theme === "summer-case" || ctx.theme === "travel-conveyor") && /מזווד|גלגל מזוודה/.test(name)) {
1957
+ set(item, [
1958
+ point(0, -320, 0, 0.8, 0.8, -8, 0),
1959
+ point(0.75, -120, 0),
1960
+ point(d * 0.6, 25, 0),
1961
+ point(end, 190, 0, 1, 1, 7)
1962
+ ]);
1963
+ } else if (ctx.theme === "wedding-rings" && /טבעת/.test(name)) {
1964
+ const left = /ראשונה/.test(name);
1965
+ set(item, [
1966
+ point(0, left ? -260 : 260, 0, 0.72, 0.72, left ? -25 : 25, 0),
1967
+ point(0.85, left ? -60 : 60, 0),
1968
+ point(d * 0.7, left ? 35 : -35, -12),
1969
+ point(end, left ? 25 : -25, 0)
1970
+ ]);
1971
+ } else if (ctx.theme === "share-mosaic" && /אריח בעלות/.test(name)) {
1972
+ const n = Number(name.match(/\d+/)?.[0] ?? 1);
1973
+ const delay = 0.08 + n % 5 * 0.12 + Math.floor(n / 5) * 0.08;
1974
+ set(item, [
1975
+ point(0, 0, 0, 0.2, 0.2, 35, 0),
1976
+ point(delay, 0, 0, 0.2, 0.2, 35, 0),
1977
+ point(delay + 0.5, 0, 0),
1978
+ point(end, 0, -16 * (n % 3))
1979
+ ]);
1980
+ } else if (ctx.theme === "fraud-alert" && /הודעה חשודה/.test(name)) {
1981
+ const n = Number(name.match(/\d+/)?.[0] ?? 1);
1982
+ const delay = 0.23 * n;
1983
+ set(item, [
1984
+ point(0, 340, 0, 1, 1, 0, 0),
1985
+ point(delay, 340, 0, 1, 1, 0, 0),
1986
+ point(delay + 0.48, 0, 0),
1987
+ point(d * 0.73, 0, -18),
1988
+ point(end, -80, -18, 1, 1, -3)
1989
+ ]);
1990
+ } else if (ctx.theme === "learning-domino" && /אבן למידה/.test(name)) {
1991
+ const n = Number(name.match(/\d+/)?.[0] ?? 1);
1992
+ const delay = 0.19 * n;
1993
+ set(item, [
1994
+ point(0, 0, -200, 1, 1, -12, 0),
1995
+ point(delay, 0, -200, 1, 1, -12, 0),
1996
+ point(delay + 0.43, 0, 0, 1, 1, 0),
1997
+ point(end, n % 2 ? 30 : -30, 10, 1, 1, 18)
1998
+ ]);
1999
+ } else if (ctx.theme === "fomo-storm" && /התראת לחץ/.test(name)) {
2000
+ const n = Number(name.match(/\d+/)?.[0] ?? 1);
2001
+ const delay = 0.1 * n;
2002
+ set(item, [
2003
+ point(0, n % 2 ? -350 : 350, 0, 0.85, 0.85, 0, 0),
2004
+ point(delay, n % 2 ? -350 : 350, 0, 0.85, 0.85, 0, 0),
2005
+ point(delay + 0.45, 0, 0),
2006
+ point(end, n % 2 ? 90 : -90, -55, 1, 1, 0, 0.45)
2007
+ ]);
2008
+ } else if (ctx.theme === "market-clock" && /מחוג/.test(name)) {
2009
+ const long = /ארוך/.test(name);
2010
+ set(item, [
2011
+ point(0, 0, 0, 1, 1, long ? -95 : -40, 0),
2012
+ point(0.48, 0, 0, 1, 1, 0),
2013
+ point(d * 0.6, 0, 0, 1, 1, long ? 78 : 33),
2014
+ point(end, 0, 0, 1, 1, long ? 140 : 65)
2015
+ ]);
2016
+ } else if (ctx.theme === "small-bricks" && /לבנה/.test(name)) {
2017
+ const n = Number(name.match(/\d+/)?.[0] ?? 1);
2018
+ const delay = n * 0.058;
2019
+ set(item, [
2020
+ point(0, 0, -220, 1, 1, 0, 0),
2021
+ point(delay, 0, -220, 1, 1, 0, 0),
2022
+ point(delay + 0.42, 0, 0),
2023
+ point(end, 0, -5)
2024
+ ]);
2025
+ } else if (ctx.theme === "two-paths" && /מסלול/.test(name)) {
2026
+ const left = /1/.test(name);
2027
+ set(item, [
2028
+ point(0, left ? -310 : 310, 0, 0.8, 0.8, 0, 0),
2029
+ point(left ? 0.5 : 0.85, 0, 0),
2030
+ point(d * 0.6, 0, 0, left ? 1.04 : 0.94, left ? 1.04 : 0.94),
2031
+ point(end, 0, 0)
2032
+ ]);
2033
+ } else if (ctx.theme === "small-store" && /פס סוכך/.test(name)) {
2034
+ const n = Number(name.match(/\d+/)?.[0] ?? 1);
2035
+ set(item, [
2036
+ point(0, 0, -240, 1, 0.2, 0, 0),
2037
+ point(0.16 * n, 0, -240, 1, 0.2, 0, 0),
2038
+ point(0.16 * n + 0.43, 0, 0),
2039
+ point(end, 0, 0)
2040
+ ]);
2041
+ } else if (ctx.theme === "travel-conveyor" && /מסוע/.test(name)) {
2042
+ set(item, [point(0, -180, 0), point(d * 0.6, 0, 0), point(end, 80, 0)]);
2043
+ } else if (ctx.theme === "mortgage-blueprint" && /קו|קיר|גג|דלת/.test(name)) {
2044
+ const n = layers.indexOf(item);
2045
+ const delay = 0.16 * (n % 7);
2046
+ set(item, [
2047
+ point(0, 0, 0, 0, 1, 0, 0),
2048
+ point(delay, 0, 0, 0, 1, 0, 0),
2049
+ point(delay + 0.6, 0, 0),
2050
+ point(end, 0, 0)
2051
+ ]);
2052
+ } else if (ctx.theme === "market-phone" && /עמודת נתון/.test(name)) {
2053
+ const n = Number(name.match(/\d+/)?.[0] ?? 1);
2054
+ const delay = 0.17 * n;
2055
+ set(item, [
2056
+ point(0, 0, 110, 1, 0.05, 0, 0),
2057
+ point(delay, 0, 110, 1, 0.05, 0, 0),
2058
+ point(delay + 0.55, 0, 0),
2059
+ point(end, 0, -30 + 9 * n, 1, 1.1)
2060
+ ]);
2061
+ }
2062
+ }
2063
+ }
2064
+ var luminance = (c) => {
2065
+ const rgb = c.slice(1).match(/../g).map((v) => parseInt(v, 16) / 255).map((v) => v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4);
2066
+ return rgb[0] * 0.2126 + rgb[1] * 0.7152 + rgb[2] * 0.0722;
2067
+ };
2068
+ var contrastRatio = (a, b) => {
2069
+ const x = luminance(a), y = luminance(b);
2070
+ return (Math.max(x, y) + 0.05) / (Math.min(x, y) + 0.05);
2071
+ };
2072
+ function contrastText(surface, preferred, alternative = "#101216") {
2073
+ if (contrastRatio(surface, preferred) >= 4.5) return preferred;
2074
+ if (contrastRatio(surface, alternative) >= 4.5) return alternative;
2075
+ return contrastRatio(surface, "#ffffff") >= contrastRatio(surface, "#101216") ? "#ffffff" : "#101216";
2076
+ }
2077
+
2078
+ // src/core/config-v2.ts
2079
+ var componentTypes = ["hook", "kinetic", "counter", "cards", "checklist", "compare", "timeline", "bars", "phone", "chat", "map-route", "coins", "confetti", "freeze", "endcard", "quote", "progress", "logo"];
2080
+ var themes = {
2081
+ summer_ice: { bg: "#e7f8ff", fg: "#081b37", accent: "#0989d8", secondary: "#ffce42" },
2082
+ bank_red: { bg: "#ffffff", fg: "#172239", accent: "#e30613", secondary: "#ffe8e9" },
2083
+ midnight: { bg: "#07152f", fg: "#ffffff", accent: "#44e0d0", secondary: "#1a3158" },
2084
+ warm: { bg: "#fff6eb", fg: "#29213d", accent: "#f15a43", secondary: "#ffdb8a" },
2085
+ mono: { bg: "#101216", fg: "#ffffff", accent: "#eeeeee", secondary: "#41444c" }
2086
+ };
2087
+ var allowed = /* @__PURE__ */ new Set(["type", "duration", "title", "subtitle", "label", "product", "cta", "words", "items", "rows", "to", "beat", "ring", "transition"]);
2088
+ function safeText(value, label) {
2089
+ if (value === void 0) return void 0;
2090
+ if (typeof value !== "string" || value.length > 220 || /[\x00-\x08\x0b\x0c\x0e-\x1f]/.test(value)) throw new Error(`${label}: \u05D8\u05E7\u05E1\u05D8 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF`);
2091
+ return value;
2092
+ }
2093
+ function parseMotionConfigV2(value) {
2094
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("\u05E7\u05D5\u05E0\u05E4\u05D9\u05D2\u05D5\u05E8\u05E6\u05D9\u05D4 v2 \u05D0\u05D9\u05E0\u05D4 \u05D0\u05D5\u05D1\u05D9\u05D9\u05E7\u05D8");
2095
+ const v = value;
2096
+ if (v.format !== "motiondesk-config/v2") throw new Error("\u05E4\u05D5\u05E8\u05DE\u05D8 v2 \u05D0\u05D9\u05E0\u05D5 \u05EA\u05E7\u05D9\u05DF");
2097
+ for (const key of Object.keys(v)) if (!["format", "title", "theme", "aspectRatio", "fps", "scenes"].includes(key)) throw new Error(`\u05E9\u05D3\u05D4 \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8: ${key}`);
2098
+ const theme = v.theme === void 0 ? "bank_red" : safeText(v.theme, "theme");
2099
+ if (!themes[theme]) throw new Error("\u05E2\u05E8\u05DB\u05EA \u05E0\u05D5\u05E9\u05D0 \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8\u05EA");
2100
+ const aspectRatio = v.aspectRatio ?? "16:9";
2101
+ if (!["16:9", "9:16", "1:1"].includes(String(aspectRatio))) throw new Error("\u05D9\u05D7\u05E1 \u05DE\u05E1\u05DA \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8");
2102
+ const fps = v.fps ?? 30;
2103
+ if (![24, 25, 30, 60].includes(Number(fps))) throw new Error("fps \u05DC\u05D0 \u05E0\u05EA\u05DE\u05DA");
2104
+ if (!Array.isArray(v.scenes) || v.scenes.length < 1 || v.scenes.length > 30) throw new Error("\u05E0\u05D3\u05E8\u05E9\u05D5\u05EA 1\u201330 \u05E1\u05E6\u05E0\u05D5\u05EA");
2105
+ const scenes = v.scenes.map((raw, index) => {
2106
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) throw new Error(`\u05E1\u05E6\u05E0\u05D4 ${index + 1} \u05D0\u05D9\u05E0\u05D4 \u05D0\u05D5\u05D1\u05D9\u05D9\u05E7\u05D8`);
2107
+ const scene = raw;
2108
+ for (const key of Object.keys(scene)) if (!allowed.has(key)) throw new Error(`\u05E1\u05E6\u05E0\u05D4 ${index + 1}: \u05E9\u05D3\u05D4 \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8 ${key}`);
2109
+ if (!componentTypes.includes(scene.type)) throw new Error(`\u05E1\u05E6\u05E0\u05D4 ${index + 1}: \u05E8\u05DB\u05D9\u05D1 \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8`);
2110
+ const duration = scene.duration ?? 4;
2111
+ if (typeof duration !== "number" || !Number.isFinite(duration) || duration < 0.5 || duration > 30) throw new Error(`\u05E1\u05E6\u05E0\u05D4 ${index + 1}: \u05DE\u05E9\u05DA \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF`);
2112
+ const beat = scene.beat ?? 0.5;
2113
+ if (typeof beat !== "number" || !Number.isFinite(beat) || beat < 0.05 || beat > 3) throw new Error(`\u05E1\u05E6\u05E0\u05D4 ${index + 1}: beat \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF`);
2114
+ if (scene.to !== void 0 && (typeof scene.to !== "number" || !Number.isFinite(scene.to) || Math.abs(scene.to) > 1e9)) throw new Error(`\u05E1\u05E6\u05E0\u05D4 ${index + 1}: \u05DE\u05E1\u05E4\u05E8 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF`);
2115
+ if (scene.ring !== void 0 && typeof scene.ring !== "boolean") throw new Error(`\u05E1\u05E6\u05E0\u05D4 ${index + 1}: ring \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF`);
2116
+ if (scene.transition !== void 0 && !["cut", "fade", "slide", "wipe", "zoom", "push"].includes(String(scene.transition))) throw new Error(`\u05E1\u05E6\u05E0\u05D4 ${index + 1}: \u05DE\u05E2\u05D1\u05E8 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF`);
2117
+ const entry = { type: scene.type, duration, beat };
2118
+ for (const key of ["title", "subtitle", "label", "product", "cta"]) if (scene[key] !== void 0) entry[key] = safeText(scene[key], key);
2119
+ for (const key of ["words", "items"]) if (scene[key] !== void 0) {
2120
+ if (!Array.isArray(scene[key]) || scene[key].length > 20) throw new Error(`${key}: \u05E8\u05E9\u05D9\u05DE\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D4`);
2121
+ entry[key] = scene[key].map((item, i) => safeText(item, `${key}.${i}`));
2122
+ }
2123
+ if (scene.rows !== void 0) {
2124
+ if (!Array.isArray(scene.rows) || scene.rows.length > 12) throw new Error("rows: \u05E8\u05E9\u05D9\u05DE\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D4");
2125
+ entry.rows = scene.rows.map((row, i) => {
2126
+ if (!Array.isArray(row) || row.length > 3) return (() => {
2127
+ throw new Error(`rows.${i}: \u05E9\u05D5\u05E8\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05E0\u05D4`);
2128
+ })();
2129
+ return row.map((cell, j) => safeText(cell, `rows.${i}.${j}`));
2130
+ });
2131
+ }
2132
+ if (scene.to !== void 0) entry.to = scene.to;
2133
+ if (scene.ring !== void 0) entry.ring = scene.ring;
2134
+ if (scene.transition !== void 0) entry.transition = scene.transition;
2135
+ return entry;
2136
+ });
2137
+ return { format: "motiondesk-config/v2", title: safeText(v.title, "title") || "\u05E1\u05E8\u05D8\u05D5\u05DF Motion \u05D7\u05D3\u05E9", theme, aspectRatio, fps, scenes };
2138
+ }
2139
+ function configV2ToProject(input) {
2140
+ const config = parseMotionConfigV2(input), ratio = config.aspectRatio, [w, h] = ratio === "9:16" ? [1080, 1920] : ratio === "1:1" ? [1080, 1080] : [1920, 1080];
2141
+ const theme = themes[config.theme], base = Math.min(w, h), portrait = h > w;
2142
+ const scenes = config.scenes.map((spec, index) => {
2143
+ const duration = spec.duration, scene = createScene(`${index + 1}. ${spec.type}`, duration);
2144
+ scene.background = theme.bg;
2145
+ scene.transition = spec.transition ?? (index ? "push" : "cut");
2146
+ scene.transitionDuration = Math.min(0.5, duration / 3);
2147
+ const add = (type, name, x, y, ww, hh, patch = {}) => {
2148
+ const layer2 = createLayer(type, { name, x: Math.round(x * w), y: Math.round(y * h), width: Math.round(ww * w), height: Math.round(hh * h), start: 0, duration, color: theme.fg, fontSize: Math.round(base * 0.065), fontWeight: 700, textAlign: "center", motion: "fade", motionDuration: 0.45, motionOut: "fade", motionOutDuration: 0.3, ...patch });
2149
+ scene.layers.push(layer2);
2150
+ return layer2;
2151
+ };
2152
+ const txt = (name, text3, x, y, ww, hh, size = 0.06, color = theme.fg, delay = 0, surface = theme.bg) => text3 !== void 0 ? add("text", name, x, y, ww, hh, { text: text3, fontSize: Math.round(base * size), color: contrastText(surface, color, theme.bg), motion: "slide-up", motionDelay: delay, splitText: "word", stagger: 0.08, shadow: "0 3px 10px #0002" }) : void 0;
2153
+ const box2 = (name, x, y, ww, hh, color = theme.accent, radius = 0.02) => add("shape", name, x, y, ww, hh, { color, borderRadius: Math.round(base * radius), motion: "pop" });
2154
+ const row = (items, y = 0.45) => items.slice(0, 5).forEach((item, i) => {
2155
+ const x = 0.08 + i * 0.84 / items.length, ww = 0.8 / items.length;
2156
+ box2(`\u05DB\u05E8\u05D8\u05D9\u05E1 ${i + 1}`, x, y, ww, 0.16, i % 2 ? theme.secondary : theme.accent);
2157
+ txt(`\u05D8\u05E7\u05E1\u05D8 \u05DB\u05E8\u05D8\u05D9\u05E1 ${i + 1}`, item, x + 0.015, y + 0.04, ww - 0.03, 0.08, 0.03, theme.fg, i * 0.12, i % 2 ? theme.secondary : theme.accent);
2158
+ });
2159
+ const headline = spec.title || spec.product || spec.label || spec.words?.[0] || "";
2160
+ switch (spec.type) {
2161
+ case "hook":
2162
+ box2("\u05E4\u05E1 \u05E4\u05EA\u05D9\u05D7\u05D4", 0.05, 0.08, 0.08, 0.82);
2163
+ txt("\u05DB\u05D5\u05EA\u05E8\u05EA", headline, 0.16, 0.29, 0.77, 0.32, 0.105);
2164
+ txt("\u05DB\u05D5\u05EA\u05E8\u05EA \u05DE\u05E9\u05E0\u05D4", spec.subtitle, 0.18, 0.65, 0.7, 0.13, 0.04, theme.accent, 0.3);
2165
+ break;
2166
+ case "kinetic":
2167
+ (spec.words?.length ? spec.words : [headline]).slice(0, 5).forEach((word, i) => txt(`\u05DE\u05D9\u05DC\u05D4 ${i + 1}`, word, 0.1, 0.15 + i * 0.15, 0.8, 0.14, 0.08, i % 2 ? theme.accent : theme.fg, i * (spec.beat || 0.5)));
2168
+ break;
2169
+ case "counter":
2170
+ txt("\u05DE\u05D5\u05E0\u05D4", String(spec.to ?? 100), 0.1, 0.27, 0.8, 0.28, 0.16, theme.accent);
2171
+ {
2172
+ const l = scene.layers.at(-1);
2173
+ l.countFrom = 0;
2174
+ l.countTo = spec.to ?? 100;
2175
+ l.motion = "none";
2176
+ l.motionDuration = Math.min(duration * 0.75, 2);
2177
+ }
2178
+ txt("\u05EA\u05D5\u05D5\u05D9\u05EA", spec.label || headline, 0.2, 0.64, 0.6, 0.13, 0.05);
2179
+ if (spec.ring) add("path", "\u05D8\u05D1\u05E2\u05EA", 0.28, 0.16, 0.44, 0.56, { pathData: `M ${0.22 * w} 0 A ${0.22 * w} ${0.28 * h} 0 1 1 ${0.22 * w - 1} 0`, stroke: theme.accent, strokeWidth: base * 0.012, color: theme.accent, motion: "zoom" });
2180
+ break;
2181
+ case "cards":
2182
+ txt("\u05DB\u05D5\u05EA\u05E8\u05EA", headline, 0.1, 0.1, 0.8, 0.15, 0.065);
2183
+ row(spec.items || spec.words || ["\u05E8\u05E2\u05D9\u05D5\u05DF", "\u05EA\u05E0\u05D5\u05E2\u05D4", "\u05EA\u05D5\u05E6\u05D0\u05D4"]);
2184
+ break;
2185
+ case "checklist":
2186
+ txt("\u05DB\u05D5\u05EA\u05E8\u05EA", headline, 0.1, 0.07, 0.8, 0.14, 0.064);
2187
+ (spec.items || ["\u05E9\u05DC\u05D1 \u05E8\u05D0\u05E9\u05D5\u05DF", "\u05E9\u05DC\u05D1 \u05E9\u05E0\u05D9", "\u05DE\u05D5\u05DB\u05E0\u05D9\u05DD"]).slice(0, 5).forEach((item, i) => {
2188
+ box2(`\u05E1\u05D9\u05DE\u05D5\u05DF ${i + 1}`, 0.15, 0.29 + i * 0.12, 0.055, 0.075);
2189
+ txt(`\u05E1\u05E2\u05D9\u05E3 ${i + 1}`, item, 0.24, 0.28 + i * 0.12, 0.6, 0.08, 0.038, theme.fg, i * 0.15);
2190
+ });
2191
+ break;
2192
+ case "compare":
2193
+ txt("\u05DB\u05D5\u05EA\u05E8\u05EA", headline, 0.1, 0.08, 0.8, 0.15);
2194
+ box2("\u05E6\u05D3 \u05D0", 0.07, 0.32, 0.4, 0.42, theme.secondary);
2195
+ box2("\u05E6\u05D3 \u05D1", 0.53, 0.32, 0.4, 0.42, theme.accent);
2196
+ txt("\u05D0\u05E4\u05E9\u05E8\u05D5\u05EA \u05D0", spec.items?.[0] || "\u05DC\u05E4\u05E0\u05D9", 0.09, 0.45, 0.36, 0.13, 0.053, theme.fg, 0, theme.secondary);
2197
+ txt("\u05D0\u05E4\u05E9\u05E8\u05D5\u05EA \u05D1", spec.items?.[1] || "\u05D0\u05D7\u05E8\u05D9", 0.55, 0.45, 0.36, 0.13, 0.053, theme.fg, 0, theme.accent);
2198
+ break;
2199
+ case "timeline":
2200
+ txt("\u05DB\u05D5\u05EA\u05E8\u05EA", headline, 0.1, 0.1, 0.8, 0.14);
2201
+ box2("\u05E6\u05D9\u05E8", 0.12, 0.52, 0.76, 0.018);
2202
+ (spec.items || ["\u05D4\u05EA\u05D7\u05DC\u05D4", "\u05D1\u05D3\u05E8\u05DA", "\u05D9\u05E2\u05D3"]).slice(0, 5).forEach((item, i, arr) => {
2203
+ const x = 0.12 + i * 0.72 / Math.max(1, arr.length - 1);
2204
+ box2(`\u05EA\u05D7\u05E0\u05D4 ${i + 1}`, x, 0.49, 0.045, 0.065);
2205
+ txt(`\u05E9\u05DD \u05EA\u05D7\u05E0\u05D4 ${i + 1}`, item, x - 0.06, 0.6, 0.17, 0.1, 0.028);
2206
+ });
2207
+ break;
2208
+ case "bars":
2209
+ txt("\u05DB\u05D5\u05EA\u05E8\u05EA", headline, 0.1, 0.08, 0.8, 0.14);
2210
+ (spec.rows || [["\u05D0", "40"], ["\u05D1", "70"], ["\u05D2", "95"]]).slice(0, 5).forEach((r, i) => {
2211
+ txt(`\u05E9\u05DD \u05E2\u05DE\u05D5\u05D3\u05D4 ${i + 1}`, r[0], 0.12, 0.3 + i * 0.12, 0.18, 0.07, 0.032);
2212
+ const l = box2(`\u05E2\u05DE\u05D5\u05D3\u05D4 ${i + 1}`, 0.32, 0.31 + i * 0.12, Math.min(0.55, Math.max(0.05, Number(r[1]) * 55e-4 || 0.3)), 0.055);
2213
+ l.keyframes = [{ at: 0, x: 0, y: 0, scaleX: 0.01, scaleY: 1, rotation: 0, opacity: 1 }, { at: Math.min(1, duration * 0.5), x: 0, y: 0, scaleX: 1, scaleY: 1, rotation: 0, opacity: 1, easing: "ease-out" }];
2214
+ });
2215
+ break;
2216
+ case "phone": {
2217
+ const frame = box2("\u05D8\u05DC\u05E4\u05D5\u05DF", portrait ? 0.2 : 0.36, 0.12, portrait ? 0.6 : 0.28, 0.75, theme.fg, 0.04);
2218
+ frame.type = "group";
2219
+ frame.color = theme.fg;
2220
+ const fw = frame.width, fh = frame.height;
2221
+ frame.children = [createLayer("shape", { name: "\u05DE\u05E1\u05D2\u05E8\u05EA \u05D8\u05DC\u05E4\u05D5\u05DF", x: 0, y: 0, width: fw, height: fh, color: theme.fg, borderRadius: base * 0.04, start: 0, duration }), createLayer("shape", { name: "\u05DE\u05E1\u05DA", x: fw * 0.05, y: fh * 0.04, width: fw * 0.9, height: fh * 0.91, color: theme.bg, borderRadius: base * 0.02, start: 0, duration }), createLayer("text", { name: "\u05DB\u05D5\u05EA\u05E8\u05EA \u05DE\u05E1\u05DA", text: headline, x: fw * 0.1, y: fh * 0.12, width: fw * 0.8, height: fh * 0.14, color: theme.fg, fontSize: Math.round(base * 0.035), textAlign: "center", start: 0, duration }), ...(spec.rows || [["\u05E4\u05E8\u05D9\u05D8", "72%"]]).slice(0, 4).map((r, i) => createLayer("text", { name: `\u05E9\u05D5\u05E8\u05EA \u05DE\u05E1\u05DA ${i + 1}`, text: r.join(" "), x: fw * 0.1, y: fh * (0.34 + i * 0.12), width: fw * 0.8, height: fh * 0.09, color: theme.fg, fontSize: Math.round(base * 0.025), textAlign: "right", start: 0, duration })), createLayer("text", { name: "\u05E4\u05E2\u05D5\u05DC\u05D4", text: spec.cta || "\u05DC\u05D4\u05DE\u05E9\u05DA", x: fw * 0.13, y: fh * 0.78, width: fw * 0.74, height: fh * 0.08, color: theme.accent, fontSize: Math.round(base * 0.03), textAlign: "center", start: 0, duration })];
2222
+ frame.motion = "slide-up";
2223
+ break;
2224
+ }
2225
+ case "chat":
2226
+ txt("\u05DB\u05D5\u05EA\u05E8\u05EA", headline, 0.1, 0.08, 0.8, 0.14);
2227
+ (spec.items || spec.words || ["\u05D4\u05D9\u05D9!", "\u05D0\u05D9\u05D6\u05D4 \u05D9\u05D5\u05E4\u05D9", "\u05D1\u05D5\u05D0\u05D5 \u05E0\u05EA\u05D7\u05D9\u05DC"]).slice(0, 5).forEach((item, i) => {
2228
+ const x = i % 2 ? 0.17 : 0.43;
2229
+ box2(`\u05D1\u05D5\u05E2\u05D4 ${i + 1}`, x, 0.27 + i * 0.12, 0.4, 0.095, i % 2 ? theme.secondary : theme.accent);
2230
+ txt(`\u05D4\u05D5\u05D3\u05E2\u05D4 ${i + 1}`, item, x + 0.02, 0.28 + i * 0.12, 0.36, 0.07, 0.03, theme.fg, i * 0.25, i % 2 ? theme.secondary : theme.accent);
2231
+ });
2232
+ break;
2233
+ case "map-route":
2234
+ txt("\u05DB\u05D5\u05EA\u05E8\u05EA", headline, 0.1, 0.07, 0.8, 0.14);
2235
+ add("path", "\u05DE\u05E1\u05DC\u05D5\u05DC", 0.12, 0.25, 0.76, 0.5, { pathData: `M 0 ${0.3 * h} C ${0.2 * w} 0 ${0.37 * w} ${0.5 * h} ${0.7 * w} ${0.1 * h}`, stroke: theme.accent, strokeWidth: base * 0.015, color: theme.accent, motion: "fade" });
2236
+ row(spec.items || ["\u05D9\u05D5\u05E6\u05D0\u05D9\u05DD", "\u05DE\u05D2\u05D9\u05E2\u05D9\u05DD"], 0.8);
2237
+ break;
2238
+ case "coins":
2239
+ txt("\u05DB\u05D5\u05EA\u05E8\u05EA", headline, 0.1, 0.08, 0.8, 0.14);
2240
+ for (let i = 0; i < 7; i++) {
2241
+ const coin = box2(`\u05DE\u05D8\u05D1\u05E2 ${i + 1}`, 0.18 + i * 0.09, 0.42 - i % 3 * 0.055, 0.075, 0.12, theme.secondary, 0.05);
2242
+ coin.rotation = i * 8;
2243
+ coin.motion = "slide-up";
2244
+ coin.motionDelay = i * 0.1;
2245
+ }
2246
+ txt("\u05E1\u05DB\u05D5\u05DD", spec.label || String(spec.to || ""), 0.1, 0.7, 0.8, 0.16, 0.07, theme.accent);
2247
+ break;
2248
+ case "confetti":
2249
+ txt("\u05DB\u05D5\u05EA\u05E8\u05EA", headline, 0.1, 0.28, 0.8, 0.25, 0.095);
2250
+ for (let i = 0; i < 18; i++) {
2251
+ const x = i * 37 % 91 / 100, y = i * 29 % 83 / 100;
2252
+ const bit = box2(`\u05E7\u05D5\u05E0\u05E4\u05D8\u05D9 ${i + 1}`, x, y, 0.015, 0.045, i % 2 ? theme.accent : theme.secondary, 0);
2253
+ bit.rotation = i * 25;
2254
+ bit.motion = "slide-down";
2255
+ bit.motionDelay = i % 6 * 0.08;
2256
+ }
2257
+ break;
2258
+ case "freeze":
2259
+ txt("\u05DB\u05D5\u05EA\u05E8\u05EA", headline, 0.1, 0.2, 0.8, 0.2, 0.085);
2260
+ box2("\u05E7\u05D5 \u05D4\u05E7\u05E4\u05D0\u05D4", 0.1, 0.52, 0.8, 0.018, theme.accent);
2261
+ txt("\u05DB\u05D9\u05EA\u05D5\u05D1", spec.subtitle || spec.label, 0.18, 0.59, 0.64, 0.12, 0.04);
2262
+ break;
2263
+ case "endcard":
2264
+ box2("\u05E4\u05E1 \u05DE\u05D5\u05E6\u05E8", 0.08, 0.17, 0.84, 0.05);
2265
+ txt("\u05DE\u05D5\u05E6\u05E8", spec.product || headline, 0.1, 0.3, 0.8, 0.19, 0.09);
2266
+ txt("\u05E4\u05E2\u05D5\u05DC\u05D4", spec.cta || "\u05DC\u05E4\u05E8\u05D8\u05D9\u05DD \u05E0\u05D5\u05E1\u05E4\u05D9\u05DD", 0.22, 0.65, 0.56, 0.13, 0.045, theme.accent, 0.3);
2267
+ break;
2268
+ case "quote":
2269
+ box2("\u05E1\u05D9\u05DE\u05DF \u05E6\u05D9\u05D8\u05D5\u05D8", 0.1, 0.16, 0.1, 0.12, theme.accent);
2270
+ txt("\u05E6\u05D9\u05D8\u05D5\u05D8", headline, 0.18, 0.33, 0.65, 0.3, 0.07);
2271
+ txt("\u05D9\u05D9\u05D7\u05D5\u05E1", spec.label, 0.2, 0.73, 0.6, 0.09, 0.035, theme.accent);
2272
+ break;
2273
+ case "progress":
2274
+ txt("\u05DB\u05D5\u05EA\u05E8\u05EA", headline, 0.1, 0.15, 0.8, 0.15);
2275
+ box2("\u05DE\u05E1\u05D9\u05DC\u05D4", 0.12, 0.5, 0.76, 0.07, theme.secondary);
2276
+ {
2277
+ const l = box2("\u05D4\u05EA\u05E7\u05D3\u05DE\u05D5\u05EA", 0.12, 0.5, 0.76, 0.07, theme.accent);
2278
+ l.keyframes = [{ at: 0, x: 0, y: 0, scaleX: 0, scaleY: 1, rotation: 0, opacity: 1 }, { at: Math.min(2, duration * 0.7), x: 0, y: 0, scaleX: 1, scaleY: 1, rotation: 0, opacity: 1, easing: "ease-out" }];
2279
+ }
2280
+ txt("\u05D9\u05E2\u05D3", spec.label || `${spec.to || 100}%`, 0.2, 0.65, 0.6, 0.11, 0.05);
2281
+ break;
2282
+ case "logo":
2283
+ box2("\u05E1\u05DE\u05DC", 0.38, 0.22, 0.24, 0.3, theme.accent, 0.06);
2284
+ txt("\u05DE\u05D5\u05EA\u05D2", headline, 0.13, 0.6, 0.74, 0.15, 0.075);
2285
+ break;
2286
+ }
2287
+ return scene;
2288
+ });
2289
+ const project = createProject(config.title, { canvas: { width: w, height: h, fps: config.fps }, scenes });
2290
+ assertProject(project);
2291
+ return project;
2292
+ }
2293
+
2294
+ // src/core/config-v3-components.ts
2295
+ var mix = (a, b, t) => "#" + [0, 2, 4].map((i) => Math.round(parseInt(a.slice(i + 1, i + 3), 16) * (1 - t) + parseInt(b.slice(i + 1, i + 3), 16) * t).toString(16).padStart(2, "0")).join("");
2296
+ function compileConfigV3Scene(spec, palette, w, h, seed, index) {
2297
+ const d = spec.duration, base = Math.min(w, h), portrait = h > w, variant = spec.variant, energy = spec.energy, a = spec.accent ?? palette.accent;
2298
+ const bg = palette.background, fg = contrastText(bg, palette.foreground), secondary = palette.secondary, accentText = contrastText(bg, a, fg);
2299
+ const factor = energy === "calm" ? 0.48 : energy === "punchy" ? 1.45 : 1, stagger = energy === "calm" ? 0.065 : energy === "punchy" ? 0.035 : 0.05;
2300
+ const spring = { stiffness: energy === "punchy" ? 190 : 100, damping: energy === "punchy" ? 14 : 23, mass: 1 };
2301
+ const headline = spec.title ?? spec.product ?? (spec.type === "kinetic" ? void 0 : spec.words?.[0]);
2302
+ const scene = createScene(`${index + 1}. ${spec.title ?? spec.product ?? "\u05E1\u05E6\u05E0\u05EA \u05EA\u05E0\u05D5\u05E2\u05D4"}`, d);
2303
+ scene.background = bg;
2304
+ scene.transition = spec.transition ?? (index ? energy === "punchy" ? "whip" : variant === "stacked" ? "stack" : "diagonal-wipe" : "cut");
2305
+ scene.transitionDuration = Math.min(d * 0.18, 0.62);
2306
+ scene.transitionEasing = [0.16, 0.85, 0.22, 1];
2307
+ const visual = variant === "split" ? portrait ? { x: 0.08 * w, y: 0.39 * h, w: 0.84 * w, h: 0.43 * h } : { x: 0.065 * w, y: 0.23 * h, w: 0.44 * w, h: 0.6 * h } : variant === "centered" ? { x: 0.14 * w, y: 0.39 * h, w: 0.72 * w, h: 0.43 * h } : { x: 0.09 * w, y: 0.17 * h, w: 0.82 * w, h: 0.43 * h };
2308
+ const titleRect = variant === "split" ? portrait ? { x: 0.09 * w, y: 0.14 * h, w: 0.82 * w, h: 0.22 * h } : { x: 0.55 * w, y: 0.25 * h, w: 0.38 * w, h: 0.48 * h } : variant === "centered" ? { x: 0.09 * w, y: 0.15 * h, w: 0.82 * w, h: 0.2 * h } : { x: 0.09 * w, y: 0.65 * h, w: 0.82 * w, h: 0.22 * h };
2309
+ const k = (time, patch = {}) => ({ ...point(d * time), ...patch });
2310
+ let serial = 0;
2311
+ const layer2 = (type, name, x, y, ww, hh, patch = {}) => {
2312
+ const l = createLayer(type, { name, x, y, width: Math.max(1, ww), height: Math.max(1, hh), start: 0, duration: d, color: fg, fontSize: base * 0.04, fontWeight: 700, motion: "none", motionOut: "none", textAlign: "center", textFit: "shrink", lineHeight: 1.12, depth: 0, ...patch });
2313
+ l.keyframes ??= [k(0, { x: (serial % 2 ? 1 : -1) * base * 0.1 * factor, y: base * 0.035 * factor, scaleX: 0.87, scaleY: 0.87, opacity: 0, blur: energy === "calm" ? 0 : 7, rotateY: energy === "punchy" ? -16 : 0 }), k(0.22, { easing: spring }), k(0.94, { y: -base * 9e-3 * factor, easing: "linear" })];
2314
+ serial++;
2315
+ scene.layers.push(l);
2316
+ return l;
2317
+ };
2318
+ const shape = (name, x, y, ww, hh, color = a, patch = {}) => layer2("shape", name, x, y, ww, hh, { color, borderRadius: base * 0.018, ...patch });
2319
+ const text3 = (name, value, x, y, ww, hh, size = base * 0.06, color = fg, delay = 0, surface = bg) => {
2320
+ if (!value) return void 0;
2321
+ let fontSize = Math.min(size, hh * 0.8);
2322
+ const lines = (font) => value.split("\n").reduce((sum, line) => sum + Math.max(1, Math.ceil(line.length * font * 0.68 / Math.max(1, ww))), 0);
2323
+ while (fontSize > 12 && lines(fontSize) * fontSize * 1.2 > hh) fontSize--;
2324
+ const result = layer2("text", name, x, y, ww, hh, { text: value, fontSize: Math.max(12, fontSize), color, splitText: "word", stagger: Math.min(d * stagger, d * 0.18 / Math.max(1, value.split(/\s+/).length)), staggerOrder: variant === "centered" ? "center" : "start", textUnitKeyframes: [point(0, 0, base * 0.065 * factor, 0.9, 0.9, energy === "punchy" ? 7 : 0, 0), { ...point(d * 0.18), easing: spring }], keyframes: [k(0, { opacity: delay > 0 ? 0 : 1 }), ...delay > 0 ? [k(delay, { opacity: 1, easing: "hold" })] : [], k(0.95)] });
2325
+ if (spec.emphasis) {
2326
+ const matches = [];
2327
+ let from = 0;
2328
+ while (from < value.length) {
2329
+ const start = value.indexOf(spec.emphasis, from);
2330
+ if (start < 0) break;
2331
+ matches.push([start, start + spec.emphasis.length]);
2332
+ from = start + Math.max(1, spec.emphasis.length);
2333
+ }
2334
+ result.textUnitColors = Array.from(value.matchAll(/\S+/gu), (unit) => matches.some(([start, end]) => unit.index < end && unit.index + unit[0].length > start) ? contrastText(surface, a, color) : color);
2335
+ }
2336
+ return result;
2337
+ };
2338
+ const localShape = (name, x, y, ww, hh, c = a, patch = {}) => shape(name, visual.x + x * visual.w, visual.y + y * visual.h, ww * visual.w, hh * visual.h, c, patch);
2339
+ const localText = (name, value, x, y, ww, hh, size = 0.07, c = fg, delay = 0, surface = bg) => text3(name, value, visual.x + x * visual.w, visual.y + y * visual.h, ww * visual.w, hh * visual.h, Math.min(base * size, visual.w * 0.22), c, delay, surface);
2340
+ const path = (name, x, y, ww, hh, pathData, c = a, sw = base * 6e-3, patch = {}) => layer2("path", name, x, y, ww, hh, { pathData, color: c, stroke: c, strokeWidth: sw, keyframes: [k(0, { reveal: 0 }), k(0.65, { reveal: 1, easing: [0.16, 0.85, 0.22, 1] }), k(0.96, { reveal: 1 })], ...patch });
2341
+ const number2 = (name, x, y, ww, hh, size, target = spec.value ?? 100) => layer2("text", name, x, y, ww, hh, { text: "0", fontSize: Math.min(size, hh * 0.8), textFit: "shrink", color: accentText, countFrom: spec.from ?? 0, countTo: target, countPrefix: spec.prefix, countSuffix: spec.suffix, countDecimals: spec.decimals ?? 0, countThousands: spec.thousands ?? true, keyframes: [k(0, { value: spec.from ?? 0, opacity: 0 }), k(0.07, { value: spec.from ?? 0 }), k(0.66, { value: target, easing: "ease-out" }), k(0.96, { value: target })] });
2342
+ const badge = (name, content, x, y, ww, hh, c = a) => {
2343
+ localShape(name, x, y, ww, hh, c);
2344
+ localText(`${name} \u05D8\u05E7\u05E1\u05D8`, content, x + 0.025, y + 0.15 * hh, ww - 0.05, hh * 0.7, 0.033, contrastText(c, palette.foreground, bg), 0, c);
2345
+ };
2346
+ const list2 = spec.items ?? spec.words ?? ["\u05E8\u05E2\u05D9\u05D5\u05DF", "\u05EA\u05E0\u05D5\u05E2\u05D4", "\u05EA\u05D5\u05E6\u05D0\u05D4"];
2347
+ const card = (item, i, n) => {
2348
+ const cols = variant === "centered" ? Math.min(3, n) : variant === "stacked" ? Math.min(4, n) : portrait ? 1 : Math.min(2, n), rows = Math.ceil(n / cols), gap = 0.035, cw = (1 - gap * (cols - 1)) / cols, ch = (0.88 - gap * (rows - 1)) / rows, x = i % cols * (cw + gap), y = Math.floor(i / cols) * (ch + gap);
2349
+ const c = i % 2 ? secondary : a;
2350
+ localShape(`\u05DB\u05E8\u05D8\u05D9\u05E1 ${i + 1}`, x, y, cw, ch, c, { rotation: variant === "stacked" ? i % 2 ? 2 : -2 : 0, depth: -0.1 - i * 0.03 });
2351
+ localText(`\u05DE\u05E1\u05E4\u05E8 \u05DB\u05E8\u05D8\u05D9\u05E1 ${i + 1}`, String(i + 1).padStart(2, "0"), x + 0.04, y + 0.04, cw - 0.08, ch * 0.27, 0.035, contrastText(c, palette.foreground, bg), Math.min(0.22, i * stagger), c);
2352
+ localText(`\u05D8\u05E7\u05E1\u05D8 \u05DB\u05E8\u05D8\u05D9\u05E1 ${i + 1}`, item, x + 0.04, y + ch * 0.35, cw - 0.08, ch * 0.54, 0.045, contrastText(c, palette.foreground, bg), Math.min(0.25, i * stagger), c);
2353
+ };
2354
+ if (spec.background === "gradient") shape("\u05DE\u05E2\u05D1\u05E8 \u05D2\u05D5\u05D5\u05DF", 0, 0, w, h, `linear-gradient(90deg, ${bg}, ${mix(bg, secondary, 0.32)})`, { keyframes: [k(0), k(1)], depth: 1, borderRadius: 0 });
2355
+ if (spec.background === "grid" || spec.background === "dots") {
2356
+ const dots = spec.background === "dots";
2357
+ for (let row = 0; row < (dots ? 8 : 1); row++) layer2("repeater", dots ? `\u05E8\u05E9\u05EA \u05E0\u05E7\u05D5\u05D3\u05D5\u05EA ${row + 1}` : "\u05E8\u05E9\u05EA \u05D0\u05E0\u05DB\u05D9\u05EA", w * 0.04, dots ? h * (0.15 + row * 0.1) : h * 0.12, dots ? base * 5e-3 : 1, dots ? base * 5e-3 : h * 0.75, { color: fg, opacity: 0.09, borderRadius: dots ? 10 : 0, depth: 1, keyframes: [k(0), k(1)], repeater: { count: dots ? 14 : 16, seed: seed + row | 0, shape: dots ? "ellipse" : "rect", offsetX: w * 0.068, offsetY: 0, rotation: 0, delay: 0 } });
2358
+ if (!dots) layer2("repeater", "\u05E8\u05E9\u05EA \u05D0\u05D5\u05E4\u05E7\u05D9\u05EA", w * 0.04, h * 0.15, w * 0.92, 1, { color: fg, opacity: 0.09, depth: 1, keyframes: [k(0), k(1)], repeater: { count: 8, seed, shape: "rect", offsetX: 0, offsetY: h * 0.1, rotation: 0, delay: 0 } });
2359
+ }
2360
+ if (spec.background === "motif") {
2361
+ const diameter = base * 0.58;
2362
+ const rings = [shape("\u05D8\u05D1\u05E2\u05EA \u05E8\u05D0\u05E9\u05D5\u05E0\u05D4", w * 0.03, h * 0.18, diameter, diameter, a, { color: bg, borderColor: a, borderWidth: base * 2e-3, borderRadius: diameter, opacity: 0.18, depth: 1 }), shape("\u05D8\u05D1\u05E2\u05EA \u05E9\u05E0\u05D9\u05D9\u05D4", w * 0.6, h * 0.35, diameter * 0.64, diameter * 0.64, secondary, { color: bg, borderColor: secondary, borderWidth: base * 0.018, borderRadius: diameter, opacity: 0.26, depth: 0.8 })];
2363
+ animateMotif({ scene: { ...scene, duration: 4 }, index, theme: "wedding-rings" }, rings);
2364
+ for (const ring of rings) ring.keyframes = ring.keyframes.map((frame) => ({ ...frame, at: frame.at / 4 * d }));
2365
+ }
2366
+ shape("\u05E7\u05D5 \u05DE\u05E2\u05E8\u05DB\u05EA", w * 0.06, h * 0.095, w * 0.88, 1, fg, { opacity: 0.2, depth: 1, keyframes: [k(0), k(1)] });
2367
+ text3("\u05DE\u05E1\u05E4\u05E8 \u05E1\u05E6\u05E0\u05D4", String(index + 1).padStart(2, "0"), w * 0.065, h * 0.05, w * 0.08, h * 0.03, base * 0.021, fg);
2368
+ shape("\u05E6\u05D9\u05E8 \u05E1\u05E6\u05E0\u05D4", w * 0.06, h * 0.925, w * 0.88, base * 4e-3, fg, { opacity: 0.15, keyframes: [k(0), k(1)] });
2369
+ shape("\u05E7\u05E6\u05D1 \u05E1\u05E6\u05E0\u05D4", w * 0.06, h * 0.925, w * 0.88, base * 4e-3, a, { transformOrigin: "left center", keyframes: [k(0, { scaleX: 0 }), k(1, { scaleX: 1, easing: "linear" })] });
2370
+ const header = text3("\u05DB\u05D5\u05EA\u05E8\u05EA", headline, titleRect.x, titleRect.y, titleRect.w, titleRect.h * 0.65, base * (headline && headline.length < 24 ? 0.09 : 0.065), fg);
2371
+ if (header) {
2372
+ header.textAlign = variant === "split" && !portrait ? "right" : "center";
2373
+ header.fontWeight = 850;
2374
+ }
2375
+ text3("\u05DB\u05D5\u05EA\u05E8\u05EA \u05DE\u05E9\u05E0\u05D4", spec.subtitle, titleRect.x, titleRect.y + titleRect.h * 0.7, titleRect.w, titleRect.h * 0.28, base * 0.033, fg, 0.08);
2376
+ switch (spec.type) {
2377
+ case "counter":
2378
+ case "donut": {
2379
+ const diameter = Math.min(visual.w * 0.85, visual.h * 0.72), x = visual.x + (visual.w - diameter) / 2, y = visual.y;
2380
+ const n = number2("\u05DE\u05D5\u05E0\u05D4", x + diameter * 0.07, y + diameter * 0.32, diameter * 0.86, diameter * 0.32, diameter * 0.23);
2381
+ if (spec.ring !== false || spec.type === "donut") {
2382
+ const pad = diameter * 0.045, r = diameter / 2 - pad, arc = `M ${diameter / 2} ${pad} A ${r} ${r} 0 1 1 ${diameter / 2 - 0.01} ${pad}`;
2383
+ path("\u05DE\u05E1\u05D9\u05DC\u05EA \u05D8\u05D1\u05E2\u05EA", x, y, diameter, diameter, arc, mix(bg, fg, 0.16), diameter * 0.035, { keyframes: [k(0, { reveal: 1 }), k(1, { reveal: 1 })] });
2384
+ path("\u05D8\u05D1\u05E2\u05EA \u05E2\u05E8\u05DA", x, y, diameter, diameter, arc, a, diameter * 0.035, { ...(spec.from ?? 0) === (spec.max ?? spec.value ?? 100) ? { keyframes: [k(0, { reveal: 1 }), k(1, { reveal: 1 })] } : { revealBinding: { layerId: n.id, from: spec.from ?? 0, to: spec.max ?? spec.value ?? 100 }, keyframes: [k(0), k(1)] } });
2385
+ }
2386
+ text3("\u05EA\u05D5\u05D5\u05D9\u05EA", spec.label, x - diameter * 0.1, y + diameter + base * 0.025, diameter * 1.2, Math.min(visual.h - diameter - base * 0.025, base * 0.09), base * 0.034, fg);
2387
+ break;
2388
+ }
2389
+ case "big-number": {
2390
+ localShape("\u05DC\u05D5\u05D7 \u05DE\u05E1\u05E4\u05E8", 0.02, 0.08, 0.96, 0.61, secondary, { rotation: variant === "stacked" ? -3 : 0 });
2391
+ const n = number2("\u05DE\u05E1\u05E4\u05E8 \u05D2\u05D3\u05D5\u05DC", visual.x + visual.w * 0.04, visual.y + visual.h * 0.1, visual.w * 0.92, visual.h * 0.51, base * 0.22);
2392
+ n.color = contrastText(secondary, a, palette.foreground);
2393
+ n.keyframes = n.keyframes.map((frame, i) => ({ ...frame, clip: { type: "inset", top: i ? 0 : 100, right: 0, bottom: 0, left: 0 }, blur: i ? 0 : 8 }));
2394
+ localText("\u05EA\u05D5\u05D5\u05D9\u05EA", spec.label, 0.05, 0.76, 0.9, 0.13, 0.04);
2395
+ break;
2396
+ }
2397
+ case "progress": {
2398
+ const n = number2("\u05DE\u05D5\u05E0\u05D4 \u05D4\u05EA\u05E7\u05D3\u05DE\u05D5\u05EA", visual.x, visual.y + visual.h * 0.05, visual.w, visual.h * 0.29, base * 0.13);
2399
+ const y = 0.49;
2400
+ localShape("\u05DE\u05E1\u05D9\u05DC\u05EA \u05D4\u05EA\u05E7\u05D3\u05DE\u05D5\u05EA", 0.03, y, 0.94, 0.065, secondary, { keyframes: [k(0), k(1)] });
2401
+ localShape("\u05DE\u05D9\u05DC\u05D5\u05D9 \u05D4\u05EA\u05E7\u05D3\u05DE\u05D5\u05EA", 0.03, y, 0.94, 0.065, a, { transformOrigin: "left center", ...(spec.from ?? 0) === (spec.max ?? spec.value ?? 100) ? { keyframes: [k(0, { reveal: 1 }), k(1, { reveal: 1 })] } : { revealBinding: { layerId: n.id, from: spec.from ?? 0, to: spec.max ?? spec.value ?? 100 }, keyframes: [k(0), k(1)] } });
2402
+ localText("\u05EA\u05D5\u05D5\u05D9\u05EA", spec.label, 0.02, 0.69, 0.96, 0.16, 0.045);
2403
+ break;
2404
+ }
2405
+ case "cards":
2406
+ list2.forEach((item, i) => card(item, i, list2.length));
2407
+ break;
2408
+ case "compare": {
2409
+ const n = 2;
2410
+ for (let i = 0; i < n; i++) {
2411
+ const vertical = variant === "stacked" || portrait, x = vertical ? 0 : i * 0.52, y = vertical ? i * 0.47 : 0, c = i ? a : secondary, cw = vertical ? 1 : 0.48, ch = vertical ? 0.42 : 0.86;
2412
+ localShape(`\u05D0\u05E4\u05E9\u05E8\u05D5\u05EA ${i + 1}`, x, y, cw, ch, c, { rotation: variant === "centered" ? i ? 2 : -2 : 0 });
2413
+ localText(`\u05E1\u05D9\u05DE\u05D5\u05DF \u05D0\u05E4\u05E9\u05E8\u05D5\u05EA ${i + 1}`, i ? "02" : "01", x + 0.04, y + 0.06, cw - 0.08, ch * 0.25, 0.045, contrastText(c, palette.foreground, bg));
2414
+ localText(`\u05EA\u05D5\u05DB\u05DF \u05D0\u05E4\u05E9\u05E8\u05D5\u05EA ${i + 1}`, list2[i] ?? (i ? "\u05D0\u05D7\u05E8\u05D9" : "\u05DC\u05E4\u05E0\u05D9"), x + 0.04, y + ch * 0.43, cw - 0.08, ch * 0.42, 0.058, contrastText(c, palette.foreground, bg), 0, c);
2415
+ }
2416
+ break;
2417
+ }
2418
+ case "checklist":
2419
+ case "chat":
2420
+ case "notification-stack": {
2421
+ const hasCta = spec.type === "notification-stack" && !!spec.cta, n = list2.length, gap = 0.025, ch = ((hasCta ? 0.7 : 0.92) - gap * (n - 1)) / n;
2422
+ list2.forEach((item, i) => {
2423
+ const chat = spec.type === "chat", x = chat ? i % 2 ? 0.03 : 0.16 : variant === "stacked" ? i * 0.012 : 0, c = i % 2 ? secondary : a, cw = chat ? 0.8 : 0.94;
2424
+ localShape(`${chat ? "\u05D1\u05D5\u05E2\u05D4" : "\u05D4\u05EA\u05E8\u05D0\u05D4"} ${i + 1}`, x, i * (ch + gap), cw, ch, c, { rotation: spec.type === "notification-stack" && variant === "centered" ? i % 2 ? 2 : -2 : 0, depth: -i * 0.03 });
2425
+ if (!chat) localText(`\u05E1\u05D9\u05DE\u05D5\u05DF ${i + 1}`, spec.type === "checklist" ? "\u2713" : "\u2022", x + 0.02, i * (ch + gap) + ch * 0.2, 0.1, ch * 0.55, 0.04, contrastText(c, palette.foreground, bg));
2426
+ localText(`\u05D4\u05D5\u05D3\u05E2\u05D4 ${i + 1}`, item, x + (chat ? 0.03 : 0.14), i * (ch + gap) + ch * 0.16, cw - (chat ? 0.06 : 0.18), ch * 0.68, 0.045, contrastText(c, palette.foreground, bg), Math.min(0.3, i * stagger), c);
2427
+ });
2428
+ if (hasCta) badge("\u05DB\u05E8\u05D8\u05D9\u05E1 \u05E4\u05E2\u05D5\u05DC\u05D4", spec.cta, 0.06, 0.78, 0.88, 0.16, a);
2429
+ break;
2430
+ }
2431
+ case "bars": {
2432
+ const values = spec.values ?? spec.rows?.map((r) => Number(r[1])) ?? [34, 49, 45, 63, 74, 91], max = spec.max ?? Math.max(1, ...values.map(Math.abs));
2433
+ const vertical = variant !== "split", n = values.length;
2434
+ values.forEach((v, i) => {
2435
+ const band = 0.9 / n, c = i === n - 1 ? a : secondary, name = spec.rows?.[i]?.[0] ?? spec.items?.[i] ?? String(i + 1), ratio = Math.min(1, Math.abs(v) / max);
2436
+ const delay = 0.06 + i * 0.24 / Math.max(1, n - 1), enter = delay + (energy === "calm" ? 0.42 : energy === "punchy" ? 0.27 : 0.35), height = visual.h * 0.65 * ratio;
2437
+ const poses = (value) => [k(0, { ...value ? { value: 0, y: vertical ? height : 0 } : { scaleY: vertical ? 0 : 1, scaleX: vertical ? 1 : 0 }, opacity: 0 }), k(delay, { ...value ? { value: 0, y: vertical ? height : 0 } : { scaleY: vertical ? 0 : 1, scaleX: vertical ? 1 : 0 } }), k(enter, { ...value ? { value: v } : {}, easing: spring }), k(0.96, { ...value ? { value: v } : {} })];
2438
+ if (vertical) {
2439
+ const x = 0.04 + i * band, bh = 0.65 * ratio;
2440
+ localShape(`\u05E2\u05DE\u05D5\u05D3\u05D4 ${i + 1}`, x, 0.72 - bh, band * 0.66, bh, c, { transformOrigin: "center bottom", keyframes: poses(false) });
2441
+ const numeric = number2(`\u05E2\u05E8\u05DA ${i + 1}`, visual.x + (x - 0.01) * visual.w, visual.y + (0.72 - bh - 0.105) * visual.h, band * 0.75 * visual.w, 0.085 * visual.h, base * 0.03, v);
2442
+ numeric.color = fg;
2443
+ numeric.countFrom = 0;
2444
+ numeric.keyframes = poses(true);
2445
+ localText(`\u05E9\u05DD ${i + 1}`, name, x - 0.02, 0.8, band * 0.8, 0.13, 0.026);
2446
+ } else {
2447
+ localText(`\u05E9\u05DD ${i + 1}`, name, 0, 0.02 + i * band, 0.22, band * 0.72, 0.032);
2448
+ localShape(`\u05E2\u05DE\u05D5\u05D3\u05D4 ${i + 1}`, 0.26, 0.04 + i * band, 0.56 * ratio, band * 0.48, c, { transformOrigin: "left center", keyframes: poses(false) });
2449
+ const numeric = number2(`\u05E2\u05E8\u05DA ${i + 1}`, visual.x + visual.w * 0.84, visual.y + (0.015 + i * band) * visual.h, visual.w * 0.15, visual.h * band * 0.76, base * 0.032, v);
2450
+ numeric.color = fg;
2451
+ numeric.countFrom = 0;
2452
+ numeric.keyframes = poses(true);
2453
+ }
2454
+ });
2455
+ break;
2456
+ }
2457
+ case "line-chart":
2458
+ case "map-route": {
2459
+ const values = spec.values ?? [25, 55, 42, 81, 67, 96], lo = Math.min(...values), hi = Math.max(...values), n = values.length;
2460
+ const points = spec.type === "line-chart" ? values.map((v, i) => [visual.w * (0.08 + i * 0.84 / (n - 1)), visual.h * (0.77 - (v - lo) / Math.max(1, hi - lo) * 0.62)]) : [[visual.w * 0.08, visual.h * 0.75], [visual.w * 0.44, visual.h * 0.18], [visual.w * 0.88, visual.h * 0.55]];
2461
+ for (let i = 0; i < 4; i++) localShape(`\u05E7\u05D5 \u05D2\u05E8\u05E3 ${i + 1}`, 0.05, 0.15 + i * 0.2, 0.9, 2e-3, fg, { opacity: 0.14, keyframes: [k(0), k(1)] });
2462
+ const lengths = points.map((p, i) => i ? Math.hypot(p[0] - points[i - 1][0], p[1] - points[i - 1][1]) : 0);
2463
+ const total = lengths.reduce((sum, v) => sum + v, 0);
2464
+ let covered = 0;
2465
+ const timing = points.map((_, i) => {
2466
+ covered += lengths[i];
2467
+ return total ? covered / total : i / (points.length - 1);
2468
+ });
2469
+ const geometry = points.map((p, i) => `${i ? "L" : "M"} ${p[0]} ${p[1]}`).join(" ");
2470
+ path(spec.type === "line-chart" ? "\u05E7\u05D5 \u05DE\u05D2\u05DE\u05D4" : "\u05DE\u05E1\u05DC\u05D5\u05DC", visual.x, visual.y, visual.w, visual.h, geometry, a, base * 8e-3, { keyframes: [k(0, { reveal: 0 }), k(0.12, { reveal: 0 }), ...points.slice(1).map((_, i) => k(0.12 + timing[i + 1] * 0.58, { reveal: timing[i + 1], easing: "linear" })), k(0.96, { reveal: 1 })] });
2471
+ const p0 = points[0], dot = base * 0.025;
2472
+ shape("\u05E0\u05E7\u05D5\u05D3\u05D4 \u05E0\u05E2\u05D4", visual.x + p0[0] - dot / 2, visual.y + p0[1] - dot / 2, dot, dot, a, { borderRadius: dot, glow: 8, glowColor: a, keyframes: [k(0, { opacity: 0 }), k(0.12), ...points.slice(1).map((p, i) => k(0.12 + timing[i + 1] * 0.58, { x: p[0] - p0[0], y: p[1] - p0[1], easing: "linear" })), k(0.96, { x: points.at(-1)[0] - p0[0], y: points.at(-1)[1] - p0[1] })] });
2473
+ if (spec.type === "map-route") (spec.items ?? ["\u05D9\u05D5\u05E6\u05D0\u05D9\u05DD", "\u05D1\u05D3\u05E8\u05DA", "\u05DE\u05D2\u05D9\u05E2\u05D9\u05DD"]).forEach((item, i, arr) => localText(`\u05EA\u05D7\u05E0\u05EA \u05DE\u05E1\u05DC\u05D5\u05DC ${i + 1}`, item, i * 0.9 / Math.max(1, arr.length), 0.86, 0.9 / arr.length, 0.1, 0.03));
2474
+ break;
2475
+ }
2476
+ case "timeline": {
2477
+ const n = list2.length, vertical = variant === "stacked" || portrait;
2478
+ localShape("\u05E7\u05D5 \u05D6\u05DE\u05DF", vertical ? 0.16 : 0.05, vertical ? 0.04 : 0.39, vertical ? 8e-3 : 0.88, vertical ? 0.83 : 9e-3, secondary, { keyframes: [k(0, { scaleX: vertical ? 1 : 0, scaleY: vertical ? 0 : 1 }), k(0.7)] });
2479
+ list2.forEach((item, i) => {
2480
+ const step = 0.84 / Math.max(1, n - 1), x = vertical ? 0.12 : 0.05 + i * step, y = vertical ? 0.04 + i * step : 0.35, size = Math.min(base * 0.055, visual.w / (n + 2));
2481
+ shape(`\u05EA\u05D7\u05E0\u05D4 ${i + 1}`, visual.x + x * visual.w, visual.y + y * visual.h, size, size, a, { borderRadius: size, keyframes: pulse(4, i * 0.03).map((k2) => ({ ...k2, at: k2.at / 4 * d })) });
2482
+ localText(`\u05E9\u05DD \u05EA\u05D7\u05E0\u05D4 ${i + 1}`, item, vertical ? 0.26 : Math.max(0, x - 0.06), vertical ? y - 0.01 : 0.57, vertical ? 0.7 : Math.min(0.18, 0.92 / n), vertical ? 0.8 / n : 0.18, 0.035);
2483
+ });
2484
+ break;
2485
+ }
2486
+ case "phone": {
2487
+ const pw = Math.min(visual.w * 0.67, visual.h * 0.63), ph = Math.min(visual.h * 0.94, pw * 1.62), px = visual.x + (visual.w - pw) / 2, py = visual.y;
2488
+ const first = scene.layers.length;
2489
+ shape("\u05DE\u05E1\u05D2\u05E8\u05EA \u05D8\u05DC\u05E4\u05D5\u05DF", px, py, pw, ph, fg, { borderRadius: pw * 0.1 });
2490
+ shape("\u05DE\u05E1\u05DA \u05D8\u05DC\u05E4\u05D5\u05DF", px + pw * 0.035, py + ph * 0.025, pw * 0.93, ph * 0.95, bg, { borderRadius: pw * 0.08 });
2491
+ shape("\u05E2\u05D3\u05E9\u05D4", px + pw * 0.35, py + ph * 0.045, pw * 0.3, ph * 0.025, fg, { borderRadius: base * 0.02 });
2492
+ text3("\u05DB\u05D5\u05EA\u05E8\u05EA \u05DE\u05E1\u05DA", spec.product ?? spec.label, px + pw * 0.09, py + ph * 0.15, pw * 0.82, ph * 0.13, pw * 0.11, fg);
2493
+ const rows = spec.rows ?? (spec.items ?? ["\u05D4\u05DB\u05D5\u05DC \u05D1\u05DE\u05E7\u05D5\u05DD \u05D0\u05D7\u05D3", "\u05E4\u05E9\u05D5\u05D8 \u05DC\u05D4\u05EA\u05E7\u05D3\u05DD", "\u05DE\u05D5\u05DB\u05E0\u05D9\u05DD \u05DC\u05D3\u05E8\u05DA"]).map((item) => [item]);
2494
+ rows.forEach((row, i) => {
2495
+ const yy = py + ph * (0.34 + i * 0.42 / rows.length), hh = ph * 0.32 / rows.length;
2496
+ shape(`\u05DB\u05E8\u05D8\u05D9\u05E1 \u05DE\u05E1\u05DA ${i + 1}`, px + pw * 0.08, yy, pw * 0.84, hh, i % 2 ? secondary : a, { borderRadius: pw * 0.025 });
2497
+ text3(`\u05E9\u05D5\u05E8\u05EA \u05DE\u05E1\u05DA ${i + 1}`, row.join(" "), px + pw * 0.12, yy + hh * 0.14, pw * 0.76, hh * 0.7, pw * 0.065, contrastText(i % 2 ? secondary : a, palette.foreground, bg));
2498
+ });
2499
+ text3("\u05E4\u05E2\u05D5\u05DC\u05D4 \u05D1\u05DE\u05E1\u05DA", spec.cta ?? "\u05DC\u05D4\u05DE\u05E9\u05DA", px + pw * 0.1, py + ph * 0.84, pw * 0.8, ph * 0.08, pw * 0.075, accentText);
2500
+ const children = scene.layers.splice(first).map((l) => ({ ...l, x: l.x - px, y: l.y - py, keyframes: [k(0), k(0.96)] }));
2501
+ layer2("group", "\u05D8\u05DC\u05E4\u05D5\u05DF", px, py, pw, ph, { children, perspective: base * 1.5, depth: -0.5, rotation: variant === "stacked" ? -5 : 0, keyframes: [k(0, { y: base * 0.14, rotateY: -25, opacity: 0 }), k(0.27, { easing: spring }), k(0.94, { rotateY: variant === "centered" ? 5 : -3, y: -base * 0.01 })] });
2502
+ break;
2503
+ }
2504
+ case "ui-cursor": {
2505
+ localShape("\u05D7\u05DC\u05D5\u05DF \u05DE\u05DE\u05E9\u05E7", 0.04, 0.05, 0.92, 0.79, secondary, { borderColor: fg, borderWidth: 1 });
2506
+ localShape("\u05E1\u05E8\u05D2\u05DC \u05D7\u05DC\u05D5\u05DF", 0.04, 0.05, 0.92, 0.1, fg);
2507
+ localText("\u05EA\u05D5\u05DB\u05DF \u05DE\u05DE\u05E9\u05E7", spec.label ?? spec.product, 0.12, 0.22, 0.76, 0.18, 0.055, contrastText(secondary, palette.foreground, bg));
2508
+ const button = localShape("\u05DB\u05E4\u05EA\u05D5\u05E8", 0.21, 0.54, 0.58, 0.17, a, { keyframes: [k(0), k(0.52), k(0.58, { scaleX: 0.94, scaleY: 0.94, easing: "ease-out" }), k(0.67, { easing: spring }), k(0.96)] });
2509
+ localText("\u05D8\u05E7\u05E1\u05D8 \u05DB\u05E4\u05EA\u05D5\u05E8", spec.cta ?? "\u05DE\u05EA\u05D7\u05D9\u05DC\u05D9\u05DD", 0.24, 0.57, 0.52, 0.11, 0.04, contrastText(a, palette.foreground, bg));
2510
+ const size = base * 0.06, cx = button.x + button.width * 0.64, cy = button.y + button.height * 0.5;
2511
+ layer2("svg", "\u05E1\u05DE\u05DF", cx, cy, size, size * 1.2, { pathData: `M 2 2 L ${size * 0.73} ${size * 0.58} L ${size * 0.46} ${size * 0.62} L ${size * 0.66} ${size} L ${size * 0.48} ${size * 1.1} L ${size * 0.28} ${size * 0.7} L 2 ${size * 0.92} Z`, color: fg, stroke: bg, strokeWidth: 2, keyframes: [k(0, { x: visual.w * 0.3, y: visual.h * 0.24, opacity: 0 }), k(0.18, { x: visual.w * 0.3, y: visual.h * 0.24 }), k(0.5, { easing: [0.16, 0.85, 0.22, 1] }), k(0.58, { scaleX: 0.86, scaleY: 0.86 }), k(0.67, { easing: spring }), k(0.96)] });
2512
+ shape("\u05D2\u05DC \u05DC\u05D7\u05D9\u05E6\u05D4", cx - size * 0.3, cy - size * 0.3, size, size, a, { borderRadius: size, color: a, opacity: 0.35, keyframes: [k(0, { scaleX: 0, scaleY: 0, opacity: 0 }), k(0.53, { scaleX: 0, scaleY: 0, opacity: 0 }), k(0.58, { scaleX: 0.4, scaleY: 0.4, opacity: 1 }), k(0.78, { scaleX: 2, scaleY: 2, opacity: 0 }), k(0.96, { opacity: 0 })] });
2513
+ break;
2514
+ }
2515
+ case "coins": {
2516
+ const size = Math.min(visual.w * 0.15, visual.h * 0.22);
2517
+ layer2("repeater", "\u05DE\u05D8\u05D1\u05E2\u05D5\u05EA", visual.x + visual.w * 0.12, visual.y + visual.h * 0.12, size, size, { color: secondary, borderColor: a, borderWidth: size * 0.06, borderRadius: size, depth: -0.2, repeater: { count: 7, seed, shape: "ellipse", offsetX: visual.w * 0.09, offsetY: visual.h * 0.035, rotation: 12, delay: d * 0.02, jitterY: visual.h * 0.09, jitterRotation: 22, colors: [a, secondary] }, keyframes: flight(4, 0, 0, -160, 0, -12, 8).map((frame) => ({ ...frame, at: frame.at / 4 * d, x: frame.x * base / 1080, y: frame.y * base / 1080 })) });
2518
+ number2("\u05E1\u05DB\u05D5\u05DD", visual.x, visual.y + visual.h * 0.53, visual.w, visual.h * 0.23, base * 0.12);
2519
+ localText("\u05EA\u05D5\u05D5\u05D9\u05EA", spec.label, 0.05, 0.83, 0.9, 0.12, 0.035);
2520
+ break;
2521
+ }
2522
+ case "confetti": {
2523
+ layer2("repeater", "\u05E7\u05D5\u05E0\u05E4\u05D8\u05D9", visual.x, visual.y + visual.h * 0.1, base * 0.018, base * 0.043, { color: a, repeater: { count: 28, seed, shape: "rect", offsetX: visual.w / 28, offsetY: 0, rotation: 13, delay: d * 8e-3, jitterY: visual.h * 0.5, jitterRotation: 120, colors: [a, secondary, fg] }, depth: 0.5, keyframes: [k(0, { y: visual.h * 0.8, opacity: 0, rotation: -25 }), k(0.3, { easing: spring }), k(0.96, { y: -visual.h * 0.2, rotation: 45, easing: "linear" })] });
2524
+ localShape("\u05D7\u05D5\u05EA\u05DD \u05D7\u05D2\u05D9\u05D2\u05D4", 0.25, 0.13, 0.5, 0.6, a, { borderRadius: base * 0.25, rotation: -6 });
2525
+ localText("\u05D7\u05D5\u05EA\u05DD", spec.emphasis ?? "\u2713", 0.3, 0.25, 0.4, 0.32, 0.16, contrastText(a, palette.foreground, bg), 0, a);
2526
+ break;
2527
+ }
2528
+ case "kinetic": {
2529
+ const words = spec.words ?? [spec.emphasis ?? headline ?? "\u05D1\u05EA\u05E0\u05D5\u05E2\u05D4"];
2530
+ words.forEach((word, i) => {
2531
+ const yy = i * 0.92 / words.length;
2532
+ const l = localText(`\u05DE\u05D9\u05DC\u05D4 ${i + 1}`, word, 0, yy, 1, 0.84 / words.length, 0.12, i % 2 ? accentText : fg, Math.min(0.32, i * (spec.beat ?? 0.5) / d));
2533
+ if (l) {
2534
+ l.splitText = "letter";
2535
+ l.staggerOrder = variant === "centered" ? "center" : variant === "stacked" ? "end" : "start";
2536
+ l.stagger = Math.min(d * 0.016, d * 0.12 / word.length);
2537
+ l.fontWeight = 900;
2538
+ l.textUnitKeyframes = [point(0, base * 0.03, base * 0.06, 0.65, 0.65, -7, 0), { ...point(d * 0.18), easing: spring }];
2539
+ }
2540
+ });
2541
+ break;
2542
+ }
2543
+ case "marquee": {
2544
+ const words = spec.words ?? spec.items ?? [spec.emphasis ?? headline ?? "\u05E7\u05D3\u05D9\u05DE\u05D4"];
2545
+ const value = words.join(" \xB7 "), stripes = variant === "centered" ? 3 : 2, band = spec.cta ? 0.72 : 1;
2546
+ for (let i = 0; i < stripes; i++) {
2547
+ const y = visual.y + visual.h * (0.08 + i * 0.29) * band, c = i % 2 ? secondary : a;
2548
+ shape(`\u05E1\u05E8\u05D8 ${i + 1}`, visual.x - visual.w * 0.06, y, visual.w * 1.12, visual.h * 0.22 * band, c, { rotation: i % 2 ? -4 : 4 });
2549
+ for (let copy = 0; copy < 2; copy++) {
2550
+ const l = text3(`\u05D8\u05E7\u05E1\u05D8 \u05E0\u05E2 ${i + 1}.${copy}`, value, visual.x + copy * visual.w * 0.95, y + visual.h * 0.035 * band, visual.w * 0.95, visual.h * 0.15 * band, base * 0.065, contrastText(c, palette.foreground, bg));
2551
+ if (l) {
2552
+ l.splitText = "none";
2553
+ l.textUnitKeyframes = void 0;
2554
+ l.keyframes = [k(0, { x: i % 2 ? -visual.w * 0.95 : 0 }), k(1, { x: i % 2 ? 0 : -visual.w * 0.95, easing: "linear" })];
2555
+ }
2556
+ }
2557
+ }
2558
+ if (spec.cta) badge("\u05DB\u05E8\u05D8\u05D9\u05E1 \u05E4\u05E2\u05D5\u05DC\u05D4", spec.cta, 0.06, 0.78, 0.88, 0.16, a);
2559
+ break;
2560
+ }
2561
+ case "hook":
2562
+ case "endcard":
2563
+ case "freeze":
2564
+ case "quote":
2565
+ case "logo": {
2566
+ if (spec.type === "quote") {
2567
+ localText("\u05E1\u05D9\u05DE\u05DF \u05E6\u05D9\u05D8\u05D5\u05D8", "\u05F4", 0.01, 0.01, 0.3, 0.4, 0.28, accentText);
2568
+ localShape("\u05E4\u05E1 \u05E6\u05D9\u05D8\u05D5\u05D8", 0.1, 0.61, 0.8, 0.012, a);
2569
+ localText("\u05D9\u05D9\u05D7\u05D5\u05E1", spec.label, 0.03, 0.76, 0.94, 0.14, 0.04);
2570
+ } else if (spec.type === "logo") {
2571
+ localShape("\u05E1\u05DE\u05DC \u05DE\u05D5\u05EA\u05D2", 0.22, 0.02, 0.56, 0.64, a, { borderRadius: base * 0.08, rotation: variant === "stacked" ? -8 : 0 });
2572
+ localShape("\u05DE\u05E8\u05DB\u05D6 \u05E1\u05DE\u05DC", 0.38, 0.17, 0.24, 0.29, bg, { borderRadius: base * 0.035, rotation: 45 });
2573
+ localText("\u05D7\u05EA\u05D9\u05DE\u05D4", spec.label, 0.05, 0.8, 0.9, 0.13, 0.04);
2574
+ } else if (spec.type === "freeze") {
2575
+ localShape("\u05E7\u05D5 \u05D4\u05E7\u05E4\u05D0\u05D4", 0.03, 0.48, 0.94, 0.017, a, { keyframes: [k(0, { scaleX: 0 }), k(0.28, { easing: spring }), k(0.9)] });
2576
+ localText("\u05DE\u05E1\u05E8 \u05D4\u05E7\u05E4\u05D0\u05D4", spec.label ?? spec.emphasis, 0.03, 0.14, 0.94, 0.23, 0.08, accentText);
2577
+ localText("\u05EA\u05D5\u05D5\u05D9\u05EA", spec.cta, 0.05, 0.7, 0.9, 0.15, 0.035);
2578
+ } else {
2579
+ const size = Math.min(visual.w * 0.65, visual.h * 0.7), x = visual.x + (visual.w - size) / 2;
2580
+ shape("\u05D3\u05D9\u05E1\u05E7 \u05EA\u05E0\u05D5\u05E2\u05D4", x, visual.y, size, size, a, { borderRadius: size, perspective: base * 1.8, depth: -0.4, modifiers: [{ type: "float", amplitude: base * 8e-3 * factor, frequency: 0.15, seed }], keyframes: [k(0, { rotateY: -50, rotation: -30, scaleX: 0.3, scaleY: 0.3, opacity: 0 }), k(0.32, { easing: spring }), k(0.95, { rotateY: 15, rotation: 12 })] });
2581
+ shape("\u05DC\u05D9\u05D1\u05EA \u05D3\u05D9\u05E1\u05E7", x + size * 0.27, visual.y + size * 0.27, size * 0.46, size * 0.46, bg, { borderRadius: size });
2582
+ if (spec.type === "endcard") {
2583
+ badge("\u05DB\u05E8\u05D8\u05D9\u05E1 \u05E4\u05E2\u05D5\u05DC\u05D4", spec.cta ?? "\u05DE\u05EA\u05D7\u05D9\u05DC\u05D9\u05DD \u05DB\u05D0\u05DF", 0.06, 0.75, 0.88, 0.19, a);
2584
+ } else localText("\u05D4\u05D3\u05D2\u05E9\u05D4", spec.emphasis ?? spec.label, 0.02, 0.78, 0.96, 0.15, 0.05, accentText);
2585
+ }
2586
+ break;
2587
+ }
2588
+ }
2589
+ if (spec.camera !== "none") {
2590
+ const key = (at, x = 0, y = 0, zoom = 1, rotation = 0) => ({ at, x, y, zoom, rotation, easing: "linear" });
2591
+ scene.camera = { keyframes: spec.camera === "orbit" ? [key(0, -base * 8e-3, base * 8e-3, 1.025, -0.6 * factor), key(d * 0.5, base * 8e-3, -base * 8e-3, 1.04, 0.4 * factor), key(d, 0, 0, 1.025, -0.2 * factor)] : spec.camera === "drift" ? [key(0, -base * 0.01, 0, 1.035), key(d, base * 0.01, -base * 0.012, 1.035, 0.25 * factor)] : [key(0), key(d, 0, -base * 7e-3, 1 + 0.035 * factor)] };
2592
+ }
2593
+ return scene;
2594
+ }
2595
+
2596
+ // src/core/config-v3.ts
2597
+ var configV3ThemePalettes = {
2598
+ summer_ice: { background: "#e7f8ff", foreground: "#081b37", accent: "#0989d8", secondary: "#ffce42" },
2599
+ bank_red: { background: "#ffffff", foreground: "#172239", accent: "#e30613", secondary: "#ffe8e9" },
2600
+ midnight: { background: "#07152f", foreground: "#ffffff", accent: "#44e0d0", secondary: "#1a3158" },
2601
+ warm: { background: "#fff6eb", foreground: "#29213d", accent: "#f15a43", secondary: "#ffdb8a" },
2602
+ mono: { background: "#101216", foreground: "#ffffff", accent: "#eeeeee", secondary: "#41444c" },
2603
+ flow: { background: "#101e2b", foreground: "#f1f3eb", accent: "#c8f36a", secondary: "#749cff" },
2604
+ pulse: { background: "#111313", foreground: "#f5f4ef", accent: "#d1ff48", secondary: "#b9a4ff" },
2605
+ orbit: { background: "#f8f2e7", foreground: "#173d8f", accent: "#ff806c", secondary: "#f4d86b" }
2606
+ };
2607
+ function configV3ToProject(input) {
2608
+ const config = parseMotionConfigV3(input), [width, height] = config.aspectRatio === "9:16" ? [1080, 1920] : config.aspectRatio === "1:1" ? [1080, 1080] : [1920, 1080];
2609
+ const palette = { ...configV3ThemePalettes[config.theme], ...config.palette };
2610
+ const scenes = config.scenes.map((spec, index) => ({ ...compileConfigV3Scene(spec, palette, width, height, config.seed, index), configV3: { config: structuredClone(config), sceneIndex: index } }));
2611
+ const project = createProject(config.title, { canvas: { width, height, fps: config.fps }, scenes });
2612
+ project.schemaVersion = 3;
2613
+ if (config.beats) project.beats = [...config.beats];
2614
+ if (config.motionBlur) project.renderSettings = { motionBlur: { ...config.motionBlur } };
2615
+ assertProject(project);
2616
+ return project;
2617
+ }
2618
+ function upgradeConfigV2ToV3(input) {
2619
+ const legacy = parseMotionConfigV2(input);
2620
+ const clean = (raw) => {
2621
+ if (typeof raw === "string" && !raw.trim()) return void 0;
2622
+ if (Array.isArray(raw)) {
2623
+ const entries = raw.map(clean).filter((value) => value !== void 0);
2624
+ return entries.length ? entries : void 0;
2625
+ }
2626
+ if (raw && typeof raw === "object") return Object.fromEntries(Object.entries(raw).map(([key, value]) => [key, clean(value)]).filter(([, value]) => value !== void 0));
2627
+ return raw;
2628
+ };
2629
+ return parseMotionConfigV3({ ...clean(legacy), format: "motiondesk-config/v3" });
2630
+ }
2631
+ function rebuildConfigV3Scene(project, sceneId, patch) {
2632
+ assertProject(project);
2633
+ if (!patch || typeof patch !== "object" || Array.isArray(patch) || Object.keys(patch).some((key) => !["variant", "energy"].includes(key))) throw new Error("\u05E2\u05D3\u05DB\u05D5\u05DF \u05E4\u05E8\u05D9\u05E1\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF");
2634
+ const position = project.scenes.findIndex((s) => s.id === sceneId);
2635
+ if (position < 0) throw new Error("\u05D4\u05E1\u05E6\u05E0\u05D4 \u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D4");
2636
+ const scene = project.scenes[position], recipe = scene.configV3;
2637
+ if (!recipe) throw new Error("\u05DC\u05E1\u05E6\u05E0\u05D4 \u05D0\u05D9\u05DF \u05DE\u05EA\u05DB\u05D5\u05DF v3");
2638
+ const config = structuredClone(recipe.config), spec = config.scenes[recipe.sceneIndex];
2639
+ Object.assign(spec, patch);
2640
+ const normalized = parseMotionConfigV3(config), palette = { ...configV3ThemePalettes[normalized.theme], ...normalized.palette };
2641
+ if (/^#[a-fA-F0-9]{6}$/.test(scene.background)) palette.background = scene.background;
2642
+ const generated = compileConfigV3Scene({ ...normalized.scenes[recipe.sceneIndex], duration: scene.duration }, palette, project.canvas.width, project.canvas.height, normalized.seed, recipe.sceneIndex);
2643
+ const rebuilt = { ...generated, id: scene.id, name: scene.name, duration: scene.duration, background: scene.background, transition: scene.transition, transitionDuration: scene.transitionDuration, transitionEasing: scene.transitionEasing, configV3: { config: normalized, sceneIndex: recipe.sceneIndex } };
2644
+ const scenes = [...project.scenes];
2645
+ scenes[position] = rebuilt;
2646
+ const result = { ...project, schemaVersion: 3, scenes };
2647
+ assertProject(result);
2648
+ return result;
2649
+ }
2650
+
2651
+ // src/core/visualMotion.ts
2652
+ var RED = "#E3063B";
2653
+ var DEEP_RED = "#A90037";
2654
+ var NAVY = "#10192A";
2655
+ var WHITE = "#FFFFFF";
2656
+ var PALE = "#FFF1F4";
2657
+ function layer(ctx, type, name, x, y, width, height, color, opts = {}) {
2658
+ const result = createLayer(type, {
2659
+ name,
2660
+ x,
2661
+ y,
2662
+ width,
2663
+ height,
2664
+ color,
2665
+ text: opts.text,
2666
+ fontSize: opts.size ?? 48,
2667
+ fontWeight: opts.weight ?? 700,
2668
+ fontFamily: "Arial",
2669
+ textAlign: opts.align ?? "center",
2670
+ borderRadius: opts.radius ?? 0,
2671
+ rotation: opts.rotation ?? 0,
2672
+ opacity: opts.opacity ?? 1,
2673
+ motion: "none",
2674
+ start: 0,
2675
+ duration: ctx.scene.duration,
2676
+ keyframes: opts.keys ?? flight(ctx.scene.duration, 0)
2677
+ });
2678
+ ctx.scene.layers.push(result);
2679
+ return result;
2680
+ }
2681
+ function box(ctx, name, x, y, width, height, color = ctx.accent, radius = 0, delay = 0, fromX = -140, travelX = 14, opacity = 1, rotation = 0) {
2682
+ return layer(ctx, "shape", name, ctx.ox + x, ctx.oy + y, width, height, color, {
2683
+ radius,
2684
+ opacity,
2685
+ rotation,
2686
+ keys: flight(ctx.scene.duration, delay, fromX, 0, travelX, -6, rotation * 0.08)
2687
+ });
2688
+ }
2689
+ function caption(ctx, name, text3, x, y, width, height, size = 38, color = ctx.ink, delay = 0.25) {
2690
+ return layer(ctx, "text", name, ctx.ox + x, ctx.oy + y, width, height, color, {
2691
+ text: text3,
2692
+ size,
2693
+ weight: 800,
2694
+ align: "center",
2695
+ keys: flight(ctx.scene.duration, delay, 0, 80, 0, -12)
2696
+ });
2697
+ }
2698
+ function motif(ctx) {
2699
+ const a = ctx.accent, ink = ctx.ink, surface = ctx.surface;
2700
+ const sq = (name, x, y, d, color = a, delay = 0) => box(ctx, name, x, y, d, d, color, d * 0.18, delay);
2701
+ const circle = (name, x, y, d, color = a, delay = 0) => box(ctx, name, x, y, d, d, color, d / 2, delay);
2702
+ const bar = (name, x, y, w, h = 18, color = a, delay = 0) => box(ctx, name, x, y, w, h, color, h / 2, delay);
2703
+ switch (ctx.theme) {
2704
+ case "car-road":
2705
+ box(ctx, "\u05DB\u05D1\u05D9\u05E9", 30, 590, 690, 32, ink, 16, 0, -460, 70);
2706
+ for (let i = 0; i < 4; i++) bar(`\u05E1\u05D9\u05DE\u05D5\u05DF \u05DB\u05D1\u05D9\u05E9 ${i + 1}`, 80 + i * 170, 600, 78, 8, surface, 0.2 + i * 0.13);
2707
+ box(ctx, "\u05E6\u05DC \u05E8\u05DB\u05D1", 136, 550, 502, 28, NAVY, 14, 0.2, -430, 50, 0.3);
2708
+ for (let i = 0; i < 3; i++) bar(`\u05E9\u05D5\u05D1\u05DC \u05DE\u05D4\u05D9\u05E8\u05D5\u05EA ${i + 1}`, 40 - i * 18, 432 + i * 44, 110 + i * 35, 7, surface, 0.35 + i * 0.12);
2709
+ box(ctx, "\u05DE\u05E8\u05DB\u05D1 \u05E8\u05DB\u05D1", 110, 390, 520, 170, a, 74, 0.2, -430, 50);
2710
+ box(ctx, "\u05D2\u05D2 \u05E8\u05DB\u05D1", 245, 315, 250, 125, a, 78, 0.3, -430, 50);
2711
+ box(ctx, "\u05D7\u05DC\u05D5\u05DF \u05E7\u05D3\u05DE\u05D9", 370, 327, 95, 68, surface, 16, 0.52, -430, 50);
2712
+ box(ctx, "\u05D7\u05DC\u05D5\u05DF \u05D0\u05D7\u05D5\u05E8\u05D9", 270, 327, 90, 68, surface, 16, 0.47, -430, 50);
2713
+ box(ctx, "\u05E4\u05E0\u05E1 \u05E7\u05D3\u05DE\u05D9", 602, 427, 28, 49, "#FFE1A8", 13, 0.48, -430, 50);
2714
+ box(ctx, "\u05E4\u05E0\u05E1 \u05D0\u05D7\u05D5\u05E8\u05D9", 106, 429, 23, 46, "#FF7A98", 11, 0.48, -430, 50);
2715
+ for (const [i, x] of [185, 505].entries()) {
2716
+ circle(`\u05D2\u05DC\u05D2\u05DC ${i + 1}`, x, 500, 98, NAVY, 0.43 + i * 0.08);
2717
+ circle(`\u05DE\u05E8\u05DB\u05D6 \u05D2\u05DC\u05D2\u05DC ${i + 1}`, x + 27, 527, 44, WHITE, 0.55 + i * 0.08);
2718
+ box(ctx, `\u05D7\u05D9\u05E9\u05D5\u05E8 \u05D0\u05E0\u05DB\u05D9 ${i + 1}`, x + 43, 530, 12, 38, NAVY, 6, 0.58 + i * 0.08, -430, 50);
2719
+ box(ctx, `\u05D7\u05D9\u05E9\u05D5\u05E8 \u05D0\u05D5\u05E4\u05E7\u05D9 ${i + 1}`, x + 30, 543, 38, 12, NAVY, 6, 0.58 + i * 0.08, -430, 50);
2720
+ }
2721
+ break;
2722
+ case "holiday-table":
2723
+ circle("\u05E6\u05DC\u05D7\u05EA \u05D7\u05D9\u05E6\u05D5\u05E0\u05D9\u05EA", 140, 170, 490, surface, 0.1);
2724
+ circle("\u05E6\u05DC\u05D7\u05EA \u05E4\u05E0\u05D9\u05DE\u05D9\u05EA", 205, 235, 360, a, 0.25);
2725
+ circle("\u05DE\u05E8\u05DB\u05D6 \u05E9\u05D5\u05DC\u05D7\u05DF", 270, 300, 230, surface, 0.42);
2726
+ for (let i = 0; i < 4; i++) {
2727
+ const x = 60 + i % 2 * 550, y = 100 + Math.floor(i / 2) * 390;
2728
+ box(ctx, `\u05DE\u05E2\u05D8\u05E4\u05EA \u05EA\u05E7\u05E6\u05D9\u05D1 ${i + 1}`, x, y, 110, 128, i % 2 ? ink : a, 18, 0.35 + i * 0.18, i % 2 ? 160 : -160);
2729
+ }
2730
+ caption(ctx, "\u05E1\u05DB\u05D5\u05DD \u05DC\u05EA\u05DB\u05E0\u05D5\u05DF", "\u20AA", 336, 338, 100, 100, 96, ink, 0.68);
2731
+ break;
2732
+ case "one-click":
2733
+ circle("\u05D2\u05DC \u05D4\u05D3\u05E3 \u05D7\u05D9\u05E6\u05D5\u05E0\u05D9", 70, 70, 630, a, 0.1);
2734
+ circle("\u05D2\u05DC \u05D4\u05D3\u05E3 \u05E4\u05E0\u05D9\u05DE\u05D9", 130, 130, 510, surface, 0.28);
2735
+ circle("\u05DB\u05E4\u05EA\u05D5\u05E8 \u05E8\u05D0\u05E9\u05D9", 245, 245, 280, a, 0.42);
2736
+ box(ctx, "\u05D5\u05D9 \u05E7\u05E6\u05E8 \u05D1\u05DB\u05E4\u05EA\u05D5\u05E8 \u05D4\u05E8\u05D0\u05E9\u05D9", 317, 368, 57, 17, WHITE, 8, 0.64, -140, 14, 1, 43);
2737
+ box(ctx, "\u05D5\u05D9 \u05D0\u05E8\u05D5\u05DA \u05D1\u05DB\u05E4\u05EA\u05D5\u05E8 \u05D4\u05E8\u05D0\u05E9\u05D9", 357, 340, 111, 17, WHITE, 8, 0.7, -140, 14, 1, -43);
2738
+ for (let i = 0; i < 3; i++) box(ctx, `\u05E9\u05DC\u05D1 ${i + 1}`, 60 + i * 238, 645, 170, 16, i === 2 ? ink : a, 8, 0.55 + i * 0.2);
2739
+ break;
2740
+ case "book-steps":
2741
+ for (let i = 0; i < 4; i++) {
2742
+ box(ctx, `\u05E1\u05E4\u05E8 \u05DE\u05D3\u05E8\u05D2\u05D4 ${i + 1}`, 60 + i * 152, 525 - i * 105, 175, 115, i % 2 ? ink : a, 12, 0.18 + i * 0.18, -220, 8);
2743
+ bar(`\u05DB\u05E8\u05D9\u05DB\u05EA \u05E1\u05E4\u05E8 ${i + 1}`, 68 + i * 152, 548 - i * 105, 150, 9, surface, 0.34 + i * 0.18);
2744
+ }
2745
+ box(ctx, "\u05EA\u05E2\u05D5\u05D3\u05D4", 580, 80, 150, 190, surface, 10, 0.95);
2746
+ circle("\u05D7\u05D5\u05EA\u05DD \u05EA\u05E2\u05D5\u05D3\u05D4", 625, 150, 60, a, 1.12);
2747
+ box(ctx, "\u05E4\u05E1 \u05EA\u05E2\u05D5\u05D3\u05D4 \u05E2\u05DC\u05D9\u05D5\u05DF", 598, 110, 115, 9, a, 4, 1.06);
2748
+ box(ctx, "\u05E4\u05E1 \u05EA\u05E2\u05D5\u05D3\u05D4 \u05EA\u05D7\u05EA\u05D5\u05DF", 598, 235, 115, 9, a, 4, 1.23);
2749
+ break;
2750
+ case "room-build":
2751
+ bar("\u05E8\u05E6\u05E4\u05EA \u05D7\u05D3\u05E8", 40, 650, 690, 24, ink, 0.08);
2752
+ bar("\u05E7\u05D9\u05E8 \u05E9\u05DE\u05D0\u05DC", 70, 115, 24, 555, a, 0.18);
2753
+ bar("\u05E7\u05D9\u05E8 \u05D9\u05DE\u05D9\u05DF", 690, 115, 24, 555, a, 0.22);
2754
+ box(ctx, "\u05D7\u05DC\u05D5\u05DF", 435, 205, 200, 230, surface, 12, 0.38);
2755
+ bar("\u05D7\u05DC\u05D5\u05E7\u05EA \u05D7\u05DC\u05D5\u05DF", 525, 205, 12, 230, a, 0.52);
2756
+ box(ctx, "\u05E1\u05E4\u05D4", 175, 490, 350, 145, a, 45, 0.58);
2757
+ for (const [i, x] of [220, 435].entries()) box(ctx, `\u05E8\u05D2\u05DC \u05E1\u05E4\u05D4 ${i + 1}`, x, 610, 35, 55, ink, 6, 0.7);
2758
+ break;
2759
+ case "summer-case":
2760
+ circle("\u05E9\u05DE\u05E9", 510, 90, 190, a, 0.12);
2761
+ for (let i = 0; i < 6; i++) {
2762
+ const angle = i * Math.PI / 3;
2763
+ bar(`\u05E7\u05E8\u05DF \u05E9\u05DE\u05E9 ${i + 1}`, 605 + Math.cos(angle) * 132, 185 + Math.sin(angle) * 132, 64, 12, a, 0.2 + i * 0.06);
2764
+ }
2765
+ box(ctx, "\u05DE\u05D6\u05D5\u05D5\u05D3\u05D4", 145, 325, 450, 320, ink, 35, 0.4);
2766
+ box(ctx, "\u05D9\u05D3\u05D9\u05EA \u05DE\u05D6\u05D5\u05D5\u05D3\u05D4", 300, 260, 145, 90, a, 42, 0.3);
2767
+ bar("\u05E4\u05E1 \u05DE\u05D6\u05D5\u05D5\u05D3\u05D4", 340, 335, 50, 300, surface, 0.6);
2768
+ for (const [i, x] of [220, 510].entries()) circle(`\u05D2\u05DC\u05D2\u05DC \u05DE\u05D6\u05D5\u05D5\u05D3\u05D4 ${i + 1}`, x, 620, 52, a, 0.7);
2769
+ break;
2770
+ case "car-garage":
2771
+ box(ctx, "\u05DE\u05E1\u05D2\u05E8\u05EA \u05DE\u05D5\u05E1\u05DA", 70, 105, 650, 560, ink, 18, 0.1);
2772
+ box(ctx, "\u05E4\u05EA\u05D7 \u05DE\u05D5\u05E1\u05DA", 115, 155, 560, 460, surface, 12, 0.25);
2773
+ for (let i = 0; i < 4; i++) bar(`\u05D7\u05E8\u05D9\u05E5 \u05EA\u05E8\u05D9\u05E1 ${i + 1}`, 130, 175 + i * 52, 530, 12, a, 0.28 + i * 0.08);
2774
+ box(ctx, "\u05E8\u05DB\u05D1 \u05D7\u05D3\u05E9", 180, 440, 440, 125, a, 62, 0.76, -450, 60);
2775
+ for (const [i, x] of [248, 510].entries()) circle(`\u05D2\u05DC\u05D2\u05DC \u05D7\u05D3\u05E9 ${i + 1}`, x, 535, 78, NAVY, 0.86);
2776
+ break;
2777
+ case "wedding-rings":
2778
+ circle("\u05D8\u05D1\u05E2\u05EA \u05E8\u05D0\u05E9\u05D5\u05E0\u05D4", 112, 220, 370, a, 0.12);
2779
+ circle("\u05D7\u05DC\u05DC \u05D8\u05D1\u05E2\u05EA \u05E8\u05D0\u05E9\u05D5\u05E0\u05D4", 176, 284, 242, surface, 0.18);
2780
+ circle("\u05D8\u05D1\u05E2\u05EA \u05E9\u05E0\u05D9\u05D9\u05D4", 330, 220, 370, ink, 0.42);
2781
+ circle("\u05D7\u05DC\u05DC \u05D8\u05D1\u05E2\u05EA \u05E9\u05E0\u05D9\u05D9\u05D4", 394, 284, 242, surface, 0.48);
2782
+ circle("\u05D7\u05D5\u05EA\u05DD \u05D4\u05D6\u05DE\u05E0\u05D4", 363, 553, 85, a, 0.82);
2783
+ circle("\u05DE\u05E8\u05DB\u05D6 \u05D7\u05D5\u05EA\u05DD \u05D4\u05D6\u05DE\u05E0\u05D4", 383, 573, 45, surface, 0.91);
2784
+ for (let i = 0; i < 5; i++) circle(`\u05E0\u05E7\u05D5\u05D3\u05EA \u05D0\u05D5\u05E8 ${i + 1}`, 125 + i * 130, 115 + i % 2 * 490, 25, a, 0.2 + i * 0.14);
2785
+ break;
2786
+ case "share-mosaic":
2787
+ for (let row = 0; row < 4; row++) for (let col = 0; col < 5; col++) {
2788
+ box(
2789
+ ctx,
2790
+ `\u05D0\u05E8\u05D9\u05D7 \u05D1\u05E2\u05DC\u05D5\u05EA ${row * 5 + col + 1}`,
2791
+ 70 + col * 128,
2792
+ 130 + row * 128,
2793
+ 102,
2794
+ 102,
2795
+ row === 1 && col === 3 ? a : row % 2 ? ink : surface,
2796
+ 10,
2797
+ 0.12 + (row + col) * 0.085,
2798
+ col % 2 ? 120 : -120,
2799
+ 3
2800
+ );
2801
+ }
2802
+ break;
2803
+ case "fraud-alert":
2804
+ box(ctx, "\u05D8\u05DC\u05E4\u05D5\u05DF \u05D0\u05D6\u05D4\u05E8\u05D4", 205, 55, 370, 650, NAVY, 42, 0.08);
2805
+ box(ctx, "\u05DE\u05E1\u05DA \u05D8\u05DC\u05E4\u05D5\u05DF", 229, 83, 322, 590, surface, 28, 0.18);
2806
+ for (let i = 0; i < 3; i++) box(ctx, `\u05D4\u05D5\u05D3\u05E2\u05D4 \u05D7\u05E9\u05D5\u05D3\u05D4 ${i + 1}`, 258, 175 + i * 130, 264, 95, i === 1 ? a : PALE, 18, 0.3 + i * 0.28, i % 2 ? 140 : -140);
2807
+ caption(ctx, "\u05E1\u05D9\u05DE\u05DF \u05D0\u05D6\u05D4\u05E8\u05D4", "!", 340, 516, 100, 100, 104, a, 1.1);
2808
+ break;
2809
+ case "student-desk":
2810
+ box(ctx, "\u05E9\u05D5\u05DC\u05D7\u05DF \u05DC\u05D9\u05DE\u05D5\u05D3", 55, 585, 660, 45, ink, 12, 0.1);
2811
+ box(ctx, "\u05DE\u05D7\u05D1\u05E8\u05EA \u05E9\u05DE\u05D0\u05DC", 145, 215, 255, 360, surface, 16, 0.24, -230, 6);
2812
+ box(ctx, "\u05DE\u05D7\u05D1\u05E8\u05EA \u05D9\u05DE\u05D9\u05DF", 396, 215, 255, 360, a, 16, 0.3, 230, -6);
2813
+ for (let i = 0; i < 4; i++) bar(`\u05E9\u05D5\u05E8\u05EA \u05DE\u05E9\u05D9\u05DE\u05D4 ${i + 1}`, 195, 287 + i * 57, 178, 10, ink, 0.5 + i * 0.12);
2814
+ circle("\u05E9\u05E2\u05D5\u05DF \u05DC\u05D9\u05DE\u05D5\u05D3", 550, 68, 146, ink, 0.5);
2815
+ caption(ctx, "\u05DE\u05D7\u05D5\u05D2 \u05E9\u05E2\u05D5\u05DF", "\u2197", 583, 91, 80, 80, 70, surface, 0.72);
2816
+ break;
2817
+ case "learning-domino":
2818
+ for (let i = 0; i < 5; i++) box(ctx, `\u05D0\u05D1\u05DF \u05DC\u05DE\u05D9\u05D3\u05D4 ${i + 1}`, 90 + i * 127, 305 + i * 30, 96, 260, i === 4 ? a : ink, 12, 0.1 + i * 0.18, -180, 14, 1, i * 8);
2819
+ bar("\u05DE\u05E1\u05DC\u05D5\u05DC \u05DC\u05DE\u05D9\u05D3\u05D4", 48, 618, 680, 26, a, 0.42);
2820
+ caption(ctx, "\u05E6\u05E2\u05D3 \u05E8\u05D0\u05E9\u05D5\u05DF", "01", 580, 80, 130, 110, 84, a, 0.96);
2821
+ break;
2822
+ case "fomo-storm":
2823
+ for (let i = 0; i < 7; i++) {
2824
+ const left = 62 + i % 3 * 220, top = 70 + i * 82;
2825
+ box(ctx, `\u05D4\u05EA\u05E8\u05D0\u05EA \u05DC\u05D7\u05E5 ${i + 1}`, left, top, 220, 74, i % 2 ? ink : a, 14, i * 0.11, i % 2 ? 450 : -450, i % 2 ? -50 : 50);
2826
+ }
2827
+ box(ctx, "\u05DE\u05E1\u05D2\u05E8\u05EA \u05E2\u05E6\u05D9\u05E8\u05D4", 175, 220, 410, 260, surface, 28, 0.72);
2828
+ caption(ctx, "\u05DE\u05D9\u05DC\u05EA \u05E2\u05E6\u05D9\u05E8\u05D4", "\u05E2\u05D5\u05E6\u05E8\u05D9\u05DD", 208, 290, 345, 110, 86, a, 0.96);
2829
+ break;
2830
+ case "market-clock":
2831
+ circle("\u05DC\u05D5\u05D7 \u05E9\u05E2\u05D5\u05DF", 100, 105, 560, surface, 0.1);
2832
+ circle("\u05E4\u05E0\u05D9\u05DD \u05E9\u05E2\u05D5\u05DF", 145, 150, 470, ink, 0.22);
2833
+ for (let i = 0; i < 12; i++) {
2834
+ const angle = i * Math.PI / 6;
2835
+ circle(`\u05E1\u05D9\u05DE\u05D5\u05DF \u05E9\u05E2\u05D4 ${i + 1}`, 370 + Math.sin(angle) * 195, 375 - Math.cos(angle) * 195, 17, surface, 0.28 + i * 0.025);
2836
+ }
2837
+ bar("\u05DE\u05D7\u05D5\u05D2 \u05D0\u05E8\u05D5\u05DA", 365, 210, 16, 225, a, 0.48);
2838
+ bar("\u05DE\u05D7\u05D5\u05D2 \u05E7\u05E6\u05E8", 372, 370, 145, 16, a, 0.55);
2839
+ circle("\u05E6\u05D9\u05E8 \u05E9\u05E2\u05D5\u05DF", 355, 360, 38, a, 0.62);
2840
+ break;
2841
+ case "small-bricks":
2842
+ for (let row = 0; row < 5; row++) for (let col = 0; col < 4; col++) {
2843
+ box(
2844
+ ctx,
2845
+ `\u05DC\u05D1\u05E0\u05D4 ${row * 4 + col + 1}`,
2846
+ 95 + col * 140 + row % 2 * 58,
2847
+ 555 - row * 95,
2848
+ 130,
2849
+ 72,
2850
+ (row + col) % 3 === 0 ? a : ink,
2851
+ 10,
2852
+ 0.1 + (row * 4 + col) * 0.065,
2853
+ 0,
2854
+ 4
2855
+ );
2856
+ }
2857
+ break;
2858
+ case "two-paths":
2859
+ bar("\u05E6\u05D5\u05DE\u05EA", 344, 35, 30, 600, ink, 0.12);
2860
+ for (const [i, side] of [-1, 1].entries()) {
2861
+ box(ctx, `\u05DE\u05E1\u05DC\u05D5\u05DC ${i + 1}`, side < 0 ? 72 : 390, 220, 270, 335, i ? a : ink, 25, 0.3 + i * 0.14, side * 320);
2862
+ caption(ctx, `\u05E1\u05DE\u05DC \u05DE\u05E1\u05DC\u05D5\u05DC ${i + 1}`, i ? "\u2302" : "\u2197", side < 0 ? 145 : 464, 310, 125, 125, 106, surface, 0.6 + i * 0.12);
2863
+ }
2864
+ circle("\u05E0\u05E7\u05D5\u05D3\u05EA \u05D4\u05D7\u05DC\u05D8\u05D4", 315, 575, 88, a, 0.9);
2865
+ break;
2866
+ case "small-store":
2867
+ box(ctx, "\u05D7\u05D6\u05D9\u05EA \u05D7\u05E0\u05D5\u05EA", 115, 235, 535, 400, surface, 14, 0.15);
2868
+ for (let i = 0; i < 5; i++) box(ctx, `\u05E4\u05E1 \u05E1\u05D5\u05DB\u05DA ${i + 1}`, 115 + i * 107, 182, 105, 105, i % 2 ? a : ink, 4, 0.23 + i * 0.1);
2869
+ box(ctx, "\u05D3\u05DC\u05EA \u05D7\u05E0\u05D5\u05EA", 185, 365, 170, 270, ink, 8, 0.55);
2870
+ box(ctx, "\u05D7\u05DC\u05D5\u05DF \u05E8\u05D0\u05D5\u05D5\u05D4", 390, 345, 205, 165, a, 8, 0.65);
2871
+ for (let i = 0; i < 3; i++) sq(`\u05DE\u05D5\u05E6\u05E8 ${i + 1}`, 418 + i * 53, 440, 37, surface, 0.78 + i * 0.08);
2872
+ break;
2873
+ case "travel-conveyor":
2874
+ box(ctx, "\u05DE\u05E1\u05D5\u05E2 \u05E9\u05D3\u05D4 \u05EA\u05E2\u05D5\u05E4\u05D4", 24, 570, 710, 58, ink, 29, 0.1, -500, 95);
2875
+ for (let i = 0; i < 6; i++) circle(`\u05D2\u05DC\u05D2\u05DC \u05DE\u05E1\u05D5\u05E2 ${i + 1}`, 54 + i * 115, 620, 45, a, 0.24 + i * 0.06);
2876
+ box(ctx, "\u05DE\u05D6\u05D5\u05D5\u05D3\u05EA \u05E0\u05E1\u05D9\u05E2\u05D4", 185, 260, 345, 315, a, 30, 0.42, -390, 90);
2877
+ box(ctx, "\u05D9\u05D3\u05D9\u05EA \u05DE\u05D6\u05D5\u05D5\u05D3\u05D4", 300, 205, 110, 75, ink, 32, 0.35);
2878
+ caption(ctx, "\u05E1\u05DE\u05DC \u05D8\u05D9\u05E1\u05D4", "\u2708", 520, 105, 170, 140, 120, ink, 0.74);
2879
+ break;
2880
+ case "mortgage-blueprint":
2881
+ box(ctx, "\u05D3\u05E3 \u05EA\u05DB\u05E0\u05D9\u05EA", 72, 85, 650, 570, surface, 12, 0.08);
2882
+ bar("\u05E7\u05D5 \u05E8\u05E6\u05E4\u05D4", 166, 520, 460, 12, a, 0.3);
2883
+ bar("\u05E7\u05D9\u05E8 \u05E9\u05DE\u05D0\u05DC", 176, 300, 13, 235, a, 0.42);
2884
+ bar("\u05E7\u05D9\u05E8 \u05D9\u05DE\u05D9\u05DF", 612, 300, 13, 235, a, 0.48);
2885
+ box(ctx, "\u05D2\u05D2 \u05E9\u05DE\u05D0\u05DC", 176, 240, 258, 15, a, 6, 0.54, -200, 4, 1, -27);
2886
+ box(ctx, "\u05D2\u05D2 \u05D9\u05DE\u05D9\u05DF", 397, 240, 258, 15, a, 6, 0.6, 200, -4, 1, 27);
2887
+ box(ctx, "\u05D3\u05DC\u05EA \u05D1\u05EA\u05DB\u05E0\u05D9\u05EA", 328, 393, 112, 132, ink, 6, 0.72);
2888
+ for (let i = 0; i < 3; i++) bar(`\u05DE\u05D9\u05D3\u05D4 ${i + 1}`, 155, 585 + i * 18, 350 - i * 55, 5, ink, 0.82 + i * 0.08);
2889
+ break;
2890
+ case "market-phone":
2891
+ box(ctx, "\u05DE\u05E1\u05D2\u05E8\u05EA \u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D4", 175, 50, 425, 665, NAVY, 45, 0.1);
2892
+ box(ctx, "\u05DE\u05E1\u05DA \u05E9\u05D5\u05E7", 203, 82, 369, 595, surface, 27, 0.2);
2893
+ for (let i = 0; i < 5; i++) box(ctx, `\u05E2\u05DE\u05D5\u05D3\u05EA \u05E0\u05EA\u05D5\u05DF ${i + 1}`, 247 + i * 58, 515 - i * 42, 36, 93 + i * 42, i % 2 ? ink : a, 7, 0.4 + i * 0.14, 0, 6);
2894
+ bar("\u05E7\u05D5 \u05DB\u05D5\u05EA\u05E8\u05EA \u05D1\u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D4", 244, 171, 275, 18, ink, 0.48);
2895
+ bar("\u05E7\u05D5 \u05E0\u05EA\u05D5\u05DF \u05D1\u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D4", 244, 216, 196, 12, a, 0.59);
2896
+ break;
2897
+ }
2898
+ }
2899
+ var storyFrames = {
2900
+ "car-road": [{ kind: "choices", labels: ["\u05E8\u05DB\u05D1 \u05D7\u05D3\u05E9", "\u05D9\u05D3 \u05E9\u05E0\u05D9\u05D9\u05D4"] }, { kind: "bars", labels: ["\u05DE\u05D7\u05D9\u05E8", "\u05EA\u05D7\u05D6\u05D5\u05E7\u05D4", "\u05DE\u05D9\u05DE\u05D5\u05DF"] }],
2901
+ "holiday-table": [{ kind: "meter", labels: ["\u05DE\u05E1\u05D2\u05E8\u05EA \u05DC\u05D7\u05D2"] }, { kind: "stack", labels: ["\u05E7\u05E0\u05D9\u05D5\u05EA", "\u05D0\u05D9\u05E8\u05D5\u05D7", "\u05E0\u05E1\u05D9\u05E2\u05D5\u05EA"] }],
2902
+ "one-click": [{ kind: "phone", labels: ["\u05E4\u05D5\u05EA\u05D7\u05D9\u05DD", "\u05D1\u05D5\u05D7\u05E8\u05D9\u05DD", "\u05DE\u05D0\u05E9\u05E8\u05D9\u05DD"] }, { kind: "steps", labels: ["\u05E4\u05E2\u05D5\u05DC\u05D4", "\u05E4\u05E8\u05D8\u05D9\u05DD", "\u05D0\u05D9\u05E9\u05D5\u05E8"] }, { kind: "check", labels: ["\u05D1\u05D3\u05D9\u05E7\u05D4", "\u05E9\u05DC\u05D9\u05D8\u05D4", "\u05D4\u05EA\u05E7\u05D3\u05DE\u05D5\u05EA"] }],
2903
+ "book-steps": [{ kind: "steps", labels: ["\u05D9\u05E2\u05D3", "\u05DC\u05D9\u05DE\u05D5\u05D3", "\u05D4\u05DB\u05E9\u05E8\u05D4"] }, { kind: "bars", labels: ["\u05D6\u05DE\u05DF", "\u05E2\u05DC\u05D5\u05EA", "\u05E9\u05D2\u05E8\u05D4"] }],
2904
+ "room-build": [{ kind: "choices", labels: ["\u05DE\u05D8\u05D1\u05D7", "\u05D7\u05D3\u05E8 \u05E2\u05D1\u05D5\u05D3\u05D4"] }, { kind: "bars", labels: ["\u05E1\u05DB\u05D5\u05DD", "\u05D6\u05DE\u05DF", "\u05EA\u05D5\u05E6\u05D0\u05D4"] }],
2905
+ "summer-case": [{ kind: "choices", labels: ["\u05E0\u05D5\u05E1\u05E2\u05D9\u05DD", "\u05E0\u05E9\u05D0\u05E8\u05D9\u05DD"] }, { kind: "meter", labels: ["\u05EA\u05E7\u05E6\u05D9\u05D1 \u05DC\u05E7\u05D9\u05E5"] }, { kind: "steps", labels: ["\u05D9\u05E2\u05D3", "\u05EA\u05DB\u05E0\u05D5\u05DF", "\u05E1\u05E4\u05D5\u05E0\u05D8\u05E0\u05D9\u05D5\u05EA"] }],
2906
+ "car-garage": [{ kind: "choices", labels: ["\u05E0\u05D5\u05D7\u05D5\u05EA", "\u05D7\u05D9\u05E1\u05DB\u05D5\u05DF"] }, { kind: "bars", labels: ["\u05E7\u05E0\u05D9\u05D9\u05D4", "\u05EA\u05D7\u05D6\u05D5\u05E7\u05D4", "\u05DE\u05D9\u05DE\u05D5\u05DF"] }],
2907
+ "wedding-rings": [{ kind: "choices", labels: ["\u05DE\u05E7\u05D5\u05DD", "\u05D0\u05E0\u05E9\u05D9\u05DD"] }, { kind: "bars", labels: ["\u05D7\u05D5\u05D5\u05D9\u05D4", "\u05EA\u05E7\u05E6\u05D9\u05D1", "\u05DE\u05E8\u05D5\u05D5\u05D7"] }, { kind: "meter", labels: ["\u05D4\u05D9\u05D5\u05DD \u05E9\u05DC\u05DB\u05DD"] }],
2908
+ "share-mosaic": [{ kind: "steps", labels: ["\u05D7\u05D1\u05E8\u05D4", "\u05D7\u05DC\u05E7", "\u05E1\u05D9\u05DB\u05D5\u05DF"] }, { kind: "check", labels: ["\u05DC\u05D5\u05DE\u05D3\u05D9\u05DD", "\u05D1\u05D5\u05D3\u05E7\u05D9\u05DD", "\u05D1\u05D5\u05D7\u05E8\u05D9\u05DD"] }],
2909
+ "fraud-alert": [{ kind: "warning", labels: ["\u05E7\u05D9\u05E9\u05D5\u05E8", "\u05E1\u05D9\u05E1\u05DE\u05D4", "\u05E7\u05D5\u05D3"] }, { kind: "phone", labels: ["\u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D4", "\u05D0\u05EA\u05E8 \u05E8\u05E9\u05DE\u05D9", "\u05D1\u05D3\u05D9\u05E7\u05D4"] }, { kind: "check", labels: ["\u05E2\u05D5\u05E6\u05E8\u05D9\u05DD", "\u05D1\u05D5\u05D3\u05E7\u05D9\u05DD", "\u05DE\u05D2\u05E0\u05D9\u05DD"] }],
2910
+ "student-desk": [{ kind: "stack", labels: ["\u05DC\u05D9\u05DE\u05D5\u05D3\u05D9\u05DD", "\u05E0\u05E1\u05D9\u05E2\u05D5\u05EA", "\u05D9\u05D5\u05DE\u05D9\u05D5\u05DD"] }, { kind: "bars", labels: ["\u05D4\u05DB\u05E0\u05E1\u05D4", "\u05D4\u05D5\u05E6\u05D0\u05D5\u05EA", "\u05D6\u05DE\u05DF"] }],
2911
+ "learning-domino": [{ kind: "steps", labels: ["\u05DE\u05D8\u05E8\u05D4", "\u05D8\u05D5\u05D5\u05D7", "\u05E1\u05D9\u05DB\u05D5\u05DF"] }, { kind: "check", labels: ["\u05D9\u05D3\u05E2", "\u05D0\u05E4\u05E9\u05E8\u05D5\u05D9\u05D5\u05EA", "\u05D4\u05D7\u05DC\u05D8\u05D4"] }],
2912
+ "fomo-storm": [{ kind: "warning", labels: ["\u05DB\u05D5\u05DC\u05DD", "\u05E2\u05DB\u05E9\u05D9\u05D5", "\u05DE\u05D4\u05E8"] }, { kind: "steps", labels: ["\u05E2\u05D5\u05E6\u05E8\u05D9\u05DD", "\u05E9\u05D5\u05D0\u05DC\u05D9\u05DD", "\u05D1\u05D5\u05D3\u05E7\u05D9\u05DD"] }],
2913
+ "market-clock": [{ kind: "meter", labels: ["\u05D0\u05D9\u05DF \u05E8\u05D2\u05E2 \u05DE\u05D5\u05E9\u05DC\u05DD"] }, { kind: "steps", labels: ["\u05DE\u05D8\u05E8\u05D4", "\u05E1\u05D9\u05DB\u05D5\u05DF", "\u05D0\u05D5\u05E4\u05E7"] }],
2914
+ "small-bricks": [{ kind: "steps", labels: ["\u05DC\u05D5\u05DE\u05D3\u05D9\u05DD", "\u05DE\u05D1\u05D9\u05E0\u05D9\u05DD", "\u05D1\u05D5\u05D7\u05E8\u05D9\u05DD"] }, { kind: "bars", labels: ["\u05E1\u05DB\u05D5\u05DD", "\u05D6\u05DE\u05DF", "\u05E1\u05D9\u05DB\u05D5\u05DF"] }],
2915
+ "two-paths": [{ kind: "choices", labels: ["\u05E9\u05D5\u05E7 \u05D4\u05D4\u05D5\u05DF", "\u05E0\u05D3\u05DC\u05F4\u05DF"] }, { kind: "stack", labels: ["\u05E0\u05D6\u05D9\u05DC\u05D5\u05EA", "\u05D4\u05D5\u05DF", "\u05E4\u05D9\u05D6\u05D5\u05E8"] }],
2916
+ "small-store": [{ kind: "choices", labels: ["\u05DE\u05DC\u05D0\u05D9", "\u05E6\u05D9\u05D5\u05D3"] }, { kind: "bars", labels: ["\u05E0\u05EA\u05D5\u05E0\u05D9\u05DD", "\u05EA\u05D6\u05E8\u05D9\u05DD", "\u05DE\u05D9\u05DE\u05D5\u05DF"] }, { kind: "phone", labels: ["\u05E6\u05D5\u05E8\u05DA", "\u05E4\u05EA\u05E8\u05D5\u05DF", "\u05D4\u05DE\u05E9\u05DA"] }],
2917
+ "travel-conveyor": [{ kind: "check", labels: ["\u05DE\u05D8\u05F4\u05D7", "\u05EA\u05E7\u05E6\u05D9\u05D1", "\u05D2\u05D9\u05D1\u05D5\u05D9"] }, { kind: "bars", labels: ["\u05D0\u05D5\u05DB\u05DC", "\u05E0\u05E1\u05D9\u05E2\u05D5\u05EA", "\u05E9\u05D5\u05E0\u05D5\u05EA"] }],
2918
+ "mortgage-blueprint": [{ kind: "meter", labels: ["\u05D9\u05DB\u05D5\u05DC\u05EA \u05D4\u05D7\u05D6\u05E8"] }, { kind: "stack", labels: ["\u05DE\u05E1\u05DC\u05D5\u05DC\u05D9\u05DD", "\u05E2\u05DC\u05D5\u05D9\u05D5\u05EA", "\u05D8\u05D5\u05D5\u05D7"] }, { kind: "check", labels: ["\u05E9\u05D0\u05DC\u05D5\u05EA", "\u05D4\u05E9\u05D5\u05D5\u05D0\u05D4", "\u05D9\u05D9\u05E2\u05D5\u05E5"] }],
2919
+ "market-phone": [{ kind: "phone", labels: ["\u05DE\u05D9\u05D3\u05E2", "\u05D4\u05E9\u05D5\u05D5\u05D0\u05D4", "\u05DE\u05E2\u05E7\u05D1"] }, { kind: "bars", labels: ["\u05E0\u05EA\u05D5\u05E0\u05D9\u05DD", "\u05DE\u05D2\u05DE\u05D4", "\u05D4\u05D7\u05DC\u05D8\u05D4"] }]
2920
+ };
2921
+ function holidayStoryboard(ctx) {
2922
+ if (ctx.theme !== "holiday-table" || ctx.index > 2) return false;
2923
+ const d = ctx.scene.duration;
2924
+ const end = d - 0.02;
2925
+ const keys = (item, frames) => {
2926
+ item.keyframes = frames;
2927
+ return item;
2928
+ };
2929
+ const disc = (name, x, y, diameter, color, delay = 0) => box(ctx, name, x, y, diameter, diameter, color, diameter / 2, delay);
2930
+ if (ctx.index === 0) {
2931
+ keys(box(ctx, "\u05DE\u05E4\u05EA \u05E9\u05D5\u05DC\u05D7\u05DF", 66, 67, 640, 630, "#920C33", 42), [
2932
+ point(0, 0, 0, 0.72, 0.72, -8, 0),
2933
+ point(0.46, 0, 0, 1, 1, 0),
2934
+ point(d * 0.72, 0, 0, 1.025, 1.025, 1),
2935
+ point(end, 0, 0, 1, 1)
2936
+ ]);
2937
+ keys(disc("\u05E6\u05DC \u05E6\u05DC\u05D7\u05EA", 151, 139, 480, "#630B2A"), [point(0, 0, 130, 0.7, 0.7, -25, 0), point(0.55, 0, 0, 1, 1, 0), point(end, 0, 0)]);
2938
+ keys(disc("\u05E6\u05DC\u05D7\u05EA \u05DC\u05D1\u05E0\u05D4", 142, 120, 480, WHITE), [point(0, 0, 130, 0.7, 0.7, -25, 0), point(0.62, 0, 0, 1, 1, 0), point(d * 0.68, 0, -9, 1.03, 1.03, 4), point(end, 0, 0)]);
2939
+ keys(disc("\u05E9\u05E4\u05EA \u05E6\u05DC\u05D7\u05EA", 190, 168, 384, PALE), [point(0, 0, 130, 0.7, 0.7, -25, 0), point(0.7, 0, 0, 1, 1, 0), point(end, 0, 0)]);
2940
+ keys(disc("\u05DE\u05E8\u05DB\u05D6 \u05E6\u05DC\u05D7\u05EA", 219, 197, 326, RED), [point(0, 0, 130, 0.7, 0.7, -25, 0), point(0.77, 0, 0, 1, 1, 0), point(end, 0, 0)]);
2941
+ const symbol = caption(ctx, "\u05E1\u05DE\u05DC \u05D7\u05D2", "\u20AA", 319, 269, 126, 160, 132, WHITE, 0.8);
2942
+ keys(symbol, [point(0, 0, 90, 0.2, 0.2, -20, 0), point(0.81, 0, 90, 0.2, 0.2, -20, 0), point(1.22, 0, 0), point(d * 0.74, 0, -9, 1.1, 1.1, 4), point(end, 0, 0)]);
2943
+ for (const [i, x] of [97, 628].entries()) {
2944
+ const side = i ? 1 : -1;
2945
+ const utensil = box(ctx, `\u05E1\u05DB\u05D5\u05F4\u05DD ${i + 1}`, x, 220, 15, 280, WHITE, 7);
2946
+ keys(utensil, [point(0, side * 170, 0, 1, 1, side * 22, 0), point(0.65, side * 170, 0, 1, 1, side * 22, 0), point(1.08, 0, 0), point(end, 0, -12, 1, 1, side * 3)]);
2947
+ }
2948
+ for (let i = 0; i < 8; i++) {
2949
+ const theta = i * Math.PI / 4;
2950
+ const x = 372 + Math.cos(theta) * 286;
2951
+ const y = 360 + Math.sin(theta) * 286;
2952
+ const spark = disc(`\u05E0\u05E7\u05D5\u05D3\u05EA \u05D7\u05D2 ${i + 1}`, x, y, i % 2 ? 12 : 18, i % 3 ? "#FFDDA3" : WHITE);
2953
+ const beat = 0.35 + i * 0.095;
2954
+ keys(spark, [point(0, 0, 0, 0.2, 0.2, 0, 0), point(beat, 0, 0, 0.2, 0.2, 0, 0), point(beat + 0.36, 0, 0), point(end, 0, -15 - i * 2, 0.7, 0.7, 0, 0.55)]);
2955
+ }
2956
+ return true;
2957
+ }
2958
+ if (ctx.index === 1) {
2959
+ keys(box(ctx, "\u05E6\u05DC \u05DB\u05E8\u05D8\u05D9\u05E1 \u05EA\u05E7\u05E6\u05D9\u05D1", 67, 99, 654, 574, "#E6BBC5", 30), [point(0, 0, 160, 0.92, 0.92, 0, 0), point(0.53, 0, 0), point(end, 0, -8)]);
2960
+ keys(box(ctx, "\u05DB\u05E8\u05D8\u05D9\u05E1 \u05EA\u05E7\u05E6\u05D9\u05D1", 53, 81, 654, 574, WHITE, 30), [point(0, 0, 160, 0.92, 0.92, 0, 0), point(0.58, 0, 0), point(d * 0.72, 0, -8), point(end, 0, 0)]);
2961
+ caption(ctx, "\u05DB\u05D5\u05EA\u05E8\u05EA \u05DC\u05D5\u05D7 \u05EA\u05DB\u05E0\u05D5\u05DF", "\u05DE\u05E1\u05D2\u05E8\u05EA \u05DC\u05D7\u05D2", 115, 113, 520, 78, 52, NAVY, 0.42);
2962
+ box(ctx, "\u05E7\u05D5 \u05DB\u05D5\u05EA\u05E8\u05EA", 116, 199, 519, 6, RED, 3, 0.55);
2963
+ const labels = ["\u05E7\u05E0\u05D9\u05D5\u05EA", "\u05D0\u05D9\u05E8\u05D5\u05D7", "\u05E0\u05E1\u05D9\u05E2\u05D5\u05EA"];
2964
+ labels.forEach((label, i) => {
2965
+ const y = 238 + i * 123;
2966
+ const delay = 0.63 + i * 0.37;
2967
+ const icon = disc(`\u05E1\u05DE\u05DC \u05E1\u05E2\u05D9\u05E3 ${i + 1}`, 113, y, 70, i === 1 ? NAVY : RED);
2968
+ keys(icon, [point(0, -95, 0, 0.6, 0.6, -20, 0), point(delay, -95, 0, 0.6, 0.6, -20, 0), point(delay + 0.32, 0, 0), point(end, 0, -5)]);
2969
+ caption(ctx, `\u05E9\u05DD \u05E1\u05E2\u05D9\u05E3 ${i + 1}`, label, 206, y + 4, 180, 64, 38, NAVY, delay + 0.09);
2970
+ const guide = box(ctx, `\u05DE\u05E1\u05DC\u05D5\u05DC \u05E1\u05E2\u05D9\u05E3 ${i + 1}`, 397, y + 20, 238, 28, "#F8DEE5", 14, delay);
2971
+ keys(guide, [point(0, 0, 0, 0.2, 1, 0, 0), point(delay, 0, 0, 0.2, 1, 0, 0), point(delay + 0.38, 0, 0), point(end, 0, 0)]);
2972
+ const fill = box(ctx, `\u05D4\u05D3\u05D2\u05E9\u05EA \u05E1\u05E2\u05D9\u05E3 ${i + 1}`, 397, y + 20, 168, 28, i === 1 ? NAVY : RED, 14, delay + 0.24);
2973
+ keys(fill, [point(0, -80, 0, 0.05, 1, 0, 0), point(delay + 0.22, -80, 0, 0.05, 1, 0, 0), point(delay + 0.73, 0, 0), point(end, 12, 0)]);
2974
+ });
2975
+ caption(ctx, "\u05D4\u05E2\u05E8\u05EA \u05EA\u05DB\u05E0\u05D5\u05DF", "\u05DE\u05EA\u05DB\u05E0\u05E0\u05D9\u05DD \u05DE\u05E8\u05D0\u05E9 \u2022 \u05D1\u05D5\u05D7\u05E8\u05D9\u05DD \u05D1\u05E0\u05D7\u05EA", 119, 594, 523, 56, 29, NAVY, 1.5);
2976
+ return true;
2977
+ }
2978
+ box(ctx, "\u05E7\u05D5 \u05D7\u05DC\u05D5\u05E7\u05D4", 360, 85, 12, 601, WHITE, 6, 0.12, 0, 0, 0.42);
2979
+ ["\u05E7\u05E0\u05D9\u05D5\u05EA", "\u05D0\u05D9\u05E8\u05D5\u05D7", "\u05E0\u05E1\u05D9\u05E2\u05D5\u05EA"].forEach((label, i) => {
2980
+ const y = 115 + i * 174;
2981
+ const delay = 0.24 + i * 0.58;
2982
+ const direction = i % 2 ? 1 : -1;
2983
+ const card = box(ctx, `\u05DB\u05E8\u05D8\u05D9\u05E1 ${label}`, 42, y, 674, 142, WHITE, 25, delay, direction * 570);
2984
+ keys(card, [
2985
+ point(0, direction * 570, 0, 0.88, 0.88, direction * 7, 0),
2986
+ point(delay, direction * 570, 0, 0.88, 0.88, direction * 7, 0),
2987
+ point(delay + 0.42, 0, 0),
2988
+ point(delay + 0.67, 0, -8, 1.025, 1.025, 0),
2989
+ point(end, 0, 0)
2990
+ ]);
2991
+ const badge = disc(`\u05DE\u05E1\u05E4\u05E8 \u05E1\u05E2\u05D9\u05E3 ${i + 1}`, 70, y + 27, 88, RED, delay + 0.16);
2992
+ keys(badge, [point(0, -90, 0, 0.2, 0.2, -35, 0), point(delay + 0.12, -90, 0, 0.2, 0.2, -35, 0), point(delay + 0.5, 0, 0), point(end, 0, -3)]);
2993
+ caption(ctx, `\u05E1\u05E4\u05E8\u05EA \u05E1\u05E2\u05D9\u05E3 ${i + 1}`, `0${i + 1}`, 88, y + 47, 52, 53, 38, WHITE, delay + 0.31);
2994
+ caption(ctx, `\u05EA\u05D5\u05D5\u05D9\u05EA \u05E1\u05E2\u05D9\u05E3 ${i + 1}`, label, 188, y + 25, 355, 93, 55, NAVY, delay + 0.21);
2995
+ const dash = box(ctx, `\u05E7\u05D5 \u05E1\u05E2\u05D9\u05E3 ${i + 1}`, 574, y + 66, 99, 10, RED, 5, delay + 0.45);
2996
+ keys(dash, [point(0, -80, 0, 0.1, 1, 0, 0), point(delay + 0.42, -80, 0, 0.1, 1, 0, 0), point(delay + 0.8, 0, 0), point(end, 20, 0)]);
2997
+ });
2998
+ return true;
2999
+ }
3000
+ function oneClickStoryboard(ctx) {
3001
+ if (ctx.theme !== "one-click" || ctx.index > 3) return false;
3002
+ const end = ctx.scene.duration - 0.02;
3003
+ const set = (item, keys) => {
3004
+ item.keyframes = keys;
3005
+ return item;
3006
+ };
3007
+ const appear = (delay, fromX = 0, fromY = 70) => [
3008
+ point(0, fromX, fromY, 0.82, 0.82, 0, 0),
3009
+ point(delay, fromX, fromY, 0.82, 0.82, 0, 0),
3010
+ point(delay + 0.38, 0, 0),
3011
+ point(end, 0, -8)
3012
+ ];
3013
+ const text3 = (name, value, x, y, w, h, size, color, delay) => set(caption(ctx, name, value, x, y, w, h, size, color, delay), appear(delay, 0, 0));
3014
+ const circle = (name, x, y, d, color, delay) => box(ctx, name, x, y, d, d, color, d / 2, delay);
3015
+ const bar = (name, x, y, w, h, color, delay, rotation = 0) => set(box(ctx, name, x, y, w, h, color, h / 2, delay, 0, 0, 1, rotation), appear(delay, 0, 0));
3016
+ const body = box(ctx, "\u05DE\u05E1\u05D2\u05E8\u05EA \u05D8\u05DC\u05E4\u05D5\u05DF \u05D3\u05D9\u05D2\u05D9\u05D8\u05DC\u05D9\u05EA", 182, 47, 394, 642, NAVY, 45, 0.08);
3017
+ const screen = box(ctx, "\u05DE\u05E1\u05DA \u05D8\u05DC\u05E4\u05D5\u05DF \u05D3\u05D9\u05D2\u05D9\u05D8\u05DC\u05D9", 204, 69, 350, 598, WHITE, 29, 0.2);
3018
+ for (const item of [body, screen]) set(item, [
3019
+ point(0, 0, 195, 0.76, 0.76, -8, 0),
3020
+ point(0.48, 0, 0, 1, 1, 0),
3021
+ point(1.78, 0, -8, 1.025, 1.025, 1),
3022
+ point(end, 0, 0)
3023
+ ]);
3024
+ box(ctx, "\u05E8\u05DE\u05E7\u05D5\u05DC \u05D8\u05DC\u05E4\u05D5\u05DF", 343, 89, 70, 8, NAVY, 4, 0.42);
3025
+ box(ctx, "\u05E9\u05D5\u05E8\u05EA \u05E0\u05D9\u05D5\u05D5\u05D8", 226, 124, 306, 8, PALE, 4, 0.53);
3026
+ for (let i = 0; i < 3; i++) {
3027
+ const dot = circle(
3028
+ `\u05E9\u05DC\u05D1 \u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D4 ${i + 1}`,
3029
+ 273 + i * 106,
3030
+ 607,
3031
+ 20,
3032
+ i === Math.min(ctx.index, 2) ? RED : "#D4D9E2",
3033
+ 0.55 + i * 0.11
3034
+ );
3035
+ set(dot, appear(0.58 + i * 0.12, 0, 26));
3036
+ }
3037
+ if (ctx.index === 0) {
3038
+ const halo = circle("\u05D4\u05D9\u05DC\u05D4 \u05E1\u05D1\u05D9\u05D1 \u05E4\u05E2\u05D5\u05DC\u05D4", 236, 169, 286, "#FDE5EC", 0.16);
3039
+ set(halo, [
3040
+ point(0, 0, 0, 0.3, 0.3, 0, 0),
3041
+ point(0.9, 0, 0, 1, 1, 0, 0.95),
3042
+ point(2, 0, 0, 1.12, 1.12, 0, 0.6),
3043
+ point(end, 0, 0, 1.27, 1.27, 0, 0.25)
3044
+ ]);
3045
+ const tile = box(ctx, "\u05D0\u05E8\u05D9\u05D7 \u05E4\u05E2\u05D5\u05DC\u05D4 \u05E8\u05D0\u05E9\u05D9", 283, 225, 194, 184, RED, 37, 0.55);
3046
+ set(tile, [
3047
+ point(0, 0, 140, 0.28, 0.28, -18, 0),
3048
+ point(0.6, 0, 140, 0.28, 0.28, -18, 0),
3049
+ point(1.1, 0, 0),
3050
+ point(2.1, 0, -9, 1.07, 1.07, 4),
3051
+ point(end, 0, 0)
3052
+ ]);
3053
+ bar("\u05D7\u05E5 \u05E4\u05E2\u05D5\u05DC\u05D4 \u05D0\u05D5\u05E4\u05E7\u05D9", 338, 313, 91, 8, WHITE, 0.84);
3054
+ bar("\u05D7\u05E5 \u05E4\u05E2\u05D5\u05DC\u05D4 \u05E2\u05DC\u05D9\u05D5\u05DF", 333, 303, 29, 8, WHITE, 0.9, -43);
3055
+ bar("\u05D7\u05E5 \u05E4\u05E2\u05D5\u05DC\u05D4 \u05EA\u05D7\u05EA\u05D5\u05DF", 333, 322, 29, 8, WHITE, 0.9, 43);
3056
+ const button = box(ctx, "\u05DB\u05E4\u05EA\u05D5\u05E8 \u05D4\u05EA\u05D7\u05DC\u05D4", 253, 481, 252, 76, NAVY, 38, 1.1);
3057
+ set(button, appear(1.13, 0, 90));
3058
+ text3("\u05DC\u05D7\u05E6\u05DF \u05D4\u05EA\u05D7\u05DC\u05D4", "\u05DE\u05EA\u05D7\u05D9\u05DC\u05D9\u05DD", 272, 491, 214, 53, 38, WHITE, 1.52);
3059
+ const tap = circle("\u05DC\u05D7\u05D9\u05E6\u05D4 \u05E8\u05D0\u05E9\u05D5\u05E0\u05D4", 409, 500, 88, "#FD9CB7", 1.7);
3060
+ set(tap, [
3061
+ point(0, 0, 0, 0.1, 0.1, 0, 0),
3062
+ point(1.67, 0, 0, 0.1, 0.1, 0, 0),
3063
+ point(2.03, 0, 0, 1, 1, 0, 0.8),
3064
+ point(end, 0, 0, 1.8, 1.8, 0, 0)
3065
+ ]);
3066
+ return true;
3067
+ }
3068
+ if (ctx.index === 1) {
3069
+ text3("\u05DB\u05D5\u05EA\u05E8\u05EA \u05E4\u05EA\u05D9\u05D7\u05EA \u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D4", "\u05D4\u05DE\u05E1\u05DA \u05E0\u05E4\u05EA\u05D7", 245, 167, 270, 70, 51, NAVY, 0.63);
3070
+ const panel = box(ctx, "\u05DC\u05D5\u05D7 \u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D4", 240, 252, 280, 280, PALE, 24, 0.7);
3071
+ set(panel, appear(0.7, 0, 100));
3072
+ const emblem = circle("\u05E1\u05DE\u05DC \u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D4", 329, 280, 100, RED, 0.88);
3073
+ set(emblem, [
3074
+ point(0, 0, 80, 0.2, 0.2, -30, 0),
3075
+ point(0.88, 0, 80, 0.2, 0.2, -30, 0),
3076
+ point(1.26, 0, 0),
3077
+ point(2.25, 0, -9, 1.12, 1.12, 8),
3078
+ point(end, 0, 0)
3079
+ ]);
3080
+ bar("\u05D2\u05D2 \u05D1\u05D9\u05EA \u05E9\u05DE\u05D0\u05DC", 351, 316, 34, 5, WHITE, 1.02, -43);
3081
+ bar("\u05D2\u05D2 \u05D1\u05D9\u05EA \u05D9\u05DE\u05D9\u05DF", 377, 316, 34, 5, WHITE, 1.02, 43);
3082
+ bar("\u05E7\u05D9\u05E8 \u05D1\u05D9\u05EA \u05E9\u05DE\u05D0\u05DC", 356, 333, 5, 30, WHITE, 1.08);
3083
+ bar("\u05E7\u05D9\u05E8 \u05D1\u05D9\u05EA \u05D9\u05DE\u05D9\u05DF", 397, 333, 5, 30, WHITE, 1.08);
3084
+ bar("\u05D1\u05E1\u05D9\u05E1 \u05D1\u05D9\u05EA", 356, 359, 46, 5, WHITE, 1.08);
3085
+ for (let i = 0; i < 3; i++) {
3086
+ const row = box(ctx, `\u05E9\u05D5\u05E8\u05EA \u05D8\u05E2\u05D9\u05E0\u05D4 ${i + 1}`, 270, 409 + i * 43, 218 - i * 34, 17, i === 0 ? RED : "#DAA6B2", 8, 1.05 + i * 0.24);
3087
+ set(row, [
3088
+ point(0, -180, 0, 0.08, 1, 0, 0),
3089
+ point(1.03 + i * 0.22, -180, 0, 0.08, 1, 0, 0),
3090
+ point(1.48 + i * 0.22, 0, 0),
3091
+ point(end, 8, 0)
3092
+ ]);
3093
+ }
3094
+ return true;
3095
+ }
3096
+ if (ctx.index === 2) {
3097
+ text3("\u05DB\u05D5\u05EA\u05E8\u05EA \u05D1\u05D7\u05D9\u05E8\u05EA \u05E4\u05E2\u05D5\u05DC\u05D4", "\u05DE\u05D4 \u05E2\u05D5\u05E9\u05D9\u05DD \u05E2\u05DB\u05E9\u05D9\u05D5?", 242, 166, 273, 78, 44, NAVY, 0.6);
3098
+ ["\u05D4\u05DC\u05D5\u05D5\u05D0\u05D4", "\u05DE\u05D9\u05D3\u05E2 \u05E0\u05D5\u05E1\u05E3"].forEach((label, i) => {
3099
+ const y = 276 + i * 130;
3100
+ const row = box(ctx, `\u05D0\u05E4\u05E9\u05E8\u05D5\u05EA \u05D1\u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D4 ${i + 1}`, 238, y, 286, 103, i ? PALE : "#FDE1E9", 20, 0.82 + i * 0.31);
3101
+ set(row, appear(0.82 + i * 0.31, i ? 180 : -180, 0));
3102
+ const marker = circle(`\u05E1\u05D9\u05DE\u05D5\u05DF \u05D0\u05E4\u05E9\u05E8\u05D5\u05EA ${i + 1}`, 263, y + 29, 44, i ? "#D6DCE4" : RED, 1.01 + i * 0.31);
3103
+ set(marker, appear(1.01 + i * 0.31, i ? 100 : -100, 0));
3104
+ text3(`\u05EA\u05D5\u05D5\u05D9\u05EA \u05D0\u05E4\u05E9\u05E8\u05D5\u05EA \u05D1\u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D4 ${i + 1}`, label, 315, y + 22, 180, 61, 37, NAVY, 1.21 + i * 0.31);
3105
+ });
3106
+ const focus = circle("\u05DC\u05D7\u05D9\u05E6\u05D4 \u05E2\u05DC \u05D1\u05D7\u05D9\u05E8\u05D4", 272, 302, 75, "#FF7D9D", 1.67);
3107
+ set(focus, [
3108
+ point(0, 0, 0, 0.1, 0.1, 0, 0),
3109
+ point(1.65, 0, 0, 0.1, 0.1, 0, 0),
3110
+ point(1.94, 0, 0, 1, 1, 0, 0.72),
3111
+ point(end, 0, 0, 2, 2, 0, 0)
3112
+ ]);
3113
+ return true;
3114
+ }
3115
+ text3("\u05DB\u05D5\u05EA\u05E8\u05EA \u05D1\u05D3\u05D9\u05E7\u05EA \u05E4\u05E8\u05D8\u05D9\u05DD", "\u05DC\u05E4\u05E0\u05D9 \u05E9\u05DE\u05D0\u05E9\u05E8\u05D9\u05DD", 229, 155, 300, 88, 35, NAVY, 0.63);
3116
+ ["\u05E4\u05E8\u05D8\u05D9\u05DD", "\u05EA\u05E0\u05D0\u05D9\u05DD", "\u05D1\u05D7\u05D9\u05E8\u05D4"].forEach((label, i) => {
3117
+ const y = 250 + i * 89;
3118
+ const row = box(ctx, `\u05E9\u05D5\u05E8\u05EA \u05D1\u05D3\u05D9\u05E7\u05D4 ${i + 1}`, 243, y, 277, 72, PALE, 15, 0.78 + i * 0.33);
3119
+ set(row, appear(0.78 + i * 0.33, i % 2 ? 130 : -130, 0));
3120
+ text3(`\u05EA\u05D5\u05DB\u05DF \u05D1\u05D3\u05D9\u05E7\u05D4 ${i + 1}`, label, 297, y + 9, 173, 50, 31, NAVY, 1.17 + i * 0.33);
3121
+ const check = circle(`\u05E1\u05D9\u05DE\u05D5\u05DF \u05D1\u05D3\u05D9\u05E7\u05D4 ${i + 1}`, 466, y + 17, 39, RED, 1.23 + i * 0.33);
3122
+ set(check, appear(1.23 + i * 0.33, 0, 0));
3123
+ bar(`\u05D5\u05D9 \u05E7\u05E6\u05E8 \u05D1\u05D3\u05D9\u05E7\u05D4 ${i + 1}`, 474, y + 37, 13, 4, WHITE, 1.31 + i * 0.33, 43);
3124
+ bar(`\u05D5\u05D9 \u05D0\u05E8\u05D5\u05DA \u05D1\u05D3\u05D9\u05E7\u05D4 ${i + 1}`, 483, y + 34, 21, 4, WHITE, 1.35 + i * 0.33, -43);
3125
+ });
3126
+ const confirm = box(ctx, "\u05DB\u05E4\u05EA\u05D5\u05E8 \u05D4\u05DE\u05E9\u05DA", 247, 550, 268, 56, RED, 28, 1.85);
3127
+ set(confirm, [
3128
+ point(0, 0, 85, 0.8, 0.8, 0, 0),
3129
+ point(1.85, 0, 85, 0.8, 0.8, 0, 0),
3130
+ point(2.27, 0, 0),
3131
+ point(end, 0, 0, 1.07, 1.07)
3132
+ ]);
3133
+ text3("\u05EA\u05D5\u05D5\u05D9\u05EA \u05D4\u05DE\u05E9\u05DA", "\u05DE\u05DE\u05E9\u05D9\u05DB\u05D9\u05DD", 282, 553, 198, 50, 31, WHITE, 2.27);
3134
+ return true;
3135
+ }
3136
+ function careerStoryboard(ctx) {
3137
+ if (ctx.theme !== "book-steps" || ctx.index > 2) return false;
3138
+ const end = ctx.scene.duration - 0.02;
3139
+ const set = (item, frames) => {
3140
+ item.keyframes = frames;
3141
+ return item;
3142
+ };
3143
+ const reveal = (delay, fromX = 0, fromY = 0) => [
3144
+ point(0, fromX, fromY, 0.88, 0.88, 0, 0),
3145
+ point(delay, fromX, fromY, 0.88, 0.88, 0, 0),
3146
+ point(delay + 0.43, 0, 0),
3147
+ point(Math.max(delay + 0.53, end - 0.44), 0, -8, 1.025, 1.025),
3148
+ point(end, 0, 0)
3149
+ ];
3150
+ const shape = (name, x, y, w, h, color, radius, delay, fromX = 0, fromY = 0) => set(box(ctx, name, x, y, w, h, color, radius, delay), reveal(delay, fromX, fromY));
3151
+ const text3 = (name, value, x, y, w, h, size, color, delay) => set(caption(ctx, name, value, x, y, w, h, size, color, delay), reveal(delay));
3152
+ if (ctx.index === 0) {
3153
+ shape("\u05D4\u05D9\u05DC\u05D4 \u05DE\u05D0\u05D7\u05D5\u05E8\u05D9 \u05E1\u05E4\u05E8\u05D9\u05DD", 73, 79, 610, 610, "#C9003C", 305, 0.04);
3154
+ ["\u05DE\u05D8\u05E8\u05D4", "\u05DC\u05D9\u05DE\u05D5\u05D3", "\u05D4\u05DB\u05E9\u05E8\u05D4"].forEach((label, i) => {
3155
+ const x = 62 + i * 127;
3156
+ const y = 495 - i * 137;
3157
+ const delay = 0.2 + i * 0.48;
3158
+ shape(`\u05E6\u05DC \u05E1\u05E4\u05E8 ${i + 1}`, x + 12, y + 15, 322, 101, "#9E0634", 15, delay, 0, 155);
3159
+ shape(`\u05E1\u05E4\u05E8 \u05DE\u05E1\u05DC\u05D5\u05DC ${i + 1}`, x, y, 322, 101, i === 1 ? PALE : WHITE, 15, delay + 0.08, 0, 155);
3160
+ shape(`\u05E9\u05D3\u05E8\u05EA \u05E1\u05E4\u05E8 ${i + 1}`, x + 10, y + 16, 12, 69, RED, 6, delay + 0.19);
3161
+ shape(`\u05D3\u05E4\u05D9 \u05E1\u05E4\u05E8 ${i + 1}`, x + 40, y + 88, 260, 4, "#EFCBD5", 2, delay + 0.21);
3162
+ text3(`\u05DE\u05E1\u05E4\u05E8 \u05E1\u05E4\u05E8 ${i + 1}`, `0${i + 1}`, x + 38, y + 14, 77, 67, 45, RED, delay + 0.28);
3163
+ text3(`\u05E0\u05D5\u05E9\u05D0 \u05E1\u05E4\u05E8 ${i + 1}`, label, x + 117, y + 16, 176, 65, 38, NAVY, delay + 0.33);
3164
+ });
3165
+ shape("\u05E7\u05D5 \u05E2\u05DC\u05D9\u05D4", 474, 121, 179, 10, WHITE, 5, 1.51, -120, 0);
3166
+ shape("\u05D7\u05D5\u05EA\u05DD \u05D9\u05E2\u05D3", 629, 99, 56, 56, WHITE, 28, 1.69, 0, 90);
3167
+ return true;
3168
+ }
3169
+ if (ctx.index === 1) {
3170
+ shape("\u05E6\u05DC \u05DC\u05D5\u05D7 \u05DE\u05E1\u05DC\u05D5\u05DC\u05D9\u05DD", 75, 103, 633, 568, "#EFDDE2", 29, 0.08, 0, 145);
3171
+ shape("\u05DC\u05D5\u05D7 \u05DE\u05E1\u05DC\u05D5\u05DC\u05D9\u05DD", 62, 86, 633, 568, WHITE, 29, 0.15, 0, 145);
3172
+ text3("\u05DB\u05D5\u05EA\u05E8\u05EA \u05D1\u05D7\u05D9\u05E8\u05EA \u05DE\u05E1\u05DC\u05D5\u05DC", "\u05D1\u05D5\u05D7\u05E8\u05D9\u05DD \u05EA\u05D7\u05D5\u05DD", 109, 119, 538, 77, 50, NAVY, 0.58);
3173
+ ["\u05E2\u05D9\u05E6\u05D5\u05D1", "\u05E0\u05EA\u05D5\u05E0\u05D9\u05DD", "\u05E4\u05D9\u05EA\u05D5\u05D7"].forEach((label, i) => {
3174
+ const y = 216 + i * 117;
3175
+ const delay = 0.79 + i * 0.49;
3176
+ shape(`\u05DB\u05E8\u05D8\u05D9\u05E1 \u05EA\u05D7\u05D5\u05DD ${i + 1}`, 102, y, 555, 87, i === 1 ? "#FDE0E8" : PALE, 20, delay, i % 2 ? 170 : -170);
3177
+ shape(`\u05E1\u05D9\u05DE\u05D5\u05DF \u05EA\u05D7\u05D5\u05DD ${i + 1}`, 125, y + 22, 43, 43, i === 1 ? RED : "#E4B5C2", 22, delay + 0.13, i % 2 ? 90 : -90);
3178
+ text3(`\u05E9\u05DD \u05EA\u05D7\u05D5\u05DD ${i + 1}`, label, 200, y + 9, 293, 66, 41, NAVY, delay + 0.3);
3179
+ shape(`\u05E7\u05D5 \u05EA\u05D7\u05D5\u05DD ${i + 1}`, 563, y + 38, 62, 9, i === 1 ? RED : "#D1AAB6", 5, delay + 0.36);
3180
+ });
3181
+ text3("\u05D4\u05E2\u05E8\u05EA \u05D1\u05D7\u05D9\u05E8\u05EA \u05DE\u05E1\u05DC\u05D5\u05DC", "\u05DC\u05D5\u05DE\u05D3\u05D9\u05DD \u05D0\u05EA \u05DE\u05D4 \u05E9\u05DE\u05EA\u05D0\u05D9\u05DD \u05DC\u05DB\u05DD", 124, 581, 510, 49, 26, NAVY, 2.55);
3182
+ return true;
3183
+ }
3184
+ shape("\u05E6\u05DC \u05DC\u05D5\u05D7 \u05EA\u05DB\u05E0\u05D5\u05DF", 75, 103, 633, 568, "#B9003C", 29, 0.06, 0, 145);
3185
+ shape("\u05DC\u05D5\u05D7 \u05EA\u05DB\u05E0\u05D5\u05DF \u05DC\u05D9\u05DE\u05D5\u05D3\u05D9\u05DD", 62, 86, 633, 568, WHITE, 29, 0.14, 0, 145);
3186
+ text3("\u05DB\u05D5\u05EA\u05E8\u05EA \u05DC\u05D5\u05D7 \u05EA\u05DB\u05E0\u05D5\u05DF \u05DC\u05D9\u05DE\u05D5\u05D3\u05D9\u05DD", "\u05DE\u05EA\u05DB\u05E0\u05E0\u05D9\u05DD \u05D0\u05EA \u05D4\u05D3\u05E8\u05DA", 103, 121, 554, 75, 45, NAVY, 0.52);
3187
+ ["\u05D6\u05DE\u05DF", "\u05E2\u05DC\u05D5\u05EA", "\u05E9\u05D2\u05E8\u05D4"].forEach((label, i) => {
3188
+ const y = 226 + i * 116;
3189
+ const delay = 0.72 + i * 0.53;
3190
+ shape(`\u05E8\u05E7\u05E2 \u05DE\u05D3\u05D3 ${i + 1}`, 101, y, 554, 87, i === 1 ? "#FDE0E8" : PALE, 18, delay, 0, 100);
3191
+ text3(`\u05E9\u05DD \u05DE\u05D3\u05D3 ${i + 1}`, label, 119, y + 9, 146, 64, 35, NAVY, delay + 0.25);
3192
+ shape(`\u05DE\u05E1\u05DC\u05D5\u05DC \u05DE\u05D3\u05D3 ${i + 1}`, 292, y + 32, 312, 22, "#DFBCC7", 11, delay + 0.19);
3193
+ const widths = [230, 173, 263];
3194
+ const fill = box(ctx, `\u05D4\u05EA\u05E7\u05D3\u05DE\u05D5\u05EA \u05DE\u05D3\u05D3 ${i + 1}`, 292, y + 32, widths[i], 22, RED, 11, delay + 0.33);
3195
+ set(fill, [
3196
+ point(0, -widths[i] / 2, 0, 0.02, 1, 0, 0),
3197
+ point(delay + 0.31, -widths[i] / 2, 0, 0.02, 1, 0, 0),
3198
+ point(delay + 0.85, 0, 0),
3199
+ point(end, 5, 0)
3200
+ ]);
3201
+ });
3202
+ text3("\u05D4\u05E2\u05E8\u05EA \u05EA\u05DB\u05E0\u05D5\u05DF \u05DC\u05D9\u05DE\u05D5\u05D3\u05D9\u05DD", "\u05D1\u05D5\u05E0\u05D9\u05DD \u05DE\u05E1\u05D2\u05E8\u05EA \u05D9\u05E9\u05D9\u05DE\u05D4", 120, 588, 519, 48, 27, NAVY, 2.65);
3203
+ return true;
3204
+ }
3205
+ function homeRefreshStoryboard(ctx) {
3206
+ if (ctx.theme !== "room-build" || ctx.index > 2) return false;
3207
+ const end = ctx.scene.duration - 0.02;
3208
+ const set = (item, frames) => {
3209
+ item.keyframes = frames;
3210
+ return item;
3211
+ };
3212
+ const arrive = (delay, dx = 0, dy = 0) => [
3213
+ point(0, dx, dy, 0.9, 0.9, 0, 0),
3214
+ point(delay, dx, dy, 0.9, 0.9, 0, 0),
3215
+ point(delay + 0.38, 0, 0),
3216
+ point(Math.max(delay + 0.5, end - 0.42), 0, -5, 1.02, 1.02),
3217
+ point(end, 0, 0)
3218
+ ];
3219
+ const shape = (name, x, y, w, h, color, radius, delay, dx = 0, dy = 0) => set(box(ctx, name, x, y, w, h, color, radius, delay), arrive(delay, dx, dy));
3220
+ const label = (name, value, x, y, w, h, size, color, delay) => set(caption(ctx, name, value, x, y, w, h, size, color, delay), arrive(delay, 0, 24));
3221
+ if (ctx.index === 0) {
3222
+ shape("\u05D4\u05D9\u05DC\u05D4 \u05E9\u05DC \u05D4\u05D1\u05D9\u05EA", 62, 55, 640, 630, "#BB0038", 310, 0.03);
3223
+ shape("\u05E9\u05D8\u05D9\u05D7 \u05D7\u05D3\u05E8", 117, 568, 534, 71, "#E9C0CA", 35, 0.37, 0, 75);
3224
+ shape("\u05E7\u05D9\u05E8 \u05D4\u05D7\u05D3\u05E8", 92, 160, 586, 425, WHITE, 20, 0.12, 0, 130);
3225
+ shape("\u05E8\u05E6\u05E4\u05EA \u05D4\u05D1\u05D9\u05EA", 91, 581, 587, 26, NAVY, 13, 0.42, -160);
3226
+ shape("\u05DE\u05E1\u05D2\u05E8\u05EA \u05D7\u05DC\u05D5\u05DF \u05D4\u05D1\u05D9\u05EA", 418, 196, 192, 228, NAVY, 14, 0.62, 0, -100);
3227
+ shape("\u05D0\u05D5\u05E8 \u05D7\u05DC\u05D5\u05DF \u05D4\u05D1\u05D9\u05EA", 430, 209, 168, 204, "#F7B8C9", 7, 0.75, 0, -85);
3228
+ shape("\u05DE\u05D5\u05D8 \u05D7\u05DC\u05D5\u05DF \u05D4\u05D1\u05D9\u05EA", 505, 209, 12, 204, WHITE, 6, 0.86);
3229
+ shape("\u05E7\u05D5 \u05D7\u05DC\u05D5\u05DF \u05D4\u05D1\u05D9\u05EA", 430, 308, 168, 10, WHITE, 5, 0.94);
3230
+ shape("\u05D1\u05E1\u05D9\u05E1 \u05E1\u05E4\u05D4", 160, 471, 350, 93, RED, 28, 1.02, -160);
3231
+ shape("\u05D2\u05D1 \u05E1\u05E4\u05D4", 174, 399, 319, 92, "#C9003C", 28, 1.14, -160);
3232
+ [181, 453].forEach((x, i) => shape(`\u05E8\u05D2\u05DC \u05E1\u05E4\u05D4 \u05D1\u05D9\u05EA ${i + 1}`, x, 557, 26, 36, NAVY, 7, 1.31));
3233
+ shape("\u05DE\u05D5\u05D8 \u05DE\u05E0\u05D5\u05E8\u05D4", 328, 202, 10, 196, NAVY, 5, 1.42, 0, -100);
3234
+ shape("\u05D0\u05D4\u05D9\u05DC \u05DE\u05E0\u05D5\u05E8\u05D4", 284, 367, 97, 64, "#EAC6D0", 18, 1.57, 0, -95);
3235
+ shape("\u05D0\u05D5\u05E8 \u05DE\u05E0\u05D5\u05E8\u05D4", 307, 409, 52, 9, "#FFC7D4", 5, 1.81);
3236
+ return true;
3237
+ }
3238
+ if (ctx.index === 1) {
3239
+ shape("\u05E6\u05DC \u05E7\u05D8\u05DC\u05D5\u05D2 \u05D7\u05D3\u05E8\u05D9\u05DD", 74, 87, 642, 584, "#E9C8D1", 30, 0.08, 0, 135);
3240
+ shape("\u05E7\u05D8\u05DC\u05D5\u05D2 \u05D7\u05D3\u05E8\u05D9\u05DD", 61, 74, 642, 584, WHITE, 30, 0.16, 0, 135);
3241
+ label("\u05DB\u05D5\u05EA\u05E8\u05EA \u05E4\u05D9\u05E0\u05D5\u05EA \u05D4\u05D1\u05D9\u05EA", "\u05D1\u05D5\u05D7\u05E8\u05D9\u05DD \u05E4\u05D9\u05E0\u05D4", 98, 101, 564, 75, 48, NAVY, 0.47);
3242
+ const rooms = [
3243
+ { name: "\u05DE\u05D8\u05D1\u05D7", color: "#FFE1E9" },
3244
+ { name: "\u05D7\u05D3\u05E8 \u05E2\u05D1\u05D5\u05D3\u05D4", color: "#F8D0DB" },
3245
+ { name: "\u05E4\u05D9\u05E0\u05EA \u05D9\u05E9\u05D9\u05D1\u05D4", color: "#FFE1E9" }
3246
+ ];
3247
+ rooms.forEach((room, i) => {
3248
+ const y = 194 + i * 138;
3249
+ const delay = 0.68 + i * 0.53;
3250
+ shape(`\u05DB\u05E8\u05D8\u05D9\u05E1 ${room.name}`, 96, y, 573, 112, room.color, 22, delay, i % 2 ? 160 : -160);
3251
+ shape(`\u05D0\u05E8\u05D9\u05D7 ${room.name}`, 113, y + 14, 81, 83, i === 1 ? RED : "#E5ACBB", 17, delay + 0.12, 0, 54);
3252
+ if (i === 0) {
3253
+ for (let cell = 0; cell < 4; cell++) shape(
3254
+ `\u05D0\u05E8\u05D9\u05D7 \u05DE\u05D8\u05D1\u05D7 ${cell + 1}`,
3255
+ 134 + cell % 2 * 25,
3256
+ y + 37 + Math.floor(cell / 2) * 25,
3257
+ 17,
3258
+ 17,
3259
+ WHITE,
3260
+ 3,
3261
+ delay + 0.22 + cell * 0.045
3262
+ );
3263
+ } else if (i === 1) {
3264
+ shape("\u05DE\u05E1\u05DA \u05D7\u05D3\u05E8 \u05D4\u05E2\u05D1\u05D5\u05D3\u05D4", 132, y + 34, 47, 31, WHITE, 5, delay + 0.23);
3265
+ shape("\u05E8\u05D2\u05DC \u05DE\u05E1\u05DA \u05D7\u05D3\u05E8 \u05D4\u05E2\u05D1\u05D5\u05D3\u05D4", 152, y + 65, 7, 11, WHITE, 2, delay + 0.29);
3266
+ shape("\u05D1\u05E1\u05D9\u05E1 \u05DE\u05E1\u05DA \u05D7\u05D3\u05E8 \u05D4\u05E2\u05D1\u05D5\u05D3\u05D4", 140, y + 76, 31, 5, WHITE, 2, delay + 0.35);
3267
+ } else {
3268
+ shape("\u05DB\u05E8\u05D9\u05EA \u05E4\u05D9\u05E0\u05EA \u05D9\u05E9\u05D9\u05D1\u05D4", 135, y + 36, 45, 40, WHITE, 17, delay + 0.23);
3269
+ shape("\u05D1\u05E1\u05D9\u05E1 \u05E4\u05D9\u05E0\u05EA \u05D9\u05E9\u05D9\u05D1\u05D4", 128, y + 73, 58, 8, WHITE, 4, delay + 0.34);
3270
+ }
3271
+ label(`\u05E9\u05DD ${room.name}`, room.name, 224, y + 20, 347, 68, 39, NAVY, delay + 0.27);
3272
+ shape(`\u05E7\u05D5 \u05D1\u05D7\u05D9\u05E8\u05D4 ${room.name}`, 599, y + 50, 42, 11, i === 1 ? RED : "#D2A4B1", 6, delay + 0.35);
3273
+ });
3274
+ label("\u05E9\u05D5\u05E8\u05EA \u05D1\u05D7\u05D9\u05E8\u05EA \u05D4\u05D1\u05D9\u05EA", "\u05DE\u05EA\u05D7\u05D9\u05DC\u05D9\u05DD \u05D1\u05DE\u05D4 \u05E9\u05D4\u05DB\u05D9 \u05D7\u05E9\u05D5\u05D1", 110, 608, 540, 43, 25, NAVY, 2.66);
3275
+ return true;
3276
+ }
3277
+ shape("\u05E6\u05DC \u05EA\u05DB\u05E0\u05D9\u05EA \u05D4\u05D1\u05D9\u05EA", 74, 87, 642, 584, "#B6003C", 30, 0.08, 0, 135);
3278
+ shape("\u05EA\u05DB\u05E0\u05D9\u05EA \u05D4\u05D1\u05D9\u05EA", 61, 74, 642, 584, WHITE, 30, 0.15, 0, 135);
3279
+ label("\u05DB\u05D5\u05EA\u05E8\u05EA \u05EA\u05DB\u05E0\u05D9\u05EA \u05D4\u05D1\u05D9\u05EA", "\u05DE\u05EA\u05DB\u05E0\u05E0\u05D9\u05DD \u05E9\u05D9\u05E0\u05D5\u05D9", 105, 104, 550, 72, 48, NAVY, 0.48);
3280
+ shape("\u05D2\u05D2 \u05D4\u05EA\u05DB\u05E0\u05D9\u05EA \u05E9\u05DE\u05D0\u05DC", 149, 232, 252, 12, RED, 6, 0.79, -90);
3281
+ shape("\u05D2\u05D2 \u05D4\u05EA\u05DB\u05E0\u05D9\u05EA \u05D9\u05DE\u05D9\u05DF", 397, 232, 252, 12, RED, 6, 0.9, 90);
3282
+ shape("\u05E7\u05D9\u05E8 \u05EA\u05DB\u05E0\u05D9\u05EA \u05E9\u05DE\u05D0\u05DC", 177, 244, 11, 230, NAVY, 5, 1.01, 0, -70);
3283
+ shape("\u05E7\u05D9\u05E8 \u05EA\u05DB\u05E0\u05D9\u05EA \u05D9\u05DE\u05D9\u05DF", 603, 244, 11, 230, NAVY, 5, 1.13, 0, -70);
3284
+ shape("\u05E8\u05E6\u05E4\u05EA \u05D4\u05EA\u05DB\u05E0\u05D9\u05EA", 177, 465, 437, 12, NAVY, 6, 1.24, -110);
3285
+ ["\u05E1\u05DB\u05D5\u05DD", "\u05D6\u05DE\u05DF", "\u05E1\u05D3\u05E8"].forEach((name, i) => {
3286
+ const y = 279 + i * 56;
3287
+ const delay = 1.27 + i * 0.38;
3288
+ label(`\u05E9\u05D3\u05D4 \u05EA\u05DB\u05E0\u05D5\u05DF ${name}`, name, 207, y, 128, 48, 30, NAVY, delay);
3289
+ shape(`\u05DE\u05E1\u05DC\u05D5\u05DC ${name}`, 360, y + 17, 205, 15, "#E9C5CE", 8, delay + 0.09);
3290
+ const width = [153, 114, 173][i];
3291
+ const fill = box(ctx, `\u05DE\u05D7\u05D5\u05D5\u05DF ${name}`, 360, y + 17, width, 15, RED, 8, delay + 0.2);
3292
+ set(fill, [
3293
+ point(0, -width / 2, 0, 0.02, 1, 0, 0),
3294
+ point(delay + 0.2, -width / 2, 0, 0.02, 1, 0, 0),
3295
+ point(delay + 0.73, 0, 0),
3296
+ point(end, 4, 0)
3297
+ ]);
3298
+ });
3299
+ label("\u05D7\u05EA\u05D9\u05DE\u05EA \u05EA\u05DB\u05E0\u05D5\u05DF \u05D4\u05D1\u05D9\u05EA", "\u05E6\u05E2\u05D3 \u05D0\u05D7\u05E8 \u05E6\u05E2\u05D3", 160, 535, 465, 59, 35, RED, 2.9);
3300
+ return true;
3301
+ }
3302
+ function summerStoryboard(ctx) {
3303
+ if (ctx.theme !== "summer-case" || ctx.index > 3) return false;
3304
+ const end = ctx.scene.duration - 0.02;
3305
+ const set = (item, frames) => {
3306
+ item.keyframes = frames;
3307
+ return item;
3308
+ };
3309
+ const inView = (delay, dx = 0, dy = 0) => [
3310
+ point(0, dx, dy, 0.84, 0.84, 0, 0),
3311
+ point(delay, dx, dy, 0.84, 0.84, 0, 0),
3312
+ point(delay + 0.33, 0, 0),
3313
+ point(Math.max(delay + 0.39, end - 0.35), 0, -6, 1.025, 1.025),
3314
+ point(end, 0, 0)
3315
+ ];
3316
+ const shape = (name, x, y, w, h, color, radius, delay, dx = 0, dy = 0) => set(box(ctx, name, x, y, w, h, color, radius, delay), inView(delay, dx, dy));
3317
+ const word = (name, value, x, y, w, h, size, color, delay) => set(caption(ctx, name, value, x, y, w, h, size, color, delay), inView(delay, 0, 34));
3318
+ if (ctx.index === 0) {
3319
+ const sun = shape("\u05E9\u05DE\u05E9 \u05D4\u05E7\u05D9\u05E5", 488, 67, 195, 195, "#FFC5D4", 98, 0.12, 0, -90);
3320
+ set(sun, [
3321
+ point(0, 0, -90, 0.3, 0.3, -35, 0),
3322
+ point(0.12, 0, -90, 0.3, 0.3, -35, 0),
3323
+ point(0.6, 0, 0),
3324
+ point(end, -15, 13, 1.14, 1.14, 25)
3325
+ ]);
3326
+ for (let i = 0; i < 7; i++) {
3327
+ const angle = i * Math.PI * 2 / 7;
3328
+ shape(
3329
+ `\u05E7\u05E8\u05DF \u05E7\u05D9\u05E5 ${i + 1}`,
3330
+ 575 + Math.cos(angle) * 135,
3331
+ 154 + Math.sin(angle) * 135,
3332
+ 37,
3333
+ 8,
3334
+ WHITE,
3335
+ 4,
3336
+ 0.28 + i * 0.07,
3337
+ 0,
3338
+ -30
3339
+ );
3340
+ }
3341
+ shape("\u05E6\u05DC \u05DE\u05D6\u05D5\u05D5\u05D3\u05D4 \u05E7\u05D9\u05E5", 94, 606, 570, 37, "#9F0033", 19, 0.36, -250);
3342
+ shape("\u05D9\u05D3\u05D9\u05EA \u05DE\u05D6\u05D5\u05D5\u05D3\u05D4 \u05E7\u05D9\u05E5", 313, 253, 141, 110, WHITE, 37, 0.49, 0, 160);
3343
+ shape("\u05E4\u05EA\u05D7 \u05D9\u05D3\u05D9\u05EA \u05E7\u05D9\u05E5", 337, 278, 93, 71, RED, 25, 0.57, 0, 160);
3344
+ shape("\u05D2\u05D5\u05E3 \u05DE\u05D6\u05D5\u05D5\u05D3\u05D4 \u05E7\u05D9\u05E5", 130, 330, 500, 296, WHITE, 38, 0.64, -430);
3345
+ shape("\u05EA\u05E4\u05E8 \u05DE\u05D6\u05D5\u05D5\u05D3\u05D4 \u05E7\u05D9\u05E5", 151, 348, 457, 260, "#FFD6E1", 27, 0.73, -430);
3346
+ ["\u05D7\u05D5\u05E4\u05E9", "\u05D7\u05D5\u05D5\u05D9\u05D4", "\u05E8\u05D2\u05E2"].forEach((label, i) => {
3347
+ const x = 189 + i * 137;
3348
+ const delay = 0.89 + i * 0.32;
3349
+ shape(`\u05DB\u05E8\u05D8\u05D9\u05E1 ${label}`, x, 395 + i % 2 * 35, 118, 117, i === 1 ? RED : "#EFA1B6", 17, delay, 0, -185);
3350
+ word(`\u05DE\u05D9\u05DC\u05EA \u05DE\u05D6\u05D5\u05D5\u05D3\u05D4 ${label}`, label, x + 4, 421 + i % 2 * 35, 111, 56, 26, WHITE, delay + 0.12);
3351
+ });
3352
+ shape("\u05E1\u05E8\u05D8 \u05DE\u05D6\u05D5\u05D5\u05D3\u05D4 \u05E7\u05D9\u05E5", 350, 348, 29, 259, NAVY, 8, 1.83, 0, -95);
3353
+ return true;
3354
+ }
3355
+ if (ctx.index === 1) {
3356
+ shape("\u05DB\u05E8\u05D8\u05D9\u05E1 \u05E8\u05D7\u05D5\u05E7", 32, 101, 329, 565, WHITE, 29, 0.15, -350);
3357
+ shape("\u05DB\u05E8\u05D8\u05D9\u05E1 \u05E7\u05E8\u05D5\u05D1", 396, 101, 329, 565, "#FFE3EA", 29, 0.36, 350);
3358
+ shape("\u05E9\u05DE\u05D9\u05D9\u05DD \u05E8\u05D7\u05D5\u05E7", 57, 135, 279, 261, "#FFD9E3", 20, 0.33, 0, -105);
3359
+ shape("\u05E9\u05DE\u05E9 \u05E8\u05D7\u05D5\u05E7", 224, 172, 83, 83, RED, 42, 0.59, 0, -95);
3360
+ shape("\u05D9\u05DD \u05E8\u05D7\u05D5\u05E7", 57, 326, 279, 72, "#E8A5B8", 13, 0.77, -95);
3361
+ shape("\u05E7\u05D5 \u05D7\u05D5\u05E3 \u05E8\u05D7\u05D5\u05E7", 77, 310, 240, 12, WHITE, 6, 0.84, -95);
3362
+ shape("\u05DE\u05D6\u05D5\u05D5\u05D3\u05D4 \u05E7\u05D8\u05E0\u05D4 \u05E8\u05D7\u05D5\u05E7", 119, 262, 88, 109, NAVY, 17, 0.98, -120);
3363
+ shape("\u05D9\u05D3\u05D9\u05EA \u05DE\u05D6\u05D5\u05D5\u05D3\u05D4 \u05E8\u05D7\u05D5\u05E7", 144, 243, 39, 31, NAVY, 13, 0.91, -120);
3364
+ word("\u05E9\u05DD \u05D0\u05E4\u05E9\u05E8\u05D5\u05EA \u05E8\u05D7\u05D5\u05E7\u05D4", "\u05E0\u05D5\u05E1\u05E2\u05D9\u05DD", 68, 465, 258, 84, 47, NAVY, 1.19);
3365
+ shape("\u05E9\u05DE\u05D9\u05D9\u05DD \u05E7\u05E8\u05D5\u05D1", 419, 135, 282, 261, WHITE, 20, 0.55, 0, -105);
3366
+ shape("\u05D2\u05D2 \u05D1\u05D9\u05EA \u05E7\u05E8\u05D5\u05D1", 467, 216, 192, 22, RED, 11, 0.9, 0, -92);
3367
+ shape("\u05D1\u05D9\u05EA \u05E7\u05E8\u05D5\u05D1", 479, 236, 170, 146, "#EF9FB5", 12, 1.01, 0, -92);
3368
+ shape("\u05D7\u05DC\u05D5\u05DF \u05D1\u05D9\u05EA \u05E7\u05E8\u05D5\u05D1", 529, 260, 58, 59, WHITE, 8, 1.17, 0, -92);
3369
+ shape("\u05D3\u05DC\u05EA \u05D1\u05D9\u05EA \u05E7\u05E8\u05D5\u05D1", 597, 298, 30, 84, NAVY, 5, 1.32, 0, -92);
3370
+ word("\u05E9\u05DD \u05D0\u05E4\u05E9\u05E8\u05D5\u05EA \u05E7\u05E8\u05D5\u05D1\u05D4", "\u05E0\u05E9\u05D0\u05E8\u05D9\u05DD \u05E7\u05E8\u05D5\u05D1", 422, 461, 278, 92, 38, NAVY, 1.45);
3371
+ shape("\u05E1\u05DE\u05DF \u05D1\u05D7\u05D9\u05E8\u05D4 \u05E8\u05D7\u05D5\u05E7", 166, 580, 62, 8, RED, 4, 1.72);
3372
+ shape("\u05E1\u05DE\u05DF \u05D1\u05D7\u05D9\u05E8\u05D4 \u05E7\u05E8\u05D5\u05D1", 529, 580, 62, 8, RED, 4, 1.86);
3373
+ return true;
3374
+ }
3375
+ if (ctx.index === 2) {
3376
+ shape("\u05E6\u05DC \u05DC\u05D5\u05D7 \u05E7\u05D9\u05E5", 75, 95, 620, 555, "#AA0034", 29, 0.06, 0, 130);
3377
+ shape("\u05DC\u05D5\u05D7 \u05E7\u05D9\u05E5", 63, 80, 620, 555, WHITE, 29, 0.14, 0, 130);
3378
+ word("\u05DB\u05D5\u05EA\u05E8\u05EA \u05DC\u05D5\u05D7 \u05E7\u05D9\u05E5", "\u05DE\u05EA\u05DB\u05E0\u05E0\u05D9\u05DD \u05D0\u05EA \u05D4\u05E7\u05D9\u05E5", 93, 113, 560, 72, 45, NAVY, 0.42);
3379
+ ["\u05D3\u05E8\u05DA", "\u05D1\u05D9\u05DC\u05D5\u05D9", "\u05DE\u05E8\u05D5\u05D5\u05D7"].forEach((label, i) => {
3380
+ const y = 227 + i * 112;
3381
+ const delay = 0.63 + i * 0.44;
3382
+ shape(`\u05E9\u05D5\u05E8\u05EA \u05E7\u05D9\u05E5 ${i + 1}`, 100, y, 543, 88, i === 1 ? "#FAD4DF" : PALE, 19, delay, i % 2 ? 160 : -160);
3383
+ word(`\u05E9\u05DD \u05DE\u05D3\u05D3 \u05E7\u05D9\u05E5 ${i + 1}`, label, 123, y + 11, 132, 64, 34, NAVY, delay + 0.18);
3384
+ shape(`\u05DE\u05E1\u05DC\u05D5\u05DC \u05E7\u05D9\u05E5 ${i + 1}`, 280, y + 34, 319, 19, "#DEB8C4", 10, delay + 0.17);
3385
+ const width = [225, 165, 259][i];
3386
+ const fill = box(ctx, `\u05D4\u05EA\u05E7\u05D3\u05DE\u05D5\u05EA \u05E7\u05D9\u05E5 ${i + 1}`, 280, y + 34, width, 19, RED, 10, delay + 0.26);
3387
+ set(fill, [
3388
+ point(0, -width / 2, 0, 0.02, 1, 0, 0),
3389
+ point(delay + 0.26, -width / 2, 0, 0.02, 1, 0, 0),
3390
+ point(delay + 0.7, 0, 0),
3391
+ point(end, 5, 0)
3392
+ ]);
3393
+ });
3394
+ word("\u05D4\u05E2\u05E8\u05EA \u05DE\u05E1\u05D2\u05E8\u05EA \u05E7\u05D9\u05E5", "\u05DE\u05E9\u05D0\u05D9\u05E8\u05D9\u05DD \u05DE\u05E7\u05D5\u05DD \u05DC\u05D1\u05D7\u05D9\u05E8\u05D4", 107, 583, 546, 49, 27, RED, 2.07);
3395
+ return true;
3396
+ }
3397
+ shape("\u05E8\u05E7\u05E2 \u05DE\u05E1\u05DC\u05D5\u05DC \u05E7\u05D9\u05E5", 54, 104, 653, 540, "#FFE5EC", 30, 0.11, 0, 130);
3398
+ shape("\u05E7\u05D5 \u05DE\u05E1\u05DC\u05D5\u05DC \u05E7\u05D9\u05E5", 112, 370, 538, 18, NAVY, 9, 0.26, -320);
3399
+ [131, 337, 546].forEach((x, i) => {
3400
+ const delay = 0.51 + i * 0.49;
3401
+ shape(`\u05EA\u05D7\u05E0\u05EA \u05E7\u05D9\u05E5 ${i + 1}`, x, 315, 128, 128, i === 2 ? RED : WHITE, 64, delay, 0, 140);
3402
+ shape(`\u05DC\u05D9\u05D1\u05EA \u05EA\u05D7\u05E0\u05EA \u05E7\u05D9\u05E5 ${i + 1}`, x + 32, 347, 64, 64, i === 2 ? WHITE : RED, 32, delay + 0.14, 0, 100);
3403
+ });
3404
+ word("\u05E8\u05D2\u05E2 \u05EA\u05DB\u05E0\u05D5\u05DF \u05E7\u05D9\u05E5", "\u05D1\u05D5\u05D7\u05E8\u05D9\u05DD", 105, 468, 180, 67, 34, NAVY, 0.8);
3405
+ word("\u05E8\u05D2\u05E2 \u05D9\u05E6\u05D9\u05D0\u05D4 \u05E7\u05D9\u05E5", "\u05D9\u05D5\u05E6\u05D0\u05D9\u05DD", 307, 468, 180, 67, 34, NAVY, 1.3);
3406
+ word("\u05E8\u05D2\u05E2 \u05E1\u05E4\u05D5\u05E0\u05D8\u05E0\u05D9 \u05E7\u05D9\u05E5", "\u05DE\u05D2\u05DC\u05D9\u05DD", 512, 468, 180, 67, 34, NAVY, 1.85);
3407
+ shape("\u05E2\u05E0\u05E3 \u05E1\u05E4\u05D5\u05E0\u05D8\u05E0\u05D9 \u05E7\u05D9\u05E5", 595, 213, 11, 108, RED, 6, 2.04, 0, 80);
3408
+ shape("\u05E0\u05E7\u05D5\u05D3\u05EA \u05D2\u05D9\u05DC\u05D5\u05D9 \u05E7\u05D9\u05E5", 569, 179, 63, 63, RED, 32, 2.18, 0, 70);
3409
+ return true;
3410
+ }
3411
+ function carUpgradeStoryboard(ctx) {
3412
+ if (ctx.theme !== "car-garage" || ctx.index > 2) return false;
3413
+ const end = ctx.scene.duration - 0.02;
3414
+ const set = (item, frames) => {
3415
+ item.keyframes = frames;
3416
+ return item;
3417
+ };
3418
+ const arrive = (delay, dx = 0, dy = 0) => [
3419
+ point(0, dx, dy, 0.9, 0.9, 0, 0),
3420
+ point(delay, dx, dy, 0.9, 0.9, 0, 0),
3421
+ point(delay + 0.38, 0, 0),
3422
+ point(Math.max(delay + 0.45, end - 0.4), 0, -5, 1.02, 1.02),
3423
+ point(end, 0, 0)
3424
+ ];
3425
+ const shape = (name, x, y, w, h, color, radius, delay, dx = 0, dy = 0) => set(box(ctx, name, x, y, w, h, color, radius, delay), arrive(delay, dx, dy));
3426
+ const word = (name, value, x, y, w, h, size, color, delay) => set(caption(ctx, name, value, x, y, w, h, size, color, delay), arrive(delay, 0, 35));
3427
+ if (ctx.index === 0) {
3428
+ shape("\u05D4\u05D9\u05DC\u05D4 \u05DE\u05D5\u05E1\u05DA", 62, 74, 640, 610, "#AF0037", 305, 0.04);
3429
+ shape("\u05E7\u05D9\u05E8 \u05DE\u05D5\u05E1\u05DA", 81, 140, 598, 463, WHITE, 21, 0.11, 0, 120);
3430
+ shape("\u05E4\u05EA\u05D7 \u05DE\u05D5\u05E1\u05DA \u05DB\u05D4\u05D4", 118, 180, 521, 369, NAVY, 12, 0.24, 0, 120);
3431
+ for (let i = 0; i < 5; i++) {
3432
+ const shutter = box(ctx, `\u05EA\u05E8\u05D9\u05E1 \u05DE\u05D5\u05E1\u05DA ${i + 1}`, 127, 188 + i * 57, 502, 52, "#E6AFBF", 3, 0.27);
3433
+ set(shutter, [point(0, 0, 0), point(0.48, 0, 0), point(1.05 + i * 0.11, 0, -205 - i * 12, 1, 0.2, 0, 0), point(end, 0, -230, 1, 0.2, 0, 0)]);
3434
+ }
3435
+ shape("\u05E8\u05E6\u05E4\u05EA \u05DE\u05D5\u05E1\u05DA", 94, 550, 580, 23, "#DCA9B8", 11, 0.3, -170);
3436
+ const body = shape("\u05D2\u05D5\u05E3 \u05E8\u05DB\u05D1 \u05DE\u05E9\u05D5\u05D3\u05E8\u05D2", 154, 419, 470, 106, RED, 50, 1.08, -470);
3437
+ set(body, [point(0, -470, 0, 1, 1, 0, 0), point(1.08, -470, 0, 1, 1, 0, 0), point(1.77, 0, 0), point(end, 40, 0)]);
3438
+ shape("\u05D2\u05D2 \u05E8\u05DB\u05D1 \u05DE\u05E9\u05D5\u05D3\u05E8\u05D2", 244, 360, 276, 79, "#F0678B", 48, 1.15, -470);
3439
+ shape("\u05D7\u05DC\u05D5\u05DF \u05E7\u05D3\u05DE\u05D9 \u05E8\u05DB\u05D1", 407, 370, 94, 61, PALE, 20, 1.39, -470);
3440
+ shape("\u05D7\u05DC\u05D5\u05DF \u05D0\u05D7\u05D5\u05E8\u05D9 \u05E8\u05DB\u05D1", 264, 370, 119, 61, PALE, 20, 1.47, -470);
3441
+ [231, 505].forEach((x, i) => {
3442
+ const wheel = shape(`\u05D2\u05DC\u05D2\u05DC \u05DE\u05E9\u05D5\u05D3\u05E8\u05D2 ${i + 1}`, x, 491, 80, 80, NAVY, 40, 1.35 + i * 0.07, -470);
3443
+ set(wheel, [
3444
+ point(0, -470, 0, 1, 1, 0, 0),
3445
+ point(1.35 + i * 0.07, -470, 0, 1, 1, 0, 0),
3446
+ point(1.89, 0, 0, 1, 1, 390),
3447
+ point(end, 40, 0, 1, 1, 720)
3448
+ ]);
3449
+ shape(`\u05D8\u05D1\u05D5\u05E8 \u05D2\u05DC\u05D2\u05DC ${i + 1}`, x + 28, 519, 24, 24, WHITE, 12, 1.62 + i * 0.07, -470);
3450
+ });
3451
+ shape("\u05E4\u05E0\u05E1 \u05E8\u05DB\u05D1 \u05DE\u05E9\u05D5\u05D3\u05E8\u05D2", 585, 450, 44, 17, WHITE, 8, 1.62, -470);
3452
+ return true;
3453
+ }
3454
+ if (ctx.index === 1) {
3455
+ shape("\u05E6\u05DC \u05DC\u05D5\u05D7 \u05E6\u05E8\u05DB\u05D9\u05DD", 72, 88, 650, 571, "#E9C5D0", 30, 0.07, 0, 140);
3456
+ shape("\u05DC\u05D5\u05D7 \u05E6\u05E8\u05DB\u05D9\u05DD", 59, 75, 650, 571, WHITE, 30, 0.15, 0, 140);
3457
+ word("\u05DB\u05D5\u05EA\u05E8\u05EA \u05E6\u05E8\u05DB\u05D9 \u05E8\u05DB\u05D1", "\u05DE\u05EA\u05D0\u05D9\u05DE\u05D9\u05DD \u05DC\u05D7\u05D9\u05D9\u05DD", 103, 113, 557, 74, 44, NAVY, 0.46);
3458
+ const needs = [
3459
+ { name: "\u05DE\u05E8\u05D5\u05D5\u05D7", x: 104, y: 230, width: 248, color: "#FFE1E9" },
3460
+ { name: "\u05E0\u05D5\u05D7\u05D5\u05EA", x: 405, y: 230, width: 248, color: "#F7CED9" },
3461
+ { name: "\u05D7\u05D9\u05E1\u05DB\u05D5\u05DF", x: 104, y: 406, width: 248, color: "#F7CED9" },
3462
+ { name: "\u05D9\u05D5\u05DE\u05D9\u05D5\u05DD", x: 405, y: 406, width: 248, color: "#FFE1E9" }
3463
+ ];
3464
+ needs.forEach((need, i) => {
3465
+ const delay = 0.67 + i * 0.38;
3466
+ shape(`\u05DB\u05E8\u05D8\u05D9\u05E1 ${need.name}`, need.x, need.y, need.width, 140, need.color, 22, delay, i % 2 ? 180 : -180);
3467
+ shape(`\u05E1\u05DE\u05DF ${need.name}`, need.x + 20, need.y + 30, 35, 35, i === 1 ? RED : "#D798AB", 18, delay + 0.1);
3468
+ word(`\u05E9\u05DD \u05E6\u05D5\u05E8\u05DA ${need.name}`, need.name, need.x + 65, need.y + 26, need.width - 88, 74, 36, NAVY, delay + 0.19);
3469
+ shape(`\u05E7\u05D5 ${need.name}`, need.x + 30, need.y + 108, need.width - 60, 8, i === 1 ? RED : "#D4A5B2", 4, delay + 0.26);
3470
+ });
3471
+ return true;
3472
+ }
3473
+ shape("\u05E6\u05DC \u05D4\u05E9\u05D5\u05D5\u05D0\u05EA \u05E8\u05DB\u05D1", 73, 91, 649, 561, "#AF0037", 30, 0.07, 0, 135);
3474
+ shape("\u05DC\u05D5\u05D7 \u05D4\u05E9\u05D5\u05D5\u05D0\u05EA \u05E8\u05DB\u05D1", 60, 78, 649, 561, WHITE, 30, 0.15, 0, 135);
3475
+ word("\u05DB\u05D5\u05EA\u05E8\u05EA \u05D4\u05E9\u05D5\u05D5\u05D0\u05EA \u05E8\u05DB\u05D1", "\u05DE\u05E1\u05EA\u05DB\u05DC\u05D9\u05DD \u05E2\u05DC \u05D4\u05DB\u05D5\u05DC", 104, 111, 556, 75, 44, NAVY, 0.49);
3476
+ ["\u05E8\u05DB\u05D9\u05E9\u05D4", "\u05EA\u05D7\u05D6\u05D5\u05E7\u05D4", "\u05DE\u05D9\u05DE\u05D5\u05DF"].forEach((name, i) => {
3477
+ const y = 231 + i * 121;
3478
+ const delay = 0.72 + i * 0.55;
3479
+ shape(`\u05E8\u05E7\u05E2 \u05E9\u05D9\u05E7\u05D5\u05DC ${name}`, 101, y, 563, 92, i === 1 ? "#F9D2DD" : PALE, 18, delay, 0, 97);
3480
+ word(`\u05E9\u05DD \u05E9\u05D9\u05E7\u05D5\u05DC ${name}`, name, 128, y + 10, 162, 67, 35, NAVY, delay + 0.17);
3481
+ shape(`\u05DE\u05E1\u05DC\u05D5\u05DC \u05E9\u05D9\u05E7\u05D5\u05DC ${name}`, 318, y + 36, 299, 20, "#DDB5C0", 10, delay + 0.15);
3482
+ const width = [184, 236, 151][i];
3483
+ const fill = box(ctx, `\u05DE\u05D7\u05D5\u05D5\u05DF \u05E9\u05D9\u05E7\u05D5\u05DC ${name}`, 318, y + 36, width, 20, RED, 10, delay + 0.23);
3484
+ set(fill, [
3485
+ point(0, -width / 2, 0, 0.02, 1, 0, 0),
3486
+ point(delay + 0.23, -width / 2, 0, 0.02, 1, 0, 0),
3487
+ point(delay + 0.73, 0, 0),
3488
+ point(end, 5, 0)
3489
+ ]);
3490
+ });
3491
+ word("\u05D4\u05E2\u05E8\u05EA \u05D4\u05E9\u05D5\u05D5\u05D0\u05EA \u05E8\u05DB\u05D1", "\u05D1\u05D5\u05D7\u05E8\u05D9\u05DD \u05DC\u05E4\u05D9 \u05D4\u05E6\u05E8\u05DB\u05D9\u05DD", 111, 591, 535, 42, 26, RED, 2.74);
3492
+ return true;
3493
+ }
3494
+ function weddingStoryboard(ctx) {
3495
+ if (ctx.theme !== "wedding-rings" || ctx.index > 3) return false;
3496
+ const end = ctx.scene.duration - 0.02;
3497
+ const set = (item, frames) => {
3498
+ item.keyframes = frames;
3499
+ return item;
3500
+ };
3501
+ const arrive = (delay, dx = 0, dy = 0) => [
3502
+ point(0, dx, dy, 0.9, 0.9, 0, 0),
3503
+ point(delay, dx, dy, 0.9, 0.9, 0, 0),
3504
+ point(delay + 0.39, 0, 0),
3505
+ point(Math.max(delay + 0.45, end - 0.42), 0, -6, 1.025, 1.025),
3506
+ point(end, 0, 0)
3507
+ ];
3508
+ const shape = (name, x, y, w, h, color, radius, delay, dx = 0, dy = 0) => set(box(ctx, name, x, y, w, h, color, radius, delay), arrive(delay, dx, dy));
3509
+ const word = (name, value, x, y, w, h, size, color, delay) => set(caption(ctx, name, value, x, y, w, h, size, color, delay), arrive(delay, 0, 36));
3510
+ if (ctx.index === 0) {
3511
+ shape("\u05D4\u05D9\u05DC\u05D4 \u05D4\u05D6\u05DE\u05E0\u05D4", 58, 52, 640, 640, "#B8003C", 320, 0.04);
3512
+ shape("\u05E6\u05DC \u05E0\u05D9\u05D9\u05E8 \u05D4\u05D6\u05DE\u05E0\u05D4", 133, 105, 506, 548, "#A30034", 30, 0.13, 0, 135);
3513
+ shape("\u05E0\u05D9\u05D9\u05E8 \u05D4\u05D6\u05DE\u05E0\u05D4", 117, 88, 506, 548, WHITE, 30, 0.22, 0, 135);
3514
+ shape("\u05D8\u05D1\u05E2\u05EA \u05D4\u05D6\u05DE\u05E0\u05D4 \u05E8\u05D0\u05E9\u05D5\u05E0\u05D4", 234, 133, 145, 145, RED, 73, 0.42, -120);
3515
+ shape("\u05D7\u05DC\u05DC \u05D8\u05D1\u05E2\u05EA \u05D4\u05D6\u05DE\u05E0\u05D4 \u05E8\u05D0\u05E9\u05D5\u05E0\u05D4", 260, 159, 93, 93, WHITE, 47, 0.5, -120);
3516
+ shape("\u05D8\u05D1\u05E2\u05EA \u05D4\u05D6\u05DE\u05E0\u05D4 \u05E9\u05E0\u05D9\u05D9\u05D4", 337, 133, 145, 145, "#F37899", 73, 0.59, 120);
3517
+ shape("\u05D7\u05DC\u05DC \u05D8\u05D1\u05E2\u05EA \u05D4\u05D6\u05DE\u05E0\u05D4 \u05E9\u05E0\u05D9\u05D9\u05D4", 363, 159, 93, 93, WHITE, 47, 0.67, 120);
3518
+ word("\u05DB\u05D5\u05EA\u05E8\u05EA \u05E8\u05E9\u05D9\u05DE\u05EA \u05D7\u05EA\u05D5\u05E0\u05D4", "\u05DE\u05EA\u05D7\u05D9\u05DC\u05D9\u05DD \u05DC\u05EA\u05DB\u05E0\u05DF", 165, 305, 417, 79, 43, NAVY, 0.86);
3519
+ ["\u05EA\u05D0\u05E8\u05D9\u05DA", "\u05DE\u05E7\u05D5\u05DD", "\u05D0\u05E0\u05E9\u05D9\u05DD"].forEach((label, i) => {
3520
+ const y = 416 + i * 62;
3521
+ const delay = 1.11 + i * 0.4;
3522
+ shape(`\u05E1\u05D9\u05DE\u05D5\u05DF \u05E8\u05E9\u05D9\u05DE\u05D4 ${i + 1}`, 192, y + 12, 24, 24, i === 2 ? RED : "#DDA6B6", 12, delay, -80);
3523
+ word(`\u05E4\u05E8\u05D9\u05D8 \u05E8\u05E9\u05D9\u05DE\u05D4 ${i + 1}`, label, 237, y, 265, 49, 30, NAVY, delay + 0.12);
3524
+ shape(`\u05E7\u05D5 \u05E8\u05E9\u05D9\u05DE\u05D4 ${i + 1}`, 510, y + 27, 69, 7, "#DEBAC5", 4, delay + 0.22);
3525
+ });
3526
+ return true;
3527
+ }
3528
+ if (ctx.index === 1) {
3529
+ shape("\u05E6\u05DC \u05E1\u05D3\u05E8 \u05E2\u05D3\u05D9\u05E4\u05D5\u05D9\u05D5\u05EA", 77, 91, 630, 553, "#E3BCC8", 29, 0.08, 0, 133);
3530
+ shape("\u05DC\u05D5\u05D7 \u05E1\u05D3\u05E8 \u05E2\u05D3\u05D9\u05E4\u05D5\u05D9\u05D5\u05EA", 61, 76, 630, 553, WHITE, 29, 0.16, 0, 133);
3531
+ word("\u05DB\u05D5\u05EA\u05E8\u05EA \u05E1\u05D3\u05E8 \u05E2\u05D3\u05D9\u05E4\u05D5\u05D9\u05D5\u05EA", "\u05DE\u05D4 \u05D4\u05DB\u05D9 \u05D7\u05E9\u05D5\u05D1?", 107, 106, 539, 74, 45, NAVY, 0.51);
3532
+ ["\u05DE\u05E7\u05D5\u05DD", "\u05D0\u05E0\u05E9\u05D9\u05DD", "\u05D7\u05D5\u05D5\u05D9\u05D4"].forEach((label, i) => {
3533
+ const y = 206 + i * 128;
3534
+ const delay = 0.74 + i * 0.61;
3535
+ shape(`\u05DB\u05E8\u05D8\u05D9\u05E1 \u05D7\u05EA\u05D5\u05E0\u05D4 ${label}`, 102, y, 547, 99, i === 1 ? "#F8D2DD" : PALE, 20, delay, i % 2 ? 180 : -180);
3536
+ shape(`\u05E2\u05D9\u05D2\u05D5\u05DC ${label}`, 123, y + 20, 60, 60, i === 1 ? RED : "#DFA6B7", 30, delay + 0.11, 0, 65);
3537
+ word(`\u05E9\u05DD \u05E2\u05D3\u05D9\u05E4\u05D5\u05EA ${label}`, label, 209, y + 12, 336, 74, 39, NAVY, delay + 0.25);
3538
+ shape(`\u05E4\u05E1 \u05E2\u05D3\u05D9\u05E4\u05D5\u05EA ${label}`, 573, y + 43, 47, 11, i === 1 ? RED : "#D2A6B2", 6, delay + 0.33);
3539
+ });
3540
+ word("\u05D4\u05E2\u05E8\u05EA \u05E1\u05D3\u05E8 \u05E2\u05D3\u05D9\u05E4\u05D5\u05D9\u05D5\u05EA", "\u05D4\u05D1\u05D7\u05D9\u05E8\u05D4 \u05E9\u05DC\u05DB\u05DD", 117, 583, 516, 46, 26, RED, 2.65);
3541
+ return true;
3542
+ }
3543
+ if (ctx.index === 2) {
3544
+ shape("\u05E6\u05DC \u05DE\u05E1\u05D2\u05E8\u05EA \u05D7\u05EA\u05D5\u05E0\u05D4", 76, 93, 629, 558, "#A80036", 29, 0.07, 0, 137);
3545
+ shape("\u05DC\u05D5\u05D7 \u05DE\u05E1\u05D2\u05E8\u05EA \u05D7\u05EA\u05D5\u05E0\u05D4", 62, 77, 629, 558, WHITE, 29, 0.15, 0, 137);
3546
+ word("\u05DB\u05D5\u05EA\u05E8\u05EA \u05DE\u05E1\u05D2\u05E8\u05EA \u05D7\u05EA\u05D5\u05E0\u05D4", "\u05DE\u05EA\u05DB\u05E0\u05E0\u05D9\u05DD \u05DE\u05E1\u05D2\u05E8\u05EA", 105, 109, 546, 78, 44, NAVY, 0.47);
3547
+ ["\u05DE\u05E7\u05D5\u05DD", "\u05D0\u05D9\u05E8\u05D5\u05D7", "\u05DE\u05E8\u05D5\u05D5\u05D7"].forEach((label, i) => {
3548
+ const y = 230 + i * 121;
3549
+ const delay = 0.7 + i * 0.58;
3550
+ shape(`\u05E9\u05D5\u05E8\u05EA \u05EA\u05E7\u05E6\u05D9\u05D1 ${label}`, 103, y, 545, 88, i === 1 ? "#F9D4DE" : PALE, 18, delay, 0, 95);
3551
+ word(`\u05E9\u05DD \u05EA\u05E7\u05E6\u05D9\u05D1 ${label}`, label, 119, y + 11, 150, 66, 33, NAVY, delay + 0.15);
3552
+ shape(`\u05DE\u05E1\u05DC\u05D5\u05DC \u05EA\u05E7\u05E6\u05D9\u05D1 ${label}`, 297, y + 34, 305, 20, "#DAB2BE", 10, delay + 0.17);
3553
+ const width = [218, 174, 247][i];
3554
+ const fill = box(ctx, `\u05DE\u05D7\u05D5\u05D5\u05DF \u05EA\u05E7\u05E6\u05D9\u05D1 ${label}`, 297, y + 34, width, 20, RED, 10, delay + 0.24);
3555
+ set(fill, [
3556
+ point(0, -width / 2, 0, 0.02, 1, 0, 0),
3557
+ point(delay + 0.24, -width / 2, 0, 0.02, 1, 0, 0),
3558
+ point(delay + 0.75, 0, 0),
3559
+ point(end, 5, 0)
3560
+ ]);
3561
+ });
3562
+ word("\u05D4\u05E2\u05E8\u05EA \u05DE\u05E1\u05D2\u05E8\u05EA \u05D7\u05EA\u05D5\u05E0\u05D4", "\u05DC\u05DC\u05D0 \u05E1\u05DB\u05D5\u05DE\u05D9\u05DD \u05DE\u05D5\u05DB\u05EA\u05D1\u05D9\u05DD", 120, 591, 520, 44, 25, RED, 2.88);
3563
+ return true;
3564
+ }
3565
+ shape("\u05E8\u05E7\u05E2 \u05D9\u05D5\u05DD \u05D7\u05EA\u05D5\u05E0\u05D4", 64, 85, 630, 568, "#FFE4EC", 29, 0.1, 0, 130);
3566
+ word("\u05DB\u05D5\u05EA\u05E8\u05EA \u05D9\u05D5\u05DD \u05D2\u05DE\u05D9\u05E9", "\u05D9\u05E9 \u05DE\u05E7\u05D5\u05DD \u05D2\u05DD \u05DC\u05E9\u05D9\u05E0\u05D5\u05D9", 112, 112, 538, 73, 43, NAVY, 0.53);
3567
+ shape("\u05E7\u05D5 \u05D6\u05DE\u05DF \u05D7\u05EA\u05D5\u05E0\u05D4", 143, 365, 473, 15, NAVY, 8, 0.74, -300);
3568
+ ["\u05DE\u05EA\u05DB\u05E0\u05E0\u05D9\u05DD", "\u05E0\u05D4\u05E0\u05D9\u05DD", "\u05DE\u05E4\u05EA\u05D9\u05E2\u05D9\u05DD"].forEach((label, i) => {
3569
+ const x = 107 + i * 210;
3570
+ const delay = 0.96 + i * 0.59;
3571
+ shape(`\u05EA\u05D7\u05E0\u05D4 ${label}`, x, 316, 111, 111, i === 2 ? RED : WHITE, 56, delay, 0, 135);
3572
+ shape(`\u05DE\u05E8\u05DB\u05D6 \u05EA\u05D7\u05E0\u05D4 ${label}`, x + 29, 345, 53, 53, i === 2 ? WHITE : RED, 27, delay + 0.14, 0, 105);
3573
+ word(`\u05E9\u05DD \u05EA\u05D7\u05E0\u05D4 ${label}`, label, x - 12, 463, 139, 67, 30, NAVY, delay + 0.24);
3574
+ });
3575
+ for (let i = 0; i < 7; i++) {
3576
+ const x = 120 + i * 86;
3577
+ shape(
3578
+ `\u05E0\u05D9\u05E6\u05D5\u05E5 \u05D7\u05EA\u05D5\u05E0\u05D4 ${i + 1}`,
3579
+ x,
3580
+ 220 + i % 3 * 17,
3581
+ 14,
3582
+ 14,
3583
+ i % 2 ? RED : "#E387A2",
3584
+ 7,
3585
+ 1.71 + i * 0.12,
3586
+ 0,
3587
+ -85
3588
+ );
3589
+ }
3590
+ return true;
3591
+ }
3592
+ function shareStoryboard(ctx) {
3593
+ if (ctx.theme !== "share-mosaic" || ctx.index > 2) return false;
3594
+ const end = ctx.scene.duration - 0.02;
3595
+ const set = (item, frames) => {
3596
+ item.keyframes = frames;
3597
+ return item;
3598
+ };
3599
+ const arrive = (delay, dx = 0, dy = 0) => [
3600
+ point(0, dx, dy, 0.88, 0.88, 0, 0),
3601
+ point(delay, dx, dy, 0.88, 0.88, 0, 0),
3602
+ point(delay + 0.36, 0, 0),
3603
+ point(Math.max(delay + 0.4, end - 0.4), 0, -8, 1.025, 1.025),
3604
+ point(end, 0, 0)
3605
+ ];
3606
+ const shape = (name, x, y, w, h, color, radius, delay, dx = 0, dy = 0) => set(box(ctx, name, x, y, w, h, color, radius, delay), arrive(delay, dx, dy));
3607
+ const word = (name, value, x, y, w, h, size, color, delay) => set(caption(ctx, name, value, x, y, w, h, size, color, delay), arrive(delay, 0, 42));
3608
+ if (ctx.index === 0) {
3609
+ shape("\u05E6\u05DC \u05D1\u05E0\u05D9\u05D9\u05DF \u05D7\u05D1\u05E8\u05D4", 113, 165, 536, 470, "#A80036", 28, 0.05, 0, 120);
3610
+ shape("\u05D1\u05E0\u05D9\u05D9\u05DF \u05D7\u05D1\u05E8\u05D4", 94, 144, 536, 470, WHITE, 28, 0.14, 0, 120);
3611
+ shape("\u05D2\u05D2 \u05D7\u05D1\u05E8\u05D4", 94, 144, 536, 69, RED, 27, 0.25, 0, -80);
3612
+ for (let row = 0; row < 3; row++) for (let col = 0; col < 4; col++) {
3613
+ const i = row * 4 + col;
3614
+ shape(
3615
+ `\u05D7\u05DC\u05E7 \u05D7\u05D1\u05E8\u05D4 ${i + 1}`,
3616
+ 122 + col * 127,
3617
+ 243 + row * 111,
3618
+ 101,
3619
+ 86,
3620
+ i === 6 ? RED : "#F7D4DE",
3621
+ 16,
3622
+ 0.43 + i * 0.135,
3623
+ col % 2 ? 110 : -110,
3624
+ 64
3625
+ );
3626
+ }
3627
+ word("\u05D7\u05DC\u05E7 \u05D1\u05D1\u05E2\u05DC\u05D5\u05EA", "\u05D7\u05DC\u05E7", 382, 379, 102, 56, 31, WHITE, 1.44);
3628
+ shape("\u05E7\u05D5 \u05D7\u05DC\u05E7 \u05D1\u05D1\u05E2\u05DC\u05D5\u05EA", 453, 540, 123, 11, RED, 6, 2.1, -110);
3629
+ return true;
3630
+ }
3631
+ if (ctx.index === 1) {
3632
+ shape("\u05DC\u05D5\u05D7 \u05D7\u05D1\u05E8\u05D4 \u05DE\u05E9\u05D5\u05EA\u05E4\u05EA", 83, 93, 612, 542, WHITE, 30, 0.08, 0, 130);
3633
+ word("\u05DB\u05D5\u05EA\u05E8\u05EA \u05DC\u05D5\u05D7 \u05D1\u05E2\u05DC\u05D5\u05EA", "\u05D7\u05D1\u05E8\u05D4", 188, 119, 404, 68, 45, NAVY, 0.4);
3634
+ const colors = [RED, "#F7A7BA", "#D52C57", "#E8BDC9"];
3635
+ for (let i = 0; i < 4; i++) {
3636
+ const x = 130 + i * 137;
3637
+ const delay = 0.74 + i * 0.35;
3638
+ shape(`\u05D8\u05D5\u05E8 \u05D7\u05DC\u05E7\u05D9\u05DD ${i + 1}`, x, 244, 108, 234, colors[i], 18, delay, 0, 190);
3639
+ shape(
3640
+ `\u05E1\u05D9\u05DE\u05D5\u05DF \u05D1\u05E2\u05DC\u05D5\u05EA ${i + 1}`,
3641
+ x + 35,
3642
+ 505,
3643
+ 38,
3644
+ 38,
3645
+ i === 0 ? RED : "#DFA6B7",
3646
+ 19,
3647
+ delay + 0.18,
3648
+ 0,
3649
+ 70
3650
+ );
3651
+ }
3652
+ shape("\u05E7\u05D5 \u05D4\u05D3\u05D2\u05E9\u05EA \u05D7\u05DC\u05E7", 127, 590, 520, 9, "#EBC6D0", 5, 2, -320);
3653
+ shape("\u05DE\u05E7\u05D8\u05E2 \u05D4\u05D3\u05D2\u05E9\u05EA \u05D7\u05DC\u05E7", 127, 590, 108, 9, RED, 5, 2.25, -108);
3654
+ return true;
3655
+ }
3656
+ if (ctx.index === 2) {
3657
+ shape("\u05DB\u05E8\u05D8\u05D9\u05E1 \u05D1\u05D3\u05D9\u05E7\u05EA \u05D4\u05D7\u05DC\u05D8\u05D4", 70, 83, 637, 560, WHITE, 30, 0.08, 0, 130);
3658
+ word("\u05DB\u05D5\u05EA\u05E8\u05EA \u05D1\u05D3\u05D9\u05E7\u05EA \u05D4\u05D7\u05DC\u05D8\u05D4", "\u05DC\u05E4\u05E0\u05D9 \u05E9\u05DE\u05D7\u05DC\u05D9\u05D8\u05D9\u05DD", 128, 110, 520, 79, 43, NAVY, 0.43);
3659
+ const labels = ["\u05DE\u05D8\u05E8\u05D4", "\u05DE\u05D9\u05D3\u05E2", "\u05E1\u05D9\u05DB\u05D5\u05DF"];
3660
+ labels.forEach((label, i) => {
3661
+ const y = 216 + i * 128, delay = 0.67 + i * 0.6;
3662
+ shape(
3663
+ `\u05E8\u05E6\u05D5\u05E2\u05EA \u05D1\u05D3\u05D9\u05E7\u05D4 ${label}`,
3664
+ 113,
3665
+ y,
3666
+ 555,
3667
+ 95,
3668
+ i === 2 ? "#F9D5DF" : PALE,
3669
+ 20,
3670
+ delay,
3671
+ i % 2 ? 180 : -180
3672
+ );
3673
+ shape(
3674
+ `\u05E0\u05E7\u05D5\u05D3\u05EA \u05D1\u05D3\u05D9\u05E7\u05D4 ${label}`,
3675
+ 135,
3676
+ y + 21,
3677
+ 54,
3678
+ 54,
3679
+ i === 2 ? RED : "#DFA0B2",
3680
+ 27,
3681
+ delay + 0.13,
3682
+ 0,
3683
+ 85
3684
+ );
3685
+ word(`\u05E9\u05DD \u05D1\u05D3\u05D9\u05E7\u05D4 ${label}`, label, 214, y + 12, 330, 71, 37, NAVY, delay + 0.26);
3686
+ shape(
3687
+ `\u05E4\u05E1 \u05D1\u05D3\u05D9\u05E7\u05D4 ${label}`,
3688
+ 578,
3689
+ y + 43,
3690
+ 61,
3691
+ 10,
3692
+ i === 2 ? RED : "#D8A3B1",
3693
+ 5,
3694
+ delay + 0.34,
3695
+ -80
3696
+ );
3697
+ });
3698
+ return true;
3699
+ }
3700
+ return false;
3701
+ }
3702
+ function fraudStoryboard(ctx) {
3703
+ if (ctx.theme !== "fraud-alert" || ctx.index > 3) return false;
3704
+ const end = ctx.scene.duration - 0.02;
3705
+ const set = (item, frames) => {
3706
+ item.keyframes = frames;
3707
+ return item;
3708
+ };
3709
+ const arrive = (delay, dx = 0, dy = 0) => [
3710
+ point(0, dx, dy, 0.88, 0.88, 0, 0),
3711
+ point(delay, dx, dy, 0.88, 0.88, 0, 0),
3712
+ point(delay + 0.36, 0, 0),
3713
+ point(Math.max(delay + 0.4, end - 0.43), 0, -7, 1.025, 1.025),
3714
+ point(end, 0, 0)
3715
+ ];
3716
+ const shape = (name, x, y, w, h, color, radius, delay, dx = 0, dy = 0) => set(box(ctx, name, x, y, w, h, color, radius, delay), arrive(delay, dx, dy));
3717
+ const word = (name, value, x, y, w, h, size, color, delay) => set(caption(ctx, name, value, x, y, w, h, size, color, delay), arrive(delay, 0, 42));
3718
+ if (ctx.index === 0) {
3719
+ shape("\u05E6\u05DC \u05D8\u05DC\u05E4\u05D5\u05DF \u05D0\u05D6\u05D4\u05E8\u05D4", 174, 85, 434, 615, "#A50034", 45, 0.05, 0, 140);
3720
+ shape("\u05D2\u05D5\u05E3 \u05D8\u05DC\u05E4\u05D5\u05DF \u05D0\u05D6\u05D4\u05E8\u05D4", 158, 68, 434, 615, NAVY, 45, 0.13, 0, 140);
3721
+ shape("\u05DE\u05E1\u05DA \u05D8\u05DC\u05E4\u05D5\u05DF \u05D0\u05D6\u05D4\u05E8\u05D4", 180, 96, 390, 558, WHITE, 29, 0.23, 0, 140);
3722
+ shape("\u05E4\u05E1 \u05DE\u05E6\u05D1 \u05D1\u05D8\u05DC\u05E4\u05D5\u05DF", 304, 107, 144, 13, NAVY, 7, 0.31, 0, 100);
3723
+ word("\u05DB\u05D5\u05EA\u05E8\u05EA \u05D4\u05D5\u05D3\u05E2\u05D5\u05EA", "\u05D4\u05D5\u05D3\u05E2\u05D5\u05EA", 229, 155, 300, 59, 39, NAVY, 0.42);
3724
+ ["\u05D4\u05D5\u05D3\u05E2\u05D4 \u05D7\u05D3\u05E9\u05D4", "\u05DC\u05E4\u05E2\u05D5\u05DC \u05DE\u05D9\u05D3"].forEach((label, i) => {
3725
+ const y = 257 + i * 134, delay = 0.72 + i * 0.6;
3726
+ shape(
3727
+ `\u05D4\u05D5\u05D3\u05E2\u05D4 \u05D7\u05E9\u05D5\u05D3\u05D4 ${i + 1}`,
3728
+ 207,
3729
+ y,
3730
+ 335,
3731
+ 108,
3732
+ i ? "#FFD9E4" : PALE,
3733
+ 20,
3734
+ delay,
3735
+ i ? 240 : -240
3736
+ );
3737
+ shape(
3738
+ `\u05E0\u05E7\u05D5\u05D3\u05EA \u05D4\u05D5\u05D3\u05E2\u05D4 ${i + 1}`,
3739
+ 224,
3740
+ y + 29,
3741
+ 49,
3742
+ 49,
3743
+ i ? RED : "#DF9EB1",
3744
+ 25,
3745
+ delay + 0.12,
3746
+ 0,
3747
+ 65
3748
+ );
3749
+ word(`\u05EA\u05D5\u05DB\u05DF \u05D4\u05D5\u05D3\u05E2\u05D4 ${i + 1}`, label, 285, y + 20, 226, 67, 30, NAVY, delay + 0.22);
3750
+ });
3751
+ shape("\u05E7\u05D5 \u05D7\u05E9\u05D3", 277, 563, 216, 10, RED, 5, 2.15, -180);
3752
+ return true;
3753
+ }
3754
+ if (ctx.index === 1) {
3755
+ shape("\u05D4\u05D9\u05DC\u05EA \u05E2\u05E6\u05D9\u05E8\u05D4 \u05D7\u05D9\u05E6\u05D5\u05E0\u05D9\u05EA", 84, 72, 598, 598, "#FCE0E9", 299, 0.08, 0, 130);
3756
+ shape("\u05D4\u05D9\u05DC\u05EA \u05E2\u05E6\u05D9\u05E8\u05D4 \u05E4\u05E0\u05D9\u05DE\u05D9\u05EA", 168, 156, 430, 430, WHITE, 215, 0.23, 0, 120);
3757
+ shape("\u05EA\u05DE\u05E8\u05D5\u05E8 \u05E2\u05E6\u05D9\u05E8\u05D4", 249, 238, 270, 270, RED, 56, 0.44, 0, 110);
3758
+ word("\u05D8\u05E7\u05E1\u05D8 \u05E2\u05E6\u05D9\u05E8\u05D4", "\u05E2\u05E6\u05D5\u05E8", 274, 302, 222, 115, 77, WHITE, 0.69);
3759
+ shape("\u05E7\u05D9\u05E9\u05D5\u05E8 \u05E9\u05DC\u05D0 \u05E0\u05E4\u05EA\u05D7", 167, 580, 438, 48, "#F8C5D4", 24, 1.15, 0, 95);
3760
+ shape("\u05E7\u05D5 \u05DE\u05D7\u05D9\u05E7\u05EA \u05E7\u05D9\u05E9\u05D5\u05E8", 154, 595, 465, 16, RED, 8, 1.54, -390);
3761
+ return true;
3762
+ }
3763
+ if (ctx.index === 2) {
3764
+ shape("\u05DB\u05E8\u05D8\u05D9\u05E1 \u05E2\u05E8\u05D5\u05E5 \u05E8\u05E9\u05DE\u05D9", 80, 83, 618, 555, WHITE, 29, 0.08, 0, 130);
3765
+ word("\u05DB\u05D5\u05EA\u05E8\u05EA \u05D1\u05D3\u05D9\u05E7\u05D4 \u05E2\u05E6\u05DE\u05D0\u05D9\u05EA", "\u05E4\u05D5\u05EA\u05D7\u05D9\u05DD \u05D1\u05E2\u05E6\u05DE\u05E0\u05D5", 127, 111, 526, 77, 44, NAVY, 0.43);
3766
+ ["\u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D4", "\u05D0\u05EA\u05E8 \u05E8\u05E9\u05DE\u05D9", "\u05D9\u05E6\u05D9\u05E8\u05EA \u05E7\u05E9\u05E8"].forEach((label, i) => {
3767
+ const y = 218 + i * 125, delay = 0.7 + i * 0.59;
3768
+ shape(
3769
+ `\u05E2\u05E8\u05D5\u05E5 \u05D1\u05D3\u05D9\u05E7\u05D4 ${label}`,
3770
+ 110,
3771
+ y,
3772
+ 555,
3773
+ 93,
3774
+ i === 0 ? "#F8D0DC" : PALE,
3775
+ 19,
3776
+ delay,
3777
+ i % 2 ? 190 : -190
3778
+ );
3779
+ shape(
3780
+ `\u05E1\u05DE\u05DC \u05E2\u05E8\u05D5\u05E5 ${label}`,
3781
+ 132,
3782
+ y + 19,
3783
+ 56,
3784
+ 56,
3785
+ i === 0 ? RED : "#DB9CAF",
3786
+ 17,
3787
+ delay + 0.14,
3788
+ 0,
3789
+ 85
3790
+ );
3791
+ word(`\u05E9\u05DD \u05E2\u05E8\u05D5\u05E5 ${label}`, label, 206, y + 10, 350, 71, 35, NAVY, delay + 0.26);
3792
+ shape(
3793
+ `\u05E4\u05E1 \u05E2\u05E8\u05D5\u05E5 ${label}`,
3794
+ 578,
3795
+ y + 42,
3796
+ 57,
3797
+ 10,
3798
+ i === 0 ? RED : "#D6A2B0",
3799
+ 5,
3800
+ delay + 0.35,
3801
+ -70
3802
+ );
3803
+ });
3804
+ return true;
3805
+ }
3806
+ shape("\u05DE\u05D2\u05DF \u05DE\u05D9\u05D3\u05E2 \u05D0\u05D9\u05E9\u05D9", 130, 112, 515, 530, WHITE, 36, 0.12, 0, 135);
3807
+ shape("\u05DC\u05D5\u05D7 \u05E0\u05E2\u05D9\u05DC\u05D4", 220, 267, 340, 283, "#FFD7E2", 34, 0.46, 0, 120);
3808
+ shape("\u05E7\u05E9\u05EA \u05DE\u05E0\u05E2\u05D5\u05DC \u05D7\u05D9\u05E6\u05D5\u05E0\u05D9\u05EA", 305, 178, 168, 155, RED, 77, 0.65, 0, 100);
3809
+ shape("\u05E7\u05E9\u05EA \u05DE\u05E0\u05E2\u05D5\u05DC \u05E4\u05E0\u05D9\u05DE\u05D9\u05EA", 332, 205, 114, 113, WHITE, 58, 0.73, 0, 100);
3810
+ shape("\u05D2\u05D5\u05E3 \u05DE\u05E0\u05E2\u05D5\u05DC", 247, 304, 287, 230, RED, 24, 0.84, 0, 110);
3811
+ shape("\u05D7\u05D5\u05E8 \u05DE\u05E0\u05E2\u05D5\u05DC", 371, 385, 40, 72, WHITE, 20, 1.16, 0, 70);
3812
+ word("\u05E1\u05D9\u05E1\u05DE\u05D4 \u05D5\u05E7\u05D5\u05D3", "\u05E1\u05D9\u05E1\u05DE\u05D4 \u2022 \u05E7\u05D5\u05D3", 231, 566, 345, 60, 30, NAVY, 1.47);
3813
+ return true;
3814
+ }
3815
+ function storyboard(ctx) {
3816
+ if (holidayStoryboard(ctx)) return true;
3817
+ if (oneClickStoryboard(ctx)) return true;
3818
+ if (careerStoryboard(ctx)) return true;
3819
+ if (homeRefreshStoryboard(ctx)) return true;
3820
+ if (summerStoryboard(ctx)) return true;
3821
+ if (carUpgradeStoryboard(ctx)) return true;
3822
+ if (weddingStoryboard(ctx)) return true;
3823
+ if (shareStoryboard(ctx)) return true;
3824
+ if (fraudStoryboard(ctx)) return true;
3825
+ const spec = storyFrames[ctx.theme][ctx.index - 1];
3826
+ if (!spec) return false;
3827
+ const { kind, labels } = spec;
3828
+ const a = ctx.accent, ink = ctx.ink, surface = ctx.surface;
3829
+ const d = ctx.scene.duration, end = d - 0.02;
3830
+ if (kind === "choices") {
3831
+ labels.slice(0, 2).forEach((label, i) => {
3832
+ const x = 38 + i * 370;
3833
+ box(ctx, `\u05D0\u05E4\u05E9\u05E8\u05D5\u05EA ${i + 1}`, x, 195, 320, 360, i ? ink : a, 32, 0.2 + i * 0.42, i ? 420 : -420, 0);
3834
+ box(ctx, `\u05E1\u05DE\u05DC \u05D0\u05E4\u05E9\u05E8\u05D5\u05EA ${i + 1}`, x + 106, 260, 108, 108, i ? a : surface, 54, 0.55 + i * 0.42, i ? 240 : -240);
3835
+ caption(ctx, `\u05EA\u05D5\u05D5\u05D9\u05EA \u05D0\u05E4\u05E9\u05E8\u05D5\u05EA ${i + 1}`, label, x + 20, 407, 280, 100, 50, i ? surface : ctx.ink === WHITE ? RED : WHITE, 0.72 + i * 0.42);
3836
+ });
3837
+ box(ctx, "\u05E6\u05D9\u05E8 \u05D4\u05E9\u05D5\u05D5\u05D0\u05D4", 371, 215, 8, 320, surface, 4, 0.88, 0, 0, 0.65);
3838
+ } else if (kind === "bars") {
3839
+ box(ctx, "\u05D1\u05E1\u05D9\u05E1 \u05D4\u05E9\u05D5\u05D5\u05D0\u05D4", 50, 605, 660, 18, ink, 9, 0.1);
3840
+ labels.slice(0, 3).forEach((label, i) => {
3841
+ const height = 310;
3842
+ const item = box(ctx, `\u05E2\u05DE\u05D5\u05D3\u05EA ${label}`, 80 + i * 215, 605 - height, 145, height, i === 1 ? ink : a, 18, 0.3 + i * 0.24, 0, 0);
3843
+ item.keyframes = [
3844
+ point(0, 0, height, 1, 0.04, 0, 0),
3845
+ point(0.25 + i * 0.22, 0, height, 1, 0.04, 0, 0),
3846
+ point(0.88 + i * 0.22, 0, 0),
3847
+ point(end, 0, -18)
3848
+ ];
3849
+ caption(ctx, `\u05E9\u05DD \u05DE\u05D3\u05D3 ${i + 1}`, label, 66 + i * 215, 642, 175, 70, 39, ink, 0.82 + i * 0.2);
3850
+ });
3851
+ } else if (kind === "steps") {
3852
+ box(ctx, "\u05E7\u05D5 \u05DE\u05E1\u05DC\u05D5\u05DC", 72, 371, 630, 16, ink, 8, 0.1, -420, 0);
3853
+ labels.slice(0, 3).forEach((label, i) => {
3854
+ const x = 65 + i * 235;
3855
+ box(ctx, `\u05EA\u05D7\u05E0\u05D4 ${i + 1}`, x, 305, 150, 150, i === 2 ? ink : a, 75, 0.22 + i * 0.37, -320, 0);
3856
+ caption(ctx, `\u05DE\u05E1\u05E4\u05E8 \u05EA\u05D7\u05E0\u05D4 ${i + 1}`, `0${i + 1}`, x + 25, 335, 100, 85, 63, i === 2 ? surface : ctx.ink === WHITE ? RED : WHITE, 0.44 + i * 0.37);
3857
+ caption(ctx, `\u05E9\u05DD \u05EA\u05D7\u05E0\u05D4 ${i + 1}`, label, x - 18, 485, 190, 85, 40, ink, 0.66 + i * 0.37);
3858
+ });
3859
+ } else if (kind === "phone") {
3860
+ box(ctx, "\u05D8\u05DC\u05E4\u05D5\u05DF \u05EA\u05D4\u05DC\u05D9\u05DA", 192, 75, 390, 630, NAVY, 46, 0.1);
3861
+ box(ctx, "\u05DE\u05E1\u05DA \u05EA\u05D4\u05DC\u05D9\u05DA", 214, 102, 346, 575, surface, 30, 0.2);
3862
+ labels.slice(0, 3).forEach((label, i) => {
3863
+ box(ctx, `\u05E9\u05D5\u05E8\u05EA \u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D4 ${i + 1}`, 244, 200 + i * 135, 286, 98, i === 2 ? a : ctx.ink === WHITE ? "#FF7A98" : "#F7BAC7", 22, 0.36 + i * 0.3, i % 2 ? 250 : -250);
3864
+ caption(ctx, `\u05E4\u05E2\u05D5\u05DC\u05EA \u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D4 ${i + 1}`, label, 258, 217 + i * 135, 257, 70, 38, NAVY, 0.56 + i * 0.3);
3865
+ });
3866
+ } else if (kind === "check" || kind === "stack" || kind === "warning") {
3867
+ labels.slice(0, 3).forEach((label, i) => {
3868
+ const y = 128 + i * 185;
3869
+ box(ctx, `\u05DB\u05E8\u05D8\u05D9\u05E1 ${i + 1}`, 62, y, 640, 145, i === 1 ? ink : surface, 22, 0.16 + i * 0.31, i % 2 ? 390 : -390);
3870
+ if (kind !== "stack") {
3871
+ box(ctx, `\u05E1\u05D9\u05DE\u05D5\u05DF ${i + 1}`, 90, y + 36, 72, 72, kind === "warning" ? RED : a, 36, 0.36 + i * 0.31, -180);
3872
+ caption(ctx, `\u05E1\u05DE\u05DC ${i + 1}`, kind === "warning" ? "!" : "\u2713", 102, y + 43, 48, 57, 43, kind === "warning" ? WHITE : ctx.ink === WHITE ? RED : WHITE, 0.55 + i * 0.31);
3873
+ }
3874
+ caption(
3875
+ ctx,
3876
+ `\u05E9\u05D5\u05E8\u05EA \u05EA\u05D5\u05DB\u05DF ${i + 1}`,
3877
+ label,
3878
+ kind === "stack" ? 115 : 195,
3879
+ y + 27,
3880
+ kind === "stack" ? 530 : 465,
3881
+ 92,
3882
+ 48,
3883
+ i === 1 ? surface : ink,
3884
+ 0.52 + i * 0.31
3885
+ );
3886
+ });
3887
+ } else if (kind === "meter") {
3888
+ box(ctx, "\u05DE\u05D3 \u05D8\u05D1\u05E2\u05EA \u05D7\u05D9\u05E6\u05D5\u05E0\u05D9", 95, 87, 570, 570, a, 285, 0.14);
3889
+ box(ctx, "\u05DE\u05D3 \u05D8\u05D1\u05E2\u05EA \u05E4\u05E0\u05D9\u05DE\u05D9", 165, 157, 430, 430, surface, 215, 0.35);
3890
+ box(ctx, "\u05DC\u05D9\u05D1\u05EA \u05D4\u05DE\u05D3", 243, 235, 274, 274, a, 137, 0.58);
3891
+ caption(
3892
+ ctx,
3893
+ "\u05DE\u05E1\u05E8 \u05D1\u05DE\u05E8\u05DB\u05D6 \u05D4\u05DE\u05D3",
3894
+ labels[0],
3895
+ 269,
3896
+ 303,
3897
+ 222,
3898
+ 140,
3899
+ 50,
3900
+ ctx.ink === WHITE ? RED : WHITE,
3901
+ 0.72
3902
+ );
3903
+ for (let i = 0; i < 4; i++) box(ctx, `\u05E4\u05E2\u05D9\u05DE\u05EA \u05DE\u05D3 ${i + 1}`, 126 + i * 143, 672, 110, 13, ink, 7, 0.78 + i * 0.19);
3904
+ }
3905
+ return true;
3906
+ }
3907
+ function visualConfigToProject(config) {
3908
+ if (!config.visualTheme) throw new Error("\u05D7\u05E1\u05E8 \u05E2\u05D5\u05DC\u05DD \u05D7\u05D6\u05D5\u05EA\u05D9");
3909
+ const scenes = config.scenes.map((spec, index) => {
3910
+ const scene = createScene(`${index + 1}. ${spec.headline.slice(0, 54)}`, spec.duration);
3911
+ const last = index === config.scenes.length - 1;
3912
+ const light = index % 3 === 1;
3913
+ scene.background = last ? `linear-gradient(135deg,${DEEP_RED},${RED})` : light ? `linear-gradient(135deg,${WHITE},${PALE})` : `linear-gradient(130deg,${RED},${DEEP_RED})`;
3914
+ scene.transition = index ? "fade" : "cut";
3915
+ const visualOnLeft = index % 2 === 0;
3916
+ const ctx = {
3917
+ scene,
3918
+ theme: config.visualTheme,
3919
+ index,
3920
+ count: config.scenes.length,
3921
+ ox: visualOnLeft ? 105 : 1020,
3922
+ oy: 160,
3923
+ ink: light ? NAVY : WHITE,
3924
+ accent: light ? RED : WHITE,
3925
+ surface: light ? PALE : "#F02450"
3926
+ };
3927
+ for (let i = 0; i < 4; i++) layer(
3928
+ ctx,
3929
+ "shape",
3930
+ `\u05E4\u05E1 \u05E8\u05E7\u05E2 ${i + 1}`,
3931
+ 0,
3932
+ 100 + i * 250,
3933
+ 1920,
3934
+ 2,
3935
+ light ? "#E9CDD4" : "#FFFFFF",
3936
+ { opacity: 0.12, keys: [point(0, -120, 0, 1, 1, 0, 0), point(0.6, 0, 0, 1, 1, 0, 1), point(spec.duration - 0.02, 90, 0, 1, 1, 0, 1)] }
3937
+ );
3938
+ if (!last) {
3939
+ const firstMotifLayer = scene.layers.length;
3940
+ if (!storyboard(ctx)) {
3941
+ motif(ctx);
3942
+ animateMotif(ctx, scene.layers.slice(firstMotifLayer));
3943
+ }
3944
+ } else {
3945
+ ctx.ox = 0;
3946
+ ctx.oy = 0;
3947
+ const motifStart = scene.layers.length;
3948
+ motif(ctx);
3949
+ const closingMotif = scene.layers.slice(motifStart);
3950
+ animateMotif(ctx, closingMotif);
3951
+ for (const item of closingMotif) {
3952
+ item.x = 850 + item.x * 0.25;
3953
+ item.y = 28 + item.y * 0.25;
3954
+ item.width = Math.max(1, item.width * 0.25);
3955
+ item.height = Math.max(1, item.height * 0.25);
3956
+ item.fontSize = Math.max(12, item.fontSize * 0.25);
3957
+ item.borderRadius *= 0.25;
3958
+ if (item.keyframes) for (const key of item.keyframes) {
3959
+ key.x *= 0.25;
3960
+ key.y *= 0.25;
3961
+ }
3962
+ }
3963
+ box(ctx, "\u05E4\u05E1 \u05D7\u05EA\u05D9\u05DE\u05D4", 610, 942, 700, 12, WHITE, 6, 0.7, 0, 0, 0.8);
3964
+ }
3965
+ const textX = last ? 230 : visualOnLeft ? 1010 : 135;
3966
+ const textY = last ? 305 : 320;
3967
+ const textW = last ? 1460 : 770;
3968
+ const headlineSize = spec.headline.length > 30 ? 72 : spec.headline.length > 22 ? 80 : 94;
3969
+ layer(ctx, "text", "\u05DB\u05D5\u05EA\u05E8\u05EA", textX, textY, textW, last ? 280 : 310, last ? WHITE : ctx.ink, {
3970
+ text: spec.headline,
3971
+ size: headlineSize,
3972
+ weight: 800,
3973
+ align: last ? "center" : "right",
3974
+ keys: flight(spec.duration, last ? 0.28 : 0.42, 0, 130, 0, -18)
3975
+ });
3976
+ if (spec.eyebrow) layer(ctx, "text", "\u05DB\u05D5\u05EA\u05E8\u05EA \u05DE\u05E9\u05E0\u05D4", textX, last ? 208 : 233, textW, 78, last ? WHITE : ctx.ink, {
3977
+ text: spec.eyebrow,
3978
+ size: 34,
3979
+ weight: 700,
3980
+ align: last ? "center" : "right",
3981
+ keys: flight(spec.duration, 0.18, 0, 60, 0, -8)
3982
+ });
3983
+ if (spec.supporting) layer(ctx, "text", "\u05D8\u05E7\u05E1\u05D8 \u05EA\u05D5\u05DE\u05DA", textX, last ? 603 : 690, textW, 170, last ? WHITE : ctx.ink, {
3984
+ text: spec.supporting,
3985
+ size: 38,
3986
+ weight: 500,
3987
+ align: last ? "center" : "right",
3988
+ keys: flight(spec.duration, 0.92, 0, 75, 0, -10)
3989
+ });
3990
+ if (spec.emphasis) layer(ctx, "text", "\u05D4\u05D3\u05D2\u05E9\u05D4", textX, last ? 810 : 865, textW, 98, last ? WHITE : light ? RED : WHITE, {
3991
+ text: spec.emphasis,
3992
+ size: 55,
3993
+ weight: 900,
3994
+ align: last ? "center" : "right",
3995
+ keys: pulse(spec.duration, 1.1)
3996
+ });
3997
+ layer(ctx, "text", "\u05DE\u05E1\u05E4\u05E8 \u05E1\u05E6\u05E0\u05D4", 118, 45, 130, 50, last ? WHITE : ctx.ink, {
3998
+ text: `${String(index + 1).padStart(2, "0")} \u05DE\u05EA\u05D5\u05DA ${String(config.scenes.length).padStart(2, "0")}`,
3999
+ size: 23,
4000
+ weight: 700,
4001
+ align: "left",
4002
+ opacity: 0.75,
4003
+ keys: flight(spec.duration, 0, 0, -24, 0, 0)
4004
+ });
4005
+ layer(ctx, "shape", "\u05E6\u05D9\u05E8 \u05D4\u05EA\u05E7\u05D3\u05DE\u05D5\u05EA", 120, 1012, 1680, 7, last ? WHITE : ctx.ink, {
4006
+ radius: 4,
4007
+ opacity: 0.25,
4008
+ keys: [point(0), point(spec.duration - 0.02)]
4009
+ });
4010
+ layer(ctx, "shape", "\u05D4\u05EA\u05E7\u05D3\u05DE\u05D5\u05EA \u05D4\u05E1\u05E6\u05E0\u05D4", 120, 1012, 1680, 7, last ? WHITE : light ? RED : WHITE, {
4011
+ radius: 4,
4012
+ opacity: 0.8,
4013
+ keys: [point(0, 0, 0, 0, 1, 0, 1), point(spec.duration - 0.02, 0, 0, 1, 1, 0, 1)]
4014
+ });
4015
+ return scene;
4016
+ });
4017
+ const project = createProject(config.title, { canvas: { width: 1920, height: 1080, fps: config.fps ?? 30 }, scenes });
4018
+ assertProject(project);
4019
+ return project;
4020
+ }
4021
+
4022
+ // src/core/config.ts
4023
+ var visualThemes = ["car-road", "holiday-table", "one-click", "book-steps", "room-build", "summer-case", "car-garage", "wedding-rings", "share-mosaic", "fraud-alert", "student-desk", "learning-domino", "fomo-storm", "market-clock", "small-bricks", "two-paths", "small-store", "travel-conveyor", "mortgage-blueprint", "market-phone"];
4024
+ var MAX_BYTES = 256 * 1024;
4025
+ function fail2(path, reason) {
4026
+ throw new Error(`${path}: ${reason}`);
4027
+ }
4028
+ function object(value, keys, path) {
4029
+ if (!value || typeof value !== "object" || Array.isArray(value) || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) fail2(path, "\u05E0\u05D3\u05E8\u05E9 \u05D0\u05D5\u05D1\u05D9\u05D9\u05E7\u05D8");
4030
+ const record2 = value;
4031
+ for (const key of Object.keys(record2)) if (!keys.includes(key)) fail2(`${path}.${key}`, "\u05E9\u05D3\u05D4 \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8");
4032
+ return record2;
4033
+ }
4034
+ function text2(value, max, path) {
4035
+ if (typeof value !== "string" || !value.trim() || value.length > max || /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/.test(value)) fail2(path, `\u05E0\u05D3\u05E8\u05E9 \u05D8\u05E7\u05E1\u05D8 \u05D1\u05D0\u05D5\u05E8\u05DA 1\u2013${max} \u05EA\u05D5\u05D5\u05D9\u05DD`);
4036
+ return value;
4037
+ }
4038
+ function choice2(value, values, path) {
4039
+ if (!values.includes(value)) fail2(path, "\u05E2\u05E8\u05DA \u05DC\u05D0 \u05E0\u05EA\u05DE\u05DA");
4040
+ return value;
4041
+ }
4042
+ function validateConfig(value) {
4043
+ const p = object(value, ["format", "title", "aspectRatio", "fps", "palette", "visualTheme", "scenes"], "config");
4044
+ const config = {
4045
+ format: choice2(p.format, ["motiondesk-config/v1"], "format"),
4046
+ title: text2(p.title, 120, "title"),
4047
+ aspectRatio: choice2(p.aspectRatio, ["16:9", "9:16", "1:1"], "aspectRatio"),
4048
+ scenes: []
4049
+ };
4050
+ if (p.fps !== void 0) config.fps = choice2(p.fps, [24, 25, 30, 60], "fps");
4051
+ if (p.visualTheme !== void 0) config.visualTheme = choice2(p.visualTheme, visualThemes, "visualTheme");
4052
+ if (p.palette !== void 0) {
4053
+ const palette = object(p.palette, ["background", "foreground", "accent"], "palette");
4054
+ const color = (key) => {
4055
+ const value2 = palette[key];
4056
+ if (typeof value2 !== "string" || !/^#[a-fA-F0-9]{6}$/.test(value2)) fail2(`palette.${key}`, "\u05E0\u05D3\u05E8\u05E9 \u05E6\u05D1\u05E2 \u05D4\u05E7\u05E1\u05D3\u05E6\u05D9\u05DE\u05DC\u05D9 \u05D1\u05DF \u05E9\u05E9 \u05E1\u05E4\u05E8\u05D5\u05EA");
4057
+ return value2;
4058
+ };
4059
+ config.palette = { background: color("background"), foreground: color("foreground"), accent: color("accent") };
4060
+ }
4061
+ if (!Array.isArray(p.scenes) || p.scenes.length < 1 || p.scenes.length > 12) fail2("scenes", "\u05E0\u05D3\u05E8\u05E9\u05D5\u05EA 1\u201312 \u05E1\u05E6\u05E0\u05D5\u05EA");
4062
+ config.scenes = p.scenes.map((value2, index) => {
4063
+ const path = `scenes.${index}`;
4064
+ const s = object(value2, ["duration", "layout", "headline", "eyebrow", "supporting", "emphasis", "motion"], path);
4065
+ if (typeof s.duration !== "number" || !Number.isFinite(s.duration) || s.duration < 0.5 || s.duration > 20) fail2(`${path}.duration`, "\u05DE\u05E9\u05DA \u05D7\u05D9\u05D9\u05D1 \u05DC\u05D4\u05D9\u05D5\u05EA \u05D1\u05D9\u05DF 0.5 \u05DC\u05BE20 \u05E9\u05E0\u05D9\u05D5\u05EA");
4066
+ const scene = { duration: s.duration, layout: choice2(s.layout, ["statement", "split", "number", "end-card"], `${path}.layout`), headline: text2(s.headline, 160, `${path}.headline`) };
4067
+ for (const [key, max] of [["eyebrow", 60], ["supporting", 280], ["emphasis", 40]]) {
4068
+ if (s[key] !== void 0) scene[key] = text2(s[key], max, `${path}.${key}`);
4069
+ }
4070
+ if (s.motion !== void 0) scene.motion = choice2(s.motion, ["fade", "slide-up", "pop"], `${path}.motion`);
4071
+ if (scene.layout === "number" && !scene.emphasis) fail2(`${path}.emphasis`, "\u05E4\u05E8\u05D9\u05E1\u05EA \u05DE\u05E1\u05E4\u05E8 \u05D3\u05D5\u05E8\u05E9\u05EA \u05D4\u05D3\u05D2\u05E9\u05D4");
4072
+ return scene;
4073
+ });
4074
+ if (config.visualTheme) {
4075
+ if (config.aspectRatio !== "16:9") fail2("aspectRatio", "\u05D4\u05E2\u05D5\u05DC\u05DE\u05D5\u05EA \u05D4\u05D7\u05D6\u05D5\u05EA\u05D9\u05D9\u05DD \u05D6\u05DE\u05D9\u05E0\u05D9\u05DD \u05DB\u05E8\u05D2\u05E2 \u05D1\u05E4\u05D5\u05E8\u05DE\u05D8 16:9");
4076
+ config.scenes.forEach((scene, index) => {
4077
+ if (scene.duration < 2.5) fail2(`scenes.${index}.duration`, "\u05E1\u05E6\u05E0\u05D4 \u05E2\u05DD \u05E2\u05D5\u05DC\u05DD \u05D7\u05D6\u05D5\u05EA\u05D9 \u05E6\u05E8\u05D9\u05DB\u05D4 \u05DC\u05D4\u05D9\u05DE\u05E9\u05DA \u05DC\u05E4\u05D7\u05D5\u05EA 2.5 \u05E9\u05E0\u05D9\u05D5\u05EA");
4078
+ });
4079
+ }
4080
+ return config;
4081
+ }
4082
+ function parseMotionConfig(json) {
4083
+ if (typeof json !== "string" || json.length > MAX_BYTES || new TextEncoder().encode(json).length > MAX_BYTES) fail2("config", "\u05E7\u05D5\u05D1\u05E5 \u05D4\u05D4\u05D2\u05D3\u05E8\u05D5\u05EA \u05D2\u05D3\u05D5\u05DC \u05DE\u05D3\u05D9");
4084
+ let value;
4085
+ try {
4086
+ value = JSON.parse(json);
4087
+ } catch {
4088
+ return fail2("config", "\u05E0\u05D3\u05E8\u05E9 JSON \u05EA\u05E7\u05D9\u05DF \u05DC\u05DC\u05D0 \u05E2\u05D8\u05D9\u05E4\u05EA Markdown");
4089
+ }
4090
+ if (value?.format === "motiondesk-config/v3") return parseMotionConfigV3(value);
4091
+ if (value?.format === "motiondesk-config/v2") return parseMotionConfigV2(value);
4092
+ return validateConfig(value);
4093
+ }
4094
+ function configToProject(input) {
4095
+ if (input.format === "motiondesk-config/v3") return configV3ToProject(input);
4096
+ if (input.format === "motiondesk-config/v2") return configV2ToProject(input);
4097
+ const config = validateConfig(input);
4098
+ if (config.visualTheme) return visualConfigToProject(config);
4099
+ const [width, height] = config.aspectRatio === "16:9" ? [1920, 1080] : config.aspectRatio === "9:16" ? [1080, 1920] : [1080, 1080];
4100
+ const palette = config.palette ?? { background: "#FFFFFF", foreground: "#252833", accent: "#E30613" };
4101
+ const base = Math.min(width, height);
4102
+ const scenes = config.scenes.map((spec, index) => {
4103
+ const scene = createScene(`${index + 1}. ${spec.headline.slice(0, 80)}`, spec.duration);
4104
+ scene.background = palette.background;
4105
+ const motion = spec.motion ?? "slide-up";
4106
+ const shape = (name, x, y, w, h, opacity = 1) => {
4107
+ scene.layers.push(createLayer("shape", { name, x: x * width, y: y * height, width: w * width, height: h * height, color: palette.accent, opacity, borderRadius: base * 0.018, motion: "fade", start: 0, duration: spec.duration }));
4108
+ };
4109
+ const label = (name, value, x, y, w, h, size, accent = false, align = "right") => {
4110
+ if (!value) return;
4111
+ const boxWidth = w * width, boxHeight = h * height;
4112
+ let fontSize = Math.round(base * size);
4113
+ const lines = (font) => value.split("\n").reduce((sum, line) => sum + Math.max(1, Math.ceil(line.length * font * 0.72 / boxWidth)), 0);
4114
+ while (fontSize > 10 && lines(fontSize) * fontSize * 1.35 > boxHeight) fontSize = Math.max(10, fontSize - 1);
4115
+ if (lines(fontSize) * fontSize * 1.35 > boxHeight) {
4116
+ const field = { "\u05DB\u05D5\u05EA\u05E8\u05EA \u05DE\u05E9\u05E0\u05D4": "eyebrow", "\u05DB\u05D5\u05EA\u05E8\u05EA": "headline", "\u05D8\u05E7\u05E1\u05D8 \u05EA\u05D5\u05DE\u05DA": "supporting", "\u05D4\u05D3\u05D2\u05E9\u05D4": "emphasis" }[name] ?? name;
4117
+ fail2(`scenes.${index}.${field}`, "\u05D4\u05D8\u05E7\u05E1\u05D8 \u05D0\u05D9\u05E0\u05D5 \u05E0\u05DB\u05E0\u05E1 \u05DC\u05EA\u05D9\u05D1\u05EA \u05D4\u05EA\u05E6\u05D5\u05D2\u05D4; \u05D9\u05E9 \u05DC\u05E7\u05E6\u05E8 \u05D0\u05D5\u05EA\u05D5 \u05D0\u05D5 \u05DC\u05D4\u05E4\u05D7\u05D9\u05EA \u05DE\u05E2\u05D1\u05E8\u05D9 \u05E9\u05D5\u05E8\u05D4");
4118
+ }
4119
+ const start = Math.min(0.08 * scene.layers.filter((l) => l.type === "text").length, spec.duration * 0.2);
4120
+ scene.layers.push(createLayer("text", { name, text: value, x: x * width, y: y * height, width: boxWidth, height: boxHeight, fontSize, fontWeight: name === "\u05D8\u05E7\u05E1\u05D8 \u05EA\u05D5\u05DE\u05DA" ? 400 : 700, color: accent ? palette.accent : palette.foreground, textAlign: align, motion, start, duration: spec.duration - start }));
4121
+ };
4122
+ switch (spec.layout) {
4123
+ case "statement":
4124
+ shape("\u05E7\u05D5 \u05D4\u05D3\u05D2\u05E9\u05D4", 0.84, 0.13, 0.08, 9e-3);
4125
+ label("\u05DB\u05D5\u05EA\u05E8\u05EA \u05DE\u05E9\u05E0\u05D4", spec.eyebrow, 0.08, 0.17, 0.84, 0.07, 0.027, true);
4126
+ label("\u05DB\u05D5\u05EA\u05E8\u05EA", spec.headline, 0.08, 0.28, 0.84, 0.3, 0.085);
4127
+ label("\u05D4\u05D3\u05D2\u05E9\u05D4", spec.emphasis, 0.08, 0.6, 0.84, 0.09, 0.044, true);
4128
+ label("\u05D8\u05E7\u05E1\u05D8 \u05EA\u05D5\u05DE\u05DA", spec.supporting, 0.08, 0.73, 0.84, 0.18, 0.033);
4129
+ break;
4130
+ case "split": {
4131
+ const portrait = height > width;
4132
+ shape("\u05DC\u05D5\u05D7 \u05D4\u05D3\u05D2\u05E9\u05D4", 0.06, portrait ? 0.64 : 0.12, portrait ? 0.88 : 0.4, portrait ? 0.29 : 0.76, 0.12);
4133
+ label("\u05DB\u05D5\u05EA\u05E8\u05EA \u05DE\u05E9\u05E0\u05D4", spec.eyebrow, portrait ? 0.08 : 0.53, 0.12, portrait ? 0.84 : 0.39, 0.08, 0.025, true);
4134
+ label("\u05DB\u05D5\u05EA\u05E8\u05EA", spec.headline, portrait ? 0.08 : 0.53, 0.23, portrait ? 0.84 : 0.39, portrait ? 0.2 : 0.34, 0.068);
4135
+ label("\u05D8\u05E7\u05E1\u05D8 \u05EA\u05D5\u05DE\u05DA", spec.supporting, portrait ? 0.08 : 0.53, portrait ? 0.45 : 0.62, portrait ? 0.84 : 0.39, portrait ? 0.15 : 0.24, 0.03);
4136
+ label("\u05D4\u05D3\u05D2\u05E9\u05D4", spec.emphasis, 0.1, portrait ? 0.69 : 0.25, portrait ? 0.8 : 0.32, portrait ? 0.19 : 0.5, 0.1, true, "center");
4137
+ break;
4138
+ }
4139
+ case "number":
4140
+ shape("\u05E4\u05E1 \u05E0\u05EA\u05D5\u05DF", 0.46, 0.59, 0.08, 9e-3);
4141
+ label("\u05DB\u05D5\u05EA\u05E8\u05EA \u05DE\u05E9\u05E0\u05D4", spec.eyebrow, 0.08, 0.08, 0.84, 0.08, 0.027, true, "center");
4142
+ label("\u05D4\u05D3\u05D2\u05E9\u05D4", spec.emphasis, 0.08, 0.2, 0.84, 0.34, 0.19, true, "center");
4143
+ label("\u05DB\u05D5\u05EA\u05E8\u05EA", spec.headline, 0.08, 0.63, 0.84, 0.15, 0.055, false, "center");
4144
+ label("\u05D8\u05E7\u05E1\u05D8 \u05EA\u05D5\u05DE\u05DA", spec.supporting, 0.08, 0.8, 0.84, 0.14, 0.03, false, "center");
4145
+ break;
4146
+ case "end-card":
4147
+ shape("\u05DE\u05E1\u05D2\u05E8\u05EA \u05E1\u05D9\u05D5\u05DD", 0.06, 0.08, 0.88, 0.84, 0.09);
4148
+ label("\u05DB\u05D5\u05EA\u05E8\u05EA \u05DE\u05E9\u05E0\u05D4", spec.eyebrow, 0.12, 0.14, 0.76, 0.08, 0.025, true, "center");
4149
+ label("\u05DB\u05D5\u05EA\u05E8\u05EA", spec.headline, 0.12, 0.26, 0.76, 0.27, 0.075, false, "center");
4150
+ label("\u05D8\u05E7\u05E1\u05D8 \u05EA\u05D5\u05DE\u05DA", spec.supporting, 0.12, 0.55, 0.76, 0.18, 0.032, false, "center");
4151
+ label("\u05D4\u05D3\u05D2\u05E9\u05D4", spec.emphasis, 0.12, 0.77, 0.76, 0.09, 0.043, true, "center");
4152
+ break;
4153
+ }
4154
+ return scene;
4155
+ });
4156
+ const project = createProject(config.title, { canvas: { width, height, fps: config.fps ?? 30 }, scenes });
4157
+ assertProject(project);
4158
+ return project;
4159
+ }
4160
+ // Annotate the CommonJS export names for ESM import in node:
4161
+ 0 && (module.exports = {
4162
+ SOURCE_ADAPTER_DEFINITIONS,
4163
+ analyzeSource,
4164
+ analyzeSourceAdapter,
4165
+ animateMotif,
4166
+ annotateSourcePreview,
4167
+ applySourceEdits,
4168
+ assertProject,
4169
+ cameraStyle,
4170
+ commitProject,
4171
+ compileProjectHtml,
4172
+ componentTypes,
4173
+ componentTypesV3,
4174
+ configToProject,
4175
+ configV2ToProject,
4176
+ configV3Backgrounds,
4177
+ configV3Cameras,
4178
+ configV3Energies,
4179
+ configV3ThemePalettes,
4180
+ configV3Themes,
4181
+ configV3ToProject,
4182
+ configV3Transitions,
4183
+ configV3Variants,
4184
+ contrastRatio,
4185
+ contrastText,
4186
+ createLayer,
4187
+ createMediaRenderPlan,
4188
+ createProject,
4189
+ createScene,
4190
+ duplicateScene,
4191
+ escapeHtml,
4192
+ evaluateLayer,
4193
+ flight,
4194
+ importHtmlSource,
4195
+ importStructuredHtml,
4196
+ isLocalAsset,
4197
+ layerStyle,
4198
+ migrateProject,
4199
+ moveScene,
4200
+ newId,
4201
+ parseMotionConfig,
4202
+ parseMotionConfigV2,
4203
+ parseMotionConfigV3,
4204
+ parseProject,
4205
+ point,
4206
+ projectDuration,
4207
+ projectWarnings,
4208
+ pulse,
4209
+ rebuildConfigV3Scene,
4210
+ removeScene,
4211
+ repeaterLayers,
4212
+ sceneAtTime,
4213
+ sceneStyle,
4214
+ serializeProject,
4215
+ sourceFingerprint,
4216
+ sourcePreviewHtml,
4217
+ textLineStyle,
4218
+ textUnitStyle,
4219
+ updateSourceText,
4220
+ upgradeConfigV2ToV3,
4221
+ validateProject,
4222
+ visualThemes
4223
+ });