@projektemacher/storymapjs 0.10.7 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (587) hide show
  1. package/CHANGELOG +431 -19
  2. package/README.md +168 -17
  3. package/dist/assets/demo-bWnOyfUw.js +1 -0
  4. package/dist/assets/harness-C3JUv5Ii.js +1 -0
  5. package/dist/assets/harness-multi-XZNex3tb.js +1 -0
  6. package/dist/assets/harness-support-CjfZIVeb.js +1 -0
  7. package/dist/assets/index-wHPqGrBS.js +1 -0
  8. package/dist/assets/main-DQ32hWBM.js +17 -0
  9. package/dist/context.json +23 -9
  10. package/dist/css/fonts/files/amatic-sc-cyrillic-400-normal.woff2 +0 -0
  11. package/dist/css/fonts/files/amatic-sc-cyrillic-700-normal.woff2 +0 -0
  12. package/dist/css/fonts/files/amatic-sc-hebrew-400-normal.woff2 +0 -0
  13. package/dist/css/fonts/files/amatic-sc-hebrew-700-normal.woff2 +0 -0
  14. package/dist/css/fonts/files/amatic-sc-vietnamese-400-normal.woff2 +0 -0
  15. package/dist/css/fonts/files/amatic-sc-vietnamese-700-normal.woff2 +0 -0
  16. package/dist/css/fonts/files/bitter-cyrillic-100-italic.woff2 +0 -0
  17. package/dist/css/fonts/files/bitter-cyrillic-100-normal.woff2 +0 -0
  18. package/dist/css/fonts/files/bitter-cyrillic-200-italic.woff2 +0 -0
  19. package/dist/css/fonts/files/bitter-cyrillic-200-normal.woff2 +0 -0
  20. package/dist/css/fonts/files/bitter-cyrillic-300-italic.woff2 +0 -0
  21. package/dist/css/fonts/files/bitter-cyrillic-300-normal.woff2 +0 -0
  22. package/dist/css/fonts/files/bitter-cyrillic-400-italic.woff2 +0 -0
  23. package/dist/css/fonts/files/bitter-cyrillic-400-normal.woff2 +0 -0
  24. package/dist/css/fonts/files/bitter-cyrillic-500-italic.woff2 +0 -0
  25. package/dist/css/fonts/files/bitter-cyrillic-500-normal.woff2 +0 -0
  26. package/dist/css/fonts/files/bitter-cyrillic-600-italic.woff2 +0 -0
  27. package/dist/css/fonts/files/bitter-cyrillic-600-normal.woff2 +0 -0
  28. package/dist/css/fonts/files/bitter-cyrillic-700-italic.woff2 +0 -0
  29. package/dist/css/fonts/files/bitter-cyrillic-700-normal.woff2 +0 -0
  30. package/dist/css/fonts/files/bitter-cyrillic-800-italic.woff2 +0 -0
  31. package/dist/css/fonts/files/bitter-cyrillic-800-normal.woff2 +0 -0
  32. package/dist/css/fonts/files/bitter-cyrillic-900-italic.woff2 +0 -0
  33. package/dist/css/fonts/files/bitter-cyrillic-900-normal.woff2 +0 -0
  34. package/dist/css/fonts/files/bitter-cyrillic-ext-100-italic.woff2 +0 -0
  35. package/dist/css/fonts/files/bitter-cyrillic-ext-100-normal.woff2 +0 -0
  36. package/dist/css/fonts/files/bitter-cyrillic-ext-200-italic.woff2 +0 -0
  37. package/dist/css/fonts/files/bitter-cyrillic-ext-200-normal.woff2 +0 -0
  38. package/dist/css/fonts/files/bitter-cyrillic-ext-300-italic.woff2 +0 -0
  39. package/dist/css/fonts/files/bitter-cyrillic-ext-300-normal.woff2 +0 -0
  40. package/dist/css/fonts/files/bitter-cyrillic-ext-400-italic.woff2 +0 -0
  41. package/dist/css/fonts/files/bitter-cyrillic-ext-400-normal.woff2 +0 -0
  42. package/dist/css/fonts/files/bitter-cyrillic-ext-500-italic.woff2 +0 -0
  43. package/dist/css/fonts/files/bitter-cyrillic-ext-500-normal.woff2 +0 -0
  44. package/dist/css/fonts/files/bitter-cyrillic-ext-600-italic.woff2 +0 -0
  45. package/dist/css/fonts/files/bitter-cyrillic-ext-600-normal.woff2 +0 -0
  46. package/dist/css/fonts/files/bitter-cyrillic-ext-700-italic.woff2 +0 -0
  47. package/dist/css/fonts/files/bitter-cyrillic-ext-700-normal.woff2 +0 -0
  48. package/dist/css/fonts/files/bitter-cyrillic-ext-800-italic.woff2 +0 -0
  49. package/dist/css/fonts/files/bitter-cyrillic-ext-800-normal.woff2 +0 -0
  50. package/dist/css/fonts/files/bitter-cyrillic-ext-900-italic.woff2 +0 -0
  51. package/dist/css/fonts/files/bitter-cyrillic-ext-900-normal.woff2 +0 -0
  52. package/dist/css/fonts/files/bitter-cyrillic-ext-wght-italic.woff2 +0 -0
  53. package/dist/css/fonts/files/bitter-cyrillic-ext-wght-normal.woff2 +0 -0
  54. package/dist/css/fonts/files/bitter-cyrillic-wght-italic.woff2 +0 -0
  55. package/dist/css/fonts/files/bitter-cyrillic-wght-normal.woff2 +0 -0
  56. package/dist/css/fonts/files/bitter-vietnamese-100-italic.woff2 +0 -0
  57. package/dist/css/fonts/files/bitter-vietnamese-100-normal.woff2 +0 -0
  58. package/dist/css/fonts/files/bitter-vietnamese-200-italic.woff2 +0 -0
  59. package/dist/css/fonts/files/bitter-vietnamese-200-normal.woff2 +0 -0
  60. package/dist/css/fonts/files/bitter-vietnamese-300-italic.woff2 +0 -0
  61. package/dist/css/fonts/files/bitter-vietnamese-300-normal.woff2 +0 -0
  62. package/dist/css/fonts/files/bitter-vietnamese-400-italic.woff2 +0 -0
  63. package/dist/css/fonts/files/bitter-vietnamese-400-normal.woff2 +0 -0
  64. package/dist/css/fonts/files/bitter-vietnamese-500-italic.woff2 +0 -0
  65. package/dist/css/fonts/files/bitter-vietnamese-500-normal.woff2 +0 -0
  66. package/dist/css/fonts/files/bitter-vietnamese-600-italic.woff2 +0 -0
  67. package/dist/css/fonts/files/bitter-vietnamese-600-normal.woff2 +0 -0
  68. package/dist/css/fonts/files/bitter-vietnamese-700-italic.woff2 +0 -0
  69. package/dist/css/fonts/files/bitter-vietnamese-700-normal.woff2 +0 -0
  70. package/dist/css/fonts/files/bitter-vietnamese-800-italic.woff2 +0 -0
  71. package/dist/css/fonts/files/bitter-vietnamese-800-normal.woff2 +0 -0
  72. package/dist/css/fonts/files/bitter-vietnamese-900-italic.woff2 +0 -0
  73. package/dist/css/fonts/files/bitter-vietnamese-900-normal.woff2 +0 -0
  74. package/dist/css/fonts/files/bitter-vietnamese-wght-italic.woff2 +0 -0
  75. package/dist/css/fonts/files/bitter-vietnamese-wght-normal.woff2 +0 -0
  76. package/dist/css/fonts/files/cairo-arabic-200-normal.woff2 +0 -0
  77. package/dist/css/fonts/files/cairo-arabic-300-normal.woff2 +0 -0
  78. package/dist/css/fonts/files/cairo-arabic-400-normal.woff2 +0 -0
  79. package/dist/css/fonts/files/cairo-arabic-500-normal.woff2 +0 -0
  80. package/dist/css/fonts/files/cairo-arabic-600-normal.woff2 +0 -0
  81. package/dist/css/fonts/files/cairo-arabic-700-normal.woff2 +0 -0
  82. package/dist/css/fonts/files/cairo-arabic-800-normal.woff2 +0 -0
  83. package/dist/css/fonts/files/cairo-arabic-900-normal.woff2 +0 -0
  84. package/dist/css/fonts/files/cairo-latin-200-normal.woff2 +0 -0
  85. package/dist/css/fonts/files/cairo-latin-300-normal.woff2 +0 -0
  86. package/dist/css/fonts/files/cairo-latin-400-normal.woff2 +0 -0
  87. package/dist/css/fonts/files/cairo-latin-500-normal.woff2 +0 -0
  88. package/dist/css/fonts/files/cairo-latin-600-normal.woff2 +0 -0
  89. package/dist/css/fonts/files/cairo-latin-700-normal.woff2 +0 -0
  90. package/dist/css/fonts/files/cairo-latin-800-normal.woff2 +0 -0
  91. package/dist/css/fonts/files/cairo-latin-900-normal.woff2 +0 -0
  92. package/dist/css/fonts/files/cairo-latin-ext-200-normal.woff2 +0 -0
  93. package/dist/css/fonts/files/cairo-latin-ext-300-normal.woff2 +0 -0
  94. package/dist/css/fonts/files/cairo-latin-ext-400-normal.woff2 +0 -0
  95. package/dist/css/fonts/files/cairo-latin-ext-500-normal.woff2 +0 -0
  96. package/dist/css/fonts/files/cairo-latin-ext-600-normal.woff2 +0 -0
  97. package/dist/css/fonts/files/cairo-latin-ext-700-normal.woff2 +0 -0
  98. package/dist/css/fonts/files/cairo-latin-ext-800-normal.woff2 +0 -0
  99. package/dist/css/fonts/files/cairo-latin-ext-900-normal.woff2 +0 -0
  100. package/dist/css/fonts/files/dancing-script-vietnamese-wght-normal.woff2 +0 -0
  101. package/dist/css/fonts/files/eb-garamond-cyrillic-ext-wght-italic.woff2 +0 -0
  102. package/dist/css/fonts/files/eb-garamond-cyrillic-ext-wght-normal.woff2 +0 -0
  103. package/dist/css/fonts/files/eb-garamond-cyrillic-wght-italic.woff2 +0 -0
  104. package/dist/css/fonts/files/eb-garamond-cyrillic-wght-normal.woff2 +0 -0
  105. package/dist/css/fonts/files/eb-garamond-greek-ext-wght-italic.woff2 +0 -0
  106. package/dist/css/fonts/files/eb-garamond-greek-ext-wght-normal.woff2 +0 -0
  107. package/dist/css/fonts/files/eb-garamond-greek-wght-italic.woff2 +0 -0
  108. package/dist/css/fonts/files/eb-garamond-greek-wght-normal.woff2 +0 -0
  109. package/dist/css/fonts/files/eb-garamond-vietnamese-wght-italic.woff2 +0 -0
  110. package/dist/css/fonts/files/eb-garamond-vietnamese-wght-normal.woff2 +0 -0
  111. package/dist/css/fonts/files/gentium-book-plus-cyrillic-400-italic.woff2 +0 -0
  112. package/dist/css/fonts/files/gentium-book-plus-cyrillic-400-normal.woff2 +0 -0
  113. package/dist/css/fonts/files/gentium-book-plus-cyrillic-700-italic.woff2 +0 -0
  114. package/dist/css/fonts/files/gentium-book-plus-cyrillic-700-normal.woff2 +0 -0
  115. package/dist/css/fonts/files/gentium-book-plus-cyrillic-ext-400-italic.woff2 +0 -0
  116. package/dist/css/fonts/files/gentium-book-plus-cyrillic-ext-400-normal.woff2 +0 -0
  117. package/dist/css/fonts/files/gentium-book-plus-cyrillic-ext-700-italic.woff2 +0 -0
  118. package/dist/css/fonts/files/gentium-book-plus-cyrillic-ext-700-normal.woff2 +0 -0
  119. package/dist/css/fonts/files/gentium-book-plus-greek-400-italic.woff2 +0 -0
  120. package/dist/css/fonts/files/gentium-book-plus-greek-400-normal.woff2 +0 -0
  121. package/dist/css/fonts/files/gentium-book-plus-greek-700-italic.woff2 +0 -0
  122. package/dist/css/fonts/files/gentium-book-plus-greek-700-normal.woff2 +0 -0
  123. package/dist/css/fonts/files/gentium-book-plus-greek-ext-400-italic.woff2 +0 -0
  124. package/dist/css/fonts/files/gentium-book-plus-greek-ext-400-normal.woff2 +0 -0
  125. package/dist/css/fonts/files/gentium-book-plus-greek-ext-700-italic.woff2 +0 -0
  126. package/dist/css/fonts/files/gentium-book-plus-greek-ext-700-normal.woff2 +0 -0
  127. package/dist/css/fonts/files/gentium-book-plus-vietnamese-400-italic.woff2 +0 -0
  128. package/dist/css/fonts/files/gentium-book-plus-vietnamese-400-normal.woff2 +0 -0
  129. package/dist/css/fonts/files/gentium-book-plus-vietnamese-700-italic.woff2 +0 -0
  130. package/dist/css/fonts/files/gentium-book-plus-vietnamese-700-normal.woff2 +0 -0
  131. package/dist/css/fonts/files/old-standard-tt-cyrillic-400-italic.woff2 +0 -0
  132. package/dist/css/fonts/files/old-standard-tt-cyrillic-400-normal.woff2 +0 -0
  133. package/dist/css/fonts/files/old-standard-tt-cyrillic-700-normal.woff2 +0 -0
  134. package/dist/css/fonts/files/old-standard-tt-cyrillic-ext-400-italic.woff2 +0 -0
  135. package/dist/css/fonts/files/old-standard-tt-cyrillic-ext-400-normal.woff2 +0 -0
  136. package/dist/css/fonts/files/old-standard-tt-cyrillic-ext-700-normal.woff2 +0 -0
  137. package/dist/css/fonts/files/old-standard-tt-vietnamese-400-italic.woff2 +0 -0
  138. package/dist/css/fonts/files/old-standard-tt-vietnamese-400-normal.woff2 +0 -0
  139. package/dist/css/fonts/files/old-standard-tt-vietnamese-700-normal.woff2 +0 -0
  140. package/dist/css/fonts/files/open-sans-cyrillic-ext-wght-italic.woff2 +0 -0
  141. package/dist/css/fonts/files/open-sans-cyrillic-ext-wght-normal.woff2 +0 -0
  142. package/dist/css/fonts/files/open-sans-cyrillic-wght-italic.woff2 +0 -0
  143. package/dist/css/fonts/files/open-sans-cyrillic-wght-normal.woff2 +0 -0
  144. package/dist/css/fonts/files/open-sans-greek-ext-wght-italic.woff2 +0 -0
  145. package/dist/css/fonts/files/open-sans-greek-ext-wght-normal.woff2 +0 -0
  146. package/dist/css/fonts/files/open-sans-greek-wght-italic.woff2 +0 -0
  147. package/dist/css/fonts/files/open-sans-greek-wght-normal.woff2 +0 -0
  148. package/dist/css/fonts/files/open-sans-hebrew-wght-italic.woff2 +0 -0
  149. package/dist/css/fonts/files/open-sans-hebrew-wght-normal.woff2 +0 -0
  150. package/dist/css/fonts/files/open-sans-vietnamese-wght-italic.woff2 +0 -0
  151. package/dist/css/fonts/files/open-sans-vietnamese-wght-normal.woff2 +0 -0
  152. package/dist/css/fonts/files/playfair-display-cyrillic-wght-italic.woff2 +0 -0
  153. package/dist/css/fonts/files/playfair-display-cyrillic-wght-normal.woff2 +0 -0
  154. package/dist/css/fonts/files/playfair-display-sc-cyrillic-400-italic.woff2 +0 -0
  155. package/dist/css/fonts/files/playfair-display-sc-cyrillic-400-normal.woff2 +0 -0
  156. package/dist/css/fonts/files/playfair-display-sc-cyrillic-700-italic.woff2 +0 -0
  157. package/dist/css/fonts/files/playfair-display-sc-cyrillic-700-normal.woff2 +0 -0
  158. package/dist/css/fonts/files/playfair-display-sc-cyrillic-900-italic.woff2 +0 -0
  159. package/dist/css/fonts/files/playfair-display-sc-cyrillic-900-normal.woff2 +0 -0
  160. package/dist/css/fonts/files/playfair-display-sc-vietnamese-400-italic.woff2 +0 -0
  161. package/dist/css/fonts/files/playfair-display-sc-vietnamese-400-normal.woff2 +0 -0
  162. package/dist/css/fonts/files/playfair-display-sc-vietnamese-700-italic.woff2 +0 -0
  163. package/dist/css/fonts/files/playfair-display-sc-vietnamese-700-normal.woff2 +0 -0
  164. package/dist/css/fonts/files/playfair-display-sc-vietnamese-900-italic.woff2 +0 -0
  165. package/dist/css/fonts/files/playfair-display-sc-vietnamese-900-normal.woff2 +0 -0
  166. package/dist/css/fonts/files/playfair-display-vietnamese-wght-italic.woff2 +0 -0
  167. package/dist/css/fonts/files/playfair-display-vietnamese-wght-normal.woff2 +0 -0
  168. package/dist/css/fonts/files/pt-sans-cyrillic-400-italic.woff2 +0 -0
  169. package/dist/css/fonts/files/pt-sans-cyrillic-400-normal.woff2 +0 -0
  170. package/dist/css/fonts/files/pt-sans-cyrillic-700-italic.woff2 +0 -0
  171. package/dist/css/fonts/files/pt-sans-cyrillic-700-normal.woff2 +0 -0
  172. package/dist/css/fonts/files/pt-sans-cyrillic-ext-400-italic.woff2 +0 -0
  173. package/dist/css/fonts/files/pt-sans-cyrillic-ext-400-normal.woff2 +0 -0
  174. package/dist/css/fonts/files/pt-sans-cyrillic-ext-700-italic.woff2 +0 -0
  175. package/dist/css/fonts/files/pt-sans-cyrillic-ext-700-normal.woff2 +0 -0
  176. package/dist/css/fonts/files/pt-sans-narrow-cyrillic-400-normal.woff2 +0 -0
  177. package/dist/css/fonts/files/pt-sans-narrow-cyrillic-700-normal.woff2 +0 -0
  178. package/dist/css/fonts/files/pt-sans-narrow-cyrillic-ext-400-normal.woff2 +0 -0
  179. package/dist/css/fonts/files/pt-sans-narrow-cyrillic-ext-700-normal.woff2 +0 -0
  180. package/dist/css/fonts/files/pt-serif-cyrillic-400-italic.woff2 +0 -0
  181. package/dist/css/fonts/files/pt-serif-cyrillic-400-normal.woff2 +0 -0
  182. package/dist/css/fonts/files/pt-serif-cyrillic-700-italic.woff2 +0 -0
  183. package/dist/css/fonts/files/pt-serif-cyrillic-700-normal.woff2 +0 -0
  184. package/dist/css/fonts/files/pt-serif-cyrillic-ext-400-italic.woff2 +0 -0
  185. package/dist/css/fonts/files/pt-serif-cyrillic-ext-400-normal.woff2 +0 -0
  186. package/dist/css/fonts/files/pt-serif-cyrillic-ext-700-italic.woff2 +0 -0
  187. package/dist/css/fonts/files/pt-serif-cyrillic-ext-700-normal.woff2 +0 -0
  188. package/dist/css/fonts/files/raleway-cyrillic-ext-wght-italic.woff2 +0 -0
  189. package/dist/css/fonts/files/raleway-cyrillic-ext-wght-normal.woff2 +0 -0
  190. package/dist/css/fonts/files/raleway-cyrillic-wght-italic.woff2 +0 -0
  191. package/dist/css/fonts/files/raleway-cyrillic-wght-normal.woff2 +0 -0
  192. package/dist/css/fonts/files/raleway-vietnamese-wght-italic.woff2 +0 -0
  193. package/dist/css/fonts/files/raleway-vietnamese-wght-normal.woff2 +0 -0
  194. package/dist/css/fonts/files/roboto-slab-cyrillic-ext-wght-normal.woff2 +0 -0
  195. package/dist/css/fonts/files/roboto-slab-cyrillic-wght-normal.woff2 +0 -0
  196. package/dist/css/fonts/files/roboto-slab-greek-ext-wght-normal.woff2 +0 -0
  197. package/dist/css/fonts/files/roboto-slab-greek-wght-normal.woff2 +0 -0
  198. package/dist/css/fonts/files/roboto-slab-vietnamese-wght-normal.woff2 +0 -0
  199. package/dist/css/fonts/files/ubuntu-cyrillic-300-italic.woff2 +0 -0
  200. package/dist/css/fonts/files/ubuntu-cyrillic-300-normal.woff2 +0 -0
  201. package/dist/css/fonts/files/ubuntu-cyrillic-400-italic.woff2 +0 -0
  202. package/dist/css/fonts/files/ubuntu-cyrillic-400-normal.woff2 +0 -0
  203. package/dist/css/fonts/files/ubuntu-cyrillic-500-italic.woff2 +0 -0
  204. package/dist/css/fonts/files/ubuntu-cyrillic-500-normal.woff2 +0 -0
  205. package/dist/css/fonts/files/ubuntu-cyrillic-700-italic.woff2 +0 -0
  206. package/dist/css/fonts/files/ubuntu-cyrillic-700-normal.woff2 +0 -0
  207. package/dist/css/fonts/files/ubuntu-cyrillic-ext-300-italic.woff2 +0 -0
  208. package/dist/css/fonts/files/ubuntu-cyrillic-ext-300-normal.woff2 +0 -0
  209. package/dist/css/fonts/files/ubuntu-cyrillic-ext-400-italic.woff2 +0 -0
  210. package/dist/css/fonts/files/ubuntu-cyrillic-ext-400-normal.woff2 +0 -0
  211. package/dist/css/fonts/files/ubuntu-cyrillic-ext-500-italic.woff2 +0 -0
  212. package/dist/css/fonts/files/ubuntu-cyrillic-ext-500-normal.woff2 +0 -0
  213. package/dist/css/fonts/files/ubuntu-cyrillic-ext-700-italic.woff2 +0 -0
  214. package/dist/css/fonts/files/ubuntu-cyrillic-ext-700-normal.woff2 +0 -0
  215. package/dist/css/fonts/files/ubuntu-greek-300-italic.woff2 +0 -0
  216. package/dist/css/fonts/files/ubuntu-greek-300-normal.woff2 +0 -0
  217. package/dist/css/fonts/files/ubuntu-greek-400-italic.woff2 +0 -0
  218. package/dist/css/fonts/files/ubuntu-greek-400-normal.woff2 +0 -0
  219. package/dist/css/fonts/files/ubuntu-greek-500-italic.woff2 +0 -0
  220. package/dist/css/fonts/files/ubuntu-greek-500-normal.woff2 +0 -0
  221. package/dist/css/fonts/files/ubuntu-greek-700-italic.woff2 +0 -0
  222. package/dist/css/fonts/files/ubuntu-greek-700-normal.woff2 +0 -0
  223. package/dist/css/fonts/files/ubuntu-greek-ext-300-italic.woff2 +0 -0
  224. package/dist/css/fonts/files/ubuntu-greek-ext-300-normal.woff2 +0 -0
  225. package/dist/css/fonts/files/ubuntu-greek-ext-400-italic.woff2 +0 -0
  226. package/dist/css/fonts/files/ubuntu-greek-ext-400-normal.woff2 +0 -0
  227. package/dist/css/fonts/files/ubuntu-greek-ext-500-italic.woff2 +0 -0
  228. package/dist/css/fonts/files/ubuntu-greek-ext-500-normal.woff2 +0 -0
  229. package/dist/css/fonts/files/ubuntu-greek-ext-700-italic.woff2 +0 -0
  230. package/dist/css/fonts/files/ubuntu-greek-ext-700-normal.woff2 +0 -0
  231. package/dist/css/fonts/files/unica-one-vietnamese-400-normal.woff2 +0 -0
  232. package/dist/css/fonts/files/vollkorn-cyrillic-ext-wght-italic.woff2 +0 -0
  233. package/dist/css/fonts/files/vollkorn-cyrillic-ext-wght-normal.woff2 +0 -0
  234. package/dist/css/fonts/files/vollkorn-cyrillic-wght-italic.woff2 +0 -0
  235. package/dist/css/fonts/files/vollkorn-cyrillic-wght-normal.woff2 +0 -0
  236. package/dist/css/fonts/files/vollkorn-greek-wght-italic.woff2 +0 -0
  237. package/dist/css/fonts/files/vollkorn-greek-wght-normal.woff2 +0 -0
  238. package/dist/css/fonts/files/vollkorn-vietnamese-wght-italic.woff2 +0 -0
  239. package/dist/css/fonts/files/vollkorn-vietnamese-wght-normal.woff2 +0 -0
  240. package/dist/css/fonts/font.abril-droidsans.css +3 -0
  241. package/dist/css/fonts/font.amatic-andika.css +57 -0
  242. package/dist/css/fonts/font.bitter-raleway.css +111 -0
  243. package/dist/css/fonts/font.cairo.css +312 -0
  244. package/dist/css/fonts/font.clicker-garamond.css +93 -0
  245. package/dist/css/fonts/font.dancing-ledger.css +12 -0
  246. package/dist/css/fonts/font.default.css +183 -0
  247. package/dist/css/fonts/font.fjalla-average.css +3 -0
  248. package/dist/css/fonts/font.georgia-helvetica.css +3 -0
  249. package/dist/css/fonts/font.knightlab.css +642 -0
  250. package/dist/css/fonts/font.lustria-lato.css +3 -0
  251. package/dist/css/fonts/font.medula-lato.css +3 -0
  252. package/dist/css/fonts/font.oldstandard.css +84 -0
  253. package/dist/css/fonts/font.opensans-gentiumbook.css +183 -0
  254. package/dist/css/fonts/font.playfair-faunaone.css +39 -0
  255. package/dist/css/fonts/font.playfair.css +147 -0
  256. package/dist/css/fonts/font.pt.css +183 -0
  257. package/dist/css/fonts/font.roboto-megrim.css +3 -0
  258. package/dist/css/fonts/font.rufina-sintony.css +3 -0
  259. package/dist/css/fonts/font.ubuntu.css +291 -0
  260. package/dist/css/fonts/font.unicaone-vollkorn.css +84 -0
  261. package/dist/css/storymap.css +1 -1
  262. package/dist/demo.html +3 -2
  263. package/dist/docs/api/.nojekyll +1 -0
  264. package/dist/docs/api/assets/custom.css +47 -0
  265. package/dist/docs/api/assets/hierarchy.js +1 -0
  266. package/dist/docs/api/assets/highlight.css +57 -0
  267. package/dist/docs/api/assets/icons.js +18 -0
  268. package/dist/docs/api/assets/icons.svg +1 -0
  269. package/dist/docs/api/assets/main.js +60 -0
  270. package/dist/docs/api/assets/navigation.js +1 -0
  271. package/dist/docs/api/assets/search.js +1 -0
  272. package/dist/docs/api/assets/style.css +1648 -0
  273. package/dist/docs/api/classes/StoryMap.html +2112 -0
  274. package/dist/docs/api/functions/MediaType.html +51 -0
  275. package/dist/docs/api/functions/isPresentation3Collection.html +47 -0
  276. package/dist/docs/api/functions/isPresentation3Manifest.html +53 -0
  277. package/dist/docs/api/functions/isSlideshowCollection.html +51 -0
  278. package/dist/docs/api/functions/loadCSS.html +63 -0
  279. package/dist/docs/api/functions/manifestToStorymapData.html +49 -0
  280. package/dist/docs/api/functions/setLanguage.html +54 -0
  281. package/dist/docs/api/functions/slideshowToStorymapData.html +51 -0
  282. package/dist/docs/api/functions/slideshowVersion.html +48 -0
  283. package/dist/docs/api/functions/storymapToManifest.html +57 -0
  284. package/dist/docs/api/functions/validateStorymap.html +53 -0
  285. package/dist/docs/api/functions/validateStorymapAndReport.html +54 -0
  286. package/dist/docs/api/hierarchy.html +28 -0
  287. package/dist/docs/api/index.html +300 -0
  288. package/dist/docs/api/interfaces/AnimationHandle.html +60 -0
  289. package/dist/docs/api/interfaces/ImagereadyPayload.html +71 -0
  290. package/dist/docs/api/interfaces/LanguageEntry.html +102 -0
  291. package/dist/docs/api/interfaces/LatLngLiteral.html +73 -0
  292. package/dist/docs/api/interfaces/LoadOptions.html +59 -0
  293. package/dist/docs/api/interfaces/MapEvents.html +116 -0
  294. package/dist/docs/api/interfaces/MapMarkerEvents.html +66 -0
  295. package/dist/docs/api/interfaces/MarkerEventPayload.html +57 -0
  296. package/dist/docs/api/interfaces/MediaEvents.html +78 -0
  297. package/dist/docs/api/interfaces/MenuBarEvents.html +114 -0
  298. package/dist/docs/api/interfaces/MessageEvents.html +72 -0
  299. package/dist/docs/api/interfaces/OlLayer.html +1400 -0
  300. package/dist/docs/api/interfaces/OlMap.html +1656 -0
  301. package/dist/docs/api/interfaces/OlProjection.html +332 -0
  302. package/dist/docs/api/interfaces/OlSource.html +784 -0
  303. package/dist/docs/api/interfaces/OlTileLayer.html +1497 -0
  304. package/dist/docs/api/interfaces/OlVectorLayer.html +1559 -0
  305. package/dist/docs/api/interfaces/OlView.html +1958 -0
  306. package/dist/docs/api/interfaces/SlideBackgroundState.html +66 -0
  307. package/dist/docs/api/interfaces/SlideEvents.html +78 -0
  308. package/dist/docs/api/interfaces/SlideNavEvents.html +72 -0
  309. package/dist/docs/api/interfaces/SlideshowPlayerSettings.html +182 -0
  310. package/dist/docs/api/interfaces/SlideshowToStorymapResult.html +60 -0
  311. package/dist/docs/api/interfaces/SlideshowTranslatorOptions.html +65 -0
  312. package/dist/docs/api/interfaces/SlideshowWarning.html +72 -0
  313. package/dist/docs/api/interfaces/StoryMapEvents.html +146 -0
  314. package/dist/docs/api/interfaces/StoryMapMarker.html +763 -0
  315. package/dist/docs/api/interfaces/StorySliderEvents.html +102 -0
  316. package/dist/docs/api/interfaces/StorymapBasemap.html +69 -0
  317. package/dist/docs/api/interfaces/StorymapData.html +77 -0
  318. package/dist/docs/api/interfaces/StorymapDataWrapper.html +60 -0
  319. package/dist/docs/api/interfaces/StorymapDocument.html +68 -0
  320. package/dist/docs/api/interfaces/StorymapError.html +63 -0
  321. package/dist/docs/api/interfaces/StorymapGeoreference.html +93 -0
  322. package/dist/docs/api/interfaces/StorymapGeoreferenceBody.html +74 -0
  323. package/dist/docs/api/interfaces/StorymapGroundControlPoint.html +69 -0
  324. package/dist/docs/api/interfaces/StorymapLanguageMap.html +57 -0
  325. package/dist/docs/api/interfaces/StorymapManifest.html +118 -0
  326. package/dist/docs/api/interfaces/StorymapManifestAnnotation.html +137 -0
  327. package/dist/docs/api/interfaces/StorymapManifestBackground.html +81 -0
  328. package/dist/docs/api/interfaces/StorymapManifestCanvas.html +188 -0
  329. package/dist/docs/api/interfaces/StorymapManifestContentResource.html +97 -0
  330. package/dist/docs/api/interfaces/StorymapManifestFeatureCollection.html +82 -0
  331. package/dist/docs/api/interfaces/StorymapManifestGeoreferencing.html +87 -0
  332. package/dist/docs/api/interfaces/StorymapManifestImageService.html +69 -0
  333. package/dist/docs/api/interfaces/StorymapManifestRange.html +75 -0
  334. package/dist/docs/api/interfaces/StorymapManifestService.html +77 -0
  335. package/dist/docs/api/interfaces/StorymapManifestSpecificResource.html +69 -0
  336. package/dist/docs/api/interfaces/StorymapManifestStatement.html +63 -0
  337. package/dist/docs/api/interfaces/StorymapMapOptions.html +92 -0
  338. package/dist/docs/api/interfaces/StorymapOptions.html +734 -0
  339. package/dist/docs/api/interfaces/StorymapOverlayLayer.html +157 -0
  340. package/dist/docs/api/interfaces/StorymapSlide.html +186 -0
  341. package/dist/docs/api/interfaces/StorymapSlideBackground.html +72 -0
  342. package/dist/docs/api/interfaces/StorymapSlideLocation.html +161 -0
  343. package/dist/docs/api/interfaces/StorymapSlideMarker.html +103 -0
  344. package/dist/docs/api/interfaces/StorymapSlideMedia.html +149 -0
  345. package/dist/docs/api/interfaces/StorymapSlideNarration.html +117 -0
  346. package/dist/docs/api/interfaces/StorymapSlideText.html +72 -0
  347. package/dist/docs/api/interfaces/StorymapTilejson.html +105 -0
  348. package/dist/docs/api/interfaces/SwipableEvents.html +102 -0
  349. package/dist/docs/api/interfaces/TextEvents.html +66 -0
  350. package/dist/docs/api/media/es.json +31 -0
  351. package/dist/docs/api/media/events.md +66 -0
  352. package/dist/docs/api/media/migration-from-knightlab.md +399 -0
  353. package/dist/docs/api/media/slideshow.md +109 -0
  354. package/dist/docs/api/media/storymap-as-iiif-manifest.md +1007 -0
  355. package/dist/docs/api/modules.html +50 -0
  356. package/dist/docs/api/types/ContentState.html +70 -0
  357. package/dist/docs/api/types/FiredEvent.html +43 -0
  358. package/dist/docs/api/types/ImagereadyKind.html +34 -0
  359. package/dist/docs/api/types/MediaTypeMatch.html +78 -0
  360. package/dist/docs/api/types/SwipeDirection.html +36 -0
  361. package/dist/docs/api/types/TileSourceFactory.html +53 -0
  362. package/dist/docs/authoring.html +306 -0
  363. package/dist/docs/events.html +263 -0
  364. package/dist/docs/iiif.html +738 -69
  365. package/dist/docs/migration.html +360 -11
  366. package/dist/docs/readme.html +149 -17
  367. package/dist/embed/index.html +8 -1
  368. package/dist/examples/font-css-false.json +33 -0
  369. package/dist/examples/issue-242-nonlatin.json +55 -0
  370. package/dist/examples/issue-305-start-at-slide-data.json +96 -0
  371. package/dist/examples/issue-358-iframe.json +57 -0
  372. package/dist/examples/issue-iiif-geo.json +32 -0
  373. package/dist/examples/issue-image-alt.json +23 -0
  374. package/dist/examples/issue-image-region.json +42 -0
  375. package/dist/examples/issue-image-srcset.json +24 -0
  376. package/dist/examples/layers-control.json +60 -0
  377. package/dist/examples/map-area-overlays.json +68 -0
  378. package/dist/examples/map-template-provider.json +36 -0
  379. package/dist/examples/multi-media.json +71 -0
  380. package/dist/examples/no-map.json +44 -0
  381. package/dist/examples-iiif/annotated-image.json +204 -0
  382. package/dist/examples-iiif/bob-boilen.json +11 -5
  383. package/dist/examples-iiif/courbet.json +9 -6
  384. package/dist/examples-iiif/empty.json +8 -4
  385. package/dist/examples-iiif/flickr-drewvigal.json +248 -24
  386. package/dist/examples-iiif/flickr-zach.wise.json +8 -4
  387. package/dist/examples-iiif/font-css-false.json +114 -0
  388. package/dist/examples-iiif/georeferenced-layer-unsupported.json +153 -0
  389. package/dist/examples-iiif/georeferenced-layer.json +318 -0
  390. package/dist/examples-iiif/iiif-wellcome.json +9 -6
  391. package/dist/examples-iiif/instagram-chenpamela.json +381 -36
  392. package/dist/examples-iiif/instagram_brentfoster.json +429 -40
  393. package/dist/examples-iiif/instagram_couch.json +261 -26
  394. package/dist/examples-iiif/instagram_joegermuska.json +441 -41
  395. package/dist/examples-iiif/instagram_matteich.json +261 -26
  396. package/dist/examples-iiif/instagram_mirandamulligan.json +261 -26
  397. package/dist/examples-iiif/instagram_raymondmccrea.json +261 -26
  398. package/dist/examples-iiif/instagram_test.json +261 -26
  399. package/dist/examples-iiif/issue-134-no-lines.json +9 -5
  400. package/dist/examples-iiif/issue-177-color-vars.json +9 -5
  401. package/dist/examples-iiif/issue-211-rtl.json +9 -5
  402. package/dist/examples-iiif/issue-242-nonlatin.json +239 -0
  403. package/dist/examples-iiif/issue-272-facebook.json +9 -5
  404. package/dist/examples-iiif/issue-305-start-at-slide-data.json +305 -0
  405. package/dist/examples-iiif/issue-305-start-at-slide.json +9 -5
  406. package/dist/examples-iiif/issue-341-distance.json +9 -5
  407. package/dist/examples-iiif/issue-358-iframe.json +190 -0
  408. package/dist/examples-iiif/issue-360-juxtapose.json +22 -7
  409. package/dist/examples-iiif/issue-368-null-fields.json +9 -5
  410. package/dist/examples-iiif/issue-375-code-lists.json +9 -5
  411. package/dist/examples-iiif/issue-381-dateline.json +9 -5
  412. package/dist/examples-iiif/issue-405-custom-icon.json +203 -0
  413. package/dist/examples-iiif/issue-425-many-slides.json +9 -5
  414. package/dist/examples-iiif/issue-428-background.json +20 -8
  415. package/dist/examples-iiif/issue-435-googlemaps.json +9 -5
  416. package/dist/examples-iiif/issue-437-documentcloud.json +22 -7
  417. package/dist/examples-iiif/issue-451-webp.json +9 -5
  418. package/dist/examples-iiif/issue-455-audio.json +9 -5
  419. package/dist/examples-iiif/issue-480-shorts.json +9 -5
  420. package/dist/examples-iiif/issue-506-marker-sync.json +9 -5
  421. package/dist/examples-iiif/issue-iiif-geo.json +200 -0
  422. package/dist/examples-iiif/issue-image-alt.json +90 -0
  423. package/dist/examples-iiif/issue-image-region.json +203 -0
  424. package/dist/examples-iiif/issue-image-srcset.json +87 -0
  425. package/dist/examples-iiif/jansteen.json +9 -6
  426. package/dist/examples-iiif/katrina.json +197 -41
  427. package/dist/examples-iiif/layers-control.json +226 -0
  428. package/dist/examples-iiif/map-area-overlays.json +289 -0
  429. package/dist/examples-iiif/map-template-provider.json +133 -0
  430. package/dist/examples-iiif/marktwain.json +255 -58
  431. package/dist/examples-iiif/multi-media.json +237 -0
  432. package/dist/examples-iiif/no-map.json +148 -0
  433. package/dist/examples-iiif/population.json +440 -76
  434. package/dist/examples-iiif/president.json +456 -83
  435. package/dist/examples-iiif/scroll-hint.json +190 -0
  436. package/dist/examples-iiif/seurat.json +113 -22
  437. package/dist/examples-iiif/zoomify-clamp.json +153 -0
  438. package/dist/examples-slideshow/single.json +79 -0
  439. package/dist/examples-slideshow/static/pixel.png +0 -0
  440. package/dist/examples-slideshow/static.json +44 -0
  441. package/dist/harness-multi.html +17 -0
  442. package/dist/harness.html +4 -2
  443. package/dist/index.html +19 -12
  444. package/dist/js/storymap.d.ts +2669 -307
  445. package/dist/js/storymap.js +10820 -6196
  446. package/dist/js/storymap.js.map +1 -1
  447. package/dist/navplace-properties.json +54 -0
  448. package/dist/site.css +54 -36
  449. package/docs/migration-from-knightlab.md +279 -19
  450. package/docs/storymap-as-iiif-manifest.md +633 -136
  451. package/package.json +12 -7
  452. package/schema/storymap.schema.json +733 -80
  453. package/src/animation/easings.ts +8 -1
  454. package/src/animation/tween.ts +186 -0
  455. package/src/core/Browser.ts +6 -5
  456. package/src/core/Load.ts +54 -2
  457. package/src/core/Util.ts +257 -193
  458. package/src/core/mixins.ts +66 -35
  459. package/src/core/viewers.ts +94 -0
  460. package/src/dom/DomEvent.ts +27 -8
  461. package/src/globals.d.ts +8 -0
  462. package/src/language/Language.ts +206 -25
  463. package/src/language/locale/.expected-gaps.json +346 -0
  464. package/src/language/locale/be.json +15 -2
  465. package/src/language/locale/bg.json +15 -2
  466. package/src/language/locale/cs.json +15 -2
  467. package/src/language/locale/de.json +23 -2
  468. package/src/language/locale/el.json +15 -2
  469. package/src/language/locale/en.json +17 -3
  470. package/src/language/locale/es.json +15 -2
  471. package/src/language/locale/et.json +5 -1
  472. package/src/language/locale/fr.json +15 -2
  473. package/src/language/locale/he.json +16 -3
  474. package/src/language/locale/hu.json +15 -2
  475. package/src/language/locale/is.json +5 -1
  476. package/src/language/locale/it.json +15 -2
  477. package/src/language/locale/jp.json +15 -2
  478. package/src/language/locale/ko.json +15 -2
  479. package/src/language/locale/nl.json +15 -2
  480. package/src/language/locale/nn.json +5 -1
  481. package/src/language/locale/no.json +15 -2
  482. package/src/language/locale/pl.json +15 -2
  483. package/src/language/locale/pt.json +15 -2
  484. package/src/language/locale/ru.json +15 -2
  485. package/src/language/locale/sk.json +15 -2
  486. package/src/language/locale/sr.json +5 -1
  487. package/src/language/locale/sv.json +15 -2
  488. package/src/language/locale/tr.json +15 -2
  489. package/src/language/locale/uk.json +15 -2
  490. package/src/language/locale/ur.json +5 -1
  491. package/src/language/locale/zh-cn.json +15 -2
  492. package/src/language/locale/zh-tw.json +15 -2
  493. package/src/main.ts +143 -0
  494. package/src/map/Map.ts +227 -112
  495. package/src/map/MapMarker.ts +44 -8
  496. package/src/map/georeference.ts +325 -0
  497. package/src/map/openlayers/Map.OpenLayers.ts +1601 -263
  498. package/src/map/openlayers/MapMarker.OpenLayers.ts +348 -24
  499. package/src/map/openlayers/zoomifyTiles.ts +1 -4
  500. package/src/map/slideView.ts +149 -0
  501. package/src/map/types.ts +2 -0
  502. package/src/media/EmbedUtil.ts +333 -24
  503. package/src/media/Media.ts +270 -59
  504. package/src/media/embedId.ts +110 -0
  505. package/src/media/types/Audio.ts +9 -82
  506. package/src/media/types/Blockquote.ts +2 -3
  507. package/src/media/types/DailyMotion.ts +5 -10
  508. package/src/media/types/DocumentCloud.ts +6 -35
  509. package/src/media/types/Facebook.ts +3 -4
  510. package/src/media/types/Flickr.ts +23 -12
  511. package/src/media/types/GoogleDoc.ts +3 -4
  512. package/src/media/types/HtmlMedia.ts +233 -0
  513. package/src/media/types/IFrame.ts +3 -4
  514. package/src/media/types/Image.ts +87 -9
  515. package/src/media/types/Juxtapose.ts +14 -5
  516. package/src/media/types/SoundCloud.ts +28 -6
  517. package/src/media/types/Text.ts +46 -21
  518. package/src/media/types/Twitter.ts +35 -20
  519. package/src/media/types/Video.ts +9 -79
  520. package/src/media/types/Vimeo.ts +11 -11
  521. package/src/media/types/Website.ts +23 -13
  522. package/src/media/types/Wikipedia.ts +18 -8
  523. package/src/media/types/YouTube.ts +72 -40
  524. package/src/scss/Typography.scss +16 -18
  525. package/src/scss/VCO.StoryMap.scss +208 -12
  526. package/src/scss/Variables.scss +3 -2
  527. package/src/scss/core/Mixins.scss +5 -63
  528. package/src/scss/core/Reset.scss +5 -18
  529. package/src/scss/fonts/font.amatic-andika.scss +3 -0
  530. package/src/scss/fonts/font.bitter-raleway.scss +6 -0
  531. package/src/scss/fonts/font.cairo.scss +79 -0
  532. package/src/scss/fonts/font.clicker-garamond.scss +5 -0
  533. package/src/scss/fonts/font.dancing-ledger.scss +1 -0
  534. package/src/scss/fonts/font.knightlab.scss +14 -0
  535. package/src/scss/fonts/font.oldstandard.scss +6 -0
  536. package/src/scss/fonts/font.opensans-gentiumbook.scss +5 -0
  537. package/src/scss/fonts/font.playfair-faunaone.scss +2 -0
  538. package/src/scss/fonts/font.playfair.scss +4 -0
  539. package/src/scss/fonts/font.pt.scss +6 -0
  540. package/src/scss/fonts/font.ubuntu.scss +4 -0
  541. package/src/scss/fonts/font.unicaone-vollkorn.scss +5 -0
  542. package/src/scss/map/VCO.Map.scss +1 -1
  543. package/src/scss/map/VCO.MapMarker.scss +114 -8
  544. package/src/scss/map/openlayers/VCO.Map.OpenLayers.scss +7 -4
  545. package/src/scss/media/VCO.Media.scss +14 -17
  546. package/src/scss/media/types/VCO.Media.Blockquote.scss +1 -1
  547. package/src/scss/media/types/VCO.Media.Text.scss +13 -5
  548. package/src/scss/media/types/VCO.Media.Twitter.scss +4 -4
  549. package/src/scss/media/types/VCO.Media.Wikipedia.scss +3 -19
  550. package/src/scss/site/site.scss +55 -36
  551. package/src/scss/slider/VCO.Slide.scss +61 -13
  552. package/src/scss/slider/VCO.SlideNav.scss +34 -24
  553. package/src/scss/slider/VCO.StorySlider.scss +53 -1
  554. package/src/scss/snapmap/VCO.SnapMap.scss +3 -3
  555. package/src/scss/ui/VCO.Consent.scss +63 -13
  556. package/src/scss/ui/VCO.Layers.scss +119 -0
  557. package/src/scss/ui/VCO.MenuBar.Button.scss +143 -14
  558. package/src/scss/ui/VCO.MenuBar.scss +9 -2
  559. package/src/scss/ui/VCO.Message.scss +16 -5
  560. package/src/site/site.ts +2 -1
  561. package/src/slider/Slide.ts +326 -74
  562. package/src/slider/SlideNav.ts +54 -9
  563. package/src/slider/StorySlider.ts +352 -60
  564. package/src/storymap/Consent.ts +429 -82
  565. package/src/storymap/StoryMap.ts +2163 -340
  566. package/src/storymap/content-state.ts +180 -0
  567. package/src/storymap/font-css.ts +72 -0
  568. package/src/storymap/from-slideshow.ts +785 -0
  569. package/src/storymap/iiif-shared.ts +228 -0
  570. package/src/storymap/iiif.ts +1742 -95
  571. package/src/storymap/to-iiif.ts +1008 -0
  572. package/src/storymap/validate.ts +80 -7
  573. package/src/types.ts +591 -29
  574. package/src/ui/LayersControl.ts +302 -0
  575. package/src/ui/MenuBar.ts +325 -61
  576. package/src/ui/Message.ts +44 -2
  577. package/src/ui/Swipable.ts +170 -85
  578. package/dist/assets/demo-D6cTmzn6.js +0 -1
  579. package/dist/assets/harness-BPFlzutp.js +0 -1
  580. package/dist/assets/index-DDsPBPZA.js +0 -1
  581. package/dist/assets/main-Y-MYUSJ4.js +0 -17
  582. package/src/animation/morpheus.d.ts +0 -41
  583. package/src/scss/VCO.StoryMap.Dark.scss +0 -138
  584. package/src/scss/Variables.Dark.scss +0 -56
  585. package/src/scss/media/types/VCO.Media.Instagram.scss +0 -7
  586. package/src/scss/media/types/VCO.Media.Profile.scss +0 -5
  587. package/src/ui/Draggable.ts +0 -374
