/* * This is free and unencumbered software released into the public domain. * * Anyone is free to copy, modify, publish, use, compile, sell, or * distribute this software, either in source code form or as a compiled * binary, for any purpose, commercial or non-commercial, and by any * means. * * In jurisdictions that recognize copyright laws, the author or authors * of this software dedicate any and all copyright interest in the * software to the public domain. We make this dedication for the benefit * of the public at large and to the detriment of our heirs and * successors. We intend this dedication to be an overt act of * relinquishment in perpetuity of all present and future rights to this * software under copyright law. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * For more information, please refer to */ // Data var segmentMap = SegmentMap; var bv = bandersnatch.videos['80988062'].interactiveVideoMoments.value; var choicePoints = bv.choicePointNavigatorMetadata.choicePointsMetadata.choicePoints; var momentsBySegment = bv.momentsBySegment; var segmentGroups = bv.segmentGroups; // Transation of choices var moments = JSON.parse(JSON.stringify(momentsBySegment)); var translated_choices = en; function switch_choices() { for (var key in translated_choices) { for (var i = 0; i < Object.keys(moments[key]).length; i++) { if ("choices" in moments[key][i]) { for (var k = 0; k < Object.keys(moments[key][i]["choices"]).length; k++) { if ("id" in moments[key][i]["choices"][k]) { if (moments[key][i]["choices"][k]['id'] in translated_choices[key]) { moments[key][i]["choices"][k]['text'] = translated_choices[key][moments[key][i]["choices"][k]["id"]]; } } } } } } return moments; } // Persistent state var ls = window.localStorage || {}; if (!('initialized' in ls)) { for (let k in bv.stateHistory) ls["persistentState_" + k] = JSON.stringify(bv.stateHistory[k]); ls['initialized'] = 't'; } function msToString(ms) { return new Date(ms).toUTCString().split(' ')[4]; } function getCurrentMs() { return Math.round(document.getElementById("video").currentTime * 1000.0); } function preconditionToJS(cond) { if (cond[0] == 'persistentState') { return 'JSON.parse(ls["persistentState_' + cond[1] + '"])'; } else if (cond[0] == 'not') { return '!(' + preconditionToJS(cond[1]) + ')'; } else if (cond[0] == 'and') { return '(' + cond.slice(1).map(preconditionToJS).join(' && ') + ')'; } else if (cond[0] == 'or') { return '(' + cond.slice(1).map(preconditionToJS).join(' || ') + ')'; } else if (cond[0] == 'eql' && cond.length == 3) { return '(' + cond.slice(1).map(preconditionToJS).join(' == ') + ')'; } else if (cond === false) { return 'false'; } else if (cond === true) { return 'true'; } else if (typeof cond === 'string') { return JSON.stringify(cond); } else { console.log('unsupported condition!', cond); return 'true'; } } function evalPrecondition(precondition, text) { if (precondition) { let cond = preconditionToJS(precondition); let match = eval(cond); console.log('precondition', text, ':', cond, '==', match); return match; } return true; } function checkPrecondition(preconditionId) { return evalPrecondition(bv.preconditions[preconditionId], preconditionId); } function resolveSegmentGroup(sg) { let results = []; for (let v of segmentGroups[sg]) { if (v.precondition) { if (!checkPrecondition(v.precondition)) continue; } if (v.segmentGroup) { results.push(resolveSegmentGroup(v.segmentGroup)); } else if (v.segment) { results.push(v.segment); } else { if (!checkPrecondition(v)) continue; results.push(v); } } console.log('segment group', sg, '=>', results); return results[0]; } /// Returns the segment ID at the given timestamp. /// There will be exactly one segment for any timestamp within the video file. function getSegmentId(ms) { for (const [k, v] of Object.entries(segmentMap.segments)) { if (ms >= v.startTimeMs && (!v.endTimeMs || ms < v.endTimeMs)) { return k; } } return null; } function getSegmentMs(segmentId) { return segmentMap.segments[segmentId].startTimeMs; } function getMoments(segmentId, ms) { let result = {}; let moments = momentsBySegment[segmentId] || []; for (let i = 0; i < moments.length; i++) { let m = moments[i]; let momentId = segmentId + '/' + i; if (ms >= m.startMs && ms < m.endMs && evalPrecondition(m.precondition, 'moment ' + momentId)) { result[momentId] = m; } } return result; } function newList(id) { var ul = document.getElementById(id); while (ul.firstChild) { ul.removeChild(ul.firstChild); } return ul; } let selectedDigits = []; function addItem(ul, text, url, TheChoice) { if (TheChoice.type !== "scene:cs_bs_phone"){ var li = document.createElement("li"); var a = document.createElement("a"); if (TheChoice && TheChoice.image){ a.style.backgroundImage = TheChoice.image.styles.backgroundImage; a.style.backgroundPosition = "center center"; a.style.backgroundSize = "10rem"; a.style.backgroundRepeat = TheChoice.image.styles.backgroundRepeat; }else{ a.textContent = text; } a.setAttribute('href', url); li.appendChild(a); ul.appendChild(li); }else{ selectedDigits = [] // Créer le conteneur des champs de saisie var inputContainer = document.createElement('div'); inputContainer.className = 'input-container'; // Créer les champs de saisie for (var i = 0; i < 5; i++) { var inputField = document.createElement('span'); inputField.type = 'text'; inputField.className = 'inputField'; inputContainer.appendChild(inputField); } // Créer l'espace entre les conteneurs var lineBreak = document.createElement('br'); inputContainer.appendChild(lineBreak.cloneNode()); inputContainer.appendChild(lineBreak.cloneNode()); // Créer le conteneur des boutons var buttonContainer = document.createElement('div'); buttonContainer.className = 'buttonsCode'; // Créer les éléments de la liste des boutons for (var i = 0; i < 10; i++) { var listItem = document.createElement('span'); listItem.className = "buttonCodeNumber" listItem.textContent = i; listItem.setAttribute('onclick', 'selectDigit(' + i + ')'); buttonContainer.appendChild(listItem); } // Ajouter les conteneurs au document var containerCode = document.createElement('div'); containerCode.className = 'containerCode'; containerCode.appendChild(inputContainer); containerCode.appendChild(buttonContainer); ul.appendChild(containerCode); updateInputPlaceholders(); } } var nextChoice = -1; var nextSegment = null; function addZones(segmentId) { var ul = newList("interactionZones"); let caption = 'currentSegment(' + segmentId + ')'; addItem(ul, caption, 'javascript:playSegment("' + segmentId + '")', false); var segment = segmentMap.segments[segmentId]; if (segment && segment.ui && segment.ui.interactionZones) { var index = 0; for (var z of segment.ui.interactionZones) { var startMs = z[0]; var stopMs = z[1]; let caption = segmentId + ' interactionZone ' + index; addItem(ul, caption, 'javascript:seek(' + startMs + ')', false); index++; } } ul = newList("nextSegments"); if (segment) { for (const [k, v] of Object.entries(segment.next)) { let caption = k; if (segment.defaultNext == k) caption = '[' + caption + ']'; addItem(ul, caption, 'javascript:playSegment("' + k + '")', false); } } } function selectDigit(digit) { if (selectedDigits.length <= 5) { const emptyInputField = getEmptyInputField(); if (emptyInputField) { emptyInputField.innerText = digit; selectedDigits.push(digit); } if (selectedDigits.length >= 5) { var code = selectedDigits.join(''); if (code == "20541"){ choice(0); } else{ choice(1); } } } updateInputPlaceholders(); } function updateInputPlaceholders() { const inputFields = document.querySelectorAll('.inputField'); for (let i = 0; i < inputFields.length; i++) { if (inputFields[i].textContent === '') { inputFields[i].textContent = "-"; } } } function getEmptyInputField() { const inputFields = document.querySelectorAll('.inputField'); for (let i = 0; i < inputFields.length; i++) { if (inputFields[i].textContent === '-') { return inputFields[i]; } } return null; } function addChoices(r) { currentChoiceMoment = r; nextChoice = -1; var ul = newList("choices"); document.getElementById("choiceCaption").innerHTML = ''; if (!r) return; nextChoice = r.defaultChoiceIndex; if (r.type == "scene:cs_bs_phone"){ addItem(ul, "", "", r); }else{ let index = 0; for (let x of r.choices) { var caption = r.defaultChoiceIndex == index ? '[' + x.text + ']' : x.text; addItem(ul, caption, 'javascript:choice(' + index + ')', x); index++; } } if (r.id in choicePoints) document.getElementById("choiceCaption").innerHTML = choicePoints[r.id].description; } function momentStart(m, seeked) { console.log('momentStart', m, seeked); if (m.choices) { addChoices(m); } if (!seeked) applyImpression(m.impressionData); } function momentUpdate(m, ms) { //console.log('momentUpdate', m); if (m.choices) { var p = 100 - ((ms - m.startMs) * 100.0 / (m.endMs - m.startMs)); document.getElementById("progress").style.width = p + '%'; } } function momentEnd(m, seeked) { console.log('momentEnd', m, seeked); if (m.choices) { addChoices(null); document.getElementById("progress").style.width = 0; } } var timerId = 0; var lastMs = 0; var currentSegment; var lastSegment = null; var prevSegment = null; // for breadcrumbs var segmentTransition = false; var lastMoments = []; function ontimeupdate(evt) { var ms = getCurrentMs(); currentSegment = getSegmentId(ms); let segment = segmentMap.segments[currentSegment]; if (timerId) { clearTimeout(timerId); timerId = 0; } // Distinguish between the user seeking manually with