{"version":3,"file":"Main.js","sources":["../../../../../node_modules/throttle-debounce/esm/index.js","../../Private/Fusion/Components/Molecules/StackedNavigation.js","../../../../../node_modules/preact/dist/preact.mjs","../../../../../node_modules/preact/hooks/dist/hooks.mjs","../../Private/Fusion/Components/Organisms/SearchContents/Components/SearchResult/Results.js","../../Private/Fusion/Components/Organisms/SearchContents/Components/SearchBar/FilterSideBar.js","../../Private/Fusion/Components/Organisms/SearchContents/Components/SearchBar.js","../../Private/Fusion/Components/Organisms/SearchContents/SearchContents.js","../../Private/Fusion/Components/Organisms/AudioPlayer/AudioPlayer.js","../../Private/Fusion/Components/Organisms/ViewedCheckButton/components/Button.js","../../Private/Fusion/Components/Organisms/ViewedCheckButton/ViewedCheckButton.js","../../Private/Fusion/Preact/Helpers/useStateWithCallback.js","../../Private/Fusion/Components/Organisms/Modal/Dialog/Dialog.js","../../Private/Fusion/Components/Organisms/Quiz/components/Button.js","../../Private/Fusion/Components/Organisms/Quiz/components/Question.js","../../Private/Fusion/Components/Organisms/Quiz/components/Radio.js","../../Private/Fusion/Components/Organisms/Quiz/components/Answers.js","../../Private/Fusion/Components/Organisms/Quiz/components/References.js","../../Private/Fusion/Components/Organisms/Quiz/components/Comments.js","../../Private/Fusion/Components/Organisms/Modal/Modal.js","../../Private/Fusion/Components/Organisms/Quiz/Quiz.js","../../Private/Fusion/Main.js","../../Private/Fusion/Components/Molecules/NavigationToggler.js"],"sourcesContent":["/* eslint-disable no-undefined,no-param-reassign,no-shadow */\n\n/**\n * Throttle execution of a function. Especially useful for rate limiting\n * execution of handlers on events like resize and scroll.\n *\n * @param {number} delay - A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher)\n * are most useful.\n * @param {Function} callback - A function to be executed after delay milliseconds. The `this` context and all arguments are passed through,\n * as-is, to `callback` when the throttled-function is executed.\n * @param {object} [options] - An object to configure options.\n * @param {boolean} [options.noTrailing] - Optional, defaults to false. If noTrailing is true, callback will only execute every `delay` milliseconds\n * while the throttled-function is being called. If noTrailing is false or unspecified, callback will be executed\n * one final time after the last throttled-function call. (After the throttled-function has not been called for\n * `delay` milliseconds, the internal counter is reset).\n * @param {boolean} [options.noLeading] - Optional, defaults to false. If noLeading is false, the first throttled-function call will execute callback\n * immediately. If noLeading is true, the first the callback execution will be skipped. It should be noted that\n * callback will never executed if both noLeading = true and noTrailing = true.\n * @param {boolean} [options.debounceMode] - If `debounceMode` is true (at begin), schedule `clear` to execute after `delay` ms. If `debounceMode` is\n * false (at end), schedule `callback` to execute after `delay` ms.\n *\n * @returns {Function} A new, throttled, function.\n */\nfunction throttle (delay, callback, options) {\n var _ref = options || {},\n _ref$noTrailing = _ref.noTrailing,\n noTrailing = _ref$noTrailing === void 0 ? false : _ref$noTrailing,\n _ref$noLeading = _ref.noLeading,\n noLeading = _ref$noLeading === void 0 ? false : _ref$noLeading,\n _ref$debounceMode = _ref.debounceMode,\n debounceMode = _ref$debounceMode === void 0 ? undefined : _ref$debounceMode;\n /*\n * After wrapper has stopped being called, this timeout ensures that\n * `callback` is executed at the proper times in `throttle` and `end`\n * debounce modes.\n */\n\n\n var timeoutID;\n var cancelled = false; // Keep track of the last time `callback` was executed.\n\n var lastExec = 0; // Function to clear existing timeout\n\n function clearExistingTimeout() {\n if (timeoutID) {\n clearTimeout(timeoutID);\n }\n } // Function to cancel next exec\n\n\n function cancel(options) {\n var _ref2 = options || {},\n _ref2$upcomingOnly = _ref2.upcomingOnly,\n upcomingOnly = _ref2$upcomingOnly === void 0 ? false : _ref2$upcomingOnly;\n\n clearExistingTimeout();\n cancelled = !upcomingOnly;\n }\n /*\n * The `wrapper` function encapsulates all of the throttling / debouncing\n * functionality and when executed will limit the rate at which `callback`\n * is executed.\n */\n\n\n function wrapper() {\n for (var _len = arguments.length, arguments_ = new Array(_len), _key = 0; _key < _len; _key++) {\n arguments_[_key] = arguments[_key];\n }\n\n var self = this;\n var elapsed = Date.now() - lastExec;\n\n if (cancelled) {\n return;\n } // Execute `callback` and update the `lastExec` timestamp.\n\n\n function exec() {\n lastExec = Date.now();\n callback.apply(self, arguments_);\n }\n /*\n * If `debounceMode` is true (at begin) this is used to clear the flag\n * to allow future `callback` executions.\n */\n\n\n function clear() {\n timeoutID = undefined;\n }\n\n if (!noLeading && debounceMode && !timeoutID) {\n /*\n * Since `wrapper` is being called for the first time and\n * `debounceMode` is true (at begin), execute `callback`\n * and noLeading != true.\n */\n exec();\n }\n\n clearExistingTimeout();\n\n if (debounceMode === undefined && elapsed > delay) {\n if (noLeading) {\n /*\n * In throttle mode with noLeading, if `delay` time has\n * been exceeded, update `lastExec` and schedule `callback`\n * to execute after `delay` ms.\n */\n lastExec = Date.now();\n\n if (!noTrailing) {\n timeoutID = setTimeout(debounceMode ? clear : exec, delay);\n }\n } else {\n /*\n * In throttle mode without noLeading, if `delay` time has been exceeded, execute\n * `callback`.\n */\n exec();\n }\n } else if (noTrailing !== true) {\n /*\n * In trailing throttle mode, since `delay` time has not been\n * exceeded, schedule `callback` to execute `delay` ms after most\n * recent execution.\n *\n * If `debounceMode` is true (at begin), schedule `clear` to execute\n * after `delay` ms.\n *\n * If `debounceMode` is false (at end), schedule `callback` to\n * execute after `delay` ms.\n */\n timeoutID = setTimeout(debounceMode ? clear : exec, debounceMode === undefined ? delay - elapsed : delay);\n }\n }\n\n wrapper.cancel = cancel; // Return the wrapper function.\n\n return wrapper;\n}\n\n/* eslint-disable no-undefined */\n/**\n * Debounce execution of a function. Debouncing, unlike throttling,\n * guarantees that a function is only executed a single time, either at the\n * very beginning of a series of calls, or at the very end.\n *\n * @param {number} delay - A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher) are most useful.\n * @param {Function} callback - A function to be executed after delay milliseconds. The `this` context and all arguments are passed through, as-is,\n * to `callback` when the debounced-function is executed.\n * @param {object} [options] - An object to configure options.\n * @param {boolean} [options.atBegin] - Optional, defaults to false. If atBegin is false or unspecified, callback will only be executed `delay` milliseconds\n * after the last debounced-function call. If atBegin is true, callback will be executed only at the first debounced-function call.\n * (After the throttled-function has not been called for `delay` milliseconds, the internal counter is reset).\n *\n * @returns {Function} A new, debounced function.\n */\n\nfunction debounce (delay, callback, options) {\n var _ref = options || {},\n _ref$atBegin = _ref.atBegin,\n atBegin = _ref$atBegin === void 0 ? false : _ref$atBegin;\n\n return throttle(delay, callback, {\n debounceMode: atBegin !== false\n });\n}\n\nexport { debounce, throttle };\n//# sourceMappingURL=index.js.map\n","window.addEventListener('DOMContentLoaded', () => {\n\n\n\n});","var n,l,u,i,t,o,r,f={},e=[],c=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function s(n,l){for(var u in l)n[u]=l[u];return n}function a(n){var l=n.parentNode;l&&l.removeChild(n)}function h(l,u,i){var t,o,r,f={};for(r in u)\"key\"==r?t=u[r]:\"ref\"==r?o=u[r]:f[r]=u[r];if(arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):i),\"function\"==typeof l&&null!=l.defaultProps)for(r in l.defaultProps)void 0===f[r]&&(f[r]=l.defaultProps[r]);return v(l,f,t,o,null)}function v(n,i,t,o,r){var f={type:n,props:i,key:t,ref:o,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==r?++u:r};return null==r&&null!=l.vnode&&l.vnode(f),f}function y(){return{current:null}}function p(n){return n.children}function d(n,l){this.props=n,this.context=l}function _(n,l){if(null==l)return n.__?_(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l0?v(k.type,k.props,k.key,null,k.__v):k)){if(k.__=u,k.__b=u.__b+1,null===(d=x[h])||d&&k.key==d.key&&k.type===d.type)x[h]=void 0;else for(y=0;y2&&(f.children=arguments.length>3?n.call(arguments,2):i),v(l.type,f,t||l.key,o||l.ref,null)}function B(n,l){var u={__c:l=\"__cC\"+r++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,i;return this.getChildContext||(u=[],(i={})[l]=this,this.getChildContext=function(){return i},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(b)},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n)}}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n=e.slice,l={__e:function(n,l,u,i){for(var t,o,r;l=l.__;)if((t=l.__c)&&!t.__)try{if((o=t.constructor)&&null!=o.getDerivedStateFromError&&(t.setState(o.getDerivedStateFromError(n)),r=t.__d),null!=t.componentDidCatch&&(t.componentDidCatch(n,i||{}),r=t.__d),r)return t.__E=t}catch(l){n=l}throw n}},u=0,i=function(n){return null!=n&&void 0===n.constructor},d.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=s({},this.state),\"function\"==typeof n&&(n=n(s({},u),this.props)),n&&s(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),b(this))},d.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),b(this))},d.prototype.render=p,t=[],g.__r=0,r=0;export{P as render,S as hydrate,h as createElement,h,p as Fragment,y as createRef,i as isValidElement,d as Component,q as cloneElement,B as createContext,x as toChildArray,l as options};\n//# sourceMappingURL=preact.module.js.map\n","import{options as n}from\"preact\";var t,r,u,i,o=0,c=[],f=[],e=n.__b,a=n.__r,v=n.diffed,l=n.__c,m=n.unmount;function d(t,u){n.__h&&n.__h(r,t,o||u),o=0;var i=r.__H||(r.__H={__:[],__h:[]});return t>=i.__.length&&i.__.push({__V:f}),i.__[t]}function p(n){return o=1,y(z,n)}function y(n,u,i){var o=d(t++,2);if(o.t=n,!o.__c&&(o.__=[i?i(u):z(void 0,u),function(n){var t=o.__N?o.__N[0]:o.__[0],r=o.t(t,n);t!==r&&(o.__N=[r,o.__[1]],o.__c.setState({}))}],o.__c=r,!r.u)){r.u=!0;var c=r.shouldComponentUpdate;r.shouldComponentUpdate=function(n,t,r){if(!o.__c.__H)return!0;var u=o.__c.__H.__.filter(function(n){return n.__c});return u.every(function(n){return!n.__N})?!c||c.call(this,n,t,r):!u.every(function(n){if(!n.__N)return!0;var t=n.__[0];return n.__=n.__N,n.__N=void 0,t===n.__[0]})&&(!c||c.call(this,n,t,r))}}return o.__N||o.__}function h(u,i){var o=d(t++,3);!n.__s&&w(o.__H,i)&&(o.__=u,o.i=i,r.__H.__h.push(o))}function s(u,i){var o=d(t++,4);!n.__s&&w(o.__H,i)&&(o.__=u,o.i=i,r.__h.push(o))}function _(n){return o=5,F(function(){return{current:n}},[])}function A(n,t,r){o=6,s(function(){return\"function\"==typeof n?(n(t()),function(){return n(null)}):n?(n.current=t(),function(){return n.current=null}):void 0},null==r?r:r.concat(n))}function F(n,r){var u=d(t++,7);return w(u.__H,r)?(u.__V=n(),u.i=r,u.__h=n,u.__V):u.__}function T(n,t){return o=8,F(function(){return n},t)}function q(n){var u=r.context[n.__c],i=d(t++,9);return i.c=n,u?(null==i.__&&(i.__=!0,u.sub(r)),u.props.value):n.__}function x(t,r){n.useDebugValue&&n.useDebugValue(r?r(t):t)}function V(n){var u=d(t++,10),i=p();return u.__=n,r.componentDidCatch||(r.componentDidCatch=function(n){u.__&&u.__(n),i[1](n)}),[i[0],function(){i[1](void 0)}]}function b(){for(var t;t=c.shift();)if(t.__P&&t.__H)try{t.__H.__h.forEach(j),t.__H.__h.forEach(k),t.__H.__h=[]}catch(r){t.__H.__h=[],n.__e(r,t.__v)}}n.__b=function(n){r=null,e&&e(n)},n.__r=function(n){a&&a(n),t=0;var i=(r=n.__c).__H;i&&(u===r?(i.__h=[],r.__h=[],i.__.forEach(function(n){n.__N&&(n.__=n.__N),n.__V=f,n.__N=n.i=void 0})):(i.__h.forEach(j),i.__h.forEach(k),i.__h=[])),u=r},n.diffed=function(t){v&&v(t);var o=t.__c;o&&o.__H&&(o.__H.__h.length&&(1!==c.push(o)&&i===n.requestAnimationFrame||((i=n.requestAnimationFrame)||function(n){var t,r=function(){clearTimeout(u),g&&cancelAnimationFrame(t),setTimeout(n)},u=setTimeout(r,100);g&&(t=requestAnimationFrame(r))})(b)),o.__H.__.forEach(function(n){n.i&&(n.__H=n.i),n.__V!==f&&(n.__=n.__V),n.i=void 0,n.__V=f})),u=r=null},n.__c=function(t,r){r.some(function(t){try{t.__h.forEach(j),t.__h=t.__h.filter(function(n){return!n.__||k(n)})}catch(u){r.some(function(n){n.__h&&(n.__h=[])}),r=[],n.__e(u,t.__v)}}),l&&l(t,r)},n.unmount=function(t){m&&m(t);var r,u=t.__c;u&&u.__H&&(u.__H.__.forEach(function(n){try{j(n)}catch(n){r=n}}),r&&n.__e(r,u.__v))};var g=\"function\"==typeof requestAnimationFrame;function j(n){var t=r,u=n.__c;\"function\"==typeof u&&(n.__c=void 0,u()),r=t}function k(n){var t=r;n.__c=n.__(),r=t}function w(n,t){return!n||n.length!==t.length||t.some(function(t,r){return t!==n[r]})}function z(n,t){return\"function\"==typeof t?t(n):t}export{p as useState,y as useReducer,h as useEffect,s as useLayoutEffect,_ as useRef,A as useImperativeHandle,F as useMemo,T as useCallback,q as useContext,x as useDebugValue,V as useErrorBoundary};\n//# sourceMappingURL=hooks.module.js.map\n","import {h, render} from 'preact';\n\nfunction Results({items}) {\n return (
\n {Array.isArray(items) &&\n }\n
\n )\n}\n\nexport default Results\n","import {h, render} from 'preact';\n\nfunction FilterSideBar({facets, onChange}) {\n return (\n
\n
\n \n \n \n \n \n \n \n \n Sélection\n \n
\n
\n Filtres des contenus\n
\n
\n
\n {Array.isArray(facets.type) &&\n
    \n {facets.type.map(({key, title, count, selected}) => (\n
  • \n \n \n
  • \n ))}\n
}\n
\n
\n {Array.isArray(facets.viewed) &&\n
    \n {facets.viewed.map(({key, title, count, selected}) => (\n
  • \n \n \n
  • \n ))}\n
}\n
\n
\n
\n
\n
\n )\n}\n\nexport default FilterSideBar\n","import {h, render} from 'preact';\nimport FilterSideBar from \"./SearchBar/FilterSideBar\";\n\nfunction SearchBar({facets, query, onChange}) {\n return (\n
\n \n\n
\n \n \n \n \n
\n
)\n}\n\nexport default SearchBar\n","import {debounce} from 'throttle-debounce';\nimport {h, render} from 'preact';\nimport {useRef, useEffect, useMemo, useState} from 'preact/hooks';\nimport Results from \"./Components/SearchResult/Results\";\nimport SearchBar from \"./Components/SearchBar\";\n\n(() => {\n\n function SearchContents({path, nodeRef, csrfToken}) {\n const [error, setError] = useState();\n const [isLoaded, setIsLoaded] = useState();\n const [results, setResults] = useState();\n const [facets, setFacets] = useState({type: [], viewed: []});\n const formData = useRef();\n\n const search = async (event) => {\n const form = formData.current;\n const query = form.query.value || '';\n const value = event.target.value || '';\n const filter = {};\n\n if (value.indexOf(':') !== -1) {\n form.typeFilter && (filter['type'] = form.typeFilter.value);\n form.viewedFilter && (filter['viewed'] = form.viewedFilter.value.substring(1));\n }\n\n try {\n const response = await fetch(`/api/search`,\n {\n cache: \"no-cache\",\n method: \"POST\",\n body: JSON.stringify({q: encodeURIComponent(query), filter: filter, node: nodeRef, path: path}),\n credentials: 'same-origin',\n headers: {\n 'X-Flow-Csrftoken': csrfToken,\n 'Content-Type': 'application/json'\n }\n });\n if ((response.status === 200)) {\n const res = await response.json();\n setIsLoaded(true);\n setResults(res.results);\n setFacets(res.facets);\n }\n } catch (error) {\n setIsLoaded(true);\n setError(error);\n }\n }\n\n const debouncedSearch = useMemo(\n () => debounce(350, search),\n []\n );\n\n const handleSubmit = (ev ) => {\n ev.preventDefault();\n let current = formData.current;\n // console.log(\n // 'Submit', current.query.value,\n // current.typeFilter.value\n // );\n\n };\n\n useEffect(() => {\n return () => {\n debouncedSearch.cancel();\n }\n }, []);\n\n useEffect(() => {\n // First empty search\n search({target: {value: null}});\n }, []);\n\n return (\n
\n
\n
\n \n \n \n
\n );\n }\n\n window.addEventListener('DOMContentLoaded', () => {\n const searchContents = document.querySelector('#SearchContents');\n if (!searchContents) return;\n const {path, node, token} = searchContents.dataset;\n if (path === '' || node === '' || token === '') return;\n\n render(, searchContents);\n });\n})();\n","(() => {\n window.addEventListener('DOMContentLoaded', () => {\n const audioPlayerContainer = document.querySelector('[data-component=\"oAudioPlayer\"]');\n if (!audioPlayerContainer) { return; }\n\n const playIconContainer = audioPlayerContainer.querySelector('.oAudio__PlayIcon');\n const seekSlider = audioPlayerContainer.querySelector('.oAudio__SeekSlider');\n const volumeSlider = audioPlayerContainer.querySelector('.oAudio__Volume__Slider');\n const muteIconContainer = audioPlayerContainer.querySelector('.oAudio__MuteIcon');\n /* Implementation of the functionality of the audio player */\n const audio = audioPlayerContainer.querySelector('audio');\n const durationContainer = audioPlayerContainer.querySelector('.oAudio__Duration');\n const currentTimeContainer = audioPlayerContainer.querySelector('.oAudio__Time');\n const outputContainer = audioPlayerContainer.querySelector('.oAudio__Volume');\n let playState = 'play',\n muteState = 'unmute',\n raf = null;\n\n playIconContainer.addEventListener('click', () => {\n if(playState === 'play') {\n audio.play();\n requestAnimationFrame(whilePlaying);\n playState = 'pause';\n playIconContainer.classList.replace('play', 'pause');\n } else {\n audio.pause();\n cancelAnimationFrame(raf);\n playState = 'play';\n playIconContainer.classList.replace('pause', 'play');\n }\n });\n\n muteIconContainer.addEventListener('click', () => {\n if (muteState === 'unmute') {\n muteIconContainer.classList.replace('unmuted', 'muted');\n audio.muted = true;\n muteState = 'mute';\n } else {\n muteIconContainer.classList.replace('muted', 'unmuted');\n audio.muted = false;\n muteState = 'unmute';\n }\n });\n\n const showRangeProgress = (rangeInput) => {\n if (rangeInput === seekSlider) {\n audioPlayerContainer.style.setProperty('--seek-before-width', rangeInput.value / rangeInput.max * 100 + '%');\n } else {\n audioPlayerContainer.style.setProperty('--volume-before-width', rangeInput.value / rangeInput.max * 100 + '%');\n }\n }\n\n seekSlider.addEventListener('input', (e) => {\n showRangeProgress(e.target);\n });\n volumeSlider.addEventListener('input', (e) => {\n showRangeProgress(e.target);\n });\n\n const calculateTime = (secs) => {\n const minutes = Math.floor(secs / 60);\n const seconds = Math.floor(secs % 60);\n const returnedSeconds = seconds < 10 ? `0${seconds}` : `${seconds}`;\n return `${minutes}:${returnedSeconds}`;\n }\n\n const displayDuration = () => {\n durationContainer.textContent = calculateTime(audio.duration);\n }\n\n const setSliderMax = () => {\n seekSlider.max = Math.floor(audio.duration);\n }\n\n const displayBufferedAmount = () => {\n if (audio.buffered.length) {\n const bufferedAmount = Math.floor(audio.buffered.end(audio.buffered.length - 1));\n audioPlayerContainer.style.setProperty('--buffered-width', `${(bufferedAmount / seekSlider.max).toFixed(3) * 100}%`);\n }\n }\n\n const whilePlaying = () => {\n seekSlider.value = Math.floor(audio.currentTime);\n currentTimeContainer.textContent = calculateTime(seekSlider.value);\n audioPlayerContainer.style.setProperty('--seek-before-width', `${seekSlider.value / seekSlider.max * 100}%`);\n raf = requestAnimationFrame(whilePlaying);\n }\n\n if (audio.readyState > 0) {\n displayDuration();\n setSliderMax();\n displayBufferedAmount();\n } else {\n audio.addEventListener('loadedmetadata', () => {\n displayDuration();\n setSliderMax();\n displayBufferedAmount();\n });\n }\n\n audio.addEventListener('progress', displayBufferedAmount);\n\n seekSlider.addEventListener('input', () => {\n currentTimeContainer.textContent = calculateTime(seekSlider.value);\n if(!audio.paused) {\n cancelAnimationFrame(raf);\n }\n });\n\n seekSlider.addEventListener('change', () => {\n audio.currentTime = seekSlider.value;\n if(!audio.paused) {\n requestAnimationFrame(whilePlaying);\n }\n });\n\n volumeSlider.addEventListener('input', (e) => {\n const value = e.target.value;\n\n outputContainer.textContent = value;\n audio.volume = value / 100;\n });\n\n\n /* Implementation of the Media Session API */\n if('mediaSession' in navigator) {\n const { title, artist, album, artwork } = audioPlayerContainer.dataset;\n navigator.mediaSession.metadata = new MediaMetadata({\n title: title || '',\n artist: artist || '',\n album: album || '',\n artwork: JSON.parse(artwork) || ''\n });\n\n navigator.mediaSession.setActionHandler('play', () => {\n if(playState === 'play') {\n audio.play();\n requestAnimationFrame(whilePlaying);\n playState = 'pause';\n } else {\n audio.pause();\n cancelAnimationFrame(raf);\n playState = 'play';\n }\n });\n navigator.mediaSession.setActionHandler('pause', () => {\n if(playState === 'play') {\n audio.play();\n requestAnimationFrame(whilePlaying);\n playState = 'pause';\n } else {\n audio.pause();\n cancelAnimationFrame(raf);\n playState = 'play';\n }\n });\n navigator.mediaSession.setActionHandler('seekbackward', (details) => {\n audio.currentTime = audio.currentTime - (details.seekOffset || 10);\n });\n navigator.mediaSession.setActionHandler('seekforward', (details) => {\n audio.currentTime = audio.currentTime + (details.seekOffset || 10);\n });\n navigator.mediaSession.setActionHandler('seekto', (details) => {\n if (details.fastSeek && 'fastSeek' in audio) {\n audio.fastSeek(details.seekTime);\n return;\n }\n audio.currentTime = details.seekTime;\n });\n navigator.mediaSession.setActionHandler('stop', () => {\n audio.currentTime = 0;\n seekSlider.value = 0;\n audioPlayerContainer.style.setProperty('--seek-before-width', '0%');\n currentTimeContainer.textContent = '0:00';\n if(playState === 'pause') {\n cancelAnimationFrame(raf);\n playState = 'play';\n }\n });\n }\n });\n\n})();\n","import {h} from 'preact';\n\nfunction Button({showInfo, checked, fetching, onChange}) {\n return (\n
\n {\n \n \n \n \n \n \n \n }\n
\n )\n}\n\nexport default Button\n","import {h, render} from 'preact';\nimport {useEffect, useState} from 'preact/hooks';\nimport {useStateWithCallback} from '../../../Preact/Helpers/useStateWithCallback'\nimport Button from \"./components/Button\";\n\n(() => {\n function ViewedCheckButton({nodeRef, csrfToken}) {\n const [error, setError] = useState(false);\n const [isFetching, setIsFetching] = useState(false);\n const [isViewed, setViewedState] = useStateWithCallback(false);\n const [isUser, setIsUser] = useState(false);\n\n const updateStatus = async (ev, viewed) => {\n setIsFetching(true);\n fetch(`/api/review`, {\n cache: \"no-cache\",\n method: \"POST\",\n body: JSON.stringify({node: nodeRef, state: viewed}),\n credentials: 'same-origin',\n headers: {\n 'X-Flow-Csrftoken': csrfToken,\n 'Content-Type': 'application/json'\n }\n }).then((response) => {\n if (response.ok) {\n return response.json();\n }\n throw new Error('Erreur serveur!');\n }).then((data) => {\n setTimeout(() => setIsFetching(false), 1000);\n setViewedState(data.reviewed);\n setIsUser(data.loggedIn);\n }).catch((error) => {\n setIsFetching(false);\n console.error(error);\n });\n }\n\n const toggleViewed = (ev) => {\n setViewedState(!isViewed, (prevValue, newValue) => {\n updateStatus(ev, newValue);\n });\n };\n\n // firstload\n useEffect(() => {\n updateStatus(null, null);\n }, []);\n\n return (\n }\n \n )\n}\n\nexport default Button\n","import {h, render} from 'preact';\n\nfunction Question({label}) {\n return (\n
\n

