@projektemacher/storymapjs 0.10.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 (326) hide show
  1. package/CHANGELOG +121 -0
  2. package/LICENSE +365 -0
  3. package/README.md +128 -0
  4. package/dist/assets/demo-DYodj6d7.js +1 -0
  5. package/dist/assets/harness-UkbbPmC4.js +1 -0
  6. package/dist/assets/index-DDsPBPZA.js +1 -0
  7. package/dist/assets/main-BDSRsIiB.js +17 -0
  8. package/dist/assets/main-Bzm6THVj.css +1 -0
  9. package/dist/assets/modulepreload-polyfill-P2Xu9kJm.js +1 -0
  10. package/dist/context.json +35 -0
  11. package/dist/css/fonts/files/abril-fatface-latin-400-normal.woff2 +0 -0
  12. package/dist/css/fonts/files/abril-fatface-latin-ext-400-normal.woff2 +0 -0
  13. package/dist/css/fonts/files/amatic-sc-latin-400-normal.woff2 +0 -0
  14. package/dist/css/fonts/files/amatic-sc-latin-700-normal.woff2 +0 -0
  15. package/dist/css/fonts/files/amatic-sc-latin-ext-400-normal.woff2 +0 -0
  16. package/dist/css/fonts/files/amatic-sc-latin-ext-700-normal.woff2 +0 -0
  17. package/dist/css/fonts/files/average-sans-latin-400-normal.woff2 +0 -0
  18. package/dist/css/fonts/files/average-sans-latin-ext-400-normal.woff2 +0 -0
  19. package/dist/css/fonts/files/bitter-latin-100-italic.woff2 +0 -0
  20. package/dist/css/fonts/files/bitter-latin-100-normal.woff2 +0 -0
  21. package/dist/css/fonts/files/bitter-latin-200-italic.woff2 +0 -0
  22. package/dist/css/fonts/files/bitter-latin-200-normal.woff2 +0 -0
  23. package/dist/css/fonts/files/bitter-latin-300-italic.woff2 +0 -0
  24. package/dist/css/fonts/files/bitter-latin-300-normal.woff2 +0 -0
  25. package/dist/css/fonts/files/bitter-latin-400-italic.woff2 +0 -0
  26. package/dist/css/fonts/files/bitter-latin-400-normal.woff2 +0 -0
  27. package/dist/css/fonts/files/bitter-latin-500-italic.woff2 +0 -0
  28. package/dist/css/fonts/files/bitter-latin-500-normal.woff2 +0 -0
  29. package/dist/css/fonts/files/bitter-latin-600-italic.woff2 +0 -0
  30. package/dist/css/fonts/files/bitter-latin-600-normal.woff2 +0 -0
  31. package/dist/css/fonts/files/bitter-latin-700-italic.woff2 +0 -0
  32. package/dist/css/fonts/files/bitter-latin-700-normal.woff2 +0 -0
  33. package/dist/css/fonts/files/bitter-latin-800-italic.woff2 +0 -0
  34. package/dist/css/fonts/files/bitter-latin-800-normal.woff2 +0 -0
  35. package/dist/css/fonts/files/bitter-latin-900-italic.woff2 +0 -0
  36. package/dist/css/fonts/files/bitter-latin-900-normal.woff2 +0 -0
  37. package/dist/css/fonts/files/bitter-latin-ext-100-italic.woff2 +0 -0
  38. package/dist/css/fonts/files/bitter-latin-ext-100-normal.woff2 +0 -0
  39. package/dist/css/fonts/files/bitter-latin-ext-200-italic.woff2 +0 -0
  40. package/dist/css/fonts/files/bitter-latin-ext-200-normal.woff2 +0 -0
  41. package/dist/css/fonts/files/bitter-latin-ext-300-italic.woff2 +0 -0
  42. package/dist/css/fonts/files/bitter-latin-ext-300-normal.woff2 +0 -0
  43. package/dist/css/fonts/files/bitter-latin-ext-400-italic.woff2 +0 -0
  44. package/dist/css/fonts/files/bitter-latin-ext-400-normal.woff2 +0 -0
  45. package/dist/css/fonts/files/bitter-latin-ext-500-italic.woff2 +0 -0
  46. package/dist/css/fonts/files/bitter-latin-ext-500-normal.woff2 +0 -0
  47. package/dist/css/fonts/files/bitter-latin-ext-600-italic.woff2 +0 -0
  48. package/dist/css/fonts/files/bitter-latin-ext-600-normal.woff2 +0 -0
  49. package/dist/css/fonts/files/bitter-latin-ext-700-italic.woff2 +0 -0
  50. package/dist/css/fonts/files/bitter-latin-ext-700-normal.woff2 +0 -0
  51. package/dist/css/fonts/files/bitter-latin-ext-800-italic.woff2 +0 -0
  52. package/dist/css/fonts/files/bitter-latin-ext-800-normal.woff2 +0 -0
  53. package/dist/css/fonts/files/bitter-latin-ext-900-italic.woff2 +0 -0
  54. package/dist/css/fonts/files/bitter-latin-ext-900-normal.woff2 +0 -0
  55. package/dist/css/fonts/files/bitter-latin-ext-wght-italic.woff2 +0 -0
  56. package/dist/css/fonts/files/bitter-latin-ext-wght-normal.woff2 +0 -0
  57. package/dist/css/fonts/files/bitter-latin-wght-italic.woff2 +0 -0
  58. package/dist/css/fonts/files/bitter-latin-wght-normal.woff2 +0 -0
  59. package/dist/css/fonts/files/clicker-script-latin-400-normal.woff2 +0 -0
  60. package/dist/css/fonts/files/clicker-script-latin-ext-400-normal.woff2 +0 -0
  61. package/dist/css/fonts/files/dancing-script-latin-ext-wght-normal.woff2 +0 -0
  62. package/dist/css/fonts/files/dancing-script-latin-wght-normal.woff2 +0 -0
  63. package/dist/css/fonts/files/eb-garamond-latin-ext-wght-italic.woff2 +0 -0
  64. package/dist/css/fonts/files/eb-garamond-latin-ext-wght-normal.woff2 +0 -0
  65. package/dist/css/fonts/files/eb-garamond-latin-wght-italic.woff2 +0 -0
  66. package/dist/css/fonts/files/eb-garamond-latin-wght-normal.woff2 +0 -0
  67. package/dist/css/fonts/files/fauna-one-latin-400-normal.woff2 +0 -0
  68. package/dist/css/fonts/files/fauna-one-latin-ext-400-normal.woff2 +0 -0
  69. package/dist/css/fonts/files/gentium-book-plus-latin-400-italic.woff2 +0 -0
  70. package/dist/css/fonts/files/gentium-book-plus-latin-400-normal.woff2 +0 -0
  71. package/dist/css/fonts/files/gentium-book-plus-latin-700-italic.woff2 +0 -0
  72. package/dist/css/fonts/files/gentium-book-plus-latin-700-normal.woff2 +0 -0
  73. package/dist/css/fonts/files/gentium-book-plus-latin-ext-400-italic.woff2 +0 -0
  74. package/dist/css/fonts/files/gentium-book-plus-latin-ext-400-normal.woff2 +0 -0
  75. package/dist/css/fonts/files/gentium-book-plus-latin-ext-700-italic.woff2 +0 -0
  76. package/dist/css/fonts/files/gentium-book-plus-latin-ext-700-normal.woff2 +0 -0
  77. package/dist/css/fonts/files/lato-latin-100-italic.woff2 +0 -0
  78. package/dist/css/fonts/files/lato-latin-100-normal.woff2 +0 -0
  79. package/dist/css/fonts/files/lato-latin-300-italic.woff2 +0 -0
  80. package/dist/css/fonts/files/lato-latin-300-normal.woff2 +0 -0
  81. package/dist/css/fonts/files/lato-latin-400-italic.woff2 +0 -0
  82. package/dist/css/fonts/files/lato-latin-400-normal.woff2 +0 -0
  83. package/dist/css/fonts/files/lato-latin-700-italic.woff2 +0 -0
  84. package/dist/css/fonts/files/lato-latin-700-normal.woff2 +0 -0
  85. package/dist/css/fonts/files/lato-latin-900-italic.woff2 +0 -0
  86. package/dist/css/fonts/files/lato-latin-900-normal.woff2 +0 -0
  87. package/dist/css/fonts/files/lato-latin-ext-100-italic.woff2 +0 -0
  88. package/dist/css/fonts/files/lato-latin-ext-100-normal.woff2 +0 -0
  89. package/dist/css/fonts/files/lato-latin-ext-300-italic.woff2 +0 -0
  90. package/dist/css/fonts/files/lato-latin-ext-300-normal.woff2 +0 -0
  91. package/dist/css/fonts/files/lato-latin-ext-400-italic.woff2 +0 -0
  92. package/dist/css/fonts/files/lato-latin-ext-400-normal.woff2 +0 -0
  93. package/dist/css/fonts/files/lato-latin-ext-700-italic.woff2 +0 -0
  94. package/dist/css/fonts/files/lato-latin-ext-700-normal.woff2 +0 -0
  95. package/dist/css/fonts/files/lato-latin-ext-900-italic.woff2 +0 -0
  96. package/dist/css/fonts/files/lato-latin-ext-900-normal.woff2 +0 -0
  97. package/dist/css/fonts/files/megrim-latin-400-normal.woff2 +0 -0
  98. package/dist/css/fonts/files/megrim-latin-ext-400-normal.woff2 +0 -0
  99. package/dist/css/fonts/files/old-standard-tt-latin-400-italic.woff2 +0 -0
  100. package/dist/css/fonts/files/old-standard-tt-latin-400-normal.woff2 +0 -0
  101. package/dist/css/fonts/files/old-standard-tt-latin-700-normal.woff2 +0 -0
  102. package/dist/css/fonts/files/old-standard-tt-latin-ext-400-italic.woff2 +0 -0
  103. package/dist/css/fonts/files/old-standard-tt-latin-ext-400-normal.woff2 +0 -0
  104. package/dist/css/fonts/files/old-standard-tt-latin-ext-700-normal.woff2 +0 -0
  105. package/dist/css/fonts/files/open-sans-latin-ext-wght-italic.woff2 +0 -0
  106. package/dist/css/fonts/files/open-sans-latin-ext-wght-normal.woff2 +0 -0
  107. package/dist/css/fonts/files/open-sans-latin-wght-italic.woff2 +0 -0
  108. package/dist/css/fonts/files/open-sans-latin-wght-normal.woff2 +0 -0
  109. package/dist/css/fonts/files/playfair-display-latin-ext-wght-italic.woff2 +0 -0
  110. package/dist/css/fonts/files/playfair-display-latin-ext-wght-normal.woff2 +0 -0
  111. package/dist/css/fonts/files/playfair-display-latin-wght-italic.woff2 +0 -0
  112. package/dist/css/fonts/files/playfair-display-latin-wght-normal.woff2 +0 -0
  113. package/dist/css/fonts/files/playfair-display-sc-latin-400-italic.woff2 +0 -0
  114. package/dist/css/fonts/files/playfair-display-sc-latin-400-normal.woff2 +0 -0
  115. package/dist/css/fonts/files/playfair-display-sc-latin-700-italic.woff2 +0 -0
  116. package/dist/css/fonts/files/playfair-display-sc-latin-700-normal.woff2 +0 -0
  117. package/dist/css/fonts/files/playfair-display-sc-latin-900-italic.woff2 +0 -0
  118. package/dist/css/fonts/files/playfair-display-sc-latin-900-normal.woff2 +0 -0
  119. package/dist/css/fonts/files/playfair-display-sc-latin-ext-400-italic.woff2 +0 -0
  120. package/dist/css/fonts/files/playfair-display-sc-latin-ext-400-normal.woff2 +0 -0
  121. package/dist/css/fonts/files/playfair-display-sc-latin-ext-700-italic.woff2 +0 -0
  122. package/dist/css/fonts/files/playfair-display-sc-latin-ext-700-normal.woff2 +0 -0
  123. package/dist/css/fonts/files/playfair-display-sc-latin-ext-900-italic.woff2 +0 -0
  124. package/dist/css/fonts/files/playfair-display-sc-latin-ext-900-normal.woff2 +0 -0
  125. package/dist/css/fonts/files/pt-sans-latin-400-italic.woff2 +0 -0
  126. package/dist/css/fonts/files/pt-sans-latin-400-normal.woff2 +0 -0
  127. package/dist/css/fonts/files/pt-sans-latin-700-italic.woff2 +0 -0
  128. package/dist/css/fonts/files/pt-sans-latin-700-normal.woff2 +0 -0
  129. package/dist/css/fonts/files/pt-sans-latin-ext-400-italic.woff2 +0 -0
  130. package/dist/css/fonts/files/pt-sans-latin-ext-400-normal.woff2 +0 -0
  131. package/dist/css/fonts/files/pt-sans-latin-ext-700-italic.woff2 +0 -0
  132. package/dist/css/fonts/files/pt-sans-latin-ext-700-normal.woff2 +0 -0
  133. package/dist/css/fonts/files/pt-sans-narrow-latin-400-normal.woff2 +0 -0
  134. package/dist/css/fonts/files/pt-sans-narrow-latin-700-normal.woff2 +0 -0
  135. package/dist/css/fonts/files/pt-sans-narrow-latin-ext-400-normal.woff2 +0 -0
  136. package/dist/css/fonts/files/pt-sans-narrow-latin-ext-700-normal.woff2 +0 -0
  137. package/dist/css/fonts/files/pt-serif-latin-400-italic.woff2 +0 -0
  138. package/dist/css/fonts/files/pt-serif-latin-400-normal.woff2 +0 -0
  139. package/dist/css/fonts/files/pt-serif-latin-700-italic.woff2 +0 -0
  140. package/dist/css/fonts/files/pt-serif-latin-700-normal.woff2 +0 -0
  141. package/dist/css/fonts/files/pt-serif-latin-ext-400-italic.woff2 +0 -0
  142. package/dist/css/fonts/files/pt-serif-latin-ext-400-normal.woff2 +0 -0
  143. package/dist/css/fonts/files/pt-serif-latin-ext-700-italic.woff2 +0 -0
  144. package/dist/css/fonts/files/pt-serif-latin-ext-700-normal.woff2 +0 -0
  145. package/dist/css/fonts/files/raleway-latin-ext-wght-italic.woff2 +0 -0
  146. package/dist/css/fonts/files/raleway-latin-ext-wght-normal.woff2 +0 -0
  147. package/dist/css/fonts/files/raleway-latin-wght-italic.woff2 +0 -0
  148. package/dist/css/fonts/files/raleway-latin-wght-normal.woff2 +0 -0
  149. package/dist/css/fonts/files/roboto-slab-latin-ext-wght-normal.woff2 +0 -0
  150. package/dist/css/fonts/files/roboto-slab-latin-wght-normal.woff2 +0 -0
  151. package/dist/css/fonts/files/rufina-latin-400-normal.woff2 +0 -0
  152. package/dist/css/fonts/files/rufina-latin-700-normal.woff2 +0 -0
  153. package/dist/css/fonts/files/rufina-latin-ext-400-normal.woff2 +0 -0
  154. package/dist/css/fonts/files/rufina-latin-ext-700-normal.woff2 +0 -0
  155. package/dist/css/fonts/files/ubuntu-latin-300-italic.woff2 +0 -0
  156. package/dist/css/fonts/files/ubuntu-latin-300-normal.woff2 +0 -0
  157. package/dist/css/fonts/files/ubuntu-latin-400-italic.woff2 +0 -0
  158. package/dist/css/fonts/files/ubuntu-latin-400-normal.woff2 +0 -0
  159. package/dist/css/fonts/files/ubuntu-latin-500-italic.woff2 +0 -0
  160. package/dist/css/fonts/files/ubuntu-latin-500-normal.woff2 +0 -0
  161. package/dist/css/fonts/files/ubuntu-latin-700-italic.woff2 +0 -0
  162. package/dist/css/fonts/files/ubuntu-latin-700-normal.woff2 +0 -0
  163. package/dist/css/fonts/files/ubuntu-latin-ext-300-italic.woff2 +0 -0
  164. package/dist/css/fonts/files/ubuntu-latin-ext-300-normal.woff2 +0 -0
  165. package/dist/css/fonts/files/ubuntu-latin-ext-400-italic.woff2 +0 -0
  166. package/dist/css/fonts/files/ubuntu-latin-ext-400-normal.woff2 +0 -0
  167. package/dist/css/fonts/files/ubuntu-latin-ext-500-italic.woff2 +0 -0
  168. package/dist/css/fonts/files/ubuntu-latin-ext-500-normal.woff2 +0 -0
  169. package/dist/css/fonts/files/ubuntu-latin-ext-700-italic.woff2 +0 -0
  170. package/dist/css/fonts/files/ubuntu-latin-ext-700-normal.woff2 +0 -0
  171. package/dist/css/fonts/files/unica-one-latin-400-normal.woff2 +0 -0
  172. package/dist/css/fonts/files/unica-one-latin-ext-400-normal.woff2 +0 -0
  173. package/dist/css/fonts/files/vollkorn-latin-ext-wght-italic.woff2 +0 -0
  174. package/dist/css/fonts/files/vollkorn-latin-ext-wght-normal.woff2 +0 -0
  175. package/dist/css/fonts/files/vollkorn-latin-wght-italic.woff2 +0 -0
  176. package/dist/css/fonts/files/vollkorn-latin-wght-normal.woff2 +0 -0
  177. package/dist/css/fonts/font.abril-droidsans.css +108 -0
  178. package/dist/css/fonts/font.amatic-andika.css +126 -0
  179. package/dist/css/fonts/font.bitter-raleway.css +162 -0
  180. package/dist/css/fonts/font.clicker-garamond.css +149 -0
  181. package/dist/css/fonts/font.dancing-ledger.css +108 -0
  182. package/dist/css/fonts/font.default.css +278 -0
  183. package/dist/css/fonts/font.fjalla-average.css +113 -0
  184. package/dist/css/fonts/font.georgia-helvetica.css +88 -0
  185. package/dist/css/fonts/font.knightlab.css +467 -0
  186. package/dist/css/fonts/font.lustria-lato.css +275 -0
  187. package/dist/css/fonts/font.medula-lato.css +270 -0
  188. package/dist/css/fonts/font.oldstandard.css +160 -0
  189. package/dist/css/fonts/font.opensans-gentiumbook.css +167 -0
  190. package/dist/css/fonts/font.playfair-faunaone.css +145 -0
  191. package/dist/css/fonts/font.playfair.css +234 -0
  192. package/dist/css/fonts/font.pt.css +271 -0
  193. package/dist/css/fonts/font.roboto-megrim.css +108 -0
  194. package/dist/css/fonts/font.rufina-sintony.css +126 -0
  195. package/dist/css/fonts/font.ubuntu.css +237 -0
  196. package/dist/css/fonts/font.unicaone-vollkorn.css +144 -0
  197. package/dist/css/icons/README.md +4 -0
  198. package/dist/css/icons/emoji.png +0 -0
  199. package/dist/css/icons/emoji@2x.png +0 -0
  200. package/dist/css/icons/vco-icons.eot +0 -0
  201. package/dist/css/icons/vco-icons.svg +63 -0
  202. package/dist/css/icons/vco-icons.ttf +0 -0
  203. package/dist/css/icons/vco-icons.woff +0 -0
  204. package/dist/css/icons/vco-icons.woff2 +0 -0
  205. package/dist/css/storymap.css +2 -0
  206. package/dist/demo.html +17 -0
  207. package/dist/demo.json +479 -0
  208. package/dist/docs/api/.nojekyll +1 -0
  209. package/dist/docs/api/assets/custom.css +47 -0
  210. package/dist/docs/api/assets/hierarchy.js +1 -0
  211. package/dist/docs/api/assets/highlight.css +22 -0
  212. package/dist/docs/api/assets/icons.js +18 -0
  213. package/dist/docs/api/assets/icons.svg +1 -0
  214. package/dist/docs/api/assets/main.js +60 -0
  215. package/dist/docs/api/assets/navigation.js +1 -0
  216. package/dist/docs/api/assets/search.js +1 -0
  217. package/dist/docs/api/assets/style.css +1648 -0
  218. package/dist/docs/api/classes/StoryMap.html +799 -0
  219. package/dist/docs/api/functions/MediaType.html +51 -0
  220. package/dist/docs/api/functions/loadCSS.html +64 -0
  221. package/dist/docs/api/functions/setLanguage.html +53 -0
  222. package/dist/docs/api/functions/validateStorymap.html +53 -0
  223. package/dist/docs/api/functions/validateStorymapAndReport.html +54 -0
  224. package/dist/docs/api/hierarchy.html +28 -0
  225. package/dist/docs/api/index.html +127 -0
  226. package/dist/docs/api/modules.html +42 -0
  227. package/dist/docs/iiif.html +912 -0
  228. package/dist/docs/migration.html +264 -0
  229. package/dist/docs/readme.html +178 -0
  230. package/dist/embed/index.html +95 -0
  231. package/dist/examples/assets/placeholder-city.jpg +0 -0
  232. package/dist/examples/assets/placeholder-landscape.jpg +0 -0
  233. package/dist/examples/assets/placeholder-portrait.jpg +0 -0
  234. package/dist/examples/assets/tone.mp3 +0 -0
  235. package/dist/examples/bob-boilen.json +123 -0
  236. package/dist/examples/courbet.json +32 -0
  237. package/dist/examples/empty.json +5 -0
  238. package/dist/examples/flickr-drewvigal.json +341 -0
  239. package/dist/examples/flickr-zach.wise.json +341 -0
  240. package/dist/examples/iiif-wellcome.json +28 -0
  241. package/dist/examples/instagram-chenpamela.json +592 -0
  242. package/dist/examples/instagram_brentfoster.json +565 -0
  243. package/dist/examples/instagram_couch.json +402 -0
  244. package/dist/examples/instagram_joegermuska.json +687 -0
  245. package/dist/examples/instagram_matteich.json +341 -0
  246. package/dist/examples/instagram_mirandamulligan.json +402 -0
  247. package/dist/examples/instagram_raymondmccrea.json +341 -0
  248. package/dist/examples/instagram_test.json +341 -0
  249. package/dist/examples/issue-134-no-lines.json +78 -0
  250. package/dist/examples/issue-177-color-vars.json +44 -0
  251. package/dist/examples/issue-211-rtl.json +44 -0
  252. package/dist/examples/issue-272-facebook.json +47 -0
  253. package/dist/examples/issue-305-start-at-slide.json +95 -0
  254. package/dist/examples/issue-341-distance.json +44 -0
  255. package/dist/examples/issue-360-juxtapose.json +35 -0
  256. package/dist/examples/issue-368-null-fields.json +60 -0
  257. package/dist/examples/issue-375-code-lists.json +35 -0
  258. package/dist/examples/issue-381-dateline.json +77 -0
  259. package/dist/examples/issue-425-many-slides.json +2723 -0
  260. package/dist/examples/issue-428-background.json +62 -0
  261. package/dist/examples/issue-435-googlemaps.json +35 -0
  262. package/dist/examples/issue-437-documentcloud.json +35 -0
  263. package/dist/examples/issue-451-webp.json +35 -0
  264. package/dist/examples/issue-455-audio.json +35 -0
  265. package/dist/examples/issue-480-shorts.json +35 -0
  266. package/dist/examples/issue-506-marker-sync.json +77 -0
  267. package/dist/examples/jansteen.json +1 -0
  268. package/dist/examples/katrina.json +161 -0
  269. package/dist/examples/marktwain.json +341 -0
  270. package/dist/examples/population.json +463 -0
  271. package/dist/examples/president.json +454 -0
  272. package/dist/examples/seurat.json +248 -0
  273. package/dist/examples-iiif/bob-boilen.json +341 -0
  274. package/dist/examples-iiif/courbet.json +80 -0
  275. package/dist/examples-iiif/empty.json +29 -0
  276. package/dist/examples-iiif/flickr-drewvigal.json +1189 -0
  277. package/dist/examples-iiif/flickr-zach.wise.json +1074 -0
  278. package/dist/examples-iiif/iiif-wellcome.json +97 -0
  279. package/dist/examples-iiif/instagram-chenpamela.json +1716 -0
  280. package/dist/examples-iiif/instagram_brentfoster.json +1804 -0
  281. package/dist/examples-iiif/instagram_couch.json +1166 -0
  282. package/dist/examples-iiif/instagram_joegermuska.json +1946 -0
  283. package/dist/examples-iiif/instagram_matteich.json +1190 -0
  284. package/dist/examples-iiif/instagram_mirandamulligan.json +1171 -0
  285. package/dist/examples-iiif/instagram_raymondmccrea.json +1165 -0
  286. package/dist/examples-iiif/instagram_test.json +1185 -0
  287. package/dist/examples-iiif/issue-134-no-lines.json +245 -0
  288. package/dist/examples-iiif/issue-177-color-vars.json +182 -0
  289. package/dist/examples-iiif/issue-211-rtl.json +182 -0
  290. package/dist/examples-iiif/issue-272-facebook.json +146 -0
  291. package/dist/examples-iiif/issue-305-start-at-slide.json +300 -0
  292. package/dist/examples-iiif/issue-341-distance.json +182 -0
  293. package/dist/examples-iiif/issue-360-juxtapose.json +112 -0
  294. package/dist/examples-iiif/issue-368-null-fields.json +202 -0
  295. package/dist/examples-iiif/issue-375-code-lists.json +111 -0
  296. package/dist/examples-iiif/issue-381-dateline.json +244 -0
  297. package/dist/examples-iiif/issue-425-many-slides.json +8476 -0
  298. package/dist/examples-iiif/issue-428-background.json +191 -0
  299. package/dist/examples-iiif/issue-435-googlemaps.json +111 -0
  300. package/dist/examples-iiif/issue-437-documentcloud.json +112 -0
  301. package/dist/examples-iiif/issue-451-webp.json +111 -0
  302. package/dist/examples-iiif/issue-455-audio.json +111 -0
  303. package/dist/examples-iiif/issue-480-shorts.json +110 -0
  304. package/dist/examples-iiif/issue-506-marker-sync.json +244 -0
  305. package/dist/examples-iiif/jansteen.json +509 -0
  306. package/dist/examples-iiif/katrina.json +499 -0
  307. package/dist/examples-iiif/marktwain.json +929 -0
  308. package/dist/examples-iiif/population.json +1464 -0
  309. package/dist/examples-iiif/president.json +1351 -0
  310. package/dist/examples-iiif/seurat.json +870 -0
  311. package/dist/football.json +344 -0
  312. package/dist/harness.html +15 -0
  313. package/dist/index.html +410 -0
  314. package/dist/js/storymap.js +25787 -0
  315. package/dist/js/storymap.js.map +1 -0
  316. package/dist/site.css +592 -0
  317. package/dist/thumbs/bosch-garden.jpg +0 -0
  318. package/dist/thumbs/iiif-wellcome.jpg +0 -0
  319. package/dist/thumbs/katrina.jpg +0 -0
  320. package/dist/thumbs/marktwain.jpg +0 -0
  321. package/dist/thumbs/population.jpg +0 -0
  322. package/dist/thumbs/president.jpg +0 -0
  323. package/dist/thumbs/seurat.jpg +0 -0
  324. package/dist/thumbs/southern-literary-trail.jpg +0 -0
  325. package/package.json +105 -0
  326. package/schema/storymap.schema.json +192 -0
