@cola1900/dsh-ppt 0.1.2

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 (730) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +57 -0
  3. package/THIRD_PARTY_NOTICES.md +29 -0
  4. package/UPSTREAM.md +17 -0
  5. package/cordis.patch.yml +8 -0
  6. package/lib/bin.js +4070 -0
  7. package/lib/catalog.js +3 -0
  8. package/lib/client.js +916 -0
  9. package/lib/index.js +3688 -0
  10. package/lib/invariant.js +13 -0
  11. package/lib/pptd-2VqVzr_T.js +2173 -0
  12. package/lib/pptd.js +2 -0
  13. package/lib/preview-assets.js +59 -0
  14. package/lib/preview-manifest.js +2 -0
  15. package/lib/text-wrap.js +20 -0
  16. package/lib/types/bin.d.ts +12 -0
  17. package/lib/types/client/OfficePptHero.d.ts +42 -0
  18. package/lib/types/client/curated-previews.d.ts +3 -0
  19. package/lib/types/client/curated-previews.generated.d.ts +2 -0
  20. package/lib/types/client/index.d.ts +6 -0
  21. package/lib/types/client/locales.d.ts +15 -0
  22. package/lib/types/client/rpc.d.ts +23 -0
  23. package/lib/types/client/standard.d.ts +31 -0
  24. package/lib/types/client.d.ts +1 -0
  25. package/lib/types/data-series.d.ts +31 -0
  26. package/lib/types/index.d.ts +25 -0
  27. package/lib/types/invariant.d.ts +8 -0
  28. package/lib/types/layouts.d.ts +54 -0
  29. package/lib/types/planning.d.ts +35 -0
  30. package/lib/types/ppt-ppt-skill.d.ts +6 -0
  31. package/lib/types/ppt-reference-semantics.generated.d.ts +2 -0
  32. package/lib/types/ppt-rpc.d.ts +5 -0
  33. package/lib/types/ppt-service.d.ts +34 -0
  34. package/lib/types/ppt-store.d.ts +47 -0
  35. package/lib/types/ppt-template-catalog.generated.d.ts +2 -0
  36. package/lib/types/ppt-template-definitions.d.ts +1 -0
  37. package/lib/types/ppt-tools.d.ts +10 -0
  38. package/lib/types/pptd-colors.d.ts +15 -0
  39. package/lib/types/pptd-convert.d.ts +21 -0
  40. package/lib/types/pptd-preview.d.ts +6 -0
  41. package/lib/types/pptd-publish.d.ts +8 -0
  42. package/lib/types/pptd-repair.d.ts +18 -0
  43. package/lib/types/pptd-tools.d.ts +5 -0
  44. package/lib/types/pptd.d.ts +89 -0
  45. package/lib/types/protocol.d.ts +547 -0
  46. package/lib/types/template-reference.d.ts +28 -0
  47. package/lib/types/template-semantics.d.ts +12 -0
  48. package/lib/types/templates.d.ts +2 -0
  49. package/lib/types/text-layout.d.ts +37 -0
  50. package/lib/validation.js +84 -0
  51. package/licenses/composer-NOTICES.md +29 -0
  52. package/licenses/dsh-desktop-LICENSE +21 -0
  53. package/licenses/html-anything/LICENSE +202 -0
  54. package/licenses/html-anything/deck-blueprint.md +22 -0
  55. package/licenses/html-anything/deck-course-module.md +23 -0
  56. package/licenses/zara/LICENSE +21 -0
  57. package/licenses/zara/templates/blue-professional/design.md +701 -0
  58. package/licenses/zara/templates/blue-professional/template.html +1423 -0
  59. package/licenses/zara/templates/blue-professional/template.json +43 -0
  60. package/licenses/zara/templates/broadside/design.md +493 -0
  61. package/licenses/zara/templates/broadside/template.html +2144 -0
  62. package/licenses/zara/templates/broadside/template.json +48 -0
  63. package/licenses/zara/templates/cartesian/design.md +513 -0
  64. package/licenses/zara/templates/cartesian/template.html +1136 -0
  65. package/licenses/zara/templates/cartesian/template.json +46 -0
  66. package/licenses/zara/templates/editorial-forest/design.md +497 -0
  67. package/licenses/zara/templates/editorial-forest/template.html +843 -0
  68. package/licenses/zara/templates/editorial-forest/template.json +44 -0
  69. package/licenses/zara/templates/monochrome/design.md +482 -0
  70. package/licenses/zara/templates/monochrome/template.html +2596 -0
  71. package/licenses/zara/templates/monochrome/template.json +49 -0
  72. package/licenses/zara/templates/neo-grid-bold/design.md +534 -0
  73. package/licenses/zara/templates/neo-grid-bold/template.html +865 -0
  74. package/licenses/zara/templates/neo-grid-bold/template.json +46 -0
  75. package/licenses/zara/templates/playful/design.md +480 -0
  76. package/licenses/zara/templates/playful/template.html +1355 -0
  77. package/licenses/zara/templates/playful/template.json +42 -0
  78. package/licenses/zara/templates/sakura-chroma/design.md +632 -0
  79. package/licenses/zara/templates/sakura-chroma/template.html +1405 -0
  80. package/licenses/zara/templates/sakura-chroma/template.json +53 -0
  81. package/licenses/zara/templates/signal/design.md +517 -0
  82. package/licenses/zara/templates/signal/template.html +2558 -0
  83. package/licenses/zara/templates/signal/template.json +49 -0
  84. package/licenses/zara/templates/soft-editorial/design.md +615 -0
  85. package/licenses/zara/templates/soft-editorial/template.html +1183 -0
  86. package/licenses/zara/templates/soft-editorial/template.json +46 -0
  87. package/package.json +107 -0
  88. package/skills/dsh-ppt/SKILL.md +36 -0
  89. package/skills/dsh-ppt/references/academic/dsh-course-workshop/design.md +61 -0
  90. package/skills/dsh-ppt/references/academic/dsh-course-workshop/metadata.json +2886 -0
  91. package/skills/dsh-ppt/references/academic/dsh-course-workshop/pages/01.jpg +0 -0
  92. package/skills/dsh-ppt/references/academic/dsh-course-workshop/pages/02.jpg +0 -0
  93. package/skills/dsh-ppt/references/academic/dsh-course-workshop/pages/03.jpg +0 -0
  94. package/skills/dsh-ppt/references/academic/dsh-course-workshop/pages/04.jpg +0 -0
  95. package/skills/dsh-ppt/references/academic/dsh-course-workshop/pages/05.jpg +0 -0
  96. package/skills/dsh-ppt/references/academic/dsh-course-workshop/pages/06.jpg +0 -0
  97. package/skills/dsh-ppt/references/academic/dsh-course-workshop/pages/07.jpg +0 -0
  98. package/skills/dsh-ppt/references/academic/dsh-course-workshop/pages/08.jpg +0 -0
  99. package/skills/dsh-ppt/references/academic/dsh-course-workshop/pages/09.jpg +0 -0
  100. package/skills/dsh-ppt/references/academic/dsh-course-workshop/pages/10.jpg +0 -0
  101. package/skills/dsh-ppt/references/academic/dsh-course-workshop/pages/11.jpg +0 -0
  102. package/skills/dsh-ppt/references/academic/dsh-course-workshop/pages/12.jpg +0 -0
  103. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source/deck.pptd +21 -0
  104. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source/pages/01.page +142 -0
  105. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source/pages/02.page +382 -0
  106. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source/pages/03.page +817 -0
  107. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source/pages/04.page +408 -0
  108. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source/pages/05.page +407 -0
  109. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source/pages/06.page +760 -0
  110. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source/pages/07.page +551 -0
  111. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source/pages/08.page +339 -0
  112. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source/pages/09.page +297 -0
  113. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source/pages/10.page +365 -0
  114. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source/pages/11.page +575 -0
  115. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source/pages/12.page +130 -0
  116. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source-zh/deck.pptd +21 -0
  117. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source-zh/pages/01.page +142 -0
  118. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source-zh/pages/02.page +382 -0
  119. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source-zh/pages/03.page +817 -0
  120. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source-zh/pages/04.page +408 -0
  121. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source-zh/pages/05.page +407 -0
  122. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source-zh/pages/06.page +760 -0
  123. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source-zh/pages/07.page +551 -0
  124. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source-zh/pages/08.page +339 -0
  125. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source-zh/pages/09.page +297 -0
  126. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source-zh/pages/10.page +365 -0
  127. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source-zh/pages/11.page +575 -0
  128. package/skills/dsh-ppt/references/academic/dsh-course-workshop/source-zh/pages/12.page +130 -0
  129. package/skills/dsh-ppt/references/academic/dsh-monochrome/design.md +61 -0
  130. package/skills/dsh-ppt/references/academic/dsh-monochrome/metadata.json +2989 -0
  131. package/skills/dsh-ppt/references/academic/dsh-monochrome/pages/01.jpg +0 -0
  132. package/skills/dsh-ppt/references/academic/dsh-monochrome/pages/02.jpg +0 -0
  133. package/skills/dsh-ppt/references/academic/dsh-monochrome/pages/03.jpg +0 -0
  134. package/skills/dsh-ppt/references/academic/dsh-monochrome/pages/04.jpg +0 -0
  135. package/skills/dsh-ppt/references/academic/dsh-monochrome/pages/05.jpg +0 -0
  136. package/skills/dsh-ppt/references/academic/dsh-monochrome/pages/06.jpg +0 -0
  137. package/skills/dsh-ppt/references/academic/dsh-monochrome/pages/07.jpg +0 -0
  138. package/skills/dsh-ppt/references/academic/dsh-monochrome/pages/08.jpg +0 -0
  139. package/skills/dsh-ppt/references/academic/dsh-monochrome/pages/09.jpg +0 -0
  140. package/skills/dsh-ppt/references/academic/dsh-monochrome/pages/10.jpg +0 -0
  141. package/skills/dsh-ppt/references/academic/dsh-monochrome/pages/11.jpg +0 -0
  142. package/skills/dsh-ppt/references/academic/dsh-monochrome/pages/12.jpg +0 -0
  143. package/skills/dsh-ppt/references/academic/dsh-monochrome/source/deck.pptd +21 -0
  144. package/skills/dsh-ppt/references/academic/dsh-monochrome/source/pages/01.page +86 -0
  145. package/skills/dsh-ppt/references/academic/dsh-monochrome/source/pages/02.page +382 -0
  146. package/skills/dsh-ppt/references/academic/dsh-monochrome/source/pages/03.page +479 -0
  147. package/skills/dsh-ppt/references/academic/dsh-monochrome/source/pages/04.page +551 -0
  148. package/skills/dsh-ppt/references/academic/dsh-monochrome/source/pages/05.page +817 -0
  149. package/skills/dsh-ppt/references/academic/dsh-monochrome/source/pages/06.page +760 -0
  150. package/skills/dsh-ppt/references/academic/dsh-monochrome/source/pages/07.page +576 -0
  151. package/skills/dsh-ppt/references/academic/dsh-monochrome/source/pages/08.page +339 -0
  152. package/skills/dsh-ppt/references/academic/dsh-monochrome/source/pages/09.page +295 -0
  153. package/skills/dsh-ppt/references/academic/dsh-monochrome/source/pages/10.page +407 -0
  154. package/skills/dsh-ppt/references/academic/dsh-monochrome/source/pages/11.page +575 -0
  155. package/skills/dsh-ppt/references/academic/dsh-monochrome/source/pages/12.page +86 -0
  156. package/skills/dsh-ppt/references/academic/dsh-monochrome/source-zh/deck.pptd +21 -0
  157. package/skills/dsh-ppt/references/academic/dsh-monochrome/source-zh/pages/01.page +86 -0
  158. package/skills/dsh-ppt/references/academic/dsh-monochrome/source-zh/pages/02.page +382 -0
  159. package/skills/dsh-ppt/references/academic/dsh-monochrome/source-zh/pages/03.page +479 -0
  160. package/skills/dsh-ppt/references/academic/dsh-monochrome/source-zh/pages/04.page +551 -0
  161. package/skills/dsh-ppt/references/academic/dsh-monochrome/source-zh/pages/05.page +817 -0
  162. package/skills/dsh-ppt/references/academic/dsh-monochrome/source-zh/pages/06.page +760 -0
  163. package/skills/dsh-ppt/references/academic/dsh-monochrome/source-zh/pages/07.page +576 -0
  164. package/skills/dsh-ppt/references/academic/dsh-monochrome/source-zh/pages/08.page +339 -0
  165. package/skills/dsh-ppt/references/academic/dsh-monochrome/source-zh/pages/09.page +295 -0
  166. package/skills/dsh-ppt/references/academic/dsh-monochrome/source-zh/pages/10.page +407 -0
  167. package/skills/dsh-ppt/references/academic/dsh-monochrome/source-zh/pages/11.page +575 -0
  168. package/skills/dsh-ppt/references/academic/dsh-monochrome/source-zh/pages/12.page +86 -0
  169. package/skills/dsh-ppt/references/business/dsh-blue-professional/design.md +53 -0
  170. package/skills/dsh-ppt/references/business/dsh-blue-professional/metadata.json +3152 -0
  171. package/skills/dsh-ppt/references/business/dsh-blue-professional/pages/01.jpg +0 -0
  172. package/skills/dsh-ppt/references/business/dsh-blue-professional/pages/02.jpg +0 -0
  173. package/skills/dsh-ppt/references/business/dsh-blue-professional/pages/03.jpg +0 -0
  174. package/skills/dsh-ppt/references/business/dsh-blue-professional/pages/04.jpg +0 -0
  175. package/skills/dsh-ppt/references/business/dsh-blue-professional/pages/05.jpg +0 -0
  176. package/skills/dsh-ppt/references/business/dsh-blue-professional/pages/06.jpg +0 -0
  177. package/skills/dsh-ppt/references/business/dsh-blue-professional/pages/07.jpg +0 -0
  178. package/skills/dsh-ppt/references/business/dsh-blue-professional/pages/08.jpg +0 -0
  179. package/skills/dsh-ppt/references/business/dsh-blue-professional/pages/09.jpg +0 -0
  180. package/skills/dsh-ppt/references/business/dsh-blue-professional/pages/10.jpg +0 -0
  181. package/skills/dsh-ppt/references/business/dsh-blue-professional/pages/11.jpg +0 -0
  182. package/skills/dsh-ppt/references/business/dsh-blue-professional/pages/12.jpg +0 -0
  183. package/skills/dsh-ppt/references/business/dsh-blue-professional/source/deck.pptd +21 -0
  184. package/skills/dsh-ppt/references/business/dsh-blue-professional/source/pages/01.page +100 -0
  185. package/skills/dsh-ppt/references/business/dsh-blue-professional/source/pages/02.page +310 -0
  186. package/skills/dsh-ppt/references/business/dsh-blue-professional/source/pages/03.page +381 -0
  187. package/skills/dsh-ppt/references/business/dsh-blue-professional/source/pages/04.page +853 -0
  188. package/skills/dsh-ppt/references/business/dsh-blue-professional/source/pages/05.page +436 -0
  189. package/skills/dsh-ppt/references/business/dsh-blue-professional/source/pages/06.page +732 -0
  190. package/skills/dsh-ppt/references/business/dsh-blue-professional/source/pages/07.page +574 -0
  191. package/skills/dsh-ppt/references/business/dsh-blue-professional/source/pages/08.page +767 -0
  192. package/skills/dsh-ppt/references/business/dsh-blue-professional/source/pages/09.page +282 -0
  193. package/skills/dsh-ppt/references/business/dsh-blue-professional/source/pages/10.page +350 -0
  194. package/skills/dsh-ppt/references/business/dsh-blue-professional/source/pages/11.page +462 -0
  195. package/skills/dsh-ppt/references/business/dsh-blue-professional/source/pages/12.page +86 -0
  196. package/skills/dsh-ppt/references/business/dsh-blue-professional/source-zh/deck.pptd +21 -0
  197. package/skills/dsh-ppt/references/business/dsh-blue-professional/source-zh/pages/01.page +100 -0
  198. package/skills/dsh-ppt/references/business/dsh-blue-professional/source-zh/pages/02.page +310 -0
  199. package/skills/dsh-ppt/references/business/dsh-blue-professional/source-zh/pages/03.page +381 -0
  200. package/skills/dsh-ppt/references/business/dsh-blue-professional/source-zh/pages/04.page +853 -0
  201. package/skills/dsh-ppt/references/business/dsh-blue-professional/source-zh/pages/05.page +436 -0
  202. package/skills/dsh-ppt/references/business/dsh-blue-professional/source-zh/pages/06.page +732 -0
  203. package/skills/dsh-ppt/references/business/dsh-blue-professional/source-zh/pages/07.page +574 -0
  204. package/skills/dsh-ppt/references/business/dsh-blue-professional/source-zh/pages/08.page +769 -0
  205. package/skills/dsh-ppt/references/business/dsh-blue-professional/source-zh/pages/09.page +282 -0
  206. package/skills/dsh-ppt/references/business/dsh-blue-professional/source-zh/pages/10.page +350 -0
  207. package/skills/dsh-ppt/references/business/dsh-blue-professional/source-zh/pages/11.page +462 -0
  208. package/skills/dsh-ppt/references/business/dsh-blue-professional/source-zh/pages/12.page +86 -0
  209. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/design.md +61 -0
  210. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/metadata.json +3883 -0
  211. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/pages/01.jpg +0 -0
  212. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/pages/02.jpg +0 -0
  213. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/pages/03.jpg +0 -0
  214. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/pages/04.jpg +0 -0
  215. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/pages/05.jpg +0 -0
  216. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/pages/06.jpg +0 -0
  217. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/pages/07.jpg +0 -0
  218. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/pages/08.jpg +0 -0
  219. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/pages/09.jpg +0 -0
  220. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/pages/10.jpg +0 -0
  221. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/pages/11.jpg +0 -0
  222. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/pages/12.jpg +0 -0
  223. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source/deck.pptd +21 -0
  224. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source/pages/01.page +355 -0
  225. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source/pages/02.page +452 -0
  226. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source/pages/03.page +561 -0
  227. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source/pages/04.page +830 -0
  228. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source/pages/05.page +887 -0
  229. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source/pages/06.page +646 -0
  230. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source/pages/07.page +881 -0
  231. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source/pages/08.page +788 -0
  232. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source/pages/09.page +365 -0
  233. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source/pages/10.page +617 -0
  234. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source/pages/11.page +645 -0
  235. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source/pages/12.page +86 -0
  236. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source-zh/deck.pptd +21 -0
  237. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source-zh/pages/01.page +354 -0
  238. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source-zh/pages/02.page +452 -0
  239. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source-zh/pages/03.page +561 -0
  240. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source-zh/pages/04.page +830 -0
  241. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source-zh/pages/05.page +887 -0
  242. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source-zh/pages/06.page +646 -0
  243. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source-zh/pages/07.page +881 -0
  244. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source-zh/pages/08.page +788 -0
  245. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source-zh/pages/09.page +365 -0
  246. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source-zh/pages/10.page +617 -0
  247. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source-zh/pages/11.page +645 -0
  248. package/skills/dsh-ppt/references/business/dsh-neo-grid-bold/source-zh/pages/12.page +86 -0
  249. package/skills/dsh-ppt/references/composition.md +19 -0
  250. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/design.md +124 -0
  251. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/metadata.json +1930 -0
  252. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/pages/01.jpg +0 -0
  253. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/pages/02.jpg +0 -0
  254. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/pages/03.jpg +0 -0
  255. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/pages/04.jpg +0 -0
  256. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/pages/05.jpg +0 -0
  257. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/pages/06.jpg +0 -0
  258. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/pages/07.jpg +0 -0
  259. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/pages/08.jpg +0 -0
  260. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/pages/09.jpg +0 -0
  261. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/pages/10.jpg +0 -0
  262. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/pages/11.jpg +0 -0
  263. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/pages/12.jpg +0 -0
  264. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source/deck.pptd +91 -0
  265. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source/pages/01.page +259 -0
  266. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source/pages/02.page +325 -0
  267. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source/pages/03.page +511 -0
  268. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source/pages/04.page +398 -0
  269. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source/pages/05.page +439 -0
  270. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source/pages/06.page +493 -0
  271. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source/pages/07.page +194 -0
  272. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source/pages/08.page +422 -0
  273. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source/pages/09.page +458 -0
  274. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source/pages/10.page +746 -0
  275. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source/pages/11.page +604 -0
  276. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source/pages/12.page +343 -0
  277. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source-zh/deck.pptd +91 -0
  278. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source-zh/pages/01.page +259 -0
  279. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source-zh/pages/02.page +325 -0
  280. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source-zh/pages/03.page +511 -0
  281. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source-zh/pages/04.page +398 -0
  282. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source-zh/pages/05.page +439 -0
  283. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source-zh/pages/06.page +493 -0
  284. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source-zh/pages/07.page +194 -0
  285. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source-zh/pages/08.page +417 -0
  286. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source-zh/pages/09.page +458 -0
  287. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source-zh/pages/10.page +746 -0
  288. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source-zh/pages/11.page +604 -0
  289. package/skills/dsh-ppt/references/consulting/curated-swiss-signal-grid/source-zh/pages/12.page +343 -0
  290. package/skills/dsh-ppt/references/consulting/dsh-cartesian/design.md +61 -0
  291. package/skills/dsh-ppt/references/consulting/dsh-cartesian/metadata.json +3196 -0
  292. package/skills/dsh-ppt/references/consulting/dsh-cartesian/pages/01.jpg +0 -0
  293. package/skills/dsh-ppt/references/consulting/dsh-cartesian/pages/02.jpg +0 -0
  294. package/skills/dsh-ppt/references/consulting/dsh-cartesian/pages/03.jpg +0 -0
  295. package/skills/dsh-ppt/references/consulting/dsh-cartesian/pages/04.jpg +0 -0
  296. package/skills/dsh-ppt/references/consulting/dsh-cartesian/pages/05.jpg +0 -0
  297. package/skills/dsh-ppt/references/consulting/dsh-cartesian/pages/06.jpg +0 -0
  298. package/skills/dsh-ppt/references/consulting/dsh-cartesian/pages/07.jpg +0 -0
  299. package/skills/dsh-ppt/references/consulting/dsh-cartesian/pages/08.jpg +0 -0
  300. package/skills/dsh-ppt/references/consulting/dsh-cartesian/pages/09.jpg +0 -0
  301. package/skills/dsh-ppt/references/consulting/dsh-cartesian/pages/10.jpg +0 -0
  302. package/skills/dsh-ppt/references/consulting/dsh-cartesian/pages/11.jpg +0 -0
  303. package/skills/dsh-ppt/references/consulting/dsh-cartesian/pages/12.jpg +0 -0
  304. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source/deck.pptd +21 -0
  305. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source/pages/01.page +98 -0
  306. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source/pages/02.page +382 -0
  307. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source/pages/03.page +817 -0
  308. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source/pages/04.page +479 -0
  309. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source/pages/05.page +576 -0
  310. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source/pages/06.page +760 -0
  311. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source/pages/07.page +339 -0
  312. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source/pages/08.page +718 -0
  313. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source/pages/09.page +295 -0
  314. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source/pages/10.page +547 -0
  315. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source/pages/11.page +575 -0
  316. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source/pages/12.page +86 -0
  317. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source-zh/deck.pptd +21 -0
  318. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source-zh/pages/01.page +98 -0
  319. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source-zh/pages/02.page +382 -0
  320. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source-zh/pages/03.page +817 -0
  321. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source-zh/pages/04.page +479 -0
  322. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source-zh/pages/05.page +576 -0
  323. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source-zh/pages/06.page +760 -0
  324. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source-zh/pages/07.page +339 -0
  325. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source-zh/pages/08.page +718 -0
  326. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source-zh/pages/09.page +295 -0
  327. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source-zh/pages/10.page +547 -0
  328. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source-zh/pages/11.page +575 -0
  329. package/skills/dsh-ppt/references/consulting/dsh-cartesian/source-zh/pages/12.page +86 -0
  330. package/skills/dsh-ppt/references/consulting/dsh-signal/design.md +61 -0
  331. package/skills/dsh-ppt/references/consulting/dsh-signal/metadata.json +3172 -0
  332. package/skills/dsh-ppt/references/consulting/dsh-signal/pages/01.jpg +0 -0
  333. package/skills/dsh-ppt/references/consulting/dsh-signal/pages/02.jpg +0 -0
  334. package/skills/dsh-ppt/references/consulting/dsh-signal/pages/03.jpg +0 -0
  335. package/skills/dsh-ppt/references/consulting/dsh-signal/pages/04.jpg +0 -0
  336. package/skills/dsh-ppt/references/consulting/dsh-signal/pages/05.jpg +0 -0
  337. package/skills/dsh-ppt/references/consulting/dsh-signal/pages/06.jpg +0 -0
  338. package/skills/dsh-ppt/references/consulting/dsh-signal/pages/07.jpg +0 -0
  339. package/skills/dsh-ppt/references/consulting/dsh-signal/pages/08.jpg +0 -0
  340. package/skills/dsh-ppt/references/consulting/dsh-signal/pages/09.jpg +0 -0
  341. package/skills/dsh-ppt/references/consulting/dsh-signal/pages/10.jpg +0 -0
  342. package/skills/dsh-ppt/references/consulting/dsh-signal/pages/11.jpg +0 -0
  343. package/skills/dsh-ppt/references/consulting/dsh-signal/pages/12.jpg +0 -0
  344. package/skills/dsh-ppt/references/consulting/dsh-signal/source/deck.pptd +21 -0
  345. package/skills/dsh-ppt/references/consulting/dsh-signal/source/pages/01.page +100 -0
  346. package/skills/dsh-ppt/references/consulting/dsh-signal/source/pages/02.page +382 -0
  347. package/skills/dsh-ppt/references/consulting/dsh-signal/source/pages/03.page +817 -0
  348. package/skills/dsh-ppt/references/consulting/dsh-signal/source/pages/04.page +760 -0
  349. package/skills/dsh-ppt/references/consulting/dsh-signal/source/pages/05.page +576 -0
  350. package/skills/dsh-ppt/references/consulting/dsh-signal/source/pages/06.page +718 -0
  351. package/skills/dsh-ppt/references/consulting/dsh-signal/source/pages/07.page +295 -0
  352. package/skills/dsh-ppt/references/consulting/dsh-signal/source/pages/08.page +551 -0
  353. package/skills/dsh-ppt/references/consulting/dsh-signal/source/pages/09.page +339 -0
  354. package/skills/dsh-ppt/references/consulting/dsh-signal/source/pages/10.page +547 -0
  355. package/skills/dsh-ppt/references/consulting/dsh-signal/source/pages/11.page +575 -0
  356. package/skills/dsh-ppt/references/consulting/dsh-signal/source/pages/12.page +86 -0
  357. package/skills/dsh-ppt/references/consulting/dsh-signal/source-zh/deck.pptd +21 -0
  358. package/skills/dsh-ppt/references/consulting/dsh-signal/source-zh/pages/01.page +100 -0
  359. package/skills/dsh-ppt/references/consulting/dsh-signal/source-zh/pages/02.page +382 -0
  360. package/skills/dsh-ppt/references/consulting/dsh-signal/source-zh/pages/03.page +817 -0
  361. package/skills/dsh-ppt/references/consulting/dsh-signal/source-zh/pages/04.page +760 -0
  362. package/skills/dsh-ppt/references/consulting/dsh-signal/source-zh/pages/05.page +576 -0
  363. package/skills/dsh-ppt/references/consulting/dsh-signal/source-zh/pages/06.page +718 -0
  364. package/skills/dsh-ppt/references/consulting/dsh-signal/source-zh/pages/07.page +295 -0
  365. package/skills/dsh-ppt/references/consulting/dsh-signal/source-zh/pages/08.page +551 -0
  366. package/skills/dsh-ppt/references/consulting/dsh-signal/source-zh/pages/09.page +339 -0
  367. package/skills/dsh-ppt/references/consulting/dsh-signal/source-zh/pages/10.page +547 -0
  368. package/skills/dsh-ppt/references/consulting/dsh-signal/source-zh/pages/11.page +575 -0
  369. package/skills/dsh-ppt/references/consulting/dsh-signal/source-zh/pages/12.page +86 -0
  370. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/design.md +61 -0
  371. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/metadata.json +3091 -0
  372. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/pages/01.jpg +0 -0
  373. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/pages/02.jpg +0 -0
  374. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/pages/03.jpg +0 -0
  375. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/pages/04.jpg +0 -0
  376. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/pages/05.jpg +0 -0
  377. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/pages/06.jpg +0 -0
  378. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/pages/07.jpg +0 -0
  379. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/pages/08.jpg +0 -0
  380. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/pages/09.jpg +0 -0
  381. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/pages/10.jpg +0 -0
  382. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/pages/11.jpg +0 -0
  383. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/pages/12.jpg +0 -0
  384. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source/deck.pptd +21 -0
  385. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source/pages/01.page +124 -0
  386. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source/pages/02.page +382 -0
  387. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source/pages/03.page +479 -0
  388. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source/pages/04.page +365 -0
  389. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source/pages/05.page +817 -0
  390. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source/pages/06.page +760 -0
  391. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source/pages/07.page +576 -0
  392. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source/pages/08.page +295 -0
  393. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source/pages/09.page +339 -0
  394. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source/pages/10.page +547 -0
  395. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source/pages/11.page +575 -0
  396. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source/pages/12.page +135 -0
  397. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source-zh/deck.pptd +21 -0
  398. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source-zh/pages/01.page +124 -0
  399. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source-zh/pages/02.page +384 -0
  400. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source-zh/pages/03.page +479 -0
  401. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source-zh/pages/04.page +365 -0
  402. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source-zh/pages/05.page +817 -0
  403. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source-zh/pages/06.page +760 -0
  404. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source-zh/pages/07.page +576 -0
  405. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source-zh/pages/08.page +295 -0
  406. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source-zh/pages/09.page +341 -0
  407. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source-zh/pages/10.page +547 -0
  408. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source-zh/pages/11.page +575 -0
  409. package/skills/dsh-ppt/references/editorial/dsh-editorial-notebook/source-zh/pages/12.page +135 -0
  410. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/design.md +61 -0
  411. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/metadata.json +3119 -0
  412. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/pages/01.jpg +0 -0
  413. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/pages/02.jpg +0 -0
  414. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/pages/03.jpg +0 -0
  415. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/pages/04.jpg +0 -0
  416. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/pages/05.jpg +0 -0
  417. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/pages/06.jpg +0 -0
  418. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/pages/07.jpg +0 -0
  419. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/pages/08.jpg +0 -0
  420. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/pages/09.jpg +0 -0
  421. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/pages/10.jpg +0 -0
  422. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/pages/11.jpg +0 -0
  423. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/pages/12.jpg +0 -0
  424. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source/deck.pptd +21 -0
  425. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source/pages/01.page +117 -0
  426. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source/pages/02.page +382 -0
  427. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source/pages/03.page +479 -0
  428. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source/pages/04.page +817 -0
  429. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source/pages/05.page +760 -0
  430. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source/pages/06.page +295 -0
  431. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source/pages/07.page +365 -0
  432. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source/pages/08.page +576 -0
  433. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source/pages/09.page +408 -0
  434. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source/pages/10.page +547 -0
  435. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source/pages/11.page +575 -0
  436. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source/pages/12.page +86 -0
  437. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source-zh/deck.pptd +21 -0
  438. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source-zh/pages/01.page +117 -0
  439. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source-zh/pages/02.page +384 -0
  440. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source-zh/pages/03.page +479 -0
  441. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source-zh/pages/04.page +817 -0
  442. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source-zh/pages/05.page +760 -0
  443. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source-zh/pages/06.page +295 -0
  444. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source-zh/pages/07.page +365 -0
  445. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source-zh/pages/08.page +576 -0
  446. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source-zh/pages/09.page +408 -0
  447. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source-zh/pages/10.page +547 -0
  448. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source-zh/pages/11.page +575 -0
  449. package/skills/dsh-ppt/references/editorial/dsh-soft-editorial/source-zh/pages/12.page +86 -0
  450. package/skills/dsh-ppt/references/pptd.md +55 -0
  451. package/skills/dsh-ppt/references/promotion/dsh-broadside/design.md +53 -0
  452. package/skills/dsh-ppt/references/promotion/dsh-broadside/metadata.json +2329 -0
  453. package/skills/dsh-ppt/references/promotion/dsh-broadside/pages/01.jpg +0 -0
  454. package/skills/dsh-ppt/references/promotion/dsh-broadside/pages/02.jpg +0 -0
  455. package/skills/dsh-ppt/references/promotion/dsh-broadside/pages/03.jpg +0 -0
  456. package/skills/dsh-ppt/references/promotion/dsh-broadside/pages/04.jpg +0 -0
  457. package/skills/dsh-ppt/references/promotion/dsh-broadside/pages/05.jpg +0 -0
  458. package/skills/dsh-ppt/references/promotion/dsh-broadside/pages/06.jpg +0 -0
  459. package/skills/dsh-ppt/references/promotion/dsh-broadside/pages/07.jpg +0 -0
  460. package/skills/dsh-ppt/references/promotion/dsh-broadside/pages/08.jpg +0 -0
  461. package/skills/dsh-ppt/references/promotion/dsh-broadside/pages/09.jpg +0 -0
  462. package/skills/dsh-ppt/references/promotion/dsh-broadside/pages/10.jpg +0 -0
  463. package/skills/dsh-ppt/references/promotion/dsh-broadside/pages/11.jpg +0 -0
  464. package/skills/dsh-ppt/references/promotion/dsh-broadside/pages/12.jpg +0 -0
  465. package/skills/dsh-ppt/references/promotion/dsh-broadside/source/deck.pptd +21 -0
  466. package/skills/dsh-ppt/references/promotion/dsh-broadside/source/pages/01.page +72 -0
  467. package/skills/dsh-ppt/references/promotion/dsh-broadside/source/pages/02.page +156 -0
  468. package/skills/dsh-ppt/references/promotion/dsh-broadside/source/pages/03.page +350 -0
  469. package/skills/dsh-ppt/references/promotion/dsh-broadside/source/pages/04.page +210 -0
  470. package/skills/dsh-ppt/references/promotion/dsh-broadside/source/pages/05.page +436 -0
  471. package/skills/dsh-ppt/references/promotion/dsh-broadside/source/pages/06.page +420 -0
  472. package/skills/dsh-ppt/references/promotion/dsh-broadside/source/pages/07.page +480 -0
  473. package/skills/dsh-ppt/references/promotion/dsh-broadside/source/pages/08.page +294 -0
  474. package/skills/dsh-ppt/references/promotion/dsh-broadside/source/pages/09.page +210 -0
  475. package/skills/dsh-ppt/references/promotion/dsh-broadside/source/pages/10.page +392 -0
  476. package/skills/dsh-ppt/references/promotion/dsh-broadside/source/pages/11.page +560 -0
  477. package/skills/dsh-ppt/references/promotion/dsh-broadside/source/pages/12.page +58 -0
  478. package/skills/dsh-ppt/references/promotion/dsh-broadside/source-zh/deck.pptd +21 -0
  479. package/skills/dsh-ppt/references/promotion/dsh-broadside/source-zh/pages/01.page +72 -0
  480. package/skills/dsh-ppt/references/promotion/dsh-broadside/source-zh/pages/02.page +156 -0
  481. package/skills/dsh-ppt/references/promotion/dsh-broadside/source-zh/pages/03.page +350 -0
  482. package/skills/dsh-ppt/references/promotion/dsh-broadside/source-zh/pages/04.page +210 -0
  483. package/skills/dsh-ppt/references/promotion/dsh-broadside/source-zh/pages/05.page +436 -0
  484. package/skills/dsh-ppt/references/promotion/dsh-broadside/source-zh/pages/06.page +420 -0
  485. package/skills/dsh-ppt/references/promotion/dsh-broadside/source-zh/pages/07.page +480 -0
  486. package/skills/dsh-ppt/references/promotion/dsh-broadside/source-zh/pages/08.page +294 -0
  487. package/skills/dsh-ppt/references/promotion/dsh-broadside/source-zh/pages/09.page +210 -0
  488. package/skills/dsh-ppt/references/promotion/dsh-broadside/source-zh/pages/10.page +392 -0
  489. package/skills/dsh-ppt/references/promotion/dsh-broadside/source-zh/pages/11.page +560 -0
  490. package/skills/dsh-ppt/references/promotion/dsh-broadside/source-zh/pages/12.page +58 -0
  491. package/skills/dsh-ppt/references/promotion/dsh-playful/design.md +61 -0
  492. package/skills/dsh-ppt/references/promotion/dsh-playful/metadata.json +3070 -0
  493. package/skills/dsh-ppt/references/promotion/dsh-playful/pages/01.jpg +0 -0
  494. package/skills/dsh-ppt/references/promotion/dsh-playful/pages/02.jpg +0 -0
  495. package/skills/dsh-ppt/references/promotion/dsh-playful/pages/03.jpg +0 -0
  496. package/skills/dsh-ppt/references/promotion/dsh-playful/pages/04.jpg +0 -0
  497. package/skills/dsh-ppt/references/promotion/dsh-playful/pages/05.jpg +0 -0
  498. package/skills/dsh-ppt/references/promotion/dsh-playful/pages/06.jpg +0 -0
  499. package/skills/dsh-ppt/references/promotion/dsh-playful/pages/07.jpg +0 -0
  500. package/skills/dsh-ppt/references/promotion/dsh-playful/pages/08.jpg +0 -0
  501. package/skills/dsh-ppt/references/promotion/dsh-playful/pages/09.jpg +0 -0
  502. package/skills/dsh-ppt/references/promotion/dsh-playful/pages/10.jpg +0 -0
  503. package/skills/dsh-ppt/references/promotion/dsh-playful/pages/11.jpg +0 -0
  504. package/skills/dsh-ppt/references/promotion/dsh-playful/pages/12.jpg +0 -0
  505. package/skills/dsh-ppt/references/promotion/dsh-playful/source/deck.pptd +21 -0
  506. package/skills/dsh-ppt/references/promotion/dsh-playful/source/pages/01.page +101 -0
  507. package/skills/dsh-ppt/references/promotion/dsh-playful/source/pages/02.page +410 -0
  508. package/skills/dsh-ppt/references/promotion/dsh-playful/source/pages/03.page +436 -0
  509. package/skills/dsh-ppt/references/promotion/dsh-playful/source/pages/04.page +845 -0
  510. package/skills/dsh-ppt/references/promotion/dsh-playful/source/pages/05.page +579 -0
  511. package/skills/dsh-ppt/references/promotion/dsh-playful/source/pages/06.page +367 -0
  512. package/skills/dsh-ppt/references/promotion/dsh-playful/source/pages/07.page +519 -0
  513. package/skills/dsh-ppt/references/promotion/dsh-playful/source/pages/08.page +323 -0
  514. package/skills/dsh-ppt/references/promotion/dsh-playful/source/pages/09.page +604 -0
  515. package/skills/dsh-ppt/references/promotion/dsh-playful/source/pages/10.page +575 -0
  516. package/skills/dsh-ppt/references/promotion/dsh-playful/source/pages/11.page +603 -0
  517. package/skills/dsh-ppt/references/promotion/dsh-playful/source/pages/12.page +86 -0
  518. package/skills/dsh-ppt/references/promotion/dsh-playful/source-zh/deck.pptd +21 -0
  519. package/skills/dsh-ppt/references/promotion/dsh-playful/source-zh/pages/01.page +100 -0
  520. package/skills/dsh-ppt/references/promotion/dsh-playful/source-zh/pages/02.page +410 -0
  521. package/skills/dsh-ppt/references/promotion/dsh-playful/source-zh/pages/03.page +436 -0
  522. package/skills/dsh-ppt/references/promotion/dsh-playful/source-zh/pages/04.page +845 -0
  523. package/skills/dsh-ppt/references/promotion/dsh-playful/source-zh/pages/05.page +579 -0
  524. package/skills/dsh-ppt/references/promotion/dsh-playful/source-zh/pages/06.page +367 -0
  525. package/skills/dsh-ppt/references/promotion/dsh-playful/source-zh/pages/07.page +519 -0
  526. package/skills/dsh-ppt/references/promotion/dsh-playful/source-zh/pages/08.page +323 -0
  527. package/skills/dsh-ppt/references/promotion/dsh-playful/source-zh/pages/09.page +604 -0
  528. package/skills/dsh-ppt/references/promotion/dsh-playful/source-zh/pages/10.page +575 -0
  529. package/skills/dsh-ppt/references/promotion/dsh-playful/source-zh/pages/11.page +603 -0
  530. package/skills/dsh-ppt/references/promotion/dsh-playful/source-zh/pages/12.page +86 -0
  531. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/design.md +61 -0
  532. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/metadata.json +3203 -0
  533. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/pages/01.jpg +0 -0
  534. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/pages/02.jpg +0 -0
  535. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/pages/03.jpg +0 -0
  536. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/pages/04.jpg +0 -0
  537. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/pages/05.jpg +0 -0
  538. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/pages/06.jpg +0 -0
  539. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/pages/07.jpg +0 -0
  540. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/pages/08.jpg +0 -0
  541. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/pages/09.jpg +0 -0
  542. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/pages/10.jpg +0 -0
  543. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/pages/11.jpg +0 -0
  544. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/pages/12.jpg +0 -0
  545. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source/deck.pptd +21 -0
  546. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source/pages/01.page +173 -0
  547. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source/pages/02.page +424 -0
  548. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source/pages/03.page +450 -0
  549. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source/pages/04.page +593 -0
  550. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source/pages/05.page +521 -0
  551. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source/pages/06.page +533 -0
  552. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source/pages/07.page +618 -0
  553. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source/pages/08.page +381 -0
  554. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source/pages/09.page +337 -0
  555. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source/pages/10.page +407 -0
  556. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source/pages/11.page +617 -0
  557. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source/pages/12.page +145 -0
  558. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source-zh/deck.pptd +21 -0
  559. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source-zh/pages/01.page +173 -0
  560. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source-zh/pages/02.page +424 -0
  561. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source-zh/pages/03.page +450 -0
  562. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source-zh/pages/04.page +593 -0
  563. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source-zh/pages/05.page +521 -0
  564. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source-zh/pages/06.page +533 -0
  565. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source-zh/pages/07.page +618 -0
  566. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source-zh/pages/08.page +381 -0
  567. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source-zh/pages/09.page +337 -0
  568. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source-zh/pages/10.page +407 -0
  569. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source-zh/pages/11.page +617 -0
  570. package/skills/dsh-ppt/references/promotion/dsh-sakura-chroma/source-zh/pages/12.page +145 -0
  571. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/design.md +122 -0
  572. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/metadata.json +1659 -0
  573. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/pages/01.jpg +0 -0
  574. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/pages/02.jpg +0 -0
  575. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/pages/03.jpg +0 -0
  576. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/pages/04.jpg +0 -0
  577. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/pages/05.jpg +0 -0
  578. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/pages/06.jpg +0 -0
  579. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/pages/07.jpg +0 -0
  580. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/pages/08.jpg +0 -0
  581. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/pages/09.jpg +0 -0
  582. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/pages/10.jpg +0 -0
  583. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/pages/11.jpg +0 -0
  584. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/pages/12.jpg +0 -0
  585. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source/deck.pptd +105 -0
  586. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source/pages/01.page +499 -0
  587. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source/pages/02.page +499 -0
  588. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source/pages/03.page +577 -0
  589. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source/pages/04.page +408 -0
  590. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source/pages/05.page +660 -0
  591. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source/pages/06.page +641 -0
  592. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source/pages/07.page +415 -0
  593. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source/pages/08.page +606 -0
  594. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source/pages/09.page +567 -0
  595. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source/pages/10.page +595 -0
  596. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source/pages/11.page +555 -0
  597. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source/pages/12.page +895 -0
  598. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source-zh/deck.pptd +105 -0
  599. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source-zh/pages/01.page +499 -0
  600. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source-zh/pages/02.page +499 -0
  601. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source-zh/pages/03.page +577 -0
  602. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source-zh/pages/04.page +408 -0
  603. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source-zh/pages/05.page +660 -0
  604. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source-zh/pages/06.page +641 -0
  605. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source-zh/pages/07.page +415 -0
  606. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source-zh/pages/08.page +606 -0
  607. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source-zh/pages/09.page +567 -0
  608. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source-zh/pages/10.page +595 -0
  609. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source-zh/pages/11.page +555 -0
  610. package/skills/dsh-ppt/references/work/curated-modular-logistics-system/source-zh/pages/12.page +895 -0
  611. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/design.md +111 -0
  612. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/metadata.json +1712 -0
  613. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/pages/01.jpg +0 -0
  614. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/pages/02.jpg +0 -0
  615. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/pages/03.jpg +0 -0
  616. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/pages/04.jpg +0 -0
  617. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/pages/05.jpg +0 -0
  618. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/pages/06.jpg +0 -0
  619. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/pages/07.jpg +0 -0
  620. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/pages/08.jpg +0 -0
  621. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/pages/09.jpg +0 -0
  622. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/pages/10.jpg +0 -0
  623. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/pages/11.jpg +0 -0
  624. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/pages/12.jpg +0 -0
  625. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source/deck.pptd +93 -0
  626. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source/pages/01.page +395 -0
  627. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source/pages/02.page +574 -0
  628. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source/pages/03.page +307 -0
  629. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source/pages/04.page +359 -0
  630. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source/pages/05.page +443 -0
  631. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source/pages/06.page +437 -0
  632. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source/pages/07.page +181 -0
  633. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source/pages/08.page +557 -0
  634. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source/pages/09.page +337 -0
  635. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source/pages/10.page +732 -0
  636. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source/pages/11.page +589 -0
  637. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source/pages/12.page +385 -0
  638. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source-zh/deck.pptd +93 -0
  639. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source-zh/pages/01.page +395 -0
  640. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source-zh/pages/02.page +574 -0
  641. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source-zh/pages/03.page +307 -0
  642. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source-zh/pages/04.page +359 -0
  643. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source-zh/pages/05.page +443 -0
  644. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source-zh/pages/06.page +437 -0
  645. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source-zh/pages/07.page +181 -0
  646. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source-zh/pages/08.page +557 -0
  647. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source-zh/pages/09.page +337 -0
  648. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source-zh/pages/10.page +732 -0
  649. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source-zh/pages/11.page +589 -0
  650. package/skills/dsh-ppt/references/work/curated-nordic-operating-report/source-zh/pages/12.page +385 -0
  651. package/skills/dsh-ppt/references/work/dsh-editorial-forest/design.md +61 -0
  652. package/skills/dsh-ppt/references/work/dsh-editorial-forest/metadata.json +3338 -0
  653. package/skills/dsh-ppt/references/work/dsh-editorial-forest/pages/01.jpg +0 -0
  654. package/skills/dsh-ppt/references/work/dsh-editorial-forest/pages/02.jpg +0 -0
  655. package/skills/dsh-ppt/references/work/dsh-editorial-forest/pages/03.jpg +0 -0
  656. package/skills/dsh-ppt/references/work/dsh-editorial-forest/pages/04.jpg +0 -0
  657. package/skills/dsh-ppt/references/work/dsh-editorial-forest/pages/05.jpg +0 -0
  658. package/skills/dsh-ppt/references/work/dsh-editorial-forest/pages/06.jpg +0 -0
  659. package/skills/dsh-ppt/references/work/dsh-editorial-forest/pages/07.jpg +0 -0
  660. package/skills/dsh-ppt/references/work/dsh-editorial-forest/pages/08.jpg +0 -0
  661. package/skills/dsh-ppt/references/work/dsh-editorial-forest/pages/09.jpg +0 -0
  662. package/skills/dsh-ppt/references/work/dsh-editorial-forest/pages/10.jpg +0 -0
  663. package/skills/dsh-ppt/references/work/dsh-editorial-forest/pages/11.jpg +0 -0
  664. package/skills/dsh-ppt/references/work/dsh-editorial-forest/pages/12.jpg +0 -0
  665. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source/deck.pptd +21 -0
  666. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source/pages/01.page +87 -0
  667. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source/pages/02.page +382 -0
  668. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source/pages/03.page +760 -0
  669. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source/pages/04.page +718 -0
  670. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source/pages/05.page +479 -0
  671. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source/pages/06.page +576 -0
  672. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source/pages/07.page +551 -0
  673. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source/pages/08.page +295 -0
  674. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source/pages/09.page +811 -0
  675. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source/pages/10.page +547 -0
  676. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source/pages/11.page +575 -0
  677. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source/pages/12.page +86 -0
  678. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source-zh/deck.pptd +21 -0
  679. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source-zh/pages/01.page +87 -0
  680. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source-zh/pages/02.page +382 -0
  681. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source-zh/pages/03.page +760 -0
  682. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source-zh/pages/04.page +718 -0
  683. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source-zh/pages/05.page +479 -0
  684. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source-zh/pages/06.page +576 -0
  685. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source-zh/pages/07.page +551 -0
  686. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source-zh/pages/08.page +295 -0
  687. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source-zh/pages/09.page +811 -0
  688. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source-zh/pages/10.page +547 -0
  689. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source-zh/pages/11.page +575 -0
  690. package/skills/dsh-ppt/references/work/dsh-editorial-forest/source-zh/pages/12.page +86 -0
  691. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/design.md +61 -0
  692. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/metadata.json +3147 -0
  693. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/pages/01.jpg +0 -0
  694. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/pages/02.jpg +0 -0
  695. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/pages/03.jpg +0 -0
  696. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/pages/04.jpg +0 -0
  697. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/pages/05.jpg +0 -0
  698. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/pages/06.jpg +0 -0
  699. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/pages/07.jpg +0 -0
  700. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/pages/08.jpg +0 -0
  701. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/pages/09.jpg +0 -0
  702. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/pages/10.jpg +0 -0
  703. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/pages/11.jpg +0 -0
  704. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/pages/12.jpg +0 -0
  705. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source/deck.pptd +21 -0
  706. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source/pages/01.page +390 -0
  707. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source/pages/02.page +1082 -0
  708. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source/pages/03.page +1511 -0
  709. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source/pages/04.page +1227 -0
  710. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source/pages/05.page +1517 -0
  711. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source/pages/06.page +1460 -0
  712. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source/pages/07.page +1276 -0
  713. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source/pages/08.page +1039 -0
  714. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source/pages/09.page +995 -0
  715. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source/pages/10.page +1275 -0
  716. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source/pages/11.page +1275 -0
  717. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source/pages/12.page +125 -0
  718. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source-zh/deck.pptd +21 -0
  719. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source-zh/pages/01.page +390 -0
  720. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source-zh/pages/02.page +1084 -0
  721. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source-zh/pages/03.page +1511 -0
  722. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source-zh/pages/04.page +1227 -0
  723. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source-zh/pages/05.page +1517 -0
  724. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source-zh/pages/06.page +1460 -0
  725. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source-zh/pages/07.page +1276 -0
  726. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source-zh/pages/08.page +1041 -0
  727. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source-zh/pages/09.page +995 -0
  728. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source-zh/pages/10.page +1275 -0
  729. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source-zh/pages/11.page +1275 -0
  730. package/skills/dsh-ppt/references/work/dsh-engineering-blueprint/source-zh/pages/12.page +125 -0