@@ -1,9 +1,11 @@
1
- import { mergeData } from "../core/Util";
1
+ import { mergeData, prefersReducedMotion } from "../core/Util";
2
2
  import { DomMixed, Evented, type EventedInstance } from "../core/mixins";
3
3
  import { DomEvent } from "../dom/DomEvent";
4
4
  import Dom from "../dom/Dom";
5
5
  import { easeInSpline } from "../animation/easings";
6
6
  import MediaType from "../media/MediaType";
7
+ import type { MediaEvents } from "../media/Media";
8
+ import { sanitizeSlideText } from "../media/EmbedUtil";
7
9
  import Text from "../media/types/Text";
8
10
  import { Browser } from "../core/Browser";
9
11
  import { MediaTypeMatch, StorymapSlide, StorymapSlideBackground } from "../types";
@@ -27,6 +29,19 @@ interface SlideOptions {
27
29
  [key: string]: unknown;
28
30
  }
29
31
 
32
+ /**
33
+ * The slide's element cache. `call_to_action` is null until the slide is told
34
+ * to show one (`addCallToAction`).
35
+ */
36
+ type SlideElements = {
37
+ container: HTMLElement;
38
+ scroll_container: HTMLElement;
39
+ background: HTMLElement;
40
+ content_container: HTMLElement;
41
+ content: HTMLElement;
42
+ call_to_action: HTMLElement | null;
43
+ };
44
+
30
45
  /* Media instance surface as used by Slide; instances are created
31
46
  dynamically via the matched MediaTypeMatch.cls constructor. Media is
32
47
  Evented — "media_loaded" signals that content heights may have changed. */
