pageflow 17.1.0 → 17.2.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 (302) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +319 -345
  3. data/README.md +3 -4
  4. data/admins/pageflow/accounts.rb +6 -6
  5. data/admins/pageflow/entry.rb +10 -8
  6. data/admins/pageflow/membership.rb +11 -11
  7. data/admins/pageflow/translations.rb +5 -5
  8. data/app/assets/images/pageflow/admin/icons/comment.svg +1 -0
  9. data/app/assets/javascripts/pageflow/dist/ui.js +1350 -630
  10. data/app/assets/javascripts/pageflow/editor/vendor.js +0 -1
  11. data/app/assets/javascripts/pageflow/ui.js +0 -1
  12. data/app/assets/stylesheets/pageflow/admin/entry_comments_indicator.scss +45 -0
  13. data/app/assets/stylesheets/pageflow/admin/permalink_input.scss +8 -1
  14. data/app/assets/stylesheets/pageflow/admin.scss +1 -0
  15. data/app/assets/stylesheets/pageflow/animations/spin.scss +9 -0
  16. data/app/assets/stylesheets/pageflow/animations.scss +1 -0
  17. data/app/assets/stylesheets/pageflow/editor/background_positioning.scss +21 -5
  18. data/app/assets/stylesheets/pageflow/editor/base.scss +9 -1
  19. data/app/assets/stylesheets/pageflow/editor/drop_down_button.scss +13 -1
  20. data/app/assets/stylesheets/pageflow/editor/edit_configuration_view.scss +5 -0
  21. data/app/assets/stylesheets/pageflow/editor/file_folders.scss +127 -0
  22. data/app/assets/stylesheets/pageflow/editor/file_meta_data.scss +0 -1
  23. data/app/assets/stylesheets/pageflow/editor/file_meta_data_overlay.scss +45 -0
  24. data/app/assets/stylesheets/pageflow/editor/file_preview.scss +138 -0
  25. data/app/assets/stylesheets/pageflow/editor/file_references.scss +68 -0
  26. data/app/assets/stylesheets/pageflow/editor/file_settings_dialog.scss +1 -1
  27. data/app/assets/stylesheets/pageflow/editor/file_stage_icons.scss +17 -0
  28. data/app/assets/stylesheets/pageflow/editor/file_stages.scss +25 -32
  29. data/app/assets/stylesheets/pageflow/editor/file_thumbnails.scss +31 -48
  30. data/app/assets/stylesheets/pageflow/editor/file_type_pills.scss +73 -0
  31. data/app/assets/stylesheets/pageflow/editor/files.scss +230 -50
  32. data/app/assets/stylesheets/pageflow/editor/filtered_files.scss +142 -14
  33. data/app/assets/stylesheets/pageflow/editor/folder_breadcrumb.scss +40 -0
  34. data/app/assets/stylesheets/pageflow/editor/info_box.scss +12 -0
  35. data/app/assets/stylesheets/pageflow/editor/inputs/edit_defaults_button.scss +15 -0
  36. data/app/assets/stylesheets/pageflow/editor/inputs.scss +1 -0
  37. data/app/assets/stylesheets/pageflow/editor/list.scss +88 -38
  38. data/app/assets/stylesheets/pageflow/editor/manage_files.scss +9 -0
  39. data/app/assets/stylesheets/pageflow/editor/menu.scss +14 -0
  40. data/app/assets/stylesheets/pageflow/editor/move_to_folder_dialog.scss +83 -0
  41. data/app/assets/stylesheets/pageflow/mixins/pageflow.scss +9 -5
  42. data/app/assets/stylesheets/pageflow/ui/color_picker.scss +230 -0
  43. data/app/assets/stylesheets/pageflow/ui/forms.scss +34 -4
  44. data/app/assets/stylesheets/pageflow/ui/functions.scss +12 -2
  45. data/app/assets/stylesheets/pageflow/ui/input/color_input.scss +9 -16
  46. data/app/assets/stylesheets/pageflow/ui/input/text_area_input.scss +15 -0
  47. data/app/assets/stylesheets/pageflow/ui/overrides.scss +8 -0
  48. data/app/assets/stylesheets/pageflow/ui/properties.scss +29 -0
  49. data/app/assets/stylesheets/pageflow/ui/tabs_view.scss +8 -3
  50. data/app/assets/stylesheets/pageflow/ui.scss +4 -2
  51. data/app/controllers/pageflow/editor/entries_controller.rb +1 -0
  52. data/app/controllers/pageflow/editor/file_folders_controller.rb +80 -0
  53. data/app/controllers/pageflow/editor/file_import_controller.rb +1 -0
  54. data/app/controllers/pageflow/editor/files_controller.rb +15 -6
  55. data/app/controllers/pageflow/editor/oembeds_controller.rb +21 -0
  56. data/app/controllers/pageflow/entries_controller.rb +17 -13
  57. data/app/controllers/pageflow/review/comment_thread_reads_controller.rb +30 -0
  58. data/app/controllers/pageflow/review/comment_threads_controller.rb +60 -0
  59. data/app/controllers/pageflow/review/comments_controller.rb +53 -0
  60. data/app/controllers/pageflow/revisions_controller.rb +4 -1
  61. data/app/helpers/pageflow/admin/entries_helper.rb +40 -0
  62. data/app/helpers/pageflow/admin/widgets_helper.rb +2 -2
  63. data/app/helpers/pageflow/common_entry_seed_helper.rb +5 -3
  64. data/app/helpers/pageflow/editor/config_helper.rb +3 -1
  65. data/app/helpers/pageflow/entries_helper.rb +24 -42
  66. data/app/helpers/pageflow/entry_json_seed_helper.rb +4 -4
  67. data/app/helpers/pageflow/public_i18n_helper.rb +9 -8
  68. data/app/helpers/pageflow/structured_data_helper.rb +4 -1
  69. data/app/helpers/pageflow/themes_helper.rb +1 -3
  70. data/app/helpers/pageflow/widgets_helper.rb +2 -1
  71. data/app/inputs/pageflow_permalink_input.rb +6 -2
  72. data/app/models/concerns/pageflow/auto_generated_perma_id.rb +11 -4
  73. data/app/models/concerns/pageflow/reusable_file.rb +1 -1
  74. data/app/models/concerns/pageflow/serialization_blacklist.rb +2 -4
  75. data/app/models/concerns/pageflow/translated_attributes.rb +101 -0
  76. data/app/models/concerns/pageflow/uploadable_file.rb +1 -1
  77. data/app/models/pageflow/comment.rb +30 -0
  78. data/app/models/pageflow/comment_thread.rb +65 -0
  79. data/app/models/pageflow/comment_thread_read.rb +22 -0
  80. data/app/models/pageflow/customized_theme.rb +3 -2
  81. data/app/models/pageflow/draft_entry.rb +20 -8
  82. data/app/models/pageflow/entry.rb +2 -0
  83. data/app/models/pageflow/entry_at_revision.rb +9 -1
  84. data/app/models/pageflow/entry_comment_summary.rb +114 -0
  85. data/app/models/pageflow/file_folder.rb +74 -0
  86. data/app/models/pageflow/file_reuse.rb +3 -2
  87. data/app/models/pageflow/file_usage.rb +8 -0
  88. data/app/models/pageflow/image_file.rb +24 -20
  89. data/app/models/pageflow/image_file_url_templates.rb +3 -3
  90. data/app/models/pageflow/legal_info.rb +38 -0
  91. data/app/models/pageflow/nested_revision_component_copy.rb +1 -1
  92. data/app/models/pageflow/permalink.rb +1 -0
  93. data/app/models/pageflow/revision.rb +6 -2
  94. data/app/models/pageflow/site.rb +10 -0
  95. data/app/models/pageflow/used_file.rb +8 -2
  96. data/app/models/pageflow/widget.rb +2 -2
  97. data/app/views/pageflow/audio_files/_audio_file.json.jbuilder +0 -1
  98. data/app/views/pageflow/editor/config/_seeds.json.jbuilder +4 -2
  99. data/app/views/pageflow/editor/entries/_entry.json.jbuilder +2 -1
  100. data/app/views/pageflow/editor/entries/seed.json.erb +1 -0
  101. data/app/views/pageflow/editor/file_folders/_file_folder.json.jbuilder +5 -0
  102. data/app/views/pageflow/editor/file_folders/create.json.jbuilder +1 -0
  103. data/app/views/pageflow/editor/file_folders/index.json.jbuilder +3 -0
  104. data/app/views/pageflow/editor/files/_file.json.jbuilder +2 -1
  105. data/app/views/pageflow/editor/image_files/_image_file.json.jbuilder +3 -0
  106. data/app/views/pageflow/editor/video_files/_video_file.json.jbuilder +3 -0
  107. data/app/views/pageflow/files/_file.json.jbuilder +2 -0
  108. data/app/views/pageflow/image_files/_image_file.json.jbuilder +0 -1
  109. data/app/views/pageflow/review/comment_threads/_comment_thread.json.jbuilder +20 -0
  110. data/app/views/pageflow/review/comment_threads/create.json.jbuilder +2 -0
  111. data/app/views/pageflow/review/comment_threads/index.json.jbuilder +13 -0
  112. data/app/views/pageflow/review/comments/_comment.json.jbuilder +13 -0
  113. data/app/views/pageflow/review/comments/create.json.jbuilder +1 -0
  114. data/app/views/pageflow/structured_data/_entry.json.jbuilder +2 -3
  115. data/app/views/pageflow/video_files/_video_file.json.jbuilder +0 -1
  116. data/config/locales/de.yml +152 -14
  117. data/config/locales/en.yml +150 -14
  118. data/config/routes.rb +14 -0
  119. data/db/migrate/20140418225525_setup_schema.rb +2 -2
  120. data/db/migrate/20251015000000_add_structured_data_type_name_to_revisions.rb +5 -0
  121. data/db/migrate/20251029142849_convert_legacy_social_embeds_to_unified_social_embed.rb +38 -0
  122. data/db/migrate/20251119083347_fix_main_storyline_positions.rb +16 -0
  123. data/db/migrate/20251119083348_ensure_scrolled_entries_have_excursion_storyline.rb +15 -0
  124. data/db/migrate/20260303000000_add_layout_version_to_revisions.rb +6 -0
  125. data/db/migrate/20260323000000_create_comment_threads_and_comments.rb +30 -0
  126. data/db/migrate/20260414000000_add_subject_range_to_comment_threads.rb +5 -0
  127. data/db/migrate/20260415000000_add_section_perma_id_to_comment_threads.rb +5 -0
  128. data/db/migrate/20260727000000_add_quote_to_comments.rb +5 -0
  129. data/db/migrate/20260728000000_create_file_folders.rb +17 -0
  130. data/db/migrate/20260805000000_add_attribute_translations_to_sites.rb +5 -0
  131. data/db/migrate/20260806000000_add_edited_at_to_comments.rb +5 -0
  132. data/db/migrate/20260810000000_create_pageflow_scrolled_lottie_files.rb +24 -0
  133. data/db/migrate/20260817000000_create_comment_thread_reads.rb +16 -0
  134. data/db/migrate/20260819000000_add_unread_comments_since_at_to_users.rb +18 -0
  135. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/editor.js +8665 -3890
  136. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/frontend.js +979 -3571
  137. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-client.js +20199 -28120
  138. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-server.js +18652 -26584
  139. data/entry_types/scrolled/app/assets/stylesheets/pageflow_scrolled/ui.scss +2 -0
  140. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/content_elements_controller.rb +33 -3
  141. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/sections_controller.rb +2 -3
  142. data/entry_types/scrolled/app/controllers/pageflow_scrolled/entries_controller.rb +21 -1
  143. data/entry_types/scrolled/app/helpers/pageflow_scrolled/cache_helper.rb +3 -3
  144. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/entry_json_seed_helper.rb +7 -5
  145. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb +5 -2
  146. data/entry_types/scrolled/app/helpers/pageflow_scrolled/entry_json_seed_helper.rb +13 -5
  147. data/entry_types/scrolled/app/helpers/pageflow_scrolled/i18n_helper.rb +28 -13
  148. data/entry_types/scrolled/app/helpers/pageflow_scrolled/packs_helper.rb +26 -11
  149. data/entry_types/scrolled/app/helpers/pageflow_scrolled/react_server_side_rendering_helper.rb +2 -2
  150. data/entry_types/scrolled/app/helpers/pageflow_scrolled/sprockets_helper.rb +16 -0
  151. data/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb +174 -3
  152. data/entry_types/scrolled/app/models/pageflow_scrolled/content_element.rb +49 -7
  153. data/entry_types/scrolled/app/models/pageflow_scrolled/lottie_file.rb +6 -0
  154. data/entry_types/scrolled/app/models/pageflow_scrolled/lottie_file_url_templates.rb +16 -0
  155. data/entry_types/scrolled/app/models/pageflow_scrolled/storyline.rb +1 -0
  156. data/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb +13 -12
  157. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry.json.jbuilder +30 -10
  158. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_theme.json.jbuilder +9 -0
  159. data/entry_types/scrolled/app/views/pageflow_scrolled/favicons/_entry.html.erb +1 -1
  160. data/entry_types/scrolled/config/configuration_schemas/pageflow-scrolled.json +414 -0
  161. data/entry_types/scrolled/config/locales/de.yml +512 -65
  162. data/entry_types/scrolled/config/locales/en.yml +518 -52
  163. data/entry_types/scrolled/lib/pageflow_scrolled/additional_seed_data.rb +2 -2
  164. data/entry_types/scrolled/lib/pageflow_scrolled/configuration.rb +51 -6
  165. data/entry_types/scrolled/lib/pageflow_scrolled/configuration_schemas.rb +91 -0
  166. data/entry_types/scrolled/lib/pageflow_scrolled/engine.rb +2 -1
  167. data/entry_types/scrolled/lib/pageflow_scrolled/entry_file_reference_locations.rb +71 -0
  168. data/entry_types/scrolled/lib/pageflow_scrolled/entry_structured_data_types/faq_page.rb +58 -0
  169. data/entry_types/scrolled/lib/pageflow_scrolled/file_reference_locations.rb +69 -0
  170. data/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb +205 -22
  171. data/entry_types/scrolled/lib/pageflow_scrolled/react_widget_type.rb +2 -4
  172. data/entry_types/scrolled/lib/pageflow_scrolled/seeds.rb +56 -36
  173. data/entry_types/scrolled/lib/pageflow_scrolled/theme_options_default_scale.rb +35 -0
  174. data/entry_types/scrolled/lib/pageflow_scrolled.rb +13 -0
  175. data/entry_types/scrolled/lib/tasks/pageflow_scrolled/storybook.rake +19 -1
  176. data/entry_types/scrolled/package/config/configurationSchemas.js +70 -0
  177. data/entry_types/scrolled/package/config/rollup/configurationSchemas.js +19 -0
  178. data/entry_types/scrolled/package/config/webpack.js +72 -0
  179. data/entry_types/scrolled/package/contentElements/hotspots-frontend.css +1 -1
  180. data/entry_types/scrolled/package/contentElements/hotspots-frontend.js +1181 -915
  181. data/entry_types/scrolled/package/contentElements/inlineBeforeAfter-frontend.css +1 -0
  182. data/entry_types/scrolled/package/contentElements/inlineBeforeAfter-frontend.js +219 -0
  183. data/entry_types/scrolled/package/contentElements/lottieAnimation-frontend.css +1 -0
  184. data/entry_types/scrolled/package/contentElements/lottieAnimation-frontend.js +244 -0
  185. data/entry_types/scrolled/package/contentElements/socialEmbed-frontend.css +1 -0
  186. data/entry_types/scrolled/package/contentElements/socialEmbed-frontend.js +823 -0
  187. data/entry_types/scrolled/package/contentElements/tikTokEmbed-frontend.js +71 -21
  188. data/entry_types/scrolled/package/contentElements/twitterEmbed-frontend.css +1 -0
  189. data/entry_types/scrolled/package/contentElements/twitterEmbed-frontend.js +277 -0
  190. data/entry_types/scrolled/package/contentElements/videoEmbed-frontend.css +1 -0
  191. data/entry_types/scrolled/package/contentElements/videoEmbed-frontend.js +244 -0
  192. data/entry_types/scrolled/package/contentElements-editor.js +1915 -1097
  193. data/entry_types/scrolled/package/contentElements-frontend.css +1 -1
  194. data/entry_types/scrolled/package/contentElements-frontend.js +3093 -1679
  195. data/entry_types/scrolled/package/editor.css +1 -0
  196. data/entry_types/scrolled/package/editor.js +8667 -4077
  197. data/entry_types/scrolled/package/entryState.js +1600 -0
  198. data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-20c600de.js +1979 -0
  199. data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-58189220.js +2538 -0
  200. data/entry_types/scrolled/package/frontend/{PhonePlatformContext-9f76033e.js → PhonePlatformContext-035a99fa.js} +7 -12
  201. data/entry_types/scrolled/package/frontend/PhonePlatformContext-9da43797.js +33 -0
  202. data/entry_types/scrolled/package/frontend/Placeholder.module-bf0966b4.js +5267 -0
  203. data/entry_types/scrolled/package/frontend/Placeholder.module-d22a9335.js +4180 -0
  204. data/entry_types/scrolled/package/frontend/ThemeIcon-ab834849.js +754 -0
  205. data/entry_types/scrolled/package/frontend/ThemeIcon-f6cb3a8f.js +773 -0
  206. data/entry_types/scrolled/package/frontend/{ToggleFullscreenCornerButton-788e9cdb.js → ToggleFullscreenCornerButton-30fd1124.js} +6 -6
  207. data/entry_types/scrolled/package/frontend/ToggleFullscreenCornerButton-61c25224.js +72 -0
  208. data/entry_types/scrolled/package/frontend/Viewer-1074fd59.js +147 -0
  209. data/entry_types/scrolled/package/frontend/Viewer-1482ca34.js +480 -0
  210. data/entry_types/scrolled/package/frontend/Viewer-70504231.js +210 -0
  211. data/entry_types/scrolled/package/frontend/{Viewer-0345ce57.js → Viewer-cc8d4072.js} +84 -92
  212. data/entry_types/scrolled/package/frontend/Wavesurfer-656e3c36.js +302 -0
  213. data/entry_types/scrolled/package/frontend/Wavesurfer-b753b838.js +385 -0
  214. data/entry_types/scrolled/package/frontend/commenting.css +1 -0
  215. data/entry_types/scrolled/package/frontend/extensions-167ae143.js +1455 -0
  216. data/entry_types/scrolled/package/frontend/extensions-2318f92b.js +5918 -0
  217. data/entry_types/scrolled/package/frontend/extensions-a461fd13.js +4890 -0
  218. data/entry_types/scrolled/package/frontend/extensions-c98269fd.js +1982 -0
  219. data/entry_types/scrolled/package/frontend/i18n-493cd2a6.js +93 -0
  220. data/entry_types/scrolled/package/frontend/i18n-e06cac14.js +100 -0
  221. data/entry_types/scrolled/package/frontend/{index-eb670c2f.js → index-2e5546f7.js} +36 -44
  222. data/entry_types/scrolled/package/frontend/index-de2b418d.js +130 -0
  223. data/entry_types/scrolled/package/frontend/index.css +1 -1
  224. data/entry_types/scrolled/package/frontend/index.js +1870 -875
  225. data/entry_types/scrolled/package/frontend/inlineEditing.css +1 -0
  226. data/entry_types/scrolled/package/frontend/useContentElementEditorState-a084912e.js +25 -0
  227. data/entry_types/scrolled/package/frontend/useDelayedBoolean-a387d85b.js +24 -0
  228. data/entry_types/scrolled/package/frontend/{usePhonePlatform-c2ba875d.js → usePhonePlatform-4ecb96d4.js} +1 -1
  229. data/entry_types/scrolled/package/frontend/usePhonePlatform-ce9ff08d.js +8 -0
  230. data/entry_types/scrolled/package/frontend-server.js +20 -209
  231. data/entry_types/scrolled/package/package.json +5 -3
  232. data/entry_types/scrolled/package/review.css +1 -0
  233. data/entry_types/scrolled/package/review.js +3306 -0
  234. data/entry_types/scrolled/package/testHelpers.js +836 -359
  235. data/entry_types/scrolled/package/widgets/consentBar.css +1 -1
  236. data/entry_types/scrolled/package/widgets/consentBar.js +269 -290
  237. data/entry_types/scrolled/package/widgets/defaultNavigation.css +2 -2
  238. data/entry_types/scrolled/package/widgets/defaultNavigation.js +911 -352
  239. data/entry_types/scrolled/package/widgets/excursionSheet.css +1 -1
  240. data/entry_types/scrolled/package/widgets/excursionSheet.js +87 -124
  241. data/entry_types/scrolled/package/widgets/iconInlineFileRights.css +1 -1
  242. data/entry_types/scrolled/package/widgets/iconInlineFileRights.js +62 -29
  243. data/entry_types/scrolled/package/widgets/iconScrollIndicator.js +32 -13
  244. data/entry_types/scrolled/package/widgets/mainStorylineSheet.css +1 -1
  245. data/entry_types/scrolled/package/widgets/mainStorylineSheet.js +56 -100
  246. data/entry_types/scrolled/package/widgets/textInlineFileRights.css +1 -1
  247. data/entry_types/scrolled/package/widgets/textInlineFileRights.js +33 -28
  248. data/entry_types/scrolled/package/widgets-server.js +1 -0
  249. data/entry_types/scrolled/spec/factories/lottie_files.rb +29 -0
  250. data/entry_types/scrolled/spec/fixtures/animation.lottie +0 -0
  251. data/entry_types/scrolled/spec/fixtures/font.woff +0 -0
  252. data/entry_types/scrolled/spec/fixtures/font.woff2 +0 -0
  253. data/lib/generators/pageflow/resque/resque_generator.rb +0 -2
  254. data/lib/pageflow/configuration.rb +49 -7
  255. data/lib/pageflow/deprecation.rb +19 -0
  256. data/lib/pageflow/engine.rb +1 -1
  257. data/lib/pageflow/entries_controller_env_helper.rb +32 -2
  258. data/lib/pageflow/entry_export_import/entry_serialization.rb +4 -4
  259. data/lib/pageflow/entry_export_import/page_type_versions.rb +2 -2
  260. data/lib/pageflow/entry_export_import/revision_serialization/import.rb +10 -0
  261. data/lib/pageflow/entry_export_import/revision_serialization.rb +3 -0
  262. data/lib/pageflow/entry_structured_data_types.rb +43 -0
  263. data/lib/pageflow/entry_type_configuration.rb +1 -0
  264. data/lib/pageflow/file_type.rb +2 -2
  265. data/lib/pageflow/file_types.rb +1 -1
  266. data/lib/pageflow/oembed_providers.rb +42 -0
  267. data/lib/pageflow/primary_domain_entry_redirect.rb +6 -0
  268. data/lib/pageflow/rails_version.rb +13 -2
  269. data/lib/pageflow/themes.rb +41 -0
  270. data/lib/pageflow/user_mixin.rb +12 -0
  271. data/lib/pageflow/version.rb +1 -1
  272. data/lib/pageflow.rb +1 -0
  273. data/package/config/eslint-rules/documented-in-toc.js +125 -0
  274. data/package/config/jest/index.js +0 -1
  275. data/package/config/webpack.js +0 -1
  276. data/package/config/webpack5.js +0 -1
  277. data/package/editor.js +4378 -1897
  278. data/package/frontend.js +647 -886
  279. data/package/package.json +2 -1
  280. data/package/review.js +384 -0
  281. data/package/testHelpers.js +248 -188
  282. data/package/ui.js +1346 -630
  283. data/package/vendor/stubs/wysihtml5.js +2 -0
  284. data/spec/factories/comment_thread_reads.rb +10 -0
  285. data/spec/factories/comment_threads.rb +10 -0
  286. data/spec/factories/comments.rb +9 -0
  287. data/spec/factories/file_folders.rb +8 -0
  288. data/spec/factories/published_entries.rb +2 -0
  289. metadata +188 -67
  290. data/app/assets/stylesheets/pageflow/editor/select_button.scss +0 -51
  291. data/entry_types/scrolled/app/helpers/pageflow_scrolled/generated_media_queries_helper.rb +0 -55
  292. data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-51914be7.js +0 -5439
  293. data/entry_types/scrolled/package/frontend/ThemeIcon-81f2f066.js +0 -1932
  294. data/entry_types/scrolled/package/frontend/Viewer-cdc549cc.js +0 -147
  295. data/entry_types/scrolled/package/frontend/Wavesurfer-1cdc3925.js +0 -313
  296. data/entry_types/scrolled/package/frontend/components-96660ffd.js +0 -3803
  297. data/entry_types/scrolled/package/frontend/inherits-539844a6.js +0 -99
  298. data/entry_types/scrolled/package/frontend/useContentElementEditorState-77fe6c79.js +0 -51
  299. data/entry_types/scrolled/package/widgets/excursionDialog.css +0 -1
  300. data/entry_types/scrolled/package/widgets/excursionDialog.js +0 -109
  301. data/lib/generators/pageflow/resque/templates/resque_enqueue_after_commit_patch.rb +0 -25
  302. data/package/vendor/jquery.minicolors.js +0 -1108