{label}

\n
\n )\n}\n\nexport default Question\n","import {h} from 'preact';\n\nfunction Radio(props) {\n const correct = props.correct || undefined;\n const selectStyle = (checked, correct) => {\n const baseClassName = 'aQuizAnswer__Label';\n const prefix = baseClassName + ' ' + baseClassName;\n\n if (correct === null) {\n return baseClassName;\n }\n if (checked && correct) {\n return prefix + '--true';\n } else if (checked && !correct) {\n return prefix + '--false';\n } else if (correct && !checked) {\n return prefix + '--correct';\n } else {\n return baseClassName;\n }\n }\n\n return (\n \n \n \n \n )\n}\n\nexport default Radio\n","import {h, render} from 'preact';\nimport Radio from \"./Radio\";\n\nfunction Answers({items, onRadioChecked, disabled}) {\n const className = !!disabled ? 'oQuiz__Answers oQuiz__Answers--off' : 'oQuiz__Answers';\n return (\n
    \n {Array.isArray(items) &&\n items.map(({label, checked, correct, id}) => (\n
  • \n \n
  • \n ))\n }\n
\n )\n}\n\nexport default Answers\n","import {h, render} from 'preact';\n\nfunction References({items}) {\n return (\n
\n

Références

\n
    \n {Array.isArray(items) &&\n items.map(({item}) => (\n
  • \n ))\n }\n
\n
\n )\n}\n\nexport default References\n","import {h, render} from 'preact';\n\nfunction Comments({items}) {\n return (\n
\n {Array.isArray(items) &&\n items.map(({item}) => (\n
\n ))\n }\n
\n )\n}\n\nexport default Comments\n","import {Fragment, h, render} from 'preact';\nimport {Dialog} from \"./Dialog/Dialog\";\n\n\n(() => {\n function Modal({content}) {\n\n return (\n {({isOpen, onOpen, onDialogClick, onClose}) => (\n \n \n \n {isOpen ? (\n
\n
\n \n
\n
\n
\n ) : null}\n \n
\n )}\n
);\n }\n\n\n window.addEventListener('DOMContentLoaded', () => {\n const nodesList = document.querySelectorAll('[data-component=\"ModalDialog\"]');\n const initModal = (element) => {\n if (!element) {\n return;\n }\n const id = element.id;\n const modal = document.querySelector(`#${id}`);\n if (!modal) return;\n const content = modal.innerHTML;\n modal.firstChild.remove();\n\n render(, modal);\n };\n\n nodesList.forEach((item) => {\n initModal(item);\n });\n });\n})();\n","import {h, Fragment, render} from 'preact';\nimport {useEffect, useRef, useState} from 'preact/hooks';\nimport Button from \"./components/Button\";\nimport Question from \"./components/Question\";\nimport Answers from \"./components/Answers\";\nimport References from \"./components/References\";\nimport Comments from \"./components/Comments\";\n\n(() => {\n function Quiz({nodeRef, csrfToken, is}) {\n const [error, setError] = useState(false);\n const [isFetching, setIsFetching] = useState(false);\n const [valid, setIsValid] = useState(false);\n const [result, setResult] = useState(false);\n const formData = useRef();\n useEffect(() => { }, [valid]);\n\n const updateStatus = async (data) => {\n let body = {node: nodeRef, is: is}\n const path = data !== null && data.path !== null ? data.path : '';\n const answer = data !== null && data.answer !== null ? data.answer : '';\n\n if (answer) { body.answer = answer };\n setIsFetching(true);\n\n /** extract it */\n fetch(`/api/quiz` + path, {\n cache: \"no-cache\",\n method: \"POST\",\n body: JSON.stringify(body),\n credentials: 'same-origin',\n headers: {\n 'X-Flow-Csrftoken': csrfToken,\n 'Content-Type': 'application/json'\n }\n }).then((response) => {\n if (response.ok) {\n return response.json();\n }\n throw new Error('Erreur serveur!');\n }).then((data) => {\n setTimeout(() => setIsFetching(false), 1000);\n setResult(data);\n }).catch((error) => {\n setIsFetching(false);\n setError(error);\n });\n }\n\n const handleSubmit = (ev ) => {\n ev.preventDefault();\n let value = formData.current.answer.value;\n if (value === '') {\n setError('Problème avec le quiz, rechargez la page.')\n }\n updateStatus({path: '/validate', answer: value});\n };\n\n const setButtonActive = (ev ) => {\n ev.preventDefault();\n setIsValid(true);\n };\n\n // firstload\n useEffect(() => {\n updateStatus(null);\n }, []);\n\n if (result.show) {\n return (\n \n \n \n
\n

{result.answerTitle}

\n \n \n
\n
\n );\n }\n\n return (\n \n \n
\n \n