diff --git a/_common/modules/bundles/bebras-interface.js b/_common/modules/bundles/bebras-interface.js
index 2c3b109..b2fd703 100644
--- a/_common/modules/bundles/bebras-interface.js
+++ b/_common/modules/bundles/bebras-interface.js
@@ -1,267 +1,267 @@
-(function () {
-
-'use strict';
-
-function getUrlParameterByName(name) {
- name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
- var regex = new RegExp("[\\?&]" + name + "=([^]*)"),
- results = regex.exec(location.href);
- return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
-}
-
-function isCrossDomain() {
- function isInIframe() {
- try {
- return window.self !== window.top;
- } catch (e) {
- return false;
- }
- }
- function isSameDomain() {
- var res = false;
- function doNothing(document){}
- try{
- res = !! parent.document;
- } catch(e){
- res = false;
- }
- return res;
- }
- return isInIframe() && !isSameDomain();
-}
-
-var platform;
-
-if (!isCrossDomain()) {
-
- /* Implementation of a platform proxy for the task iframe. This object is always
- * available, but is effective only when setPlatform is called with a true
- * platform object.
- */
-
- platform = {
- registered_objects: [],
- parent_platform: null,
- initFailed: false,
- setPlatform: function(platformArg) {
- platform.parent_platform = platformArg;
- },
- trigger: function(event, content) {
- for (var i = 0; i < platform.registered_objects.length; i++) {
- var object = platform.registered_objects[i];
- if (typeof (object[event]) != "undefined") {
- object[event].apply(object, content);
- }
- }
- },
- subscribe: function(object) {
- this.registered_objects.push(object);
- },
- unsubscribe: function(object) {
- var index = this.registered_objects.indexOf(object);
- if (index != -1) {
- this.registered_objects.splice(index, 1);
- }
- },
- validate: function(mode, success, error) {
- // TODO: this case is a bit blur...
- var res = platform.parent_platform.validate(mode, success, error);
- this.trigger('validate', [mode]);
- return res;
- },
- showView: function(views, success, error) {
- return platform.parent_platform.showView(views, success, error);
- },
- askHint: function(platformToken, success, error) {
- return platform.parent_platform.askHint(platformToken, success, error);
- },
- updateHeight: function(height, success, error) {
- return platform.parent_platform.updateDisplay({height: height}, success, error);
- },
- updateDisplay: function(data, success, error) {
- return platform.parent_platform.updateDisplay(data, success, error);
- },
- getTaskParams: function(key, defaultValue, success, error) {
- return platform.parent_platform.getTaskParams(key, defaultValue, success, error);
- },
- openUrl: function(url, success, error) {
- return platform.parent_platform.openUrl(url, success, error);
- },
- initCallback: function(callback) {
- this.initCallbackFun = callback;
- if (platform.initDone) {
- callback();
- }
- },
- initWithTask: function(task) {
- platform.task = task;
- window.task = task;
- platform.initDone = true;
- if (platform.initCallbackFun) {
- platform.initCallbackFun();
- }
- }
- };
-
-} else {
-
- // cross-domain version, depends on jschannel
- platform = {};
- var callAndTrigger = function(fun, triggerName, error, args) {
- return function() {
- try {
- platform.trigger(triggerName, args);
- fun(arguments);
- } catch(e) {
- error(e.toString()+'\n'+e.stack);
- }
- };
- };
- platform.ready = false;
- platform.initFailed = false;
- platform.initWithTask = function(task) {
- if (typeof Channel === 'undefined') {
- platform.initFailed = true;
- console.error('cannot init task if jschannel is not present');
- return;
- }
-
- var previousHeights = [];
- var getHeightFiltered = function(success, error) {
- // If the new height has already been returned just before the current
- // height, we're in a loop between two heights, possibly because of a
- // scrollbar.
- // In that case we want to keep the largest of the two heights.
- if(!task.getHeight) { error('task.getHeight not defined yet'); }
- task.getHeight(function(h) {
- if((previousHeights.length == 2) &&
- (previousHeights[0] == h) &&
- (previousHeights[1] >= h)) {
- success(previousHeights[1]);
- return;
- }
- previousHeights.push(h);
- previousHeights = previousHeights.slice(-2);
- success(h);
- }, error);
- }
-
- var gradeAnswer = function(params, success, error) {
- var newSuccess = function(score, message, scoreToken) {
- success([score, message, scoreToken]);
- };
- if (typeof task.gradeAnswer === 'function') {
- task.gradeAnswer(params[0], params[1], newSuccess, error);
- } else {
- window.grader.gradeTask(params[0], params[1], newSuccess, error);
- }
- };
- var channelId = getUrlParameterByName('channelId');
- var chan = Channel.build({window: window.parent, origin: "*", scope: channelId, onReady: function() {platform.ready = true;}});
- platform.chan = chan;
- platform.task = task;
- platform.channelId = channelId;
- chan.bind('task.load', function(trans, views) {task.load(views, callAndTrigger(trans.complete, 'load', trans.error, [views]), trans.error);trans.delayReturn(true);});
- chan.bind('task.unload', function(trans) {task.unload(callAndTrigger(trans.complete, 'unload', trans.error, null), trans.error);trans.delayReturn(true);});
- chan.bind('task.getHeight', function(trans) {getHeightFiltered(trans.complete, trans.error);trans.delayReturn(true);});
- chan.bind('task.getMetaData', function(trans) {task.getMetaData(trans.complete, trans.error);trans.delayReturn(true);});
- chan.bind('task.getViews', function(trans) {task.getViews(trans.complete, trans.error);trans.delayReturn(true);});
- chan.bind('task.showViews', function(trans, views) {task.showViews(views, callAndTrigger(trans.complete, 'showViews', trans.error, [views]), trans.error);trans.delayReturn(true);});
- chan.bind('task.updateToken', function(trans, token) {task.updateToken(token, trans.complete, trans.error);trans.delayReturn(true);});
- chan.bind('task.reloadAnswer', function(trans, answer) {task.reloadAnswer(answer, callAndTrigger(trans.complete, 'reloadAnswer', trans.error, [answer]), trans.error);trans.delayReturn(true);});
- chan.bind('task.getAnswer', function(trans) {task.getAnswer(trans.complete, trans.error);trans.delayReturn(true);});
- chan.bind('task.getState', function(trans) {task.getState(trans.complete, trans.error);trans.delayReturn(true);});
- chan.bind('task.getResources', function(trans) {task.getResources(trans.complete, trans.error);trans.delayReturn(true);});
- chan.bind('task.reloadState', function(trans, state) {task.reloadState(state, callAndTrigger(trans.complete, 'reloadState', trans.error, [state]), trans.error);trans.delayReturn(true);});
- chan.bind('grader.gradeTask', function(trans, params) {gradeAnswer(params, trans.complete, trans.error);trans.delayReturn(true);});
- chan.bind('task.gradeAnswer', function(trans, params) {gradeAnswer(params, trans.complete, trans.error);trans.delayReturn(true);});
- };
-
- platform.registered_objects = [];
- platform.trigger = function(event, content) {
- for (var i = 0; i < platform.registered_objects.length; i++) {
- var object = platform.registered_objects[i];
- if (typeof object[event] !== "undefined") {
- object[event].apply(object, content);
- }
- }
- };
- platform.subscribe = function(object) {
- platform.registered_objects.push(object);
- };
- platform.unsubscribe = function(object) {
- var index = platform.registered_objects.indexOf(object);
- if (index != -1) {
- platform.registered_objects.splice(index, 1);
- }
- };
- platform.stop = function() {
- platform.chan.destroy();
- };
- platform.validate = function (sMode, success, error) {
- if (!success) success = function(){}; // not mandatory, as most code doesn't use it
- if (!error) error = function() {console.error(arguments);};
- platform.chan.call({method: "platform.validate",
- params: sMode,
- error: error,
- success: callAndTrigger(success, 'validate', error, [sMode])
- });
- };
- platform.getTaskParams = function(key, defaultValue, success, error) {
- if (!success) success = function(){};
- if (!error) error = function() {console.error(arguments);};
- platform.chan.call({method: "platform.getTaskParams",
- params: [key, defaultValue],
- error: error,
- success: success
- });
- };
- platform.showView = function(views, success, error) {
- if (!success) success = function(){};
- if (!error) error = function() {console.error(arguments);};
- platform.chan.call({method: "platform.showView",
- params: views,
- error: error,
- success: success
- });
- };
- platform.askHint = function(platformToken, success, error) {
- if (!success) success = function(){};
- if (!error) error = function() {console.error(arguments);};
- platform.chan.call({method: "platform.askHint",
- params: platformToken,
- error: error,
- success: success
- });
- };
- platform.updateHeight = function(height, success, error) {
- // Legacy
- platform.updateDisplay({height: height}, success, error);
- };
- platform.updateDisplay = function(data, success, error) {
- if (!success) success = function(){};
- if (!error) error = function() {console.error(arguments);};
- platform.chan.call({method: "platform.updateDisplay",
- params: data,
- error: error,
- success: success
- });
- };
- platform.openUrl = function(url, success, error) {
- if (!success) success = function(){};
- if (!error) error = function() {console.error(arguments);};
- platform.chan.call({method: "platform.openUrl",
- params: url,
- error: error,
- success: success
- });
- };
-}
-
-window.platform = platform;
-
-}());
-
+(function () {
+
+'use strict';
+
+function getUrlParameterByName(name) {
+ name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
+ var regex = new RegExp("[\\?&]" + name + "=([^]*)"),
+ results = regex.exec(location.href);
+ return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
+}
+
+function isCrossDomain() {
+ function isInIframe() {
+ try {
+ return window.self !== window.top;
+ } catch (e) {
+ return false;
+ }
+ }
+ function isSameDomain() {
+ var res = false;
+ function doNothing(document){}
+ try{
+ res = !! parent.document;
+ } catch(e){
+ res = false;
+ }
+ return res;
+ }
+ return isInIframe() && !isSameDomain();
+}
+
+var platform;
+
+if (!isCrossDomain()) {
+
+ /* Implementation of a platform proxy for the task iframe. This object is always
+ * available, but is effective only when setPlatform is called with a true
+ * platform object.
+ */
+
+ platform = {
+ registered_objects: [],
+ parent_platform: null,
+ initFailed: false,
+ setPlatform: function(platformArg) {
+ platform.parent_platform = platformArg;
+ },
+ trigger: function(event, content) {
+ for (var i = 0; i < platform.registered_objects.length; i++) {
+ var object = platform.registered_objects[i];
+ if (typeof (object[event]) != "undefined") {
+ object[event].apply(object, content);
+ }
+ }
+ },
+ subscribe: function(object) {
+ this.registered_objects.push(object);
+ },
+ unsubscribe: function(object) {
+ var index = this.registered_objects.indexOf(object);
+ if (index != -1) {
+ this.registered_objects.splice(index, 1);
+ }
+ },
+ validate: function(mode, success, error) {
+ // TODO: this case is a bit blur...
+ var res = platform.parent_platform.validate(mode, success, error);
+ this.trigger('validate', [mode]);
+ return res;
+ },
+ showView: function(views, success, error) {
+ return platform.parent_platform.showView(views, success, error);
+ },
+ askHint: function(platformToken, success, error) {
+ return platform.parent_platform.askHint(platformToken, success, error);
+ },
+ updateHeight: function(height, success, error) {
+ return platform.parent_platform.updateDisplay({height: height}, success, error);
+ },
+ updateDisplay: function(data, success, error) {
+ return platform.parent_platform.updateDisplay(data, success, error);
+ },
+ getTaskParams: function(key, defaultValue, success, error) {
+ return platform.parent_platform.getTaskParams(key, defaultValue, success, error);
+ },
+ openUrl: function(url, success, error) {
+ return platform.parent_platform.openUrl(url, success, error);
+ },
+ initCallback: function(callback) {
+ this.initCallbackFun = callback;
+ if (platform.initDone) {
+ callback();
+ }
+ },
+ initWithTask: function(task) {
+ platform.task = task;
+ window.task = task;
+ platform.initDone = true;
+ if (platform.initCallbackFun) {
+ platform.initCallbackFun();
+ }
+ }
+ };
+
+} else {
+
+ // cross-domain version, depends on jschannel
+ platform = {};
+ var callAndTrigger = function(fun, triggerName, error, args) {
+ return function() {
+ try {
+ platform.trigger(triggerName, args);
+ fun(arguments);
+ } catch(e) {
+ error(e.toString()+'\n'+e.stack);
+ }
+ };
+ };
+ platform.ready = false;
+ platform.initFailed = false;
+ platform.initWithTask = function(task) {
+ if (typeof Channel === 'undefined') {
+ platform.initFailed = true;
+ console.error('cannot init task if jschannel is not present');
+ return;
+ }
+
+ var previousHeights = [];
+ var getHeightFiltered = function(success, error) {
+ // If the new height has already been returned just before the current
+ // height, we're in a loop between two heights, possibly because of a
+ // scrollbar.
+ // In that case we want to keep the largest of the two heights.
+ if(!task.getHeight) { error('task.getHeight not defined yet'); }
+ task.getHeight(function(h) {
+ if((previousHeights.length == 2) &&
+ (previousHeights[0] == h) &&
+ (previousHeights[1] >= h)) {
+ success(previousHeights[1]);
+ return;
+ }
+ previousHeights.push(h);
+ previousHeights = previousHeights.slice(-2);
+ success(h);
+ }, error);
+ }
+
+ var gradeAnswer = function(params, success, error) {
+ var newSuccess = function(score, message, scoreToken) {
+ success([score, message, scoreToken]);
+ };
+ if (typeof task.gradeAnswer === 'function') {
+ task.gradeAnswer(params[0], params[1], newSuccess, error);
+ } else {
+ window.grader.gradeTask(params[0], params[1], newSuccess, error);
+ }
+ };
+ var channelId = getUrlParameterByName('channelId');
+ var chan = Channel.build({window: window.parent, origin: "*", scope: channelId, onReady: function() {platform.ready = true;}});
+ platform.chan = chan;
+ platform.task = task;
+ platform.channelId = channelId;
+ chan.bind('task.load', function(trans, views) {task.load(views, callAndTrigger(trans.complete, 'load', trans.error, [views]), trans.error);trans.delayReturn(true);});
+ chan.bind('task.unload', function(trans) {task.unload(callAndTrigger(trans.complete, 'unload', trans.error, null), trans.error);trans.delayReturn(true);});
+ chan.bind('task.getHeight', function(trans) {getHeightFiltered(trans.complete, trans.error);trans.delayReturn(true);});
+ chan.bind('task.getMetaData', function(trans) {task.getMetaData(trans.complete, trans.error);trans.delayReturn(true);});
+ chan.bind('task.getViews', function(trans) {task.getViews(trans.complete, trans.error);trans.delayReturn(true);});
+ chan.bind('task.showViews', function(trans, views) {task.showViews(views, callAndTrigger(trans.complete, 'showViews', trans.error, [views]), trans.error);trans.delayReturn(true);});
+ chan.bind('task.updateToken', function(trans, token) {task.updateToken(token, trans.complete, trans.error);trans.delayReturn(true);});
+ chan.bind('task.reloadAnswer', function(trans, answer) {task.reloadAnswer(answer, callAndTrigger(trans.complete, 'reloadAnswer', trans.error, [answer]), trans.error);trans.delayReturn(true);});
+ chan.bind('task.getAnswer', function(trans) {task.getAnswer(trans.complete, trans.error);trans.delayReturn(true);});
+ chan.bind('task.getState', function(trans) {task.getState(trans.complete, trans.error);trans.delayReturn(true);});
+ chan.bind('task.getResources', function(trans) {task.getResources(trans.complete, trans.error);trans.delayReturn(true);});
+ chan.bind('task.reloadState', function(trans, state) {task.reloadState(state, callAndTrigger(trans.complete, 'reloadState', trans.error, [state]), trans.error);trans.delayReturn(true);});
+ chan.bind('grader.gradeTask', function(trans, params) {gradeAnswer(params, trans.complete, trans.error);trans.delayReturn(true);});
+ chan.bind('task.gradeAnswer', function(trans, params) {gradeAnswer(params, trans.complete, trans.error);trans.delayReturn(true);});
+ };
+
+ platform.registered_objects = [];
+ platform.trigger = function(event, content) {
+ for (var i = 0; i < platform.registered_objects.length; i++) {
+ var object = platform.registered_objects[i];
+ if (typeof object[event] !== "undefined") {
+ object[event].apply(object, content);
+ }
+ }
+ };
+ platform.subscribe = function(object) {
+ platform.registered_objects.push(object);
+ };
+ platform.unsubscribe = function(object) {
+ var index = platform.registered_objects.indexOf(object);
+ if (index != -1) {
+ platform.registered_objects.splice(index, 1);
+ }
+ };
+ platform.stop = function() {
+ platform.chan.destroy();
+ };
+ platform.validate = function (sMode, success, error) {
+ if (!success) success = function(){}; // not mandatory, as most code doesn't use it
+ if (!error) error = function() {console.error(arguments);};
+ platform.chan.call({method: "platform.validate",
+ params: sMode,
+ error: error,
+ success: callAndTrigger(success, 'validate', error, [sMode])
+ });
+ };
+ platform.getTaskParams = function(key, defaultValue, success, error) {
+ if (!success) success = function(){};
+ if (!error) error = function() {console.error(arguments);};
+ platform.chan.call({method: "platform.getTaskParams",
+ params: [key, defaultValue],
+ error: error,
+ success: success
+ });
+ };
+ platform.showView = function(views, success, error) {
+ if (!success) success = function(){};
+ if (!error) error = function() {console.error(arguments);};
+ platform.chan.call({method: "platform.showView",
+ params: views,
+ error: error,
+ success: success
+ });
+ };
+ platform.askHint = function(platformToken, success, error) {
+ if (!success) success = function(){};
+ if (!error) error = function() {console.error(arguments);};
+ platform.chan.call({method: "platform.askHint",
+ params: platformToken,
+ error: error,
+ success: success
+ });
+ };
+ platform.updateHeight = function(height, success, error) {
+ // Legacy
+ platform.updateDisplay({height: height}, success, error);
+ };
+ platform.updateDisplay = function(data, success, error) {
+ if (!success) success = function(){};
+ if (!error) error = function() {console.error(arguments);};
+ platform.chan.call({method: "platform.updateDisplay",
+ params: data,
+ error: error,
+ success: success
+ });
+ };
+ platform.openUrl = function(url, success, error) {
+ if (!success) success = function(){};
+ if (!error) error = function() {console.error(arguments);};
+ platform.chan.call({method: "platform.openUrl",
+ params: url,
+ error: error,
+ success: success
+ });
+ };
+}
+
+window.platform = platform;
+
+}());
+
(function() {
'use strict';
@@ -390,7 +390,7 @@ window.displayHelper = {
enemyWarning: "Attention : dans ce défi, l'ordinateur vous empêchera de trouver la solution par hasard."
},
en: {
- version: "Version",
+ version: "版本",
levelVersionName_easy: "easy version",
levelVersionName_medium: "medium version",
levelVersionName_hard: "hard version",
@@ -419,21 +419,21 @@ window.displayHelper = {
tryToDoBetterOrChangeTask: "Try to do even better, or move on to another task.",
tryToDoBetterOrMoveToNextLevel: "Try to do even better, or move on to a more difficult version.",
bestPossibleScoreCongrats: "This is the best possible score on this task, congratulations!",
- forMorePointsMoveToNextLevel: "To obtain more points, move on to a harder version of this task.",
+ forMorePointsMoveToNextLevel: "要想获得更多的分数,请进入更难的版本。",
youDidBetterBefore: "You did better before.",
- scoreStays2: "Your score stays the same.",
- reloadBestAnswer: "Reload your best answer.",
- noAnswerSaved: "No answer saved so far for this version.",
+ scoreStays2: "你的得分保持不变",
+ reloadBestAnswer: "重新加载你的最佳答案。",
+ noAnswerSaved: "到目前为止,这个版本还没有答案。",
validate: "Validate",
- restart: "Restart",
+ restart: "重新开始",
harderLevelSolved: "Warning: you already solved a harder version of this task. You won't be able to obtain extra points with this version.",
showLevelAnyway: "Show it to me anyways.",
- scoreObtained: "Obtained score:",
+ scoreObtained: "得分:",
hardVersionTakesTime: "Solving a {0} can take a lot of time. Consider working on the {1} to gain points quickly.",
illKeepThatInMind: "I'll consider it.",
harderLevelAvailable: "Note that for this task, you may try to directly work on a harder version than this one.",
lockedLevel: "This version is locked. Solve the previous version to display it!",
- gradeThisAnswer: "Grade this answer",
+ gradeThisAnswer: "验证一下",
// The following messages are used for tasks with no feedback
saveAnswer: "Save this answer",
@@ -456,7 +456,7 @@ window.displayHelper = {
scoreWouldStay: "With this answer, your score would stay the same:",
answerNotSavedContestOver: "The contest being over, your answer was not saved. You may {0}.",
reloadSubmittedAnswer: "reload the validated answer",
- difficultyWarning: "Warning: solving this version takes time.
You would solve the 2 or 3 star versions of other tasks more quickly.",
+ difficultyWarning: "提醒: 解决这个版本很耗费时间。
解决2星或3星版本的任务可以更快哦。",
enemyWarning: "Warning: in this challenge, the computer will make sure you don't find the solution by chance."
},
sv: {
@@ -2120,1312 +2120,1312 @@ function drawStars(id, nbStars, starWidth, rate, mode) {
window.platform.subscribe(displayHelper);
})();
-
-var Beav = new Object();
-
-
-/**********************************************************************************/
-/* Object */
-
-Beav.Object = new Object();
-
-Beav.Object.eq = function eq(x, y) {
- // assumes arguments to be of same type
- var tx = typeof(x);
- var ty = typeof(y);
- if (tx != ty) {
- throw "Beav.Object.eq incompatible types";
- }
- if (tx == "boolean" || tx == "number" || tx == "string" || tx == "undefined") {
- return x == y;
- }
- if ($.isArray(x)) {
- if (! $.isArray(y))
- throw "Beav.Object.eq incompatible types";
- if (x.length != y.length)
- return false;
- for (var i = 0; i < x.length; i++)
- if (! eq(x[i], y[i]))
- return false;
- return true;
- }
- if (tx == "object") {
- var kx = [];
- for (var key in x) {
- kx.push(key);
- }
- var ky = [];
- for (var key in y) {
- ky.push(key);
- }
- var sort_keys = function(n1,n2) { return (n1 < n2) ? -1 : ((n1 > n2) ? 1 : 0); };
- kx.sort(sort_keys);
- ky.sort(sort_keys);
- if (kx.length != ky.length)
- return false;
- for (var i = 0; i < kx.length; i++) {
- var ex = kx[i];
- var ey = ky[i];
- if (ex != ey)
- return false;
- if (! eq(x[ex], y[ex]))
- return false;
- }
- return true;
- }
- throw "Beav.Object.eq unsupported types";
-};
-
-
-/**********************************************************************************/
-/* Array */
-
-Beav.Array = new Object();
-
-Beav.Array.make = function(nb, initValue) {
- var t = [];
- for (var i = 0; i < nb; i++)
- t[i] = initValue;
- return t;
-};
-
-Beav.Array.init = function(nb, initFct) {
- var t = [];
- for (var i = 0; i < nb; i++)
- t.push(initFct(i));
- return t;
-};
-
-Beav.Array.indexOf = function(t, v, eq) {
- if (eq === undefined)
- eq = Beav.Object.eq;
- for (var i = 0; i < t.length; i++)
- if (eq(t[i], v))
- return i;
- return -1;
-};
-
-Beav.Array.has = function(t, v, eq) {
- return Beav.Array.indexOf(t, v, eq) != -1;
-};
-
-Beav.Array.filterCount = function(t, filterFct) {
- var count = 0;
- for (var i = 0; i < t.length; i++)
- if (filterFct(t[i], i))
- count++;
- return count;
-};
-
-Beav.Array.stableSort = function(t, compFct) {
- var swap = function(a, b) {
- var v = t[a];
- t[a] = t[b];
- t[b] = v;
- };
- var insert = function (i, j, v) {
- while(i+1 < j && compFct(t[i+1], v) < 0) {
- swap(i, i+1);
- i++;
- }
- t[i] = v;
- };
- var merge = function(i, k, j) {
- for ( ; i": ">",
- '"': '"',
- "'": ''',
- "/": '/' };
- return String(stringToEncode).replace(/[&<>"'\/]/g, function (s) {
- return entityMap[s];
- });
-};
-
-
-/**********************************************************************************/
-/* Raphael */
-
-Beav.Raphael = new Object();
-
-Beav.Raphael.line = function(paper, x1, y1, x2, y2) {
- return paper.path([ "M", x1, y1, "L", x2, y2 ]);
-};
-
-Beav.Raphael.lineRelative = function(paper, x1, y1, dx, dy) {
- return Beav.Raphael.line(paper, x1, y1, x1+dx, y1+dy);
-};
-
-
-/**********************************************************************************/
-/* Random */
-
-Beav.Random = new Object();
-
-Beav.Random.bit = function(randomSeed, idBit) {
- return (randomSeed & (1 << idBit)) ? 1 : 0;
-};
-
-
-/**********************************************************************************/
-/* Task */
-
-Beav.Task = new Object();
-
-Beav.Task.scoreInterpolate = function(minScore, maxScore, minResult, maxResult, result) {
- // requires minResult <= result <= maxResult and minScore <= maxScore
- return Math.round(minScore + (maxScore - minScore) * (result - minResult) / (maxResult - minResult));
-};
-
-
-/**********************************************************************************/
-/* Geometry */
-
-Beav.Geometry = new Object();
-
-Beav.Geometry.distance = function(x1,y1,x2,y2) {
- return Math.sqrt(Math.pow(x2 - x1,2) + Math.pow(y2 - y1,2));
-};
-
-/*
- This is used to handle drag on devices that have both a touch screen and a mouse.
- Can be tested on chrome by loading a task in desktop mode, then switching to tablet mode.
- To call instead of element.drag(onMove, onStart, onEnd);
-*/
-Beav.dragWithTouch = function(element, onMove, onStart, onEnd) {
- var touchingX = 0;
- var touchingY = 0;
- var disabled = false;
-
- function onTouchStart(evt) {
- if (disabled) {
- return;
- }
- var touches = evt.changedTouches;
- touchingX = touches[0].pageX;
- touchingY = touches[0].pageY;
- onStart(touches[0].pageX, touches[0].pageY, evt);
- }
-
- function onTouchEnd(evt) {
- if (disabled) {
- return;
- }
- onEnd(null);
- }
-
- function onTouchMove(evt) {
- if (disabled) {
- return;
- }
- var touches = evt.changedTouches;
- var dx = touches[0].pageX - touchingX;
- var dy = touches[0].pageY - touchingY;
- onMove(dx, dy, touches[0].pageX, touches[0].pageY, evt);
- }
-
- function callOnStart(x,y,event) {
- disabled = true;
- onStart(x,y,event);
- }
-
- function callOnMove(dx,dy,x,y,event) {
- disabled = true;
- onMove(dx,dy,x,y,event);
- }
-
- function callOnEnd(event) {
- disabled = false;
- onEnd(event);
- }
-
- // element.undrag();
- element.drag(callOnMove,callOnStart,callOnEnd);
- if (element.touchstart) {
- element.touchstart(onTouchStart);
- element.touchend(onTouchEnd);
- element.touchcancel(onTouchEnd);
- element.touchmove(onTouchMove);
- }
-}
-(function() {
-
-'use strict';
-
-// requires jQuery, and a task object in the global scope.
-
-// this should be called before the task loads, because the task can modify
-// its html at load, and we want to return unmodified html in getTaskResources.
-var res = {};
-
-var taskResourcesLoaded = false;
-
-window.implementGetResources = function(task) {
- task.getResources = function(callback)
- {
- if (taskResourcesLoaded) {
- callback(res);
- return;
- }
- res.task = ('task' in res) ? res.task : [{ type: 'html', content: $('#task').html() }];
- res.solution = ('solution' in res) ? res.solution : [{ type: 'html', content: $('#solution').html() }];
- res.grader = [];
- res.task_modules = [];
- res.solution_modules = [];
- res.grader_modules = [];
- if (!res.hints) {
- res.hints = [];
- $('.hint').each(function(index) {
- res.hints[res.hints.length] = [{type: 'html', content: $(this).html() }];
- $(this).attr('hint-Num', res.hints.length-1);
- });
- }
- res.proxy = [];
- res.proxy_modules = [];
- res.display = [];
- res.display_modules = [];
- res.sat = [];
- res.sat_modules = [];
- res.files = [];
- if (!res.title) {
- res.title = $('title').text();
- }
-
- // Resources
- var curDest = 'task';
- var curType = 'javascript';
- $('script, style, link').each(function() {
- if ($(this).hasClass('remove')) {
- return;
- }
- if ($(this).hasClass('solution') && $(this).hasClass('module')) {
- curDest = res.solution_modules;
- }
- else if ($(this).hasClass('solution')) {
- curDest = res.solution;
- }
- else if ($(this).hasClass('grader') && $(this).hasClass('module')) {
- curDest = res.grader_modules;
- }
- else if ($(this).hasClass('grader')) {
- curDest = res.grader;
- }
- else if ($(this).hasClass('hint')) {
- res.hints.push([{ type: 'html', content: $(this).html() }]);
- return;
- }
- else if ($(this).hasClass('proxy') && $(this).hasClass('module')) {
- curDest = res.proxy_modules;
- }
- else if ($(this).hasClass('proxy')) {
- curDest = res.proxy;
- }
- else if ($(this).hasClass('stdButtonsAndMessages') && $(this).hasClass('module')) {
- curDest = res.display_modules;
- }
- else if ($(this).hasClass('stdButtonsAndMessages')) {
- curDest = res.display;
- }
- else if ($(this).hasClass('stdAnswerTypes') && $(this).hasClass('module')) {
- curDest = res.sat_modules;
- }
- else if ($(this).hasClass('stdAnswerTypes')) {
- curDest = res.sat;
- }
- else if ($(this).hasClass('module')) {
- curDest = res.task_modules;
- }
- else {
- curDest = res.task;
- }
-
- if ($(this).is('script')) {
- curType = 'javascript';
- }
- else if ($(this).is('style') || $(this).is('link')) {
- curType = 'css';
- }
-
- if ($(this).attr('src')) {
- curDest.push({ type: curType, url: $(this).attr('src'), id: $(this).attr('id') });
- }
- else if ($(this).attr('href')) {
- curDest.push({ type: curType, url: $(this).attr('href'), id: $(this).attr('id') });
- }
- else {
- curDest.push({ type: curType, id: $(this).attr('id'), content: $(this).html() });
- }
- });
-
- // Images
- var images = [];
- var image = '';
- $('#task img').each(function() {
- var src = $(this).attr('src');
- if (src) {
- image = src.toString();
- if ($.inArray(image, images) === -1) {
- res.task.push({ type: 'image', url: image });
- images.push(image);
- }
- }
- });
- fillImages($('#task').html(), images, res.task);
- $('script').each(function() {
- if ($(this).hasClass('remove') || $(this).attr('src') || $(this).attr('href')) {
- return;
- }
- fillImages($(this).html(), images, res.task);
- });
- $('#solution img').each(function() {
- image = $(this).attr('src').toString();
- if ($.inArray(image, images) === -1) {
- res.solution.push({ type: 'image', url: image });
- images.push(image);
- }
- });
- fillImages($('#solution').html(), images, res.solution);
- $('.hint').each(function() {
- var hintnum = $(this).attr('hint-num');
- $('[hint-num='+hintnum+'] img').each(function() {
- image = $(this).attr('src').toString();
- if ($.inArray(image, images) === -1) {
- res.hints[hintnum].push({ type: 'image', url: image });
- images.push(image);
- }
- });
- fillImages($(this).html(), images, res.hints[hintnum]);
- });
-
- // Links
- $('iframe').each(function () {
- var curUrl = $(this).attr('src');
- if(curUrl.indexOf('://') == -1 && curUrl.charAt(0) != '/') {
- res.files.push({ type: this.tagName, url: $(this).attr('src') });
- }
- });
-
- // Other resources
- $('source, track').each(function() {
- res.files.push({ type: this.tagName, url: $(this).attr('src') });
- });
- $('fioi-video-player').each(function() {
- var fileAttributes = ["data-source", "data-image", "data-subtitles"];
- for(var i=0; i