@@ -35,8 +50,27 @@ interface MediaInstance {
35
50
  loadMedia: () => void;
36
51
  stopMedia: () => void;
37
52
  updateDisplay: (w?: number, h?: number, l?: string) => void;
38
- on?: EventedInstance["on"];
39
- _state?: { loaded?: boolean };
53
+ dispose?: () => void;
54
+ on?: EventedInstance<MediaEvents>["on"];
55
+ off?: EventedInstance<MediaEvents>["off"];
56
+ _state?: { loaded?: boolean; eager?: boolean };
57
+ /** Per-item consent identity: each item is built with its own
58
+ `media_name`/`media_type`, which `hasPlayableMedia` reads back (#358). */
59
+ options?: { media_type?: string };
60
+ }
61
+
62
+ export interface SlideBackgroundState {
63
+ image: boolean;
64
+ color: boolean;
65
+ color_value: string;
66
+ }
67
+
68
+ export interface SlideEvents {
69
+ background_change: SlideBackgroundState;
70
+ call_to_action: Event;
71
+ loaded: StorymapSlide;
72
+ added: StorymapSlide;
73
+ removed: StorymapSlide;
40
74
  }
41
75
 
42
76
  interface SlideHas {
@@ -44,28 +78,33 @@ interface SlideHas {
44
78
  text: boolean;
45
79
  media: boolean;
46
80
  title: boolean;
47
- background: {
48
- image: boolean;
49
- color: boolean;
50
- color_value: string;
51
- };
81
+ background: SlideBackgroundState;
52
82
  }
53
83
 
54
84
  class SlideBase {
55
- declare "_el": Record<string, HTMLElement>;
85
+ /** `call_to_action` is only created when the slide shows one. */
86
+ declare "_el": SlideElements;
87
+ /** The primary media item; always `_medias[0]` when present (#358). */
56
88
  declare "_media": MediaInstance | null;
57
- declare "_mediaclass": unknown;
89
+ /** Every media item: `[media, ...media_extra]` with a non-empty url. */
90
+ declare "_medias": MediaInstance[];
58
91
  declare "_text": Text;
59
92
  declare "_state": { loaded: boolean };
60
93
  declare "_scroll_hint": HTMLElement | null;
61
94
  declare "_scroll_hint_dismissed": boolean;
95
+ declare "_onSlideScrollBound": EventListener;
96
+ /** Every `media_ended` handler registered via `onMediaEnded`, with the
97
+ media it was attached to so `dispose()` can remove them. */
98
+ declare "_media_ended_fns": { media: MediaInstance; fn: () => void }[];
99
+ /** The `media_loaded` handlers below, kept for the same reason. */
100
+ declare "_media_loaded_fns": { media: MediaInstance; fn: () => void }[];
62
101
  declare "has": SlideHas;
63
102
  declare "title": string;
64
103
  declare "data": StorymapSlide;
65
104
  declare "options": SlideOptions;
66
105
  declare "active": boolean;
67
106
  declare "animator": unknown;
68
- declare "fire": EventedInstance["fire"];
107
+ declare "fire": EventedInstance<SlideEvents>["fire"];
69
108
  declare "onLoaded": () => void;
70
109
 
71
110
  //_el: {},
@@ -85,7 +124,7 @@ class SlideBase {
85
124
 
86
125
  // Components
87
126
  this._media = null;
88
- this._mediaclass = {};
127
+ this._medias = [];
89
128
  this._text = {} as Text;
90
129
 
91
130
  // State
@@ -107,7 +146,7 @@ class SlideBase {
107
146
  },
108
147
  };
109
148
 
110
- this.has.title = title_slide;
149
+ this.has.title = title_slide === true;
111
150
 
112
151
  this.title = "";
113
152
 
@@ -139,7 +178,9 @@ class SlideBase {
139
178
  // Animation Object
140
179
  this.animator = {};
141
180
 
142
- // Merge Data and Options
181
+ this._onSlideScrollBound = null as unknown as EventListener;
182
+ this._media_ended_fns = [];
183
+ this._media_loaded_fns = [];
143
184
  mergeData(this.options, options);
144
185
  mergeData(this.data, data);
145
186
 
@@ -154,9 +195,57 @@ class SlideBase {
154
195
 
155
196
  hide() {}
156
197
 
198
+ /**
199
+ * Release the slide's listeners, media and DOM. Called by
200
+ * `StorySlider.dispose()`; the slide must not be used afterwards.
201
+ */
202
+ dispose() {
203
+ // the scroll listener was registered against a bound copy, so this
204
+ // only works because that reference was kept
205
+ if (this._onSlideScrollBound) {
206
+ this._el.container?.removeEventListener("scroll", this._onSlideScrollBound);
207
+ this._onSlideScrollBound = null as unknown as EventListener;
208
+ }
209
+ if (this._el.call_to_action) {
210
+ DomEvent.removeListener(this._el.call_to_action, "click", this._onCallToAction, this);
211
+ }
212
+ if (this._scroll_hint) {
213
+ DomEvent.removeListener(this._scroll_hint, "click", this._onScrollHintClick, this);
214
+ this._scroll_hint = null;
215
+ }
216
+ this._el.container?.getAnimations?.().forEach((a) => a.cancel());
217
+ // the media_ended handlers registered via onMediaEnded() live on the
218
+ // media objects, which outlive this slide once nulled — remove them
219
+ // here or a disposed slide's advance closure fires on a later ended
220
+ this.clearMediaEnded();
221
+ for (const { media, fn } of this._media_loaded_fns) {
222
+ media.off?.("media_loaded", fn);
223
+ }
224
+ this._media_loaded_fns = [];
225
+ for (const media of this._medias) {
226
+ media.dispose?.();
227
+ }
228
+ this._medias = [];
229
+ this._media = null;
230
+ this._el.container?.remove();
231
+ }
232
+
157
233
  setActive(is_active: boolean) {
158
234
  this.active = is_active;
159
235
 
236
+ // Off-screen slides are translated away but stay in the DOM, so a
237
+ // screen reader would read every slide's headline, body and caption.
238
+ // Hide inactive slides from assistive tech next to the flip that
239
+ // already marks them inactive; `inert` additionally drops their
240
+ // controls from keyboard reach. Neither affects loading: preloaded
241
+ // media (including iframes) still builds and fetches underneath.
242
+ this._el.container.setAttribute("aria-hidden", String(!is_active));
243
+ if (is_active) {
244
+ this._el.container.removeAttribute("inert");
245
+ } else {
246
+ this._el.container.setAttribute("inert", "");
247
+ }
248
+
160
249
  if (this.active) {
161
250
  if (this.data.background) {
162
251
  this.fire("background_change", this.has.background);
@@ -164,7 +253,16 @@ class SlideBase {
164
253
  // the hint may re-appear on a revisit if the content still
165
254
  // overflows (the dismissed flag resets per activation)
166
255
  this._scroll_hint_dismissed = false;
256
+ // the active slide's images load eagerly: media built after this
257
+ // point (the 1200ms load timer) honors the flag, already-built
258
+ // images are upgraded below
259
+ for (const media of this._medias) {
260
+ if (media._state) {
261
+ media._state.eager = true;
262
+ }
263
+ }
167
264
  this.loadMedia();
265
+ this._eagerLoadImages();
168
266
  this._updateScrollHint();
169
267
  } else {
170
268
  this.stopMedia();
@@ -177,40 +275,137 @@ class SlideBase {
177
275
  }
178
276
 
179
277
  loadMedia() {
180
- if (this._media && !this._state.loaded) {
181
- this._media.loadMedia();
278
+ if (this._medias.length > 0 && !this._state.loaded) {
279
+ for (const media of this._medias) {
280
+ media.loadMedia();
281
+ }
182
282
  this._state.loaded = true;
183
283
  }
184
284
  }
185
285
 
286
+ /* Perf: preloaded slide images are `lazy`; make them `eager` the
287
+ moment the slide becomes active so navigation never waits on a
288
+ deferred fetch (loading starts now, not on intersection). */
289
+ _eagerLoadImages() {
290
+ this._el.container
291
+ .querySelectorAll<HTMLImageElement>("img.vco-media-image")
292
+ .forEach((img) => {
293
+ img.loading = "eager";
294
+ });
295
+ }
296
+
186
297
  stopMedia() {
187
- if (this._media && this._state.loaded) {
188
- try {
189
- this._media.stopMedia();
190
- } catch (e: unknown) {
191
- // Some sort of race condition or other ordering condition can cause
192
- // an error when the preview tab is selected in the editor due to
193
- // the stopped media not being properly formed.
194
- if (
195
- (e as Error).message === "this._el.content_item.querySelector is not a function"
196
- ) {
197
- console.log("Ignoring error in editor context: " + (e as Error).message);
198
- } else {
199
- throw e;
298
+ if (this._medias.length > 0 && this._state.loaded) {
299
+ for (const media of this._medias) {
300
+ // An audio bed that outlives its slide
301
+ // (`media.stopOnExit: false`, slideshow ambient audio) keeps
302
+ // playing; StoryMap stops it when another slide claims audio.
303
+ // Slideshow-only: internal documents always stop.
304
+ const mediaData = (media as unknown as { data?: { stopOnExit?: boolean } }).data;
305
+ const sourced =
306
+ (this.options as { slideshow_source?: unknown }).slideshow_source === true;
307
+ if (sourced && mediaData?.stopOnExit === false) continue;
308
+ try {
309
+ media.stopMedia();
310
+ } catch (e: unknown) {
311
+ // Some sort of race condition or other ordering condition can cause
312
+ // an error when the preview tab is selected in the editor due to
313
+ // the stopped media not being properly formed.
314
+ if (
315
+ (e as Error).message ===
316
+ "this._el.content_item.querySelector is not a function"
317
+ ) {
318
+ console.warn("Ignoring error in editor context: " + (e as Error).message);
319
+ } else {
320
+ throw e;
321
+ }
200
322
  }
201
323
  }
202
- // If the media load never started (its pending timer was
203
- // cancelled on a quick pass-through), allow a revisit to retry
204
- if (!this._media._state?.loaded) {
324
+ // If no media load started (pending timers were cancelled on a
325
+ // quick pass-through), allow a revisit to retry
326
+ if (!this._medias.some((media) => media._state?.loaded)) {
205
327
  this._state.loaded = false;
206
328
  }
207
329
  }
208
330
  }
209
331
 
332
+ /**
333
+ * Stop this slide's ambient audio beds (`media.stopOnExit: false`) —
334
+ * called by the viewer when another slide claims the audio, not on every
335
+ * deactivation (see `stopMedia`, which skips them).
336
+ */
337
+ stopAmbientMedia() {
338
+ // Slideshow-only by construction (see stopMedia): without the source
339
+ // flag no media can be ambient, so there is nothing to stop.
340
+ if ((this.options as { slideshow_source?: unknown }).slideshow_source !== true) return;
341
+ if (this._medias.length > 0 && this._state.loaded) {
342
+ for (const media of this._medias) {
343
+ const mediaData = (media as unknown as { data?: { stopOnExit?: boolean } }).data;
344
+ if (mediaData?.stopOnExit !== false) continue;
345
+ try {
346
+ media.stopMedia();
347
+ } catch {
348
+ // same editor-context race stopMedia() already tolerates
349
+ }
350
+ }
351
+ }
352
+ }
353
+
210
354
  getBackground() {
211
355
  return this.has.background;
212
356
  }
213
357
 
358
+ /**
359
+ * True when this slide's media is a timed, playable one (audio or video).
360
+ * `autoplay_media` waits for such a slide's media to end instead of using
361
+ * its timer; everything else keeps the timer.
362
+ */
363
+ hasPlayableMedia(): boolean {
364
+ if (this._medias.length === 0) {
365
+ const kind = this.options.media_type as string | undefined;
366
+ return kind === "audio" || kind === "video";
367
+ }
368
+ return this._medias.some((media) => {
369
+ const kind = media.options?.media_type;
370
+ return kind === "audio" || kind === "video";
371
+ });
372
+ }
373
+
374
+ /**
375
+ * Call `fn` when this slide's media finishes playing. A slide with no
376
+ * media — or media that cannot end — never calls it, which is why
377
+ * `autoplay_media` keeps its timer as a fallback rather than waiting on
378
+ * an event that may not arrive. Multi-media slides never call it either:
379
+ * waiting for the last of several items to end would stall autoplay, so
380
+ * the timer stays the advance for those (#358).
381
+ */
382
+ onMediaEnded(fn: () => void): void {
383
+ const playable = this._medias.filter((media) => {
384
+ const kind = media.options?.media_type;
385
+ return (kind === "audio" || kind === "video") && media.on;
386
+ });
387
+ if (playable.length !== 1) return;
388
+ playable[0].on?.("media_ended", fn);
389
+ this._media_ended_fns.push({ media: playable[0], fn });
390
+ }
391
+
392
+ /**
393
+ * Drop `media_ended` handlers armed by `onMediaEnded()` without waiting
394
+ * for dispose: re-arming (autoplay revisit) or navigating away must not
395
+ * accumulate stale advance closures — an ambient bed outliving its slide
396
+ * would otherwise fire a previous slide's advance on ending.
397
+ */
398
+ clearMediaEnded(): void {
399
+ for (const { media, fn } of this._media_ended_fns) {
400
+ try {
401
+ media.off?.("media_ended", fn);
402
+ } catch {
403
+ // same editor-context race stopMedia() already tolerates
404
+ }
405
+ }
406
+ this._media_ended_fns = [];
407
+ }
408
+
214
409
  scrollToTop() {
215
410
  this._el.container.scrollTop = 0;
216
411
  }
@@ -235,11 +430,10 @@ class SlideBase {
235
430
  return;
236
431
  }
237
432
  if (!this._scroll_hint) {
238
- this._scroll_hint = Dom.create(
239
- "div",
240
- "vco-slide-scroll-hint",
241
- el,
242
- );
433
+ // a real button for keyboard/AT operability (issue #385 wave)
434
+ this._scroll_hint = Dom.create("button", "vco-slide-scroll-hint", el);
435
+ this._scroll_hint.setAttribute("type", "button");
436
+ this._scroll_hint.setAttribute("aria-label", "Scroll down");
243
437
  this._scroll_hint.innerHTML = "<span class='vco-icon-arrow-down'></span>";
244
438
  DomEvent.addListener(this._scroll_hint, "click", this._onScrollHintClick, this);
245
439
  }
@@ -255,7 +449,10 @@ class SlideBase {
255
449
  _onScrollHintClick() {
256
450
  // scroll down one step, then hide (the scroll event dismisses too)
257
451
  const el = this._el.container;
258
- el.scrollBy({ top: el.clientHeight * 0.8, behavior: "smooth" });
452
+ el.scrollBy({
453
+ top: el.clientHeight * 0.8,
454
+ behavior: prefersReducedMotion() ? "auto" : "smooth",
455
+ });
259
456
  this._scroll_hint_dismissed = true;
260
457
  this._hideScrollHint();
261
458
  }
@@ -271,13 +468,20 @@ class SlideBase {
271
468
  }
272
469
 
273
470
  addCallToAction(str: string) {
471
+ // a real button for keyboard/AT operability (issue #385 wave), like
472
+ // the menubar buttons; the classes carry the look
274
473
  this._el.call_to_action = Dom.create(
275
- "div",
474
+ "button",
276
475
  "vco-slide-calltoaction",
277
476
  this._el.content_container,
278
477
  );
279
- this._el.call_to_action.innerHTML =
280
- "<span class='vco-slide-calltoaction-button-text'>" + str + "</span>";
478
+ this._el.call_to_action.setAttribute("type", "button");
479
+ // The text comes from `call_to_action_text` in the storymap JSON, so
480
+ // it goes through the sanitizer like every other author string
481
+ // instead of being concatenated into markup.
482
+ const button_text = Dom.create("span", "vco-slide-calltoaction-button-text");
483
+ button_text.appendChild(sanitizeSlideText(str));
484
+ this._el.call_to_action?.appendChild(button_text);
281
485
  DomEvent.addListener(this._el.call_to_action, "click", this._onCallToAction, this);
282
486
  }
283
487
 
@@ -308,8 +512,11 @@ class SlideBase {
308
512
  this._el.content = Dom.create("div", "vco-slide-content", this._el.content_container);
309
513
  this._el.background = Dom.create("div", "vco-slide-background", this._el.container);
310
514
  // first scroll of any kind hides the scroll hint (passive: the
311
- // listener never prevents default)
312
- this._el.container.addEventListener("scroll", this._onSlideScroll.bind(this), {
515
+ // listener never prevents default). The reference is kept because
516
+ // `.bind()` returns a new function each call, so the listener could
517
+ // otherwise never be removed again.
518
+ this._onSlideScrollBound = this._onSlideScroll.bind(this);
519
+ this._el.container.addEventListener("scroll", this._onSlideScrollBound, {
313
520
  passive: true,
314
521
  });
315
522
  // Style Slide Background
@@ -334,53 +541,90 @@ class SlideBase {
334
541
  }
335
542
  }
336
543
 
337
- // Determine Assets for layout and loading
338
- if (this.data.media && this.data.media.url && this.data.media.url !== "") {
544
+ // Determine Assets for layout and loading. A slide has media when
545
+ // any item — the primary or an extra — carries a non-empty url, so
546
+ // an empty `media.url` still yields false (#358).
547
+ const slide_media_items = [this.data.media, ...(this.data.media_extra ?? [])].filter(
548
+ (item): item is NonNullable<StorymapSlide["media"]> => !!item?.url,
549
+ );
550
+ if (slide_media_items.length > 0) {
339
551
  this.has.media = true;
340
552
  }
341
553
  if (this.data.text && this.data.text.text) {
342
554
  this.has.text = true;
343
555
  }
344
- if (this.data.text && this.data.text.headline) {
556
+ if (this.data.text?.headline) {
345
557
  this.has.headline = true;
346
558
  this.title = this.data.text.headline;
347
559
  }
348
560
 
349
- // Create Media
350
- if (this.has.media) {
351
- // Determine the media type
352
- this.data.media.mediatype = MediaType(this.data.media) as MediaTypeMatch;
353
- this.options.media_name = this.data.media.mediatype.name;
354
- this.options.media_type = this.data.media.mediatype.type;
355
-
356
- // Create a media object using the matched class name
357
- this._media = new this.data.media.mediatype.cls(
358
- this.data.media,
359
- this.options,
360
- ) as MediaInstance;
361
- // loaded media changes the content height — the scroll hint
362
- // may appear or disappear
363
- this._media.on?.("media_loaded", () => this._updateScrollHint());
561
+ // Create Media (#358): the primary item plus every extra with a
562
+ // non-empty url, in order. Each item gets its own MediaType match and
563
+ // its own consent identity (media_name/media_type), so per-slide
564
+ // consent asks and the audio badge tell items apart.
565
+ const media_items = slide_media_items;
566
+ if (media_items.length > 0) {
567
+ for (const item of media_items) {
568
+ // Determine the media type
569
+ item.mediatype = MediaType(item) as MediaTypeMatch;
570
+ // Item 0 keeps the historical write-back: the marker icon
571
+ // class reads it off the slide data.
572
+ if (item === media_items[0]) {
573
+ this.options.media_name = item.mediatype.name;
574
+ this.options.media_type = item.mediatype.type;
575
+ }
576
+ // Create a media object using the matched class name
577
+ const media = new item.mediatype.cls(item, {
578
+ ...this.options,
579
+ media_name: item.mediatype.name,
580
+ media_type: item.mediatype.type,
581
+ }) as MediaInstance;
582
+ // loaded media changes the content height — the scroll hint
583
+ // may appear or disappear
584
+ const on_loaded = () => this._updateScrollHint();
585
+ media.on?.("media_loaded", on_loaded);
586
+ this._media_loaded_fns.push({ media, fn: on_loaded });
587
+ this._medias.push(media);
588
+ }
589
+ this._media = this._medias[0] ?? null;
364
590
  }
365
591
 
366
592
  // Create Text
367
- if (this.has.text || this.has.headline) {
593
+ if ((this.has.text || this.has.headline) && this.data.text) {
368
594
  this._text = new Text(this.data.text, {
369
595
  title: this.has.title,
370
596
  text_align: this.options.text_align as string | undefined,
597
+ language: this.data.language ?? undefined,
371
598
  });
372
599
  }
373
600
 
374
- // Add to DOM
601
+ // Add to DOM. Each branch has just established the members it uses
602
+ // (has.media -> _medias, has.text/headline -> _text). The media loop
603
+ // preserves the historical ordering: media-then-text, or
604
+ // text-then-media when there is a headline but no body text.
605
+ const medias = this._medias;
606
+ if (medias.length > 1) {
607
+ // `row` seats two items side by side; anything else stacks (D4)
608
+ const layout =
609
+ this.data.media_layout === "row" && medias.length === 2 ? "row" : "stack";
610
+ this._el.container.classList.add("vco-slide-media-multiple");
611
+ this._el.container.setAttribute("data-layout", layout);
612
+ }
375
613
  if (!this.has.text && !this.has.headline && this.has.media) {
376
614
  this._el.container.className += " vco-slide-media-only";
377
- this._media.addTo(this._el.content);
615
+ for (const media of medias) {
616
+ media.addTo(this._el.content);
617
+ }
378
618
  } else if (this.has.headline && this.has.media && !this.has.text) {
379
619
  this._el.container.className += " vco-slide-media-only";
380
620
  this._text.addTo(this._el.content);
381
- this._media.addTo(this._el.content);
621
+ for (const media of medias) {
622
+ media.addTo(this._el.content);
623
+ }
382
624
  } else if (this.has.text && this.has.media) {
383
- this._media.addTo(this._el.content);
625
+ for (const media of medias) {
626
+ media.addTo(this._el.content);
627
+ }
384
628
  this._text.addTo(this._el.content);
385
629
  } else if (this.has.text || this.has.headline) {
386
630
  this._el.container.className += " vco-slide-text-only";
@@ -436,15 +680,19 @@ class SlideBase {
436
680
  this.options.height = this._el.container.offsetHeight;
437
681
  }
438
682
 
439
- if (this._media) {
683
+ if (this._medias.length > 0) {
440
684
  if (!this.has.text && this.has.headline) {
441
- this._media.updateDisplay(
442
- this.options.width,
443
- this.options.height - this._text.headlineHeight(),
444
- layout,
445
- );
685
+ for (const media of this._medias) {
686
+ media.updateDisplay(
687
+ this.options.width,
688
+ this.options.height - this._text.headlineHeight(),
689
+ layout,
690
+ );
691
+ }
446
692
  } else {
447
- this._media.updateDisplay(this.options.width, this.options.height, layout);
693
+ for (const media of this._medias) {
694
+ media.updateDisplay(this.options.width, this.options.height, layout);
695
+ }
448
696
  }
449
697
  }
450
698
 
@@ -453,7 +701,11 @@ class SlideBase {
453
701
  }
454
702
  }
455
703
 
456
- export default class Slide extends DomMixed(Evented(SlideBase)) {
704
+ const EventedSlideBase = Evented<SlideEvents, typeof SlideBase>(SlideBase);
705
+
706
+ export default class Slide extends DomMixed<SlideEvents, typeof EventedSlideBase>(
707
+ EventedSlideBase,
708
+ ) {
457
709
  constructor(...args: ConstructorParameters<typeof SlideBase>) {
458
710
  super(...args);
459
711
  }