@@ -0,0 +1,912 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>StoryMap data as IIIF manifests — StoryMapJS</title>
7
+ <meta name="description" content="StoryMap data as IIIF manifests — StoryMapJS documentation" />
8
+ <link rel="stylesheet" href="../site.css" />
9
+ </head>
10
+ <body class="sm-site">
11
+
12
+ <nav class="navbar navbar-dark">
13
+ <ul>
14
+ <li class="logo">
15
+ <a href="../index.html">StoryMap <span>JS</span></a>
16
+ </li>
17
+ </ul>
18
+ <ul class="nav-right">
19
+ <li>
20
+ <a class="button button-dark button-active" href="https://github.com/cmahnke/StoryMapJS"
21
+ >GitHub</a
22
+ >
23
+ </li>
24
+ <li>
25
+ <a class="button button-dark" href="https://github.com/cmahnke/StoryMapJS/issues"
26
+ >Issues</a
27
+ >
28
+ </li>
29
+ </ul>
30
+ </nav>
31
+ <header class="header-product header-product-docs">
32
+ <nav id="navbar-secondary" class="navbar navbar-subnav" aria-label="Page navigation">
33
+ <ul>
34
+ <li><a class="button" href="../index.html#overview">Overview</a></li>
35
+ <li><a class="button" href="../index.html#examples">Examples</a></li>
36
+ <li><a class="button" href="./readme.html">README</a></li>
37
+ <li><a class="button" href="./migration.html">Migration guide</a></li>
38
+ <li><a class="button" href="./iiif.html">IIIF docs</a></li>
39
+ <li><a class="button" href="./api/index.html">API docs</a></li>
40
+ <li><a class="button" href="../index.html#help">Help</a></li>
41
+ </ul>
42
+ </nav>
43
+ </header>
44
+ <main class="sm-docs">
45
+ <h1>StoryMap data as IIIF Presentation 3.0 manifests</h1>
46
+ <p>A proposal for exchanging StoryMapJS data as
47
+ <a href="https://iiif.io/api/presentation/3.0/">IIIF Presentation API 3.0</a> manifests so
48
+ that stories can be preserved, harvested and re-rendered by IIIF-aware tools.</p>
49
+ <p>The legacy format is described by <a href="https://github.com/cmahnke/StoryMapJS/tree/main/schema/storymap.schema.json"><code>schema/storymap.schema.json</code></a>;
50
+ the fixtures in <a href="../examples/"><code>public/examples/</code></a> are real-world samples.
51
+ <code>scripts/convert-to-iiif.mjs</code> converts every fixture to this proposal
52
+ (<a href="../examples-iiif/"><code>public/examples-iiif/</code></a>), and
53
+ <code>scripts/validate-iiif.mjs</code> checks every converted manifest against the
54
+ <a href="https://presentation-validator.iiif.io/">official IIIF presentation validator</a>
55
+ (<code>npm run validate:iiif</code>). All converted fixtures pass the official validator.</p>
56
+ <h2>Contexts</h2>
57
+ <p>A manifest carries three context URLs: the Presentation 3.0 context, the
58
+ official <a href="https://iiif.io/api/extension/navplace/">navPlace extension</a> context,
59
+ and the StoryMap extension context:</p>
60
+ <pre><code class="language-json">{
61
+ &quot;@context&quot;: [
62
+ &quot;http://iiif.io/api/presentation/3/context.json&quot;,
63
+ &quot;http://iiif.io/api/extension/navplace/context.json&quot;,
64
+ &quot;https://cmahnke.github.io/StoryMapJS/context.json&quot;
65
+ ]
66
+ }
67
+ </code></pre>
68
+ <h3>navPlace context (official)</h3>
69
+ <p>Served at <code>http://iiif.io/api/extension/navplace/context.json</code>. It binds the
70
+ <code>navPlace</code> property to a GeoJSON FeatureCollection:</p>
71
+ <pre><code class="language-json">{
72
+ &quot;@context&quot;: {
73
+ &quot;@version&quot;: 1.1,
74
+ &quot;iiif_navPlace&quot;: &quot;http://iiif.io/api/extension/navplace#&quot;,
75
+ &quot;navPlace&quot;: {
76
+ &quot;@context&quot;: &quot;https://geojson.org/geojson-ld/geojson-context.jsonld&quot;,
77
+ &quot;@id&quot;: &quot;iiif_navPlace:navPlace&quot;
78
+ }
79
+ }
80
+ }
81
+ </code></pre>
82
+ <h3>StoryMap context</h3>
83
+ <p>StoryMap-specific terms use the <code>storymap:</code> prefix (the term IRIs live under
84
+ <code>https://christianmahnke.de/iiif/storymap#</code>). The context document is
85
+ <a href="../context.json"><code>public/context.json</code></a> — it ships with the demo build
86
+ and is served at <code>https://cmahnke.github.io/StoryMapJS/context.json</code>, which is
87
+ what the fixtures reference. Content:</p>
88
+ <pre><code class="language-json">{
89
+ &quot;@context&quot;: {
90
+ &quot;@version&quot;: 1.1,
91
+ &quot;storymap&quot;: &quot;https://christianmahnke.de/iiif/storymap#&quot;,
92
+ &quot;mapType&quot;: &quot;storymap:mapType&quot;,
93
+ &quot;mapAsImage&quot;: &quot;storymap:mapAsImage&quot;,
94
+ &quot;mapAccessToken&quot;: &quot;storymap:mapAccessToken&quot;,
95
+ &quot;mapBackgroundColor&quot;: &quot;storymap:mapBackgroundColor&quot;,
96
+ &quot;mapCenterOffset&quot;: &quot;storymap:mapCenterOffset&quot;,
97
+ &quot;mapSubdomains&quot;: &quot;storymap:mapSubdomains&quot;,
98
+ &quot;iiifUrl&quot;: { &quot;@id&quot;: &quot;storymap:iiifUrl&quot;, &quot;@type&quot;: &quot;@id&quot; },
99
+ &quot;fontCss&quot;: &quot;storymap:fontCss&quot;,
100
+ &quot;callToAction&quot;: &quot;storymap:callToAction&quot;,
101
+ &quot;callToActionText&quot;: &quot;storymap:callToActionText&quot;,
102
+ &quot;startAtSlide&quot;: &quot;storymap:startAtSlide&quot;,
103
+ &quot;language&quot;: &quot;storymap:language&quot;,
104
+ &quot;calculateZoom&quot;: &quot;storymap:calculateZoom&quot;,
105
+ &quot;lessBounce&quot;: &quot;storymap:lessBounce&quot;,
106
+ &quot;lineFollowsPath&quot;: &quot;storymap:lineFollowsPath&quot;,
107
+ &quot;showLines&quot;: &quot;storymap:showLines&quot;,
108
+ &quot;showHistoryLine&quot;: &quot;storymap:showHistoryLine&quot;,
109
+ &quot;lineColor&quot;: &quot;storymap:lineColor&quot;,
110
+ &quot;lineColorInactive&quot;: &quot;storymap:lineColorInactive&quot;,
111
+ &quot;lineWeight&quot;: &quot;storymap:lineWeight&quot;,
112
+ &quot;lineOpacity&quot;: &quot;storymap:lineOpacity&quot;,
113
+ &quot;lineDash&quot;: &quot;storymap:lineDash&quot;,
114
+ &quot;lineJoin&quot;: &quot;storymap:lineJoin&quot;,
115
+ &quot;useCustomMarkers&quot;: &quot;storymap:useCustomMarkers&quot;,
116
+ &quot;type&quot;: { &quot;@id&quot;: &quot;storymap:type&quot;, &quot;@type&quot;: &quot;@id&quot; },
117
+ &quot;background&quot;: &quot;storymap:background&quot;,
118
+ &quot;mediaCaption&quot;: &quot;storymap:mediaCaption&quot;,
119
+ &quot;mediaCredit&quot;: &quot;storymap:mediaCredit&quot;,
120
+ &quot;date&quot;: &quot;storymap:date&quot;
121
+ }
122
+ }
123
+ </code></pre>
124
+ <h2>Manifest ↔ storymap root</h2>
125
+ <table>
126
+ <thead>
127
+ <tr>
128
+ <th>IIIF</th>
129
+ <th>StoryMap</th>
130
+ <th>Notes</th>
131
+ </tr>
132
+ </thead>
133
+ <tbody><tr>
134
+ <td><code>id</code></td>
135
+ <td>—</td>
136
+ <td><code>https://example.org/storymap/&lt;name&gt;</code> (absolute URIs required)</td>
137
+ </tr>
138
+ <tr>
139
+ <td><code>type</code></td>
140
+ <td>—</td>
141
+ <td><code>&quot;Manifest&quot;</code></td>
142
+ </tr>
143
+ <tr>
144
+ <td><code>label</code></td>
145
+ <td><code>storymap.title</code> (extra)</td>
146
+ <td>Language map, e.g. <code>{&quot;none&quot;: [&quot;StoryMapJS&quot;]}</code>; the legacy format has no title field, so readers keep it as an extra <code>title</code> field</td>
147
+ </tr>
148
+ <tr>
149
+ <td><code>items</code></td>
150
+ <td><code>storymap.slides</code></td>
151
+ <td>One Canvas per slide, in slide order</td>
152
+ </tr>
153
+ <tr>
154
+ <td><code>summary</code></td>
155
+ <td>—</td>
156
+ <td>Optional language map</td>
157
+ </tr>
158
+ <tr>
159
+ <td><code>provider</code></td>
160
+ <td>—</td>
161
+ <td>Optional publishing institution</td>
162
+ </tr>
163
+ <tr>
164
+ <td><code>behavior</code></td>
165
+ <td>—</td>
166
+ <td><code>[&quot;paged&quot;]</code> — the story is consumed slide by slide</td>
167
+ </tr>
168
+ <tr>
169
+ <td><code>requiredStatement</code></td>
170
+ <td><code>storymap.iiif.attribution</code></td>
171
+ <td>Only when an attribution is present</td>
172
+ </tr>
173
+ <tr>
174
+ <td><code>navPlace</code> <em>(optional)</em></td>
175
+ <td>—</td>
176
+ <td>Optional manifest-level aggregation of canvas locations</td>
177
+ </tr>
178
+ <tr>
179
+ <td><code>service</code> (map config)</td>
180
+ <td><code>storymap.*</code> map settings</td>
181
+ <td>See &quot;StoryMap-specific terms&quot; below</td>
182
+ </tr>
183
+ </tbody></table>
184
+ <h2>Canvas ↔ slide</h2>
185
+ <p>Each slide becomes one Canvas in <code>items</code> order. Canvas ids are
186
+ <code>&lt;manifest-id&gt;/canvas/&lt;n&gt;</code> (1-based); each Canvas carries a single AnnotationPage
187
+ (<code>&lt;canvas-id&gt;/annotationpage/1</code>) holding the slide&#39;s painted media
188
+ (<code>&lt;canvas-id&gt;/annotation/1</code>, <code>motivation: &quot;painting&quot;</code>, <code>target: &lt;canvas-id&gt;</code>).</p>
189
+ <table>
190
+ <thead>
191
+ <tr>
192
+ <th>IIIF</th>
193
+ <th>StoryMap</th>
194
+ <th>Notes</th>
195
+ </tr>
196
+ </thead>
197
+ <tbody><tr>
198
+ <td><code>id</code>, <code>type</code></td>
199
+ <td>—</td>
200
+ <td><code>&quot;Canvas&quot;</code></td>
201
+ </tr>
202
+ <tr>
203
+ <td><code>label</code></td>
204
+ <td><code>slide.text.headline</code></td>
205
+ <td>Language map <code>{&quot;none&quot;: [headline]}</code>; omitted when the headline is empty</td>
206
+ </tr>
207
+ <tr>
208
+ <td><code>summary</code></td>
209
+ <td><code>slide.text.text</code></td>
210
+ <td>Language map; the slide body text (may contain HTML)</td>
211
+ </tr>
212
+ <tr>
213
+ <td><code>height</code>, <code>width</code></td>
214
+ <td>—</td>
215
+ <td>Nominal <code>1080 × 1080</code> for non-image slides; actual image dimensions for image-map slides</td>
216
+ </tr>
217
+ <tr>
218
+ <td><code>items</code></td>
219
+ <td><code>slide.media</code></td>
220
+ <td>AnnotationPage with the painting annotation, see below</td>
221
+ </tr>
222
+ <tr>
223
+ <td><code>storymap:type</code></td>
224
+ <td><code>slide.type</code></td>
225
+ <td><code>&quot;overview&quot;</code> marks the map overview slide</td>
226
+ </tr>
227
+ <tr>
228
+ <td><code>storymap:background</code></td>
229
+ <td><code>slide.background</code></td>
230
+ <td><code>{url, color}</code> — only present keys</td>
231
+ </tr>
232
+ <tr>
233
+ <td><code>storymap:mediaCaption</code></td>
234
+ <td><code>slide.media.caption</code></td>
235
+ <td></td>
236
+ </tr>
237
+ <tr>
238
+ <td><code>storymap:mediaCredit</code></td>
239
+ <td><code>slide.media.credit</code></td>
240
+ <td></td>
241
+ </tr>
242
+ <tr>
243
+ <td><code>storymap:date</code></td>
244
+ <td><code>slide.date</code></td>
245
+ <td>String or object, verbatim</td>
246
+ </tr>
247
+ <tr>
248
+ <td><code>navPlace</code></td>
249
+ <td><code>slide.location</code></td>
250
+ <td>See below</td>
251
+ </tr>
252
+ </tbody></table>
253
+ <h2>Locations via navPlace</h2>
254
+ <p>Canvas locations use the official
255
+ <a href="https://iiif.io/api/extension/navplace/">navPlace extension</a>: each Canvas with
256
+ a numeric <code>location.lat</code>/<code>location.lon</code> carries a <code>navPlace</code> FeatureCollection
257
+ with one GeoJSON Feature:</p>
258
+ <ul>
259
+ <li><code>geometry</code>: <code>{type: &quot;Point&quot;, coordinates: [lon, lat]}</code> — the storymap values
260
+ verbatim. For image-map storymaps (<code>storymap:mapAsImage: true</code>) the values are
261
+ image coordinates rather than WGS84 degrees; consumers can detect this via
262
+ <code>storymap:mapAsImage</code>.</li>
263
+ <li><code>properties</code>: marker data — <code>zoom</code>, <code>line</code>, <code>icon</code>, <code>iconSize</code>, <code>image</code>,
264
+ <code>use_custom_marker</code>, <code>name</code> (only present keys).</li>
265
+ <li><code>location.use_custom_marker</code> / <code>use_custom_markers</code> (manifest) opt into
266
+ custom marker rendering; see the storymap terms below.</li>
267
+ </ul>
268
+ <p>Alternatively a manifest MAY aggregate all slide locations in a single
269
+ manifest-level <code>navPlace</code> with one Feature per Canvas in <code>items</code> order.</p>
270
+ <h2>Slide media</h2>
271
+ <p>The slide&#39;s media becomes a painting annotation on the canvas with a typed body:</p>
272
+ <ul>
273
+ <li>Image URLs → <code>{id, type: &quot;Image&quot;, format: &quot;image/jpeg&quot; | ...}</code></li>
274
+ <li>Video services (YouTube, Vimeo, Dailymotion, Vine) → <code>{id, type: &quot;Video&quot;}</code></li>
275
+ <li>Audio services (SoundCloud) → <code>{id, type: &quot;Sound&quot;}</code></li>
276
+ <li>Page-embedded media (tweets, Wikipedia, photo pages) → <code>{id, type: &quot;Text&quot;, format: &quot;text/html&quot;}</code></li>
277
+ <li>Text-only slides (no media URL, or a media value that is an HTML snippet) →
278
+ <code>{type: &quot;TextualBody&quot;, format: &quot;text/html&quot;, value: &quot;&lt;html&gt;&quot;}</code></li>
279
+ </ul>
280
+ <p>Media URL inference (YouTube players, Twitter embeds, etc.) remains a viewer
281
+ concern — manifests carry plain typed bodies and never embed service-specific
282
+ logic.</p>
283
+ <h2>IIIF image-map slides (replacing zoomify)</h2>
284
+ <p>Storymaps that paint an image as the map (<code>map_as_image: true</code> with <code>map_type: &quot;iiif&quot;</code>, formerly <code>&quot;zoomify&quot;</code>) have canvases that paint an Image annotation
285
+ whose body references an IIIF Image API service. The canvas dimensions are the
286
+ actual image dimensions. Two body variants are valid:</p>
287
+ <p><strong>(a) plain image body:</strong></p>
288
+ <pre><code class="language-json">{
289
+ &quot;id&quot;: &quot;https://iiif.io/api/image/3.0/example/reference/28473c77da3deebe4375c3a50572d9d3-laocoon/full/max/0/default.jpg&quot;,
290
+ &quot;type&quot;: &quot;Image&quot;,
291
+ &quot;format&quot;: &quot;image/jpeg&quot;,
292
+ &quot;width&quot;: 2315,
293
+ &quot;height&quot;: 3000
294
+ }
295
+ </code></pre>
296
+ <p><strong>(b) body with an ImageService3 reference (preferred):</strong></p>
297
+ <pre><code class="language-json">{
298
+ &quot;id&quot;: &quot;https://iiif.io/api/image/3.0/example/reference/28473c77da3deebe4375c3a50572d9d3-laocoon/full/max/0/default.jpg&quot;,
299
+ &quot;type&quot;: &quot;Image&quot;,
300
+ &quot;format&quot;: &quot;image/jpeg&quot;,
301
+ &quot;width&quot;: 2315,
302
+ &quot;height&quot;: 3000,
303
+ &quot;service&quot;: [
304
+ {
305
+ &quot;id&quot;: &quot;https://iiif.io/api/image/3.0/example/reference/28473c77da3deebe4375c3a50572d9d3-laocoon/info.json&quot;,
306
+ &quot;type&quot;: &quot;ImageService3&quot;,
307
+ &quot;profile&quot;: &quot;level2&quot;
308
+ }
309
+ ]
310
+ }
311
+ </code></pre>
312
+ <p>The converter emits variant (b). Legacy <code>zoomify</code> storymaps are converted to
313
+ <code>storymap:mapType: &quot;iiif&quot;</code>; since the original zoomify tile paths are dead, the
314
+ converter substitutes the IIIF reference image above (the legacy pyramid
315
+ definition is not carried — nothing reads it).</p>
316
+ <h2>StoryMap-specific terms</h2>
317
+ <h3>Manifest level — via a map configuration service</h3>
318
+ <p>The official validator validates manifests against a JSON Schema whose Manifest
319
+ class is closed (<code>additionalProperties: false</code>), so manifest-level StoryMap
320
+ settings cannot be placed directly on the Manifest object. They live on a
321
+ dedicated extension service instead — a JSON-LD-idiomatic place for extended
322
+ configuration, and one the validator accepts (<code>service</code> entries allow extra
323
+ properties):</p>
324
+ <pre><code class="language-json">{
325
+ &quot;service&quot;: [
326
+ {
327
+ &quot;id&quot;: &quot;https://example.org/storymap/&lt;name&gt;/map-config&quot;,
328
+ &quot;type&quot;: &quot;Service&quot;,
329
+ &quot;profile&quot;: &quot;https://christianmahnke.de/iiif/storymap/mapconfig&quot;,
330
+ &quot;storymap:mapType&quot;: &quot;osm:standard&quot;
331
+ }
332
+ ]
333
+ }
334
+ </code></pre>
335
+ <table>
336
+ <thead>
337
+ <tr>
338
+ <th>Service property (storymap:)</th>
339
+ <th>StoryMap field</th>
340
+ <th>Values</th>
341
+ </tr>
342
+ </thead>
343
+ <tbody><tr>
344
+ <td><code>mapType</code></td>
345
+ <td><code>map_type</code></td>
346
+ <td><code>osm:standard</code>, <code>mapbox:...</code>, <code>stadia:...</code>, <code>iiif</code>, or an <code>https://...</code> tile URL; <code>zoomify</code> is replaced by <code>iiif</code></td>
347
+ </tr>
348
+ <tr>
349
+ <td><code>mapAsImage</code></td>
350
+ <td><code>map_as_image</code></td>
351
+ <td><code>true</code> when the image itself is the map</td>
352
+ </tr>
353
+ <tr>
354
+ <td><code>mapAccessToken</code></td>
355
+ <td><code>map_access_token</code></td>
356
+ <td>Mapbox/Stadia token from the storymap data, never the repository</td>
357
+ </tr>
358
+ <tr>
359
+ <td><code>mapBackgroundColor</code></td>
360
+ <td><code>map_background_color</code></td>
361
+ <td>CSS color</td>
362
+ </tr>
363
+ <tr>
364
+ <td><code>mapCenterOffset</code></td>
365
+ <td><code>map_center_offset</code></td>
366
+ <td><code>{left, top}</code></td>
367
+ </tr>
368
+ <tr>
369
+ <td><code>mapSubdomains</code></td>
370
+ <td><code>map_subdomains</code></td>
371
+ <td>Tile URL subdomains</td>
372
+ </tr>
373
+ <tr>
374
+ <td><code>iiifUrl</code></td>
375
+ <td><code>iiif.url</code></td>
376
+ <td>IIIF Image API <code>info.json</code> URL for image-map storymaps</td>
377
+ </tr>
378
+ <tr>
379
+ <td><code>fontCss</code></td>
380
+ <td><code>font_css</code></td>
381
+ <td>e.g. <code>stock:dancing-ledger</code></td>
382
+ </tr>
383
+ <tr>
384
+ <td><code>callToAction</code></td>
385
+ <td><code>call_to_action</code></td>
386
+ <td>boolean</td>
387
+ </tr>
388
+ <tr>
389
+ <td><code>callToActionText</code></td>
390
+ <td><code>call_to_action_text</code></td>
391
+ <td>string</td>
392
+ </tr>
393
+ <tr>
394
+ <td><code>startAtSlide</code></td>
395
+ <td><code>start_at_slide</code></td>
396
+ <td>0-based slide index</td>
397
+ </tr>
398
+ <tr>
399
+ <td><code>language</code></td>
400
+ <td><code>language</code></td>
401
+ <td>IETF language tag</td>
402
+ </tr>
403
+ <tr>
404
+ <td><code>calculateZoom</code></td>
405
+ <td><code>calculate_zoom</code></td>
406
+ <td>boolean</td>
407
+ </tr>
408
+ <tr>
409
+ <td><code>lessBounce</code></td>
410
+ <td><code>less_bounce</code></td>
411
+ <td>boolean</td>
412
+ </tr>
413
+ <tr>
414
+ <td><code>lineFollowsPath</code></td>
415
+ <td><code>line_follows_path</code></td>
416
+ <td>boolean</td>
417
+ </tr>
418
+ <tr>
419
+ <td><code>showLines</code></td>
420
+ <td><code>show_lines</code></td>
421
+ <td>boolean</td>
422
+ </tr>
423
+ <tr>
424
+ <td><code>showHistoryLine</code></td>
425
+ <td><code>show_history_line</code></td>
426
+ <td>boolean</td>
427
+ </tr>
428
+ <tr>
429
+ <td><code>lineColor</code></td>
430
+ <td><code>line_color</code></td>
431
+ <td>CSS color</td>
432
+ </tr>
433
+ <tr>
434
+ <td><code>lineColorInactive</code></td>
435
+ <td><code>line_color_inactive</code></td>
436
+ <td>CSS color</td>
437
+ </tr>
438
+ <tr>
439
+ <td><code>lineWeight</code></td>
440
+ <td><code>line_weight</code></td>
441
+ <td>number (px)</td>
442
+ </tr>
443
+ <tr>
444
+ <td><code>lineOpacity</code></td>
445
+ <td><code>line_opacity</code></td>
446
+ <td>0–1</td>
447
+ </tr>
448
+ <tr>
449
+ <td><code>lineDash</code></td>
450
+ <td><code>line_dash</code></td>
451
+ <td>CSS dash pattern</td>
452
+ </tr>
453
+ <tr>
454
+ <td><code>lineJoin</code></td>
455
+ <td><code>line_join</code></td>
456
+ <td>CSS line join</td>
457
+ </tr>
458
+ <tr>
459
+ <td><code>useCustomMarkers</code></td>
460
+ <td><code>use_custom_markers</code></td>
461
+ <td>boolean</td>
462
+ </tr>
463
+ </tbody></table>
464
+ <h3>Canvas level — direct properties</h3>
465
+ <p>Canvas objects are open for extension terms, so slide-specific StoryMap data is
466
+ carried directly on the Canvas: <code>storymap:type</code>, <code>storymap:background</code>,
467
+ <code>storymap:mediaCaption</code>, <code>storymap:mediaCredit</code>, <code>storymap:date</code> (see the
468
+ Canvas table above).</p>
469
+ <p>Readers must use the prefixed term for the slide type (<code>storymap:type</code>): the
470
+ bare <code>type</code> key of a Canvas is the IIIF class type (<code>&quot;Canvas&quot;</code>) and can never
471
+ carry the StoryMap slide type.</p>
472
+ <h2>Validator interop</h2>
473
+ <p>The official IIIF presentation validator
474
+ (<code>https://presentation-validator.iiif.io/validate?version=3.0&amp;format=json</code>)
475
+ validates manifests with a static JSON Schema:</p>
476
+ <ul>
477
+ <li><code>navPlace</code> (manifest- and canvas-level) is part of the schema and passes;
478
+ GeoJSON Feature <code>properties</code> are open objects and tolerate marker data.</li>
479
+ <li>Canvas objects are open and tolerate <code>storymap:</code> terms.</li>
480
+ <li>The Manifest object is <strong>closed</strong> — <code>storymap:</code> terms directly on the Manifest
481
+ are rejected, hence the map configuration service described above.</li>
482
+ <li><code>@context</code> entries must be URI strings; a StoryMap namespace cannot be
483
+ declared inline but must be referenced by URL.</li>
484
+ </ul>
485
+ <p><code>npm run validate:iiif</code> posts every manifest in <code>public/examples-iiif/</code> to the
486
+ official validator and fails CI when any of them is rejected.</p>
487
+ <h2>Worked example</h2>
488
+ <p>A small hurricane storymap: an overview slide (text-only media), a slide with a
489
+ photo, and a slide with a YouTube video — full manifest:</p>
490
+ <pre><code class="language-json">{
491
+ &quot;@context&quot;: [
492
+ &quot;http://iiif.io/api/presentation/3/context.json&quot;,
493
+ &quot;http://iiif.io/api/extension/navplace/context.json&quot;,
494
+ &quot;https://cmahnke.github.io/StoryMapJS/context.json&quot;
495
+ ],
496
+ &quot;id&quot;: &quot;https://example.org/storymap/storm&quot;,
497
+ &quot;type&quot;: &quot;Manifest&quot;,
498
+ &quot;label&quot;: { &quot;none&quot;: [&quot;storm&quot;] },
499
+ &quot;behavior&quot;: [&quot;paged&quot;],
500
+ &quot;provider&quot;: [
501
+ {
502
+ &quot;id&quot;: &quot;https://example.org/&quot;,
503
+ &quot;type&quot;: &quot;Agent&quot;,
504
+ &quot;label&quot;: { &quot;none&quot;: [&quot;StoryMapJS&quot;] }
505
+ }
506
+ ],
507
+ &quot;service&quot;: [
508
+ {
509
+ &quot;id&quot;: &quot;https://example.org/storymap/storm/map-config&quot;,
510
+ &quot;type&quot;: &quot;Service&quot;,
511
+ &quot;profile&quot;: &quot;https://christianmahnke.de/iiif/storymap/mapconfig&quot;,
512
+ &quot;storymap:mapType&quot;: &quot;osm:standard&quot;,
513
+ &quot;storymap:language&quot;: &quot;en&quot;,
514
+ &quot;storymap:showLines&quot;: true,
515
+ &quot;storymap:showHistoryLine&quot;: true,
516
+ &quot;storymap:lineColor&quot;: &quot;#c0392b&quot;,
517
+ &quot;storymap:lineWeight&quot;: 3,
518
+ &quot;storymap:lineOpacity&quot;: 0.8
519
+ }
520
+ ],
521
+ &quot;items&quot;: [
522
+ {
523
+ &quot;id&quot;: &quot;https://example.org/storymap/storm/canvas/1&quot;,
524
+ &quot;type&quot;: &quot;Canvas&quot;,
525
+ &quot;height&quot;: 1080,
526
+ &quot;width&quot;: 1080,
527
+ &quot;label&quot;: { &quot;none&quot;: [&quot;The Path of the Storm&quot;] },
528
+ &quot;summary&quot;: { &quot;none&quot;: [&quot;A storm formed over the warm ocean.&quot;] },
529
+ &quot;items&quot;: [
530
+ {
531
+ &quot;id&quot;: &quot;https://example.org/storymap/storm/canvas/1/annotationpage/1&quot;,
532
+ &quot;type&quot;: &quot;AnnotationPage&quot;,
533
+ &quot;items&quot;: [
534
+ {
535
+ &quot;id&quot;: &quot;https://example.org/storymap/storm/canvas/1/annotation/1&quot;,
536
+ &quot;type&quot;: &quot;Annotation&quot;,
537
+ &quot;motivation&quot;: &quot;painting&quot;,
538
+ &quot;body&quot;: {
539
+ &quot;type&quot;: &quot;TextualBody&quot;,
540
+ &quot;format&quot;: &quot;text/html&quot;,
541
+ &quot;value&quot;: &quot;A storm formed over the warm ocean.&quot;
542
+ },
543
+ &quot;target&quot;: &quot;https://example.org/storymap/storm/canvas/1&quot;
544
+ }
545
+ ]
546
+ }
547
+ ],
548
+ &quot;storymap:type&quot;: &quot;overview&quot;,
549
+ &quot;storymap:date&quot;: &quot;Sep 1&quot;
550
+ },
551
+ {
552
+ &quot;id&quot;: &quot;https://example.org/storymap/storm/canvas/2&quot;,
553
+ &quot;type&quot;: &quot;Canvas&quot;,
554
+ &quot;height&quot;: 1080,
555
+ &quot;width&quot;: 1080,
556
+ &quot;label&quot;: { &quot;none&quot;: [&quot;Sep 2&quot;] },
557
+ &quot;summary&quot;: { &quot;none&quot;: [&quot;The storm made landfall.&quot;] },
558
+ &quot;items&quot;: [
559
+ {
560
+ &quot;id&quot;: &quot;https://example.org/storymap/storm/canvas/2/annotationpage/1&quot;,
561
+ &quot;type&quot;: &quot;AnnotationPage&quot;,
562
+ &quot;items&quot;: [
563
+ {
564
+ &quot;id&quot;: &quot;https://example.org/storymap/storm/canvas/2/annotation/1&quot;,
565
+ &quot;type&quot;: &quot;Annotation&quot;,
566
+ &quot;motivation&quot;: &quot;painting&quot;,
567
+ &quot;body&quot;: {
568
+ &quot;id&quot;: &quot;https://example.org/images/landfall.jpg&quot;,
569
+ &quot;type&quot;: &quot;Image&quot;,
570
+ &quot;format&quot;: &quot;image/jpeg&quot;
571
+ },
572
+ &quot;target&quot;: &quot;https://example.org/storymap/storm/canvas/2&quot;
573
+ }
574
+ ]
575
+ }
576
+ ],
577
+ &quot;storymap:mediaCaption&quot;: &quot;Landfall&quot;,
578
+ &quot;storymap:mediaCredit&quot;: &quot;Weather Service&quot;,
579
+ &quot;storymap:date&quot;: &quot;Sep 2&quot;,
580
+ &quot;navPlace&quot;: {
581
+ &quot;id&quot;: &quot;https://example.org/storymap/storm/canvas/2/navplace&quot;,
582
+ &quot;type&quot;: &quot;FeatureCollection&quot;,
583
+ &quot;features&quot;: [
584
+ {
585
+ &quot;id&quot;: &quot;https://example.org/storymap/storm/canvas/2/navplace/feature/1&quot;,
586
+ &quot;type&quot;: &quot;Feature&quot;,
587
+ &quot;geometry&quot;: { &quot;type&quot;: &quot;Point&quot;, &quot;coordinates&quot;: [-89.6, 28.2] },
588
+ &quot;properties&quot;: { &quot;zoom&quot;: 10, &quot;line&quot;: true }
589
+ }
590
+ ]
591
+ }
592
+ },
593
+ {
594
+ &quot;id&quot;: &quot;https://example.org/storymap/storm/canvas/3&quot;,
595
+ &quot;type&quot;: &quot;Canvas&quot;,
596
+ &quot;height&quot;: 1080,
597
+ &quot;width&quot;: 1080,
598
+ &quot;label&quot;: { &quot;none&quot;: [&quot;Sep 3&quot;] },
599
+ &quot;items&quot;: [
600
+ {
601
+ &quot;id&quot;: &quot;https://example.org/storymap/storm/canvas/3/annotationpage/1&quot;,
602
+ &quot;type&quot;: &quot;AnnotationPage&quot;,
603
+ &quot;items&quot;: [
604
+ {
605
+ &quot;id&quot;: &quot;https://example.org/storymap/storm/canvas/3/annotation/1&quot;,
606
+ &quot;type&quot;: &quot;Annotation&quot;,
607
+ &quot;motivation&quot;: &quot;painting&quot;,
608
+ &quot;body&quot;: {
609
+ &quot;id&quot;: &quot;https://www.youtube.com/watch?v=example&quot;,
610
+ &quot;type&quot;: &quot;Video&quot;
611
+ },
612
+ &quot;target&quot;: &quot;https://example.org/storymap/storm/canvas/3&quot;
613
+ }
614
+ ]
615
+ }
616
+ ],
617
+ &quot;storymap:mediaCredit&quot;: &quot;News&quot;,
618
+ &quot;storymap:date&quot;: &quot;Sep 3&quot;,
619
+ &quot;navPlace&quot;: {
620
+ &quot;id&quot;: &quot;https://example.org/storymap/storm/canvas/3/navplace&quot;,
621
+ &quot;type&quot;: &quot;FeatureCollection&quot;,
622
+ &quot;features&quot;: [
623
+ {
624
+ &quot;id&quot;: &quot;https://example.org/storymap/storm/canvas/3/navplace/feature/1&quot;,
625
+ &quot;type&quot;: &quot;Feature&quot;,
626
+ &quot;geometry&quot;: { &quot;type&quot;: &quot;Point&quot;, &quot;coordinates&quot;: [-90.1, 29.9] },
627
+ &quot;properties&quot;: { &quot;zoom&quot;: 9, &quot;line&quot;: true }
628
+ }
629
+ ]
630
+ }
631
+ }
632
+ ]
633
+ }
634
+ </code></pre>
635
+ <h2>Full mapping table</h2>
636
+ <table>
637
+ <thead>
638
+ <tr>
639
+ <th>Legacy field (storymap root)</th>
640
+ <th>IIIF path</th>
641
+ </tr>
642
+ </thead>
643
+ <tbody><tr>
644
+ <td><code>slides</code></td>
645
+ <td><code>items[]</code> (Canvas per slide)</td>
646
+ </tr>
647
+ <tr>
648
+ <td><code>language</code></td>
649
+ <td><code>service[0].storymap:language</code></td>
650
+ </tr>
651
+ <tr>
652
+ <td><code>map_type</code></td>
653
+ <td><code>service[0].storymap:mapType</code> (<code>zoomify</code> → <code>iiif</code>)</td>
654
+ </tr>
655
+ <tr>
656
+ <td><code>map_as_image</code></td>
657
+ <td><code>service[0].storymap:mapAsImage</code></td>
658
+ </tr>
659
+ <tr>
660
+ <td><code>map_mini</code></td>
661
+ <td><em>dropped</em> (viewer setting, not part of the exchange format)</td>
662
+ </tr>
663
+ <tr>
664
+ <td><code>map_subdomains</code></td>
665
+ <td><code>service[0].storymap:mapSubdomains</code></td>
666
+ </tr>
667
+ <tr>
668
+ <td><code>map_access_token</code></td>
669
+ <td><code>service[0].storymap:mapAccessToken</code></td>
670
+ </tr>
671
+ <tr>
672
+ <td><code>map_background_color</code></td>
673
+ <td><code>service[0].storymap:mapBackgroundColor</code></td>
674
+ </tr>
675
+ <tr>
676
+ <td><code>map_center_offset</code></td>
677
+ <td><code>service[0].storymap:mapCenterOffset</code></td>
678
+ </tr>
679
+ <tr>
680
+ <td><code>map_popup</code></td>
681
+ <td><em>dropped</em> (viewer setting)</td>
682
+ </tr>
683
+ <tr>
684
+ <td><code>use_custom_markers</code></td>
685
+ <td><code>service[0].storymap:useCustomMarkers</code></td>
686
+ </tr>
687
+ <tr>
688
+ <td><code>zoom_distance</code></td>
689
+ <td><em>dropped</em> (viewer setting)</td>
690
+ </tr>
691
+ <tr>
692
+ <td><code>calculate_zoom</code></td>
693
+ <td><code>service[0].storymap:calculateZoom</code></td>
694
+ </tr>
695
+ <tr>
696
+ <td><code>less_bounce</code></td>
697
+ <td><code>service[0].storymap:lessBounce</code></td>
698
+ </tr>
699
+ <tr>
700
+ <td><code>line_follows_path</code></td>
701
+ <td><code>service[0].storymap:lineFollowsPath</code></td>
702
+ </tr>
703
+ <tr>
704
+ <td><code>show_lines</code></td>
705
+ <td><code>service[0].storymap:showLines</code></td>
706
+ </tr>
707
+ <tr>
708
+ <td><code>show_history_line</code></td>
709
+ <td><code>service[0].storymap:showHistoryLine</code></td>
710
+ </tr>
711
+ <tr>
712
+ <td><code>line_color</code></td>
713
+ <td><code>service[0].storymap:lineColor</code></td>
714
+ </tr>
715
+ <tr>
716
+ <td><code>line_color_inactive</code></td>
717
+ <td><code>service[0].storymap:lineColorInactive</code></td>
718
+ </tr>
719
+ <tr>
720
+ <td><code>line_weight</code></td>
721
+ <td><code>service[0].storymap:lineWeight</code></td>
722
+ </tr>
723
+ <tr>
724
+ <td><code>line_opacity</code></td>
725
+ <td><code>service[0].storymap:lineOpacity</code></td>
726
+ </tr>
727
+ <tr>
728
+ <td><code>line_dash</code></td>
729
+ <td><code>service[0].storymap:lineDash</code></td>
730
+ </tr>
731
+ <tr>
732
+ <td><code>line_join</code></td>
733
+ <td><code>service[0].storymap:lineJoin</code></td>
734
+ </tr>
735
+ <tr>
736
+ <td><code>iiif.url</code></td>
737
+ <td><code>service[0].storymap:iiifUrl</code> + canvas Image annotation <code>service[]</code></td>
738
+ </tr>
739
+ <tr>
740
+ <td><code>iiif.attribution</code></td>
741
+ <td><code>requiredStatement</code></td>
742
+ </tr>
743
+ <tr>
744
+ <td><code>zoomify</code></td>
745
+ <td><em>dropped</em> (zoomify is replaced by the IIIF reference image)</td>
746
+ </tr>
747
+ <tr>
748
+ <td><code>font_css</code></td>
749
+ <td><code>service[0].storymap:fontCss</code></td>
750
+ </tr>
751
+ <tr>
752
+ <td><code>call_to_action</code></td>
753
+ <td><code>service[0].storymap:callToAction</code></td>
754
+ </tr>
755
+ <tr>
756
+ <td><code>call_to_action_text</code></td>
757
+ <td><code>service[0].storymap:callToActionText</code></td>
758
+ </tr>
759
+ <tr>
760
+ <td><code>relative_date</code></td>
761
+ <td><em>dropped</em> (viewer setting)</td>
762
+ </tr>
763
+ <tr>
764
+ <td><code>start_at_slide</code></td>
765
+ <td><code>service[0].storymap:startAtSlide</code></td>
766
+ </tr>
767
+ <tr>
768
+ <td><em>(root) <code>width</code>, <code>height</code></em></td>
769
+ <td><em>dropped</em> (viewer embed size)</td>
770
+ </tr>
771
+ </tbody></table>
772
+ <table>
773
+ <thead>
774
+ <tr>
775
+ <th>Legacy field (slide)</th>
776
+ <th>IIIF path</th>
777
+ </tr>
778
+ </thead>
779
+ <tbody><tr>
780
+ <td><code>type: &quot;overview&quot;</code></td>
781
+ <td>Canvas <code>storymap:type: &quot;overview&quot;</code></td>
782
+ </tr>
783
+ <tr>
784
+ <td><code>date</code></td>
785
+ <td>Canvas <code>storymap:date</code></td>
786
+ </tr>
787
+ <tr>
788
+ <td><code>text.headline</code></td>
789
+ <td>Canvas <code>label</code> (language map)</td>
790
+ </tr>
791
+ <tr>
792
+ <td><code>text.text</code></td>
793
+ <td>Canvas <code>summary</code> (language map)</td>
794
+ </tr>
795
+ <tr>
796
+ <td><code>location.lat</code>, <code>location.lon</code></td>
797
+ <td>Canvas <code>navPlace</code> Feature <code>geometry.coordinates</code></td>
798
+ </tr>
799
+ <tr>
800
+ <td><code>location.zoom</code></td>
801
+ <td>Canvas <code>navPlace</code> Feature <code>properties.zoom</code></td>
802
+ </tr>
803
+ <tr>
804
+ <td><code>location.line</code></td>
805
+ <td>Canvas <code>navPlace</code> Feature <code>properties.line</code></td>
806
+ </tr>
807
+ <tr>
808
+ <td><code>location.name</code></td>
809
+ <td>Canvas <code>navPlace</code> Feature <code>properties.name</code></td>
810
+ </tr>
811
+ <tr>
812
+ <td><code>location.icon</code></td>
813
+ <td>Canvas <code>navPlace</code> Feature <code>properties.icon</code></td>
814
+ </tr>
815
+ <tr>
816
+ <td><code>location.iconSize</code></td>
817
+ <td>Canvas <code>navPlace</code> Feature <code>properties.iconSize</code></td>
818
+ </tr>
819
+ <tr>
820
+ <td><code>location.image</code></td>
821
+ <td>Canvas <code>navPlace</code> Feature <code>properties.image</code></td>
822
+ </tr>
823
+ <tr>
824
+ <td><code>location.use_custom_marker</code></td>
825
+ <td>Canvas <code>navPlace</code> Feature <code>properties.use_custom_marker</code></td>
826
+ </tr>
827
+ <tr>
828
+ <td><code>media.url</code> (image)</td>
829
+ <td>Annotation body <code>{type: &quot;Image&quot;, format: ...}</code></td>
830
+ </tr>
831
+ <tr>
832
+ <td><code>media.url</code> (video service)</td>
833
+ <td>Annotation body <code>{type: &quot;Video&quot;}</code></td>
834
+ </tr>
835
+ <tr>
836
+ <td><code>media.url</code> (audio service)</td>
837
+ <td>Annotation body <code>{type: &quot;Sound&quot;}</code></td>
838
+ </tr>
839
+ <tr>
840
+ <td><code>media.url</code> (web page)</td>
841
+ <td>Annotation body <code>{type: &quot;Text&quot;, format: &quot;text/html&quot;}</code></td>
842
+ </tr>
843
+ <tr>
844
+ <td><code>media.url</code> (absent / HTML)</td>
845
+ <td>Annotation body <code>{type: &quot;TextualBody&quot;, value: ...}</code></td>
846
+ </tr>
847
+ <tr>
848
+ <td><code>media.caption</code></td>
849
+ <td>Canvas <code>storymap:mediaCaption</code></td>
850
+ </tr>
851
+ <tr>
852
+ <td><code>media.credit</code></td>
853
+ <td>Canvas <code>storymap:mediaCredit</code></td>
854
+ </tr>
855
+ <tr>
856
+ <td><code>media.thumb</code></td>
857
+ <td><em>dropped</em> (thumbnails may be added via Canvas <code>thumbnail</code>)</td>
858
+ </tr>
859
+ <tr>
860
+ <td><code>background</code></td>
861
+ <td>Canvas <code>storymap:background</code> <code>{url, color}</code></td>
862
+ </tr>
863
+ <tr>
864
+ <td><code>uniqueid</code></td>
865
+ <td><em>dropped</em> (canvas <code>id</code>s are the canonical identifiers)</td>
866
+ </tr>
867
+ </tbody></table>
868
+ <h2>Conversion</h2>
869
+ <p><code>node scripts/convert-to-iiif.mjs</code> regenerates <code>public/examples-iiif/</code> from
870
+ <code>public/examples/</code>. Ids are deterministic:</p>
871
+ <ul>
872
+ <li>Manifest: <code>https://example.org/storymap/&lt;name&gt;</code></li>
873
+ <li>Canvas: <code>&lt;manifest-id&gt;/canvas/&lt;n&gt;</code> (1-based, slide order)</li>
874
+ <li>AnnotationPage: <code>&lt;canvas-id&gt;/annotationpage/1</code></li>
875
+ <li>Annotation: <code>&lt;canvas-id&gt;/annotation/1</code></li>
876
+ <li>FeatureCollection / Feature: <code>&lt;canvas-id&gt;/navplace[.../feature/1]</code></li>
877
+ </ul>
878
+
879
+ </main>
880
+
881
+ <footer class="footer-knightlab">
882
+ <div class="footer-grid">
883
+ <div>
884
+ <div class="footer-brand">StoryMap <span>JS</span></div>
885
+ <ul class="list-social">
886
+ <li>
887
+ <a href="https://github.com/cmahnke/StoryMapJS" title="StoryMapJS fork on GitHub"
888
+ >GitHub</a
889
+ >
890
+ </li>
891
+ <li>
892
+ <a href="https://github.com/NUKnightLab/StoryMapJS" title="Upstream Knight Lab repository"
893
+ >Upstream</a
894
+ >
895
+ </li>
896
+ </ul>
897
+ </div>
898
+ <div class="footer-description">
899
+ <p>
900
+ A TypeScript rewrite of
901
+ <a href="https://github.com/NUKnightLab/StoryMapJS">NUKnightLab/StoryMapJS</a>,
902
+ the original tool by
903
+ <a href="https://knightlab.northwestern.edu/">Northwestern University Knight Lab</a>.
904
+ </p>
905
+ <span class="copyright">
906
+ Released under the <a href="https://opensource.org/license/MPL-2-0">MPL-2.0</a> license.
907
+ </span>
908
+ </div>
909
+ </div>
910
+ </footer>
911
+ </body>
912
+ </html>