From 331d0a69153cb5610324469be4b9b6ab6679f675 Mon Sep 17 00:00:00 2001 From: Aldo Date: Sat, 17 Apr 2021 19:00:10 +0200 Subject: [PATCH] Sequencing enhancements --- app/models/game.rb | 2 +- .../javascripts/sgame_api/SGAME.CORE.js | 39 +- .../javascripts/sgame_api/SGAME.Sequencing.js | 82 +++- .../app/assets/javascripts/sgame_api/SGAME.js | 4 +- lib/plugins/sgame/lib/tasks/sgame.rake | 2 +- public/sgame_api/SGAME.js | 439 ++++++++++-------- public/sgame_api/SGAME.min.js | 142 +++--- 7 files changed, 429 insertions(+), 281 deletions(-) diff --git a/app/models/game.rb b/app/models/game.rb index 581c66a..b2c654d 100644 --- a/app/models/game.rb +++ b/app/models/game.rb @@ -6,7 +6,7 @@ class Game < ActiveRecord::Base belongs_to :template, class_name: :GameTemplate, foreign_key: "game_template_id" has_many :mappings, class_name: :GameEventMapping, :dependent => :destroy has_many :events, class_name: :GameTemplateEvent, :through => :template - has_many :los, :through => :mappings + has_many :los, -> { uniq }, :through => :mappings has_attached_file :thumbnail, :styles => SgamePlatform::Application.config.thumbnail_styles diff --git a/lib/plugins/sgame/app/assets/javascripts/sgame_api/SGAME.CORE.js b/lib/plugins/sgame/app/assets/javascripts/sgame_api/SGAME.CORE.js index 919596d..a744c03 100644 --- a/lib/plugins/sgame/app/assets/javascripts/sgame_api/SGAME.CORE.js +++ b/lib/plugins/sgame/app/assets/javascripts/sgame_api/SGAME.CORE.js @@ -4,6 +4,7 @@ SGAME.CORE = (function(){ var _options = {}; //Internal vars var _togglePauseFunction = undefined; + var _sequence_finished = false; var _final_screen_text = "Congratulations. You have achieved the objectives of this educational game. You may close this window or continue playing."; //SGAME settings (provided by the SGAME platform) @@ -170,8 +171,6 @@ SGAME.CORE = (function(){ _settings["los"][lo_ids[i]]["nshown"] = 0; //number of times shown _settings["los"][lo_ids[i]]["succesfully_consumed"] = false; _settings["los"][lo_ids[i]]["nsuccess"] = 0; //number of times succesfully consumed - _settings["los"][lo_ids[i]].groups = []; //Groups, for applying sequencing rules. - _settings["los"][lo_ids[i]]["acts_as_asset"] = ((_settings["los"][lo_ids[i]]["scorm_type"]==="asset")||((_settings["los"][lo_ids[i]]["scorm_type"]==="sco")&&(_settings["los"][lo_ids[i]]["report_data"]===false))); _los_can_be_shown = true; @@ -189,9 +188,19 @@ SGAME.CORE = (function(){ } if(typeof _settings["sequencing"]["sequence"] === "object"){ + //Reset LOs + var lo_ids = Object.keys(_settings["los"]); + _nLOs = lo_ids.length; + for(var x=0; x<_nLOs; x++){ + _settings["los"][lo_ids[x]]["can_be_shown"] = false; + _settings["los"][lo_ids[x]].groups = []; //Groups for applying sequencing rules. + } + + _los_can_be_shown = false; + var group_ids = Object.keys(_settings["sequencing"]["sequence"]); _nGroups = group_ids.length; - for(var j=0; j<_nGroups;j++){ + for(var j=0; j<_nGroups; j++){ //Add additional vars for SGAME var group = _settings["sequencing"]["sequence"][group_ids[j]]; group["can_be_shown"] = ((typeof group.conditions === "undefined")||(group.conditions.length === 0)); @@ -205,9 +214,15 @@ SGAME.CORE = (function(){ _settings["sequencing"]["sequence"][group_ids[j]] = group; for(var l=0; l 0); + //Currently, no locked group depends on the status of this group to be unlocked. + + if (nConditionsMet > 0){ + //A condition related to this group unlocking another group has been met. This group can be locked. + return true; + } else { + //This group does not unlock any other group. + //Lock when completed or successed depending on the sequencing approach. + switch(_sequencingApproach){ + case "linear_completion": + return group.shown; + case "linear_success": + return group.succesfully_consumed; + case "custom": + default: + return ((group.shown)&&(group.succesfully_consumed)); + break; + } + } + }; + + var _changeCanBeShownForLOsInGroup = function(group,los,canBeShown){ + for(var i=0; i 0) { + return true + }else { + switch(_sequencingApproach) { + case "linear_completion": + return group.shown; + case "linear_success": + return group.succesfully_consumed; + case "custom": + ; + default: + return group.shown && group.succesfully_consumed; + break + } + } + }; + var _changeCanBeShownForLOsInGroup = function(group, los, canBeShown) { + for(var i = 0;i < group.los.length;i++) { + los[group.los[i]]["can_be_shown"] = canBeShown + } + return los + }; + var _unlockLOsWithoutGroup = function(los) { + var lo_ids = Object.keys(los); + for(var i = 0;i < lo_ids.length;i++) { + if(typeof los[lo_ids[i]].groups === "undefined" || los[lo_ids[i]].groups.length === 0) { + los[lo_ids[i]]["can_be_shown"] = true + } + } + return los + }; + return{init:init, validateSequence:validateSequence, updateGroupsTracking:updateGroupsTracking} +}(); SGAME.API = function() { var init = function() { }; @@ -1064,6 +1287,7 @@ SGAME.API = function() { SGAME.CORE = function() { var _options = {}; var _togglePauseFunction = undefined; + var _sequence_finished = false; var _final_screen_text = "Congratulations. You have achieved the objectives of this educational game. You may close this window or continue playing."; var _settings = {}; var _settings_loaded = false; @@ -1178,7 +1402,6 @@ SGAME.CORE = function() { _settings["los"][lo_ids[i]]["nshown"] = 0; _settings["los"][lo_ids[i]]["succesfully_consumed"] = false; _settings["los"][lo_ids[i]]["nsuccess"] = 0; - _settings["los"][lo_ids[i]].groups = []; _settings["los"][lo_ids[i]]["acts_as_asset"] = _settings["los"][lo_ids[i]]["scorm_type"] === "asset" || _settings["los"][lo_ids[i]]["scorm_type"] === "sco" && _settings["los"][lo_ids[i]]["report_data"] === false; _los_can_be_shown = true } @@ -1193,6 +1416,13 @@ SGAME.CORE = function() { } } if(typeof _settings["sequencing"]["sequence"] === "object") { + var lo_ids = Object.keys(_settings["los"]); + _nLOs = lo_ids.length; + for(var x = 0;x < _nLOs;x++) { + _settings["los"][lo_ids[x]]["can_be_shown"] = false; + _settings["los"][lo_ids[x]].groups = [] + } + _los_can_be_shown = false; var group_ids = Object.keys(_settings["sequencing"]["sequence"]); _nGroups = group_ids.length; for(var j = 0;j < _nGroups;j++) { @@ -1207,10 +1437,15 @@ SGAME.CORE = function() { } _settings["sequencing"]["sequence"][group_ids[j]] = group; for(var l = 0;l < group.los.length;l++) { - _settings["los"][group.los[l]].groups.push(group.id) + _settings["los"][group.los[l]].groups.push(group.id); + _settings["los"][group.los[l]]["can_be_shown"] = group["can_be_shown"] === true; + if(_settings["los"][group.los[l]]["can_be_shown"] === true) { + _los_can_be_shown = true + } } } } + SGAME.Sequencing.init(_settings["sequencing"]) }; var triggerLO = function(event_id, callback) { switch(_settings["sequencing"]["interruptions"]) { @@ -1307,8 +1542,13 @@ SGAME.CORE = function() { if(report.success === true) { _settings["los"][lo["id"]]["nsuccess"] += 1 } - if(_settings["sequencing"]["approach"] !== "random") { - _settings["sequencing"]["sequence"] = SGAME.Sequencing.updateGroupsTracking(_settings["los"][lo["id"]], _settings["sequencing"]["sequence"], _settings["los"]) + if(_settings["sequencing"]["approach"] !== "random" && _sequence_finished === false) { + var output = SGAME.Sequencing.updateGroupsTracking(_settings["los"][lo["id"]], _settings["sequencing"]["sequence"], _settings["los"]); + _settings["sequencing"]["sequence"] = output.groups; + _settings["los"] = output.los; + if(output.finished) { + _sequence_finished = true + } } switch(_settings["sequencing"]["repeat_lo"]) { case "repeat": @@ -1577,7 +1817,13 @@ SGAME.CORE = function() { return SGAME.Utils.getRandomElement(filtered_candidates) }; var _selectLoFromCandidatesSequence = function(loCandidatesFromMapping) { - return _selectLoFromCandidatesRandom(_getLoCandidatesFromSequecingRules(loCandidatesFromMapping)) + var candidates; + if(_sequence_finished === false) { + candidates = _getLoCandidatesFromSequecingRules(loCandidatesFromMapping) + }else { + candidates = loCandidatesFromMapping + } + return _selectLoFromCandidatesRandom(candidates) }; var _getLoCandidatesFromSequecingRules = function(loCandidatesFromMapping) { var candidates = []; @@ -1992,185 +2238,6 @@ SGAME.Observer = function(undefined) { }; return{start:start, stop:stop, isStopped:isStopped} }(); -SGAME.Sequencing = function() { - var supportedGroupRequirements = ["completion", "success"]; - var init = function() { - }; - var validateSequence = function(sequence, los) { - if(typeof sequence !== "object" || typeof los !== "object") { - return false - } - var group_ids = Object.keys(sequence); - var lo_ids = Object.keys(los); - for(var i = 0;i < group_ids.length;i++) { - var group = _validateGroup(sequence[group_ids[i]], lo_ids); - if(group !== false) { - sequence[group_ids[i]] = group - }else { - delete sequence[group_ids[i]] - } - } - sequence = _validateGroupsConditions(sequence); - var valid_group_ids = Object.keys(sequence); - var los_in_valid_groups = []; - for(var j = 0;j < valid_group_ids.length;j++) { - var group = sequence[valid_group_ids[j]]; - for(var k = 0;k < group.los.length;k++) { - if(los_in_valid_groups.indexOf(group.los[k]) === -1) { - los_in_valid_groups.push(group.los[k]) - } - } - } - if(typeof valid_group_ids.length < 2 || los_in_valid_groups.length < 2) { - return false - } - return sequence - }; - var _validateGroup = function(group, lo_ids) { - var validLos = []; - for(var i = 0;i < group.los.length;i++) { - var loId = group.los[i]; - if(lo_ids.indexOf(loId) !== -1) { - validLos.push(loId) - } - } - group.los = validLos; - if(group.los.length < 1) { - return false - } - return group - }; - var _validateGroupsConditions = function(groups) { - var group_ids = Object.keys(groups); - var nGroups = group_ids.length; - for(var i = 0;i < nGroups;i++) { - var group = _validateGroupConditions(groups[group_ids[i]], group_ids); - if(group !== false) { - groups[group_ids[i]] = group - }else { - delete groups[group_ids[i]] - } - } - var nNewGroups = Object.keys(groups).length; - if(nNewGroups === nGroups) { - return groups - }else { - return _validateGroupsConditions(groups) - } - }; - var _validateGroupConditions = function(group, groupIds) { - if(typeof group.conditions === "undefined") { - return group - } - if(typeof group.conditions !== "object") { - return false - } - if(group.conditions.length === 0) { - delete group.conditions; - return group - } - var validConditions = []; - for(var i = 0;i < group.conditions.length;i++) { - var condition = group.conditions[i]; - if(groupIds.indexOf(condition.group + "") !== -1) { - if(supportedGroupRequirements.indexOf(condition.requirement) !== -1) { - validConditions.push(condition) - } - } - } - group.conditions = validConditions; - if(group.conditions.length === 0) { - return false - } - return group - }; - var updateGroupsTracking = function(lo, groups, los) { - for(var i = 0;i < lo.groups.length;i++) { - var group = groups[lo.groups[i] + ""]; - groups[lo.groups[i] + ""] = _updateGroupTracking(group, los) - } - var group_ids = Object.keys(groups); - for(var j = 0;j < group_ids.length;j++) { - var ogroup = groups[group_ids[j]]; - if(ogroup.can_be_shown === false && (ogroup.shown === false && ogroup.succesfully_consumed === false)) { - groups[group_ids[j]] = _updateGroupUnlock(ogroup, groups) - } - } - for(var k = 0;k < lo.groups.length;k++) { - var ogroup = groups[lo.groups[k] + ""]; - if(ogroup.can_be_shown === true) { - groups[lo.groups[k] + ""] = _updateGroupLock(ogroup, groups) - } - } - return groups - }; - var _updateGroupTracking = function(group, los) { - if((group.shown && group.succesfully_consumed) === true) { - return group - } - var gShown = true; - var gSuccess = true; - for(var i = 0;i < group.los.length;i++) { - var lo = los[group.los[i]]; - gShown = gShown && lo.shown === true; - gSuccess = gSuccess && lo.succesfully_consumed === true - } - group.shown = gShown; - group.succesfully_consumed = gSuccess; - if(group.succesfully_consumed) { - group.can_be_shown = false - } - return group - }; - var _updateGroupUnlock = function(group, groups) { - if(typeof group.conditions === "undefined") { - return group - } - var unlock = true; - for(var k = 0;k < group.conditions.length;k++) { - if(group.conditions[k].met === false) { - switch(group.conditions[k].requirement) { - case "completion": - group.conditions[k].met = groups[group.conditions[k].group + ""].shown === true; - break; - case "success": - group.conditions[k].met = groups[group.conditions[k].group + ""].succesfully_consumed === true; - break - } - unlock = unlock && group.conditions[k].met; - if(unlock === false) { - break - } - } - } - group.can_be_shown = unlock; - return group - }; - var _updateGroupLock = function(group, groups) { - var lock = _getLockForGroup(group, groups); - group.can_be_shown = lock === false; - return group - }; - var _getLockForGroup = function(group, groups) { - var group_ids = Object.keys(groups); - var nConditions = 0; - for(var j = 0;j < group_ids.length;j++) { - var ogroup = groups[group_ids[j]]; - if(ogroup.id != group.id && typeof ogroup.conditions !== "undefined") { - for(var k = 0;k < ogroup.conditions.length;k++) { - if(ogroup.conditions[k].group == group.id) { - nConditions = nConditions + 1; - if(ogroup.conditions[k].met === false) { - return false - } - } - } - } - } - return nConditions > 0 - }; - return{init:init, validateSequence:validateSequence, updateGroupsTracking:updateGroupsTracking} -}(); SGAME.TrafficLight = function(undefined) { var current_color; var changeColorTimer; diff --git a/public/sgame_api/SGAME.min.js b/public/sgame_api/SGAME.min.js index 46daf93..c991d02 100644 --- a/public/sgame_api/SGAME.min.js +++ b/public/sgame_api/SGAME.min.js @@ -1,73 +1,75 @@ -iso8601Parser=function(e){return{getDuration:function(l){var e=[31104E3,2592E3,604800,86400,3600,60,1];try{var a;var n=l;l=[2,3,4,5,7,8,9];var d=[0,0,0,0,0,0,0],h;if(n=n.toUpperCase()){if("string"!==typeof n)throw Error("Invalid iso8601 period string '"+n+"'");if(h=/^P((\d+Y)?(\d+M)?(\d+W)?(\d+D)?)?(T(\d+H)?(\d+M)?(\d+S)?)?$/.exec(n))for(n=0;na.length?c[a[0]]=b:(c[a[0]]||(c[a[0]]={}),c=c[a.shift()],n(a.join("."),b,c))}function d(a,b){var c=a.split(/\./), -g;if(2>c.length)try{return b[c[0]]}catch(f){return k(a),"false"}else{g=c.shift();if(b[g])return String(d(c.join("."),b[g]));k(a);return"false"}}function h(a){var b,c=0;for(b in a)a.hasOwnProperty(b)&&(c+=1);return c}function q(a,b){if(c.debug){window.console||(window.console={},window.console.info=noconsole,window.console.log=noconsole,window.console.warn=noconsole,window.console.error=noconsole,window.console.trace=noconsole);switch(b){case 1:console.error(a);break;case 2:console.warn(a);break;case 4:console.info(a); -break;case 3:console.log(a);break;default:return console.log(a),!1}return!0}3>b&&c.throw_alerts&&alert(a);return!1}function p(a,b){if("function"==typeof c.listeners[a]&&"undefined"!=typeof b)c.listeners[a](b)}function f(a,b){for(var c in b)b.hasOwnProperty(c)&&("object"==typeof a[c]?"object"==typeof b[c]&&(a[c]=f(a[c],b[c])):a[c]=b[c]);return a}function b(a,b){(function(){function a(b,c){c=c||{bubbles:!1,cancelable:!1,detail:void 0};var v=document.createEvent("CustomEvent");v.initCustomEvent(b,c.bubbles, -c.cancelable,c.detail);return v}if("function"===typeof window.CustomEvent)return!1;a.prototype=window.Event.prototype;window.CustomEvent=a})();document.dispatchEvent(new CustomEvent(a,{detail:b}))}function s(a){return"object"!==type(a)||a.nodeType||isWindow(a)?!1:!(a.constructor&&!hasOwn.call(a.constructor.prototype,"isPrototypeOf"))}var c=f({version:"2.4",prefix:"Local_API_1484_11",errorCode:0,diagnostic:"",initialized:0,terminated:0,user:void 0,debug:!0,listeners:{},CMI:{_version:"1.0",comments_from_learner:{_children:"comment,location,timestamp", +iso8601Parser=function(c){return{getDuration:function(f){var c=[31104E3,2592E3,604800,86400,3600,60,1];try{var l;var a=f;f=[2,3,4,5,7,8,9];var t=[0,0,0,0,0,0,0],r;if(a=a.toUpperCase()){if("string"!==typeof a)throw Error("Invalid iso8601 period string '"+a+"'");if(r=/^P((\d+Y)?(\d+M)?(\d+W)?(\d+D)?)?(T(\d+H)?(\d+M)?(\d+S)?)?$/.exec(a))for(a=0;ab.length?d[b[0]]=n:(d[b[0]]||(d[b[0]]={}),d=d[b.shift()],a(b.join("."),n,d))}function t(a,b){var d=a.split(/\./), +n;if(2>d.length)try{return b[d[0]]}catch(h){return g(a),"false"}else{n=d.shift();if(b[n])return String(t(d.join("."),b[n]));g(a);return"false"}}function r(a){var b,d=0;for(b in a)a.hasOwnProperty(b)&&(d+=1);return d}function m(a,b){if(d.debug){window.console||(window.console={},window.console.info=noconsole,window.console.log=noconsole,window.console.warn=noconsole,window.console.error=noconsole,window.console.trace=noconsole);switch(b){case 1:console.error(a);break;case 2:console.warn(a);break;case 4:console.info(a); +break;case 3:console.log(a);break;default:return console.log(a),!1}return!0}3>b&&d.throw_alerts&&alert(a);return!1}function s(a,b){if("function"==typeof d.listeners[a]&&"undefined"!=typeof b)d.listeners[a](b)}function e(a,b){for(var d in b)b.hasOwnProperty(d)&&("object"==typeof a[d]?"object"==typeof b[d]&&(a[d]=e(a[d],b[d])):a[d]=b[d]);return a}function b(a,b){(function(){function a(b,d){d=d||{bubbles:!1,cancelable:!1,detail:void 0};var v=document.createEvent("CustomEvent");v.initCustomEvent(b,d.bubbles, +d.cancelable,d.detail);return v}if("function"===typeof window.CustomEvent)return!1;a.prototype=window.Event.prototype;window.CustomEvent=a})();document.dispatchEvent(new CustomEvent(a,{detail:b}))}function k(a){return"object"!==type(a)||a.nodeType||isWindow(a)?!1:!(a.constructor&&!hasOwn.call(a.constructor.prototype,"isPrototypeOf"))}var d=e({version:"2.4",prefix:"Local_API_1484_11",errorCode:0,diagnostic:"",initialized:0,terminated:0,user:void 0,debug:!0,listeners:{},CMI:{_version:"1.0",comments_from_learner:{_children:"comment,location,timestamp", _count:"0"},comments_from_lms:{_children:"comment,location,timestamp",_count:"0"},completion_status:"unknown",completion_threshold:"0.7",credit:"credit",entry:"ab-initio",exit:"",interactions:{_children:"id,type,objectives,timestamp,correct_responses,weighting,learner_response,result,latency,description",_count:"0"},launch_data:"",learner_id:"100",learner_name:"Simulated User",learner_preference:{_children:"audio_level,language,delivery_speed,audio_captioning",audio_level:"1",language:"",delivery_speed:"1", -audio_captioning:"0"},location:"",max_time_allowed:"",mode:"normal",objectives:{_children:"id,score,success_status,completion_status,description",_count:"0"},progress_measure:"",scaled_passing_score:"0.5",score:{_children:"scaled,raw,min,max",scaled:"",raw:"",min:"",max:""},session_time:"PT0H0M0S",success_status:"unknown",suspend_data:"",time_limit_action:"",total_time:"PT0H0M0S"}},e),g={},m={0:"No error",101:"General exception",102:"General Initialization Failure",103:"Already Initialized",104:"Content Instance Terminated", +audio_captioning:"0"},location:"",max_time_allowed:"",mode:"normal",objectives:{_children:"id,score,success_status,completion_status,description",_count:"0"},progress_measure:"",scaled_passing_score:"0.5",score:{_children:"scaled,raw,min,max",scaled:"",raw:"",min:"",max:""},session_time:"PT0H0M0S",success_status:"unknown",suspend_data:"",time_limit_action:"",total_time:"PT0H0M0S"}},c),h={},n={0:"No error",101:"General exception",102:"General Initialization Failure",103:"Already Initialized",104:"Content Instance Terminated", 111:"General Termination Failure",112:"Termination Before Initialization",113:"Termination After Termination",122:"Retrieve Data Before Initialization",123:"Retrieve Data After Termination",132:"Store Data Before Initialization",133:"Store Data After Termination",142:"Commit Before Initialization",143:"Commit After Termination",201:"General Argument Error",301:"General Get Failure",351:"General Set Failure",391:"General Commit Failure",401:"Undefined Data Model",402:"Unimplemented Data Model Element", -403:"Data Model Element Value Not Initialized",404:"Data Model Element Is Read Only",405:"Data Model Element Is Write Only",406:"Data Model Element Type Mismatch",407:"Data Model Element Value Out Of Range",408:"Data Model Dependency Not Established"},r=this;"object"===typeof c.user&&("string"===typeof c.user.name&&(c.CMI.learner_name=c.user.name),"string"===typeof c.user.id&&(c.CMI.learner_id=c.user.id));this.isRunning=function(){return 1===c.initialized&&0===c.terminated};this.Initialize=function(){q(c.prefix+ -": Initializing...",3);c.cmi?(g=c.cmi,"suspend"===g.exit&&(g.entry="resume")):g=c.CMI;c.initialized=1;c.terminated=0;return"true"};this.GetValue=function(a){c.errorCode=0;var b="false";a=a.toString();var f=[];if(this.isRunning()){f=a.split(".");if(0<="|exit|session_time|".indexOf("|"+f[f.length-1]+"|"))return q(c.prefix+": This "+a+" is write only",4),c.errorCode=405,"false";f=a.toLowerCase().split(".");switch(f[0]){case "cmi":switch(b="false",a){case "cmi.exit":case "cmi.session_time":c.errorCode= -405;c.diagnostic="Sorry, this has been specified as a read-only value for "+a;break;case "cmi.learner_name":b=c.CMI.learner_name;break;default:b=d(a.substr(4,a.length),g),"undefined"===b&&(c.errorCode=401,c.diagnostic="Sorry, there was a undefined response from "+a,b="false"),q(c.prefix+": GetValue "+a+" = "+b,4)}}return b}c.errorCode=123;return b};this.SetValue=function(b,f){q(c.prefix+": SetValue: "+b+" = "+f,4);c.errorCode=0;var m=[],r=b.toString(),e=f.toString(),d=0,k=0,d=[];if(this.isRunning()){d= -r.split(".");if("adl"===d[0]&&"id"===d[4]||"comments_from_lms"===d[1]||("comments_from_learner"===d[1]?0:0<="|_version|completion_threshold|credit|entry|launch_data|learner_id|learner_name|_children|_count|mode|maximum_time_allowed|scaled_passing_score|time_limit_action|total_time|comment|".indexOf("|"+d[d.length-1]+"|")))return q(c.prefix+": This "+r+" is read only",4),c.errorCode=404,"false";m=r.split(".");switch(m[0]){case "cmi":switch(b){case "cmi.location":1E3=k&&(k=100);d=Math.max(0,Math.min(1,(d- -m)/k));p("cmi.score.scaled",d);break;case "cmi.success_status":if(-1==="|passed|failed|unknown|".indexOf("|"+e+"|"))return l(b,e);p(b,e);break;default:switch(m[1]){case "comments_from_lms":return c.errorCode="404",c.diagnostic="The cmi.comments_from_lms element is entirely read only.","false";case "comments_from_learner":if(-1===g.comments_from_learner._children.indexOf(m[3]))return l(b,e);n(r.substr(4,r.length),e,g);g.comments_from_learner._count=(h(g.comments_from_learner)-2).toString();return"true"; -case "interactions":if(-1===g.interactions._children.indexOf(m[3]))return l(b,e);g.interactions._count=(h(g.interactions)-2).toString();if(isNaN(parseInt(m[2],10)))return"false";if(!s(g.interactions[m[2]])){if("id"===m[3])return g.interactions[m[2]]={},n(r.substr(4,r.length),e,g),g.interactions._count=(h(g.interactions)-2).toString(),s(g.interactions[m[2]].objectives)||(q(c.prefix+": Constructing objectives object for new interaction",4),g.interactions[m[2]].objectives={},g.interactions[m[2]].objectives._count= -"-1"),s(g.interactions[m[2]].correct_responses)||(q(c.prefix+": Constructing correct responses object for new interaction",4),g.interactions[m[2]].correct_responses={},g.interactions[m[2]].correct_responses._count="-1"),"true";q("Can't add interaction without ID first!",3);return"false"}if("objectives"===m[3]){if("id"===m[5])for(k=parseInt(g.interactions[m[2]].objectives._count,10),d=0;da.length?c[a[0]]=b:(c[a[0]]||(c[a[0]]={}),c=c[a.shift()],n(a.join("."),b,c))}function d(a,b){var c=a.split(/\./), -f;if(2>c.length)try{return b[c[0]]}catch(g){return k(a),"false"}else{f=c.shift();if(b[f])return String(d(c.join("."),b[f]));k(a);return"false"}}function h(a,c){if(b.debug){window.console||(window.console={},window.console.info=noconsole,window.console.log=noconsole,window.console.warn=noconsole,window.console.error=noconsole,window.console.trace=noconsole);switch(c){case 1:console.error(a);break;case 2:console.warn(a);break;case 4:console.info(a);break;case 3:console.log(a);break;default:return console.log(a), -!1}return!0}3>c&&b.throw_alerts&&alert(a);return!1}function q(a,c){if("function"==typeof b.listeners[a]&&"undefined"!=typeof c)b.listeners[a](c)}function p(a,b){for(var c in b)b.hasOwnProperty(c)&&("object"==typeof a[c]?"object"==typeof b[c]&&(a[c]=p(a[c],b[c])):a[c]=b[c]);return a}function f(a,b){(function(){function a(b,c){c=c||{bubbles:!1,cancelable:!1,detail:void 0};var f=document.createEvent("CustomEvent");f.initCustomEvent(b,c.bubbles,c.cancelable,c.detail);return f}if("function"===typeof window.CustomEvent)return!1; -a.prototype=window.Event.prototype;window.CustomEvent=a})();document.dispatchEvent(new CustomEvent(a,{detail:b}))}var b=p({version:"1.1",prefix:"Local_API_SCORM_12",errorCode:0,diagnostic:"",initialized:0,terminated:0,user:void 0,debug:!0,listeners:{},CMI:{_version:"3.4",comments:"",comments_from_lms:"",launch_data:"",suspend_data:"",core:{entry:"ab-initio",credit:"credit",lesson_status:"not attempted",lesson_mode:"normal",lesson_location:"",student_id:"100",student_name:"Simulated User",student_preference:{_children:"audio,language,speed,text", -audio:"0",language:"",speed:"0",text:"0"},score:{_children:"raw,min,max",raw:"",max:"",min:""},total_time:"0000:00:00.00",session_time:"",exit:""},student_data:{_children:"mastery_score,time_limit_action,max_time_allowed",mastery_score:"50",max_time_allowed:"",time_limit_action:"continue,no message"}}},e),s={},c={0:"No error",101:"General exception",102:"General Initialization Failure",103:"Already Initialized",104:"Content Instance Terminated",111:"General Termination Failure",112:"Termination Before Initialization", +403:"Data Model Element Value Not Initialized",404:"Data Model Element Is Read Only",405:"Data Model Element Is Write Only",406:"Data Model Element Type Mismatch",407:"Data Model Element Value Out Of Range",408:"Data Model Dependency Not Established"},q=this;"object"===typeof d.user&&("string"===typeof d.user.name&&(d.CMI.learner_name=d.user.name),"string"===typeof d.user.id&&(d.CMI.learner_id=d.user.id));this.isRunning=function(){return 1===d.initialized&&0===d.terminated};this.Initialize=function(){m(d.prefix+ +": Initializing...",3);d.cmi?(h=d.cmi,"suspend"===h.exit&&(h.entry="resume")):h=d.CMI;d.initialized=1;d.terminated=0;return"true"};this.GetValue=function(a){d.errorCode=0;var b="false";a=a.toString();var n=[];if(this.isRunning()){n=a.split(".");if(0<="|exit|session_time|".indexOf("|"+n[n.length-1]+"|"))return m(d.prefix+": This "+a+" is write only",4),d.errorCode=405,"false";n=a.toLowerCase().split(".");switch(n[0]){case "cmi":switch(b="false",a){case "cmi.exit":case "cmi.session_time":d.errorCode= +405;d.diagnostic="Sorry, this has been specified as a read-only value for "+a;break;case "cmi.learner_name":b=d.CMI.learner_name;break;default:b=t(a.substr(4,a.length),h),"undefined"===b&&(d.errorCode=401,d.diagnostic="Sorry, there was a undefined response from "+a,b="false"),m(d.prefix+": GetValue "+a+" = "+b,4)}}return b}d.errorCode=123;return b};this.SetValue=function(b,n){m(d.prefix+": SetValue: "+b+" = "+n,4);d.errorCode=0;var e=[],q=b.toString(),c=n.toString(),p=0,g=0,p=[];if(this.isRunning()){p= +q.split(".");if("adl"===p[0]&&"id"===p[4]||"comments_from_lms"===p[1]||("comments_from_learner"===p[1]?0:0<="|_version|completion_threshold|credit|entry|launch_data|learner_id|learner_name|_children|_count|mode|maximum_time_allowed|scaled_passing_score|time_limit_action|total_time|comment|".indexOf("|"+p[p.length-1]+"|")))return m(d.prefix+": This "+q+" is read only",4),d.errorCode=404,"false";e=q.split(".");switch(e[0]){case "cmi":switch(b){case "cmi.location":1E3=g&&(g=100);p=Math.max(0,Math.min(1,(p- +e)/g));s("cmi.score.scaled",p);break;case "cmi.success_status":if(-1==="|passed|failed|unknown|".indexOf("|"+c+"|"))return f(b,c);s(b,c);break;default:switch(e[1]){case "comments_from_lms":return d.errorCode="404",d.diagnostic="The cmi.comments_from_lms element is entirely read only.","false";case "comments_from_learner":if(-1===h.comments_from_learner._children.indexOf(e[3]))return f(b,c);a(q.substr(4,q.length),c,h);h.comments_from_learner._count=(r(h.comments_from_learner)-2).toString();return"true"; +case "interactions":if(-1===h.interactions._children.indexOf(e[3]))return f(b,c);h.interactions._count=(r(h.interactions)-2).toString();if(isNaN(parseInt(e[2],10)))return"false";if(!k(h.interactions[e[2]])){if("id"===e[3])return h.interactions[e[2]]={},a(q.substr(4,q.length),c,h),h.interactions._count=(r(h.interactions)-2).toString(),k(h.interactions[e[2]].objectives)||(m(d.prefix+": Constructing objectives object for new interaction",4),h.interactions[e[2]].objectives={},h.interactions[e[2]].objectives._count= +"-1"),k(h.interactions[e[2]].correct_responses)||(m(d.prefix+": Constructing correct responses object for new interaction",4),h.interactions[e[2]].correct_responses={},h.interactions[e[2]].correct_responses._count="-1"),"true";m("Can't add interaction without ID first!",3);return"false"}if("objectives"===e[3]){if("id"===e[5])for(g=parseInt(h.interactions[e[2]].objectives._count,10),p=0;pb.length?e[b[0]]=d:(e[b[0]]||(e[b[0]]={}),e=e[b.shift()],a(b.join("."),d,e))}function t(a,b){var d=a.split(/\./), +e;if(2>d.length)try{return b[d[0]]}catch(h){return g(a),"false"}else{e=d.shift();if(b[e])return String(t(d.join("."),b[e]));g(a);return"false"}}function r(a,d){if(b.debug){window.console||(window.console={},window.console.info=noconsole,window.console.log=noconsole,window.console.warn=noconsole,window.console.error=noconsole,window.console.trace=noconsole);switch(d){case 1:console.error(a);break;case 2:console.warn(a);break;case 4:console.info(a);break;case 3:console.log(a);break;default:return console.log(a), +!1}return!0}3>d&&b.throw_alerts&&alert(a);return!1}function m(a,d){if("function"==typeof b.listeners[a]&&"undefined"!=typeof d)b.listeners[a](d)}function s(a,b){for(var d in b)b.hasOwnProperty(d)&&("object"==typeof a[d]?"object"==typeof b[d]&&(a[d]=s(a[d],b[d])):a[d]=b[d]);return a}function e(a,b){(function(){function a(b,d){d=d||{bubbles:!1,cancelable:!1,detail:void 0};var e=document.createEvent("CustomEvent");e.initCustomEvent(b,d.bubbles,d.cancelable,d.detail);return e}if("function"===typeof window.CustomEvent)return!1; +a.prototype=window.Event.prototype;window.CustomEvent=a})();document.dispatchEvent(new CustomEvent(a,{detail:b}))}var b=s({version:"1.1",prefix:"Local_API_SCORM_12",errorCode:0,diagnostic:"",initialized:0,terminated:0,user:void 0,debug:!0,listeners:{},CMI:{_version:"3.4",comments:"",comments_from_lms:"",launch_data:"",suspend_data:"",core:{entry:"ab-initio",credit:"credit",lesson_status:"not attempted",lesson_mode:"normal",lesson_location:"",student_id:"100",student_name:"Simulated User",student_preference:{_children:"audio,language,speed,text", +audio:"0",language:"",speed:"0",text:"0"},score:{_children:"raw,min,max",raw:"",max:"",min:""},total_time:"0000:00:00.00",session_time:"",exit:""},student_data:{_children:"mastery_score,time_limit_action,max_time_allowed",mastery_score:"50",max_time_allowed:"",time_limit_action:"continue,no message"}}},c),k={},d={0:"No error",101:"General exception",102:"General Initialization Failure",103:"Already Initialized",104:"Content Instance Terminated",111:"General Termination Failure",112:"Termination Before Initialization", 113:"Termination After Termination",122:"Retrieve Data Before Initialization",123:"Retrieve Data After Termination",132:"Store Data Before Initialization",133:"Store Data After Termination",142:"Commit Before Initialization",143:"Commit After Termination",201:"General Argument Error",301:"General Get Failure",351:"General Set Failure",391:"General Commit Failure",401:"Undefined Data Model",402:"Unimplemented Data Model Element",403:"Data Model Element Value Not Initialized",404:"Data Model Element Is Read Only", -405:"Data Model Element Is Write Only",406:"Data Model Element Type Mismatch",407:"Data Model Element Value Out Of Range",408:"Data Model Dependency Not Established"},g=this;"object"===typeof b.user&&("string"===typeof b.user.name&&(b.CMI.core.student_name=b.user.name),"string"===typeof b.user.id&&(b.CMI.core.student_id=b.user.id));this.isRunning=function(){return 1===b.initialized&&0===b.terminated};this.LMSInitialize=function(){h(b.prefix+": Initializing...",3);s=b.CMI;b.initialized=1;b.terminated= -0;return"true"};this.LMSGetValue=function(a){b.errorCode=0;var c="false";a=a.toString();var f=[];if(this.isRunning()){f=a.split(".");if(0<="|exit|session_time|".indexOf("|"+f[f.length-1]+"|"))return b.errorCode=405,"false";f=a.toLowerCase().split(".");switch(f[0]){case "cmi":c=a;a="false";switch(c){case "cmi.core.exit":case "cmi.core.session_time":b.errorCode=405;b.diagnostic="Sorry, this has been specified as a read-only value for "+c;break;default:c=c.replace("cmi.",""),a=d(c,s),"undefined"===a&& -(b.errorCode=401,b.diagnostic="Sorry, there was a undefined response from "+c,a="false")}c=a}return c}b.errorCode=123;return c};this.LMSSetValue=function(c,f){h(b.prefix+": SetValue: "+c+" = "+f,4);b.errorCode=0;var g=[],d=c.toString(),e=f.toString();if(this.isRunning()){var g=d.split("."),k=g[g.length-1],g="adl"===g[0]&&"id"===g[4]?!0:"comments_from_lms"===g[1]?!0:0<="|_version|completion_threshold|credit|entry|launch_data|learner_id|learner_name|_children|_count|mode|maximum_time_allowed|scaled_passing_score|time_limit_action|total_time|comment|".indexOf("|"+ -k+"|");if(g)return b.errorCode=404,"false";g=d.split(".");switch(g[0]){case "cmi":switch(c){case "cmi.core.lesson_location":1E3=p&&(p=100);g=Math.max(0, -Math.min(1,(g-k)/p));q("cmi.score.scaled",g)}d=d.replace("cmi.","");n(d,e,s)}return"true"}b.errorCode=b.terminated?133:132;return"false"};this.LMSCommit=function(){f("StoreData",{runtimedata:s});return"true"};this.LMSTerminate=function(){g.LMSCommit();b.terminated=1;b.initialized=0;return"true"};this.LMSFinish=function(){g.LMSCommit();b.terminated=1;b.initialized=0;return"true"};this.LMSGetErrorString=function(a){return""!==a&&(a=parseInt(a,10),void 0!==c[a])?c[a]:""};this.LMSGetLastError=function(){return b.errorCode}; -this.LMSGetDiagnostic=function(){return b.diagnostic};this.setCMILMSValue=function(a,c){"string"==typeof a&&(b.CMI[a]=c)};this.addListener=function(a,c){"string"==typeof a&&"function"==typeof c&&(b.listeners[a]=c)}};SGAME=function(){return{init:function(e){return SGAME.CORE.init(e)},loadSettings:function(e){return SGAME.CORE.loadSettings(e)},triggerLO:function(e,l){return SGAME.CORE.triggerLO(e,l)},showLO:function(e,l){return SGAME.CORE.showLO(e,l)},showRandomLO:function(e){return SGAME.CORE.showRandomLO(e)},closeLO:function(){return SGAME.CORE.closeLO()},getSettings:function(){return SGAME.CORE.getSettings()},losCanBeShown:function(e){return SGAME.CORE.losCanBeShown(e)},successWhenNoLOs:function(e){return SGAME.CORE.successWhenNoLOs(e)}}}(); -SGAME.VERSION="0.7";SGAME.AUTHORS="Aldo Gordillo, Enrique Barra";SGAME.URL="https://github.com/ging/sgame_platform";SGAME.Debugger=function(){var e=!1;return{init:function(l){!0===l&&(e=l)},isDebugging:function(){return e},log:function(l){e&&window.console&&console.log(l)}}}();SGAME.Messenger=function(){function e(b,f){this.data=b||{};-1!==["PROTOCOL","APP"].indexOf(f)?this.type=f:this.type="APP";this.origin=a;this.destination=n}var l=["PROTOCOL","APP"],k=["SGAME_GATEWAY","SGAME_API"],a="SGAME_API",n="SGAME_GATEWAY",d=!1,h=!1,q=function(a){try{window.parent.parent.postMessage(a,"*")}catch(f){}},p=function(b){var d;d="object"!==typeof b||"string"!==typeof b.data?!1:f(b.data);if(d)switch(b=JSON.parse(b.data),b.type){case "PROTOCOL":if(b.data)switch(b.data.key){case "onIframeMessengerHello":"SGAME_GATEWAY"=== -b.origin&&!0!==h&&(h=!0,b.data.settings=SGAME.CORE.getSettings(),b.destination=b.origin,b.origin=a,q(JSON.stringify(b)),SGAME.CORE.onConnectedToVLE())}break;case "APP":if(b.data&&"string"===typeof b.data.key)switch(b.data.key){case "lms_data":if("object"===typeof b.data.value){d=b.data.value;b={};if("string"===typeof d.name||"number"===typeof d.name)b.name=""+d.name;if("string"===typeof d.id||"number"===typeof d.id)b.id=""+d.id;d=SGAME.CORE.getVLEData();d.user=b;SGAME.CORE.setVLEData(d)}}}},f=function(a){try{if(a= -JSON.parse(a),-1===l.indexOf(a.type)||-1===k.indexOf(a.origin))return!1}catch(f){return!1}return!0};return{init:function(a){if(!d){d=!0;try{window.parent.addEventListener?window.parent.addEventListener("message",p,!1):window.attachEvent&&window.parent.attachEvent("message",p)}catch(f){}}},isConnected:function(){return h},sendMessage:function(a){d&&h&&(a=JSON.stringify(new e(a,void 0)),f(a)&&q(a))}}}();SGAME.API=function(){var e=function(e,k){var a=new XMLHttpRequest;a.onreadystatechange=function(){if(4==a.readyState&&200==a.status){var e=JSON.parse(a.responseText);k(e)}};a.open("GET",e,!0);a.send("")};return{init:function(){},requestLOMetadata:function(l,k,a){try{e("undefined"==typeof l?"/lo/random/metadata.json":"/lo/"+l+"/metadata.json",function(a){k(a)})}catch(n){a(n)}}}}();SGAME.CORE=function(){var e={},l=void 0,k="Congratulations. You have achieved the objectives of this educational game. You may close this window or continue playing.",a={},n=!1,d={},h={progress_measure:0,completion_status:"incompleted",score:0,success_status:"unknown"},q=["repeat","repeat_unless_successfully_consumed","no_repeat"],p=["no_restrictions","n_times","1_per_timeperiod"],f=["random","linear_completion","linear_success","custom"],b="all_los percentage_los n_los n_times disabled onstart".split(" "), -s="all_los percentage_los n_los n_times disabled onstart oncompletion".split(" "),c="no_more_los all_los_consumed all_los_succesfully_consumed completion_status success_status never".split(" "),g=["success","failure","success_unless_damage","failure_unless_blocking"],m=!1,r=0,v=0,w=0,x=0,t=0,D=!1,z=void 0,E=function(u){a=u;"undefined"===typeof a.game_metadata&&(a.game_metadata={});"undefined"===typeof a.los&&(a.los={});"undefined"===typeof a.events&&(a.events={});"undefined"===typeof a.event_mapping&& -(a.event_mapping={});"undefined"===typeof a.sequencing&&(a.sequencing={});-1===q.indexOf(a.sequencing.repeat_lo)&&(a.sequencing.repeat_lo="repeat");-1===p.indexOf(a.sequencing.interruptions)&&(a.sequencing.interruptions="no_restrictions");-1===f.indexOf(a.sequencing.approach)&&(a.sequencing.approach="random",delete a.sequencing.sequence);-1!==["n_times","1_per_timeperiod"].indexOf(a.sequencing.interruptions)&&"number"===typeof a.sequencing.interruptions_n||delete a.sequencing.interruptions_n;-1!== -["n_times","1_per_timeperiod"].indexOf(a.sequencing.interruptions)&&"number"!==typeof a.sequencing.interruptions_n&&(a.sequencing.interruptions="no_restrictions");"undefined"===typeof a.game_settings&&(a.game_settings={});-1===b.indexOf(a.game_settings.completion_status)&&(a.game_settings.completion_status="disabled");-1!==["percentage_los","n_los","n_times"].indexOf(a.game_settings.completion_status)&&"number"===typeof a.game_settings.completion_status_n||delete a.game_settings.completion_status_n; --1!==["percentage_los","n_los","n_times"].indexOf(a.game_settings.completion_status)&&"number"!==typeof a.game_settings.completion_status_n&&(a.game_settings.completion_status="disabled",delete a.game_settings.completion_status_n);-1===s.indexOf(a.game_settings.success_status)&&(a.game_settings.success_status="disabled");-1!==["percentage_los","n_los","n_times"].indexOf(a.game_settings.success_status)&&"number"===typeof a.game_settings.success_status_n||delete a.game_settings.success_status_n;-1!== -["percentage_los","n_los","n_times"].indexOf(a.game_settings.success_status)&&"number"!==typeof a.game_settings.success_status_n&&(a.game_settings.success_status="disabled",delete a.game_settings.success_status_n);-1===c.indexOf(a.game_settings.completion_notification)&&(a.game_settings.completion_notification="never");-1===g.indexOf(a.game_settings.behaviour_when_no_more_los)&&(a.game_settings.behaviour_when_no_more_los="success_unless_damage");"string"===typeof a.game_settings.completion_notification_text&& -(k=a.game_settings.completion_notification_text);if("object"===typeof a.los){u=Object.keys(a.los);r=u.length;for(var d=0;dd.length)return A(b,c);var g=G(d);if(0=d||0>=r?1:v/r/d;break;case "n_los":d=Math.min(a.game_settings.completion_status_n, -r);b=0===d?1:v/d;break;case "n_times":b=0>=a.game_settings.completion_status_n?1:w/a.game_settings.completion_status_n;break;case "onstart":b=1}b=Math.max(Math.min(1,+b.toFixed(2)),0);c=1===b?"completed":"incompleted";d=0;switch(a.game_settings.success_status){case "all_los":a.game_settings.success_status_n=100;case "percentage_los":d=Math.min(100,Math.max(0,a.game_settings.success_status_n))/100;d=0>=d||0>=r?1:x/r/d;break;case "n_los":d=Math.min(a.game_settings.success_status_n,r);d=0===d?1:v/d; -break;case "n_times":d=0>=a.game_settings.success_status_n?1:t/a.game_settings.success_status_n;break;case "oncompletion":d=b;break;case "onstart":d=1}d=Math.max(Math.min(1,+d.toFixed(2)),0);h={progress_measure:b,completion_status:c,score:d,success_status:1===d?"passed":"failed"};SGAME.Messenger.sendMessage({key:"tracking",value:h})},J=function(a){!0!==K()?"function"===typeof a&&a(!1):O(a)},K=function(){if(!0===D)return!1;switch(a.game_settings.completion_notification){case "no_more_los":return!1=== -m;case "all_los_consumed":return v>=r;case "all_los_succesfully_consumed":return x>=r;case "completion_status":return"completed"===h.completion_status;case "success_status":return"passed"===h.success_status;case "never":return!1;default:return!1}},O=function(a){D=!0;SGAME.Fancybox.create({dialog:!0,msg:k},function(){"function"===typeof a&&a(!0)})},H=function(a){for(var b=[],c,d=0;d=a.sequencing.interruptions_n?A(b,c):C(b,c);case "1_per_timeperiod":return"undefined"!==typeof z&& -(new Date-z)/1E3<=a.sequencing.interruptions_n?A(b,c):C(b,c)}},showLO:B,showRandomLO:function(a){SGAME.API.requestLOMetadata(void 0,function(b){B(b,a)},function(){"function"===typeof a&&a(null,null)})},closeLO:function(){SGAME.Fancybox.closeCurrentFancybox()},getSettings:function(){return a},losCanBeShown:function(a){return!1===m?!1:"undefined"===typeof a?m:0c?(b=c,s=b/f):(s=g,b=s*f);if("lo"===p)var m={},r;else var v="";h&&(h.width&&(b=h.width),h.height&&(s=h.height),"lo"===p?h.lo&&(m=h.lo,"string"===typeof m.url&&(r=m.url)):"string"==typeof h.msg&&(v=h.msg));if("lo"===p){if("string"!=typeof r||"undefined"==typeof m.scorm_type)return;var w=e,f=API_1484_11=API=e,x=SGAME.CORE.getVLEData();"object"===typeof x.user&&(f=x.user);"sco"===m.scorm_type&&("1.2"===m.scorm_version?w=API=new Local_API_SCORM_12({user:f,debug:SGAME.Debugger.isDebugging()}):"2004"=== -m.scorm_version&&(w=API_1484_11=new Local_API_1484_11({user:f,debug:SGAME.Debugger.isDebugging()})))}f=document.createElement("div");f.style.width=b+"px";f.style.height=s+"px";f.style.maxWidth=c+"px";f.style.maxHeight=g+"px";f.style.overflow="lo"===p?"hidden":"auto";f.style.background="white";f.style.position="absolute";f.style.top=0;f.style.zIndex=9999;f.style.borderRadius="1em";f.style.border="2px solid black";f.setAttribute("id","sgame_fancybox");f.style.marginLeft=(window.innerWidth-b)/2+"px"; -f.style.marginTop=(window.innerHeight-s)/2+"px";g=document.createElement("img");g.src="/assets/sgame/close.png";c=Math.max(25,Math.floor(0.05*s));g.style.width=c+"px";g.style.height=c+"px";g.style.padding="5px";g.style.cursor="pointer";g.style.position="absolute";g.style.right=0;g.onclick=function(){d()};f.appendChild(g);if("lo"===p){var t=document.createElement("img");t.id="trafficLight";t.src="/assets/sgame/trafficLight/trafficLight_red.png";v=Math.max(40,Math.floor(0.085*s));g=Math.max(30,Math.floor(0.75* -v));t.style.height=v+"px";t.style.width=g+"px";t.style.padding="4px";t.style.position="absolute";t.style.left="0px";t.style.top="0px";t.style.background="#fff";t.style.borderRadius="0px 0px 20px 0px";t.style.borderRight="2px solid black";t.style.borderBottom="2px solid black";f.appendChild(t);t=document.createElement("iframe");t.src=r;r=Math.ceil(Math.max(c,v))+4;v=Math.floor(0.02*s);c=Math.floor(0.02*b);t.style.marginLeft=c+"px";t.style.marginTop=r+"px";t.style.width=Math.max(0,b-c-c)+"px";t.style.height= -Math.max(0,s-r-v)+"px";t.style.overflow="auto";t.scrolling="yes";t.style.frameBorder="0";t.style.borderStyle="none";t.setAttribute("allowfullscreen","false");f.appendChild(t)}else b=document.createElement("p"),b.id="dialog",b.innerHTML=v,b.style.padding="15px",b.style.marginTop="30px",b.style.marginBottom="20px",b.style.marginRight="20px",b.style.marginLeft="20px",b.style.textAlign="center",b.style.fontSize="24px",b.style.position="relative",b.style.cursor="default",b.style.color="#000",b.style.fontFamily= -"initial",f.appendChild(b);l=f;k=p;document.body.appendChild(f);"lo"===p&&SGAME.Observer.start(t,m,w)},closeCurrentFancybox:d}}();SGAME.Observer=function(e){var l=!0,k=e,a=e,n=e,d,h,q,p,f,b,s=function(){n=a=k=e;d=Date.now();h=!1;b=f=p=q=e},c=function(){!1===a.acts_as_asset&&"undefined"!==typeof n&&(n.addListener("cmi.success_status",function(a){q=a;"passed"===q&&"green"!=SGAME.TrafficLight.getCurrentColor()&&(SGAME.TrafficLight.stop(),SGAME.TrafficLight.changeColor("green"))}),n.addListener("cmi.score.scaled",function(a){p=a;0.8<=p&&"green"!=SGAME.TrafficLight.getCurrentColor()&&(SGAME.TrafficLight.stop(),SGAME.TrafficLight.changeColor("green"))}), -n.addListener("cmi.completion_status",function(a){f=a}),n.addListener("cmi.progress_measure",function(a){b=a}))};return{start:function(b,d,f){if(!1===l||"undefined"!=typeof k)return null;l=!1;s();k=b;a=d;n=f;c();SGAME.TrafficLight.changeColor("red");if(!0===a.acts_as_asset){b:{b=a.lom_metadata;if(b.educational&&b.educational.typicalLearningTime&&b.educational.typicalLearningTime.duration&&(b=iso8601Parser.getDuration(b.educational.typicalLearningTime.duration)))break b;b=null}b=!b||0>=b?15:Math.min(0.5* -b,120);SGAME.TrafficLight.setUpBlink("yellow",0.5*b-0.5,0.5*b);SGAME.TrafficLight.changeColor("green",b)}},stop:function(){if(!0===l||"undefined"==typeof k)return null;l=!0;SGAME.TrafficLight.stop();var c=Math.round((Date.now()-d)/1E3);h="green"===SGAME.TrafficLight.getCurrentColor();c={lo_metadata:a,time:c,success:h};"undefined"!=typeof q&&(c.scorm_success_status=q);"undefined"!=typeof p&&(c.scorm_scaled_score=p);"undefined"!=typeof f&&(c.scorm_completion_status=f);"undefined"!=typeof b&&(c.scorm_progress_measure= -b);s();return c},isStopped:function(){return l}}}();SGAME.Sequencing=function(){var e=["completion","success"],l=function(a){for(var e=Object.keys(a),d=e.length,h=0;hp.los.length?!1:p;!1!==p?a[d[k]]=p:delete a[d[k]]}a=l(a);d=Object.keys(a);h=[];for(k=0;ktypeof d.length||2>h.length?!1:a},updateGroupsTracking:function(a,e,d){for(var h=0;h=t&&(t=100);h=Math.max(0, +Math.min(1,(h-s)/t));m("cmi.score.scaled",h)}c=c.replace("cmi.","");a(c,g,k)}return"true"}b.errorCode=b.terminated?133:132;return"false"};this.LMSCommit=function(){e("StoreData",{runtimedata:k});return"true"};this.LMSTerminate=function(){h.LMSCommit();b.terminated=1;b.initialized=0;return"true"};this.LMSFinish=function(){h.LMSCommit();b.terminated=1;b.initialized=0;return"true"};this.LMSGetErrorString=function(a){return""!==a&&(a=parseInt(a,10),void 0!==d[a])?d[a]:""};this.LMSGetLastError=function(){return b.errorCode}; +this.LMSGetDiagnostic=function(){return b.diagnostic};this.setCMILMSValue=function(a,d){"string"==typeof a&&(b.CMI[a]=d)};this.addListener=function(a,d){"string"==typeof a&&"function"==typeof d&&(b.listeners[a]=d)}};SGAME=function(){return{init:function(c){return SGAME.CORE.init(c)},loadSettings:function(c){return SGAME.CORE.loadSettings(c)},triggerLO:function(c,f){return SGAME.CORE.triggerLO(c,f)},showLO:function(c,f){return SGAME.CORE.showLO(c,f)},showRandomLO:function(c){return SGAME.CORE.showRandomLO(c)},closeLO:function(){return SGAME.CORE.closeLO()},getSettings:function(){return SGAME.CORE.getSettings()},losCanBeShown:function(c){return SGAME.CORE.losCanBeShown(c)},successWhenNoLOs:function(c){return SGAME.CORE.successWhenNoLOs(c)}}}(); +SGAME.VERSION="1.0.0";SGAME.AUTHORS="Aldo Gordillo";SGAME.URL="https://github.com/ging/sgame_platform";SGAME.Debugger=function(){var c=!1;return{init:function(f){!0===f&&(c=f)},isDebugging:function(){return c},log:function(f){c&&window.console&&console.log(f)}}}();SGAME.Messenger=function(){function c(b,e){this.data=b||{};-1!==["PROTOCOL","APP"].indexOf(e)?this.type=e:this.type="APP";this.origin=l;this.destination=a}var f=["PROTOCOL","APP"],g=["SGAME_GATEWAY","SGAME_API"],l="SGAME_API",a="SGAME_GATEWAY",t=!1,r=!1,m=function(a){try{window.parent.parent.postMessage(a,"*")}catch(e){}},s=function(a){var c;c="object"!==typeof a||"string"!==typeof a.data?!1:e(a.data);if(c)switch(a=JSON.parse(a.data),a.type){case "PROTOCOL":if(a.data)switch(a.data.key){case "onIframeMessengerHello":"SGAME_GATEWAY"=== +a.origin&&!0!==r&&(r=!0,a.data.settings=SGAME.CORE.getSettings(),a.destination=a.origin,a.origin=l,m(JSON.stringify(a)),SGAME.CORE.onConnectedToVLE())}break;case "APP":if(a.data&&"string"===typeof a.data.key)switch(a.data.key){case "lms_data":if("object"===typeof a.data.value){c=a.data.value;a={};if("string"===typeof c.name||"number"===typeof c.name)a.name=""+c.name;if("string"===typeof c.id||"number"===typeof c.id)a.id=""+c.id;c=SGAME.CORE.getVLEData();c.user=a;SGAME.CORE.setVLEData(c)}}}},e=function(a){try{if(a= +JSON.parse(a),-1===f.indexOf(a.type)||-1===g.indexOf(a.origin))return!1}catch(e){return!1}return!0};return{init:function(a){if(!t){t=!0;try{window.parent.addEventListener?window.parent.addEventListener("message",s,!1):window.attachEvent&&window.parent.attachEvent("message",s)}catch(e){}}},isConnected:function(){return r},sendMessage:function(a){t&&r&&(a=JSON.stringify(new c(a,void 0)),e(a)&&m(a))}}}();SGAME.Sequencing=function(){var c,f=["completion","success"],g=function(a){for(var c=Object.keys(a),f=c.length,e=0;ek.los.length?!1:k;!1!==k?a[f[b]]=k:delete a[f[b]]}a=g(a);f=Object.keys(a);e=[];for(b=0;btypeof f.length||2>e.length?!1:a},updateGroupsTracking:function(c,f,g){for(var e=0;ec.length)return B(b,d);var e=G(c);if(0=c||0>=v?1:w/v/c;break;case "n_los":c=Math.min(a.game_settings.completion_status_n,v);b=0===c?1:w/c;break;case "n_times":b=0>=a.game_settings.completion_status_n?1:x/a.game_settings.completion_status_n;break;case "onstart":b=1}b=Math.max(Math.min(1,+b.toFixed(2)),0);d=1===b?"completed":"incompleted";c=0;switch(a.game_settings.success_status){case "all_los":a.game_settings.success_status_n=100;case "percentage_los":c= +Math.min(100,Math.max(0,a.game_settings.success_status_n))/100;c=0>=c||0>=v?1:u/v/c;break;case "n_los":c=Math.min(a.game_settings.success_status_n,v);c=0===c?1:w/c;break;case "n_times":c=0>=a.game_settings.success_status_n?1:y/a.game_settings.success_status_n;break;case "oncompletion":c=b;break;case "onstart":c=1}c=Math.max(Math.min(1,+c.toFixed(2)),0);m={progress_measure:b,completion_status:d,score:c,success_status:1===c?"passed":"failed"};SGAME.Messenger.sendMessage({key:"tracking",value:m})},J= +function(a){!0!==K()?"function"===typeof a&&a(!1):O(a)},K=function(){if(!0===p)return!1;switch(a.game_settings.completion_notification){case "no_more_los":return!1===q;case "all_los_consumed":return w>=v;case "all_los_succesfully_consumed":return u>=v;case "completion_status":return"completed"===m.completion_status;case "success_status":return"passed"===m.success_status;case "never":return!1;default:return!1}},O=function(a){p=!0;SGAME.Fancybox.create({dialog:!0,msg:l},function(){"function"===typeof a&& +a(!0)})},H=function(a){for(var b=[],c,d=0;d=a.sequencing.interruptions_n?B(b,d):D(b,d);case "1_per_timeperiod":return"undefined"!==typeof A&&(new Date-A)/1E3<=a.sequencing.interruptions_n?B(b,d):D(b,d)}},showLO:C,showRandomLO:function(a){SGAME.API.requestLOMetadata(void 0,function(b){C(b,a)},function(){"function"===typeof a&&a(null,null)})},closeLO:function(){SGAME.Fancybox.closeCurrentFancybox()},getSettings:function(){return a},losCanBeShown:function(a){return!1===q?!1:"undefined"===typeof a?q:0d?(b=d,k=b/e):(k=h,b=k*e);if("lo"===s)var n={},q;else var v="";r&&(r.width&&(b=r.width),r.height&&(k=r.height),"lo"===s?r.lo&&(n=r.lo,"string"===typeof n.url&&(q=n.url)):"string"==typeof r.msg&&(v=r.msg));if("lo"===s){if("string"!=typeof q||"undefined"==typeof n.scorm_type)return;var w=c,e=API_1484_11=API=c,x=SGAME.CORE.getVLEData();"object"===typeof x.user&&(e=x.user);"sco"===n.scorm_type&&("1.2"===n.scorm_version?w=API=new Local_API_SCORM_12({user:e,debug:SGAME.Debugger.isDebugging()}):"2004"=== +n.scorm_version&&(w=API_1484_11=new Local_API_1484_11({user:e,debug:SGAME.Debugger.isDebugging()})))}e=document.createElement("div");e.style.width=b+"px";e.style.height=k+"px";e.style.maxWidth=d+"px";e.style.maxHeight=h+"px";e.style.overflow="lo"===s?"hidden":"auto";e.style.background="white";e.style.position="absolute";e.style.top=0;e.style.zIndex=9999;e.style.borderRadius="1em";e.style.border="2px solid black";e.setAttribute("id","sgame_fancybox");e.style.marginLeft=(window.innerWidth-b)/2+"px"; +e.style.marginTop=(window.innerHeight-k)/2+"px";h=document.createElement("img");h.src="/assets/sgame/close.png";d=Math.max(25,Math.floor(0.05*k));h.style.width=d+"px";h.style.height=d+"px";h.style.padding="5px";h.style.cursor="pointer";h.style.position="absolute";h.style.right=0;h.onclick=function(){t()};e.appendChild(h);if("lo"===s){var u=document.createElement("img");u.id="trafficLight";u.src="/assets/sgame/trafficLight/trafficLight_red.png";v=Math.max(40,Math.floor(0.085*k));h=Math.max(30,Math.floor(0.75* +v));u.style.height=v+"px";u.style.width=h+"px";u.style.padding="4px";u.style.position="absolute";u.style.left="0px";u.style.top="0px";u.style.background="#fff";u.style.borderRadius="0px 0px 20px 0px";u.style.borderRight="2px solid black";u.style.borderBottom="2px solid black";e.appendChild(u);u=document.createElement("iframe");u.src=q;q=Math.ceil(Math.max(d,v))+4;v=Math.floor(0.02*k);d=Math.floor(0.02*b);u.style.marginLeft=d+"px";u.style.marginTop=q+"px";u.style.width=Math.max(0,b-d-d)+"px";u.style.height= +Math.max(0,k-q-v)+"px";u.style.overflow="auto";u.scrolling="yes";u.style.frameBorder="0";u.style.borderStyle="none";u.setAttribute("allowfullscreen","false");e.appendChild(u)}else b=document.createElement("p"),b.id="dialog",b.innerHTML=v,b.style.padding="15px",b.style.marginTop="30px",b.style.marginBottom="20px",b.style.marginRight="20px",b.style.marginLeft="20px",b.style.textAlign="center",b.style.fontSize="24px",b.style.position="relative",b.style.cursor="default",b.style.color="#000",b.style.fontFamily= +"initial",e.appendChild(b);f=e;g=s;document.body.appendChild(e);"lo"===s&&SGAME.Observer.start(u,n,w)},closeCurrentFancybox:t}}();SGAME.Observer=function(c){var f=!0,g=c,l=c,a=c,t,r,m,s,e,b,k=function(){a=l=g=c;t=Date.now();r=!1;b=e=s=m=c},d=function(){!1===l.acts_as_asset&&"undefined"!==typeof a&&(a.addListener("cmi.success_status",function(a){m=a;"passed"===m&&"green"!=SGAME.TrafficLight.getCurrentColor()&&(SGAME.TrafficLight.stop(),SGAME.TrafficLight.changeColor("green"))}),a.addListener("cmi.score.scaled",function(a){s=a;0.8<=s&&"green"!=SGAME.TrafficLight.getCurrentColor()&&(SGAME.TrafficLight.stop(),SGAME.TrafficLight.changeColor("green"))}), +a.addListener("cmi.completion_status",function(a){e=a}),a.addListener("cmi.progress_measure",function(a){b=a}))};return{start:function(b,c,e){if(!1===f||"undefined"!=typeof g)return null;f=!1;k();g=b;l=c;a=e;d();SGAME.TrafficLight.changeColor("red");if(!0===l.acts_as_asset){b:{b=l.lom_metadata;if(b.educational&&b.educational.typicalLearningTime&&b.educational.typicalLearningTime.duration&&(b=iso8601Parser.getDuration(b.educational.typicalLearningTime.duration)))break b;b=null}b=!b||0>=b?15:Math.min(0.5* +b,120);SGAME.TrafficLight.setUpBlink("yellow",0.5*b-0.5,0.5*b);SGAME.TrafficLight.changeColor("green",b)}},stop:function(){if(!0===f||"undefined"==typeof g)return null;f=!0;SGAME.TrafficLight.stop();var a=Math.round((Date.now()-t)/1E3);r="green"===SGAME.TrafficLight.getCurrentColor();a={lo_metadata:l,time:a,success:r};"undefined"!=typeof m&&(a.scorm_success_status=m);"undefined"!=typeof s&&(a.scorm_scaled_score=s);"undefined"!=typeof e&&(a.scorm_completion_status=e);"undefined"!=typeof b&&(a.scorm_progress_measure= +b);k();return a},isStopped:function(){return f}}}();SGAME.TrafficLight=function(c){var f,g,l,a,t,r=function(a){var b=document.getElementById("trafficLight");b&&(f=a,b.src=m(a))},m=function(a){switch(a){case "green":return"/assets/sgame/trafficLight/trafficLight_green.png";case "yellow":return"/assets/sgame/trafficLight/trafficLight_yellow.png";case "red":return"/assets/sgame/trafficLight/trafficLight_red.png";default:return"/assets/sgame/trafficLight/trafficLight.png"}},s=function(c,b){var f=document.getElementById("trafficLight");if(f){var d=!1;a= +setInterval(function(){f&&(d?(f.src=m(null),d=!1):(f.src=m(c),d=!0))},500);t=setTimeout(function(){clearTimeout(a)},1E3*b)}};return{getCurrentColor:function(){return f},changeColor:function(a,b){b?g=setTimeout(function(){r(a)},1E3*b):r(a)},setUpBlink:function(a,b,c){c?l=setTimeout(function(){s(a,b)},1E3*c):s(a,b)},stop:function(){g&&clearTimeout(g);l&&clearTimeout(l);a&&clearTimeout(a);t&&clearTimeout(t)}}}();SGAME.Utils=function(){var c=void 0;return{init:function(c){},getRandomElement:function(c){if("number"==typeof c)return c;var g;g=c.length-1;if("number"!=typeof g)throw{name:"Invalid number format exception"};g=Math.round(0+Math.random()*(g-0));return c[g]},loadScript:function(c,g){if("string"===typeof c&&"function"===typeof g){var l=document.getElementsByTagName("head")[0];if(l){var a=document.createElement("script");a.setAttribute("src",c);a.setAttribute("type","text/javascript");a.onreadystatechange= +function(){"complete"!=this.readyState&&"loaded"!=this.readyState||g()};a.onload=g;l.appendChild(a)}}},getProtocol:function(){if("undefined"!==typeof c)return c;var f;try{f=document.location.protocol}catch(g){}"string"===typeof f&&(f=f.match(/[\w]+/),f=f instanceof Array&&"string"===typeof f[0]?f[0]:void 0);return c="string"===typeof f?f:"unknown"},checkUrlProtocol:function(c){if("string"===typeof c){var g=c.match(/^https?:\/\//);if(g instanceof Array&&1===g.length){var g=g[0].replace("://",""),l= +SGAME.Utils.getProtocol();if(g!==l)switch(l){case "https":c="https"+c.replace(g,"")}}}return c}}}();