@@ -0,0 +1,2173 @@
1
+ const MISPLACED_TEXT_STYLE_FIELDS = new Set(["fontFamily", "fontSize", "bold", "italic", "color", "lineHeight", "letterSpacing", "wrap", "align", "verticalAlign", "textDirection", "style"]);
2
+ import { wrapTextLines } from "./text-wrap.js";
3
+ import { lstat, readFile, readdir, realpath } from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { createHash } from "node:crypto";
6
+ import yaml from "js-yaml";
7
+ import PptxGenJSImport from "pptxgenjs";
8
+ //#region lib/types/pptd-colors.js
9
+ /** Shared PPTD color normalization used by checking, preview, and PPTX export. */
10
+ /** Deterministic series palette used when a chart series omits an explicit color. */
11
+ const PPTD_CHART_SERIES_PALETTE = [
12
+ "#2563EB",
13
+ "#F59E0B",
14
+ "#10B981",
15
+ "#EF4444",
16
+ "#8B5CF6",
17
+ "#06B6D4"
18
+ ];
19
+ function record$1(value) {
20
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
21
+ }
22
+ function themeColors(project) {
23
+ return record$1(project.theme.colors) ?? {};
24
+ }
25
+ /** Resolve a literal or theme-referenced PPTD color without applying a silent fallback. */
26
+ function resolvePptdColor(project, value) {
27
+ let current = value;
28
+ const colors = themeColors(project);
29
+ for (let depth = 0; depth < 8 && typeof current === "string" && current.startsWith("$"); depth += 1) current = colors[current.slice(1)];
30
+ return typeof current === "string" && /^#[0-9a-f]{6}(?:[0-9a-f]{2})?$/iu.test(current) ? current : void 0;
31
+ }
32
+ /**
33
+ * Normalize chart-series colors from either color scalars or solid paint objects.
34
+ * Pie series may supply an array; unsupported paints and invalid colors return undefined.
35
+ */
36
+ function resolvePptdChartSeriesColors(project, value) {
37
+ if (value === void 0) return void 0;
38
+ const values = Array.isArray(value) ? value : [value];
39
+ if (values.length === 0) return void 0;
40
+ const resolved = values.map((item) => {
41
+ const paint = record$1(item);
42
+ return resolvePptdColor(project, paint === void 0 ? item : paint.type === "solid" ? paint.color : void 0);
43
+ });
44
+ return resolved.every((item) => item !== void 0) ? resolved : void 0;
45
+ }
46
+ //#endregion
47
+ //#region lib/types/text-layout.js
48
+ /** Deterministic text-box capacity estimates shared by template references and PPT renderers. */
49
+ const WIDTH_RESERVE = .95;
50
+ const DEFAULT_LINE_HEIGHT = 1.15;
51
+ function positive(value, fallback) {
52
+ return value !== void 0 && Number.isFinite(value) && value > 0 ? value : fallback;
53
+ }
54
+ function glyphWidth(character) {
55
+ if (/\p{Mark}/u.test(character)) return 0;
56
+ if (/\s/u.test(character)) return .33;
57
+ if (/^[ilI1|.,'`:;!]$/u.test(character)) return .3;
58
+ if (/^[mwMW@%&]$/u.test(character)) return .82;
59
+ if (/^[A-Z]$/u.test(character)) return .68;
60
+ if (/^[\u0000-\u00ff]$/u.test(character)) return .56;
61
+ if (/\p{Extended_Pictographic}/u.test(character)) return 1;
62
+ return 1;
63
+ }
64
+ function lineWidth(text, fontSize, letterSpacing, bold) {
65
+ const characters = Array.from(text);
66
+ const glyphs = characters.reduce((sum, character) => sum + glyphWidth(character), 0);
67
+ const spacing = Math.max(0, characters.length - 1) * letterSpacing;
68
+ return glyphs * fontSize * (bold ? 1.04 : 1) + spacing;
69
+ }
70
+ /**
71
+ * Estimate native text wrapping while retaining the authored font size.
72
+ * @param input - Text, box geometry, and effective text style in PowerPoint points.
73
+ * @returns Estimated line use and overflow state.
74
+ */
75
+ function measureTextLayout(input) {
76
+ const fontSize = positive(input.fontSize, 18);
77
+ const lineHeight = positive(input.lineHeight, DEFAULT_LINE_HEIGHT);
78
+ const letterSpacing = typeof input.letterSpacing === "number" && Number.isFinite(input.letterSpacing) ? input.letterSpacing : 0;
79
+ const availableLineWidth = Math.max(0, input.width) * WIDTH_RESERVE;
80
+ const paragraphWidths = input.text.length === 0 ? [] : input.text.split("\n").map((line) => lineWidth(line, fontSize, letterSpacing, input.bold === true));
81
+ const widestLine = Math.max(0, ...paragraphWidths);
82
+ const wrap = input.wrap !== false;
83
+ const lineCount = input.text.length === 0 ? 0 : wrapTextLines(input.text, availableLineWidth, text => lineWidth(text, fontSize, letterSpacing, input.bold === true), wrap).length;
84
+ const requiredHeight = lineCount * fontSize * lineHeight;
85
+ const maxLineCount = Math.max(0, Math.floor(Math.max(0, input.height) / (fontSize * lineHeight)));
86
+ const horizontalOverflow = !wrap && widestLine > availableLineWidth;
87
+ return {
88
+ lineCount,
89
+ maxLineCount,
90
+ requiredHeight,
91
+ availableLineWidth,
92
+ widestLine,
93
+ horizontalOverflow,
94
+ overflow: horizontalOverflow || lineCount > maxLineCount
95
+ };
96
+ }
97
+ /**
98
+ * Derive a conservative full-width character budget for an empty text region.
99
+ * @param width - Text-region width in PowerPoint points.
100
+ * @param height - Text-region height in PowerPoint points.
101
+ * @param fontSize - Intended font size in points.
102
+ * @param lineHeight - Line-height multiplier.
103
+ * @returns Recommended full-width character count.
104
+ */
105
+ function recommendedTextCapacity(width, height, fontSize, lineHeight = DEFAULT_LINE_HEIGHT) {
106
+ const size = positive(fontSize, 18);
107
+ const spacing = positive(lineHeight, DEFAULT_LINE_HEIGHT);
108
+ const charactersPerLine = Math.max(1, Math.floor(Math.max(0, width) * WIDTH_RESERVE / size));
109
+ const lines = Math.max(1, Math.floor(Math.max(0, height) / (size * spacing)));
110
+ return Math.max(1, Math.min(1e3, Math.floor(charactersPerLine * lines * .9)));
111
+ }
112
+ //#endregion
113
+ //#region lib/types/pptd.js
114
+ /** Local PPTD v2 parser, checker, loader, and native editable PPTX renderer. */
115
+ const PptxGenJS = typeof PptxGenJSImport === "function" ? PptxGenJSImport : PptxGenJSImport.default;
116
+ const POINTS_PER_INCH = 72;
117
+ const MAX_MANIFEST_BYTES = 512 * 1024;
118
+ const MAX_PAGE_BYTES = 2 * 1024 * 1024;
119
+ const MAX_ASSET_BYTES = 32 * 1024 * 1024;
120
+ const MAX_TOTAL_ASSET_BYTES = 256 * 1024 * 1024;
121
+ const MAX_PAGES = 200;
122
+ const MAX_ELEMENTS_PER_PAGE = 2e3;
123
+ function record(value) {
124
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
125
+ }
126
+ function string(value) {
127
+ return typeof value === "string" ? value : void 0;
128
+ }
129
+ function number(value) {
130
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
131
+ }
132
+ function boolean(value) {
133
+ return typeof value === "boolean" ? value : void 0;
134
+ }
135
+ const NATIVE_CHART_TYPES = new Set([
136
+ "bar",
137
+ "line",
138
+ "area",
139
+ "scatter",
140
+ "bubble",
141
+ "pie",
142
+ "radar"
143
+ ]);
144
+ const UNSUPPORTED_CHART_TYPES = new Set([
145
+ "candlestick",
146
+ "waterfall",
147
+ "heatmap",
148
+ "treemap",
149
+ "sunburst",
150
+ "sankey"
151
+ ]);
152
+ const NATIVE_SHAPE_NAMES = new Set(Object.values(new PptxGenJS().ShapeType));
153
+ const MANIFEST_FIELDS = new Set([
154
+ "version",
155
+ "title",
156
+ "size",
157
+ "template",
158
+ "theme",
159
+ "pages"
160
+ ]);
161
+ const TEMPLATE_FIELDS = new Set([
162
+ "id",
163
+ "name",
164
+ "sourceFile",
165
+ "sourceSha256"
166
+ ]);
167
+ const PAGE_FIELDS = new Set([
168
+ "pageType",
169
+ "templateReference",
170
+ "background",
171
+ "notes",
172
+ "elements"
173
+ ]);
174
+ const TEMPLATE_REFERENCE_FIELDS = new Set([
175
+ "sourceSlideNumber",
176
+ "rationale",
177
+ "contentRelationship"
178
+ ]);
179
+ const TEMPLATE_RELATIONSHIPS = new Set([
180
+ "statement",
181
+ "independent",
182
+ "comparison",
183
+ "process",
184
+ "timeline",
185
+ "overlap",
186
+ "data",
187
+ "generic"
188
+ ]);
189
+ const ELEMENT_BASE_FIELDS = [
190
+ "elementId",
191
+ "elementType",
192
+ "bounds"
193
+ ];
194
+ const ELEMENT_FIELDS = {
195
+ text: new Set([
196
+ ...ELEMENT_BASE_FIELDS,
197
+ "rotation",
198
+ "opacity",
199
+ "flip",
200
+ "content"
201
+ ]),
202
+ shape: new Set([
203
+ ...ELEMENT_BASE_FIELDS,
204
+ "rotation",
205
+ "opacity",
206
+ "flip",
207
+ "shapeName",
208
+ "adjustments",
209
+ "viewBox",
210
+ "path",
211
+ "fill",
212
+ "border",
213
+ "shadow"
214
+ ]),
215
+ line: new Set([
216
+ ...ELEMENT_BASE_FIELDS,
217
+ "rotation",
218
+ "opacity",
219
+ "flip",
220
+ "viewBox",
221
+ "points",
222
+ "curve",
223
+ "arrow",
224
+ "border",
225
+ "shadow"
226
+ ]),
227
+ image: new Set([
228
+ ...ELEMENT_BASE_FIELDS,
229
+ "rotation",
230
+ "opacity",
231
+ "flip",
232
+ "src",
233
+ "cropShape",
234
+ "fit",
235
+ "crop",
236
+ "border",
237
+ "shadow"
238
+ ]),
239
+ icon: new Set([
240
+ ...ELEMENT_BASE_FIELDS,
241
+ "rotation",
242
+ "opacity",
243
+ "flip",
244
+ "iconName",
245
+ "color",
246
+ "fill",
247
+ "border",
248
+ "shadow"
249
+ ]),
250
+ table: new Set([
251
+ ...ELEMENT_BASE_FIELDS,
252
+ "columnWidths",
253
+ "rowHeights",
254
+ "rows",
255
+ "style",
256
+ "fill",
257
+ "shadow"
258
+ ]),
259
+ chart: new Set([
260
+ ...ELEMENT_BASE_FIELDS,
261
+ "data",
262
+ "series",
263
+ "seriesDefaults",
264
+ "xAxis",
265
+ "yAxis",
266
+ "barWidth",
267
+ "barGap",
268
+ "categoryGap",
269
+ "spokeAxis",
270
+ "title",
271
+ "legend",
272
+ "dataLabels",
273
+ "fontFamily",
274
+ "fill",
275
+ "border",
276
+ "shadow"
277
+ ])
278
+ };
279
+ function unknownFields(value, allowed) {
280
+ return Object.keys(value).filter((key) => !allowed.has(key));
281
+ }
282
+ function compatibilitySummary(project) {
283
+ const summary = {
284
+ native: 0,
285
+ normalized: 0,
286
+ vectorFallback: 0,
287
+ rasterFallback: 0,
288
+ unsupported: 0
289
+ };
290
+ const recordLevel = (level) => {
291
+ if (level === "native") summary.native += 1;
292
+ else if (level === "normalized") summary.normalized += 1;
293
+ else if (level === "vector-fallback") summary.vectorFallback += 1;
294
+ else if (level === "raster-fallback") summary.rasterFallback += 1;
295
+ else summary.unsupported += 1;
296
+ };
297
+ for (const page of project.pages) for (const element of page.elements) {
298
+ const type = string(element.elementType);
299
+ if (type === "icon") {
300
+ recordLevel("normalized");
301
+ continue;
302
+ }
303
+ if (type === "shape" && element.shapeName === "custom") {
304
+ recordLevel("vector-fallback");
305
+ continue;
306
+ }
307
+ if (type === "line" && (string(element.curve) === "smooth" || (string(element.points)?.trim().split(/\s+/u).length ?? 0) > 2)) {
308
+ recordLevel("vector-fallback");
309
+ continue;
310
+ }
311
+ if (type === "image" && record(element.cropShape)?.shapeName === "custom") {
312
+ recordLevel("raster-fallback");
313
+ continue;
314
+ }
315
+ if (type === "chart") {
316
+ const chartTypes = (Array.isArray(element.series) ? element.series.map(record).filter((item) => item !== void 0) : []).map((item) => string(item.type)).filter((item) => item !== void 0);
317
+ if (chartTypes.some((item) => UNSUPPORTED_CHART_TYPES.has(item))) {
318
+ recordLevel("unsupported");
319
+ continue;
320
+ }
321
+ if (chartTypes.some((item) => !NATIVE_CHART_TYPES.has(item))) {
322
+ recordLevel("unsupported");
323
+ continue;
324
+ }
325
+ }
326
+ const fill = record(element.fill);
327
+ const content = record(element.content);
328
+ recordLevel(fill?.type === "gradient" || fill?.type === "image" || content?.gradient !== void 0 || content?.shadow !== void 0 || element.shadow !== void 0 || element.adjustments !== void 0 || element.crop !== void 0 || element.cropShape !== void 0 ? "normalized" : "native");
329
+ }
330
+ return summary;
331
+ }
332
+ function tuple(value, size) {
333
+ if (!Array.isArray(value) || value.length !== size) return void 0;
334
+ const values = value.map(number);
335
+ return values.every((item) => item !== void 0) ? values : void 0;
336
+ }
337
+ function safeProjectPath(value) {
338
+ if (value === "" || path.isAbsolute(value) || value.includes("\\")) return void 0;
339
+ const normalized = path.posix.normalize(value);
340
+ return normalized === ".." || normalized.startsWith("../") || normalized.startsWith("/") ? void 0 : normalized;
341
+ }
342
+ function parseYaml(content, file, issues) {
343
+ try {
344
+ const value = record(yaml.load(content, {
345
+ schema: yaml.JSON_SCHEMA,
346
+ json: true
347
+ }));
348
+ if (value !== void 0) return value;
349
+ issues.push({
350
+ code: "yaml-root",
351
+ severity: "error",
352
+ file,
353
+ message: `${file} 的 YAML 根节点必须是对象。`
354
+ });
355
+ } catch (error) {
356
+ issues.push({
357
+ code: "yaml-syntax",
358
+ severity: "error",
359
+ file,
360
+ message: `${file} 无法解析:${error instanceof Error ? error.message : String(error)}`
361
+ });
362
+ }
363
+ }
364
+ /** Parse a bounded in-memory PPTD v2 project into a renderer-independent AST. */
365
+ function parsePptdProject(source) {
366
+ const issues = [...source.issues ?? []];
367
+ const manifest = parseYaml(source.manifest, source.entryName, issues) ?? {};
368
+ for (const field of unknownFields(manifest, MANIFEST_FIELDS)) issues.push({
369
+ code: "unknown-field",
370
+ severity: "error",
371
+ file: source.entryName,
372
+ message: `PPTD 包含未知字段 ${field}。`
373
+ });
374
+ if (manifest.version !== "v2") issues.push({
375
+ code: "version",
376
+ severity: "error",
377
+ file: source.entryName,
378
+ message: "PPTD version 必须为 v2。"
379
+ });
380
+ const size = tuple(manifest.size, 2);
381
+ const pageWidth = size?.[0];
382
+ const pageHeight = size?.[1];
383
+ if (pageWidth === void 0 || pageHeight === void 0 || pageWidth <= 0 || pageHeight <= 0) issues.push({
384
+ code: "page-size",
385
+ severity: "error",
386
+ file: source.entryName,
387
+ message: "PPTD size 必须是两个正数。"
388
+ });
389
+ const template = manifest.template === void 0 ? void 0 : record(manifest.template);
390
+ if (manifest.template !== void 0 && template === void 0) issues.push({
391
+ code: "template",
392
+ severity: "error",
393
+ file: source.entryName,
394
+ message: "PPTD template 必须是对象。"
395
+ });
396
+ if (template !== void 0) {
397
+ for (const field of unknownFields(template, TEMPLATE_FIELDS)) issues.push({
398
+ code: "unknown-field",
399
+ severity: "error",
400
+ file: source.entryName,
401
+ message: `PPTD template 包含未知字段 ${field}。`
402
+ });
403
+ if (typeof template.id !== "string" || typeof template.name !== "string") issues.push({
404
+ code: "template",
405
+ severity: "error",
406
+ file: source.entryName,
407
+ message: "PPTD template.id 和 template.name 必须是字符串。"
408
+ });
409
+ if (template.sourceFile !== void 0 && typeof template.sourceFile !== "string") issues.push({
410
+ code: "template",
411
+ severity: "error",
412
+ file: source.entryName,
413
+ message: "PPTD template.sourceFile 必须是字符串。"
414
+ });
415
+ if (template.sourceSha256 !== void 0 && (typeof template.sourceSha256 !== "string" || !/^[0-9a-f]{64}$/iu.test(template.sourceSha256))) issues.push({
416
+ code: "template",
417
+ severity: "error",
418
+ file: source.entryName,
419
+ message: "PPTD template.sourceSha256 必须是 SHA-256。"
420
+ });
421
+ }
422
+ const pageRefs = Array.isArray(manifest.pages) ? manifest.pages : [];
423
+ if (!Array.isArray(manifest.pages) || pageRefs.length === 0 || pageRefs.length > MAX_PAGES) issues.push({
424
+ code: "pages",
425
+ severity: "error",
426
+ file: source.entryName,
427
+ message: `PPTD pages 必须包含 1 到 ${MAX_PAGES} 个页面路径。`
428
+ });
429
+ const pages = [];
430
+ const seen = /* @__PURE__ */ new Set();
431
+ for (const [index, rawRef] of pageRefs.slice(0, MAX_PAGES).entries()) {
432
+ const ref = typeof rawRef === "string" ? safeProjectPath(rawRef) : void 0;
433
+ if (ref === void 0 || !ref.endsWith(".page")) {
434
+ issues.push({
435
+ code: "page-path",
436
+ severity: "error",
437
+ page: index + 1,
438
+ message: `第 ${index + 1} 个页面路径无效。`
439
+ });
440
+ continue;
441
+ }
442
+ if (seen.has(ref)) {
443
+ issues.push({
444
+ code: "duplicate-page",
445
+ severity: "error",
446
+ file: ref,
447
+ page: index + 1,
448
+ message: `页面 ${ref} 被重复引用。`
449
+ });
450
+ continue;
451
+ }
452
+ seen.add(ref);
453
+ const content = source.pages.get(ref);
454
+ if (content === void 0) {
455
+ issues.push({
456
+ code: "missing-page",
457
+ severity: "error",
458
+ file: ref,
459
+ page: index + 1,
460
+ message: `找不到页面文件 ${ref}。`
461
+ });
462
+ continue;
463
+ }
464
+ const parsed = parseYaml(content, ref, issues);
465
+ if (parsed === void 0) continue;
466
+ for (const field of unknownFields(parsed, PAGE_FIELDS)) issues.push({
467
+ code: "unknown-field",
468
+ severity: "error",
469
+ file: ref,
470
+ page: index + 1,
471
+ message: `页面包含未知字段 ${field}。`
472
+ });
473
+ const elements = Array.isArray(parsed.elements) ? parsed.elements.map(record).filter((item) => item !== void 0) : [];
474
+ if (!Array.isArray(parsed.elements) || elements.length > MAX_ELEMENTS_PER_PAGE) issues.push({
475
+ code: "elements",
476
+ severity: "error",
477
+ file: ref,
478
+ page: index + 1,
479
+ message: `页面 elements 必须是数组且不超过 ${MAX_ELEMENTS_PER_PAGE} 个元素。`
480
+ });
481
+ const background = record(parsed.background);
482
+ const templateReference = parsed.templateReference === void 0 ? void 0 : record(parsed.templateReference);
483
+ if (parsed.templateReference !== void 0 && templateReference === void 0) issues.push({
484
+ code: "template-reference",
485
+ severity: "error",
486
+ file: ref,
487
+ page: index + 1,
488
+ message: "页面 templateReference 必须是对象。"
489
+ });
490
+ if (templateReference !== void 0) {
491
+ for (const field of unknownFields(templateReference, TEMPLATE_REFERENCE_FIELDS)) issues.push({
492
+ code: "unknown-field",
493
+ severity: "error",
494
+ file: ref,
495
+ page: index + 1,
496
+ message: `页面 templateReference 包含未知字段 ${field}。`
497
+ });
498
+ if (!Number.isInteger(templateReference.sourceSlideNumber) || Number(templateReference.sourceSlideNumber) <= 0) issues.push({
499
+ code: "template-reference",
500
+ severity: "error",
501
+ file: ref,
502
+ page: index + 1,
503
+ message: "页面 templateReference.sourceSlideNumber 必须是正整数。"
504
+ });
505
+ if (typeof templateReference.rationale !== "string" || templateReference.rationale.trim() === "") issues.push({
506
+ code: "template-reference",
507
+ severity: "error",
508
+ file: ref,
509
+ page: index + 1,
510
+ message: "页面 templateReference.rationale 必须说明源页选择理由。"
511
+ });
512
+ if (templateReference.contentRelationship !== void 0 && (typeof templateReference.contentRelationship !== "string" || !TEMPLATE_RELATIONSHIPS.has(templateReference.contentRelationship))) issues.push({
513
+ code: "template-reference",
514
+ severity: "error",
515
+ file: ref,
516
+ page: index + 1,
517
+ message: "页面 templateReference.contentRelationship 必须是受支持的内容关系。"
518
+ });
519
+ }
520
+ for (const element of elements) {
521
+ const type = string(element.elementType);
522
+ const allowed = type === void 0 ? void 0 : ELEMENT_FIELDS[type];
523
+ if (allowed === void 0) continue;
524
+ for (const field of unknownFields(element, allowed)) issues.push({
525
+ code: type === "text" && MISPLACED_TEXT_STYLE_FIELDS.has(field) ? "misplaced-text-style" : "unknown-field",
526
+ severity: "error",
527
+ file: ref,
528
+ page: index + 1,
529
+ ...typeof element.elementId === "string" ? { elementId: element.elementId } : {},
530
+ message: type === "text" && MISPLACED_TEXT_STYLE_FIELDS.has(field) ? `文本属性 ${field} 应放在 content 内,请修正 YAML 缩进。` : `元素包含未知字段 ${field}。`
531
+ });
532
+ }
533
+ pages.push({
534
+ file: ref,
535
+ ...typeof parsed.pageType === "string" ? { pageType: parsed.pageType } : {},
536
+ ...templateReference === void 0 || !Number.isInteger(templateReference.sourceSlideNumber) || typeof templateReference.rationale !== "string" ? {} : { templateReference: {
537
+ sourceSlideNumber: Number(templateReference.sourceSlideNumber),
538
+ rationale: templateReference.rationale,
539
+ ...typeof templateReference.contentRelationship === "string" && TEMPLATE_RELATIONSHIPS.has(templateReference.contentRelationship) ? { contentRelationship: templateReference.contentRelationship } : {}
540
+ } },
541
+ ...background === void 0 ? {} : { background },
542
+ notes: typeof parsed.notes === "string" ? parsed.notes : "",
543
+ elements: elements.slice(0, MAX_ELEMENTS_PER_PAGE)
544
+ });
545
+ }
546
+ return {
547
+ source,
548
+ title: typeof manifest.title === "string" ? manifest.title : path.basename(source.entryName, ".pptd"),
549
+ width: pageWidth ?? 960,
550
+ height: pageHeight ?? 540,
551
+ ...template === void 0 ? {} : { template },
552
+ theme: record(manifest.theme) ?? {},
553
+ pages,
554
+ parseIssues: issues
555
+ };
556
+ }
557
+ function projectDigest(project) {
558
+ const hash = createHash("sha256").update(project.source.manifest);
559
+ for (const page of project.pages) hash.update(page.file).update(project.source.pages.get(page.file) ?? "");
560
+ for (const asset of [...project.source.assets.values()].sort((left, right) => left.path.localeCompare(right.path))) hash.update(asset.path).update(asset.sha256);
561
+ return hash.digest("hex");
562
+ }
563
+ function themeMap(project, key) {
564
+ return record(project.theme[key]) ?? {};
565
+ }
566
+ function themeReferenceIssue(project, value, mapName, file, page, elementId) {
567
+ if (typeof value !== "string" || !value.startsWith("$")) return void 0;
568
+ const key = value.slice(1);
569
+ if (key !== "" && key in themeMap(project, mapName)) return void 0;
570
+ return {
571
+ code: "invalid-theme",
572
+ severity: "error",
573
+ file,
574
+ ...page === void 0 ? {} : { page },
575
+ ...elementId === void 0 ? {} : { elementId },
576
+ message: `主题引用 ${value} 不存在于 theme.${mapName}。`
577
+ };
578
+ }
579
+ function colorThemeIssues(project, value, file, page, elementId) {
580
+ const issues = [];
581
+ const visited = /* @__PURE__ */ new WeakSet();
582
+ const visit = (current, field) => {
583
+ if (typeof current === "string") {
584
+ if (field === "color" || field === "backgroundColor" || field === "lineColor" || field === "areaColor" || field === "fill") {
585
+ const issue = themeReferenceIssue(project, current, "colors", file, page, elementId);
586
+ if (issue !== void 0) issues.push(issue);
587
+ }
588
+ return;
589
+ }
590
+ if (Array.isArray(current)) {
591
+ if (visited.has(current)) return;
592
+ visited.add(current);
593
+ for (const item of current) visit(item, field);
594
+ return;
595
+ }
596
+ const object = record(current);
597
+ if (object === void 0) return;
598
+ if (visited.has(object)) return;
599
+ visited.add(object);
600
+ for (const [key, child] of Object.entries(object)) visit(child, key === "fill" ? "fill" : key);
601
+ };
602
+ visit(value);
603
+ return issues;
604
+ }
605
+ function themeColorChainIssues(project) {
606
+ const colors = themeMap(project, "colors");
607
+ const issues = [];
608
+ const reportedCycles = /* @__PURE__ */ new Set();
609
+ const reportedInvalidTerminals = /* @__PURE__ */ new Set();
610
+ for (const start of Object.keys(colors)) {
611
+ const path = [];
612
+ let key = start;
613
+ while (true) {
614
+ const cycleIndex = path.indexOf(key);
615
+ if (cycleIndex >= 0) {
616
+ const cycle = path.slice(cycleIndex);
617
+ const signature = [...cycle].sort().join("\0");
618
+ if (!reportedCycles.has(signature)) {
619
+ reportedCycles.add(signature);
620
+ issues.push({
621
+ code: "invalid-theme",
622
+ severity: "error",
623
+ file: project.source.entryName,
624
+ message: `theme.colors 存在循环引用:${[...cycle, key].map((item) => `$${item}`).join(" -> ")}。`
625
+ });
626
+ }
627
+ break;
628
+ }
629
+ path.push(key);
630
+ const value = colors[key];
631
+ if (typeof value !== "string" || !value.startsWith("$")) {
632
+ if (key !== start && (typeof value !== "string" || !/^#[0-9a-f]{6}(?:[0-9a-f]{2})?$/iu.test(value))) {
633
+ if (!reportedInvalidTerminals.has(key)) {
634
+ reportedInvalidTerminals.add(key);
635
+ issues.push({
636
+ code: "invalid-theme",
637
+ severity: "error",
638
+ file: project.source.entryName,
639
+ message: `theme.colors.${start} 最终指向无效颜色 theme.colors.${key}。`
640
+ });
641
+ }
642
+ }
643
+ break;
644
+ }
645
+ const next = value.slice(1);
646
+ if (!(next in colors)) break;
647
+ key = next;
648
+ }
649
+ }
650
+ return issues;
651
+ }
652
+ function resolveThemeReference(value, map) {
653
+ if (typeof value !== "string" || !value.startsWith("$")) return value;
654
+ return map[value.slice(1)];
655
+ }
656
+ function resolveColorValue(project, value, fallback = "#000000") {
657
+ return resolvePptdColor(project, value) ?? fallback;
658
+ }
659
+ function colorOptions(project, value, opacity = 1) {
660
+ const resolved = resolveColorValue(project, value);
661
+ const alpha = resolved.length === 9 ? Number.parseInt(resolved.slice(7, 9), 16) / 255 : 1;
662
+ const transparency = Math.round((1 - Math.max(0, Math.min(1, alpha * opacity))) * 100);
663
+ return {
664
+ color: resolved.slice(1, 7).toUpperCase(),
665
+ ...transparency === 0 ? {} : { transparency }
666
+ };
667
+ }
668
+ function readableForeground(background) {
669
+ const red = Number.parseInt(background.slice(0, 2), 16) / 255;
670
+ const green = Number.parseInt(background.slice(2, 4), 16) / 255;
671
+ const blue = Number.parseInt(background.slice(4, 6), 16) / 255;
672
+ return red * .2126 + green * .7152 + blue * .0722 < .5 ? "E2E8F0" : "1F2937";
673
+ }
674
+ function textStyle(project, content) {
675
+ return {
676
+ ...record(resolveThemeReference(content.style, themeMap(project, "textStyles"))) ?? {},
677
+ ...content
678
+ };
679
+ }
680
+ function plainText(value) {
681
+ return value.replace(/<br\s*\/?\s*>/giu, "\n").replace(/<\/p\s*>/giu, "\n").replace(/<li(?:\s[^>]*)?>/giu, "• ").replace(/<\/li\s*>/giu, "\n").replace(/<[^>]+>/gu, "").replace(/&lt;/gu, "<").replace(/&gt;/gu, ">").replace(/&amp;/gu, "&").replace(/&quot;/gu, "\"").replace(/\n{3,}/gu, "\n\n").trimEnd();
682
+ }
683
+ function textLayout(project, element) {
684
+ // Fix structural errors before estimating layout with fallback styles.
685
+ if (unknownFields(element, ELEMENT_FIELDS.text).length > 0) return void 0;
686
+ const bounds = tuple(element.bounds, 4);
687
+ const content = record(element.content);
688
+ if (bounds === void 0 || content === void 0 || typeof content.text !== "string" || plainText(content.text).trim() === "") return void 0;
689
+ const style = textStyle(project, content);
690
+ const fontSize = number(style.fontSize) ?? 18;
691
+ const inlineSizes = Array.from(content.text.matchAll(/font-size\s*:\s*(\d+(?:\.\d+)?)px/giu), (match) => Number(match[1]));
692
+ const vertical = style.textDirection === "vertical";
693
+ const lineHeight = number(style.lineHeight);
694
+ const letterSpacing = number(style.letterSpacing);
695
+ const wrap = boolean(style.wrap);
696
+ return measureTextLayout({
697
+ text: plainText(content.text),
698
+ width: bounds[vertical ? 3 : 2] ?? 0,
699
+ height: bounds[vertical ? 2 : 3] ?? 0,
700
+ fontSize: Math.max(fontSize, ...inlineSizes),
701
+ bold: boolean(style.bold) === true || /<(?:b|strong)(?:\s|>)/iu.test(content.text),
702
+ ...lineHeight === void 0 ? {} : { lineHeight },
703
+ ...letterSpacing === void 0 ? {} : { letterSpacing },
704
+ ...wrap === void 0 ? {} : { wrap }
705
+ });
706
+ }
707
+ function localAssetPath(value) {
708
+ if (typeof value !== "string" || /^https?:\/\//iu.test(value)) return void 0;
709
+ return safeProjectPath(value);
710
+ }
711
+ function elementContext(page, element) {
712
+ return {
713
+ page,
714
+ ...typeof element.elementId === "string" ? { elementId: element.elementId } : {}
715
+ };
716
+ }
717
+ function compatibilityIssue(page, context, level, feature) {
718
+ const severity = level === "unsupported" ? "error" : "warning";
719
+ return {
720
+ code: `compatibility-${level}`,
721
+ severity,
722
+ file: page.file,
723
+ ...context,
724
+ message: `${feature} 的渲染兼容级别为 ${level}。`
725
+ };
726
+ }
727
+ function validTableGrid(element) {
728
+ const rows = Array.isArray(element.rows) ? element.rows : [];
729
+ const columnWidths = Array.isArray(element.columnWidths) ? element.columnWidths.map(number) : [];
730
+ const rowHeights = Array.isArray(element.rowHeights) ? element.rowHeights.map(number) : [];
731
+ const columnCount = columnWidths.length;
732
+ const rowCount = rowHeights.length;
733
+ if (rowCount === 0 || columnCount === 0 || rows.length !== rowCount) return false;
734
+ if (columnWidths.some((value) => value === void 0 || value < 0 || value > 1) || rowHeights.some((value) => value === void 0 || value < 0 || value > 1)) return false;
735
+ const nearOne = (values) => {
736
+ const total = values.reduce((sum, value) => sum + (value ?? 0), 0);
737
+ return Math.abs(total - 1) < .001;
738
+ };
739
+ if (!nearOne(columnWidths) || !nearOne(rowHeights)) return false;
740
+ const occupied = Array.from({ length: rowCount }, () => Array.from({ length: columnCount }, () => false));
741
+ for (const [rowIndex, rawRow] of rows.entries()) {
742
+ if (!Array.isArray(rawRow)) return false;
743
+ let columnIndex = 0;
744
+ for (const rawCell of rawRow) {
745
+ while (columnIndex < columnCount && occupied[rowIndex]?.[columnIndex] === true) columnIndex += 1;
746
+ const cell = record(rawCell) ?? {};
747
+ const rowSpan = number(cell.rowSpan) ?? 1;
748
+ const colSpan = number(cell.colSpan) ?? 1;
749
+ if (!Number.isInteger(rowSpan) || !Number.isInteger(colSpan) || rowSpan < 1 || colSpan < 1 || rowIndex + rowSpan > rowCount || columnIndex + colSpan > columnCount) return false;
750
+ for (let row = rowIndex; row < rowIndex + rowSpan; row += 1) {
751
+ const occupiedRow = occupied[row];
752
+ if (occupiedRow === void 0) return false;
753
+ for (let column = columnIndex; column < columnIndex + colSpan; column += 1) {
754
+ if (occupiedRow[column] === true) return false;
755
+ occupiedRow[column] = true;
756
+ }
757
+ }
758
+ columnIndex += colSpan;
759
+ }
760
+ if (occupied[rowIndex]?.some((value) => !value) === true) return false;
761
+ }
762
+ return true;
763
+ }
764
+ function checkElement(project, page, pageNumber, element, ids) {
765
+ const issues = [];
766
+ const context = elementContext(pageNumber, element);
767
+ const id = string(element.elementId);
768
+ issues.push(...colorThemeIssues(project, element, page.file, pageNumber, id));
769
+ if (id === void 0 || id.trim() === "") issues.push({
770
+ code: "element-id",
771
+ severity: "error",
772
+ file: page.file,
773
+ ...context,
774
+ message: "元素缺少 elementId。"
775
+ });
776
+ else if (ids.has(id)) issues.push({
777
+ code: "duplicate-id",
778
+ severity: "error",
779
+ file: page.file,
780
+ ...context,
781
+ message: `元素 ID ${id} 重复。`
782
+ });
783
+ else ids.add(id);
784
+ const bounds = tuple(element.bounds, 4);
785
+ const [x = 0, y = 0, width = -1, height = -1] = bounds ?? [];
786
+ if (bounds === void 0 || width < 0 || height < 0) issues.push({
787
+ code: "bounds",
788
+ severity: "error",
789
+ file: page.file,
790
+ ...context,
791
+ message: "元素 bounds 必须是 [x, y, width, height]。"
792
+ });
793
+ else if (x < 0 || y < 0 || x + width > project.width + .01 || y + height > project.height + .01) issues.push({
794
+ code: "out-of-bounds",
795
+ severity: "error",
796
+ file: page.file,
797
+ ...context,
798
+ message: "元素超出 PPTD 页面边界。"
799
+ });
800
+ const type = string(element.elementType);
801
+ if (![
802
+ "text",
803
+ "shape",
804
+ "line",
805
+ "image",
806
+ "icon",
807
+ "table",
808
+ "chart"
809
+ ].includes(type ?? "")) {
810
+ issues.push({
811
+ code: "element-type",
812
+ severity: "error",
813
+ file: page.file,
814
+ ...context,
815
+ message: `不支持的 elementType:${type ?? "missing"}。`
816
+ });
817
+ return issues;
818
+ }
819
+ if (type === "text") {
820
+ const content = record(element.content);
821
+ const styleIssue = themeReferenceIssue(project, content?.style, "textStyles", page.file, pageNumber, id);
822
+ if (styleIssue !== void 0) issues.push(styleIssue);
823
+ if (content === void 0 || typeof content.text !== "string") issues.push({
824
+ code: "text-content",
825
+ severity: "error",
826
+ file: page.file,
827
+ ...context,
828
+ message: "文本元素需要 content.text。"
829
+ });
830
+ else {
831
+ const layout = textLayout(project, element);
832
+ if (layout?.overflow === true) {
833
+ const message = layout.horizontalOverflow ? `文本设置为不换行,但预计宽度 ${Math.ceil(layout.widestLine)}pt 超过文本框可用宽度 ${Math.floor(layout.availableLineWidth)}pt;请缩短文案或增大文本框。` : `文本预计需要 ${layout.lineCount} 行,当前文本框可容纳 ${layout.maxLineCount} 行;请缩短文案、增大文本框或拆分页面。`;
834
+ issues.push({
835
+ code: "text-overflow",
836
+ severity: "error",
837
+ file: page.file,
838
+ ...context,
839
+ message
840
+ });
841
+ }
842
+ }
843
+ if (content !== void 0 && (content.gradient !== void 0 || content.shadow !== void 0)) issues.push(compatibilityIssue(page, context, "normalized", "文本渐变或阴影"));
844
+ if (typeof content?.text === "string" && /<(?:u|s|sup|sub|a|ol)(?:\s|>)/iu.test(content.text)) issues.push(compatibilityIssue(page, context, "normalized", "高级富文本标签"));
845
+ }
846
+ if (type === "shape") {
847
+ const name = string(element.shapeName);
848
+ if (name === void 0) issues.push({
849
+ code: "shape-name",
850
+ severity: "error",
851
+ file: page.file,
852
+ ...context,
853
+ message: "形状元素需要 shapeName。"
854
+ });
855
+ else if (name === "custom") if (tuple(element.viewBox, 2) === void 0 || typeof element.path !== "string") issues.push({
856
+ code: "custom-shape",
857
+ severity: "error",
858
+ file: page.file,
859
+ ...context,
860
+ message: "自定义形状需要 viewBox 和 SVG path。"
861
+ });
862
+ else issues.push(compatibilityIssue(page, context, "vector-fallback", "自定义 SVG 形状"));
863
+ else if (!NATIVE_SHAPE_NAMES.has(name)) issues.push({
864
+ code: "shape-name",
865
+ severity: "error",
866
+ file: page.file,
867
+ ...context,
868
+ message: `未知的内置形状:${name}。`
869
+ });
870
+ if (element.adjustments !== void 0) issues.push(compatibilityIssue(page, context, "normalized", "形状 adjustments"));
871
+ const fill = record(element.fill);
872
+ if (fill?.type === "gradient" || fill?.type === "image") issues.push(compatibilityIssue(page, context, "normalized", "形状渐变或图片填充"));
873
+ if (element.shadow !== void 0) issues.push(compatibilityIssue(page, context, "normalized", "形状阴影"));
874
+ }
875
+ if (type === "line") {
876
+ const points = typeof element.points === "string" ? element.points.trim().split(/\s+/u) : [];
877
+ const invalidPoint = points.some((point) => !/^-?\d+(?:\.\d+)?,-?\d+(?:\.\d+)?$/u.test(point));
878
+ if (tuple(element.viewBox, 2) === void 0 || points.length < 2 || invalidPoint) issues.push({
879
+ code: "line-path",
880
+ severity: "error",
881
+ file: page.file,
882
+ ...context,
883
+ message: "线条元素需要有效的 viewBox 和至少两个 points。"
884
+ });
885
+ else if (points.length > 2 || element.curve === "smooth") issues.push(compatibilityIssue(page, context, "vector-fallback", "贝塞尔曲线"));
886
+ if (element.shadow !== void 0) issues.push(compatibilityIssue(page, context, "normalized", "线条阴影"));
887
+ }
888
+ if (type === "image") {
889
+ if (typeof element.src !== "string") issues.push({
890
+ code: "image-src",
891
+ severity: "error",
892
+ file: page.file,
893
+ ...context,
894
+ message: "图片元素需要 src。"
895
+ });
896
+ else if (/^https?:\/\//iu.test(element.src)) issues.push({
897
+ code: "remote-image",
898
+ severity: "error",
899
+ file: page.file,
900
+ ...context,
901
+ message: "本地 PPTD 渲染器不访问网络图片,请先将图片放入项目目录。"
902
+ });
903
+ else {
904
+ const assetPath = localAssetPath(element.src);
905
+ if (assetPath === void 0 || !project.source.assets.has(assetPath)) issues.push({
906
+ code: "missing-asset",
907
+ severity: "error",
908
+ file: page.file,
909
+ ...context,
910
+ message: `找不到图片资源 ${element.src}。`
911
+ });
912
+ }
913
+ const fit = record(element.fit);
914
+ if (fit !== void 0 && ![
915
+ "fill",
916
+ "contain",
917
+ "cover"
918
+ ].includes(string(fit.mode) ?? "")) issues.push({
919
+ code: "image-fit",
920
+ severity: "error",
921
+ file: page.file,
922
+ ...context,
923
+ message: "图片 fit.mode 必须是 fill、contain 或 cover。"
924
+ });
925
+ if (element.crop !== void 0 || element.cropShape !== void 0 || element.shadow !== void 0 || element.border !== void 0) {
926
+ const cropShape = record(element.cropShape);
927
+ issues.push(compatibilityIssue(page, context, cropShape?.shapeName === "custom" ? "raster-fallback" : "normalized", "图片裁剪、边框或阴影"));
928
+ }
929
+ }
930
+ if (type === "table") {
931
+ if (typeof element.style === "string") {
932
+ const styleIssue = themeReferenceIssue(project, element.style, "tableStyles", page.file, pageNumber, id);
933
+ if (styleIssue !== void 0) issues.push(styleIssue);
934
+ }
935
+ const rows = Array.isArray(element.rows) ? element.rows : [];
936
+ for (const rawRow of rows) for (const rawCell of Array.isArray(rawRow) ? rawRow : []) {
937
+ const styleIssue = themeReferenceIssue(project, record(rawCell)?.textStyle, "textStyles", page.file, pageNumber, id);
938
+ if (styleIssue !== void 0) issues.push(styleIssue);
939
+ }
940
+ if (!validTableGrid(element)) issues.push({
941
+ code: "table-data",
942
+ severity: "error",
943
+ file: page.file,
944
+ ...context,
945
+ message: "表格网格、宽高比例或合并区域无效。"
946
+ });
947
+ }
948
+ if (type === "chart") {
949
+ const data = record(element.data);
950
+ const cols = Array.isArray(data?.cols) ? data.cols : [];
951
+ const rows = Array.isArray(data?.rows) ? data.rows : [];
952
+ const series = Array.isArray(element.series) ? element.series.map(record).filter((item) => item !== void 0) : [];
953
+ const validRows = rows.every((row) => Array.isArray(row) && row.length === cols.length);
954
+ const validSeries = series.length > 0 && series.every((item) => {
955
+ const encode = record(item.encode);
956
+ const refs = encode === void 0 ? [] : Object.values(encode).filter((value) => typeof value === "string");
957
+ return typeof item.type === "string" && refs.length >= 2 && refs.every((ref) => cols.includes(ref));
958
+ });
959
+ if (cols.length < 2 || rows.length === 0 || !validRows || !validSeries) issues.push({
960
+ code: "chart-data",
961
+ severity: "error",
962
+ file: page.file,
963
+ ...context,
964
+ message: "图表 data/series/encode 结构不完整。"
965
+ });
966
+ const chartTypes = series.map((item) => string(item.type)).filter((item) => item !== void 0);
967
+ const unknownTypes = chartTypes.filter((item) => !NATIVE_CHART_TYPES.has(item) && !UNSUPPORTED_CHART_TYPES.has(item));
968
+ if (unknownTypes.length > 0) issues.push({
969
+ code: "chart-type",
970
+ severity: "error",
971
+ file: page.file,
972
+ ...context,
973
+ message: `未知的图表类型:${[...new Set(unknownTypes)].join("、")}。`
974
+ });
975
+ const unsupportedTypes = chartTypes.filter((item) => UNSUPPORTED_CHART_TYPES.has(item));
976
+ if (unsupportedTypes.length > 0) issues.push(compatibilityIssue(page, context, "unsupported", `图表类型 ${[...new Set(unsupportedTypes)].join("、")}`));
977
+ const seriesDefaults = record(element.seriesDefaults) ?? {};
978
+ for (const [seriesIndex, item] of series.entries()) {
979
+ const chartType = string(item.type) ?? "bar";
980
+ const effective = {
981
+ ...record(seriesDefaults[chartType]) ?? {},
982
+ ...item
983
+ };
984
+ const paint = chartType === "line" || chartType === "area" || chartType === "radar" ? effective.lineColor ?? effective.areaColor : effective.fill;
985
+ if (paint === void 0) continue;
986
+ const multipleColors = Array.isArray(paint);
987
+ const validColors = resolvePptdChartSeriesColors(project, paint) !== void 0;
988
+ if (multipleColors && chartType !== "pie" || !validColors) issues.push({
989
+ code: "chart-series-color",
990
+ severity: "error",
991
+ file: page.file,
992
+ ...context,
993
+ message: `图表序列 ${seriesIndex + 1} 的颜色需要使用 #RRGGBB、#RRGGBBAA、主题颜色引用或 solid 填充;饼图同时接受颜色数组。`
994
+ });
995
+ }
996
+ }
997
+ if (type === "icon") if (typeof element.iconName !== "string") issues.push({
998
+ code: "icon-name",
999
+ severity: "error",
1000
+ file: page.file,
1001
+ ...context,
1002
+ message: "图标元素需要 iconName。"
1003
+ });
1004
+ else issues.push(compatibilityIssue(page, context, "normalized", "Font Awesome 图标"));
1005
+ return issues;
1006
+ }
1007
+ function textLayerIssues(project, page, pageNumber) {
1008
+ const issues = [];
1009
+ const overlap = (left, right) => {
1010
+ const rightEdge = Math.min((left[0] ?? 0) + (left[2] ?? 0), (right[0] ?? 0) + (right[2] ?? 0));
1011
+ const leftEdge = Math.max(left[0] ?? 0, right[0] ?? 0);
1012
+ const bottomEdge = Math.min((left[1] ?? 0) + (left[3] ?? 0), (right[1] ?? 0) + (right[3] ?? 0));
1013
+ const topEdge = Math.max(left[1] ?? 0, right[1] ?? 0);
1014
+ const width = Math.max(0, rightEdge - leftEdge);
1015
+ return {
1016
+ area: width * Math.max(0, bottomEdge - topEdge),
1017
+ width
1018
+ };
1019
+ };
1020
+ for (const [index, element] of page.elements.entries()) {
1021
+ if (element.elementType !== "text") continue;
1022
+ const textBounds = tuple(element.bounds, 4);
1023
+ if (textBounds === void 0 || (textBounds[2] ?? 0) <= 0 || (textBounds[3] ?? 0) <= 0) continue;
1024
+ const textArea = (textBounds[2] ?? 0) * (textBounds[3] ?? 0);
1025
+ const estimatedBottom = (textBounds[1] ?? 0) + (textLayout(project, element)?.requiredHeight ?? 0);
1026
+ for (const earlier of page.elements.slice(0, index)) {
1027
+ if (earlier.elementType !== "table" && earlier.elementType !== "chart") continue;
1028
+ const earlierBounds = tuple(earlier.bounds, 4);
1029
+ if (earlierBounds === void 0) continue;
1030
+ if (overlap(textBounds, earlierBounds).area / textArea >= .15) {
1031
+ issues.push({
1032
+ code: "text-occlusion",
1033
+ severity: "warning",
1034
+ file: page.file,
1035
+ page: pageNumber,
1036
+ ...typeof element.elementId === "string" ? { elementId: element.elementId } : {},
1037
+ message: `文本与 ${string(earlier.elementId) ?? earlier.elementType} 的内容区域重叠。`
1038
+ });
1039
+ break;
1040
+ }
1041
+ }
1042
+ for (const later of page.elements.slice(index + 1)) {
1043
+ if (later.elementType === "line" || number(later.opacity) === 0) continue;
1044
+ const laterBounds = tuple(later.bounds, 4);
1045
+ if (laterBounds === void 0) continue;
1046
+ const intersection = overlap(textBounds, laterBounds);
1047
+ if (intersection.area / textArea >= .15) {
1048
+ issues.push({
1049
+ code: "text-occlusion",
1050
+ severity: "warning",
1051
+ file: page.file,
1052
+ page: pageNumber,
1053
+ ...typeof element.elementId === "string" ? { elementId: element.elementId } : {},
1054
+ message: `文本可能被后绘制元素 ${string(later.elementId) ?? later.elementType ?? "unknown"} 遮挡。`
1055
+ });
1056
+ break;
1057
+ }
1058
+ const laterTop = laterBounds[1] ?? 0;
1059
+ if (laterTop > (textBounds[1] ?? 0) && laterTop < (textBounds[1] ?? 0) + (textBounds[3] ?? 0) && estimatedBottom > laterTop && intersection.width / (textBounds[2] ?? 1) >= .3) {
1060
+ issues.push({
1061
+ code: "text-drift",
1062
+ severity: "warning",
1063
+ file: page.file,
1064
+ page: pageNumber,
1065
+ ...typeof element.elementId === "string" ? { elementId: element.elementId } : {},
1066
+ message: `文本可能跨入下方元素 ${string(later.elementId) ?? later.elementType ?? "unknown"} 的边界。`
1067
+ });
1068
+ break;
1069
+ }
1070
+ }
1071
+ }
1072
+ return issues;
1073
+ }
1074
+ function isCompositionBookend(page) {
1075
+ return /^(?:cover|title|opening|section|closing|final)$/iu.test(page.pageType?.trim() ?? "");
1076
+ }
1077
+ function visibleTextSizes(project, page) {
1078
+ return page.elements.flatMap((element) => {
1079
+ if (element.elementType !== "text") return [];
1080
+ const content = record(element.content);
1081
+ if (content === void 0 || typeof content.text !== "string" || plainText(content.text).trim() === "") return [];
1082
+ return [number(textStyle(project, content).fontSize) ?? 18];
1083
+ });
1084
+ }
1085
+ function coverFocusIssues(project) {
1086
+ const canvasArea = project.width * project.height;
1087
+ return project.pages.flatMap((page, index) => {
1088
+ if (!/^(?:cover|title|opening)$/iu.test(page.pageType?.trim() ?? "")) return [];
1089
+ if (page.elements.reduce((largest, element) => {
1090
+ if (![
1091
+ "image",
1092
+ "chart",
1093
+ "table"
1094
+ ].includes(string(element.elementType) ?? "")) return largest;
1095
+ const bounds = tuple(element.bounds, 4);
1096
+ if (bounds === void 0 || canvasArea <= 0) return largest;
1097
+ return Math.max(largest, (bounds[2] ?? 0) * (bounds[3] ?? 0) / canvasArea);
1098
+ }, 0) >= .25) return [];
1099
+ const sizes = visibleTextSizes(project, page).sort((left, right) => left - right);
1100
+ if (sizes.length < 3) return [];
1101
+ const middle = Math.floor(sizes.length / 2);
1102
+ const median = sizes.length % 2 === 1 ? sizes[middle] ?? 0 : ((sizes[middle - 1] ?? 0) + (sizes[middle] ?? 0)) / 2;
1103
+ const largest = sizes.at(-1) ?? 0;
1104
+ if (median > 0 && largest / median >= 3) return [];
1105
+ return [{
1106
+ code: "cover-focus",
1107
+ severity: "warning",
1108
+ file: page.file,
1109
+ page: index + 1,
1110
+ message: "封面需要更明确的首读焦点:让一张图片、图表或表格占据至少 25% 画布,或让最大标题达到可见文字中位字号的 3 倍。"
1111
+ }];
1112
+ });
1113
+ }
1114
+ function compositionFamily(element) {
1115
+ const type = string(element.elementType);
1116
+ if (type === "text" || type === "icon") return "text";
1117
+ if (type === "image" || type === "chart" || type === "table") return "visual";
1118
+ if (type === "shape") return "shape";
1119
+ }
1120
+ function layoutSignature(project, page) {
1121
+ const canvasArea = project.width * project.height;
1122
+ const landmarks = /* @__PURE__ */ new Set();
1123
+ for (const element of page.elements) {
1124
+ const family = compositionFamily(element);
1125
+ const bounds = tuple(element.bounds, 4);
1126
+ if (family === void 0 || bounds === void 0 || canvasArea <= 0) continue;
1127
+ const [x = 0, y = 0, width = 0, height = 0] = bounds;
1128
+ if (width <= 0 || height <= 0) continue;
1129
+ const areaShare = width * height / canvasArea;
1130
+ if (family === "shape" && (areaShare < .01 || areaShare > .85)) continue;
1131
+ const column = Math.max(0, Math.min(3, Math.floor((x + width / 2) / project.width * 4)));
1132
+ const row = Math.max(0, Math.min(3, Math.floor((y + height / 2) / project.height * 4)));
1133
+ const scale = areaShare >= .25 ? "large" : areaShare >= .08 ? "medium" : "small";
1134
+ landmarks.add(`${family}:${column}:${row}:${scale}`);
1135
+ }
1136
+ return [...landmarks].sort().join("|");
1137
+ }
1138
+ function layoutRepetitionIssues(project) {
1139
+ const issues = [];
1140
+ let runStart = 0;
1141
+ let runSignature;
1142
+ const finishRun = (end) => {
1143
+ if (runSignature === void 0 || end - runStart < 3) return;
1144
+ const first = project.pages[runStart];
1145
+ if (first === void 0) return;
1146
+ issues.push({
1147
+ code: "layout-repetition",
1148
+ severity: "warning",
1149
+ file: first.file,
1150
+ page: runStart + 1,
1151
+ message: `第 ${runStart + 1}–${end} 页连续使用相同构图轮廓。调整主视觉位置、尺度或内容分组,并重新预览这组页面;固定指标序列可以保留重复。`
1152
+ });
1153
+ };
1154
+ for (const [index, page] of project.pages.entries()) {
1155
+ const signature = isCompositionBookend(page) ? "" : layoutSignature(project, page);
1156
+ if (signature === "") {
1157
+ finishRun(index);
1158
+ runStart = index + 1;
1159
+ runSignature = void 0;
1160
+ continue;
1161
+ }
1162
+ if (signature === runSignature) continue;
1163
+ finishRun(index);
1164
+ runStart = index;
1165
+ runSignature = signature;
1166
+ }
1167
+ finishRun(project.pages.length);
1168
+ return issues;
1169
+ }
1170
+ function compositionIssues(project) {
1171
+ return [...coverFocusIssues(project), ...layoutRepetitionIssues(project)];
1172
+ }
1173
+ /** Check structure, renderability, and measurable composition signals without external effects. */
1174
+ function checkPptdProject(project) {
1175
+ const issues = [...project.parseIssues];
1176
+ issues.push(...colorThemeIssues(project, project.theme, project.source.entryName));
1177
+ for (const [key, value] of Object.entries(themeMap(project, "colors"))) {
1178
+ const referenceIssue = themeReferenceIssue(project, value, "colors", project.source.entryName);
1179
+ if (referenceIssue !== void 0) issues.push(referenceIssue);
1180
+ if (typeof value !== "string" || !value.startsWith("$") && !/^#[0-9a-f]{6}(?:[0-9a-f]{2})?$/iu.test(value)) issues.push({
1181
+ code: "invalid-theme",
1182
+ severity: "error",
1183
+ file: project.source.entryName,
1184
+ message: `theme.colors.${key} 必须是颜色或颜色主题引用。`
1185
+ });
1186
+ }
1187
+ issues.push(...themeColorChainIssues(project));
1188
+ for (const [index, page] of project.pages.entries()) {
1189
+ const ids = /* @__PURE__ */ new Set();
1190
+ issues.push(...colorThemeIssues(project, page.background, page.file, index + 1));
1191
+ for (const element of page.elements) issues.push(...checkElement(project, page, index + 1, element, ids));
1192
+ issues.push(...textLayerIssues(project, page, index + 1));
1193
+ }
1194
+ issues.push(...compositionIssues(project));
1195
+ const errorCount = issues.filter((item) => item.severity === "error").length;
1196
+ const warningCount = issues.filter((item) => item.severity === "warning").length;
1197
+ return {
1198
+ status: errorCount > 0 ? "fail" : warningCount > 0 ? "warning" : "pass",
1199
+ digest: projectDigest(project),
1200
+ pageCount: project.pages.length,
1201
+ nativeObjectCount: project.pages.reduce((sum, page) => sum + page.elements.length, 0),
1202
+ warningCount,
1203
+ errorCount,
1204
+ issues,
1205
+ compatibility: compatibilitySummary(project)
1206
+ };
1207
+ }
1208
+ function inches(value) {
1209
+ return value / POINTS_PER_INCH;
1210
+ }
1211
+ function frame(element) {
1212
+ const [x = 0, y = 0, width = 0, height = 0] = tuple(element.bounds, 4) ?? [
1213
+ 0,
1214
+ 0,
1215
+ 0,
1216
+ 0
1217
+ ];
1218
+ return {
1219
+ x: inches(x),
1220
+ y: inches(y),
1221
+ w: inches(width),
1222
+ h: inches(height)
1223
+ };
1224
+ }
1225
+ function fontFace(value, fallback = "Arial", text = "") {
1226
+ if (typeof value === "string") return value;
1227
+ const font = record(value);
1228
+ const eastAsian = /[\u2e80-\u9fff\uf900-\ufaff]/u.test(text);
1229
+ const ea = process.platform === "darwin" ? font?.mac ?? font?.ea : process.platform === "win32" ? font?.win ?? font?.ea : font?.ea;
1230
+ return (eastAsian ? string(ea) ?? string(font?.latin) : string(font?.latin) ?? string(ea)) ?? fallback;
1231
+ }
1232
+ function inlineStyle(project, raw) {
1233
+ const options = {};
1234
+ for (const declaration of raw?.split(";") ?? []) {
1235
+ const [name, ...rest] = declaration.split(":");
1236
+ const value = rest.join(":").trim();
1237
+ if (name?.trim() === "color") options.color = colorOptions(project, value).color;
1238
+ if (name?.trim() === "font-size" && /^\d+(?:\.\d+)?px$/u.test(value)) options.fontSize = Number.parseFloat(value);
1239
+ if (name?.trim() === "font-family" && value !== "") {
1240
+ const face = value.replace(/^['"]|['"]$/gu, "").split(",")[0]?.trim();
1241
+ if (face !== void 0) options.fontFace = face;
1242
+ }
1243
+ if (name?.trim() === "background-color") options.highlight = colorOptions(project, value).color;
1244
+ if (name?.trim() === "font-weight" && (value === "bold" || Number(value) >= 600)) options.bold = true;
1245
+ if (name?.trim() === "font-style" && value === "italic") options.italic = true;
1246
+ }
1247
+ return options;
1248
+ }
1249
+ function richRuns(project, value) {
1250
+ const runs = [];
1251
+ const stack = [{
1252
+ tag: "root",
1253
+ options: {}
1254
+ }];
1255
+ const currentOptions = () => stack.at(-1)?.options ?? {};
1256
+ for (const token of value.split(/(<[^>]+>)/gu)) {
1257
+ if (token === "") continue;
1258
+ if (!token.startsWith("<")) {
1259
+ const decoded = plainText(token);
1260
+ if (decoded !== "") runs.push({
1261
+ text: decoded,
1262
+ options: { ...currentOptions() }
1263
+ });
1264
+ continue;
1265
+ }
1266
+ const closing = /^<\/([a-z0-9]+)/iu.exec(token);
1267
+ if (closing !== null) {
1268
+ const tag = closing[1]?.toLowerCase();
1269
+ if (tag === void 0) continue;
1270
+ if (tag === "p" || tag === "li") runs.push({
1271
+ text: "\n",
1272
+ options: { ...currentOptions() }
1273
+ });
1274
+ while (stack.length > 1) if (stack.pop()?.tag === tag) break;
1275
+ continue;
1276
+ }
1277
+ const opening = /^<([a-z0-9]+)/iu.exec(token);
1278
+ if (opening === null) continue;
1279
+ const tag = opening[1]?.toLowerCase();
1280
+ if (tag === void 0) continue;
1281
+ if (tag === "br") {
1282
+ runs.push({
1283
+ text: "\n",
1284
+ options: { ...currentOptions() }
1285
+ });
1286
+ continue;
1287
+ }
1288
+ if (tag === "li") runs.push({
1289
+ text: "• ",
1290
+ options: { ...currentOptions() }
1291
+ });
1292
+ const style = /\sstyle=(?:"([^"]*)"|'([^']*)')/iu.exec(token);
1293
+ const options = {
1294
+ ...currentOptions(),
1295
+ ...inlineStyle(project, style?.[1] ?? style?.[2])
1296
+ };
1297
+ if (tag === "strong") options.bold = true;
1298
+ if (tag === "em") options.italic = true;
1299
+ if (tag === "u") options.underline = { style: "sng" };
1300
+ if (tag === "s") options.strike = "sngStrike";
1301
+ if (tag === "sup") options.superscript = true;
1302
+ if (tag === "sub") options.subscript = true;
1303
+ if (tag === "a") {
1304
+ const href = /\shref=(?:"([^"]*)"|'([^']*)')/iu.exec(token)?.slice(1).find((item) => item !== void 0);
1305
+ if (href !== void 0 && /^(?:https?:|mailto:)/iu.test(href)) options.hyperlink = { url: href };
1306
+ }
1307
+ stack.push({
1308
+ tag,
1309
+ options
1310
+ });
1311
+ }
1312
+ while (runs.at(-1)?.text === "\n") runs.pop();
1313
+ return runs;
1314
+ }
1315
+ function flipOptions(element) {
1316
+ const flip = Array.isArray(element.flip) ? element.flip : [];
1317
+ return {
1318
+ ...typeof flip[0] === "boolean" ? { flipH: flip[0] } : {},
1319
+ ...typeof flip[1] === "boolean" ? { flipV: flip[1] } : {}
1320
+ };
1321
+ }
1322
+ function shadowOptions(project, value) {
1323
+ const shadow = record(value);
1324
+ if (shadow === void 0 || number(shadow.blur) === void 0 || typeof shadow.color !== "string") return void 0;
1325
+ const resolved = resolveColorValue(project, shadow.color);
1326
+ const alpha = resolved.length === 9 ? Number.parseInt(resolved.slice(7, 9), 16) / 255 : 1;
1327
+ const [offsetX = 0, offsetY = 0] = tuple(shadow.offset, 2) ?? [0, 0];
1328
+ const angle = (Math.atan2(-offsetY, offsetX) * 180 / Math.PI + 360) % 360;
1329
+ return {
1330
+ type: "outer",
1331
+ color: resolved.slice(1, 7).toUpperCase(),
1332
+ opacity: alpha,
1333
+ blur: number(shadow.blur) ?? 0,
1334
+ offset: Math.hypot(offsetX, offsetY),
1335
+ angle
1336
+ };
1337
+ }
1338
+ function dash(value) {
1339
+ return value === "dash" || value === "dot" ? value : "solid";
1340
+ }
1341
+ function border(project, value) {
1342
+ const config = record(value);
1343
+ if (config === void 0) return void 0;
1344
+ const style = dash(config.style);
1345
+ return {
1346
+ color: colorOptions(project, config.color).color,
1347
+ width: number(config.width) ?? 1,
1348
+ ...style === "solid" ? {} : { dash: style }
1349
+ };
1350
+ }
1351
+ function horizontalAlign(value, fallback) {
1352
+ return value === "center" || value === "right" || value === "justify" ? value : fallback;
1353
+ }
1354
+ function verticalAlign(value, fallback) {
1355
+ return value === "middle" || value === "bottom" ? value : fallback;
1356
+ }
1357
+ function renderText(project, slide, element) {
1358
+ const content = record(element.content) ?? {};
1359
+ const style = textStyle(project, content);
1360
+ const align = Array.isArray(style.align) ? style.align : [];
1361
+ const raw = string(content.text) ?? "";
1362
+ const runs = /<[^>]+>/u.test(raw) ? richRuns(project, raw) : raw;
1363
+ const textColor = colorOptions(project, style.color).color;
1364
+ const objectName = string(element.elementId);
1365
+ const charSpacing = number(style.letterSpacing);
1366
+ const horizontal = horizontalAlign(align[0], "left");
1367
+ const vertical = verticalAlign(align[1], "top");
1368
+ const textShadow = shadowOptions(project, style.shadow);
1369
+ slide.addText(runs, {
1370
+ ...frame(element),
1371
+ ...objectName === void 0 ? {} : { objectName },
1372
+ fontFace: fontFace(style.fontFamily, "Arial", raw),
1373
+ fontSize: number(style.fontSize) ?? 18,
1374
+ color: textColor,
1375
+ bold: boolean(style.bold) ?? false,
1376
+ italic: boolean(style.italic) ?? false,
1377
+ align: horizontal,
1378
+ valign: vertical,
1379
+ margin: 0,
1380
+ breakLine: false,
1381
+ wrap: boolean(style.wrap) ?? true,
1382
+ textDirection: style.textDirection === "vertical" ? "vert" : "horz",
1383
+ rotate: number(element.rotation) ?? 0,
1384
+ ...flipOptions(element),
1385
+ transparency: Math.round((1 - (number(element.opacity) ?? 1)) * 100),
1386
+ ...textShadow === void 0 ? {} : { shadow: textShadow },
1387
+ ...charSpacing === void 0 ? {} : { charSpacing }
1388
+ });
1389
+ }
1390
+ function solidFill(project, value, opacity = 1) {
1391
+ const fill = record(value);
1392
+ if (fill === void 0) return void 0;
1393
+ if (fill.type === "solid") return colorOptions(project, fill.color, opacity);
1394
+ if (fill.type === "gradient" && Array.isArray(fill.stops)) {
1395
+ const first = record(fill.stops[0]);
1396
+ return first === void 0 ? void 0 : colorOptions(project, first.color, opacity);
1397
+ }
1398
+ }
1399
+ function shapeType(pptx, value) {
1400
+ const name = typeof value === "string" ? value : "rect";
1401
+ const shape = pptx.ShapeType[name];
1402
+ if (shape === void 0) throw new Error(`Unsupported PPTD preset shape: ${name}`);
1403
+ return shape;
1404
+ }
1405
+ function xmlEscape(value) {
1406
+ return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;");
1407
+ }
1408
+ function svgPaint(project, fillValue, opacity) {
1409
+ const fill = record(fillValue);
1410
+ if (fill?.type === "gradient" && Array.isArray(fill.stops) && fill.stops.length >= 2) {
1411
+ const id = "pptd-gradient";
1412
+ const stops = fill.stops.map((rawStop) => {
1413
+ const stop = record(rawStop) ?? {};
1414
+ const color = colorOptions(project, stop.color, opacity);
1415
+ return `<stop offset="${Math.round(Math.max(0, Math.min(1, number(stop.position) ?? 0)) * 100)}%" stop-color="#${color.color}"${color.transparency === void 0 ? "" : ` stop-opacity="${1 - color.transparency / 100}"`}/>`;
1416
+ }).join("");
1417
+ if (fill.gradientType === "radial") return {
1418
+ paint: `url(#${id})`,
1419
+ definition: `<radialGradient id="${id}">${stops}</radialGradient>`
1420
+ };
1421
+ const angle = number(fill.angle) ?? 0;
1422
+ return {
1423
+ paint: `url(#${id})`,
1424
+ definition: `<linearGradient id="${id}" x1="0" y1="0.5" x2="1" y2="0.5" gradientTransform="rotate(${angle} 0.5 0.5)">${stops}</linearGradient>`
1425
+ };
1426
+ }
1427
+ return {
1428
+ paint: `#${colorOptions(project, fill?.type === "solid" ? fill.color : "#000000", opacity).color}`,
1429
+ definition: ""
1430
+ };
1431
+ }
1432
+ function svgData(svg) {
1433
+ return `data:image/svg+xml;base64,${Buffer.from(svg).toString("base64")}`;
1434
+ }
1435
+ function renderCustomShape(project, slide, element) {
1436
+ const viewBox = tuple(element.viewBox, 2) ?? [1, 1];
1437
+ const pathData = string(element.path) ?? "";
1438
+ const opacity = number(element.opacity) ?? 1;
1439
+ const fill = svgPaint(project, element.fill, opacity);
1440
+ const line = border(project, element.border);
1441
+ const shadow = shadowOptions(project, element.shadow);
1442
+ const shadowAngle = shadow?.angle ?? 0;
1443
+ const shadowOffset = shadow?.offset ?? 0;
1444
+ const shadowBlur = shadow?.blur ?? 0;
1445
+ const objectName = string(element.elementId);
1446
+ const [width = 1, height = 1] = viewBox;
1447
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}"><defs>${[fill.definition, shadow === void 0 ? "" : [
1448
+ "<filter id=\"pptd-shadow\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">",
1449
+ `<feDropShadow dx="${Math.cos(shadowAngle * Math.PI / 180) * shadowOffset}" dy="${-Math.sin(shadowAngle * Math.PI / 180) * shadowOffset}" stdDeviation="${shadowBlur / 2}" flood-color="#${shadow?.color ?? "000000"}" flood-opacity="${shadow?.opacity ?? 1}"/>`,
1450
+ "</filter>"
1451
+ ].join("")].join("")}</defs><path d="${xmlEscape(pathData)}" fill="${fill.paint}" fill-rule="evenodd"${line === void 0 ? " stroke=\"none\"" : ` stroke="#${line.color}" stroke-width="${line.width}"${line.dash === void 0 ? "" : ` stroke-dasharray="${line.dash === "dot" ? "1 2" : "4 3"}"`}`}${shadow === void 0 ? "" : " filter=\"url(#pptd-shadow)\""}/></svg>`;
1452
+ slide.addImage({
1453
+ ...frame(element),
1454
+ data: svgData(svg),
1455
+ ...objectName === void 0 ? {} : { objectName },
1456
+ rotate: number(element.rotation) ?? 0,
1457
+ ...flipOptions(element)
1458
+ });
1459
+ }
1460
+ function renderShape(project, pptx, slide, element) {
1461
+ if (element.shapeName === "custom") {
1462
+ renderCustomShape(project, slide, element);
1463
+ return;
1464
+ }
1465
+ const opacity = number(element.opacity) ?? 1;
1466
+ const fill = solidFill(project, element.fill, opacity);
1467
+ const line = border(project, element.border);
1468
+ const objectName = string(element.elementId);
1469
+ const shapeShadow = shadowOptions(project, element.shadow);
1470
+ slide.addShape(shapeType(pptx, element.shapeName), {
1471
+ ...frame(element),
1472
+ ...objectName === void 0 ? {} : { objectName },
1473
+ rotate: number(element.rotation) ?? 0,
1474
+ ...flipOptions(element),
1475
+ ...fill === void 0 ? { fill: {
1476
+ color: "FFFFFF",
1477
+ transparency: 100
1478
+ } } : { fill },
1479
+ line: line === void 0 ? {
1480
+ color: "FFFFFF",
1481
+ transparency: 100
1482
+ } : line,
1483
+ ...shapeShadow === void 0 ? {} : { shadow: shapeShadow }
1484
+ });
1485
+ }
1486
+ function renderCurvedLine(project, slide, element, points) {
1487
+ const [width = 1, height = 1] = tuple(element.viewBox, 2) ?? [1, 1];
1488
+ const [first = [0, 0], ...rest] = points;
1489
+ const [startX = 0, startY = 0] = first;
1490
+ const pathData = rest.length === 3 ? `M ${startX} ${startY} C ${rest.map((point) => point.join(" ")).join(" ")}` : `M ${startX} ${startY} ${rest.map((point) => `L ${point[0] ?? 0} ${point[1] ?? 0}`).join(" ")}`;
1491
+ const line = border(project, element.border) ?? {
1492
+ color: "000000",
1493
+ width: 1
1494
+ };
1495
+ const arrow = Array.isArray(element.arrow) ? element.arrow : [];
1496
+ const marker = (id, kind) => kind === null || kind === void 0 ? "" : [
1497
+ `<marker id="${id}" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto" markerUnits="strokeWidth">`,
1498
+ kind === "oval" ? "<circle cx=\"4\" cy=\"4\" r=\"3\" fill=\"context-stroke\"/>" : kind === "diamond" ? "<path d=\"M0,4 L4,0 L8,4 L4,8 Z\" fill=\"context-stroke\"/>" : "<path d=\"M0,0 L8,4 L0,8 Z\" fill=\"context-stroke\"/>",
1499
+ "</marker>"
1500
+ ].join("");
1501
+ const dash = line.dash === void 0 ? "" : ` stroke-dasharray="${line.dash === "dot" ? "1 2" : "4 3"}"`;
1502
+ const markerStart = arrow[0] === void 0 || arrow[0] === null ? "" : " marker-start=\"url(#start)\"";
1503
+ const markerEnd = arrow[1] === void 0 || arrow[1] === null ? "" : " marker-end=\"url(#end)\"";
1504
+ const svg = [
1505
+ `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}">`,
1506
+ `<defs>${marker("start", arrow[0])}${marker("end", arrow[1])}</defs>`,
1507
+ `<path d="${pathData}" fill="none" stroke="#${line.color}" stroke-width="${line.width}"`,
1508
+ `${dash}${markerStart}${markerEnd}/></svg>`
1509
+ ].join("");
1510
+ const objectName = string(element.elementId);
1511
+ slide.addImage({
1512
+ ...frame(element),
1513
+ data: svgData(svg),
1514
+ ...objectName === void 0 ? {} : { objectName },
1515
+ rotate: number(element.rotation) ?? 0,
1516
+ ...flipOptions(element)
1517
+ });
1518
+ }
1519
+ function renderLine(project, pptx, slide, element) {
1520
+ const points = (string(element.points) ?? "").trim().split(/\s+/u).map((value) => value.split(",").map(Number));
1521
+ if (points.length > 2 || element.curve === "smooth") {
1522
+ renderCurvedLine(project, slide, element, points);
1523
+ return;
1524
+ }
1525
+ const viewBox = tuple(element.viewBox, 2) ?? [1, 1];
1526
+ const bounds = frame(element);
1527
+ const first = points[0] ?? [0, 0];
1528
+ const last = points.at(-1) ?? [viewBox[0] ?? 1, viewBox[1] ?? 1];
1529
+ const x1 = bounds.x + (first[0] ?? 0) / (viewBox[0] ?? 1) * bounds.w;
1530
+ const y1 = bounds.y + (first[1] ?? 0) / (viewBox[1] ?? 1) * bounds.h;
1531
+ const x2 = bounds.x + (last[0] ?? 0) / (viewBox[0] ?? 1) * bounds.w;
1532
+ const y2 = bounds.y + (last[1] ?? 0) / (viewBox[1] ?? 1) * bounds.h;
1533
+ const line = border(project, element.border) ?? {
1534
+ color: "000000",
1535
+ width: 1
1536
+ };
1537
+ const arrow = Array.isArray(element.arrow) ? element.arrow : [];
1538
+ const objectName = string(element.elementId);
1539
+ const lineShadow = shadowOptions(project, element.shadow);
1540
+ slide.addShape(pptx.ShapeType.line, {
1541
+ x: Math.min(x1, x2),
1542
+ y: Math.min(y1, y2),
1543
+ w: Math.abs(x2 - x1),
1544
+ h: Math.abs(y2 - y1),
1545
+ ...objectName === void 0 ? {} : { objectName },
1546
+ flipH: x2 < x1,
1547
+ flipV: y2 < y1,
1548
+ rotate: number(element.rotation) ?? 0,
1549
+ line: {
1550
+ ...line,
1551
+ ...arrow[0] === void 0 || arrow[0] === null ? {} : { beginArrowType: arrow[0] },
1552
+ ...arrow[1] === void 0 || arrow[1] === null ? {} : { endArrowType: arrow[1] }
1553
+ },
1554
+ ...lineShadow === void 0 ? {} : { shadow: lineShadow }
1555
+ });
1556
+ }
1557
+ function renderImage(project, slide, element) {
1558
+ const assetPath = localAssetPath(element.src);
1559
+ const asset = assetPath === void 0 ? void 0 : project.source.assets.get(assetPath);
1560
+ if (asset === void 0) throw new Error(`PPTD image ${String(element.src)} is unavailable`);
1561
+ const objectName = string(element.elementId);
1562
+ const mode = string(record(element.fit)?.mode) ?? "cover";
1563
+ const bounds = frame(element);
1564
+ const cropShape = record(element.cropShape);
1565
+ const imageShadow = shadowOptions(project, element.shadow);
1566
+ slide.addImage({
1567
+ ...bounds,
1568
+ ...objectName === void 0 ? {} : { objectName },
1569
+ data: `data:${asset.mediaType};base64,${Buffer.from(asset.bytes).toString("base64")}`,
1570
+ rotate: number(element.rotation) ?? 0,
1571
+ ...flipOptions(element),
1572
+ transparency: Math.round((1 - (number(element.opacity) ?? 1)) * 100),
1573
+ ...mode === "fill" ? {} : { sizing: {
1574
+ type: mode,
1575
+ w: bounds.w,
1576
+ h: bounds.h
1577
+ } },
1578
+ ...cropShape?.shapeName === "ellipse" ? { rounding: true } : {},
1579
+ ...imageShadow === void 0 ? {} : { shadow: imageShadow }
1580
+ });
1581
+ const imageBorder = border(project, element.border);
1582
+ if (imageBorder !== void 0) slide.addShape(cropShape?.shapeName === "ellipse" ? "ellipse" : "rect", {
1583
+ ...bounds,
1584
+ objectName: `${objectName ?? "image"}-border`,
1585
+ fill: {
1586
+ color: "FFFFFF",
1587
+ transparency: 100
1588
+ },
1589
+ line: imageBorder,
1590
+ rotate: number(element.rotation) ?? 0,
1591
+ ...flipOptions(element)
1592
+ });
1593
+ }
1594
+ function mergeCellStyle(project, table, row, column, rowCount, columnCount, cell) {
1595
+ const tableTheme = record(resolveThemeReference(table.style, themeMap(project, "tableStyles"))) ?? {};
1596
+ const baseline = record(tableTheme.cellStyle) ?? {};
1597
+ const bodyStyles = Array.isArray(tableTheme.bodyStyles) ? tableTheme.bodyStyles.map(record).filter((item) => item !== void 0) : [];
1598
+ const body = row > 0 && row < rowCount - 1 && bodyStyles.length > 0 ? bodyStyles[(row - 1) % bodyStyles.length] ?? {} : {};
1599
+ const rowStyle = row === 0 ? record(tableTheme.firstRowStyle) ?? {} : row === rowCount - 1 ? record(tableTheme.lastRowStyle) ?? {} : body;
1600
+ const columnStyle = column === 0 ? record(tableTheme.firstColumnStyle) ?? {} : column === columnCount - 1 ? record(tableTheme.lastColumnStyle) ?? {} : {};
1601
+ return boolean(tableTheme.rowOverColumn) === false ? {
1602
+ ...baseline,
1603
+ ...rowStyle,
1604
+ ...columnStyle,
1605
+ ...cell
1606
+ } : {
1607
+ ...baseline,
1608
+ ...columnStyle,
1609
+ ...rowStyle,
1610
+ ...cell
1611
+ };
1612
+ }
1613
+ function tableBorder(project, value) {
1614
+ const none = {
1615
+ color: "FFFFFF",
1616
+ pt: 0
1617
+ };
1618
+ const one = (item) => {
1619
+ const parsed = border(project, item);
1620
+ return parsed === void 0 ? none : {
1621
+ color: parsed.color,
1622
+ pt: parsed.width,
1623
+ ...parsed.dash === void 0 ? {} : { dash: parsed.dash }
1624
+ };
1625
+ };
1626
+ if (value === null) return [
1627
+ none,
1628
+ none,
1629
+ none,
1630
+ none
1631
+ ];
1632
+ if (Array.isArray(value)) {
1633
+ if (value.length === 2) return [
1634
+ one(value[0]),
1635
+ one(value[1]),
1636
+ one(value[0]),
1637
+ one(value[1])
1638
+ ];
1639
+ if (value.length === 4) return [
1640
+ one(value[0]),
1641
+ one(value[1]),
1642
+ one(value[2]),
1643
+ one(value[3])
1644
+ ];
1645
+ }
1646
+ return record(value) === void 0 ? void 0 : one(value);
1647
+ }
1648
+ function renderTable(project, slide, element) {
1649
+ const rows = element.rows;
1650
+ const rowCount = rows.length;
1651
+ const columnCount = Array.isArray(element.columnWidths) ? element.columnWidths.length : rows[0]?.length ?? 0;
1652
+ const tableRows = rows.map((row, rowIndex) => row.map((rawCell, columnIndex) => {
1653
+ const cell = record(rawCell) ?? { text: typeof rawCell === "string" || typeof rawCell === "number" ? String(rawCell) : "" };
1654
+ const style = {
1655
+ ...record(resolveThemeReference(cell.textStyle, themeMap(project, "textStyles"))) ?? {},
1656
+ ...mergeCellStyle(project, element, rowIndex, columnIndex, rowCount, columnCount, cell)
1657
+ };
1658
+ const align = Array.isArray(style.align) ? style.align : [];
1659
+ const horizontal = horizontalAlign(align[0], "center");
1660
+ const vertical = verticalAlign(align[1], "middle");
1661
+ const fill = solidFill(project, style.fill);
1662
+ const cellBorder = tableBorder(project, style.border);
1663
+ const rowSpan = number(cell.rowSpan);
1664
+ const colSpan = number(cell.colSpan);
1665
+ const options = {
1666
+ fontFace: fontFace(style.fontFamily, "Arial", string(cell.text) ?? ""),
1667
+ fontSize: number(style.fontSize) ?? 10,
1668
+ color: colorOptions(project, style.color).color,
1669
+ bold: boolean(style.bold) ?? false,
1670
+ italic: boolean(style.italic) ?? false,
1671
+ align: horizontal,
1672
+ valign: vertical,
1673
+ margin: .03,
1674
+ ...rowSpan === void 0 ? {} : { rowspan: rowSpan },
1675
+ ...colSpan === void 0 ? {} : { colspan: colSpan },
1676
+ ...fill === void 0 ? {} : { fill },
1677
+ ...cellBorder === void 0 ? {} : { border: cellBorder }
1678
+ };
1679
+ return {
1680
+ text: plainText(string(cell.text) ?? ""),
1681
+ options
1682
+ };
1683
+ }));
1684
+ const bounds = frame(element);
1685
+ const colRatios = Array.isArray(element.columnWidths) ? element.columnWidths.map(number).filter((item) => item !== void 0) : [];
1686
+ const rowRatios = Array.isArray(element.rowHeights) ? element.rowHeights.map(number).filter((item) => item !== void 0) : [];
1687
+ const colW = colRatios.length === columnCount ? colRatios.map((value) => value * bounds.w) : void 0;
1688
+ const rowH = rowRatios.length === rowCount ? rowRatios.map((value) => value * bounds.h) : void 0;
1689
+ const objectName = string(element.elementId);
1690
+ slide.addTable(tableRows, {
1691
+ ...bounds,
1692
+ ...objectName === void 0 ? {} : { objectName },
1693
+ autoPage: false,
1694
+ ...colW === void 0 ? {} : { colW },
1695
+ ...rowH === void 0 ? {} : { rowH },
1696
+ border: {
1697
+ color: "FFFFFF",
1698
+ pt: 0
1699
+ },
1700
+ margin: 0
1701
+ });
1702
+ }
1703
+ function legendPosition(value) {
1704
+ return {
1705
+ bottom: "b",
1706
+ left: "l",
1707
+ right: "r",
1708
+ top: "t",
1709
+ topRight: "tr"
1710
+ }[string(value) ?? ""] ?? "r";
1711
+ }
1712
+ function valueAxisOptions(project, axis) {
1713
+ const label = record(axis.label) ?? {};
1714
+ const grid = record(axis.gridLine);
1715
+ const minimum = number(axis.min);
1716
+ const maximum = number(axis.max);
1717
+ const fontSize = number(label.fontSize);
1718
+ const title = string(axis.title);
1719
+ return {
1720
+ ...minimum === void 0 ? {} : { valAxisMinVal: minimum },
1721
+ ...maximum === void 0 ? {} : { valAxisMaxVal: maximum },
1722
+ ...fontSize === void 0 ? {} : { valAxisLabelFontSize: fontSize },
1723
+ ...title === void 0 ? {} : {
1724
+ showValAxisTitle: true,
1725
+ valAxisTitle: title
1726
+ },
1727
+ ...axis.gridLine === false ? { valGridLine: { style: "none" } } : grid === void 0 ? {} : { valGridLine: {
1728
+ color: colorOptions(project, grid.color, 1).color,
1729
+ style: dash(grid.style)
1730
+ } }
1731
+ };
1732
+ }
1733
+ function chartAxisOptions(project, element, horizontal = false) {
1734
+ const xAxis = Array.isArray(element.xAxis) ? record(element.xAxis[0]) ?? {} : record(element.xAxis) ?? {};
1735
+ const yAxis = (Array.isArray(element.yAxis) ? element.yAxis.map(record).filter((item) => item !== void 0) : [record(element.yAxis) ?? {}])[0] ?? {};
1736
+ const valueAxis = horizontal ? xAxis : yAxis;
1737
+ const categoryAxis = horizontal ? yAxis : xAxis;
1738
+ const categoryLabel = record(categoryAxis.label) ?? {};
1739
+ return {
1740
+ ...valueAxisOptions(project, valueAxis),
1741
+ ...number(categoryLabel.fontSize) === void 0 ? {} : { catAxisLabelFontSize: number(categoryLabel.fontSize) },
1742
+ ...number(categoryLabel.rotate) === void 0 ? {} : { catAxisLabelRotate: number(categoryLabel.rotate) },
1743
+ ...categoryAxis.gridLine === false ? { catGridLine: { style: "none" } } : {}
1744
+ };
1745
+ }
1746
+ function renderChart(project, pptx, slide, element, foregroundColor) {
1747
+ const data = record(element.data) ?? {};
1748
+ const columns = (Array.isArray(data.cols) ? data.cols : []).map((value) => String(value));
1749
+ const rows = Array.isArray(data.rows) ? data.rows : [];
1750
+ const columnIsNumeric = (column) => {
1751
+ if (column === void 0) return false;
1752
+ const columnIndex = columns.indexOf(column);
1753
+ if (columnIndex < 0) return false;
1754
+ const values = rows.map((row) => row[columnIndex]).filter((value) => value !== void 0 && value !== null && value !== "");
1755
+ return values.length > 0 && values.every((value) => {
1756
+ if (typeof value === "number") return Number.isFinite(value);
1757
+ return typeof value === "string" && value.trim() !== "" && Number.isFinite(Number(value));
1758
+ });
1759
+ };
1760
+ const seriesDefaults = record(element.seriesDefaults) ?? {};
1761
+ const xAxis = Array.isArray(element.xAxis) ? record(element.xAxis[0]) ?? {} : record(element.xAxis) ?? {};
1762
+ const yAxes = Array.isArray(element.yAxis) ? element.yAxis.map(record).filter((item) => item !== void 0) : [record(element.yAxis) ?? {}];
1763
+ const mergeSeries = (raw) => {
1764
+ const defaults = record(seriesDefaults[string(raw.type) ?? ""]) ?? {};
1765
+ const merged = {
1766
+ ...defaults,
1767
+ ...raw
1768
+ };
1769
+ for (const key of [
1770
+ "marker",
1771
+ "dataLabels",
1772
+ "border",
1773
+ "upBars",
1774
+ "downBars",
1775
+ "totalBars",
1776
+ "increaseBars",
1777
+ "decreaseBars"
1778
+ ]) {
1779
+ const base = record(defaults[key]);
1780
+ const specific = record(raw[key]);
1781
+ if (base !== void 0 || specific !== void 0) merged[key] = {
1782
+ ...base ?? {},
1783
+ ...specific ?? {}
1784
+ };
1785
+ }
1786
+ return merged;
1787
+ };
1788
+ const series = (Array.isArray(element.series) ? element.series : []).map(record).filter((item) => item !== void 0).map(mergeSeries);
1789
+ const types = [];
1790
+ const mergeableGroups = /* @__PURE__ */ new Map();
1791
+ for (const [index, item] of series.entries()) {
1792
+ const encode = record(item.encode) ?? {};
1793
+ const chartTypeName = string(item.type) ?? "bar";
1794
+ const xColumn = string(encode.x);
1795
+ const yColumn = string(encode.y);
1796
+ const horizontal = chartTypeName === "bar" && columnIsNumeric(xColumn) && !columnIsNumeric(yColumn);
1797
+ const categoryColumn = string(chartTypeName === "pie" || chartTypeName === "radar" ? encode.category : horizontal ? encode.y : encode.x) ?? columns[0] ?? "category";
1798
+ const valueColumn = string(chartTypeName === "pie" ? encode.value : horizontal ? encode.x : encode.y) ?? columns[1] ?? "value";
1799
+ const categoryIndex = columns.indexOf(categoryColumn);
1800
+ const valueIndex = columns.indexOf(valueColumn);
1801
+ const selectedRows = (() => {
1802
+ const filter = record(item.dataFilter);
1803
+ const filterColumn = string(filter?.col);
1804
+ if (filterColumn === void 0) return rows;
1805
+ const filterIndex = columns.indexOf(filterColumn);
1806
+ return rows.filter((row) => row[filterIndex] === filter?.value);
1807
+ })();
1808
+ const filteredRows = horizontal ? [...selectedRows].reverse() : selectedRows;
1809
+ const filteredLabels = filteredRows.map((row) => {
1810
+ const value = row[categoryIndex];
1811
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : "";
1812
+ });
1813
+ const values = filteredRows.map((row) => Number(row[valueIndex] ?? 0));
1814
+ const type = chartTypeName === "line" ? pptx.ChartType.line : chartTypeName === "area" ? pptx.ChartType.area : chartTypeName === "scatter" ? pptx.ChartType.scatter : chartTypeName === "bubble" ? pptx.ChartType.bubble : chartTypeName === "radar" ? pptx.ChartType.radar : chartTypeName === "pie" && (number(item.innerRadius) ?? 0) > 0 ? pptx.ChartType.doughnut : chartTypeName === "pie" ? pptx.ChartType.pie : pptx.ChartType.bar;
1815
+ const chartColors = (resolvePptdChartSeriesColors(project, chartTypeName === "line" || chartTypeName === "area" || chartTypeName === "radar" ? item.lineColor ?? item.areaColor : item.fill) ?? [PPTD_CHART_SERIES_PALETTE[index % PPTD_CHART_SERIES_PALETTE.length] ?? "#2563EB"]).map((value) => colorOptions(project, value, 1).color);
1816
+ const labelsConfig = record(item.dataLabels);
1817
+ const showLabels = boolean(labelsConfig?.show) === true;
1818
+ const showPercent = labelsConfig?.content === "percentage";
1819
+ const dataLabelFontSize = number(labelsConfig?.fontSize);
1820
+ const dataLabelColor = labelsConfig?.color === void 0 ? foregroundColor : colorOptions(project, labelsConfig.color).color;
1821
+ const axisIndex = Math.max(0, Math.trunc(number(item.yAxisIndex) ?? 0));
1822
+ const valueAxis = horizontal ? xAxis : yAxes[axisIndex] ?? yAxes[0] ?? {};
1823
+ const valueAxisLabel = record(valueAxis.label) ?? {};
1824
+ const valueAxisGrid = record(valueAxis.gridLine);
1825
+ const valueAxisMin = number(valueAxis.min);
1826
+ const valueAxisMax = number(valueAxis.max);
1827
+ const valueAxisLabelFontSize = number(valueAxisLabel.fontSize);
1828
+ const valueAxisTitle = string(valueAxis.title);
1829
+ const groupOptions = {
1830
+ ...horizontal ? { barDir: "bar" } : chartTypeName === "bar" ? { barDir: "col" } : {},
1831
+ ...axisIndex === 1 ? { secondaryValAxis: true } : {},
1832
+ ...valueAxisMin === void 0 ? {} : { valAxisMinVal: valueAxisMin },
1833
+ ...valueAxisMax === void 0 ? {} : { valAxisMaxVal: valueAxisMax },
1834
+ ...valueAxisLabelFontSize === void 0 ? {} : { valAxisLabelFontSize: valueAxisLabelFontSize },
1835
+ ...valueAxisTitle === void 0 ? {} : {
1836
+ showValAxisTitle: true,
1837
+ valAxisTitle: valueAxisTitle
1838
+ },
1839
+ ...valueAxis.gridLine === false ? { valGridLine: { style: "none" } } : valueAxisGrid === void 0 ? {} : { valGridLine: {
1840
+ color: colorOptions(project, valueAxisGrid.color, 1).color,
1841
+ style: dash(valueAxisGrid.style)
1842
+ } },
1843
+ ...showLabels && !showPercent ? { showValue: true } : {},
1844
+ ...showLabels && showPercent ? { showPercent: true } : {},
1845
+ dataLabelColor,
1846
+ ...dataLabelFontSize === void 0 ? {} : {
1847
+ dataLabelFontSize,
1848
+ dataLabelPosition: "outEnd"
1849
+ },
1850
+ ...chartTypeName === "line" ? {
1851
+ lineSize: number(item.width) ?? 2,
1852
+ lineDataSymbol: "circle"
1853
+ } : {},
1854
+ ...chartTypeName === "area" ? { lineSize: number(item.width) ?? 2 } : {},
1855
+ ...chartTypeName === "radar" ? { radarStyle: item.areaColor === void 0 ? "marker" : "filled" } : {},
1856
+ ...(chartTypeName === "line" || chartTypeName === "area") && item.marker === false ? { lineDataSymbol: "none" } : {},
1857
+ ...(chartTypeName === "line" || chartTypeName === "area") && record(item.marker) !== void 0 ? {
1858
+ lineDataSymbol: record(item.marker)?.shape === "rect" ? "square" : string(record(item.marker)?.shape) ?? "circle",
1859
+ lineDataSymbolSize: number(record(item.marker)?.size) ?? 6
1860
+ } : {},
1861
+ ...item.stack === "percent" ? { barGrouping: "percentStacked" } : item.stack === "value" || item.stack === "stream" ? { barGrouping: "stacked" } : chartTypeName === "bar" ? { barGrouping: "clustered" } : {},
1862
+ ...item.nullHandling === "gap" ? { displayBlanksAs: "gap" } : { displayBlanksAs: "span" },
1863
+ ...type === pptx.ChartType.doughnut ? { holeSize: Math.round((number(item.innerRadius) ?? .5) * 100) } : {}
1864
+ };
1865
+ const dataSeries = {
1866
+ name: string(item.name) ?? valueColumn ?? `Series ${index + 1}`,
1867
+ labels: filteredLabels,
1868
+ values,
1869
+ ...chartTypeName === "bubble" ? { sizes: filteredRows.map((row) => Number(row[columns.indexOf(string(encode.size) ?? "")] ?? 0)) } : {}
1870
+ };
1871
+ const mergeable = type !== pptx.ChartType.pie && type !== pptx.ChartType.doughnut;
1872
+ const groupKey = chartTypeName === "bar" ? `${type}:${horizontal ? "horizontal" : "vertical"}:${axisIndex}:${String(groupOptions.barGrouping)}` : `${type}:${JSON.stringify(groupOptions)}`;
1873
+ const existing = mergeable ? mergeableGroups.get(groupKey) : void 0;
1874
+ if (existing === void 0) {
1875
+ const chartGroup = {
1876
+ type,
1877
+ data: [dataSeries],
1878
+ options: {
1879
+ ...groupOptions,
1880
+ chartColors
1881
+ }
1882
+ };
1883
+ types.push(chartGroup);
1884
+ if (mergeable) mergeableGroups.set(groupKey, chartGroup);
1885
+ continue;
1886
+ }
1887
+ existing.data.push(dataSeries);
1888
+ existing.options.chartColors = [...existing.options.chartColors ?? [], ...chartColors];
1889
+ if (groupOptions.showValue === true) existing.options.showValue = true;
1890
+ if (groupOptions.showPercent === true) existing.options.showPercent = true;
1891
+ if (existing.options.dataLabelFontSize === void 0 && groupOptions.dataLabelFontSize !== void 0) existing.options.dataLabelFontSize = groupOptions.dataLabelFontSize;
1892
+ }
1893
+ const legend = typeof element.legend === "boolean" ? { show: element.legend } : record(element.legend) ?? {};
1894
+ const font = fontFace(element.fontFamily, "Arial", JSON.stringify(types.map(group => group.data)));
1895
+ const objectName = string(element.elementId);
1896
+ const title = typeof element.title === "string" ? { text: element.title } : record(element.title) ?? {};
1897
+ const chartFill = solidFill(project, element.fill);
1898
+ const chartBorder = border(project, element.border);
1899
+ const legendFontSize = number(legend.fontSize);
1900
+ const titleFontSize = number(title.fontSize);
1901
+ const titleText = string(title.text);
1902
+ const barGap = number(element.barGap);
1903
+ const valAxes = series.some((item) => Math.trunc(number(item.yAxisIndex) ?? 0) === 1) ? [valueAxisOptions(project, yAxes[0] ?? {}), valueAxisOptions(project, yAxes[1] ?? {})] : void 0;
1904
+ const common = {
1905
+ ...frame(element),
1906
+ ...objectName === void 0 ? {} : { objectName },
1907
+ showLegend: boolean(legend.show) ?? series.some((item) => ![
1908
+ "waterfall",
1909
+ "heatmap",
1910
+ "treemap",
1911
+ "sunburst",
1912
+ "sankey"
1913
+ ].includes(string(item.type) ?? "")),
1914
+ legendPos: legendPosition(legend.position),
1915
+ legendFontFace: fontFace(legend.fontFamily, font),
1916
+ legendColor: colorOptions(project, legend.color ?? `#${foregroundColor}`).color,
1917
+ ...legendFontSize === void 0 ? {} : { legendFontSize },
1918
+ catAxisLabelFontFace: font,
1919
+ catAxisLabelColor: foregroundColor,
1920
+ catAxisLineColor: foregroundColor,
1921
+ valAxisLabelFontFace: font,
1922
+ valAxisLabelColor: foregroundColor,
1923
+ valAxisLineColor: foregroundColor,
1924
+ showTitle: titleText !== void 0,
1925
+ ...titleText === void 0 ? {} : { title: titleText },
1926
+ titleFontFace: fontFace(title.fontFamily, font),
1927
+ titleColor: colorOptions(project, title.color ?? `#${foregroundColor}`).color,
1928
+ ...titleFontSize === void 0 ? {} : { titleFontSize },
1929
+ showValue: false,
1930
+ chartArea: {
1931
+ border: chartBorder === void 0 ? {
1932
+ color: "FFFFFF",
1933
+ pt: 0
1934
+ } : {
1935
+ color: chartBorder.color,
1936
+ pt: chartBorder.width
1937
+ },
1938
+ fill: chartFill ?? {
1939
+ color: "FFFFFF",
1940
+ transparency: 100
1941
+ }
1942
+ },
1943
+ plotArea: {
1944
+ border: {
1945
+ color: "FFFFFF",
1946
+ pt: 0
1947
+ },
1948
+ fill: {
1949
+ color: "FFFFFF",
1950
+ transparency: 100
1951
+ }
1952
+ },
1953
+ ...barGap === void 0 ? {} : { barGapWidthPct: Math.round(barGap * 100) },
1954
+ ...valAxes === void 0 ? {} : { valAxes },
1955
+ ...chartAxisOptions(project, element, series.some((item) => {
1956
+ const encode = record(item.encode) ?? {};
1957
+ return string(item.type) === "bar" && columnIsNumeric(string(encode.x)) && !columnIsNumeric(string(encode.y));
1958
+ }))
1959
+ };
1960
+ slide.addChart(types, common);
1961
+ }
1962
+ function renderIcon(project, slide, element) {
1963
+ const color = colorOptions(project, element.color).color;
1964
+ const objectName = string(element.elementId);
1965
+ slide.addText(string(element.iconName) ?? "●", {
1966
+ ...frame(element),
1967
+ ...objectName === void 0 ? {} : { objectName },
1968
+ fontFace: "Arial",
1969
+ fontSize: 18,
1970
+ color,
1971
+ margin: 0,
1972
+ align: "center",
1973
+ valign: "middle",
1974
+ fit: "shrink"
1975
+ });
1976
+ }
1977
+ function renderElement(project, pptx, slide, element, foregroundColor) {
1978
+ if (element.elementType === "text") {
1979
+ renderText(project, slide, element);
1980
+ return;
1981
+ }
1982
+ if (element.elementType === "shape") {
1983
+ renderShape(project, pptx, slide, element);
1984
+ return;
1985
+ }
1986
+ if (element.elementType === "line") {
1987
+ renderLine(project, pptx, slide, element);
1988
+ return;
1989
+ }
1990
+ if (element.elementType === "image") {
1991
+ renderImage(project, slide, element);
1992
+ return;
1993
+ }
1994
+ if (element.elementType === "table") {
1995
+ renderTable(project, slide, element);
1996
+ return;
1997
+ }
1998
+ if (element.elementType === "chart") {
1999
+ renderChart(project, pptx, slide, element, foregroundColor);
2000
+ return;
2001
+ }
2002
+ if (element.elementType === "icon") {
2003
+ renderIcon(project, slide, element);
2004
+ return;
2005
+ }
2006
+ }
2007
+ /** Render one checked PPTD AST to editable native PowerPoint objects. */
2008
+ async function renderPptdProject(project) {
2009
+ const check = checkPptdProject(project);
2010
+ if (check.status === "fail") {
2011
+ const details = check.issues.filter((issue) => issue.severity === "error").slice(0, 3).map((issue) => `${issue.code}${issue.elementId === void 0 ? "" : `(${issue.elementId})`}: ${issue.message}`).join("; ");
2012
+ throw new Error(`PPTD rendering requires a passing check; received ${check.errorCount} errors${details === "" ? "" : `: ${details}`}`);
2013
+ }
2014
+ const pptx = new PptxGenJS();
2015
+ const layoutName = `DSH_PPTD_${project.width}x${project.height}`;
2016
+ pptx.defineLayout({
2017
+ name: layoutName,
2018
+ width: inches(project.width),
2019
+ height: inches(project.height)
2020
+ });
2021
+ pptx.layout = layoutName;
2022
+ pptx.author = "DSH PPTD";
2023
+ pptx.company = "DeepSeek Harness";
2024
+ pptx.subject = "Local PPTD v2 editable rendering";
2025
+ pptx.title = project.title;
2026
+ const textStyles = themeMap(project, "textStyles");
2027
+ const titleStyle = record(textStyles.title) ?? {};
2028
+ const bodyStyle = record(textStyles.body) ?? {};
2029
+ pptx.theme = {
2030
+ headFontFace: fontFace(titleStyle.fontFamily, "Arial"),
2031
+ bodyFontFace: fontFace(bodyStyle.fontFamily, "Arial")
2032
+ };
2033
+ for (const page of project.pages) {
2034
+ const slide = pptx.addSlide();
2035
+ const background = solidFill(project, page.background);
2036
+ slide.background = background ?? { color: "FFFFFF" };
2037
+ const foregroundColor = readableForeground(background?.color ?? "FFFFFF");
2038
+ for (const element of page.elements) renderElement(project, pptx, slide, element, foregroundColor);
2039
+ if (page.notes.trim() !== "") slide.addNotes(page.notes);
2040
+ }
2041
+ const output = await pptx.write({
2042
+ outputType: "nodebuffer",
2043
+ compression: true
2044
+ });
2045
+ return {
2046
+ bytes: new Uint8Array(output),
2047
+ nativeObjectCount: check.nativeObjectCount,
2048
+ check
2049
+ };
2050
+ }
2051
+ function mediaType(file, bytes) {
2052
+ const extension = path.extname(file).toLowerCase();
2053
+ if (extension === ".png" && bytes[0] === 137 && bytes[1] === 80) return "image/png";
2054
+ if ((extension === ".jpg" || extension === ".jpeg") && bytes[0] === 255 && bytes[1] === 216) return "image/jpeg";
2055
+ if (extension === ".gif" && Buffer.from(bytes.subarray(0, 3)).toString("ascii") === "GIF") return "image/gif";
2056
+ if (extension === ".webp" && Buffer.from(bytes.subarray(8, 12)).toString("ascii") === "WEBP") return "image/webp";
2057
+ if (extension === ".svg" && Buffer.from(bytes.subarray(0, 512)).toString("utf8").includes("<svg")) return "image/svg+xml";
2058
+ }
2059
+ async function confinedFile(root, relative, maximumBytes) {
2060
+ const safe = safeProjectPath(relative);
2061
+ if (safe === void 0) throw new Error(`PPTD path is not project-relative: ${relative}`);
2062
+ const target = await realpath(path.join(root, ...safe.split("/")));
2063
+ if (target !== root && !target.startsWith(`${root}${path.sep}`)) throw new Error(`PPTD path escapes the project root: ${relative}`);
2064
+ const metadata = await lstat(target);
2065
+ if (!metadata.isFile() || metadata.size > maximumBytes) throw new Error(`PPTD file is invalid or too large: ${relative}`);
2066
+ return {
2067
+ real: target,
2068
+ bytes: await readFile(target)
2069
+ };
2070
+ }
2071
+ /** Resolve a PPTD entry file from either the entry itself or its project directory. */
2072
+ async function resolvePptdEntry(inputPath) {
2073
+ const input = await realpath(path.resolve(inputPath));
2074
+ const metadata = await lstat(input);
2075
+ if (metadata.isFile()) {
2076
+ if (!input.endsWith(".pptd")) throw new Error("PPTD entry must use the .pptd extension");
2077
+ return input;
2078
+ }
2079
+ if (!metadata.isDirectory()) throw new Error("PPTD input must be an entry file or project directory");
2080
+ const entries = (await readdir(input, { withFileTypes: true })).filter((entry) => entry.isFile() && entry.name.endsWith(".pptd")).map((entry) => entry.name).sort();
2081
+ if (entries.length !== 1) throw new Error(`PPTD project directory must contain exactly one .pptd entry; found ${entries.length}`);
2082
+ const entry = entries.at(0);
2083
+ if (entry === void 0) throw new Error("PPTD project directory must contain one .pptd entry");
2084
+ return path.join(input, entry);
2085
+ }
2086
+ /** Load a confined local PPTD project. Network resources stay disabled. */
2087
+ async function loadPptdProject(entryPath) {
2088
+ const entry = await resolvePptdEntry(entryPath);
2089
+ const metadata = await lstat(entry);
2090
+ if (!metadata.isFile() || metadata.size > MAX_MANIFEST_BYTES) throw new Error("PPTD entry is invalid or too large");
2091
+ const root = path.dirname(entry);
2092
+ const manifest = await readFile(entry, "utf8");
2093
+ const raw = parseYaml(manifest, path.basename(entry), []);
2094
+ if (raw === void 0) return parsePptdProject({
2095
+ entryName: path.basename(entry),
2096
+ manifest,
2097
+ pages: /* @__PURE__ */ new Map(),
2098
+ assets: /* @__PURE__ */ new Map()
2099
+ });
2100
+ const refs = Array.isArray(raw.pages) ? raw.pages.slice(0, MAX_PAGES) : [];
2101
+ const pages = /* @__PURE__ */ new Map();
2102
+ const loadIssues = [];
2103
+ for (const rawRef of refs) {
2104
+ const ref = typeof rawRef === "string" ? safeProjectPath(rawRef) : void 0;
2105
+ if (ref === void 0) continue;
2106
+ try {
2107
+ const file = await confinedFile(root, ref, MAX_PAGE_BYTES);
2108
+ pages.set(ref, Buffer.from(file.bytes).toString("utf8"));
2109
+ } catch (error) {
2110
+ loadIssues.push({
2111
+ code: "file-read",
2112
+ severity: "error",
2113
+ file: ref,
2114
+ message: `无法读取页面文件 ${ref}:${error instanceof Error ? error.message : String(error)}`
2115
+ });
2116
+ }
2117
+ }
2118
+ const partial = parsePptdProject({
2119
+ entryName: path.basename(entry),
2120
+ manifest,
2121
+ pages,
2122
+ assets: /* @__PURE__ */ new Map(),
2123
+ issues: loadIssues
2124
+ });
2125
+ const refsToLoad = /* @__PURE__ */ new Set();
2126
+ for (const page of partial.pages) for (const element of page.elements) if (element.elementType === "image") {
2127
+ const ref = localAssetPath(element.src);
2128
+ if (ref !== void 0) refsToLoad.add(ref);
2129
+ }
2130
+ const assets = /* @__PURE__ */ new Map();
2131
+ let totalBytes = 0;
2132
+ for (const ref of refsToLoad) {
2133
+ let file;
2134
+ try {
2135
+ file = await confinedFile(root, ref, MAX_ASSET_BYTES);
2136
+ } catch (error) {
2137
+ loadIssues.push({
2138
+ code: "file-read",
2139
+ severity: "error",
2140
+ file: ref,
2141
+ message: `无法读取资源 ${ref}:${error instanceof Error ? error.message : String(error)}`
2142
+ });
2143
+ continue;
2144
+ }
2145
+ totalBytes += file.bytes.byteLength;
2146
+ if (totalBytes > MAX_TOTAL_ASSET_BYTES) throw new Error("PPTD image resources exceed the aggregate byte limit");
2147
+ const type = mediaType(ref, file.bytes);
2148
+ if (type === void 0) {
2149
+ loadIssues.push({
2150
+ code: "invalid-resource",
2151
+ severity: "error",
2152
+ file: ref,
2153
+ message: `图片资源格式或内容无效:${ref}`
2154
+ });
2155
+ continue;
2156
+ }
2157
+ assets.set(ref, {
2158
+ path: ref,
2159
+ mediaType: type,
2160
+ bytes: file.bytes,
2161
+ sha256: createHash("sha256").update(file.bytes).digest("hex")
2162
+ });
2163
+ }
2164
+ return parsePptdProject({
2165
+ entryName: path.basename(entry),
2166
+ manifest,
2167
+ pages,
2168
+ assets,
2169
+ issues: loadIssues
2170
+ });
2171
+ }
2172
+ //#endregion
2173
+ export { resolvePptdEntry as a, renderPptdProject as i, loadPptdProject as n, recommendedTextCapacity as o, parsePptdProject as r, checkPptdProject as t };