@@ -0,0 +1,4180 @@
1
+ import { documentHiddenState, events, browser, PlayerSourceIDMap, media, MultiPlayer, settings, features, consent } from 'pageflow/frontend';
2
+ import React, { createContext, useRef, useEffect, useMemo, useContext, useCallback, useReducer, useState, useLayoutEffect } from 'react';
3
+ import classNames from 'classnames';
4
+ import { t as createScrollPositionLifecycleProvider, v as createScrollPositionLifecycleHook, m as useIsStaticPreview, e as extensible, d as api, x as useMediaQuery, y as TrimDefaultMarginTop, w as widths, B as BackgroundColorProvider, z as ContentElement, A as useScrollTarget, D as Layout, g as useContentElementAttributes, G as ExtensionsProvider, S as ScrollTargetEmitterProvider, H as ActiveExcursionProvider, I as StaticPreview, J as camelize, T as Text, K as renderLink, N as renderLeaf } from './FloatingPortalRootProvider-20c600de.js';
5
+ import BackboneEvents from 'backbone-events-standalone';
6
+ import { useEntryMetadata, useNestedFiles, useWidget, useContentElement, useFileWithInlineRights, useSectionForegroundContentElements, useSectionsWithChapter, useLegalInfo, useContentElementConsentVendor, useTheme, EntryStateProvider, useEntryStateDispatch, useSection } from 'pageflow-scrolled/entryState';
7
+ import I18n from 'i18n-js';
8
+ import { u as useI18n, L as LocaleProvider } from './i18n-493cd2a6.js';
9
+ import stripTags from 'striptags';
10
+ import Measure from 'react-measure';
11
+ import { u as useBrowserFeature, P as PhonePlatformContext, B as BrowserFeaturesProvider } from './PhonePlatformContext-035a99fa.js';
12
+ import { u as useContentElementEditorState } from './useContentElementEditorState-a084912e.js';
13
+ import { T as ThemeIcon } from './ThemeIcon-ab834849.js';
14
+
15
+ const SectionLifecycleContext = createContext();
16
+ const SectionLifecycleProvider = createScrollPositionLifecycleProvider(SectionLifecycleContext);
17
+ const useSectionLifecycle = createScrollPositionLifecycleHook(SectionLifecycleContext);
18
+
19
+ class Atmo {
20
+ constructor({
21
+ atmoSourceId,
22
+ multiPlayer,
23
+ backgroundMedia
24
+ }) {
25
+ this.multiPlayer = multiPlayer;
26
+ this.atmoSourceId = atmoSourceId;
27
+ this.backgroundMedia = backgroundMedia;
28
+ this.backgroundMedia.on('change:muted', () => {
29
+ this.update();
30
+ });
31
+ documentHiddenState(hiddenState => {
32
+ if (hiddenState === 'hidden') {
33
+ this.multiPlayer.fadeOutIfPlaying();
34
+ } else {
35
+ this.update();
36
+ }
37
+ });
38
+ this.listenTo(this.multiPlayer, 'playfailed', () => {
39
+ backgroundMedia.mute(true);
40
+ });
41
+ }
42
+ disable() {
43
+ this.disabled = true;
44
+ this.multiPlayer.fadeOutAndPause();
45
+ events.trigger('atmo:disabled');
46
+ }
47
+ enable() {
48
+ this.disabled = false;
49
+ this.update();
50
+ events.trigger('atmo:enabled');
51
+ }
52
+ pause() {
53
+ if (browser.has('volume control support')) {
54
+ return this.multiPlayer.fadeOutAndPause();
55
+ } else {
56
+ this.multiPlayer.pause();
57
+ }
58
+ }
59
+ turnDown() {
60
+ if (browser.has('volume control support')) {
61
+ return this.multiPlayer.changeVolumeFactor(0.2);
62
+ } else {
63
+ this.multiPlayer.pause();
64
+ }
65
+ }
66
+ resume() {
67
+ if (this.multiPlayer.paused()) {
68
+ if (this.disabled || this.backgroundMedia.muted) {
69
+ return Promise.resolve();
70
+ } else {
71
+ return this.multiPlayer.resumeAndFadeIn();
72
+ }
73
+ } else {
74
+ return this.multiPlayer.changeVolumeFactor(1);
75
+ }
76
+ }
77
+ update() {
78
+ if (!this.disabled) {
79
+ if (this.backgroundMedia.muted) {
80
+ this.multiPlayer.fadeOutAndPause();
81
+ } else {
82
+ this.multiPlayer.fadeTo(this.atmoSourceId);
83
+ }
84
+ }
85
+ }
86
+ createMediaPlayerHooks(atmoDuringPlayback) {
87
+ var atmo = this;
88
+ return {
89
+ before: function () {
90
+ if (atmoDuringPlayback === 'mute') {
91
+ atmo.pause();
92
+ } else if (atmoDuringPlayback === 'turnDown') {
93
+ atmo.turnDown();
94
+ }
95
+ },
96
+ after: function () {
97
+ atmo.resume();
98
+ }
99
+ };
100
+ }
101
+ }
102
+ Object.assign(Atmo.prototype, BackboneEvents);
103
+
104
+ function getContextValue(updateAtmo, createMediaPlayerHooks) {
105
+ let empty = () => {};
106
+ return {
107
+ updateAtmo: updateAtmo || empty,
108
+ createMediaPlayerHooks: createMediaPlayerHooks || empty
109
+ };
110
+ }
111
+ const AtmoContext = createContext(getContextValue());
112
+ function AtmoProvider({
113
+ children
114
+ }) {
115
+ let atmoConfig = useRef({});
116
+ useEffect(() => {
117
+ let currentAtmo = atmoConfig.current;
118
+ currentAtmo.pool = PlayerSourceIDMap(media, {
119
+ playerOptions: {
120
+ tagName: 'audio',
121
+ loop: true
122
+ }
123
+ });
124
+ currentAtmo.multiPlayer = new MultiPlayer(currentAtmo.pool, {
125
+ fadeDuration: 500,
126
+ crossFade: true,
127
+ playFromBeginning: false,
128
+ rewindOnChange: true
129
+ });
130
+ currentAtmo.atmo = new Atmo({
131
+ multiPlayer: currentAtmo.multiPlayer,
132
+ backgroundMedia: media
133
+ });
134
+ }, []);
135
+ let updateAtmo = function ({
136
+ audioFilePermaId,
137
+ sources
138
+ }) {
139
+ let currentAtmo = atmoConfig.current;
140
+ if (currentAtmo.atmo) {
141
+ currentAtmo.pool.mapSources(audioFilePermaId, sources);
142
+ currentAtmo.atmo.atmoSourceId = audioFilePermaId;
143
+ currentAtmo.atmo.update();
144
+ }
145
+ };
146
+ let createMediaPlayerHooks = function (options) {
147
+ if (atmoConfig.current.atmo) {
148
+ return atmoConfig.current.atmo.createMediaPlayerHooks(options);
149
+ }
150
+ };
151
+ let contextValue = useMemo(() => {
152
+ return getContextValue(updateAtmo, createMediaPlayerHooks);
153
+ }, []);
154
+ return /*#__PURE__*/React.createElement(AtmoContext.Provider, {
155
+ value: contextValue
156
+ }, children);
157
+ }
158
+ function useAtmo() {
159
+ return useContext(AtmoContext);
160
+ }
161
+
162
+ function PlayerContainer({
163
+ filePermaId,
164
+ sources,
165
+ textTrackSources,
166
+ type,
167
+ playsInline,
168
+ loop,
169
+ controls,
170
+ altText,
171
+ mediaEventsContextData,
172
+ atmoDuringPlayback,
173
+ onSetup
174
+ }) {
175
+ const playerWrapperRef = useRef(null);
176
+ let atmo = useAtmo();
177
+ useEffect(() => {
178
+ let playerWrapper = playerWrapperRef.current;
179
+ if (sources) {
180
+ let disposeHandler;
181
+ let player = media.getPlayer(sources, {
182
+ textTrackSources,
183
+ filePermaId,
184
+ tagName: type,
185
+ playsInline: playsInline,
186
+ loop: loop,
187
+ controls: controls,
188
+ hooks: atmoDuringPlayback ? atmo.createMediaPlayerHooks(atmoDuringPlayback) : {},
189
+ //create hooks only for inline media players
190
+ mediaEventsContextData,
191
+ altText,
192
+ onRelease() {
193
+ playerWrapper.removeChild(player.el());
194
+ player = null;
195
+ if (disposeHandler) {
196
+ disposeHandler();
197
+ }
198
+ }
199
+ });
200
+ playerWrapper.appendChild(player.el());
201
+ if (onSetup) {
202
+ disposeHandler = onSetup(player);
203
+ }
204
+ return () => {
205
+ // onRelease might already have been called by the pool when
206
+ // it needed to re-use a player.
207
+ if (player) {
208
+ media.releasePlayer(player);
209
+ }
210
+ };
211
+ }
212
+ });
213
+ return /*#__PURE__*/React.createElement("div", {
214
+ ref: playerWrapperRef
215
+ });
216
+ }
217
+ PlayerContainer.defaultProps = {
218
+ textTrackSources: []
219
+ };
220
+
221
+ // This function assumes that that the parameters are arrays of
222
+ // objects containing only skalar values. It is not a full deep
223
+ // equality check, but suffices for the use case.
224
+ function deepEqual(a, b) {
225
+ if (a.length !== b.length) {
226
+ return false;
227
+ }
228
+ for (let i = 0; i < a.length; i++) {
229
+ let aItem = a[i];
230
+ let bItem = b[i];
231
+ if (Object.keys(aItem).length !== Object.keys(bItem).length) {
232
+ return false;
233
+ }
234
+ for (let key in aItem) {
235
+ if (aItem[key] !== bItem[key]) {
236
+ return false;
237
+ }
238
+ }
239
+ }
240
+ return true;
241
+ }
242
+ function areEqual(prevProps, nextProps) {
243
+ return prevProps.type === nextProps.type && prevProps.playsInline === nextProps.playsInline && prevProps.loop === nextProps.loop && prevProps.controls === nextProps.controls && prevProps.altText === nextProps.altText && prevProps.atmoDuringPlayback === nextProps.atmoDuringPlayback && deepEqual(prevProps.sources, nextProps.sources) && deepEqual(prevProps.textTrackSources, nextProps.textTrackSources);
244
+ }
245
+ var PlayerContainer$1 = React.memo(PlayerContainer, areEqual);
246
+
247
+ function watchPlayer(player, actions) {
248
+ player.on('loadedmetadata', () => actions.metaDataLoaded(player.currentTime(), player.duration()));
249
+ player.on('loadeddata', () => actions.dataLoaded());
250
+ player.on('progress', () => actions.progress(player.bufferedEnd()));
251
+ player.on('play', actions.playing);
252
+ player.on('playfailed', actions.playFailed);
253
+ player.on('pause', actions.paused);
254
+ player.on('waiting', actions.waiting);
255
+ player.on('seeking', actions.seeking);
256
+ player.on('seeked', actions.seeked);
257
+ player.on('bufferunderrun', actions.bufferUnderrun);
258
+ player.on('bufferunderruncontinue', actions.bufferUnderrunContinue);
259
+ player.on('timeupdate', handleTimeUpdate);
260
+ player.on('ended', actions.ended);
261
+ player.one('loadedmetadata', () => actions.saveMediaElementId(player.getMediaElement().id));
262
+ function handleTimeUpdate() {
263
+ actions.timeUpdate(player.currentTime(), player.duration());
264
+ }
265
+ return () => {
266
+ player.off('loadedmetadata');
267
+ player.off('loadeddata');
268
+ player.off('progress');
269
+ player.off('play', actions.playing);
270
+ player.off('playfailed', actions.playFailed);
271
+ player.off('pause', actions.paused);
272
+ player.off('waiting', actions.waiting);
273
+ player.off('seeking', actions.seeking);
274
+ player.off('seeked', actions.seeked);
275
+ player.off('bufferunderrun', actions.bufferUnderrun);
276
+ player.off('bufferunderruncontinue', actions.bufferUnderrunContinue);
277
+ player.off('timeupdate', handleTimeUpdate);
278
+ player.off('canplay');
279
+ player.off('ended', actions.ended);
280
+ actions.discardMediaElementId();
281
+ };
282
+ }
283
+
284
+ function applyPlayerState(player, playerState, playerActions) {
285
+ player.one('loadedmetadata', () => player.currentTime(playerState.currentTime));
286
+ player.changeVolumeFactor(playerState.volumeFactor, 0);
287
+ if (playerState.shouldPrebuffer) {
288
+ player.prebuffer().then(playerActions.prebuffered);
289
+ }
290
+ if (playerState.shouldPlay) {
291
+ player.play();
292
+ }
293
+ player.on('canplay', function () {
294
+ if (playerState.shouldPlay && player.paused()) {
295
+ player.play();
296
+ }
297
+ });
298
+ }
299
+
300
+ function updatePlayerState(player, prevPlayerState, playerState, playerActions) {
301
+ if (!prevPlayerState.shouldPrebuffer && playerState.shouldPrebuffer) {
302
+ player.prebuffer().then(() => setTimeout(playerActions.prebuffered, 0));
303
+ }
304
+ if (!prevPlayerState.shouldPlay && playerState.shouldPlay) {
305
+ if (playerState.fadeDuration) {
306
+ player.playAndFadeIn(playerState.fadeDuration);
307
+ } else {
308
+ player.playOrPlayOnLoad();
309
+ }
310
+ } else if (prevPlayerState.shouldPlay && !playerState.shouldPlay && playerState.isPlaying) {
311
+ if (playerState.fadeDuration && !player.muted()) {
312
+ player.fadeOutAndPause(playerState.fadeDuration);
313
+ } else {
314
+ player.pause();
315
+ }
316
+ }
317
+ if (playerState.shouldSeekTo !== undefined && prevPlayerState.shouldSeekTo !== playerState.shouldSeekTo) {
318
+ player.currentTime(playerState.shouldSeekTo);
319
+ }
320
+ if (prevPlayerState.volumeFactor !== playerState.volumeFactor) {
321
+ player.changeVolumeFactor(playerState.volumeFactor, playerState.volumeFactorFadeDuration);
322
+ }
323
+ }
324
+
325
+ function updateObjectPosition(player, x, y) {
326
+ player.getMediaElement().style.objectPosition = typeof x !== 'undefined' && typeof y !== 'undefined' ? `${x}% ${y}%` : '';
327
+ }
328
+
329
+ function getEventObject({
330
+ section,
331
+ sectionsCount
332
+ }) {
333
+ let page = {
334
+ getAnalyticsData: () => ({
335
+ chapterIndex: section === null || section === void 0 ? void 0 : section.chapter.index,
336
+ chapterTitle: section === null || section === void 0 ? void 0 : section.chapter.title,
337
+ index: section ? section.sectionIndex : -1,
338
+ total: sectionsCount
339
+ }),
340
+ index: section ? section.sectionIndex : -1,
341
+ configuration: {
342
+ title: section ? section.chapter.title + ', Section ' + section.sectionIndex : null
343
+ }
344
+ };
345
+ return page;
346
+ }
347
+ const EventContext = createContext(getEventObject({}));
348
+ function EventContextDataProvider({
349
+ section,
350
+ sectionsCount,
351
+ children
352
+ }) {
353
+ let contextValue = useMemo(() => {
354
+ return {
355
+ page: getEventObject({
356
+ section,
357
+ sectionsCount
358
+ })
359
+ };
360
+ }, [section, sectionsCount]);
361
+ return /*#__PURE__*/React.createElement(EventContext.Provider, {
362
+ value: contextValue
363
+ }, children);
364
+ }
365
+ function PlayerEventContextDataProvider({
366
+ playbackMode,
367
+ playerDescription,
368
+ children
369
+ }) {
370
+ const original = useEventContextData();
371
+ const value = useMemo(() => ({
372
+ ...original,
373
+ playbackMode,
374
+ playerDescription
375
+ }), [original, playbackMode, playerDescription]);
376
+ return /*#__PURE__*/React.createElement(EventContext.Provider, {
377
+ value: value
378
+ }, children);
379
+ }
380
+ function useEventContextData() {
381
+ return useContext(EventContext);
382
+ }
383
+
384
+ function updateTextTracksMode(player, activeTextTrackFileId) {
385
+ [].slice.call(player.textTracks()).forEach(textTrack => {
386
+ if (textTrack.id === `text_track_file_${activeTextTrackFileId}`) {
387
+ textTrack.mode = 'showing';
388
+ } else {
389
+ textTrack.mode = 'disabled';
390
+ }
391
+ });
392
+ }
393
+ function watchTextTracks(player, getActiveTextTrackFileId) {
394
+ function handleTextTracksUpdate() {
395
+ updateTextTracksMode(player, getActiveTextTrackFileId());
396
+ }
397
+ player.on('play', handleTextTracksUpdate);
398
+ player.on('texttrackchange', handleTextTracksUpdate);
399
+ handleTextTracksUpdate();
400
+ return () => {
401
+ player.off('play', handleTextTracksUpdate);
402
+ player.off('texttrackchange', handleTextTracksUpdate);
403
+ };
404
+ }
405
+ function getTextTrackSources(textTrackFiles, textTracksDisabled) {
406
+ if (textTracksDisabled) {
407
+ return [];
408
+ }
409
+ return textTrackFiles.filter(textTrackFile => textTrackFile.isReady).map(textTrackFile => ({
410
+ id: `text_track_file_${textTrackFile.id}`,
411
+ kind: textTrackFile.configuration.kind,
412
+ label: textTrackFile.displayLabel,
413
+ srclang: textTrackFile.configuration.srclang,
414
+ src: textTrackFile.urls.vtt
415
+ }));
416
+ }
417
+
418
+ function usePlayerTextTracks({
419
+ playerRef,
420
+ activeTextTrackFileId
421
+ }) {
422
+ const activeTextTrackFileIdRef = useRef(activeTextTrackFileId);
423
+ useEffect(() => {
424
+ activeTextTrackFileIdRef.current = activeTextTrackFileId;
425
+ if (playerRef.current) {
426
+ updateTextTracksMode(playerRef.current, activeTextTrackFileId);
427
+ }
428
+ }, [activeTextTrackFileId, playerRef]);
429
+ return useCallback(player => {
430
+ const unwatchTextTracks = watchTextTracks(player, () => activeTextTrackFileIdRef.current);
431
+ return () => {
432
+ unwatchTextTracks();
433
+ };
434
+ }, []);
435
+ }
436
+
437
+ var textTrackStyles = {"inset":"textTracks-module_inset__K7DIL"};
438
+
439
+ var styles = {"wrapper":"MediaPlayer-module_wrapper__1cSGR","cover":"MediaPlayer-module_cover__2wGez","contentElementBox":"MediaPlayer-module_contentElementBox__3zsPl","posterVisible":"MediaPlayer-module_posterVisible__3C_WZ"};
440
+
441
+ const PLAY = 'MEDIA_PLAY';
442
+ const PLAYING = 'MEDIA_PLAYING';
443
+ const PLAY_FAILED = 'MEDIA_PLAY_FAILED';
444
+ const PAUSE = 'MEDIA_PAUSE';
445
+ const PAUSED = 'MEDIA_PAUSED';
446
+ const PLAY_AND_FADE_IN = 'MEDIA_PLAY_AND_FADE_IN';
447
+ const FADE_OUT_AND_PAUSE = 'MEDIA_FADE_OUT_AND_PAUSE';
448
+ const CHANGE_VOLUME_FACTOR = 'CHANGE_VOLUME_FACTOR';
449
+ const META_DATA_LOADED = 'MEDIA_META_DATA_LOADED';
450
+ const DATA_LOADED = 'MEDIA_DATA_LOADED';
451
+ const PROGRESS = 'MEDIA_PROGRESS';
452
+ const TIME_UPDATE = 'MEDIA_TIME_UPDATE';
453
+ const ENDED = 'MEDIA_ENDED';
454
+ const SCRUB_TO = 'MEDIA_SCRUB_TO';
455
+ const SEEK_TO = 'MEDIA_SEEK_TO';
456
+ const SEEKING = 'MEDIA_SEEKING';
457
+ const SEEKED = 'MEDIA_SEEKED';
458
+ const WAITING = 'MEDIA_WAITING';
459
+ const PREBUFFER = 'MEDIA_PREBUFFER';
460
+ const PREBUFFERED = 'MEDIA_PREBUFFERED';
461
+ const BUFFER_UNDERRUN = 'MEDIA_BUFFER_UNDERRUN';
462
+ const BUFFER_UNDERRUN_CONTINUE = 'MEDIA_BUFFER_UNDERRUN_CONTINUE';
463
+ const MOUSE_ENTERED = 'MEDIA_MOUSE_ENTERED';
464
+ const MOUSE_LEFT = 'MEDIA_MOUSE_LEFT';
465
+ const MOUSE_ENTERED_CONTROLS = 'MEDIA_MOUSE_ENTERED_CONTROLS';
466
+ const MOUSE_LEFT_CONTROLS = 'MEDIA_MOUSE_LEFT_CONTROLS';
467
+ const FOCUS_ENTERED_CONTROLS = 'MEDIA_FOCUS_ENTERED_CONTROLS';
468
+ const FOCUS_LEFT_CONTROLS = 'MEDIA_FOCUS_LEFT_CONTROLS';
469
+ const USER_INTERACTION = 'MEDIA_USER_INTERACTION';
470
+ const USER_IDLE = 'MEDIA_USER_IDLE';
471
+ const SAVE_MEDIA_ELEMENT_ID = 'MEDIA_SAVE_MEDIA_ELEMENT_ID';
472
+ const DISCARD_MEDIA_ELEMENT_ID = 'MEDIA_DISCARD_MEDIA_ELEMENT_ID';
473
+ function createActions(dispatch) {
474
+ return {
475
+ playBlessed({
476
+ via
477
+ } = {}) {
478
+ media.mute(false);
479
+ dispatch({
480
+ type: PLAY,
481
+ payload: {
482
+ via
483
+ }
484
+ });
485
+ },
486
+ play({
487
+ via
488
+ } = {}) {
489
+ dispatch({
490
+ type: PLAY,
491
+ payload: {
492
+ via
493
+ }
494
+ });
495
+ },
496
+ playing() {
497
+ dispatch({
498
+ type: PLAYING
499
+ });
500
+ },
501
+ playFailed() {
502
+ dispatch({
503
+ type: PLAY_FAILED
504
+ });
505
+ },
506
+ pause({
507
+ via
508
+ } = {}) {
509
+ dispatch({
510
+ type: PAUSE,
511
+ payload: {
512
+ via
513
+ }
514
+ });
515
+ },
516
+ paused() {
517
+ dispatch({
518
+ type: PAUSED
519
+ });
520
+ },
521
+ playAndFadeIn(fadeDuration, {
522
+ via
523
+ } = {}) {
524
+ dispatch({
525
+ type: PLAY_AND_FADE_IN,
526
+ payload: {
527
+ fadeDuration: fadeDuration,
528
+ via
529
+ }
530
+ });
531
+ },
532
+ fadeOutAndPause(fadeDuration, {
533
+ via
534
+ } = {}) {
535
+ dispatch({
536
+ type: FADE_OUT_AND_PAUSE,
537
+ payload: {
538
+ fadeDuration: fadeDuration,
539
+ via
540
+ }
541
+ });
542
+ },
543
+ changeVolumeFactor(volumeFactor, fadeDuration) {
544
+ dispatch({
545
+ type: CHANGE_VOLUME_FACTOR,
546
+ payload: {
547
+ fadeDuration: fadeDuration,
548
+ volumeFactor: volumeFactor
549
+ }
550
+ });
551
+ },
552
+ metaDataLoaded(currentTime, duration) {
553
+ dispatch({
554
+ type: META_DATA_LOADED,
555
+ payload: {
556
+ currentTime: currentTime,
557
+ duration: duration
558
+ }
559
+ });
560
+ },
561
+ dataLoaded() {
562
+ dispatch({
563
+ type: DATA_LOADED
564
+ });
565
+ },
566
+ progress(bufferedEnd) {
567
+ dispatch({
568
+ type: PROGRESS,
569
+ payload: {
570
+ bufferedEnd: bufferedEnd
571
+ }
572
+ });
573
+ },
574
+ timeUpdate(currentTime, duration) {
575
+ dispatch({
576
+ type: TIME_UPDATE,
577
+ payload: {
578
+ currentTime: currentTime,
579
+ duration: duration
580
+ }
581
+ });
582
+ },
583
+ ended() {
584
+ dispatch({
585
+ type: ENDED
586
+ });
587
+ },
588
+ scrubTo(time) {
589
+ dispatch({
590
+ type: SCRUB_TO,
591
+ payload: {
592
+ time: time
593
+ }
594
+ });
595
+ },
596
+ seekTo(time) {
597
+ dispatch({
598
+ type: SEEK_TO,
599
+ payload: {
600
+ time: time
601
+ }
602
+ });
603
+ },
604
+ seeking() {
605
+ dispatch({
606
+ type: SEEKING
607
+ });
608
+ },
609
+ seeked() {
610
+ dispatch({
611
+ type: SEEKED
612
+ });
613
+ },
614
+ waiting() {
615
+ dispatch({
616
+ type: WAITING
617
+ });
618
+ },
619
+ prebuffer() {
620
+ dispatch({
621
+ type: PREBUFFER
622
+ });
623
+ },
624
+ prebuffered() {
625
+ dispatch({
626
+ type: PREBUFFERED
627
+ });
628
+ },
629
+ bufferUnderrun() {
630
+ dispatch({
631
+ type: BUFFER_UNDERRUN
632
+ });
633
+ },
634
+ bufferUnderrunContinue() {
635
+ dispatch({
636
+ type: BUFFER_UNDERRUN_CONTINUE
637
+ });
638
+ },
639
+ mouseEntered() {
640
+ dispatch({
641
+ type: MOUSE_ENTERED
642
+ });
643
+ },
644
+ mouseLeft() {
645
+ dispatch({
646
+ type: MOUSE_LEFT
647
+ });
648
+ },
649
+ mouseEnteredControls() {
650
+ dispatch({
651
+ type: MOUSE_ENTERED_CONTROLS
652
+ });
653
+ },
654
+ mouseLeftControls() {
655
+ dispatch({
656
+ type: MOUSE_LEFT_CONTROLS
657
+ });
658
+ },
659
+ userInteraction() {
660
+ dispatch({
661
+ type: USER_INTERACTION
662
+ });
663
+ },
664
+ userIdle() {
665
+ dispatch({
666
+ type: USER_IDLE
667
+ });
668
+ },
669
+ focusEnteredControls() {
670
+ dispatch({
671
+ type: FOCUS_ENTERED_CONTROLS
672
+ });
673
+ },
674
+ focusLeftControls() {
675
+ dispatch({
676
+ type: FOCUS_LEFT_CONTROLS
677
+ });
678
+ },
679
+ saveMediaElementId(id) {
680
+ dispatch({
681
+ type: SAVE_MEDIA_ELEMENT_ID,
682
+ payload: {
683
+ id: id
684
+ }
685
+ });
686
+ },
687
+ discardMediaElementId() {
688
+ dispatch({
689
+ type: DISCARD_MEDIA_ELEMENT_ID
690
+ });
691
+ }
692
+ };
693
+ }
694
+
695
+ function getInitialPlayerState() {
696
+ return {
697
+ isPlaying: false,
698
+ shouldPlay: false,
699
+ unplayed: true,
700
+ dataLoaded: false,
701
+ isLoading: true,
702
+ playFailed: false,
703
+ duration: 0,
704
+ bufferedEnd: 0,
705
+ shouldPrebuffer: true,
706
+ fadeDuration: undefined,
707
+ bufferUnderrun: undefined,
708
+ scrubbingAt: undefined,
709
+ currentTime: 0,
710
+ mediaElementId: undefined,
711
+ shouldSeekTo: undefined,
712
+ userHovering: false,
713
+ userHoveringControls: false,
714
+ focusInsideControls: false,
715
+ userIdle: false,
716
+ volumeFactor: 1
717
+ };
718
+ }
719
+ function playerStateReducer(state, action) {
720
+ switch (action.type) {
721
+ case PLAY:
722
+ return {
723
+ ...state,
724
+ isLoading: true,
725
+ shouldPlay: true,
726
+ playFailed: false,
727
+ lastControlledVia: action.payload.via
728
+ };
729
+ case PLAYING:
730
+ return {
731
+ ...state,
732
+ shouldPlay: true,
733
+ isPlaying: true,
734
+ unplayed: false,
735
+ userIdle: false
736
+ };
737
+ case PLAY_AND_FADE_IN:
738
+ return {
739
+ ...state,
740
+ shouldPlay: true,
741
+ fadeDuration: action.payload.fadeDuration,
742
+ isLoading: true,
743
+ lastControlledVia: action.payload.via
744
+ };
745
+ case FADE_OUT_AND_PAUSE:
746
+ return {
747
+ ...state,
748
+ shouldPlay: false,
749
+ fadeDuration: action.payload.fadeDuration,
750
+ isLoading: false,
751
+ lastControlledVia: action.payload.via
752
+ };
753
+ case PLAY_FAILED:
754
+ return {
755
+ ...state,
756
+ shouldPlay: false,
757
+ playFailed: true,
758
+ fadeDuration: null,
759
+ unplayed: true,
760
+ isLoading: false
761
+ };
762
+ case PAUSE:
763
+ return {
764
+ ...state,
765
+ shouldPlay: false,
766
+ isLoading: false,
767
+ fadeDuration: null,
768
+ lastControlledVia: action.payload.via
769
+ };
770
+ case PAUSED:
771
+ if (state.bufferUnderrun) {
772
+ return {
773
+ ...state,
774
+ isPlaying: false
775
+ };
776
+ } else {
777
+ return {
778
+ ...state,
779
+ shouldPlay: false,
780
+ fadeDuration: null,
781
+ isPlaying: false,
782
+ isLoading: false
783
+ };
784
+ }
785
+ case SCRUB_TO:
786
+ return {
787
+ ...state,
788
+ scrubbingAt: action.payload.time
789
+ };
790
+ case SEEK_TO:
791
+ return {
792
+ ...state,
793
+ shouldSeekTo: action.payload.time
794
+ };
795
+ case SEEKING:
796
+ return {
797
+ ...state,
798
+ isLoading: true
799
+ };
800
+ case SEEKED:
801
+ return {
802
+ ...state,
803
+ shouldSeekTo: undefined,
804
+ scrubbingAt: undefined,
805
+ isLoading: false
806
+ };
807
+ case META_DATA_LOADED:
808
+ return {
809
+ ...state,
810
+ currentTime: action.payload.currentTime,
811
+ duration: action.payload.duration
812
+ };
813
+ case DATA_LOADED:
814
+ return {
815
+ ...state,
816
+ dataLoaded: true
817
+ };
818
+ case PROGRESS:
819
+ return {
820
+ ...state,
821
+ bufferedEnd: action.payload.bufferedEnd
822
+ };
823
+ case TIME_UPDATE:
824
+ return {
825
+ ...state,
826
+ currentTime: action.payload.currentTime,
827
+ duration: action.payload.duration,
828
+ isLoading: false
829
+ };
830
+ case ENDED:
831
+ return {
832
+ ...state,
833
+ shouldPlay: false,
834
+ isPlaying: false,
835
+ unplayed: true,
836
+ lastControlledVia: null
837
+ };
838
+ case WAITING:
839
+ return {
840
+ ...state,
841
+ isLoading: true
842
+ };
843
+ case PREBUFFER:
844
+ return {
845
+ ...state,
846
+ shouldPrebuffer: true
847
+ };
848
+ case PREBUFFERED:
849
+ return {
850
+ ...state,
851
+ shouldPrebuffer: false
852
+ };
853
+ case BUFFER_UNDERRUN:
854
+ return {
855
+ ...state,
856
+ bufferUnderrun: true
857
+ };
858
+ case BUFFER_UNDERRUN_CONTINUE:
859
+ return {
860
+ ...state,
861
+ bufferUnderrun: false
862
+ };
863
+ case MOUSE_ENTERED:
864
+ return {
865
+ ...state,
866
+ userHovering: true
867
+ };
868
+ case MOUSE_LEFT:
869
+ return {
870
+ ...state,
871
+ userHovering: false
872
+ };
873
+ case MOUSE_ENTERED_CONTROLS:
874
+ return {
875
+ ...state,
876
+ userHoveringControls: true
877
+ };
878
+ case MOUSE_LEFT_CONTROLS:
879
+ return {
880
+ ...state,
881
+ userHoveringControls: false
882
+ };
883
+ case FOCUS_ENTERED_CONTROLS:
884
+ return {
885
+ ...state,
886
+ focusInsideControls: true,
887
+ userIdle: false
888
+ };
889
+ case FOCUS_LEFT_CONTROLS:
890
+ return {
891
+ ...state,
892
+ focusInsideControls: false,
893
+ userIdle: false
894
+ };
895
+ case USER_INTERACTION:
896
+ if (!state.userIdle) {
897
+ return state;
898
+ }
899
+ return {
900
+ ...state,
901
+ userIdle: false
902
+ };
903
+ case USER_IDLE:
904
+ return {
905
+ ...state,
906
+ userIdle: true
907
+ };
908
+ case SAVE_MEDIA_ELEMENT_ID:
909
+ return {
910
+ ...state,
911
+ mediaElementId: action.payload.id
912
+ };
913
+ case DISCARD_MEDIA_ELEMENT_ID:
914
+ return {
915
+ ...state,
916
+ dataLoaded: false,
917
+ isPlaying: false,
918
+ mediaElementId: null
919
+ };
920
+ case CHANGE_VOLUME_FACTOR:
921
+ return {
922
+ ...state,
923
+ volumeFactor: action.payload.volumeFactor,
924
+ volumeFactorFadeDuration: action.payload.fadeDuration
925
+ };
926
+ default:
927
+ return state;
928
+ }
929
+ }
930
+ function usePlayerState() {
931
+ const [state, dispatch] = useReducer(playerStateReducer, getInitialPlayerState());
932
+ const actions = useMemo(() => createActions(dispatch), [dispatch]);
933
+ return [state, actions];
934
+ }
935
+
936
+ function MediaPlayer(props) {
937
+ const isStaticPreview = useIsStaticPreview();
938
+ const load = props.load === 'auto' && isStaticPreview ? 'poster' : props.load;
939
+ const posterVisible = props.posterImageUrl && (props.type !== 'video' || load === 'poster' || !props.playerState.dataLoaded || props.playerState.unplayed);
940
+ return /*#__PURE__*/React.createElement("div", {
941
+ className: classNames(styles.wrapper, styles[props.fit], {
942
+ [styles.contentElementBox]: props.applyContentElementBoxStyles,
943
+ [styles.posterVisible]: posterVisible,
944
+ [textTrackStyles.inset]: props.textTracksInset
945
+ })
946
+ }, load === 'auto' && /*#__PURE__*/React.createElement(PreparedMediaPlayer, props), load !== 'none' && /*#__PURE__*/React.createElement(Poster, {
947
+ imageUrl: props.posterImageUrl,
948
+ objectPosition: props.objectPosition
949
+ }));
950
+ }
951
+ MediaPlayer.defaultProps = {
952
+ load: 'auto'
953
+ };
954
+ function Poster({
955
+ imageUrl,
956
+ objectPosition
957
+ }) {
958
+ if (!imageUrl) {
959
+ return null;
960
+ }
961
+ return /*#__PURE__*/React.createElement("img", {
962
+ src: imageUrl,
963
+ alt: "",
964
+ style: {
965
+ objectPosition: objectPosition && `${objectPosition.x}% ${objectPosition.y}%`
966
+ }
967
+ });
968
+ }
969
+ function PreparedMediaPlayer(props) {
970
+ let playerRef = useRef();
971
+ let previousPlayerState = useRef(props.playerState);
972
+ let eventContextData = useEventContextData();
973
+ const setupTextTracks = usePlayerTextTracks({
974
+ playerRef,
975
+ activeTextTrackFileId: props.textTracks.activeFileId
976
+ });
977
+ let onSetup = newPlayer => {
978
+ playerRef.current = newPlayer;
979
+ const unwatchPlayer = watchPlayer(newPlayer, props.playerActions);
980
+ const unwatchTextTracks = setupTextTracks(newPlayer);
981
+ applyPlayerState(newPlayer, props.playerState, props.playerActions);
982
+ updateObjectPosition(newPlayer, props.objectPosition.x, props.objectPosition.y);
983
+ return () => {
984
+ unwatchTextTracks();
985
+ unwatchPlayer();
986
+ playerRef.current = undefined;
987
+ };
988
+ };
989
+ useEffect(() => {
990
+ let player = playerRef.current;
991
+ if (player) {
992
+ updatePlayerState(player, previousPlayerState.current, props.playerState, props.playerActions);
993
+ }
994
+ previousPlayerState.current = props.playerState;
995
+ }, [props.playerState, props.playerActions]);
996
+ useEffect(() => {
997
+ const player = playerRef.current;
998
+ if (player) {
999
+ updateObjectPosition(player, props.objectPosition.x, props.objectPosition.y);
1000
+ }
1001
+ }, [props.objectPosition.x, props.objectPosition.y]);
1002
+ return /*#__PURE__*/React.createElement(PlayerContainer$1, {
1003
+ type: props.type,
1004
+ sources: appendSuffix(props.sources, props.sourceUrlSuffix),
1005
+ textTrackSources: getTextTrackSources(props.textTracks.files, props.textTracksDisabled),
1006
+ filePermaId: props.filePermaId,
1007
+ loop: props.loop,
1008
+ controls: props.controls,
1009
+ playsInline: props.playsInline,
1010
+ mediaEventsContextData: {
1011
+ ...eventContextData,
1012
+ ...props.mediaEventsContextData
1013
+ },
1014
+ atmoDuringPlayback: props.atmoDuringPlayback,
1015
+ onSetup: onSetup,
1016
+ altText: props.altText
1017
+ });
1018
+ }
1019
+ PreparedMediaPlayer.defaultProps = {
1020
+ objectPosition: {},
1021
+ textTracks: {
1022
+ files: []
1023
+ }
1024
+ };
1025
+ function appendSuffix(sources, suffix) {
1026
+ if (!suffix) {
1027
+ return sources;
1028
+ }
1029
+ return sources.map(source => ({
1030
+ ...source,
1031
+ src: `${source.src}${suffix}`
1032
+ }));
1033
+ }
1034
+
1035
+ function useSetting(name) {
1036
+ const [value, setValue] = useState(settings.get(name));
1037
+ useEffect(() => {
1038
+ function update() {
1039
+ setValue(settings.get(name));
1040
+ }
1041
+ settings.on(`change:${name}`, update);
1042
+ return () => settings.off(undefined, update);
1043
+ }, [setValue, name]);
1044
+ const setter = useCallback(value => settings.set(name, value), [name]);
1045
+ return [value, setter];
1046
+ }
1047
+
1048
+ function useTextTracks({
1049
+ file,
1050
+ defaultTextTrackFilePermaId,
1051
+ captionsByDefault
1052
+ }) {
1053
+ let [setting, setSetting] = useSetting('textTrack');
1054
+ setting = setting || {};
1055
+ const {
1056
+ t
1057
+ } = useI18n();
1058
+ const {
1059
+ locale
1060
+ } = useEntryMetadata();
1061
+ const textTrackFiles = useTextTrackFiles({
1062
+ file
1063
+ });
1064
+ const autoTextTrackFile = getAutoTextTrackFile(textTrackFiles, defaultTextTrackFilePermaId, locale, captionsByDefault);
1065
+ return {
1066
+ mode: setting.kind === 'off' ? 'off' : setting.kind ? 'user' : 'auto',
1067
+ autoDisplayLabel: autoTextTrackFile ? t('pageflow_scrolled.public.text_track_modes.auto', {
1068
+ label: autoTextTrackFile.displayLabel
1069
+ }) : t('pageflow_scrolled.public.text_track_modes.auto_off'),
1070
+ files: textTrackFiles,
1071
+ activeFileId: getActiveTextTrackFileId(textTrackFiles, autoTextTrackFile, setting),
1072
+ select(textTrackFileIdOrKind) {
1073
+ if (textTrackFileIdOrKind === 'off') {
1074
+ setSetting({
1075
+ kind: 'off'
1076
+ });
1077
+ } else if (textTrackFileIdOrKind === 'auto') {
1078
+ setSetting({});
1079
+ } else {
1080
+ const textTrackFile = textTrackFiles.find(file => file.id === textTrackFileIdOrKind);
1081
+ setSetting({
1082
+ kind: textTrackFile.configuration.kind,
1083
+ srclang: textTrackFile.configuration.srclang
1084
+ });
1085
+ }
1086
+ }
1087
+ };
1088
+ }
1089
+ function useTextTrackFiles({
1090
+ file
1091
+ }) {
1092
+ const {
1093
+ t
1094
+ } = useI18n();
1095
+ return useNestedFiles({
1096
+ collectionName: 'textTrackFiles',
1097
+ parent: file
1098
+ }).map(file => addDisplayLabel(file, t)).sort((file1, file2) => file1.displayLabel.localeCompare(file2.displayLabel));
1099
+ }
1100
+ function getActiveTextTrackFileId(textTrackFiles, autoTextTrackFile, setting) {
1101
+ if (setting.kind === 'off') {
1102
+ return null;
1103
+ }
1104
+ const file = textTrackFiles.find(textTrackFile => textTrackFile.configuration.srclang === setting.srclang && textTrackFile.configuration.kind === setting.kind);
1105
+ if (file) {
1106
+ return file.id;
1107
+ }
1108
+ return autoTextTrackFile && autoTextTrackFile.id;
1109
+ }
1110
+ function getAutoTextTrackFile(textTrackFiles, defaultTextTrackFilePermaId, locale, captionsByDefault) {
1111
+ if (defaultTextTrackFilePermaId) {
1112
+ const defaultTextTrackFile = textTrackFiles.find(textTrackFile => textTrackFile.permaId === defaultTextTrackFilePermaId);
1113
+ if (defaultTextTrackFile) {
1114
+ return defaultTextTrackFile;
1115
+ }
1116
+ }
1117
+ const subtitlesInEntryLanguage = textTrackFiles.find(textTrackFile => {
1118
+ return textTrackFile.configuration.kind === 'subtitles' && textTrackFile.configuration.srclang === locale;
1119
+ });
1120
+ const defaultCaptions = captionsByDefault ? textTrackFiles.find(textTrackFile => {
1121
+ return textTrackFile.configuration.kind === 'captions';
1122
+ }) : null;
1123
+ return subtitlesInEntryLanguage || defaultCaptions;
1124
+ }
1125
+ function addDisplayLabel(textTrackFile, t) {
1126
+ return {
1127
+ ...textTrackFile,
1128
+ displayLabel: textTrackFile.configuration.label || t('pageflow_scrolled.public.languages.' + textTrackFile.configuration.srclang || 'unknown', {
1129
+ defaultValue: t('pageflow_scrolled.public.languages.unknown')
1130
+ })
1131
+ };
1132
+ }
1133
+
1134
+ const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
1135
+
1136
+ function usePrevious(value) {
1137
+ const ref = useRef();
1138
+ useEffect(() => {
1139
+ ref.current = value;
1140
+ });
1141
+ return ref.current;
1142
+ }
1143
+
1144
+ const MediaMutedContext = createContext(false);
1145
+ function MediaMutedProvider({
1146
+ children
1147
+ }) {
1148
+ const [value, setValue] = useState(media.muted);
1149
+ useEffect(() => {
1150
+ media.on('change:muted', setValue);
1151
+ return () => media.off('change:muted', setValue);
1152
+ }, []);
1153
+ return /*#__PURE__*/React.createElement(MediaMutedContext.Provider, {
1154
+ value: value
1155
+ }, children);
1156
+ }
1157
+
1158
+ /**
1159
+ * Returns boolean indicating whether the entry is currently muted.
1160
+ */
1161
+ function useMediaMuted() {
1162
+ return useContext(MediaMutedContext);
1163
+ }
1164
+ function useOnUnmuteMedia(callback) {
1165
+ const muted = useMediaMuted();
1166
+ const wasMuted = usePrevious(muted);
1167
+ useIsomorphicLayoutEffect(() => {
1168
+ if (wasMuted && !muted) {
1169
+ callback();
1170
+ }
1171
+ }, [wasMuted, muted, callback]);
1172
+ }
1173
+
1174
+ function ensureProtocol(protocol, url) {
1175
+ if (url && url.match(/^\/\//)) {
1176
+ return `${protocol}:${url}`;
1177
+ }
1178
+ return url;
1179
+ }
1180
+
1181
+ function formatTimeDuration(durationInMs) {
1182
+ const seconds = Math.round(durationInMs / 1000) % 60;
1183
+ const minutes = Math.floor(durationInMs / 1000 / 60) % 60;
1184
+ const hours = Math.floor(durationInMs / 1000 / 60 / 60);
1185
+ let result = 'PT';
1186
+ if (hours > 0) {
1187
+ result += `${hours}H`;
1188
+ }
1189
+ if (minutes > 0) {
1190
+ result += `${minutes}M`;
1191
+ }
1192
+ if (seconds > 0 || minutes === 0 && hours === 0) {
1193
+ result += `${seconds}S`;
1194
+ }
1195
+ return result;
1196
+ }
1197
+
1198
+ function StructuredData({
1199
+ data
1200
+ }) {
1201
+ return /*#__PURE__*/React.createElement("script", {
1202
+ type: "application/ld+json",
1203
+ dangerouslySetInnerHTML: {
1204
+ __html: JSON.stringify(data)
1205
+ }
1206
+ });
1207
+ }
1208
+
1209
+ function AudioStructuredData({
1210
+ file
1211
+ }) {
1212
+ const entryMedadata = useEntryMetadata();
1213
+ const data = {
1214
+ '@context': 'http://schema.org',
1215
+ '@type': 'AudioObject',
1216
+ name: file.basename,
1217
+ description: file.configuration.alt,
1218
+ url: ensureProtocol('https', file.urls.mp3),
1219
+ duration: formatTimeDuration(file.durationInMs),
1220
+ datePublished: entryMedadata.publishedAt,
1221
+ uploadDate: file.createdAt,
1222
+ copyrightHolder: {
1223
+ '@type': 'Organization',
1224
+ name: file.rights
1225
+ }
1226
+ };
1227
+ return /*#__PURE__*/React.createElement(StructuredData, {
1228
+ data: data
1229
+ });
1230
+ }
1231
+
1232
+ var styles$1 = {"spaceForTextTracks":"AudioPlayer-module_spaceForTextTracks__169MK","spaceForTextTracksActive":"AudioPlayer-module_spaceForTextTracksActive__99m7R"};
1233
+
1234
+ /**
1235
+ * Render audio file in MediaPlayer.
1236
+ *
1237
+ * @param {Object} props
1238
+ * @param {Object} props.audioFile - Audio file obtained via `useFile`.
1239
+ * @param {number} [props.posterImageFile] - Poster image file obtained via `useFile`.
1240
+ * @param {number} [props.defaultTextTrackFileId] - Perma id of default text track file.
1241
+ * @param {string} [props.load] - Control lazy loading. `"auto"` (default), `"poster"` or `"none"`.
1242
+ */
1243
+ function AudioPlayer({
1244
+ audioFile,
1245
+ posterImageFile,
1246
+ ...props
1247
+ }) {
1248
+ const textTracks = useTextTracks({
1249
+ file: audioFile,
1250
+ defaultTextTrackFilePermaId: props.defaultTextTrackFilePermaId,
1251
+ captionsByDefault: useMediaMuted()
1252
+ });
1253
+ if (audioFile && audioFile.isReady) {
1254
+ return /*#__PURE__*/React.createElement("div", {
1255
+ className: classNames(styles$1.spaceForTextTracks, {
1256
+ [styles$1.spaceForTextTracksActive]: !posterImageFile && textTracks.files.length
1257
+ })
1258
+ }, /*#__PURE__*/React.createElement(MediaPlayer, Object.assign({
1259
+ type: 'audio',
1260
+ textTracks: textTracks,
1261
+ filePermaId: audioFile.permaId,
1262
+ sources: processSources(audioFile),
1263
+ textTracksInset: !!posterImageFile,
1264
+ posterImageUrl: posterImageFile && posterImageFile.isReady ? posterImageFile.urls.large : undefined,
1265
+ altText: audioFile.configuration.alt,
1266
+ mediaEventsContextData: {
1267
+ fileDisplayName: audioFile.displayName
1268
+ }
1269
+ }, props)), /*#__PURE__*/React.createElement(AudioStructuredData, {
1270
+ file: audioFile
1271
+ }));
1272
+ }
1273
+ return null;
1274
+ }
1275
+ AudioPlayer.defaultProps = {
1276
+ controls: true
1277
+ };
1278
+ function processSources(audioFile) {
1279
+ var sources = [];
1280
+ if (audioFile.urls['ogg'] && !has('broken ogg support')) {
1281
+ sources.push({
1282
+ type: 'audio/ogg',
1283
+ src: `${audioFile.urls['ogg']}?u=1`
1284
+ });
1285
+ }
1286
+ if (audioFile.urls['mp3']) {
1287
+ sources.push({
1288
+ type: 'audio/mp3',
1289
+ src: `${audioFile.urls['mp3']}?u=1`
1290
+ });
1291
+ }
1292
+ if (audioFile.urls['m4a']) {
1293
+ sources.push({
1294
+ type: 'audio/m4a',
1295
+ src: `${audioFile.urls['m4a']}?u=1`
1296
+ });
1297
+ }
1298
+ return sources;
1299
+ }
1300
+ function has(featureName) {
1301
+ return typeof window !== 'undefined' && browser.has(featureName);
1302
+ }
1303
+
1304
+ function SectionAtmo({
1305
+ audioFile
1306
+ }) {
1307
+ const lastAudioFile = usePrevious(audioFile);
1308
+ let atmo = useAtmo();
1309
+ let processAtmo = useCallback(() => {
1310
+ let sources = undefined;
1311
+ if (audioFile && audioFile.isReady) {
1312
+ sources = processSources(audioFile);
1313
+ }
1314
+ if (atmo) {
1315
+ atmo.updateAtmo({
1316
+ sources: sources,
1317
+ audioFilePermaId: audioFile === null || audioFile === void 0 ? void 0 : audioFile.permaId
1318
+ });
1319
+ }
1320
+ }, [atmo, audioFile]);
1321
+ useSectionLifecycle({
1322
+ onActivate() {
1323
+ processAtmo();
1324
+ }
1325
+ });
1326
+ useEffect(() => {
1327
+ if (lastAudioFile !== undefined && (lastAudioFile && lastAudioFile.permaId) !== (audioFile && audioFile.permaId)) {
1328
+ processAtmo();
1329
+ }
1330
+ }, [processAtmo, lastAudioFile, audioFile]);
1331
+ return null;
1332
+ }
1333
+
1334
+ var styles$2 = {"Foreground":"Foreground-module_Foreground__13ODU","fullFadeHeight":"Foreground-module_fullFadeHeight__2p9dx","fullHeight":"Foreground-module_fullHeight__1vMXb","spaceAbove":"Foreground-module_spaceAbove__dUi9X","spaceBelow":"Foreground-module_spaceBelow__SF0a9","suppressedPaddingTop":"Foreground-module_suppressedPaddingTop__3rVKd","suppressedPaddingBottom":"Foreground-module_suppressedPaddingBottom__3tvTs","forcePadding":"Foreground-module_forcePadding__3mh-s"};
1335
+
1336
+ const ForcePaddingContext = createContext(false);
1337
+ const Foreground = extensible('Foreground', function Foreground(props) {
1338
+ const forcePadding = useContext(ForcePaddingContext);
1339
+ return /*#__PURE__*/React.createElement("div", {
1340
+ className: className(props, forcePadding),
1341
+ style: {
1342
+ minHeight: props.minHeight
1343
+ }
1344
+ }, props.children);
1345
+ });
1346
+ function className(props, forcePadding) {
1347
+ var _props$suppressedPadd, _props$suppressedPadd2, _props$section;
1348
+ return classNames(styles$2.Foreground, props.transitionStyles.foreground, props.transitionStyles[`foreground-${props.state}`], {
1349
+ [styles$2.suppressedPaddingTop]: (_props$suppressedPadd = props.suppressedPaddings) === null || _props$suppressedPadd === void 0 ? void 0 : _props$suppressedPadd.top
1350
+ }, {
1351
+ [styles$2.suppressedPaddingBottom]: (_props$suppressedPadd2 = props.suppressedPaddings) === null || _props$suppressedPadd2 === void 0 ? void 0 : _props$suppressedPadd2.bottom
1352
+ }, {
1353
+ [styles$2.forcePadding]: forcePadding
1354
+ }, styles$2[`${props.heightMode}Height`], styles$2[spaceClassName((_props$section = props.section) === null || _props$section === void 0 ? void 0 : _props$section.remainingVerticalSpace)]);
1355
+ }
1356
+ function spaceClassName(remainingVerticalSpace) {
1357
+ if (remainingVerticalSpace === 'above') {
1358
+ return 'spaceAbove';
1359
+ } else if (remainingVerticalSpace === 'below') {
1360
+ return 'spaceBelow';
1361
+ }
1362
+ }
1363
+
1364
+ function getEffectValue(file, name) {
1365
+ var _find;
1366
+ return (_find = ((file === null || file === void 0 ? void 0 : file.effects) || []).find(effect => effect.name === name)) === null || _find === void 0 ? void 0 : _find.value;
1367
+ }
1368
+
1369
+ var styles$3 = {"outer":"BackdropFrameEffect-module_outer__1Od-V","inner":"BackdropFrameEffect-module_inner__n74el"};
1370
+
1371
+ function BackdropFrameEffect({
1372
+ backdrop
1373
+ }) {
1374
+ const value = getEffectValue(backdrop, 'frame');
1375
+ if (!value) {
1376
+ return null;
1377
+ }
1378
+ const {
1379
+ color,
1380
+ design
1381
+ } = normalizeFrameValue(value);
1382
+ if (!color) {
1383
+ return null;
1384
+ }
1385
+ return /*#__PURE__*/React.createElement("div", {
1386
+ className: classNames(styles$3.outer, frameScopeClass(design)),
1387
+ style: {
1388
+ '--frame-color': color
1389
+ }
1390
+ }, /*#__PURE__*/React.createElement("div", {
1391
+ className: styles$3.inner
1392
+ }));
1393
+ }
1394
+ function normalizeFrameValue(value) {
1395
+ if (typeof value === 'string') {
1396
+ return {
1397
+ color: value
1398
+ };
1399
+ }
1400
+ return value;
1401
+ }
1402
+ function frameScopeClass(design) {
1403
+ return `scope-backdropFrame-${design || 'default'}`;
1404
+ }
1405
+
1406
+ function _extends() {
1407
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
1408
+ for (var i = 1; i < arguments.length; i++) {
1409
+ var source = arguments[i];
1410
+ for (var key in source) {
1411
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
1412
+ target[key] = source[key];
1413
+ }
1414
+ }
1415
+ }
1416
+ return target;
1417
+ };
1418
+ return _extends.apply(this, arguments);
1419
+ }
1420
+ var ai = (({
1421
+ styles = {},
1422
+ ...props
1423
+ }) => /*#__PURE__*/React.createElement("svg", _extends({
1424
+ xmlns: "http://www.w3.org/2000/svg",
1425
+ viewBox: "89.27 100.72 365.5 365.49"
1426
+ }, props), /*#__PURE__*/React.createElement("path", {
1427
+ fill: "currentColor",
1428
+ fillRule: "evenodd",
1429
+ d: "M272.03 100.72c100.92 0 182.74 81.82 182.74 182.75s-81.82 182.74-182.74 182.74S89.28 384.39 89.28 283.47s81.82-182.75 182.75-182.75"
1430
+ }), /*#__PURE__*/React.createElement("path", {
1431
+ d: "M170.79 353.74c-1.08 0-2.05-.43-2.92-1.31-.88-.87-1.31-1.84-1.31-2.92 0-.67.07-1.27.2-1.81l47.34-129.32c.4-1.48 1.24-2.79 2.52-3.93 1.27-1.14 3.05-1.71 5.34-1.71h29.81c2.28 0 4.06.57 5.34 1.71 1.27 1.14 2.11 2.45 2.52 3.93l47.14 129.32c.27.54.4 1.14.4 1.81 0 1.08-.44 2.05-1.31 2.92s-1.91 1.31-3.12 1.31h-24.78c-2.01 0-3.52-.5-4.53-1.51-1.01-1.01-1.65-1.91-1.91-2.72l-7.86-20.55h-53.78l-7.65 20.55c-.27.81-.88 1.71-1.81 2.72-.94 1.01-2.55 1.51-4.83 1.51h-24.78zm47.34-53.78h37.47l-18.93-53.18-18.53 53.18zm109.98 53.78c-1.48 0-2.69-.47-3.63-1.41s-1.41-2.15-1.41-3.63V217.77c0-1.48.47-2.68 1.41-3.63s2.15-1.41 3.63-1.41h26.99c1.48 0 2.68.47 3.63 1.41.94.94 1.41 2.15 1.41 3.63V348.7c0 1.48-.47 2.69-1.41 3.63s-2.15 1.41-3.63 1.41h-26.99z",
1432
+ fill: "var(--ai-indicator-letter-color, #fff)"
1433
+ })));
1434
+
1435
+ function _extends$1() {
1436
+ _extends$1 = Object.assign ? Object.assign.bind() : function (target) {
1437
+ for (var i = 1; i < arguments.length; i++) {
1438
+ var source = arguments[i];
1439
+ for (var key in source) {
1440
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
1441
+ target[key] = source[key];
1442
+ }
1443
+ }
1444
+ }
1445
+ return target;
1446
+ };
1447
+ return _extends$1.apply(this, arguments);
1448
+ }
1449
+ var aiGenerated = (({
1450
+ styles = {},
1451
+ ...props
1452
+ }) => /*#__PURE__*/React.createElement("svg", _extends$1({
1453
+ xmlns: "http://www.w3.org/2000/svg",
1454
+ viewBox: "207.3 144.35 1384.24 266.42"
1455
+ }, props), /*#__PURE__*/React.createElement("path", {
1456
+ fill: "currentColor",
1457
+ fillRule: "evenodd",
1458
+ d: "M352.84 410.77H1446c85.55 0 145.54-59.94 145.54-133.2 0-73.27-59.99-133.21-145.54-133.21H352.84c-85.55 0-145.54 59.94-145.54 133.2 0 73.26 64.99 133.2 150.54 133.2"
1459
+ }), /*#__PURE__*/React.createElement("path", {
1460
+ d: "M326.09 341c-.98 0-1.87-.4-2.66-1.19-.8-.8-1.19-1.68-1.19-2.66 0-.61.06-1.16.18-1.65l43.18-117.96c.37-1.35 1.13-2.54 2.3-3.58 1.16-1.04 2.79-1.56 4.87-1.56h27.19c2.08 0 3.7.52 4.87 1.56 1.16 1.04 1.93 2.24 2.3 3.58l42.99 117.96c.24.49.37 1.04.37 1.65 0 .98-.4 1.87-1.19 2.66-.8.8-1.75 1.19-2.85 1.19h-22.6c-1.84 0-3.22-.46-4.13-1.38-.92-.92-1.5-1.75-1.75-2.48l-7.17-18.74h-49.06l-6.98 18.74c-.25.73-.8 1.56-1.65 2.48-.86.92-2.33 1.38-4.41 1.38h-22.6zm43.18-49.06h34.18l-17.27-48.51-16.9 48.51zM469.58 341c-1.35 0-2.45-.43-3.31-1.29-.86-.86-1.29-1.96-1.29-3.31V216.97c0-1.35.43-2.45 1.29-3.31s1.96-1.29 3.31-1.29h24.62c1.35 0 2.45.43 3.31 1.29.86.86 1.29 1.96 1.29 3.31V336.4c0 1.35-.43 2.45-1.29 3.31s-1.96 1.29-3.31 1.29h-24.62zm169.67-15.13c-8.43 0-15.63-1.41-21.59-4.24-5.97-2.83-10.58-6.95-13.86-12.38-3.27-5.43-5.04-11.99-5.31-19.71-.09-3.85-.13-7.98-.13-12.38s.04-8.56.13-12.51c.27-7.53 2.04-13.94 5.31-19.24 3.27-5.29 7.94-9.35 13.99-12.17 6.05-2.83 13.2-4.24 21.46-4.24 6.64 0 12.46.85 17.49 2.56 5.02 1.7 9.24 3.92 12.65 6.66s6.01 5.72 7.8 8.95c1.79 3.23 2.74 6.32 2.83 9.28 0 .81-.27 1.5-.81 2.08-.54.58-1.26.87-2.15.87h-16.68c-.9 0-1.59-.18-2.08-.54-.49-.36-.92-.9-1.28-1.61-.63-1.61-1.64-3.25-3.03-4.91-1.39-1.66-3.25-3.07-5.58-4.24-2.33-1.16-5.38-1.75-9.15-1.75-5.65 0-10.11 1.48-13.39 4.44-3.27 2.96-5.04 7.8-5.31 14.53-.27 7.71-.27 15.56 0 23.54.27 7 2.08 12.02 5.45 15.07 3.36 3.05 7.87 4.57 13.52 4.57 3.68 0 6.97-.65 9.89-1.95 2.91-1.3 5.22-3.34 6.93-6.12 1.7-2.78 2.56-6.32 2.56-10.63v-3.36h-14.66c-.9 0-1.66-.34-2.29-1.01-.63-.67-.94-1.46-.94-2.35v-8.61c0-.99.31-1.79.94-2.42.63-.63 1.39-.94 2.29-.94h32.96c.99 0 1.79.31 2.42.94.63.63.94 1.44.94 2.42v14.66c0 7.71-1.68 14.31-5.04 19.77-3.36 5.47-8.16 9.66-14.39 12.58s-13.52 4.37-21.86 4.37zm71.48-1.35c-.99 0-1.79-.31-2.42-.94-.63-.63-.94-1.43-.94-2.42v-87.44c0-.99.31-1.79.94-2.42.63-.63 1.43-.94 2.42-.94h60.94c.99 0 1.79.31 2.42.94.63.63.94 1.44.94 2.42v10.76c0 .9-.32 1.66-.94 2.29-.63.63-1.44.94-2.42.94h-43.59v21.12h40.63c.99 0 1.79.32 2.42.94.63.63.94 1.44.94 2.42v9.95c0 .9-.32 1.66-.94 2.29s-1.44.94-2.42.94h-40.63v21.79h44.66c.99 0 1.79.32 2.42.94.63.63.94 1.44.94 2.42v10.63c0 .99-.32 1.8-.94 2.42s-1.44.94-2.42.94h-62.02zm95.15 0c-.99 0-1.79-.31-2.42-.94-.63-.63-.94-1.43-.94-2.42v-87.44c0-.99.31-1.79.94-2.42.63-.63 1.43-.94 2.42-.94h12.24c1.34 0 2.33.31 2.96.94.63.63 1.03 1.12 1.21 1.48l35.92 56.1v-55.15c0-.99.31-1.79.94-2.42.63-.63 1.39-.94 2.29-.94h13.72c.99 0 1.79.31 2.42.94.63.63.94 1.44.94 2.42v87.44c0 .9-.32 1.68-.94 2.35-.63.67-1.44 1.01-2.42 1.01h-12.38c-1.35 0-2.31-.34-2.89-1.01a29.53 29.53 0 00-1.28-1.41l-35.78-54.35v53.41c0 .99-.32 1.8-.94 2.42s-1.44.94-2.42.94h-13.59zm106.31 0c-.99 0-1.79-.31-2.42-.94-.63-.63-.94-1.43-.94-2.42v-87.44c0-.99.31-1.79.94-2.42.63-.63 1.43-.94 2.42-.94h60.94c.99 0 1.79.31 2.42.94.63.63.94 1.44.94 2.42v10.76c0 .9-.32 1.66-.94 2.29-.63.63-1.44.94-2.42.94h-43.59v21.12h40.63c.99 0 1.79.32 2.42.94.63.63.94 1.44.94 2.42v9.95c0 .9-.32 1.66-.94 2.29s-1.44.94-2.42.94h-40.63v21.79h44.66c.99 0 1.79.32 2.42.94.63.63.94 1.44.94 2.42v10.63c0 .99-.32 1.8-.94 2.42s-1.44.94-2.42.94h-62.02zm95.16 0c-.99 0-1.79-.31-2.42-.94-.63-.63-.94-1.43-.94-2.42v-87.44c0-.99.31-1.79.94-2.42.63-.63 1.43-.94 2.42-.94H1043c11.21 0 20.04 2.58 26.5 7.73 6.46 5.16 9.69 12.58 9.69 22.26 0 6.55-1.57 12.02-4.71 16.41-3.14 4.4-7.35 7.67-12.65 9.82l18.97 33.63c.27.54.4 1.03.4 1.48 0 .72-.27 1.37-.81 1.95-.54.58-1.21.87-2.02.87h-14.93c-1.61 0-2.82-.42-3.63-1.28-.81-.85-1.39-1.64-1.75-2.35l-16.41-30.81h-16.28v31.07c0 .99-.32 1.8-.94 2.42s-1.44.94-2.42.94h-14.66zm18.03-51.52h17.22c4.93 0 8.59-1.12 10.96-3.36 2.38-2.24 3.56-5.38 3.56-9.42s-1.17-7.22-3.5-9.55c-2.33-2.33-6.01-3.5-11.03-3.5h-17.22V273zm75.24 51.52c-.81 0-1.48-.29-2.02-.87-.54-.58-.81-1.23-.81-1.95 0-.45.04-.85.13-1.21l32.02-86.5c.27-.99.81-1.84 1.61-2.56.81-.72 1.93-1.08 3.36-1.08h17.22c1.43 0 2.56.36 3.36 1.08.81.72 1.35 1.57 1.61 2.56l32.02 86.5c.09.36.13.76.13 1.21 0 .72-.27 1.37-.81 1.95-.54.58-1.21.87-2.02.87h-13.99c-1.35 0-2.33-.31-2.96-.94-.63-.63-1.03-1.21-1.21-1.75l-5.78-15.07h-37.94l-5.78 15.07c-.18.54-.58 1.12-1.21 1.75-.63.63-1.61.94-2.96.94h-13.99zm28.92-35.11h27.85l-13.86-38.74-13.99 38.74zm96.1 35.11c-.99 0-1.79-.31-2.42-.94-.63-.63-.94-1.43-.94-2.42v-72.1h-24.48c-.9 0-1.66-.31-2.29-.94-.63-.63-.94-1.39-.94-2.29v-12.11c0-.99.31-1.79.94-2.42.63-.63 1.39-.94 2.29-.94h70.49c.99 0 1.79.31 2.42.94.63.63.94 1.44.94 2.42v12.11c0 .9-.32 1.66-.94 2.29-.63.63-1.44.94-2.42.94h-24.35v72.1c0 .99-.32 1.8-.94 2.42s-1.44.94-2.42.94h-14.93zm72.68 0c-.99 0-1.79-.31-2.42-.94-.63-.63-.94-1.43-.94-2.42v-87.44c0-.99.31-1.79.94-2.42.63-.63 1.43-.94 2.42-.94h60.94c.99 0 1.79.31 2.42.94.63.63.94 1.44.94 2.42v10.76c0 .9-.32 1.66-.94 2.29-.63.63-1.44.94-2.42.94h-43.59v21.12h40.63c.99 0 1.79.32 2.42.94.63.63.94 1.44.94 2.42v9.95c0 .9-.32 1.66-.94 2.29s-1.44.94-2.42.94h-40.63v21.79h44.66c.99 0 1.79.32 2.42.94.63.63.94 1.44.94 2.42v10.63c0 .99-.32 1.8-.94 2.42s-1.44.94-2.42.94h-62.02zm95.16 0c-.99 0-1.79-.31-2.42-.94-.63-.63-.94-1.43-.94-2.42v-87.44c0-.99.31-1.79.94-2.42.63-.63 1.43-.94 2.42-.94h33.77c8.97 0 16.46 1.41 22.46 4.24 6.01 2.83 10.6 6.95 13.79 12.38 3.18 5.43 4.86 12.13 5.04 20.11.09 3.95.13 7.4.13 10.36s-.05 6.37-.13 10.22c-.27 8.34-1.93 15.25-4.98 20.72-3.05 5.47-7.53 9.53-13.45 12.17-5.92 2.65-13.32 3.97-22.2 3.97h-34.44zm18.03-17.35h15.74c4.48 0 8.16-.67 11.03-2.02 2.87-1.35 5-3.47 6.39-6.39 1.39-2.91 2.13-6.7 2.22-11.37.09-2.6.16-4.93.2-7 .04-2.06.04-4.12 0-6.19-.05-2.06-.11-4.35-.2-6.86-.18-6.73-1.91-11.68-5.18-14.86-3.27-3.18-8.32-4.78-15.13-4.78h-15.07v59.46z",
1461
+ fill: "var(--ai-indicator-letter-color, #fff)"
1462
+ })));
1463
+
1464
+ function _extends$2() {
1465
+ _extends$2 = Object.assign ? Object.assign.bind() : function (target) {
1466
+ for (var i = 1; i < arguments.length; i++) {
1467
+ var source = arguments[i];
1468
+ for (var key in source) {
1469
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
1470
+ target[key] = source[key];
1471
+ }
1472
+ }
1473
+ }
1474
+ return target;
1475
+ };
1476
+ return _extends$2.apply(this, arguments);
1477
+ }
1478
+ var aiModified = (({
1479
+ styles = {},
1480
+ ...props
1481
+ }) => /*#__PURE__*/React.createElement("svg", _extends$2({
1482
+ xmlns: "http://www.w3.org/2000/svg",
1483
+ viewBox: "231.11 144.35 1230.56 266.42"
1484
+ }, props), /*#__PURE__*/React.createElement("path", {
1485
+ fill: "currentColor",
1486
+ fillRule: "evenodd",
1487
+ d: "M376.65 410.77h939.48c85.55 0 145.54-59.94 145.54-133.2 0-73.27-59.99-133.21-145.54-133.21H381.65c-85.55 0-150.54 59.94-150.54 133.2 0 73.26 64.99 133.2 150.54 133.2"
1488
+ }), /*#__PURE__*/React.createElement("path", {
1489
+ d: "M626.46 325.63c-.92 0-1.72-.32-2.4-.96-.69-.64-1.03-1.46-1.03-2.47v-89.25c0-1.01.34-1.83 1.03-2.47.69-.64 1.49-.96 2.4-.96h12.77c1.37 0 2.4.37 3.09 1.1.69.73 1.17 1.28 1.44 1.65l25.27 46.55 25.54-46.55c.18-.36.62-.91 1.3-1.65.69-.73 1.72-1.1 3.09-1.1h12.77c1.01 0 1.83.32 2.47.96.64.64.96 1.47.96 2.47v89.25c0 1.01-.32 1.83-.96 2.47s-1.47.96-2.47.96h-14.01c-.92 0-1.69-.32-2.33-.96-.64-.64-.96-1.46-.96-2.47v-55.48l-17.44 32.68c-.46.82-1.05 1.56-1.79 2.2-.73.64-1.69.96-2.88.96h-6.45c-1.19 0-2.15-.32-2.88-.96a8.203 8.203 0 01-1.79-2.2l-17.44-32.68v55.48c0 1.01-.32 1.83-.96 2.47-.64.64-1.42.96-2.33.96h-14.01zM784.28 327c-8.33 0-15.52-1.37-21.56-4.12-6.04-2.75-10.76-6.89-14.14-12.43-3.39-5.54-5.22-12.52-5.49-20.94-.09-3.94-.14-7.85-.14-11.74s.04-7.85.14-11.88c.27-8.24 2.13-15.17 5.56-20.8 3.43-5.63 8.19-9.86 14.28-12.7s13.2-4.26 21.35-4.26 15.13 1.42 21.21 4.26c6.09 2.84 10.87 7.07 14.35 12.7 3.48 5.63 5.31 12.56 5.49 20.8.18 4.03.28 7.99.28 11.88s-.09 7.81-.28 11.74c-.27 8.42-2.11 15.4-5.49 20.94-3.39 5.54-8.1 9.68-14.14 12.43-6.04 2.75-13.18 4.12-21.42 4.12zm0-17.71c5.31 0 9.68-1.62 13.11-4.88 3.43-3.25 5.24-8.44 5.42-15.58.18-4.03.27-7.8.27-11.33s-.09-7.25-.27-11.19c-.09-4.76-.96-8.65-2.61-11.67-1.65-3.02-3.82-5.24-6.52-6.66-2.7-1.42-5.84-2.13-9.41-2.13s-6.73.71-9.47 2.13c-2.75 1.42-4.92 3.64-6.52 6.66-1.6 3.02-2.5 6.91-2.68 11.67-.09 3.94-.14 7.67-.14 11.19s.04 7.3.14 11.33c.27 7.14 2.1 12.34 5.49 15.58 3.39 3.25 7.78 4.88 13.18 4.88zm72.41 16.34c-1.01 0-1.83-.32-2.47-.96-.64-.64-.96-1.46-.96-2.47v-89.25c0-1.01.32-1.83.96-2.47.64-.64 1.46-.96 2.47-.96h34.47c9.15 0 16.8 1.44 22.93 4.33 6.13 2.88 10.82 7.1 14.07 12.63 3.25 5.54 4.96 12.38 5.15 20.53.09 4.03.14 7.55.14 10.57s-.05 6.5-.14 10.44c-.27 8.51-1.97 15.56-5.08 21.15-3.11 5.58-7.69 9.73-13.73 12.43-6.04 2.7-13.59 4.05-22.66 4.05h-35.15zm18.4-17.71h16.07c4.58 0 8.33-.69 11.26-2.06 2.93-1.37 5.1-3.55 6.52-6.52 1.42-2.97 2.17-6.84 2.27-11.6.09-2.65.16-5.03.21-7.14.04-2.1.04-4.21 0-6.32-.05-2.1-.12-4.44-.21-7-.18-6.87-1.95-11.92-5.29-15.17s-8.49-4.87-15.45-4.87h-15.38v60.69zm89.58 17.71c-1.01 0-1.83-.32-2.47-.96-.64-.64-.96-1.46-.96-2.47v-89.25c0-1.01.32-1.83.96-2.47.64-.64 1.46-.96 2.47-.96h15.52c1.01 0 1.83.32 2.47.96.64.64.96 1.47.96 2.47v89.25c0 1.01-.32 1.83-.96 2.47-.64.64-1.46.96-2.47.96h-15.52zm53.33 0c-1.01 0-1.83-.32-2.47-.96-.64-.64-.96-1.46-.96-2.47v-89.25c0-1.01.32-1.83.96-2.47.64-.64 1.46-.96 2.47-.96h61.24c1.01 0 1.83.32 2.47.96.64.64.96 1.47.96 2.47v11.67c0 1.01-.32 1.83-.96 2.47-.64.64-1.47.96-2.47.96h-43.25v23.21h40.51c1.01 0 1.83.32 2.47.96.64.64.96 1.47.96 2.47v11.67c0 .92-.32 1.69-.96 2.33-.64.64-1.46.96-2.47.96h-40.51v32.54c0 1.01-.32 1.83-.96 2.47-.64.64-1.46.96-2.47.96H1018zm94.25 0c-1.01 0-1.83-.32-2.47-.96-.64-.64-.96-1.46-.96-2.47v-89.25c0-1.01.32-1.83.96-2.47.64-.64 1.46-.96 2.47-.96h15.52c1.01 0 1.83.32 2.47.96.64.64.96 1.47.96 2.47v89.25c0 1.01-.32 1.83-.96 2.47-.64.64-1.46.96-2.47.96h-15.52zm53.32 0c-1.01 0-1.83-.32-2.47-.96-.64-.64-.96-1.46-.96-2.47v-89.25c0-1.01.32-1.83.96-2.47.64-.64 1.46-.96 2.47-.96h62.2c1.01 0 1.83.32 2.47.96.64.64.96 1.47.96 2.47v10.99c0 .92-.32 1.69-.96 2.33-.64.64-1.47.96-2.47.96h-44.49v21.56h41.47c1.01 0 1.83.32 2.47.96.64.64.96 1.47.96 2.47v10.16c0 .92-.32 1.7-.96 2.33-.64.64-1.47.96-2.47.96h-41.47v22.25h45.59c1.01 0 1.83.32 2.47.96.64.64.96 1.47.96 2.47v10.85c0 1.01-.32 1.83-.96 2.47-.64.64-1.47.96-2.47.96h-63.3zm97.13 0c-1.01 0-1.83-.32-2.47-.96-.64-.64-.96-1.46-.96-2.47v-89.25c0-1.01.32-1.83.96-2.47.64-.64 1.46-.96 2.47-.96h34.47c9.15 0 16.8 1.44 22.93 4.33 6.13 2.88 10.82 7.1 14.07 12.63 3.25 5.54 4.96 12.38 5.15 20.53.09 4.03.14 7.55.14 10.57s-.05 6.5-.14 10.44c-.27 8.51-1.97 15.56-5.08 21.15-3.11 5.58-7.69 9.73-13.73 12.43-6.04 2.7-13.59 4.05-22.66 4.05h-35.15zm18.4-17.71h16.07c4.58 0 8.33-.69 11.26-2.06 2.93-1.37 5.1-3.55 6.52-6.52 1.42-2.97 2.17-6.84 2.27-11.6.09-2.65.16-5.03.21-7.14.04-2.1.04-4.21 0-6.32-.05-2.1-.12-4.44-.21-7-.18-6.87-1.95-11.92-5.29-15.17s-8.49-4.87-15.45-4.87h-15.38v60.69zM349.9 341c-.98 0-1.87-.4-2.66-1.19-.8-.8-1.19-1.68-1.19-2.66 0-.61.06-1.16.18-1.65l43.18-117.96c.37-1.35 1.13-2.54 2.3-3.58 1.16-1.04 2.78-1.56 4.87-1.56h27.19c2.08 0 3.7.52 4.87 1.56 1.16 1.04 1.93 2.24 2.3 3.58l42.99 117.96c.24.49.37 1.04.37 1.65 0 .98-.4 1.87-1.19 2.66-.8.8-1.75 1.19-2.85 1.19h-22.6c-1.84 0-3.22-.46-4.13-1.38s-1.5-1.75-1.75-2.48l-7.17-18.74h-49.06l-6.98 18.74c-.25.73-.8 1.56-1.65 2.48-.86.92-2.33 1.38-4.41 1.38h-22.6zm43.18-49.06h34.18l-17.27-48.51-16.9 48.51zM493.39 341c-1.35 0-2.45-.43-3.31-1.29-.86-.86-1.29-1.96-1.29-3.31V216.97c0-1.35.43-2.45 1.29-3.31s1.96-1.29 3.31-1.29h24.62c1.35 0 2.45.43 3.31 1.29.86.86 1.29 1.96 1.29 3.31V336.4c0 1.35-.43 2.45-1.29 3.31s-1.96 1.29-3.31 1.29h-24.62z",
1490
+ fill: "var(--ai-indicator-letter-color, #fff)"
1491
+ })));
1492
+
1493
+ var styles$4 = {"icon":"AiIndicatorIcon-module_icon__1g9xt"};
1494
+
1495
+ const icons = {
1496
+ ai,
1497
+ ai_generated: aiGenerated,
1498
+ ai_modified: aiModified
1499
+ };
1500
+
1501
+ /**
1502
+ * Render one of the EU icons for labelling AI generated content.
1503
+ *
1504
+ * @param {Object} props
1505
+ * @param {string} props.kind - Either: ai, ai_generated, ai_modified.
1506
+ * @param {string} [props.className]
1507
+ */
1508
+ function AiIndicatorIcon({
1509
+ kind,
1510
+ className
1511
+ }) {
1512
+ const aiIndicatorLabel = useAiIndicatorLabel();
1513
+ const Icon = icons[kind];
1514
+ if (!Icon) {
1515
+ return null;
1516
+ }
1517
+ return /*#__PURE__*/React.createElement(Icon, {
1518
+ className: classNames(styles$4.icon, className),
1519
+ role: "img",
1520
+ "aria-label": aiIndicatorLabel(kind)
1521
+ });
1522
+ }
1523
+ function useAiIndicatorLabel() {
1524
+ const {
1525
+ t
1526
+ } = useI18n();
1527
+ return kind => t(kind, {
1528
+ scope: 'pageflow_scrolled.public.ai_indicators'
1529
+ });
1530
+ }
1531
+
1532
+ function isBlank(html) {
1533
+ return !!stripTags(html).match(/^\s*$/);
1534
+ }
1535
+ function presence(html) {
1536
+ return isBlank(html) ? null : html;
1537
+ }
1538
+ function isBlankEditableTextValue(value) {
1539
+ var _value$0$children$;
1540
+ return !value || value.length === 0 || value.length === 1 && value[0].children.length <= 1 && !((_value$0$children$ = value[0].children[0]) === null || _value$0$children$ === void 0 ? void 0 : _value$0$children$.text);
1541
+ }
1542
+
1543
+ const Widget = extensible('Widget', function Widget({
1544
+ role,
1545
+ props,
1546
+ children,
1547
+ renderFallback
1548
+ }) {
1549
+ const widget = useWidget({
1550
+ role
1551
+ });
1552
+ if (!widget) {
1553
+ return renderFallback ? renderFallback({
1554
+ ...props,
1555
+ children
1556
+ }) : null;
1557
+ }
1558
+ const Component = api.widgetTypes.getComponent(widget.typeName);
1559
+ return /*#__PURE__*/React.createElement(Component, Object.assign({
1560
+ configuration: widget.configuration
1561
+ }, props, {
1562
+ children: children
1563
+ }));
1564
+ });
1565
+
1566
+ var styles$5 = {"list":"InlineFileRights-module_list__2OuO5","aiIcon":"InlineFileRights-module_aiIcon__2QpAh"};
1567
+
1568
+ function InlineFileRights({
1569
+ items = [],
1570
+ context = 'standAlone',
1571
+ position,
1572
+ playerControlsFadedOut,
1573
+ playerControlsStandAlone,
1574
+ configuration = {}
1575
+ }) {
1576
+ const filteredItems = items.filter(item => item.file && (hasRights(item.file) || hasAiIndicator(item.file)));
1577
+ if (!filteredItems.length) {
1578
+ return null;
1579
+ }
1580
+ return /*#__PURE__*/React.createElement(Widget, {
1581
+ role: "inlineFileRights",
1582
+ props: {
1583
+ context,
1584
+ position,
1585
+ playerControlsFadedOut,
1586
+ playerControlsStandAlone,
1587
+ configuration,
1588
+ hasRights: filteredItems.some(({
1589
+ file
1590
+ }) => hasRights(file)),
1591
+ hasAiIndicators: filteredItems.some(({
1592
+ file
1593
+ }) => hasAiIndicator(file))
1594
+ }
1595
+ }, /*#__PURE__*/React.createElement("ul", {
1596
+ className: styles$5.list
1597
+ }, filteredItems.map(({
1598
+ label,
1599
+ file
1600
+ }) => /*#__PURE__*/React.createElement(Item, {
1601
+ key: `${label}-${file.id}`,
1602
+ label: label,
1603
+ file: file
1604
+ }))));
1605
+ }
1606
+ function Item({
1607
+ label,
1608
+ file
1609
+ }) {
1610
+ const {
1611
+ t
1612
+ } = useI18n();
1613
+ return /*#__PURE__*/React.createElement("li", {
1614
+ "data-rights": hasRights(file) ? '' : undefined
1615
+ }, (label || hasRights(file)) && /*#__PURE__*/React.createElement("span", {
1616
+ "data-part": "rights"
1617
+ }, label && /*#__PURE__*/React.createElement("span", {
1618
+ "data-label": true
1619
+ }, t(label, {
1620
+ scope: 'pageflow_scrolled.public.inline_file_rights_labels'
1621
+ }), ": "), hasRights(file) && renderRights(file), hasRights(file) && renderLicense(file)), hasAiIndicator(file) && ' ', renderAiIndicator(file));
1622
+ }
1623
+ function hasRights(file) {
1624
+ return file.inlineRights && !isBlank(file.rights);
1625
+ }
1626
+ function hasAiIndicator(file) {
1627
+ return !!file.configuration.ai_indicator;
1628
+ }
1629
+ function renderRights(file) {
1630
+ if (isBlank(file.configuration.source_url)) {
1631
+ return file.rights;
1632
+ } else {
1633
+ return /*#__PURE__*/React.createElement("a", {
1634
+ href: file.configuration.source_url,
1635
+ target: "_blank",
1636
+ rel: "noopener noreferrer"
1637
+ }, file.rights);
1638
+ }
1639
+ }
1640
+ function renderLicense(file) {
1641
+ if (!file.license) {
1642
+ return null;
1643
+ }
1644
+ return /*#__PURE__*/React.createElement(React.Fragment, null, ' ', "(", /*#__PURE__*/React.createElement("a", {
1645
+ href: file.license.url,
1646
+ target: "_blank",
1647
+ rel: "noopener noreferrer"
1648
+ }, file.license.name), ")");
1649
+ }
1650
+ function renderAiIndicator(file) {
1651
+ if (!hasAiIndicator(file)) {
1652
+ return null;
1653
+ }
1654
+ return /*#__PURE__*/React.createElement("span", {
1655
+ "data-part": "ai-indicator"
1656
+ }, /*#__PURE__*/React.createElement(AiIndicatorIcon, {
1657
+ kind: file.configuration.ai_indicator,
1658
+ className: styles$5.aiIcon
1659
+ }), !isBlank(file.configuration.ai_indicator_text) && ` ${file.configuration.ai_indicator_text}`);
1660
+ }
1661
+
1662
+ var styles$6 = {"fade-duration":"0.5s","wrapper":"SectionInlineFileRights-module_wrapper__1l6rr","fade":"SectionInlineFileRights-module_fade__1Snfk","inactive":"SectionInlineFileRights-module_inactive__1VpQh"};
1663
+
1664
+ function SectionInlineFileRights({
1665
+ section,
1666
+ state,
1667
+ backdrop,
1668
+ atmoAudioFile
1669
+ }) {
1670
+ var _section$nextSection, _section$nextSection$;
1671
+ return /*#__PURE__*/React.createElement("div", {
1672
+ className: classNames(styles$6.wrapper, {
1673
+ [styles$6.fade]: (_section$nextSection = section.nextSection) === null || _section$nextSection === void 0 ? void 0 : (_section$nextSection$ = _section$nextSection.transition) === null || _section$nextSection$ === void 0 ? void 0 : _section$nextSection$.startsWith('fade'),
1674
+ [styles$6.inactive]: state !== 'active'
1675
+ })
1676
+ }, /*#__PURE__*/React.createElement(InlineFileRights, {
1677
+ context: "section",
1678
+ items: [{
1679
+ label: 'image',
1680
+ file: backdrop.image
1681
+ }, {
1682
+ label: 'video',
1683
+ file: backdrop.video
1684
+ }, {
1685
+ label: 'atmo',
1686
+ file: atmoAudioFile
1687
+ }]
1688
+ }));
1689
+ }
1690
+
1691
+ var breakpoints = {"breakpoint-sm":"(min-width: 640px)","breakpoint-md":"(min-width: 768px)","breakpoint-lg":"(min-width: 1024px)","breakpoint-xl":"(min-width: 1280px)","breakpoint-below-sm":"(max-width: 639px)","breakpoint-below-md":"(max-width: 767px)","breakpoint-below-lg":"(max-width: 1023px)","breakpoint-below-xl":"(max-width: 1279px)"};
1692
+
1693
+ const PhoneLayoutContext = createContext(false);
1694
+ function PhoneLayoutProvider({
1695
+ children
1696
+ }) {
1697
+ const phoneLayout = useMediaQuery(breakpoints['breakpoint-below-sm']);
1698
+ return /*#__PURE__*/React.createElement(PhoneLayoutContext.Provider, {
1699
+ value: phoneLayout
1700
+ }, children);
1701
+ }
1702
+ function usePhoneLayout() {
1703
+ return useContext(PhoneLayoutContext);
1704
+ }
1705
+
1706
+ function prefersReducedMotion() {
1707
+ return window.matchMedia('(prefers-reduced-motion)').matches;
1708
+ }
1709
+
1710
+ const SectionViewTimelineContext = React.createContext();
1711
+ function SectionViewTimelineProvider({
1712
+ backdrop,
1713
+ children
1714
+ }) {
1715
+ var _backdrop$effects;
1716
+ const [timeline, setTimeline] = useState();
1717
+ const ref = useRef();
1718
+ const isNeeded = backdrop === null || backdrop === void 0 ? void 0 : (_backdrop$effects = backdrop.effects) === null || _backdrop$effects === void 0 ? void 0 : _backdrop$effects.some(effect => effect.name === 'scrollParallax');
1719
+ useEffect(() => {
1720
+ if (!isNeeded || !window.ViewTimeline || prefersReducedMotion()) {
1721
+ return;
1722
+ }
1723
+ setTimeline(new window.ViewTimeline({
1724
+ subject: ref.current
1725
+ }));
1726
+ return () => setTimeline(null);
1727
+ }, [isNeeded]);
1728
+ return /*#__PURE__*/React.createElement("div", {
1729
+ ref: ref
1730
+ }, /*#__PURE__*/React.createElement(SectionViewTimelineContext.Provider, {
1731
+ value: timeline
1732
+ }, children));
1733
+ }
1734
+ function useSectionViewTimeline() {
1735
+ return useContext(SectionViewTimelineContext);
1736
+ }
1737
+
1738
+ const SelectableWidget = extensible('SelectableWidget', Widget);
1739
+
1740
+ function useSectionPadding(section, {
1741
+ portrait
1742
+ } = {}) {
1743
+ const usePortraitPaddings = section.customPortraitPaddings !== false && portrait;
1744
+ const paddingTop = usePortraitPaddings && section.portraitPaddingTop ? section.portraitPaddingTop : section.paddingTop;
1745
+ const paddingBottom = usePortraitPaddings && section.portraitPaddingBottom ? section.portraitPaddingBottom : section.paddingBottom;
1746
+ const styles = {};
1747
+ if (paddingTop) {
1748
+ styles['--foreground-padding-top'] = `var(--theme-section-padding-top-${paddingTop})`;
1749
+ }
1750
+ if (paddingBottom) {
1751
+ styles['--foreground-padding-bottom'] = `var(--theme-section-padding-bottom-${paddingBottom})`;
1752
+ }
1753
+ return {
1754
+ styles,
1755
+ paddingTop,
1756
+ paddingBottom
1757
+ };
1758
+ }
1759
+
1760
+ var styles$7 = {"probe":"SectionIntersectionObserver-module_probe__1_1UM"};
1761
+
1762
+ const SectionIntersectionObserverContext = createContext([]);
1763
+ function SectionIntersectionObserver({
1764
+ sections,
1765
+ probeClassName,
1766
+ onChange,
1767
+ children
1768
+ }) {
1769
+ const sectionsByIdRef = useRef();
1770
+ const callbackRef = useRef();
1771
+ const [observer, setObserver] = useState(null);
1772
+ useEffect(() => {
1773
+ sectionsByIdRef.current = sections.reduce((result, section) => {
1774
+ result[section.id] = section;
1775
+ return result;
1776
+ }, {});
1777
+ }, [sections]);
1778
+ useEffect(() => {
1779
+ callbackRef.current = onChange;
1780
+ }, [onChange]);
1781
+ useEffect(() => {
1782
+ let visibleSection = null;
1783
+ const newObserver = new IntersectionObserver(entries => {
1784
+ entries.forEach(entry => {
1785
+ const section = sectionsByIdRef.current[entry.target.dataset.id];
1786
+ if (entry.isIntersecting) {
1787
+ visibleSection = section;
1788
+ callbackRef.current(visibleSection);
1789
+ } else if (visibleSection === section) {
1790
+ visibleSection = null;
1791
+ callbackRef.current(visibleSection);
1792
+ }
1793
+ });
1794
+ }, {
1795
+ rootMargin: '0px 0px -100% 0px'
1796
+ });
1797
+ setObserver(newObserver);
1798
+ return () => newObserver.disconnect();
1799
+ }, [sections]);
1800
+ const previousContextValue = useContext(SectionIntersectionObserverContext);
1801
+ const contextValue = useMemo(() => [...previousContextValue, {
1802
+ observer,
1803
+ probeClassName
1804
+ }], [previousContextValue, observer, probeClassName]);
1805
+ return /*#__PURE__*/React.createElement(SectionIntersectionObserverContext.Provider, {
1806
+ value: contextValue
1807
+ }, children);
1808
+ }
1809
+ function SectionIntersectionProbe({
1810
+ section
1811
+ }) {
1812
+ const isStaticPreview = useIsStaticPreview();
1813
+ const observers = useContext(SectionIntersectionObserverContext);
1814
+ const probeRefs = useRef([]);
1815
+ useEffect(() => {
1816
+ if (isStaticPreview) {
1817
+ return;
1818
+ }
1819
+ const elements = probeRefs.current.slice();
1820
+ observers.forEach(({
1821
+ observer
1822
+ }, index) => {
1823
+ if (observer && elements[index]) {
1824
+ observer.observe(elements[index]);
1825
+ }
1826
+ });
1827
+ return () => {
1828
+ observers.forEach(({
1829
+ observer
1830
+ }, index) => {
1831
+ if (observer && elements[index]) {
1832
+ observer.unobserve(elements[index]);
1833
+ }
1834
+ });
1835
+ };
1836
+ }, [observers, isStaticPreview]);
1837
+ return observers.map(({
1838
+ probeClassName
1839
+ }, index) => /*#__PURE__*/React.createElement("div", {
1840
+ ref: el => probeRefs.current[index] = el,
1841
+ key: index,
1842
+ className: classNames(styles$7.probe, probeClassName),
1843
+ "data-id": section.id
1844
+ }));
1845
+ }
1846
+
1847
+ function NoOpShadow(props) {
1848
+ return /*#__PURE__*/React.createElement("div", null, props.children);
1849
+ }
1850
+
1851
+ var styles$8 = {"root":"Fullscreen-module_root__1N3CI"};
1852
+
1853
+ const DimensionContext = React.createContext({});
1854
+ function useFullscreenDimensions() {
1855
+ return useContext(DimensionContext);
1856
+ }
1857
+ function FullscreenDimensionProvider({
1858
+ width,
1859
+ height,
1860
+ children
1861
+ }) {
1862
+ const value = useMemo(() => ({
1863
+ width,
1864
+ height
1865
+ }), [width, height]);
1866
+ return /*#__PURE__*/React.createElement(DimensionContext.Provider, {
1867
+ value: value
1868
+ }, children);
1869
+ }
1870
+ var Fullscreen = React.forwardRef(function Fullscreen(props, ref) {
1871
+ const {
1872
+ height
1873
+ } = useFullscreenDimensions();
1874
+ return /*#__PURE__*/React.createElement("div", {
1875
+ ref: ref,
1876
+ className: styles$8.root,
1877
+ style: {
1878
+ height
1879
+ }
1880
+ }, props.children);
1881
+ });
1882
+
1883
+ var styles$9 = {"static":"GradientShadow-module_static__rXNpZ","dynamic":"GradientShadow-module_dynamic__2v2JU","align-right":"GradientShadow-module_align-right__3iXZs","dark":"GradientShadow-module_dark__1YuV5","align-left":"GradientShadow-module_align-left__3qcNM","align-center":"GradientShadow-module_align-center__2C7cl","align-centerRagged":"GradientShadow-module_align-centerRagged__2-iv8","light":"GradientShadow-module_light__Vn92v","shadow":"GradientShadow-module_shadow__2UiDH"};
1884
+
1885
+ function GradientShadow(props) {
1886
+ // Hide static shadow if motif area intersects with content area.
1887
+ const staticShadowOpacity = props.motifAreaState.isContentPadded ? 0 : props.staticShadowOpacity;
1888
+
1889
+ // If motif area intersects with content area horizontally, fade in
1890
+ // shadow soon as the content has been scrolled far enough to start
1891
+ // intersecting with the motif area vertically.
1892
+ const opacityFactor =
1893
+ // Make shadow reach full opacity when content has been scrolled
1894
+ // up half way across the motif area.
1895
+ roundToFirstDecimalPlace(Math.min(1, props.motifAreaState.intersectionRatioY * 2));
1896
+ return /*#__PURE__*/React.createElement("div", {
1897
+ className: classNames(styles$9[`align-${props.align}`], props.inverted ? styles$9.light : styles$9.dark),
1898
+ style: props.overlayStyle
1899
+ }, /*#__PURE__*/React.createElement("div", {
1900
+ className: styles$9.dynamic,
1901
+ style: {
1902
+ opacity: props.dynamicShadowOpacity * opacityFactor
1903
+ }
1904
+ }, /*#__PURE__*/React.createElement(Fullscreen, null)), /*#__PURE__*/React.createElement("div", {
1905
+ className: styles$9.static,
1906
+ style: {
1907
+ opacity: staticShadowOpacity
1908
+ }
1909
+ }, /*#__PURE__*/React.createElement(Fullscreen, null)), props.children);
1910
+ }
1911
+ GradientShadow.defaultProps = {
1912
+ opacity: 0.7,
1913
+ align: 'left'
1914
+ };
1915
+ function roundToFirstDecimalPlace(value) {
1916
+ return Math.round(value * 10) / 10;
1917
+ }
1918
+
1919
+ var styles$a = {"wrapper":"SplitShadow-module_wrapper__2yZUo","overlay":"SplitShadow-module_overlay__1LVuY","align-left":"SplitShadow-module_align-left__22AzL","align-right":"SplitShadow-module_align-right__F-YIn","align-center":"SplitShadow-module_align-center__3PKJV","align-centerRagged":"SplitShadow-module_align-centerRagged__3YTll","dark":"SplitShadow-module_dark__3BOPU","light":"SplitShadow-module_light__jF6Hb"};
1920
+
1921
+ function SplitShadow(props) {
1922
+ if (props.motifAreaState.isContentPadded) {
1923
+ return /*#__PURE__*/React.createElement("div", null, props.children);
1924
+ }
1925
+ return /*#__PURE__*/React.createElement("div", {
1926
+ className: classNames(styles$a.wrapper, styles$a[`align-${props.align}`], props.inverted ? styles$a.light : styles$a.dark)
1927
+ }, /*#__PURE__*/React.createElement("div", {
1928
+ className: styles$a.overlay,
1929
+ style: props.overlayStyle
1930
+ }, /*#__PURE__*/React.createElement(Fullscreen, null)), props.children);
1931
+ }
1932
+
1933
+ var styles$b = {"start":"InvisibleBoxWrapper-module_start__F1nZ7","end":"InvisibleBoxWrapper-module_end__nphD-"};
1934
+
1935
+ var boundaryMarginStyles = {"noTopMargin":"BoxBoundaryMargin-module_noTopMargin__2jB2d","noBottomMargin":"BoxBoundaryMargin-module_noBottomMargin__22VC_"};
1936
+
1937
+ function InvisibleBoxWrapper({
1938
+ position,
1939
+ width,
1940
+ openStart,
1941
+ openEnd,
1942
+ atSectionStart,
1943
+ atSectionEnd,
1944
+ children
1945
+ }) {
1946
+ const full = width === widths.full;
1947
+ return /*#__PURE__*/React.createElement(TrimDefaultMarginTop, {
1948
+ value: atSectionStart
1949
+ }, /*#__PURE__*/React.createElement("div", {
1950
+ className: classNames({
1951
+ [styles$b.start]: !openStart && !full,
1952
+ [styles$b.end]: !openEnd && !full,
1953
+ [boundaryMarginStyles.noTopMargin]: atSectionStart,
1954
+ [boundaryMarginStyles.noBottomMargin]: atSectionEnd
1955
+ })
1956
+ }, children));
1957
+ }
1958
+
1959
+ var styles$c = {"wrapper":"GradientBox-module_wrapper__1Jj7N","content":"GradientBox-module_content__96lDk","shadow":"GradientBox-module_shadow__2XilX","gradient":"GradientBox-module_gradient__31tJ-","long":"GradientBox-module_long__10s6v","root":"GradientBox-module_root__8Xn9W","withShadow":"GradientBox-module_withShadow__3mhPR","shadowDark":"GradientBox-module_shadowDark__3Tv0L","shadowLight":"GradientBox-module_shadowLight__Bieg6"};
1960
+
1961
+ function GradientBox(props) {
1962
+ return /*#__PURE__*/React.createElement("div", {
1963
+ className: classNames(styles$c.root, {
1964
+ [styles$c.gradient]: props.motifAreaState.isContentPadded,
1965
+ [styles$c.long]: props.coverInvisibleNextSection
1966
+ }),
1967
+ style: {
1968
+ ...props.overlayStyle,
1969
+ paddingTop: props.motifAreaState.paddingTop
1970
+ }
1971
+ }, /*#__PURE__*/React.createElement("div", {
1972
+ className: styles$c.wrapper
1973
+ }, /*#__PURE__*/React.createElement("div", {
1974
+ className: classNames(styles$c.shadow, props.inverted ? styles$c.shadowLight : styles$c.shadowDark, props.transitionStyles.boxShadow, props.transitionStyles[`boxShadow-${props.state}`]),
1975
+ style: {
1976
+ top: props.motifAreaState.paddingTop,
1977
+ opacity: props.staticShadowOpacity
1978
+ }
1979
+ }), /*#__PURE__*/React.createElement("div", {
1980
+ className: styles$c.content
1981
+ }, props.children)));
1982
+ }
1983
+
1984
+ var styles$d = {"content":"CardBox-module_content__36v7J","wrapper":"CardBox-module_wrapper__3vnaH"};
1985
+
1986
+ function CardBox(props) {
1987
+ return /*#__PURE__*/React.createElement("div", {
1988
+ className: styles$d.wrapper,
1989
+ style: {
1990
+ paddingTop: props.motifAreaState.paddingTop
1991
+ }
1992
+ }, /*#__PURE__*/React.createElement("div", {
1993
+ className: styles$d.content
1994
+ }, props.children));
1995
+ }
1996
+
1997
+ var styles$e = {"darkContentSurfaceColor":"var(--theme-dark-content-surface-color, #101010)","lightContentSurfaceColor":"var(--theme-light-content-surface-color, #fff)","darkContentTextColor":"var(--theme-dark-content-text-color, #222)","lightContentTextColor":"var(--theme-light-content-text-color, #fff)","darkContentLinkColor":"var(--theme-dark-content-link-color, var(--theme-content-link-color, currentColor))","lightContentLinkColor":"var(--theme-light-content-link-color, var(--theme-content-link-color, currentColor))","card":"CardBoxWrapper-module_card__hvRUa scope-cardsAppearance","cardContent":"CardBoxWrapper-module_cardContent__39rPo","cardBg":"CardBoxWrapper-module_cardBg__154o2","cardStart":"CardBoxWrapper-module_cardStart__2NywG","cardEnd":"CardBoxWrapper-module_cardEnd__x4Ye6","cardEndPadding":"CardBoxWrapper-module_cardEndPadding__3oLd8","cardBgWhite":"CardBoxWrapper-module_cardBgWhite__xXhg7 scope-darkContent","cardBgBlack":"CardBoxWrapper-module_cardBgBlack__Ahp3s scope-lightContent"};
1998
+
1999
+ function CardBoxWrapper(props) {
2000
+ if (outsideBox(props)) {
2001
+ return /*#__PURE__*/React.createElement(TrimDefaultMarginTop, {
2002
+ value: props.atSectionStart
2003
+ }, /*#__PURE__*/React.createElement("div", {
2004
+ className: props.transitionStyles.foregroundOpacity
2005
+ }, props.children));
2006
+ }
2007
+ return /*#__PURE__*/React.createElement("div", {
2008
+ className: className$1(props)
2009
+ }, /*#__PURE__*/React.createElement("div", {
2010
+ className: classNames(styles$e.cardBg, props.transitionStyles.foregroundOpacity),
2011
+ style: props.overlayStyle
2012
+ }), /*#__PURE__*/React.createElement("div", {
2013
+ className: classNames(styles$e.cardContent, props.transitionStyles.foregroundOpacity)
2014
+ }, /*#__PURE__*/React.createElement(BackgroundColorProvider, {
2015
+ invert: true
2016
+ }, props.children)));
2017
+ }
2018
+ function outsideBox(props) {
2019
+ return props.position === 'sticky' || props.position === 'inline' && props.width > widths.md || props.customMargin;
2020
+ }
2021
+ function className$1(props) {
2022
+ return classNames(styles$e.card, props.inverted ? styles$e.cardBgBlack : styles$e.cardBgWhite, {
2023
+ [styles$e.cardStart]: !props.openStart
2024
+ }, {
2025
+ [styles$e.cardEnd]: !props.openEnd
2026
+ }, {
2027
+ [styles$e.cardEndPadding]: !props.openEnd && !props.lastMarginBottom
2028
+ }, {
2029
+ [boundaryMarginStyles.noTopMargin]: props.atSectionStart
2030
+ }, {
2031
+ [boundaryMarginStyles.noBottomMargin]: props.atSectionEnd
2032
+ });
2033
+ }
2034
+
2035
+ var styles$f = {"wrapper":"SplitBox-module_wrapper__36ofK","content":"SplitBox-module_content__2jasQ","overlay":"SplitBox-module_overlay__1XXB3","overlayDark":"SplitBox-module_overlayDark__hTqkR SplitBox-module_overlay__1XXB3","overlayLight":"SplitBox-module_overlayLight__3nAl1 SplitBox-module_overlay__1XXB3","long":"SplitBox-module_long__Zw0dc"};
2036
+
2037
+ function SplitBox(props) {
2038
+ return /*#__PURE__*/React.createElement("div", {
2039
+ className: styles$f.wrapper,
2040
+ style: {
2041
+ paddingTop: props.motifAreaState.paddingTop
2042
+ }
2043
+ }, props.motifAreaState.isContentPadded && /*#__PURE__*/React.createElement("div", {
2044
+ className: classNames(props.inverted ? styles$f.overlayLight : styles$f.overlayDark, props.transitionStyles.foregroundOpacity, {
2045
+ [styles$f.long]: props.coverInvisibleNextSection
2046
+ }, props.transitionStyles.boxShadow, props.transitionStyles[`boxShadow-${props.state}`]),
2047
+ style: {
2048
+ top: props.motifAreaState.paddingTop,
2049
+ ...props.overlayStyle
2050
+ }
2051
+ }), /*#__PURE__*/React.createElement("div", {
2052
+ className: classNames(styles$f.content, props.transitionStyles.foregroundOpacity)
2053
+ }, props.children));
2054
+ }
2055
+
2056
+ function isTranslucentColor(color) {
2057
+ return !!color && color.length > 7 && color.slice(-2).toLowerCase() !== 'ff';
2058
+ }
2059
+
2060
+ function useAppearanceOverlayStyle(section) {
2061
+ const {
2062
+ appearance,
2063
+ cardSurfaceColor,
2064
+ splitOverlayColor,
2065
+ shadowColor,
2066
+ overlayBackdropBlur
2067
+ } = section;
2068
+ return useMemo(() => {
2069
+ if (appearance === 'cards') {
2070
+ return overlayStyle(cardSurfaceColor, overlayBackdropBlur);
2071
+ } else if (appearance === 'split') {
2072
+ return overlayStyle(splitOverlayColor, overlayBackdropBlur, true);
2073
+ } else if (!appearance || appearance === 'shadow') {
2074
+ return shadowColor ? {
2075
+ '--shadow-color': shadowColor
2076
+ } : {};
2077
+ }
2078
+ return {};
2079
+ }, [appearance, cardSurfaceColor, splitOverlayColor, shadowColor, overlayBackdropBlur]);
2080
+ }
2081
+ function overlayStyle(color, backdropBlur, blurByDefault) {
2082
+ const style = {};
2083
+ if (color) {
2084
+ style.backgroundColor = color;
2085
+ }
2086
+ const blur = resolvedBackdropBlur(color, backdropBlur, blurByDefault);
2087
+ if (blur > 0) {
2088
+ style.backdropFilter = `blur(${blur / 100 * 10}px)`;
2089
+ }
2090
+ return style;
2091
+ }
2092
+ function resolvedBackdropBlur(color, backdropBlur, blurByDefault) {
2093
+ if (blurByDefault) {
2094
+ if (color && !isTranslucentColor(color)) {
2095
+ return 0;
2096
+ }
2097
+ } else if (!isTranslucentColor(color)) {
2098
+ return 0;
2099
+ }
2100
+ return backdropBlur !== null && backdropBlur !== void 0 ? backdropBlur : 100;
2101
+ }
2102
+
2103
+ const components = {
2104
+ shadow: {
2105
+ Shadow: GradientShadow,
2106
+ Box: GradientBox,
2107
+ BoxWrapper: InvisibleBoxWrapper
2108
+ },
2109
+ transparent: {
2110
+ Shadow: NoOpShadow,
2111
+ Box: CardBox,
2112
+ BoxWrapper: InvisibleBoxWrapper
2113
+ },
2114
+ cards: {
2115
+ Shadow: NoOpShadow,
2116
+ Box: CardBox,
2117
+ BoxWrapper: CardBoxWrapper
2118
+ },
2119
+ split: {
2120
+ Shadow: SplitShadow,
2121
+ Box: SplitBox,
2122
+ BoxWrapper: InvisibleBoxWrapper
2123
+ }
2124
+ };
2125
+ const sectionScopeNames = {
2126
+ shadow: 'shadowAppearanceSection',
2127
+ transparent: 'transparentAppearanceSection',
2128
+ cards: 'cardsAppearanceSection',
2129
+ split: 'splitAppearanceSection'
2130
+ };
2131
+ function getAppearanceComponents(appearance) {
2132
+ return components[appearance || 'shadow'];
2133
+ }
2134
+ function getAppearanceSectionScopeName(appearance) {
2135
+ return sectionScopeNames[appearance || 'shadow'];
2136
+ }
2137
+
2138
+ function getSize(el) {
2139
+ if (!el) {
2140
+ return {
2141
+ left: 0,
2142
+ top: 0,
2143
+ width: 0,
2144
+ height: 0,
2145
+ bottom: 0
2146
+ };
2147
+ }
2148
+ return {
2149
+ left: el.offsetLeft,
2150
+ top: el.offsetTop,
2151
+ width: el.offsetWidth,
2152
+ height: el.offsetHeight,
2153
+ bottom: el.offsetParent ? el.offsetParent.offsetHeight - el.offsetTop - el.offsetHeight : 0
2154
+ };
2155
+ }
2156
+ function useDimension() {
2157
+ const [componentSize, setComponentSize] = useState(getSize(null));
2158
+ const [currentNode, setCurrentNode] = useState(null);
2159
+ const measuredRef = useCallback(node => {
2160
+ setCurrentNode(node);
2161
+ setComponentSize(getSize(node));
2162
+ }, []);
2163
+ useEffect(function () {
2164
+ function handleResize() {
2165
+ setComponentSize(getSize(currentNode));
2166
+ }
2167
+ if (!currentNode) {
2168
+ return;
2169
+ }
2170
+ handleResize();
2171
+ window.addEventListener('resize', handleResize);
2172
+ return function () {
2173
+ window.removeEventListener('resize', handleResize);
2174
+ };
2175
+ }, [currentNode]);
2176
+ return [componentSize, measuredRef];
2177
+ }
2178
+
2179
+ var styles$g = {"FillColor":"FillColor-module_FillColor__S1uEG"};
2180
+
2181
+ function FillColor(props) {
2182
+ return /*#__PURE__*/React.createElement("div", {
2183
+ className: styles$g.FillColor,
2184
+ style: {
2185
+ backgroundColor: props.color
2186
+ }
2187
+ }, /*#__PURE__*/React.createElement(Fullscreen, null));
2188
+ }
2189
+
2190
+ /**
2191
+ * Extend image or video file with position/motif area related
2192
+ * properties that are needed to use the file as a section backdrop.
2193
+ *
2194
+ * The added properties are:
2195
+ *
2196
+ * `cropPosition`: Position in percent that can be used as
2197
+ * `background-position` or `object-position` to center the given
2198
+ * motif area in the container.
2199
+ *
2200
+ * `motifAreaOffsetRect`: Pixel position and size of the motif area in
2201
+ * the container assuming the crop position has been applied.
2202
+ *
2203
+ * `motifArea`: Either the passed motif area object or the motif area
2204
+ * from the legacy file configuration if no motif area has been
2205
+ * passed.
2206
+ *
2207
+ * @param {Object} options
2208
+ * @param {Object} options.file - Image or video file obtained via
2209
+ * `useFile`.
2210
+ * @param {Object} options.motifArea - Section specific setting
2211
+ * specifying motif area rect in percent.
2212
+ * @param {Object} options.containerDimension - Width and height in
2213
+ * pixels of the container (normally the backdrop) the file shall be
2214
+ * displayed as background of.
2215
+ *
2216
+ * @private
2217
+ */
2218
+ function useBackgroundFile({
2219
+ file,
2220
+ motifArea,
2221
+ containerDimension,
2222
+ effects
2223
+ }) {
2224
+ if (!file) {
2225
+ return null;
2226
+ }
2227
+
2228
+ // Calculate scale factor required to make the file cover the container:
2229
+
2230
+ const originalRatio = file.width / file.height;
2231
+ const containerRatio = containerDimension.width / containerDimension.height;
2232
+ const scale = containerRatio > originalRatio ? containerDimension.width / file.width : containerDimension.height / file.height;
2233
+
2234
+ // Calculate the pixel size the image will have inside the container:
2235
+
2236
+ const displayFileWidth = file.width * scale;
2237
+ const displayFileHeight = file.height * scale;
2238
+
2239
+ // Calculate the pixel position of the center of the motif area in
2240
+ // the scaled image:
2241
+
2242
+ const motifCenterX = motifArea ? motifArea.left + motifArea.width / 2 : 50;
2243
+ const motifCenterY = motifArea ? motifArea.top + motifArea.height / 2 : 50;
2244
+ const displayMotifCenterX = motifCenterX * displayFileWidth / 100;
2245
+ const displayMotifCenterY = motifCenterY * displayFileHeight / 100;
2246
+
2247
+ // If the x-axis position (inside the image) of the center of the
2248
+ // motif area is smaller than `A = containerDimension.width / 2`, we
2249
+ // need to set the crop position to 0% to ensure that the full width
2250
+ // motif area is visible:
2251
+ //
2252
+ // center of motif area
2253
+ // |
2254
+ // oXXXXXooo...........
2255
+ // |-A-|
2256
+ //
2257
+ // Legend:
2258
+ // o: Part of the image that is visible in the container
2259
+ // .: Part of the image that is clipped
2260
+ // X: Part of the motif area that is visible in the container
2261
+ // x: Part of the motif area that is clipped
2262
+ //
2263
+ // If the x-axis position (inside the image) of the center of the
2264
+ // motif area is greater than
2265
+ // `B = image.width - containerDimension.width / 2`, we need to set the
2266
+ // crop position to 100%:
2267
+ //
2268
+ // ............oooXXXXXo
2269
+ // |-------B-------|
2270
+ //
2271
+ // For positions between A and B we want to linearly shift the crop
2272
+ // position to ensure the center of the motif area is centered in
2273
+ // the container:
2274
+ //
2275
+ // ...ooXXXXXoo.........
2276
+ //
2277
+ // This also applies if the motif area is wider than the container:
2278
+ //
2279
+ // .xxXXXXXXXXXxx.......
2280
+ //
2281
+
2282
+ const Ax = containerDimension.width / 2;
2283
+ const Ay = containerDimension.height / 2;
2284
+ const Bx = displayFileWidth - containerDimension.width / 2;
2285
+ const By = displayFileHeight - containerDimension.height / 2;
2286
+ const cropPosition = {
2287
+ x: Bx - Ax > 0 ? Math.min(100, Math.max(0, (displayMotifCenterX - Ax) / (Bx - Ax) * 100)) : 50,
2288
+ y: By - Ay > 0 ? Math.min(100, Math.max(0, (displayMotifCenterY - Ay) / (By - Ay) * 100)) : 50
2289
+ };
2290
+
2291
+ // Calculate the amount of pixels the image will be shifted
2292
+ // when the crop position is applied:
2293
+
2294
+ const cropLeft = (displayFileWidth - containerDimension.width) * cropPosition.x / 100;
2295
+ const cropTop = (displayFileHeight - containerDimension.height) * cropPosition.y / 100;
2296
+
2297
+ // Calculate the pixel position and dimension of the motif area
2298
+ // relative to the container assuming the crop position has been
2299
+ // applied:
2300
+
2301
+ const motifAreaOffsetRect = motifArea && {
2302
+ top: Math.round(displayFileHeight * motifArea.top / 100 - cropTop),
2303
+ left: Math.round(displayFileWidth * motifArea.left / 100 - cropLeft),
2304
+ width: Math.round(displayFileWidth * motifArea.width / 100),
2305
+ height: Math.round(displayFileHeight * motifArea.height / 100)
2306
+ };
2307
+ return {
2308
+ ...file,
2309
+ cropPosition,
2310
+ motifArea,
2311
+ motifAreaOffsetRect,
2312
+ effects
2313
+ };
2314
+ }
2315
+
2316
+ function useVideoQualitySetting() {
2317
+ const [value, setValue] = useSetting('videoQuality');
2318
+ return [value || 'auto', setValue];
2319
+ }
2320
+
2321
+ browser.feature('dash', () => true);
2322
+ browser.feature('video', () => true);
2323
+ browser.feature('highdef', () => true);
2324
+ function sources(videoFile, {
2325
+ quality = 'auto',
2326
+ adaptiveMinQuality
2327
+ } = {}) {
2328
+ if (typeof window !== 'undefined') {
2329
+ if (!browser.has('video')) {
2330
+ return [];
2331
+ }
2332
+ if (!browser.has('highdef')) {
2333
+ return [{
2334
+ type: 'video/mp4',
2335
+ src: videoFile.urls.high
2336
+ }];
2337
+ }
2338
+ if (!browser.has('dash')) {
2339
+ return [{
2340
+ type: 'video/mp4',
2341
+ src: videoFile.urls['4k'] || videoFile.urls.fullhd || videoFile.urls.high
2342
+ }];
2343
+ }
2344
+ }
2345
+ if (features.isEnabled('force_fullhd_video_quality')) {
2346
+ return [{
2347
+ type: 'video/mp4',
2348
+ src: videoFile.urls.fullhd || videoFile.urls.high
2349
+ }];
2350
+ } else if (quality === 'auto') {
2351
+ let result = [{
2352
+ type: 'application/x-mpegURL',
2353
+ src: getPlaylistSrc(videoFile, 'hls', adaptiveMinQuality)
2354
+ }, {
2355
+ type: 'video/mp4',
2356
+ src: videoFile.urls.high
2357
+ }];
2358
+ if (videoFile.urls['dash-playlist'] && !features.isEnabled('hls_instead_of_dash')) {
2359
+ result = [{
2360
+ type: 'application/dash+xml',
2361
+ src: getPlaylistSrc(videoFile, 'dash', adaptiveMinQuality)
2362
+ }].concat(result);
2363
+ }
2364
+ return result;
2365
+ } else {
2366
+ if (!videoFile.urls[quality]) {
2367
+ quality = 'high';
2368
+ }
2369
+ return [{
2370
+ type: 'video/mp4',
2371
+ src: videoFile.urls[quality]
2372
+ }];
2373
+ }
2374
+ }
2375
+ function getPlaylistSrc(videoFile, format, adaptiveMinQuality) {
2376
+ const key = adaptiveMinQuality ? `${format}-playlist-${adaptiveMinQuality}-and-up` : `${format}-playlist`;
2377
+ const result = videoFile.urls[key];
2378
+ if (!result && adaptiveMinQuality) {
2379
+ return getPlaylistSrc(videoFile, format);
2380
+ }
2381
+ return result;
2382
+ }
2383
+
2384
+ function VideoStructuredData({
2385
+ file
2386
+ }) {
2387
+ const entryMedadata = useEntryMetadata();
2388
+ const data = {
2389
+ '@context': 'http://schema.org',
2390
+ '@type': 'VideoObject',
2391
+ name: file.basename,
2392
+ description: file.configuration.alt,
2393
+ url: ensureProtocol('https', file.urls.high),
2394
+ thumbnailUrl: ensureProtocol('https', file.urls.posterMedium),
2395
+ width: file.width,
2396
+ height: file.height,
2397
+ duration: formatTimeDuration(file.durationInMs),
2398
+ datePublished: entryMedadata.publishedAt,
2399
+ uploadDate: file.createdAt,
2400
+ copyrightHolder: {
2401
+ '@type': 'Organization',
2402
+ name: file.rights
2403
+ }
2404
+ };
2405
+ return /*#__PURE__*/React.createElement(StructuredData, {
2406
+ data: data
2407
+ });
2408
+ }
2409
+
2410
+ /**
2411
+ * Render video file in MediaPlayer.
2412
+ *
2413
+ * @param {Object} props
2414
+ * @param {Object} props.videoFile - Video file obtained via `useFile`.
2415
+ * @param {number} [props.posterImageFile] - Poster image file obtained via `useFile`.
2416
+ * @param {number} [props.defaultTextTrackFileId] - Perma id of default text track file.
2417
+ * @param {string} [props.load] - Control lazy loading. `"auto"` (default), `"poster"` or `"none"`.
2418
+ * @param {String} [props.fit] - `"contain"` (default) or `"cover"`.
2419
+ * @param {String} [props.adaptiveMinQuality] - Pass "high" or "fullhd" to use HLS/Dash playlists
2420
+ * with at least given quality.
2421
+ */
2422
+ function VideoPlayer({
2423
+ videoFile,
2424
+ posterImageFile,
2425
+ adaptiveMinQuality,
2426
+ ...props
2427
+ }) {
2428
+ const [activeQuality] = useVideoQualitySetting();
2429
+ const textTracks = useTextTracks({
2430
+ file: videoFile,
2431
+ defaultTextTrackFilePermaId: props.defaultTextTrackFilePermaId,
2432
+ captionsByDefault: useMediaMuted()
2433
+ });
2434
+ if (videoFile && videoFile.isReady) {
2435
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(MediaPlayer, Object.assign({
2436
+ type: 'video',
2437
+ fit: props.fit,
2438
+ textTracks: textTracks,
2439
+ filePermaId: videoFile.permaId,
2440
+ sources: sources(videoFile, {
2441
+ quality: activeQuality,
2442
+ adaptiveMinQuality
2443
+ }),
2444
+ textTracksInset: true,
2445
+ posterImageUrl: posterImageFile && posterImageFile.isReady ? posterImageFile.urls.large : videoFile.urls.posterLarge,
2446
+ altText: videoFile.configuration.alt,
2447
+ objectPosition: props.fit === 'cover' ? videoFile.cropPosition : undefined,
2448
+ mediaEventsContextData: {
2449
+ fileDisplayName: videoFile.displayName
2450
+ }
2451
+ }, props)), /*#__PURE__*/React.createElement(VideoStructuredData, {
2452
+ file: videoFile
2453
+ }));
2454
+ }
2455
+ return null;
2456
+ }
2457
+ VideoPlayer.defaultProps = {
2458
+ fit: 'contain',
2459
+ controls: true
2460
+ };
2461
+
2462
+ var styles$h = {"root":"MotifArea-module_root__1_ACd","visible":"MotifArea-module_visible__18Kln","corner":"MotifArea-module_corner__3hB5t","topLeft":"MotifArea-module_topLeft__3vHHi","topRight":"MotifArea-module_topRight__2gNmC","bottomLeft":"MotifArea-module_bottomLeft__2qEqb","bottomRight":"MotifArea-module_bottomRight__3OjTb"};
2463
+
2464
+ const MotifAreaVisibilityContext = React.createContext(false);
2465
+ function MotifAreaVisibilityProvider({
2466
+ visible,
2467
+ children
2468
+ }) {
2469
+ return /*#__PURE__*/React.createElement(MotifAreaVisibilityContext.Provider, {
2470
+ value: visible
2471
+ }, children);
2472
+ }
2473
+
2474
+ const MotifArea = function MotifArea(props) {
2475
+ var _props$file;
2476
+ const lastPosition = useRef();
2477
+ const position = ((_props$file = props.file) === null || _props$file === void 0 ? void 0 : _props$file.isReady) && getPosition(props);
2478
+ const visible = useContext(MotifAreaVisibilityContext);
2479
+ const elementRef = useRef();
2480
+ const onUpdate = props.onUpdate;
2481
+ const setElementRef = useCallback(element => {
2482
+ elementRef.current = element;
2483
+ onUpdate(element);
2484
+ }, [elementRef, onUpdate]);
2485
+ useEffect(() => {
2486
+ if (lastPosition.current && position && (lastPosition.current.top !== position.top || lastPosition.current.left !== position.left || lastPosition.current.width !== position.width || lastPosition.current.height !== position.height)) {
2487
+ onUpdate(elementRef.current);
2488
+ }
2489
+ lastPosition.current = position;
2490
+ });
2491
+ if (!position) {
2492
+ return null;
2493
+ }
2494
+ const hasMotifArea = !!props.file.motifAreaOffsetRect;
2495
+ return /*#__PURE__*/React.createElement("div", {
2496
+ ref: setElementRef,
2497
+ className: classNames(styles$h.root, {
2498
+ [styles$h.visible]: visible && hasMotifArea
2499
+ }),
2500
+ style: position,
2501
+ onMouseEnter: props.onMouseEnter,
2502
+ onMouseLeave: props.onMouseLeave
2503
+ }, /*#__PURE__*/React.createElement("div", {
2504
+ className: classNames(styles$h.corner, styles$h.topLeft)
2505
+ }), /*#__PURE__*/React.createElement("div", {
2506
+ className: classNames(styles$h.corner, styles$h.topRight)
2507
+ }), /*#__PURE__*/React.createElement("div", {
2508
+ className: classNames(styles$h.corner, styles$h.bottomLeft)
2509
+ }), /*#__PURE__*/React.createElement("div", {
2510
+ className: classNames(styles$h.corner, styles$h.bottomRight)
2511
+ }));
2512
+ };
2513
+ MotifArea.defaultProps = {
2514
+ onUpdate: () => {}
2515
+ };
2516
+ function getPosition(props) {
2517
+ return props.file.motifAreaOffsetRect || {
2518
+ top: 0,
2519
+ left: 0,
2520
+ width: 0,
2521
+ height: 0
2522
+ };
2523
+ }
2524
+
2525
+ var styles$i = {"effects":"Effects-module_effects__14Z24","autoZoom":"Effects-module_autoZoom__9JEWM"};
2526
+
2527
+ function Effects({
2528
+ file,
2529
+ children
2530
+ }) {
2531
+ const ref = useRef();
2532
+ const sectionViewTimeline = useSectionViewTimeline();
2533
+ const isStaticPreview = useIsStaticPreview();
2534
+ const {
2535
+ isVisible
2536
+ } = useSectionLifecycle();
2537
+ const scrollParallaxValue = getEffectValue(file, 'scrollParallax');
2538
+ const autoZoomValue = getEffectValue(file, 'autoZoom');
2539
+ const [autoZoomRunning, setAutoZoomRunning] = useState(false);
2540
+ useIsomorphicLayoutEffect(() => {
2541
+ if (scrollParallaxValue && !isStaticPreview && sectionViewTimeline) {
2542
+ const max = 20 * scrollParallaxValue / 100;
2543
+ const scale = 100 + 2 * max;
2544
+ const animation = ref.current.animate({
2545
+ transform: [`translateY(${max}%) scale(${scale}%)`, `translateY(${-max}%) scale(${scale}%)`]
2546
+ }, {
2547
+ fill: 'forwards',
2548
+ timeline: sectionViewTimeline,
2549
+ rangeStart: 'cover 0%',
2550
+ composite: 'add',
2551
+ rangeEnd: 'cover 100%'
2552
+ });
2553
+ return () => animation.cancel();
2554
+ }
2555
+ }, [sectionViewTimeline, scrollParallaxValue, isStaticPreview]);
2556
+ useIsomorphicLayoutEffect(() => {
2557
+ setAutoZoomRunning(autoZoomValue && isVisible && !prefersReducedMotion());
2558
+ }, [autoZoomValue, isVisible]);
2559
+ return /*#__PURE__*/React.createElement("div", {
2560
+ ref: ref,
2561
+ className: classNames(styles$i.effects, {
2562
+ [styles$i.autoZoom]: autoZoomRunning
2563
+ }),
2564
+ style: {
2565
+ filter: getFilter((file === null || file === void 0 ? void 0 : file.effects) || []),
2566
+ ...getAutoZoomProperties(autoZoomValue, file)
2567
+ }
2568
+ }, children);
2569
+ }
2570
+ function getFilter(effects) {
2571
+ const components = effects.map(effect => {
2572
+ if (effect.name === 'blur') {
2573
+ return `blur(${effect.value / 100 * 10}px)`;
2574
+ } else if (['brightness', 'contrast', 'saturate'].includes(effect.name)) {
2575
+ const value = Math.round(effect.value < 0 ? 100 + effect.value * 0.6 : 100 + effect.value);
2576
+ return `${effect.name}(${value}%)`;
2577
+ } else if (['grayscale', 'sepia'].includes(effect.name)) {
2578
+ return `${effect.name}(${effect.value}%)`;
2579
+ }
2580
+ return null;
2581
+ }).filter(Boolean);
2582
+ return components.length ? components.join(' ') : null;
2583
+ }
2584
+ function getAutoZoomProperties(autoZoomValue, file) {
2585
+ if (!autoZoomValue) {
2586
+ return null;
2587
+ }
2588
+ const x = (file === null || file === void 0 ? void 0 : file.motifArea) ? 50 - (file.motifArea.left + file.motifArea.width / 2) : 0;
2589
+ const y = (file === null || file === void 0 ? void 0 : file.motifArea) ? 50 - (file.motifArea.top + file.motifArea.height / 2) : 0;
2590
+ return {
2591
+ '--auto-zoom-origin-x': `${x}%`,
2592
+ '--auto-zoom-origin-y': `${y}%`,
2593
+ '--auto-zoom-duration': `${1000 * (autoZoomValue / 100) + 40000 * (1 - autoZoomValue / 100)}ms`
2594
+ };
2595
+ }
2596
+
2597
+ function BackgroundVideo({
2598
+ video,
2599
+ onMotifAreaUpdate,
2600
+ containerDimension
2601
+ }) {
2602
+ const [playerState, playerActions] = usePlayerState();
2603
+ const {
2604
+ shouldLoad,
2605
+ shouldPrepare
2606
+ } = useSectionLifecycle({
2607
+ onVisible() {
2608
+ playerActions.changeVolumeFactor(0, 0);
2609
+ playerActions.play();
2610
+ },
2611
+ onActivate() {
2612
+ playerActions.changeVolumeFactor(1, 1000);
2613
+ },
2614
+ onDeactivate() {
2615
+ playerActions.changeVolumeFactor(0, 1000);
2616
+ },
2617
+ onInvisible() {
2618
+ playerActions.pause();
2619
+ }
2620
+ });
2621
+ useEffect(() => {
2622
+ let documentState = documentHiddenState(visibilityState => {
2623
+ if (visibilityState === 'hidden') {
2624
+ playerActions.pause();
2625
+ } else {
2626
+ playerActions.play();
2627
+ }
2628
+ });
2629
+ return () => {
2630
+ documentState.removeCallback();
2631
+ };
2632
+ }, [playerActions]);
2633
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Effects, {
2634
+ file: video
2635
+ }, /*#__PURE__*/React.createElement(PlayerEventContextDataProvider, {
2636
+ playerDescription: "Backdrop Video",
2637
+ playbackMode: "loop"
2638
+ }, /*#__PURE__*/React.createElement(VideoPlayer, {
2639
+ load: shouldPrepare ? 'auto' : shouldLoad ? 'poster' : 'none',
2640
+ playerState: playerState,
2641
+ playerActions: playerActions,
2642
+ videoFile: video,
2643
+ textTracksDisabled: true,
2644
+ adaptiveMinQuality: "high",
2645
+ fit: "cover",
2646
+ loop: true,
2647
+ playsInline: true
2648
+ }))), /*#__PURE__*/React.createElement(MotifArea, {
2649
+ key: video.permaId,
2650
+ onUpdate: onMotifAreaUpdate,
2651
+ file: video,
2652
+ containerWidth: containerDimension.width,
2653
+ containerHeight: containerDimension.height
2654
+ }));
2655
+ }
2656
+
2657
+ var styles$j = {"fill":"Image-module_fill__1D1wH","contain":"Image-module_contain__3_XWB"};
2658
+
2659
+ function ImageStructuredData({
2660
+ file
2661
+ }) {
2662
+ const entryMedadata = useEntryMetadata();
2663
+ const data = {
2664
+ '@context': 'http://schema.org',
2665
+ '@type': 'ImageObject',
2666
+ name: file.basename,
2667
+ description: file.configuration.alt,
2668
+ url: ensureProtocol('https', file.urls.large),
2669
+ width: file.width,
2670
+ height: file.height,
2671
+ datePublished: entryMedadata.publishedAt,
2672
+ uploadDate: file.createdAt,
2673
+ copyrightHolder: {
2674
+ '@type': 'Organization',
2675
+ name: file.rights
2676
+ }
2677
+ };
2678
+ return /*#__PURE__*/React.createElement(StructuredData, {
2679
+ data: data
2680
+ });
2681
+ }
2682
+
2683
+ /**
2684
+ * Render an image file.
2685
+ *
2686
+ * @param {Object} props
2687
+ * @param {Object} props.imageFile - Image file obtained via `useFile`.
2688
+ * @param {string|string[]} [props.variant] - Paperclip style to use. Defaults to
2689
+ * large. Pass an array (e.g. `['large', 'ultra']`) to emit a `srcset` with
2690
+ * width descriptors. The first entry is used as `src` fallback.
2691
+ * @param {string} [props.sizes] - Sizes attribute for srcset. Defaults to `"100vw"`.
2692
+ * @param {boolean} [props.load] - Whether to load the image. Can be used for lazy loading.
2693
+ * @param {boolean} [props.structuredData] - Whether to render a JSON+LD script tag.
2694
+ * @param {boolean} [props.preferSvg] - Use original if image is SVG.
2695
+ * @param {boolean} [props.fill=true] - Position absolute and fill parent.
2696
+ * @param {boolean} [props.fit=cover] - `"contain"` or `"cover"`.
2697
+ */
2698
+ function Image({
2699
+ imageFile,
2700
+ ...props
2701
+ }) {
2702
+ if (imageFile && imageFile.isReady && props.load) {
2703
+ return /*#__PURE__*/React.createElement(React.Fragment, null, renderImageTag(props, imageFile), renderStructuredData(props, imageFile));
2704
+ }
2705
+ return null;
2706
+ }
2707
+ function renderImageTag(props, imageFile) {
2708
+ const cropPositionX = imageFile.cropPosition ? imageFile.cropPosition.x : 50;
2709
+ const cropPositionY = imageFile.cropPosition ? imageFile.cropPosition.y : 50;
2710
+ return /*#__PURE__*/React.createElement("img", {
2711
+ className: classNames({
2712
+ [styles$j.fill]: props.fill,
2713
+ [styles$j.contain]: props.fit === 'contain'
2714
+ }),
2715
+ src: imageSrc(imageFile, props),
2716
+ srcSet: imageSrcSet(imageFile, props),
2717
+ sizes: imageSizes(imageFile, props),
2718
+ alt: imageFile.configuration.alt ? imageFile.configuration.alt : '',
2719
+ width: props.width,
2720
+ height: props.height,
2721
+ style: {
2722
+ objectPosition: `${cropPositionX}% ${cropPositionY}%`
2723
+ }
2724
+ });
2725
+ }
2726
+ function imageSrc(imageFile, props) {
2727
+ const {
2728
+ variant
2729
+ } = props;
2730
+ if (Array.isArray(variant)) {
2731
+ return imageUrl(imageFile, {
2732
+ ...props,
2733
+ variant: variant[0]
2734
+ });
2735
+ }
2736
+ return imageUrl(imageFile, props);
2737
+ }
2738
+ function imageSrcSet(imageFile, {
2739
+ variant,
2740
+ preferSvg
2741
+ }) {
2742
+ var _imageFile$extension;
2743
+ if (!Array.isArray(variant)) return undefined;
2744
+ if (preferSvg && ((_imageFile$extension = imageFile.extension) === null || _imageFile$extension === void 0 ? void 0 : _imageFile$extension.toLowerCase()) === 'svg') return undefined;
2745
+ if (!imageFile.variantWidths) return undefined;
2746
+ const entries = imageFile.variantWidths.filter(([, v]) => variant.includes(v) && imageFile.urls[v]).map(([w, v]) => `${imageFile.urls[v]} ${w}`);
2747
+ if (entries.length <= 1) return undefined;
2748
+ return entries.join(', ');
2749
+ }
2750
+ function imageSizes(imageFile, props) {
2751
+ if (imageSrcSet(imageFile, props)) {
2752
+ return props.sizes || '100vw';
2753
+ }
2754
+ return undefined;
2755
+ }
2756
+ function imageUrl(imageFile, {
2757
+ variant,
2758
+ preferSvg
2759
+ }) {
2760
+ if (variant === 'ultra' && !imageFile.urls.ultra) {
2761
+ variant = 'large';
2762
+ }
2763
+ if (preferSvg && imageFile.extension.toLowerCase() === 'svg') {
2764
+ return imageFile.urls.original;
2765
+ } else {
2766
+ return imageFile.urls[variant];
2767
+ }
2768
+ }
2769
+ function renderStructuredData(props, file) {
2770
+ if (props.structuredData && file) {
2771
+ return /*#__PURE__*/React.createElement(ImageStructuredData, {
2772
+ file: file
2773
+ });
2774
+ }
2775
+ }
2776
+ Image.defaultProps = {
2777
+ load: true,
2778
+ variant: 'large',
2779
+ fill: true
2780
+ };
2781
+
2782
+ function BackgroundImage({
2783
+ image,
2784
+ onMotifAreaUpdate,
2785
+ containerDimension
2786
+ }) {
2787
+ const {
2788
+ shouldLoad
2789
+ } = useSectionLifecycle();
2790
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Effects, {
2791
+ file: image
2792
+ }, /*#__PURE__*/React.createElement(Image, {
2793
+ imageFile: image,
2794
+ load: shouldLoad,
2795
+ structuredData: true,
2796
+ preferSvg: true,
2797
+ variant: features.isEnabled('image_srcset') ? ['medium', 'large', 'ultra'] : 'large'
2798
+ })), /*#__PURE__*/React.createElement(MotifArea, {
2799
+ key: image === null || image === void 0 ? void 0 : image.permaId,
2800
+ onUpdate: onMotifAreaUpdate,
2801
+ file: image,
2802
+ containerWidth: containerDimension.width,
2803
+ containerHeight: containerDimension.height
2804
+ }));
2805
+ }
2806
+
2807
+ const BackgroundContentElement = extensible('BackgroundContentElement', function BackgroundContentElement({
2808
+ contentElement,
2809
+ isIntersecting,
2810
+ onMotifAreaUpdate,
2811
+ containerDimension
2812
+ }) {
2813
+ const sectionLifecycle = useSectionLifecycle();
2814
+ const lifecycleOverride = useMemo(() => ({
2815
+ ...sectionLifecycle,
2816
+ isActive: sectionLifecycle.isActive && !isIntersecting
2817
+ }), [sectionLifecycle, isIntersecting]);
2818
+ const sectionProps = useMemo(() => ({
2819
+ isIntersecting,
2820
+ containerDimension
2821
+ }), [isIntersecting, containerDimension]);
2822
+ return /*#__PURE__*/React.createElement("div", {
2823
+ ref: onMotifAreaUpdate
2824
+ }, /*#__PURE__*/React.createElement(ContentElement, {
2825
+ id: contentElement.id,
2826
+ permaId: contentElement.permaId,
2827
+ type: contentElement.type,
2828
+ position: contentElement.position,
2829
+ width: 3,
2830
+ itemProps: contentElement.props,
2831
+ sectionProps: sectionProps,
2832
+ lifecycleOverride: lifecycleOverride
2833
+ }));
2834
+ });
2835
+
2836
+ function BackgroundAsset(props) {
2837
+ const backgroundFile = useBackgroundFile({
2838
+ file: props.backdrop.video || props.backdrop.image,
2839
+ motifArea: props.backdrop.motifArea,
2840
+ effects: props.backdrop.effects,
2841
+ containerDimension: props.containerDimension
2842
+ });
2843
+ if (props.backdrop.contentElement) {
2844
+ return /*#__PURE__*/React.createElement(Fullscreen, {
2845
+ ref: props.setContainerRef
2846
+ }, /*#__PURE__*/React.createElement(BackgroundContentElement, {
2847
+ contentElement: props.backdrop.contentElement,
2848
+ onMotifAreaUpdate: props.onMotifAreaUpdate,
2849
+ containerDimension: props.containerDimension,
2850
+ isIntersecting: props.motifAreaState.isMotifIntersected
2851
+ }));
2852
+ } else if (props.backdrop.video) {
2853
+ return /*#__PURE__*/React.createElement(Fullscreen, {
2854
+ ref: props.setContainerRef
2855
+ }, /*#__PURE__*/React.createElement(BackgroundVideo, {
2856
+ video: backgroundFile,
2857
+ onMotifAreaUpdate: props.onMotifAreaUpdate,
2858
+ containerDimension: props.containerDimension
2859
+ }));
2860
+ } else if (props.backdrop.color) {
2861
+ return /*#__PURE__*/React.createElement(FillColor, {
2862
+ color: props.backdrop.color
2863
+ });
2864
+ } else {
2865
+ return /*#__PURE__*/React.createElement(Fullscreen, {
2866
+ ref: props.setContainerRef
2867
+ }, /*#__PURE__*/React.createElement(BackgroundImage, {
2868
+ image: backgroundFile,
2869
+ onMotifAreaUpdate: props.onMotifAreaUpdate,
2870
+ containerDimension: props.containerDimension
2871
+ }));
2872
+ }
2873
+ }
2874
+
2875
+ var styles$k = {"Backdrop":"Backdrop-module_Backdrop__1w4UZ","noCompositionLayer":"Backdrop-module_noCompositionLayer__33IlH","coverSection":"Backdrop-module_coverSection__201GK","defaultBackground":"Backdrop-module_defaultBackground__1YQQL"};
2876
+
2877
+ var sharedStyles = {"fade-duration":"0.5s","fixed":"shared-module_fixed__3T2AK","justifyBottom":"shared-module_justifyBottom__22ncu","fadedOut":"shared-module_fadedOut__D8bt8","perElementFade":"shared-module_perElementFade__3MhBy","foregroundOpacity":"shared-module_foregroundOpacity__8EnGc"};
2878
+
2879
+ const Backdrop = extensible('Backdrop', function Backdrop(props) {
2880
+ const [containerDimension, setContainerRef] = useDimension();
2881
+ const {
2882
+ shouldLoad
2883
+ } = useSectionLifecycle();
2884
+ return /*#__PURE__*/React.createElement("div", {
2885
+ className: classNames(styles$k.Backdrop, {
2886
+ [styles$k.noCompositionLayer]: !shouldLoad && !props.eagerLoad
2887
+ }, {
2888
+ [styles$k.coverSection]: props.size === 'coverSection'
2889
+ }, props.transitionStyles.backdrop, props.transitionStyles[`backdrop-${props.state}`])
2890
+ }, /*#__PURE__*/React.createElement("div", {
2891
+ className: classNames(props.transitionStyles.backdropInner, {
2892
+ [sharedStyles.justifyBottom]: props.backdrop.contentElement
2893
+ })
2894
+ }, /*#__PURE__*/React.createElement("div", {
2895
+ className: classNames(styles$k.defaultBackground, props.transitionStyles.backdropInner2)
2896
+ }, props.children( /*#__PURE__*/React.createElement(BackgroundAsset, Object.assign({}, props, {
2897
+ containerDimension: containerDimension,
2898
+ setContainerRef: setContainerRef
2899
+ }))))));
2900
+ });
2901
+ Backdrop.defaultProps = {
2902
+ children: children => children,
2903
+ transitionStyles: {}
2904
+ };
2905
+
2906
+ function isIntersectingX(rectA, rectB) {
2907
+ return rectA.left < rectB.right && rectA.right > rectB.left || rectB.left < rectA.right && rectB.right > rectA.left;
2908
+ }
2909
+
2910
+ function getBoundingClientRect(el) {
2911
+ if (!el) {
2912
+ return {
2913
+ left: 0,
2914
+ right: 0,
2915
+ top: 0,
2916
+ bottom: 0,
2917
+ width: 0,
2918
+ height: 0
2919
+ };
2920
+ }
2921
+ return el.getBoundingClientRect();
2922
+ }
2923
+ function useBoundingClientRect({
2924
+ updateOnScrollAndResize = true,
2925
+ dependencies = []
2926
+ } = {}) {
2927
+ const [boundingClientRect, setBoundingClientRect] = useState(getBoundingClientRect(null));
2928
+ const [currentNode, setCurrentNode] = useState(null);
2929
+ const measureRef = useCallback(node => {
2930
+ setCurrentNode(node);
2931
+ setBoundingClientRect(getBoundingClientRect(node));
2932
+ }, []);
2933
+ useIsomorphicLayoutEffect(() => {
2934
+ if (dependencies.length && currentNode) {
2935
+ setBoundingClientRect(getBoundingClientRect(currentNode));
2936
+ }
2937
+ }, dependencies);
2938
+ useEffect(function () {
2939
+ function handler() {
2940
+ setBoundingClientRect(getBoundingClientRect(currentNode));
2941
+ }
2942
+ if (!currentNode || !updateOnScrollAndResize) {
2943
+ return;
2944
+ }
2945
+ window.addEventListener('resize', handler);
2946
+ window.addEventListener('scroll', handler);
2947
+ return function () {
2948
+ window.removeEventListener('resize', handler);
2949
+ window.removeEventListener('scroll', handler);
2950
+ };
2951
+ }, [currentNode, updateOnScrollAndResize]);
2952
+ return [boundingClientRect, measureRef];
2953
+ }
2954
+
2955
+ /**
2956
+ * Handles the state of the section layout based on the current
2957
+ * position of content and motif area. Returns an array of the form:
2958
+ *
2959
+ * [
2960
+ * {
2961
+ * isContentPadded, // true if motif and content will
2962
+ * // not fit side by side.
2963
+ *
2964
+ * isMotifIntersected, // true if either section content or
2965
+ * // or content from the next section
2966
+ * // entering with a fadeBg transition
2967
+ * // overlaps the motif. Used to hide
2968
+ * // interactive parts (e.g., player
2969
+ * // controls) of backdrop content
2970
+ * // elements.
2971
+ *
2972
+ * intersectionRatioY, // Ratio of the motif area that is
2973
+ * // covered by the content given the
2974
+ * // current scroll position of motif
2975
+ * // is exposed.
2976
+ *
2977
+ * paddingTop, // Distance to shift down the content
2978
+ * // to ensure the motif area can be
2979
+ * // seen when entering the section.
2980
+ *
2981
+ * minHeight, // Min Height of the section to ensure
2982
+ * // the motif area can be seen.
2983
+ * },
2984
+ * setMotifAreaRectRef, // Assign motif area element that shall be
2985
+ * // measured.
2986
+ *
2987
+ * setContentAreaRef // Assign content area element that
2988
+ * // shall be measured.
2989
+ * ]
2990
+ *
2991
+ * @param {Object} options
2992
+ * @param {boolean} backdropContentElement - Whether the section has a
2993
+ * backdrop content element.
2994
+ * @param {string[]} transitions - Names of the section's enter and exit
2995
+ * transitions.
2996
+ * @param {boolean} fullHeight - Whether the section has full or dynamic
2997
+ * height.
2998
+ * @param {boolean} empty - Whether the section contains content
2999
+ * elements.
3000
+ * @param {boolean} exposeMotifArea - Whether to pad content down if it
3001
+ * would otherwise intersect with the motif area.
3002
+ *
3003
+ * @private
3004
+ */
3005
+ function useMotifAreaState({
3006
+ backdropContentElement,
3007
+ transitions,
3008
+ fullHeight,
3009
+ empty,
3010
+ exposeMotifArea,
3011
+ updateOnScrollAndResize
3012
+ } = {}) {
3013
+ const [motifAreaRect, setMotifAreaRectRef] = useBoundingClientRect({
3014
+ updateOnScrollAndResize
3015
+ });
3016
+ const [motifAreaDimension, setMotifAreaDimensionRef] = useDimension();
3017
+ const [isPadded, setIsPadded] = useState(false);
3018
+ const setMotifAreaRef = useCallback(node => {
3019
+ setMotifAreaRectRef(node);
3020
+ setMotifAreaDimensionRef(node);
3021
+ }, [setMotifAreaRectRef, setMotifAreaDimensionRef]);
3022
+ const [contentAreaRect, setContentAreaRef] = useBoundingClientRect({
3023
+ updateOnScrollAndResize,
3024
+ dependencies: [isPadded]
3025
+ });
3026
+ const contentRequiresPadding = exposeMotifArea && isIntersectingX(motifAreaRect, contentAreaRect) && motifAreaRect.height > 0 && !empty;
3027
+ const paddingTop = getMotifAreaPadding(contentRequiresPadding, transitions, motifAreaDimension, backdropContentElement, empty);
3028
+
3029
+ // Force measuring content area again since applying the padding
3030
+ // changes the intersection ratio.
3031
+ const willBePadded = !!paddingTop;
3032
+ useEffect(() => {
3033
+ setIsPadded(willBePadded);
3034
+ }, [willBePadded]);
3035
+ const intersectionRatioY = getIntersectionRatioY(motifAreaRect, contentAreaRect);
3036
+ return [{
3037
+ paddingTop,
3038
+ isContentPadded: contentRequiresPadding || backdropContentElement,
3039
+ minHeight: getMotifAreaMinHeight(fullHeight, transitions, motifAreaDimension),
3040
+ intersectionRatioY: contentRequiresPadding ? intersectionRatioY : 0,
3041
+ isMotifIntersected: getIsMotifIntersected(empty, transitions, intersectionRatioY)
3042
+ }, setMotifAreaRef, setContentAreaRef];
3043
+ }
3044
+ function getMotifAreaPadding(contentRequiresPadding, transitions, motifAreaDimension, backdropContentElement, empty) {
3045
+ if (backdropContentElement) {
3046
+ if (transitions[0] === 'fadeIn' || empty && transitions[1] === 'fadeOut') {
3047
+ return '70vh';
3048
+ } else {
3049
+ return '110vh';
3050
+ }
3051
+ } else if (!contentRequiresPadding) {
3052
+ return;
3053
+ }
3054
+ if (transitions[0] === 'fadeIn' || transitions[0] === 'fadeInBg') {
3055
+ // Once the section has become active, the backdrop becomes
3056
+ // visible all at once. Motif area aware background positioning
3057
+ // ensures that the motif area is within the viewport. Still, when
3058
+ // scrolling fast, the top of the section will already have
3059
+ // reached the top of the viewport once the fade transitions ends.
3060
+ //
3061
+ // If the motif area is at the top of the backdrop, adding its
3062
+ // height as padding is enough to ensure that the content does not
3063
+ // immediately start intersecting.
3064
+ //
3065
+ // If the motif area is at the bottom of the backdrop, additional
3066
+ // padding is needed to prevent the content from hiding the motif
3067
+ // right at the start. Adding the full top distance of the motif
3068
+ // area, though, means a full viewport height has to be scrolled
3069
+ // by after the content of the previous section has been faded out
3070
+ // before the content of the section enters the viewport.
3071
+ // Subjectively, this feels like to little feedback that more
3072
+ // content is coming. We therefore reduce the additional distance
3073
+ // by a third.
3074
+ return motifAreaDimension.top * 2 / 3 + motifAreaDimension.height;
3075
+ }
3076
+ if (transitions[0] === 'reveal') {
3077
+ // The backdrop remains in a fixed position while the content is
3078
+ // being scrolled in. Shifting the content down by the height of
3079
+ // the motif area means the motif area will be completely visible
3080
+ // when the top of the section aligns with the top of the motif
3081
+ // area.
3082
+ //
3083
+ // For exit transition `scrollOut`, the min height determined
3084
+ // below, ensures that the top of the section can actually reach
3085
+ // that position before the section begins to scroll.
3086
+ return motifAreaDimension.height;
3087
+ } else {
3088
+ // In the remaining `scrollIn` case, content and backdrop move in
3089
+ // together. We need to shift content down below the motif.
3090
+ return motifAreaDimension.top + motifAreaDimension.height;
3091
+ }
3092
+ }
3093
+ function getMotifAreaMinHeight(fullHeight, transitions, motifAreaDimension) {
3094
+ if (fullHeight) {
3095
+ return;
3096
+ }
3097
+ if (transitions[0] === 'reveal') {
3098
+ if (transitions[1] === 'conceal') {
3099
+ // Ensure section is tall enough to reveal the full height of
3100
+ // the motif area once the section passes it.
3101
+ return motifAreaDimension.height;
3102
+ } else {
3103
+ // Ensure backdrop can be revealed far enough before the section
3104
+ // starts scrolling.
3105
+ return motifAreaDimension.bottom + motifAreaDimension.height;
3106
+ }
3107
+ } else {
3108
+ // Ensure motif is visible in scrolled in section.
3109
+ return motifAreaDimension.top + motifAreaDimension.height;
3110
+ }
3111
+ }
3112
+ function getIntersectionRatioY(motifAreaRect, contentAreaRect) {
3113
+ const motifAreaOverlap = Math.max(0, Math.min(motifAreaRect.height, motifAreaRect.bottom - contentAreaRect.top));
3114
+ return motifAreaRect.height > 0 ? motifAreaOverlap / motifAreaRect.height : 0;
3115
+ }
3116
+ function getIsMotifIntersected(empty, transitions, intersectionRatioY) {
3117
+ // Hide interactive parts of backdrop content elements (e.g., player
3118
+ // controls) if:
3119
+ // - section has content and it has been scrolled to overlap or
3120
+ // - next section enters with fadeOutBg making it contents potentially
3121
+ // overlap the motif area
3122
+ return !empty || transitions[1] === 'fadeOutBg' ? intersectionRatioY > 0 : false;
3123
+ }
3124
+
3125
+ /**
3126
+ * Returns boolean indicating whether viewport orientation is currently
3127
+ * portrait.
3128
+ */
3129
+ function usePortraitOrientation(options) {
3130
+ return useMediaQuery('(orientation: portrait)', options);
3131
+ }
3132
+
3133
+ function useBackdrop(section) {
3134
+ var _section$backdrop, _section$backdrop2, _section$backdrop3;
3135
+ const videoBackdrop = useFileBackdrop({
3136
+ section,
3137
+ collectionName: 'videoFiles',
3138
+ propertyName: 'video'
3139
+ });
3140
+ const imageBackdrop = useFileBackdrop({
3141
+ section,
3142
+ collectionName: 'imageFiles',
3143
+ propertyName: 'image'
3144
+ });
3145
+ const contentElement = useContentElement({
3146
+ permaId: (_section$backdrop = section.backdrop) === null || _section$backdrop === void 0 ? void 0 : _section$backdrop.contentElement,
3147
+ layout: 'backdrop'
3148
+ });
3149
+ if (contentElement && contentElement.sectionId === section.id) {
3150
+ return {
3151
+ contentElement
3152
+ };
3153
+ } else if (((_section$backdrop2 = section.backdrop) === null || _section$backdrop2 === void 0 ? void 0 : _section$backdrop2.color) || ((_section$backdrop3 = section.backdrop) === null || _section$backdrop3 === void 0 ? void 0 : _section$backdrop3.image) && section.backdrop.image.toString().startsWith('#')) {
3154
+ return {
3155
+ color: section.backdrop.color || section.backdrop.image,
3156
+ effects: section.backdropEffects
3157
+ };
3158
+ } else {
3159
+ return videoBackdrop || imageBackdrop || {};
3160
+ }
3161
+ }
3162
+ function useFileBackdrop({
3163
+ section,
3164
+ collectionName,
3165
+ propertyName
3166
+ }) {
3167
+ const file = useFileWithInlineRights({
3168
+ configuration: section.backdrop || {},
3169
+ collectionName,
3170
+ propertyName
3171
+ });
3172
+ const mobileFile = useFileWithInlineRights({
3173
+ configuration: section.backdrop || {},
3174
+ collectionName,
3175
+ propertyName: `${propertyName}Mobile`
3176
+ });
3177
+ const mobile = usePortraitOrientation({
3178
+ active: file && mobileFile
3179
+ });
3180
+ if (mobileFile && (mobile || !file)) {
3181
+ return {
3182
+ [propertyName]: mobileFile,
3183
+ motifArea: section.backdrop[`${propertyName}MobileMotifArea`],
3184
+ effects: section.backdropEffectsMobile,
3185
+ portrait: true
3186
+ };
3187
+ } else if (file) {
3188
+ return {
3189
+ [propertyName]: file,
3190
+ motifArea: section.backdrop[`${propertyName}MotifArea`],
3191
+ effects: section.backdropEffects,
3192
+ portrait: false
3193
+ };
3194
+ } else {
3195
+ return null;
3196
+ }
3197
+ }
3198
+
3199
+ var styles$l = {"darkContentTextColor":"var(--theme-dark-content-text-color, #222)","lightContentTextColor":"var(--theme-light-content-text-color, #fff)","darkContentLinkColor":"var(--theme-dark-content-link-color, var(--theme-content-link-color, currentColor))","lightContentLinkColor":"var(--theme-light-content-link-color, var(--theme-content-link-color, currentColor))","Section":"Section-module_Section__Yo58b","first":"Section-module_first__1vLBH","narrow":"Section-module_narrow__3Dawu","lightContent":"Section-module_lightContent__1hqim scope-lightContent","darkContent":"Section-module_darkContent__20cnO scope-darkContent"};
3200
+
3201
+ var fadeInBgConceal = {"fade-duration":"0.5s","backdrop":"fadeInBgConceal-module_backdrop__11JGO","backdropInner":"fadeInBgConceal-module_backdropInner__1IAYD shared-module_fixed__3T2AK","backdrop-below":"fadeInBgConceal-module_backdrop-below__3E6Uk"};
3202
+
3203
+ var fadeInBgFadeOut = {"fade-duration":"0.5s","backdrop":"fadeInBgFadeOut-module_backdrop__r0YXp","backdropInner":"fadeInBgFadeOut-module_backdropInner__IQp87 shared-module_fixed__3T2AK","backdrop-below":"fadeInBgFadeOut-module_backdrop-below__2G-Ic","foreground":"fadeInBgFadeOut-module_foreground__Q2vkT","foreground-above":"fadeInBgFadeOut-module_foreground-above__3pmz9 shared-module_fadedOut__D8bt8"};
3204
+
3205
+ var fadeInBgFadeOutBg = {"fade-duration":"0.5s","backdrop":"fadeInBgFadeOutBg-module_backdrop__15ocl","backdropInner":"fadeInBgFadeOutBg-module_backdropInner__sAnz6 shared-module_fixed__3T2AK","boxShadow":"fadeInBgFadeOutBg-module_boxShadow__xUKyj","boxShadow-above":"fadeInBgFadeOutBg-module_boxShadow-above__2bY0E","backdrop-below":"fadeInBgFadeOutBg-module_backdrop-below__1rDT6"};
3206
+
3207
+ var fadeInBgScrollOut = {"fade-duration":"0.5s","backdrop":"fadeInBgScrollOut-module_backdrop__1bSsb","backdropInner":"fadeInBgScrollOut-module_backdropInner__3JZBG","backdropInner2":"fadeInBgScrollOut-module_backdropInner2__q-00L","foreground":"fadeInBgScrollOut-module_foreground__1ODH9","backdrop-below":"fadeInBgScrollOut-module_backdrop-below__2Dbkr"};
3208
+
3209
+ var fadeInConceal = {"fade-duration":"0.5s","backdrop":"fadeInConceal-module_backdrop__1zaRO","backdropInner":"fadeInConceal-module_backdropInner__1AIvq shared-module_fixed__3T2AK","backdrop-below":"fadeInConceal-module_backdrop-below__AWyQe","foreground":"fadeInConceal-module_foreground__3giM9","foreground-below":"fadeInConceal-module_foreground-below__2z5Op shared-module_fadedOut__D8bt8"};
3210
+
3211
+ var fadeInFadeOut = {"fade-duration":"0.5s","backdrop":"fadeInFadeOut-module_backdrop__Y4xOA","backdropInner":"fadeInFadeOut-module_backdropInner__1oRfP shared-module_fixed__3T2AK","backdrop-below":"fadeInFadeOut-module_backdrop-below__1h2I4","foreground":"fadeInFadeOut-module_foreground__1eleZ","foreground-above":"fadeInFadeOut-module_foreground-above__249wa shared-module_fadedOut__D8bt8","foreground-below":"fadeInFadeOut-module_foreground-below__3mE6f shared-module_fadedOut__D8bt8"};
3212
+
3213
+ var fadeInFadeOutBg = {"fade-duration":"0.5s","backdrop":"fadeInFadeOutBg-module_backdrop__2-IF3","backdropInner":"fadeInFadeOutBg-module_backdropInner__3r_bo shared-module_fixed__3T2AK","boxShadow":"fadeInFadeOutBg-module_boxShadow__3x7Ki","backdrop-below":"fadeInFadeOutBg-module_backdrop-below__4Ys_2","boxShadow-above":"fadeInFadeOutBg-module_boxShadow-above__3T2K5","foreground":"fadeInFadeOutBg-module_foreground__24f_M","foreground-below":"fadeInFadeOutBg-module_foreground-below__3pTRc shared-module_fadedOut__D8bt8"};
3214
+
3215
+ var fadeInScrollOut = {"fade-duration":"0.5s","backdrop":"fadeInScrollOut-module_backdrop__2FhBb","backdropInner":"fadeInScrollOut-module_backdropInner__1OfNZ","backdropInner2":"fadeInScrollOut-module_backdropInner2__5bNPT","foreground":"fadeInScrollOut-module_foreground__3h0EX","foreground-below":"fadeInScrollOut-module_foreground-below__1Jcql shared-module_fadedOut__D8bt8","backdrop-below":"fadeInScrollOut-module_backdrop-below__3cRLH"};
3216
+
3217
+ var revealConceal = {"backdrop":"revealConceal-module_backdrop__dLUhU utils-module_clip__34eot","backdropInner":"revealConceal-module_backdropInner__2k1Z- shared-module_fixed__3T2AK"};
3218
+
3219
+ var revealFadeOut = {"fade-duration":"0.5s","backdrop":"revealFadeOut-module_backdrop___Q1QF utils-module_clip__34eot","backdropInner":"revealFadeOut-module_backdropInner__17qRn shared-module_fixed__3T2AK","foreground":"revealFadeOut-module_foreground__1GzBs","foreground-above":"revealFadeOut-module_foreground-above__3GxOf shared-module_fadedOut__D8bt8"};
3220
+
3221
+ var revealFadeOutBg = {"fade-duration":"0.5s","backdrop":"revealFadeOutBg-module_backdrop__30OCF utils-module_clip__34eot","backdropInner":"revealFadeOutBg-module_backdropInner__3v3tM shared-module_fixed__3T2AK","boxShadow":"revealFadeOutBg-module_boxShadow__1NZRz","boxShadow-above":"revealFadeOutBg-module_boxShadow-above__2r4ov"};
3222
+
3223
+ var revealScrollOut = {"backdrop":"revealScrollOut-module_backdrop__2yOXd utils-module_clip__34eot","backdropInner":"revealScrollOut-module_backdropInner__211p3","backdropInner2":"revealScrollOut-module_backdropInner2__v6WqM","foreground":"revealScrollOut-module_foreground__3z-hw"};
3224
+
3225
+ var scrollInConceal = {"backdrop":"scrollInConceal-module_backdrop__2OJJC"};
3226
+
3227
+ var scrollInFadeOut = {"fade-duration":"0.5s","backdrop":"scrollInFadeOut-module_backdrop__1vXJd","foreground":"scrollInFadeOut-module_foreground__3Ikxb","foreground-above":"scrollInFadeOut-module_foreground-above__6ipm- shared-module_fadedOut__D8bt8"};
3228
+
3229
+ var scrollInFadeOutBg = {"fade-duration":"0.5s","backdrop":"scrollInFadeOutBg-module_backdrop__zw95c","boxShadow":"scrollInFadeOutBg-module_boxShadow__3UxCQ","boxShadow-above":"scrollInFadeOutBg-module_boxShadow-above__3kfau"};
3230
+
3231
+ var scrollInScrollOut = {"backdrop":"scrollInScrollOut-module_backdrop__XzCge","backdropInner":"scrollInScrollOut-module_backdropInner__1ftIm"};
3232
+
3233
+ const styles$m = {
3234
+ fadeInBgConceal,
3235
+ fadeInBgFadeOut,
3236
+ fadeInBgFadeOutBg,
3237
+ fadeInBgScrollOut,
3238
+ fadeInConceal,
3239
+ fadeInFadeOut,
3240
+ fadeInFadeOutBg,
3241
+ fadeInScrollOut,
3242
+ revealConceal,
3243
+ revealFadeOut,
3244
+ revealFadeOutBg,
3245
+ revealScrollOut,
3246
+ scrollInConceal,
3247
+ scrollInFadeOut,
3248
+ scrollInFadeOutBg,
3249
+ scrollInScrollOut
3250
+ };
3251
+ const enterTransitions = {
3252
+ fade: 'fadeIn',
3253
+ fadeBg: 'fadeInBg',
3254
+ scroll: 'scrollIn',
3255
+ scrollOver: 'scrollIn',
3256
+ reveal: 'reveal',
3257
+ beforeAfter: 'reveal'
3258
+ };
3259
+ const exitTransitions = {
3260
+ fade: 'fadeOut',
3261
+ fadeBg: 'fadeOutBg',
3262
+ scroll: 'scrollOut',
3263
+ scrollOver: 'conceal',
3264
+ reveal: 'scrollOut',
3265
+ beforeAfter: 'conceal'
3266
+ };
3267
+ function getTransitionNames() {
3268
+ return Object.keys(exitTransitions);
3269
+ }
3270
+ function getAvailableTransitionNames(section, previousSection) {
3271
+ if (!section.fullHeight || !previousSection.fullHeight) {
3272
+ return getTransitionNames().filter(name => !name.startsWith('fade'));
3273
+ }
3274
+ return getTransitionNames();
3275
+ }
3276
+ function getTransitionStyles(section, overlayStyle) {
3277
+ const name = getTransitionStylesName(section);
3278
+ if (!styles$m[name]) {
3279
+ throw new Error(`Unknown transition ${name}`);
3280
+ }
3281
+ const base = styles$m[name];
3282
+ const [enter, exit] = getEnterAndExitTransitions(section);
3283
+ if ((overlayStyle === null || overlayStyle === void 0 ? void 0 : overlayStyle.backdropFilter) && (enter.startsWith('fade') || exit.startsWith('fade'))) {
3284
+ return {
3285
+ ...base,
3286
+ foreground: base.foreground ? `${base.foreground} ${sharedStyles.perElementFade}` : sharedStyles.perElementFade,
3287
+ foregroundOpacity: sharedStyles.foregroundOpacity
3288
+ };
3289
+ }
3290
+ return base;
3291
+ }
3292
+ function getEnterAndExitTransitions(section) {
3293
+ return [enterTransitions[getTransitionName(section.previousSection, section)], exitTransitions[getTransitionName(section, section.nextSection)]];
3294
+ }
3295
+ function getTransitionStylesName(section) {
3296
+ const [enter, exit] = getEnterAndExitTransitions(section);
3297
+ return `${enter}${capitalize(exit)}`;
3298
+ }
3299
+ function getTransitionName(previousSection, section) {
3300
+ if (!section) {
3301
+ var _previousSection$chap;
3302
+ if ((previousSection === null || previousSection === void 0 ? void 0 : (_previousSection$chap = previousSection.chapter) === null || _previousSection$chap === void 0 ? void 0 : _previousSection$chap.isExcursion) || !(previousSection === null || previousSection === void 0 ? void 0 : previousSection.fullHeight)) {
3303
+ return 'scroll';
3304
+ }
3305
+ return 'fadeBg';
3306
+ }
3307
+ if (!previousSection) {
3308
+ return 'scroll';
3309
+ }
3310
+ if ((!section.fullHeight || !previousSection.fullHeight) && section.transition.startsWith('fade')) {
3311
+ return 'scroll';
3312
+ }
3313
+ return section.transition;
3314
+ }
3315
+ function capitalize(string) {
3316
+ return string.charAt(0).toUpperCase() + string.slice(1);
3317
+ }
3318
+
3319
+ const Section = extensible('Section', function Section({
3320
+ section,
3321
+ transitions,
3322
+ backdrop,
3323
+ contentElements,
3324
+ state,
3325
+ onActivate,
3326
+ domIdPrefix
3327
+ }) {
3328
+ var _section$chapter, _section$transition;
3329
+ const ref = useScrollTarget(section.id);
3330
+ const sectionOverlayStyle = useAppearanceOverlayStyle(section);
3331
+ const transitionStyles = getTransitionStyles(section, sectionOverlayStyle);
3332
+ const atmoAudioFile = useFileWithInlineRights({
3333
+ configuration: section,
3334
+ collectionName: 'audioFiles',
3335
+ propertyName: 'atmoAudioFileId'
3336
+ });
3337
+ const sectionPadding = useSectionPadding(section, {
3338
+ portrait: backdrop.portrait
3339
+ });
3340
+ return /*#__PURE__*/React.createElement("section", {
3341
+ id: `${domIdPrefix}-${section.permaId}`,
3342
+ ref: ref,
3343
+ className: classNames(styles$l.Section, transitionStyles.section, {
3344
+ [styles$l.first]: section.sectionIndex === 0 && !((_section$chapter = section.chapter) === null || _section$chapter === void 0 ? void 0 : _section$chapter.isExcursion)
3345
+ }, {
3346
+ [styles$l.narrow]: section.width === 'narrow'
3347
+ }, `scope-${getAppearanceSectionScopeName(section.appearance)}`, section.invert ? styles$l.darkContent : styles$l.lightContent),
3348
+ style: sectionPadding.styles
3349
+ }, /*#__PURE__*/React.createElement(SectionLifecycleProvider, {
3350
+ onActivate: onActivate,
3351
+ entersWithFadeTransition: (_section$transition = section.transition) === null || _section$transition === void 0 ? void 0 : _section$transition.startsWith('fade')
3352
+ }, /*#__PURE__*/React.createElement(SectionIntersectionProbe, {
3353
+ section: section
3354
+ }), /*#__PURE__*/React.createElement(SectionViewTimelineProvider, {
3355
+ backdrop: backdrop
3356
+ }, /*#__PURE__*/React.createElement(BackgroundColorProvider, {
3357
+ dark: !section.invert
3358
+ }, /*#__PURE__*/React.createElement(SectionAtmo, {
3359
+ audioFile: atmoAudioFile
3360
+ }), /*#__PURE__*/React.createElement(SectionContents, {
3361
+ section: section,
3362
+ transitions: transitions,
3363
+ backdrop: backdrop,
3364
+ contentElements: contentElements,
3365
+ state: state,
3366
+ transitionStyles: transitionStyles,
3367
+ sectionOverlayStyle: sectionOverlayStyle,
3368
+ sectionPadding: sectionPadding
3369
+ }), /*#__PURE__*/React.createElement(SectionInlineFileRights, {
3370
+ section: section,
3371
+ backdrop: backdrop,
3372
+ atmoAudioFile: atmoAudioFile,
3373
+ state: state
3374
+ }), section.sectionIndex === 0 && /*#__PURE__*/React.createElement(SelectableWidget, {
3375
+ role: "scrollIndicator",
3376
+ props: {
3377
+ sectionLayout: section.layout
3378
+ }
3379
+ })))));
3380
+ });
3381
+ Section.defaultProps = {
3382
+ domIdPrefix: 'section'
3383
+ };
3384
+ function SectionContents({
3385
+ section,
3386
+ backdrop,
3387
+ contentElements,
3388
+ state,
3389
+ transitions,
3390
+ transitionStyles,
3391
+ sectionOverlayStyle,
3392
+ sectionPadding
3393
+ }) {
3394
+ const {
3395
+ shouldPrepare
3396
+ } = useSectionLifecycle();
3397
+ const [, exitTransition] = transitions;
3398
+ const [motifAreaState, setMotifAreaRef, setContentAreaRef] = useMotifAreaState({
3399
+ backdropContentElement: 'contentElement' in backdrop,
3400
+ updateOnScrollAndResize: shouldPrepare,
3401
+ exposeMotifArea: section.exposeMotifArea,
3402
+ transitions,
3403
+ empty: !contentElements.length,
3404
+ fullHeight: section.fullHeight
3405
+ });
3406
+ const sectionProperties = useMemo(() => ({
3407
+ layout: section.layout,
3408
+ invert: section.invert,
3409
+ sectionIndex: section.sectionIndex,
3410
+ constrainContentWidth: section.appearance === 'split' && !motifAreaState.isContentPadded
3411
+ }), [section.layout, section.invert, section.sectionIndex, section.appearance, motifAreaState.isContentPadded]);
3412
+ const {
3413
+ Shadow,
3414
+ Box,
3415
+ BoxWrapper
3416
+ } = getAppearanceComponents(section.appearance);
3417
+ const staticShadowOpacity = percentToFraction(section.staticShadowOpacity, {
3418
+ defaultValue: 0.7
3419
+ });
3420
+ const dynamicShadowOpacity = percentToFraction(section.dynamicShadowOpacity, {
3421
+ defaultValue: 0.7
3422
+ });
3423
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Backdrop, {
3424
+ backdrop: backdrop,
3425
+ eagerLoad: section.sectionIndex === 0,
3426
+ size: section.backdropSize,
3427
+ motifAreaState: motifAreaState,
3428
+ onMotifAreaUpdate: setMotifAreaRef,
3429
+ state: state,
3430
+ transitionStyles: transitionStyles
3431
+ }, children => /*#__PURE__*/React.createElement(Shadow, {
3432
+ align: section.layout,
3433
+ inverted: section.invert,
3434
+ motifAreaState: motifAreaState,
3435
+ staticShadowOpacity: staticShadowOpacity,
3436
+ dynamicShadowOpacity: dynamicShadowOpacity,
3437
+ overlayStyle: sectionOverlayStyle
3438
+ }, children)), /*#__PURE__*/React.createElement(BackdropFrameEffect, {
3439
+ backdrop: backdrop
3440
+ }), /*#__PURE__*/React.createElement(Foreground, {
3441
+ section: section,
3442
+ transitionStyles: transitionStyles,
3443
+ state: state,
3444
+ motifAreaState: motifAreaState,
3445
+ sectionPadding: sectionPadding,
3446
+ minHeight: motifAreaState.minHeight,
3447
+ suppressedPaddings: getSuppressedPaddings(contentElements, motifAreaState),
3448
+ heightMode: heightMode(section)
3449
+ }, /*#__PURE__*/React.createElement(Box, {
3450
+ inverted: section.invert,
3451
+ coverInvisibleNextSection: exitTransition.startsWith('fade'),
3452
+ transitionStyles: transitionStyles,
3453
+ state: state,
3454
+ motifAreaState: motifAreaState,
3455
+ staticShadowOpacity: staticShadowOpacity,
3456
+ overlayStyle: sectionOverlayStyle
3457
+ }, /*#__PURE__*/React.createElement(Layout, {
3458
+ sectionId: section.id,
3459
+ items: contentElements,
3460
+ appearance: section.appearance,
3461
+ constrainContentWidth: sectionProperties.constrainContentWidth,
3462
+ contentAreaRef: setContentAreaRef,
3463
+ sectionProps: sectionProperties,
3464
+ isContentPadded: motifAreaState.isContentPadded
3465
+ }, (children, boxProps) => /*#__PURE__*/React.createElement(BoxWrapper, Object.assign({}, boxProps, {
3466
+ transitionStyles: transitionStyles,
3467
+ overlayStyle: sectionOverlayStyle,
3468
+ inverted: section.invert
3469
+ }), children)))));
3470
+ }
3471
+ function ConnectedSection(props) {
3472
+ const contentElements = useSectionForegroundContentElements({
3473
+ sectionId: props.section.id,
3474
+ layout: props.section.layout,
3475
+ phoneLayout: usePhoneLayout()
3476
+ });
3477
+ const backdrop = useBackdrop(props.section);
3478
+ const transitions = getEnterAndExitTransitions(props.section);
3479
+ return /*#__PURE__*/React.createElement(Section, Object.assign({}, props, {
3480
+ transitions: transitions,
3481
+ backdrop: backdrop,
3482
+ contentElements: contentElements
3483
+ }));
3484
+ }
3485
+ function heightMode(section) {
3486
+ if (section.fullHeight) {
3487
+ if (section.transition.startsWith('fade') && section.previousSection || section.nextSection && section.nextSection.transition.startsWith('fade')) {
3488
+ return 'fullFade';
3489
+ } else {
3490
+ return 'full';
3491
+ }
3492
+ }
3493
+ return 'dynamic';
3494
+ }
3495
+ function getSuppressedPaddings(contentElements, motifAreaState) {
3496
+ return {
3497
+ top: isFullWidthElement(contentElements[0]) || motifAreaState.isContentPadded,
3498
+ bottom: isFullWidthElement(contentElements[contentElements.length - 1])
3499
+ };
3500
+ }
3501
+ function isFullWidthElement(element) {
3502
+ return element && element.position === 'inline' && element.width === widths.full;
3503
+ }
3504
+ function percentToFraction(value, {
3505
+ defaultValue
3506
+ }) {
3507
+ return typeof value !== 'undefined' ? value / 100 : defaultValue;
3508
+ }
3509
+
3510
+ const CurrentChapterContext = React.createContext();
3511
+ const CurrentSectionIndexStateContext = React.createContext();
3512
+ function CurrentSectionProvider({
3513
+ children
3514
+ }) {
3515
+ const [currentSectionIndex, setCurrentSectionIndex] = useState(0);
3516
+ const currentSectionIndexState = useMemo(() => [currentSectionIndex, setCurrentSectionIndex], [currentSectionIndex, setCurrentSectionIndex]);
3517
+ const sections = useSectionsWithChapter();
3518
+ const currentSection = sections[currentSectionIndex];
3519
+ return /*#__PURE__*/React.createElement(CurrentChapterContext.Provider, {
3520
+ value: currentSection === null || currentSection === void 0 ? void 0 : currentSection.chapter
3521
+ }, /*#__PURE__*/React.createElement(CurrentSectionIndexStateContext.Provider, {
3522
+ value: currentSectionIndexState
3523
+ }, children));
3524
+ }
3525
+
3526
+ /**
3527
+ * Returns chapter containing the current scroll position.
3528
+ *
3529
+ * @example
3530
+ *
3531
+ * const chapter = useCurrentChapter();
3532
+ * chapter // =>
3533
+ * {
3534
+ * id: 3,
3535
+ * permaId: 5,
3536
+ * title: 'Chapter 1',
3537
+ * summary: 'An introductory chapter',
3538
+ * chapterSlug: 'chapter-1'
3539
+ * }
3540
+ */
3541
+ function useCurrentChapter() {
3542
+ return useContext(CurrentChapterContext);
3543
+ }
3544
+ function useCurrentSectionIndexState() {
3545
+ return useContext(CurrentSectionIndexStateContext);
3546
+ }
3547
+
3548
+ function usePostMessageListener(receiveData) {
3549
+ useEffect(() => {
3550
+ if (window.parent !== window) {
3551
+ window.addEventListener('message', receive);
3552
+ }
3553
+ return () => window.removeEventListener('message', receive);
3554
+ function receive(message) {
3555
+ if (window.location.href.indexOf(message.origin) === 0) {
3556
+ receiveData(message.data);
3557
+ }
3558
+ }
3559
+ }, [receiveData]);
3560
+ }
3561
+
3562
+ var contentStyles = {"Content":"Content-module_Content__m7urk"};
3563
+
3564
+ var styles$n = {"focusOutlineDisabled":"focusOutline-module_focusOutlineDisabled__KV7d-"};
3565
+
3566
+ const FocusVisibleContext = createContext();
3567
+ function useFocusOutlineVisible() {
3568
+ return useContext(FocusVisibleContext);
3569
+ }
3570
+ function FocusOutlineProvider({
3571
+ children
3572
+ }) {
3573
+ const [value, setValue] = useState();
3574
+ useEffect(() => {
3575
+ document.body.addEventListener('keydown', enable);
3576
+ document.body.addEventListener('mousedown', disable);
3577
+ disable();
3578
+ return () => {
3579
+ document.body.removeEventListener('keydown', enable);
3580
+ document.body.removeEventListener('mousedown', disable);
3581
+ };
3582
+ function enable() {
3583
+ document.body.classList.remove(styles$n.focusOutlineDisabled);
3584
+ setValue(true);
3585
+ }
3586
+ function disable() {
3587
+ document.body.classList.add(styles$n.focusOutlineDisabled);
3588
+ setValue(false);
3589
+ }
3590
+ }, []);
3591
+ return /*#__PURE__*/React.createElement(FocusVisibleContext.Provider, {
3592
+ value: value
3593
+ }, children);
3594
+ }
3595
+
3596
+ const PhonePlatformProvider = extensible('PhonePlatformProvider', function PhonePlatformProvider({
3597
+ children
3598
+ }) {
3599
+ const isPhonePlatform = useBrowserFeature('phone platform');
3600
+ return /*#__PURE__*/React.createElement(PhonePlatformContext.Provider, {
3601
+ value: isPhonePlatform
3602
+ }, children);
3603
+ });
3604
+
3605
+ const AudioFocusContext = createContext();
3606
+ function AudioFocusProvider({
3607
+ children
3608
+ }) {
3609
+ const [currentKey, setCurrentKey] = useState([]);
3610
+ const value = useMemo(() => [currentKey, setCurrentKey], [currentKey, setCurrentKey]);
3611
+ return /*#__PURE__*/React.createElement(AudioFocusContext.Provider, {
3612
+ value: value
3613
+ }, children);
3614
+ }
3615
+
3616
+ /**
3617
+ * Prevent parallel playback of multiple media elements.
3618
+ *
3619
+ * @param {Object} options
3620
+ * @param {number} options.key - Unique id used to identify the element.
3621
+ * @param {boolean} options.request - Set to true to request audio focus.
3622
+ * @param {Function} options.onLost -
3623
+ * Callback that will be invoked if another element requests audio
3624
+ * focus, thereby preempting your hold of audio focus. The callback
3625
+ * should pause the element.
3626
+ */
3627
+ function useAudioFocus({
3628
+ key,
3629
+ request,
3630
+ onLost
3631
+ }) {
3632
+ const wasRequested = usePrevious(request);
3633
+ const [currentKey, setCurrentKey] = useContext(AudioFocusContext);
3634
+ const previousKey = usePrevious(currentKey);
3635
+ useEffect(() => {
3636
+ if (request && !wasRequested) {
3637
+ setCurrentKey(key);
3638
+ }
3639
+ }, [request, wasRequested, setCurrentKey, key]);
3640
+ useEffect(() => {
3641
+ if (previousKey === key && currentKey !== key) {
3642
+ onLost();
3643
+ }
3644
+ }, [currentKey, previousKey, key, onLost]);
3645
+ }
3646
+
3647
+ const ConsentContext = createContext();
3648
+ function ConsentProvider({
3649
+ consent,
3650
+ children
3651
+ }) {
3652
+ return /*#__PURE__*/React.createElement(ConsentContext.Provider, {
3653
+ value: consent
3654
+ }, children);
3655
+ }
3656
+ function useConsentRequested() {
3657
+ const consent = useContext(ConsentContext);
3658
+ const [request, setRequest] = useState({});
3659
+ useIsomorphicLayoutEffect(() => {
3660
+ let unmounted = false;
3661
+ (async () => {
3662
+ const {
3663
+ vendors,
3664
+ acceptAll,
3665
+ denyAll,
3666
+ save
3667
+ } = await consent.requested();
3668
+ if (!unmounted) {
3669
+ setRequest({
3670
+ vendors,
3671
+ acceptAll() {
3672
+ acceptAll();
3673
+ setRequest({});
3674
+ },
3675
+ denyAll() {
3676
+ denyAll();
3677
+ setRequest({});
3678
+ },
3679
+ save(decisions) {
3680
+ save(decisions);
3681
+ setRequest({});
3682
+ }
3683
+ });
3684
+ }
3685
+ })();
3686
+ return () => unmounted = true;
3687
+ }, [consent]);
3688
+ return request;
3689
+ }
3690
+ function useConsentGiven(vendorName) {
3691
+ const consent = useContext(ConsentContext);
3692
+ const {
3693
+ isEditable
3694
+ } = useContentElementEditorState();
3695
+ const isStaticPreview = useIsStaticPreview();
3696
+ const [consentGiven, setConsentGiven] = useState(isEditable || isStaticPreview);
3697
+ useIsomorphicLayoutEffect(() => {
3698
+ let unmounted = false;
3699
+ (async () => {
3700
+ if (!vendorName || isEditable || isStaticPreview) {
3701
+ return;
3702
+ }
3703
+ const result = await consent.requireAccepted(vendorName);
3704
+ if (!unmounted && result === 'fulfilled') {
3705
+ setConsentGiven(true);
3706
+ }
3707
+ })();
3708
+ return () => unmounted = true;
3709
+ }, [consent, vendorName]);
3710
+ const giveConsent = useCallback(() => consent.accept(vendorName), [consent, vendorName]);
3711
+ return [consentGiven, giveConsent];
3712
+ }
3713
+
3714
+ // eslint-disable-next-line no-script-url
3715
+ const displayPrivacySettingsUrl = 'javascript:pageflowDisplayPrivacySettings()';
3716
+
3717
+ /**
3718
+ * Returns the privacy link URL, label and link props. When vendors
3719
+ * are passed, the vendors query parameter and consent hash are
3720
+ * appended to the URL. Handles absolute, protocol-relative and
3721
+ * relative URLs.
3722
+ *
3723
+ * @param {Object} [options]
3724
+ * @param {string} [options.vendors] - Comma-separated vendor names.
3725
+ *
3726
+ * @example
3727
+ *
3728
+ * const {url, label, props} = usePrivacyLink({vendors: 'youtube'});
3729
+ * // props => {href: '...', target: '_blank', rel: 'noreferrer noopener'}
3730
+ */
3731
+ function usePrivacyLink({
3732
+ vendors
3733
+ } = {}) {
3734
+ const {
3735
+ privacy
3736
+ } = useLegalInfo();
3737
+ const url = vendors && privacy.url && privacy.url !== displayPrivacySettingsUrl ? appendVendorsParam(privacy.url, vendors) : privacy.url;
3738
+ return {
3739
+ url,
3740
+ label: privacy.label,
3741
+ props: linkProps(url)
3742
+ };
3743
+ }
3744
+ function linkProps(url) {
3745
+ if (url === displayPrivacySettingsUrl) {
3746
+ return {
3747
+ href: '#privacySettings',
3748
+ onClick(event) {
3749
+ window.pageflowDisplayPrivacySettings();
3750
+ event.preventDefault();
3751
+ }
3752
+ };
3753
+ }
3754
+ return {
3755
+ href: url,
3756
+ target: '_blank',
3757
+ rel: 'noreferrer noopener'
3758
+ };
3759
+ }
3760
+ function appendVendorsParam(privacyLinkUrl, vendors) {
3761
+ const isProtocolRelative = privacyLinkUrl.startsWith('//');
3762
+ const urlString = isProtocolRelative ? 'https:' + privacyLinkUrl : privacyLinkUrl;
3763
+ const url = new URL(urlString, 'https://localhost');
3764
+ url.searchParams.set('vendors', vendors);
3765
+ url.hash = '#consent';
3766
+ if (isProtocolRelative) {
3767
+ return url.toString().replace('https:', '');
3768
+ } else if (!privacyLinkUrl.includes('://')) {
3769
+ return url.pathname + url.search + url.hash;
3770
+ }
3771
+ return url.toString();
3772
+ }
3773
+
3774
+ var styles$o = {"optIn":"OptIn-module_optIn__3nHo1","optInIcon":"OptIn-module_optInIcon__3-81I","optInMessage":"OptIn-module_optInMessage__1OfTR","optInButton":"OptIn-module_optInButton__1LhtX","privacyLink":"OptIn-module_privacyLink__1dekq"};
3775
+
3776
+ function _extends$3() {
3777
+ _extends$3 = Object.assign ? Object.assign.bind() : function (target) {
3778
+ for (var i = 1; i < arguments.length; i++) {
3779
+ var source = arguments[i];
3780
+ for (var key in source) {
3781
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
3782
+ target[key] = source[key];
3783
+ }
3784
+ }
3785
+ }
3786
+ return target;
3787
+ };
3788
+ return _extends$3.apply(this, arguments);
3789
+ }
3790
+ var OptInIcon = (({
3791
+ styles = {},
3792
+ ...props
3793
+ }) => /*#__PURE__*/React.createElement("svg", _extends$3({
3794
+ xmlns: "http://www.w3.org/2000/svg",
3795
+ viewBox: "0 0 131 95"
3796
+ }, props), /*#__PURE__*/React.createElement("path", {
3797
+ d: "M32.01.01C46.678-.01 61.345.009 76.014.002 83.007.007 90-.009 96.99.011c.015 9.157.014 18.316 0 27.474-1.357.073-2.706.259-4.048.478-.01-7.986 0-15.975-.004-23.961-18.958-.003-37.917-.003-56.875 0l-.001 28.916c.01 2.37-.022 4.742.016 7.113 6.173-.025 12.348-.006 18.52-.011 5.804.01 11.609-.022 17.41.013-1 1.28-2.001 2.56-2.844 3.948-12.372.024-24.748-.011-37.12.019-.06-.365-.03-.735-.034-1.1V17.497c.007-5.83-.024-11.659.001-17.486zm17.617 8.004a5.999 5.999 0 014.359 1.49c1.273 1.116 2.048 2.8 2.013 4.498.042 1.806-.845 3.59-2.263 4.702-1.271 1.013-2.975 1.483-4.583 1.228a5.88 5.88 0 01-3.479-1.785c-1.44-1.459-2.013-3.695-1.475-5.67.6-2.448 2.905-4.346 5.428-4.463zm22.106 7.758c.181-.258.332-.54.547-.772 2.325 3.868 4.683 7.717 7.02 11.578.891 1.503 1.85 2.973 2.7 4.5a35.062 35.062 0 00-5.646 3.779c-.154.162-.387.14-.592.143-10.585-.014-21.174.014-31.762-.015.088-.228.308-.367.47-.542 3.79-3.745 7.58-7.484 11.365-11.232.098-.085.217-.265.366-.15 2.65 1.308 5.3 2.62 7.951 3.928 2.545-3.73 5.052-7.48 7.581-11.217zM0 21.042c.256-.058.517-.039.775-.039 9.175.007 18.349-.007 27.523.007l.064.076c.017 1.308-.012 2.618.015 3.927-5.416.038-10.834.001-16.252.018-.01 7.981-.013 15.962.002 23.944 11.917.013 23.834.013 35.752 0 .022-.674-.002-1.35.012-2.023 4.034.01 8.07.01 12.105 0 .002 11.349.01 22.698-.003 34.048-12.082-.025-24.163-.003-36.244-.01-7.911.007-15.823-.015-23.734.01-.02-19.988.01-39.975-.015-59.959zm3.435 4.043c-.904.236-1.577 1.152-1.482 2.086.079.997.994 1.837 1.999 1.82 1.367.002 2.736.015 4.105-.007 1.04-.036 1.928-.995 1.878-2.03-.003-.996-.867-1.896-1.868-1.925-1.294-.01-2.585.002-3.878-.005-.252.004-.51-.013-.754.061zm-.219 8.067c-.815.317-1.373 1.203-1.256 2.076.1.938.94 1.724 1.89 1.756 1.25.016 2.5-.002 3.752.008.439.008.9-.025 1.288-.246.73-.39 1.173-1.257 1.019-2.075-.136-.889-.95-1.62-1.852-1.645-1.328-.007-2.653.002-3.98-.004-.29-.005-.589.016-.86.13zm.219 7.923c-.762.2-1.372.884-1.471 1.665-.128.844.384 1.718 1.158 2.064.403.192.859.19 1.295.181 1.217-.008 2.434.011 3.651-.008 1.032-.047 1.92-.998 1.868-2.034-.007-.994-.87-1.891-1.87-1.922-1.293-.011-2.584.002-3.877-.006-.252-.001-.51-.008-.754.06zm-.01 8.003c-1.018.249-1.706 1.392-1.413 2.403.21.868 1.057 1.512 1.95 1.497 1.364-.003 2.728.01 4.09-.006 1.02-.034 1.906-.958 1.883-1.975.026-1.017-.858-1.958-1.88-1.981-1.252-.011-2.503.002-3.754-.003-.292-.004-.591-.018-.877.065zm48.107 0c-1.117.272-1.79 1.607-1.323 2.66a2.027 2.027 0 001.86 1.238c1.326.003 2.652.003 3.977 0 1.056.025 2.032-.916 1.996-1.978.045-1.022-.86-1.96-1.88-1.984-1.252-.008-2.503.003-3.754-.002-.293 0-.591-.017-.876.066zM12.13 53.016c-.015 7.981-.012 15.961-.001 23.943 11.917.003 23.836.003 35.753 0 .011-7.982.014-15.962-.001-23.943a14203.52 14203.52 0 00-35.75 0zm-8.694 4.05c-.797.208-1.422.943-1.482 1.764-.112 1.07.805 2.103 1.883 2.137 1.371.014 2.743.003 4.113.006 1.035.01 1.977-.89 1.986-1.928.054-1.033-.83-2.003-1.87-2.037-1.254-.01-2.508.003-3.763-.005-.289 0-.584-.014-.867.064zm48.108.003c-.951.235-1.623 1.244-1.456 2.208.123.947 1.016 1.71 1.972 1.696h3.997c1.031.013 1.994-.886 1.984-1.928.071-1.036-.829-2.011-1.866-2.037-1.254-.01-2.51.003-3.764-.005-.29 0-.586-.014-.867.066zM3.425 65.066c-.955.242-1.634 1.262-1.45 2.234.14.9.957 1.638 1.874 1.662 1.364.011 2.727 0 4.09.006 1.06.022 2.023-.925 1.997-1.984.027-1.02-.86-1.952-1.882-1.98-1.211-.012-2.426.002-3.637-.004-.332-.001-.669-.021-.992.066zm48.107.003c-.927.231-1.584 1.195-1.456 2.14.093.935.935 1.723 1.879 1.752 1.365.011 2.73 0 4.093.006 1.055.016 2.043-.917 1.994-1.984.045-1.023-.86-1.958-1.88-1.981-1.252-.011-2.502.002-3.753-.003-.294-.003-.592-.012-.877.07zM3.435 73.057c-.797.204-1.422.94-1.482 1.76-.111 1.07.802 2.112 1.883 2.138 1.371.013 2.743.002 4.113.005 1.035.017 1.977-.891 1.986-1.928.054-1.033-.835-1.997-1.87-2.037-1.254-.01-2.508.003-3.763-.005-.289.001-.584-.01-.867.067zm48.108 0c-.887.22-1.543 1.118-1.476 2.029.035.974.892 1.837 1.874 1.869 1.37.013 2.742.002 4.114.005 1.033.017 1.993-.883 1.985-1.925.071-1.039-.833-2.006-1.868-2.04-1.254-.01-2.509.003-3.763-.005-.289.001-.585-.01-.866.067zM96.83 31.045c6.813-.36 13.73 1.456 19.431 5.154a32.396 32.396 0 019.482 9.342 31.527 31.527 0 015.043 13.773c.625 5.36-.123 10.88-2.225 15.867-1.766 4.254-4.499 8.108-7.91 11.243a32.605 32.605 0 01-11.584 6.844 33.066 33.066 0 01-15.656 1.337 32.59 32.59 0 01-13.329-5.235c-5.2-3.514-9.323-8.551-11.692-14.307a31.532 31.532 0 01-2.327-14.038 31.433 31.433 0 013.839-13.243 32.232 32.232 0 018.329-9.799c5.259-4.156 11.865-6.62 18.6-6.938zm15.6 12.011c-8.543.979-17.086 1.933-25.627 2.92-.013 8.152.006 16.308-.008 24.462-2.325-.848-5.015-.792-7.24.318-1.33.665-2.493 1.763-2.997 3.169-.503 1.356-.289 2.934.528 4.128.752 1.154 1.947 1.978 3.235 2.465 1.48.569 3.115.675 4.68.452 1.888-.295 3.742-1.222 4.862-2.784.67-.936.965-2.102.894-3.237-.014-7.054.008-14.105-.01-21.158 1.976-.282 3.965-.458 5.946-.7 4.944-.56 9.885-1.124 14.827-1.682V67.42c-1.677-.563-3.506-.755-5.247-.362-1.764.38-3.483 1.32-4.479 2.84a4.618 4.618 0 00-.637 3.729c.32 1.196 1.12 2.243 2.139 2.959 1.533 1.101 3.474 1.576 5.355 1.489 2.036-.083 4.111-.843 5.498-2.353a5.078 5.078 0 001.329-3.83c-.007-6.755-.002-13.51-.005-20.265.058-2.962-.002-5.924-.002-8.884-1.018.053-2.03.212-3.04.313z"
3798
+ })));
3799
+
3800
+ /**
3801
+ * Render opt in prompt instead of children if third party consent
3802
+ * cookie has been configured in theme options and user has not given
3803
+ * consent for passed provider.
3804
+ *
3805
+ * @param {Object} props
3806
+ * @param {string} props.providerName -
3807
+ * Only render children if user has given consent for this provider.
3808
+ * @param {React.ReactElement} props.children -
3809
+ * Children to conditionally render.
3810
+ * @param {function} [props.wrapper] -
3811
+ * Function that receives children to allow wrapping opt-in prompt
3812
+ * in custom elements.
3813
+ * @param {boolean} [props.icon=true] -
3814
+ * Allow hiding the icon in the opt-in prompt.
3815
+ *
3816
+ * @name ThirdPartyOptIn
3817
+ */
3818
+ function OptIn({
3819
+ children,
3820
+ providerName,
3821
+ wrapper,
3822
+ icon
3823
+ }) {
3824
+ const {
3825
+ t
3826
+ } = useI18n();
3827
+ const {
3828
+ contentElementId
3829
+ } = useContentElementAttributes();
3830
+ const contentElementConsentVendor = useContentElementConsentVendor({
3831
+ contentElementId
3832
+ });
3833
+ providerName = providerName || (contentElementConsentVendor === null || contentElementConsentVendor === void 0 ? void 0 : contentElementConsentVendor.name);
3834
+ const privacyLink = usePrivacyLink({
3835
+ vendors: providerName
3836
+ });
3837
+ const cookieMessage = (contentElementConsentVendor === null || contentElementConsentVendor === void 0 ? void 0 : contentElementConsentVendor.optInPrompt) || t(`pageflow_scrolled.public.third_party_consent.opt_in_prompt.${providerName}`);
3838
+ const [consentedHere, setConsentedHere] = useState(false);
3839
+ const [consentGiven, giveConsent] = useConsentGiven(providerName);
3840
+ if (consentGiven || !providerName) {
3841
+ return typeof children === 'function' ? children({
3842
+ consentedHere
3843
+ }) : children;
3844
+ }
3845
+ function accept() {
3846
+ giveConsent(providerName);
3847
+ setConsentedHere(true);
3848
+ }
3849
+ return wrapper( /*#__PURE__*/React.createElement("div", {
3850
+ className: styles$o.optIn
3851
+ }, icon && /*#__PURE__*/React.createElement("div", {
3852
+ className: styles$o.optInIcon
3853
+ }, /*#__PURE__*/React.createElement(OptInIcon, null)), /*#__PURE__*/React.createElement("div", {
3854
+ className: styles$o.optInMessage
3855
+ }, cookieMessage), privacyLink.url && /*#__PURE__*/React.createElement("div", {
3856
+ className: styles$o.privacyLink
3857
+ }, /*#__PURE__*/React.createElement("a", privacyLink.props, privacyLink.label)), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("button", {
3858
+ className: styles$o.optInButton,
3859
+ onClick: accept
3860
+ }, t('pageflow_scrolled.public.third_party_consent.confirm')))));
3861
+ }
3862
+ OptIn.defaultProps = {
3863
+ icon: true,
3864
+ wrapper: children => children
3865
+ };
3866
+
3867
+ var styles$p = {"optOut":"OptOutInfo-module_optOut__2Q3d5","tooltip":"OptOutInfo-module_tooltip__2bpU0","icon":"OptOutInfo-module_icon__1kL6Q utils-module_unstyledButton__3rgne","full":"OptOutInfo-module_full__s_Ono"};
3868
+
3869
+ /**
3870
+ * Display info tooltip with a link to opt out of third party
3871
+ * embeds. Opt out url needs to be configured in theme options.
3872
+ *
3873
+ * @param {Object} props
3874
+ * @param {string} props.providerName -
3875
+ * Only display if user has given consent for this provider.
3876
+ * @param {boolean} [hide] -
3877
+ * Temporarily hide the tooltip, e.g. while the embed is playing
3878
+ *
3879
+ * @name ThirdPartyOptOutInfo
3880
+ */
3881
+ function OptOutInfo({
3882
+ providerName,
3883
+ hide,
3884
+ inset
3885
+ }) {
3886
+ var _theme$options$thirdP;
3887
+ const {
3888
+ t
3889
+ } = useI18n();
3890
+ const theme = useTheme();
3891
+ const optOutUrl = (_theme$options$thirdP = theme.options.thirdPartyConsent) === null || _theme$options$thirdP === void 0 ? void 0 : _theme$options$thirdP.optOutUrl;
3892
+ const {
3893
+ width,
3894
+ contentElementId
3895
+ } = useContentElementAttributes();
3896
+ const contentElementConsentVendor = useContentElementConsentVendor({
3897
+ contentElementId
3898
+ });
3899
+ providerName = providerName || (contentElementConsentVendor === null || contentElementConsentVendor === void 0 ? void 0 : contentElementConsentVendor.name);
3900
+ const [consentGiven] = useConsentGiven(providerName);
3901
+ if (!optOutUrl || !consentGiven) {
3902
+ return null;
3903
+ }
3904
+ const linkText = t('pageflow_scrolled.public.third_party_consent.opt_out.prompt_link');
3905
+ const linkHtml = `<a href="${optOutUrl}" target="_blank" rel="noopener noreferrer">${linkText}</a>`;
3906
+ const html = t('pageflow_scrolled.public.third_party_consent.opt_out.prompt', {
3907
+ link: linkHtml
3908
+ });
3909
+ return /*#__PURE__*/React.createElement("div", {
3910
+ className: classNames(styles$p.optOut, {
3911
+ [styles$p.full]: width === widths.full || inset
3912
+ }),
3913
+ style: hide ? {
3914
+ opacity: 0,
3915
+ visibility: 'hidden'
3916
+ } : undefined
3917
+ }, /*#__PURE__*/React.createElement("button", {
3918
+ className: styles$p.icon
3919
+ }, /*#__PURE__*/React.createElement(ThemeIcon, {
3920
+ name: "information"
3921
+ })), /*#__PURE__*/React.createElement("div", {
3922
+ className: styles$p.tooltip
3923
+ }, /*#__PURE__*/React.createElement("div", {
3924
+ dangerouslySetInnerHTML: {
3925
+ __html: html
3926
+ }
3927
+ })));
3928
+ }
3929
+
3930
+ function registerVendors({
3931
+ contentElementTypes,
3932
+ seed,
3933
+ consent,
3934
+ cookieName
3935
+ }) {
3936
+ const options = seed.config.theme.options.thirdPartyConsent;
3937
+ const locale = seed.collections.entries[0].locale;
3938
+ cookieName = cookieName || (options === null || options === void 0 ? void 0 : options.cookieName);
3939
+ [...seed.config.consentVendors, ...contentElementTypes.consentVendors({
3940
+ contentElements: seed.collections.contentElements,
3941
+ t(key, options) {
3942
+ return I18n.t(key, {
3943
+ ...options,
3944
+ locale
3945
+ });
3946
+ }
3947
+ })].forEach(vendor => {
3948
+ var _options$cookieProvid;
3949
+ consent.registerVendor(vendor.name, {
3950
+ displayName: vendor.displayName,
3951
+ description: vendor.description,
3952
+ paradigm: cookieName ? vendor.paradigm || 'opt-in' : 'skip',
3953
+ cookieName: cookieName,
3954
+ cookieKey: options === null || options === void 0 ? void 0 : (_options$cookieProvid = options.cookieProviderNameMapping) === null || _options$cookieProvid === void 0 ? void 0 : _options$cookieProvid[vendor.name],
3955
+ cookieDomain: options === null || options === void 0 ? void 0 : options.cookieDomain
3956
+ });
3957
+ });
3958
+ consent.closeVendorRegistration();
3959
+ }
3960
+
3961
+ function RootProviders({
3962
+ seed,
3963
+ consent: consent$1 = consent,
3964
+ children
3965
+ }) {
3966
+ return /*#__PURE__*/React.createElement(FocusOutlineProvider, null, /*#__PURE__*/React.createElement(BrowserFeaturesProvider, null, /*#__PURE__*/React.createElement(ExtensionsProvider, null, /*#__PURE__*/React.createElement(PhonePlatformProvider, null, /*#__PURE__*/React.createElement(PhoneLayoutProvider, null, /*#__PURE__*/React.createElement(MediaMutedProvider, null, /*#__PURE__*/React.createElement(AudioFocusProvider, null, /*#__PURE__*/React.createElement(EntryStateProvider, {
3967
+ seed: seed
3968
+ }, /*#__PURE__*/React.createElement(CurrentSectionProvider, null, /*#__PURE__*/React.createElement(LocaleProvider, null, /*#__PURE__*/React.createElement(ConsentProvider, {
3969
+ consent: consent$1
3970
+ }, /*#__PURE__*/React.createElement(ScrollTargetEmitterProvider, null, /*#__PURE__*/React.createElement(ActiveExcursionProvider, null, children)))))))))))));
3971
+ }
3972
+
3973
+ const ContentElementConfigurationUpdateContext = React.createContext(() => {});
3974
+ function useContentElementConfigurationUpdate() {
3975
+ return useContext(ContentElementConfigurationUpdateContext);
3976
+ }
3977
+
3978
+ var styles$q = {"crop":"SectionThumbnail-module_crop__Q1nZj","scale":"SectionThumbnail-module_scale__2tKDG"};
3979
+
3980
+ function StandaloneSectionThumbnail({
3981
+ seed,
3982
+ ...props
3983
+ }) {
3984
+ return /*#__PURE__*/React.createElement(RootProviders, {
3985
+ seed: seed
3986
+ }, /*#__PURE__*/React.createElement(SectionThumbnail, props));
3987
+ }
3988
+ function SectionThumbnail({
3989
+ sectionPermaId,
3990
+ subscribe,
3991
+ scale
3992
+ }) {
3993
+ const dispatch = useEntryStateDispatch();
3994
+ useEffect(() => {
3995
+ if (subscribe) {
3996
+ return subscribe(dispatch);
3997
+ }
3998
+ }, [subscribe, dispatch]);
3999
+ const section = useSection({
4000
+ sectionPermaId
4001
+ });
4002
+ const scaleFactor = scale ? 5 : 1;
4003
+ if (section) {
4004
+ return /*#__PURE__*/React.createElement(StaticPreview, null, /*#__PURE__*/React.createElement(Measure, {
4005
+ client: true
4006
+ }, ({
4007
+ measureRef,
4008
+ contentRect
4009
+ }) => /*#__PURE__*/React.createElement(FullscreenDimensionProvider, clientDimensions(contentRect, scaleFactor), /*#__PURE__*/React.createElement("div", {
4010
+ ref: measureRef,
4011
+ className: styles$q.crop,
4012
+ inert: ""
4013
+ }, /*#__PURE__*/React.createElement("div", {
4014
+ className: classNames({
4015
+ [styles$q.scale]: scale
4016
+ })
4017
+ }, /*#__PURE__*/React.createElement("div", {
4018
+ className: contentStyles.Content,
4019
+ style: viewportUnitCustomProperties(clientDimensions(contentRect, scaleFactor))
4020
+ }, /*#__PURE__*/React.createElement(ConnectedSection, {
4021
+ state: "active",
4022
+ domIdPrefix: "section-preview",
4023
+ section: {
4024
+ ...section,
4025
+ transition: 'preview'
4026
+ }
4027
+ })))))));
4028
+ } else {
4029
+ return /*#__PURE__*/React.createElement("div", {
4030
+ className: styles$q.root
4031
+ }, "Not found.");
4032
+ }
4033
+ }
4034
+ SectionThumbnail.defaultProps = {
4035
+ scale: true,
4036
+ subscribe: () => {}
4037
+ };
4038
+ function clientDimensions(contentRect, scaleFactor) {
4039
+ return {
4040
+ width: contentRect.client.width && Math.ceil(contentRect.client.width * scaleFactor),
4041
+ height: contentRect.client.height && Math.ceil(contentRect.client.height * scaleFactor)
4042
+ };
4043
+ }
4044
+ function viewportUnitCustomProperties({
4045
+ width,
4046
+ height
4047
+ }) {
4048
+ return {
4049
+ '--vw': width && `${width / 100}px`,
4050
+ '--vh': height && `${height / 100}px`
4051
+ };
4052
+ }
4053
+
4054
+ const WidgetConfigurationUpdateContext = React.createContext(() => {});
4055
+ function useWidgetConfigurationUpdate() {
4056
+ return useContext(WidgetConfigurationUpdateContext);
4057
+ }
4058
+
4059
+ const ContentElementEditorCommandEmitterContext = createContext({
4060
+ on() {},
4061
+ off() {}
4062
+ });
4063
+ function useContentElementEditorCommandSubscription(callback) {
4064
+ const {
4065
+ contentElementId
4066
+ } = useContentElementAttributes();
4067
+ const emitter = useContext(ContentElementEditorCommandEmitterContext);
4068
+ useEffect(() => {
4069
+ emitter.on(`command:${contentElementId}`, callback);
4070
+ return () => emitter.off(`command:${contentElementId}`, callback);
4071
+ }, [emitter, callback, contentElementId]);
4072
+ }
4073
+
4074
+ function capitalize$1(string) {
4075
+ return string.charAt(0).toUpperCase() + string.slice(1);
4076
+ }
4077
+
4078
+ const utils = {
4079
+ capitalize: capitalize$1,
4080
+ camelize,
4081
+ isBlank,
4082
+ isBlankEditableTextValue,
4083
+ isTranslucentColor,
4084
+ presence
4085
+ };
4086
+
4087
+ var tableStyles = {"table":"EditableTable-module_table__uncog"};
4088
+
4089
+ const defaultValue = [{
4090
+ type: 'row',
4091
+ children: [{
4092
+ type: 'label',
4093
+ children: [{
4094
+ text: ''
4095
+ }]
4096
+ }, {
4097
+ type: 'value',
4098
+ children: [{
4099
+ text: ''
4100
+ }]
4101
+ }]
4102
+ }];
4103
+ const EditableTable = extensible('EditableTable', function EditableTable({
4104
+ value,
4105
+ className,
4106
+ labelScaleCategory = 'body',
4107
+ valueScaleCategory = 'body',
4108
+ stackedInPhoneLayout = false
4109
+ }) {
4110
+ const phoneLayout = usePhoneLayout();
4111
+ const stacked = stackedInPhoneLayout && phoneLayout;
4112
+ return /*#__PURE__*/React.createElement("table", {
4113
+ className: classNames(className, tableStyles.table),
4114
+ "data-stacked": stacked ? '' : undefined
4115
+ }, /*#__PURE__*/React.createElement("tbody", null, render(value || defaultValue, {
4116
+ labelScaleCategory,
4117
+ valueScaleCategory
4118
+ })));
4119
+ });
4120
+ function render(children, options) {
4121
+ return children.map((element, index) => {
4122
+ if (element.type) {
4123
+ return createRenderElement(options)({
4124
+ attributes: {
4125
+ key: index
4126
+ },
4127
+ element,
4128
+ children: render(element.children, options)
4129
+ });
4130
+ } else {
4131
+ return renderLeaf({
4132
+ attributes: {
4133
+ key: index
4134
+ },
4135
+ leaf: element,
4136
+ children: children.length === 1 && element.text.trim() === '' ? '\uFEFF' : element.text
4137
+ });
4138
+ }
4139
+ });
4140
+ }
4141
+ function createRenderElement({
4142
+ labelScaleCategory,
4143
+ valueScaleCategory
4144
+ }) {
4145
+ return function renderElement({
4146
+ attributes,
4147
+ children,
4148
+ element
4149
+ }) {
4150
+ switch (element.type) {
4151
+ case 'row':
4152
+ return /*#__PURE__*/React.createElement("tr", attributes, children);
4153
+ case 'link':
4154
+ return renderLink({
4155
+ attributes,
4156
+ children,
4157
+ element
4158
+ });
4159
+ case 'label':
4160
+ return /*#__PURE__*/React.createElement("td", Object.assign({}, attributes, cellAttributes(element)), /*#__PURE__*/React.createElement(Text, {
4161
+ scaleCategory: labelScaleCategory
4162
+ }, children));
4163
+ default:
4164
+ return /*#__PURE__*/React.createElement("td", Object.assign({}, attributes, cellAttributes(element)), /*#__PURE__*/React.createElement(Text, {
4165
+ scaleCategory: valueScaleCategory
4166
+ }, children));
4167
+ }
4168
+ };
4169
+ }
4170
+ function cellAttributes(element) {
4171
+ return utils.isBlankEditableTextValue([element]) ? {
4172
+ 'data-blank': ''
4173
+ } : {};
4174
+ }
4175
+
4176
+ var frontendStyles = {"root":"EditableInlineText-module_root__3eA-J","hyphens-manual":"EditableInlineText-module_hyphens-manual__3Lj4H","hyphens-none":"EditableInlineText-module_hyphens-none__1UvNH","textEffects":"EditableInlineText-module_textEffects__Wqvj0"};
4177
+
4178
+ var styles$r = {"placeholder":"Placeholder-module_placeholder__L1CTm"};
4179
+
4180
+ export { Atmo as $, AtmoProvider as A, OptOutInfo as B, ConnectedSection as C, useConsentRequested as D, EventContextDataProvider as E, Fullscreen as F, AiIndicatorIcon as G, useAiIndicatorLabel as H, InlineFileRights as I, SectionIntersectionObserver as J, usePrivacyLink as K, getTransitionNames as L, getAvailableTransitionNames as M, getAppearanceSectionScopeName as N, OptIn as O, PlayerEventContextDataProvider as P, Image as Q, RootProviders as R, SelectableWidget as S, MediaPlayer as T, getInitialPlayerState as U, playerStateReducer as V, Widget as W, usePlayerState as X, VideoPlayer as Y, AudioPlayer as Z, processSources as _, usePostMessageListener as a, AtmoContext as a0, useAtmo as a1, StandaloneSectionThumbnail as a2, SectionThumbnail as a3, MotifAreaVisibilityProvider as a4, ForcePaddingContext as a5, ContentElementConfigurationUpdateContext as a6, WidgetConfigurationUpdateContext as a7, createRenderElement as a8, usePhoneLayout as a9, tableStyles as aa, useContentElementConfigurationUpdate as b, contentStyles as c, usePrevious as d, useFocusOutlineVisible as e, useTextTracks as f, getEventObject as g, useMediaMuted as h, isBlankEditableTextValue as i, useVideoQualitySetting as j, useIsomorphicLayoutEffect as k, frontendStyles as l, utils as m, styles$c as n, useAudioFocus as o, useBackgroundFile as p, useWidgetConfigurationUpdate as q, registerVendors as r, styles$r as s, useContentElementEditorCommandSubscription as t, useCurrentSectionIndexState as u, ContentElementEditorCommandEmitterContext as v, useCurrentChapter as w, useOnUnmuteMedia as x, usePortraitOrientation as y, EditableTable as z };