{"version":3,"sources":["../../loader/bootstrap.js","../tools/fixedDecimals.js","../tools/stats.js","../tools/getConfig.js","../tools/getLabels.js","../tools/getStatus.js","../tools/performances/tester.js","../tools/bandwidth/tester.js","../tools/upload/tester.js","../tools/getPlatformInfo.js","../tools/browser/tester.js","../tools/diagnostic/tpl/main!tpl","../tools/diagnostic/tpl/result!tpl","../tools/diagnostic/tpl/details!tpl","../tools/diagnostic/tpl/feedback!tpl","tpl!taoClientDiagnostic/tools/diagnostic/tpl/quality-bar","../../taoClientDiagnosticCss/diagnostics!css","../tools/diagnostic/diagnostic.js","onLayerEnd0.js","module-create.js","/github/workspace/tao/views/build/config-wrap-end-default.js"],"names":[],"mappings":"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","sourcesContent":["/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2016-2018 (original work) Open Assessment Technologies SA ;\n */\n\n/**\n * Bootstrap the app, start the entry controller\n * @author Bertrand Chevrier \n */\n(function(){\n 'use strict';\n\n\n\n var loaderScript = document.getElementById('amd-loader');\n var configUrl = loaderScript.getAttribute('data-config');\n var bundle = loaderScript.getAttribute('data-bundle');\n\n var loadController = function loadController(){\n var controllerOptions = {};\n var controllerPath = loaderScript.getAttribute('data-controller');\n var params = loaderScript.getAttribute('data-params');\n try{\n controllerOptions = JSON.parse(params);\n } catch(err){\n controllerOptions = {};\n }\n window.require([controllerPath], function(controller) {\n var startController = function startController(){\n if(!window.started){\n window.started = true;\n controller.start(controllerOptions);\n }\n };\n document.addEventListener('readystatechange', startController, false);\n if (document.readyState === 'complete') {\n startController();\n }\n });\n };\n\n //always start to load the config\n window.require([configUrl], function() {\n\n //define the global loading mechanism\n if(!window.loadBundles){\n //keep tracl of loaded bundles, even if require does it,\n //this prevent some unecessary cycles\n window.loaded = {};\n\n /**\n * Loading entry point for inter bundle dependency,\n * always take the bundles from the params and window.bundles\n * @param {String[]} [bundles] - an optional list of bundle to load\n */\n window.loadBundles = function loadBundles(bundles){\n bundles = bundles || [];\n bundles = bundles.concat(window.bundles)\n bundles = bundles.filter( function(item, index){\n return item && bundles.indexOf(item) === index && window.loaded[item] !== true;\n });\n require(bundles, function(){\n bundles.forEach( function( item ) {\n window.loaded[item] = true;\n });\n loadController();\n });\n }\n }\n\n if(bundle || (window.bundles && window.bundles.length)) {\n window.loadBundles([bundle]);\n } else {\n loadController();\n }\n });\n})();\n\ndefine(\"loader/bootstrap\", function(){});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2015-2021 (original work) Open Assessment Technologies SA ;\n */\ndefine('taoClientDiagnostic/tools/fixedDecimals',[],function() {\n 'use strict';\n\n /**\n * Rounds a value to a fixed number of decimals\n * @param {number} value - The value to round\n * @param {number} decimals - The number of decimal\n * @returns {number}\n */\n return function fixedDecimals(value, decimals) {\n const shift = Math.pow(10, Math.abs(decimals || 1));\n return Math.round(Number(value) * shift) / shift || 0;\n };\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2015-2021 (original work) Open Assessment Technologies SA ;\n */\ndefine('taoClientDiagnostic/tools/stats',['lodash', 'taoClientDiagnostic/tools/fixedDecimals'], function(_, fixedDecimals) {\n 'use strict';\n\n /**\n * Gets a getter function that extracts a value from a record.\n * @param {string|Function} name - the name to extract from the record, or a getter function\n * @returns {Function}\n * @private\n */\n function valueGetter(name) {\n if ('function' === typeof name) {\n return name;\n }\n\n return item => (item && item[name]) || 0;\n }\n\n /**\n * Computes some stats on a list from a particular field\n * @param {Array|object} list - The list to compute stats on\n * @param {string|Function} fieldName - The name of the field to process, or a callback method returning the value\n * @param {number} [decimals] - Optional number of fixed decimals for values\n * @returns {object}\n */\n return function stats(list, fieldName, decimals) {\n const getValue = valueGetter(fieldName);\n const values = [];\n let min = Number.MAX_VALUE;\n let max = 0;\n let count = 0;\n\n // process first pass stats: compute sum, min and max values\n const sum = _.reduce(\n list,\n (sum, item) => {\n if ('undefined' !== typeof item) {\n const value = getValue(item);\n values.push(value);\n min = Math.min(min, value);\n max = Math.max(max, value);\n sum += value;\n count++;\n return sum;\n }\n },\n 0\n );\n\n // compute the average value\n const average = sum / (count || 1);\n\n // process second pass stats: compute variance\n const sum2 = values.reduce((sum, value) => {\n const diff = value - average;\n sum += diff * diff;\n return sum;\n }, 0);\n\n // compute standard variance\n const variance = count > 1 ? Math.sqrt(sum2 / (count - 1)) : 0;\n\n // compute the median value\n values.sort();\n const middle = count / 2;\n const median = (values[Math.floor(middle)] + values[Math.ceil(middle)]) / 2;\n\n const results = {\n min,\n max,\n sum,\n count,\n average,\n median,\n variance\n };\n\n if (decimals) {\n _.forEach(results, (value, key) => {\n results[key] = fixedDecimals(value, decimals);\n });\n }\n\n results.values = list;\n return results;\n };\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2016-2021 (original work) Open Assessment Technologies SA ;\n */\ndefine('taoClientDiagnostic/tools/getConfig',['lodash'], function(_) {\n 'use strict';\n\n /**\n * Gets a config set\n * @param {object} [config]\n * @param {object} [defaults]\n * @returns {object}\n */\n return function getConfig(config, defaults) {\n return _(config || {})\n .omit(value => value === null || typeof value === 'undefined')\n .defaults(defaults || {})\n .value();\n };\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2017-2021 (original work) Open Assessment Technologies SA ;\n */\ndefine('taoClientDiagnostic/tools/getLabels',[],function() {\n 'use strict';\n\n /**\n * Gets the list of messages related to a particular level.\n * The level is provided as a numeric value, starting from 1.\n * @param {Array|object} messages - The list of messages for all levels.\n * If only one object is provided is will be wrapped into an array\n * @param {number|string} level - The level for which filter the messages.\n * It should be comprised within the available indexes.\n * Higher levels will be reduced to the higher available,\n * lower levels will be increased to the lowest.\n * @returns {object}\n */\n return function getLabels(messages, level) {\n messages = messages || {};\n\n if (!Array.isArray(messages)) {\n messages = [messages];\n }\n\n // Compute the level value that targets which list of labels to use.\n // It should be comprised within the available indexes.\n // Higher levels will be reduced to the higher available, lower levels will be increased to the lowest.\n level = Math.min(Math.max(parseInt(level, 10) || 0, 1), messages.length || 1) - 1;\n\n return messages[level] || {};\n };\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2016-2021 (original work) Open Assessment Technologies SA ;\n */\ndefine('taoClientDiagnostic/tools/getStatus',['lodash'], function(_) {\n 'use strict';\n\n /**\n * Gets the correct status message for a given percentage from a list of thresholds.\n * @param {number|string} percentage - The actual percentage. Must be comprised between 0 and 100.\n * Other values will be adjusted to fit the interval.\n * @param {Array|object} [thresholds] - A list of descriptors for each thresholds.\n * A threshold field must be provided for each.\n * @param {object} [opts]\n * @param {object} [minimumGlobalPercentage] - lowest value that will be used in the global score computation\n * @returns {object} Returns the corresponding threshold, or an empty object if none match.\n */\n return function getStatus(percentage, thresholds, opts) {\n const options = opts || {};\n const testPercentage = Math.max(0, Math.min(100, Math.round(parseInt(percentage, 10) || 0)));\n const globalPercentage = options.minimumGlobalPercentage\n ? Math.max(testPercentage, options.minimumGlobalPercentage)\n : testPercentage;\n\n // need a structure compatible with the handlebars template\n const status = {\n // the percentage is between 0 and 100 and obviously must be a number\n percentage: testPercentage,\n globalPercentage: globalPercentage,\n quality: {}\n };\n\n // grab a feedback related to the percentage in the thresholds list\n if (thresholds) {\n if (!Array.isArray(thresholds)) {\n thresholds = [thresholds];\n }\n\n let feedback;\n const len = thresholds.length;\n for (let i = 0; i < len; i++) {\n const step = thresholds[i];\n if (step && (!step.threshold || status.percentage >= step.threshold)) {\n feedback = step;\n } else {\n break;\n }\n }\n\n if (feedback) {\n status.feedback = _.clone(feedback);\n }\n }\n\n return status;\n };\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2015-2021 (original work) Open Assessment Technologies SA ;\n */\ndefine('taoClientDiagnostic/tools/performances/tester',[\n 'jquery',\n 'lodash',\n 'i18n',\n 'async',\n 'context',\n 'helpers',\n 'taoClientDiagnostic/tools/stats',\n 'taoQtiItem/qtiItem/core/Loader',\n 'taoQtiItem/qtiCommonRenderer/renderers/Renderer',\n 'taoClientDiagnostic/tools/getConfig',\n 'taoClientDiagnostic/tools/getLabels',\n 'taoClientDiagnostic/tools/getStatus'\n], function($, _, __, async, context, helpers, stats, Loader, Renderer, getConfig, getLabels, getStatus) {\n 'use strict';\n\n /**\n * Duration of one second (in milliseconds)\n * @type {number}\n * @private\n */\n const _second = 1000;\n\n /**\n * Default timeout duration\n * @type {number}\n * @private\n */\n const _defaultTimeout = 30 * _second;\n\n /**\n * Default number of renderings by samples\n * @type {number}\n * @private\n */\n const _defaultOccurrencesCount = 10;\n\n /**\n * List of default samples\n * @type {Array}\n * @private\n */\n const _defaultSamples = [\n 'taoClientDiagnostic/tools/performances/data/sample1/',\n 'taoClientDiagnostic/tools/performances/data/sample2/',\n 'taoClientDiagnostic/tools/performances/data/sample3/'\n ];\n\n /**\n * Default values for the performances tester\n * @type {object}\n * @private\n */\n const _defaults = {\n id: 'performances',\n\n // The threshold for optimal performances\n optimal: 0.025,\n\n // The threshold for minimal performances\n threshold: 0.25\n };\n\n /**\n * A list of thresholds for performances check\n * @type {Array}\n * @private\n */\n const _thresholds = [\n {\n threshold: 0,\n message: __('Very slow performances'),\n type: 'error'\n },\n {\n threshold: 33,\n message: __('Average performances'),\n type: 'warning'\n },\n {\n threshold: 66,\n message: __('Good performances'),\n type: 'success'\n }\n ];\n\n /**\n * List of translated texts per level.\n * The level is provided through the config as a numeric value, starting from 1.\n * @type {object}\n * @private\n */\n const _messages = [\n // level 1\n {\n title: __('Workstation performances'),\n status: __('Checking the performances...'),\n performancesMin: __('Minimum rendering time'),\n performancesMax: __('Maximum rendering time'),\n performancesAverage: __('Average rendering time')\n }\n ];\n\n /**\n * Base text used to build sample identifiers\n * @type {string}\n * @private\n */\n const _sampleBaseId = 'sample';\n\n /**\n * Loads a page inside a div and compute the time to load\n * @param {object} data The descriptor of the page to load\n * @param {Function} done A callback function called to provide the result\n * @private\n */\n function loadItem(data, done) {\n //item location config\n const qtiJsonFile = `${data.url}qti.json`;\n const urlTokens = data.url.split('/');\n const extension = urlTokens[0];\n const fullpath = require.s.contexts._.config.paths[extension];\n const baseUrl = data.url.replace(extension, fullpath);\n const loader = new Loader();\n const renderer = new Renderer({\n baseUrl: baseUrl // compatibility mode for legacy installations\n });\n\n // check needed by compatibility mode for legacy installations\n if (renderer.getAssetManager) {\n renderer.getAssetManager().setData('baseUrl', baseUrl);\n }\n\n require([`json!${qtiJsonFile}`], function(itemData) {\n loader.loadItemData(itemData, function(item) {\n renderer.load(function() {\n //start right before rendering\n const start = window.performance.now();\n\n //set renderer\n item.setRenderer(this);\n\n //render markup\n const $container = $('
').appendTo('body');\n $container.append(item.render());\n\n //execute javascript\n item.postRender();\n\n //remove item\n $container.remove();\n\n //done\n const end = window.performance.now();\n\n const duration = (end - start) / _second;\n\n const result = {\n id: data.id,\n url: data.url,\n duration: duration\n };\n\n done(null, result);\n }, this.getLoadedClasses());\n });\n });\n }\n\n /**\n * Performs a browser performances test by running a heavy page\n *\n * @param {object} config - Some optional configs\n * @param {string} [config.id] - The identifier of the test\n * @param {number} [config.optimal] - The threshold for optimal performances\n * @param {number} [config.threshold] - The threshold for minimal performances\n * @param {string} [config.level] - The intensity level of the test. It will aim which messages list to use.\n * @returns {object}\n */\n return function performancesTester(config) {\n const initConfig = getConfig(config, _defaults);\n const labels = getLabels(_messages, initConfig.level);\n let idx = 0;\n const _samples = _.map((!_.isEmpty(initConfig.samples) && initConfig.samples) || _defaultSamples, sample => {\n idx++;\n return {\n id: _sampleBaseId + idx,\n url: sample,\n timeout: initConfig.timeout * 1000 || _defaultTimeout,\n nb: initConfig.occurrences || _defaultOccurrencesCount\n };\n });\n\n // add one occurrence on the first sample to obfuscate the time needed to load the runner\n _samples[0].nb++;\n\n return {\n /**\n * Performs a performances test, then call a function to provide the result\n * @param {Function} done\n */\n start(done) {\n const tests = [];\n\n _.forEach(_samples, data => {\n const cb = _.partial(loadItem, data);\n let iterations = data.nb || 1;\n while (iterations--) {\n tests.push(cb);\n }\n });\n\n async.series(tests, (err, measures) => {\n const decimals = 2;\n\n if (err && !measures.length) {\n //something went wrong\n throw err;\n }\n\n // remove the first result to obfuscate the time needed to load the runner\n measures.shift();\n\n const results = stats(measures, 'duration', decimals);\n const status = this.getFeedback(results.average);\n const summary = this.getSummary(results);\n\n done(status, summary, results);\n });\n },\n\n /**\n * Gets the labels loaded for the tester\n * @returns {object}\n */\n get labels() {\n return labels;\n },\n\n /**\n * Builds the results summary\n * @param {object} results\n * @returns {object}\n */\n getSummary(results) {\n return {\n performancesMin: { message: labels.performancesMin, value: `${results.min} s` },\n performancesMax: { message: labels.performancesMax, value: `${results.max} s` },\n performancesAverage: { message: labels.performancesAverage, value: `${results.average} s` }\n };\n },\n\n /**\n * Gets the feedback status for the provided result value\n * @param {Number} result\n * @returns {object}\n */\n getFeedback(result) {\n const optimal = initConfig.optimal;\n const range = Math.abs(optimal - initConfig.threshold);\n const status = getStatus(((range + optimal - result) / range) * 100, _thresholds);\n\n status.title = labels.title;\n status.id = initConfig.id;\n return status;\n }\n };\n };\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2015-2021 (original work) Open Assessment Technologies SA ;\n */\ndefine('taoClientDiagnostic/tools/bandwidth/tester',[\n 'lodash',\n 'i18n',\n 'async',\n 'context',\n 'taoClientDiagnostic/tools/getConfig',\n 'taoClientDiagnostic/tools/getLabels',\n 'taoClientDiagnostic/tools/stats',\n 'taoClientDiagnostic/tools/fixedDecimals',\n 'taoClientDiagnostic/tools/getStatus'\n], function(_, __, async, context, getConfig, getLabels, stats, fixedDecimals, getStatus) {\n 'use strict';\n\n /**\n * A binary kilo bytes (KiB)\n * @type {number}\n * @private\n */\n const _kilo = 1024;\n\n /**\n * A binary mega bytes (MiB)\n * @type {number}\n * @private\n */\n const _mega = _kilo * _kilo;\n\n /**\n * Duration of one second (in milliseconds)\n * @type {number}\n * @private\n */\n const _second = 1000;\n\n /**\n * A list of thresholds for bandwidth check\n * @type {Array}\n * @private\n */\n const _thresholds = [\n {\n threshold: 0,\n message: __('Low bandwidth'),\n type: 'error'\n },\n {\n threshold: 33,\n message: __('Average bandwidth'),\n type: 'warning'\n },\n {\n threshold: 66,\n message: __('Good bandwidth'),\n type: 'success'\n }\n ];\n\n /**\n * Default values for the bandwidth tester\n * @type {object}\n * @private\n */\n const _defaults = {\n id: 'bandwidth',\n\n // The typical bandwidth needed for a test taker (Mbps)\n unit: 0.16,\n\n // The thresholds for optimal bandwidth\n ideal: 45,\n\n // Maximum number of test takers to display\n max: 100,\n\n // Lowest value that will be used in the global score computation\n minimumGlobalPercentage: false,\n\n // A list of thresholds for bandwidth check\n feedbackThresholds: _thresholds,\n\n fallbackThreshold: 0.2\n };\n\n /**\n * List of descriptors defining the data sets to download.\n * - file : path of the file containing the test data\n * - size : the given size of the file\n * - timeout : the timeout for the download\n * - threshold : a bandwidth threshold above which the data set can be downloaded to evaluate a more accurate value\n * - nb : number of download iterations\n * @type {object}\n * @private\n */\n const _downloadData = {\n '10KB': {\n id: '10KB',\n file: 'data/bin10KB.data',\n size: 10 * _kilo,\n timeout: _second,\n threshold: 0,\n nb: 10\n },\n '100KB': {\n id: '100KB',\n file: 'data/bin100KB.data',\n size: 100 * _kilo,\n timeout: 2 * _second,\n threshold: 0,\n nb: 5\n },\n '1MB': {\n id: '1MB',\n file: 'data/bin1MB.data',\n size: _mega,\n timeout: 20 * _second,\n threshold: 0,\n nb: 3\n }\n };\n\n /**\n * List of translated texts per level.\n * The level is provided through the config as a numeric value, starting from 1.\n * @type {object[]}\n * @private\n */\n const _messages = [\n // level 1\n {\n title: __('Bandwidth'),\n status: __('Checking the bandwidth...'),\n legend: __('Number of simultaneous test takers the connection can handle'),\n bandwidthMin: __('Minimum bandwidth'),\n bandwidthMax: __('Maximum bandwidth'),\n bandwidthAverage: __('Average bandwidth')\n },\n // level 2\n {\n title: __('Media intensive bandwidth'),\n status: __('Checking the media intensive bandwidth...'),\n legend: __('Number of simultaneous test takers the connection can handle with media intensive'),\n bandwidthMin: __('Minimum intensive bandwidth'),\n bandwidthMax: __('Maximum intensive bandwidth'),\n bandwidthAverage: __('Average intensive bandwidth')\n }\n ];\n\n /**\n * Download a data set as described by the provided descriptor and compute the duration.\n * @param {object} data The data set descriptor to use for download\n * @param {Function} cb A callback function called at the end of the download.\n * This callback is also called if a timeout breaks the download;\n * @private\n */\n function download(data, cb) {\n if (data.threshold && this.bandwidth < data.threshold) {\n return cb('threshold');\n }\n\n const start = window.performance.now();\n const url = `${context['root_url']}taoClientDiagnostic/views/js/tools/bandwidth/${data.file}?${Date.now()}`;\n const timeoutId = window.setTimeout(cb, data.timeout, 'timeout');\n const request = new XMLHttpRequest();\n request.open('GET', url, true);\n request.setRequestHeader('Accept', 'application/octet-stream');\n\n request.onload = () => {\n const end = window.performance.now();\n clearTimeout(timeoutId);\n\n const duration = end - start;\n const bytes = data.size;\n const seconds = duration / _second;\n\n // speed in Mbps\n const speed = (bytes * 8) / seconds / _mega;\n\n this.bandwidth = Math.max(this.bandwidth, speed);\n\n return cb(null, {\n id: data.id,\n file: data.file,\n size: data.size,\n duration,\n speed\n });\n };\n request.onerror = err => {\n clearTimeout(timeoutId);\n cb(err);\n };\n\n request.onreadystatechange = () => {\n if (request.readyState === 4 && request.status !== 200) {\n clearTimeout(timeoutId);\n cb(request.status);\n }\n };\n\n request.send();\n }\n\n /**\n * Performs a bandwidth test by downloading a bunch of data sets with different sizes\n *\n * @param {object} config - Some optional configs\n * @param {string} [config.id] - The identifier of the test\n * @param {number} [config.unit] - The typical bandwidth needed for a test taker (Mbps)\n * @param {number} [config.ideal] - The thresholds for optimal bandwidth\n * @param {number} [config.max] - Maximum number of test takers to display\n * @param {string} [config.level] - The intensity level of the test. It will aim which messages list to use.\n * @returns {object}\n */\n return function bandwidthTester(config) {\n const initConfig = getConfig(config, _defaults);\n const labels = getLabels(_messages, initConfig.level);\n\n // override the feedback thresholds given by the config in case it is an empty array\n if (_.isArray(initConfig.feedbackThresholds) && !initConfig.feedbackThresholds.length) {\n initConfig.feedbackThresholds = _thresholds;\n }\n\n return {\n /**\n * Performs a bandwidth test, then call a function to provide the result\n * @param {Function} done\n */\n start(done) {\n const tests = [];\n\n _.forEach(_downloadData, data => {\n const cb = download.bind(this, data);\n let iterations = data.nb || 1;\n while (iterations--) {\n tests.push(cb);\n }\n });\n\n this.bandwidth = 0;\n\n async.series(tests, (err, measures) => {\n let duration = 0;\n let size = 0;\n const decimals = 2;\n const resultsBySize = {};\n\n function getValue(value) {\n let speed = 0;\n\n if (value) {\n duration += value.duration;\n size += value.size;\n\n speed = value.speed;\n value.speed = fixedDecimals(speed, decimals);\n }\n\n return speed;\n }\n\n if (err && !measures.length) {\n //something went wrong\n throw err;\n }\n const results = stats(measures, getValue, decimals);\n\n _.forEach(_downloadData, (data, key) => {\n resultsBySize[key] = stats(\n _.filter(measures, o => o.id === key),\n getValue,\n decimals\n );\n });\n\n results.duration = fixedDecimals(duration / _second, decimals);\n results.size = size;\n\n const summary = this.getSummary(results);\n const status = this.getFeedback(results, resultsBySize);\n\n done(status, summary, results);\n });\n },\n\n /**\n * Gets the labels loaded for the tester\n * @returns {object}\n */\n get labels() {\n return labels;\n },\n\n /**\n * Builds the results summary\n * @param {object} results\n * @returns {object}\n */\n getSummary(results) {\n return {\n bandwidthMin: { message: labels.bandwidthMin, value: results.min + ' Mbps' },\n bandwidthMax: { message: labels.bandwidthMax, value: results.max + ' Mbps' },\n bandwidthAverage: { message: labels.bandwidthAverage, value: results.average + ' Mbps' }\n };\n },\n\n /**\n * Gets the feedback status for the provided result value\n * @param {object} result\n * @param {number} result.max\n * @param {number} result.min\n * @param {number} result.average\n * @param {object} resultsBySize - result statistics grouped by size\n * @returns {object}\n */\n getFeedback(result, resultsBySize) {\n const avgResult = result.average;\n const bandwidthUnit = initConfig.unit;\n const threshold = initConfig.ideal;\n const maxTestTakers = initConfig.max;\n const max = threshold * bandwidthUnit;\n const getStatusOptions = initConfig.minimumGlobalPercentage\n ? { minimumGlobalPercentage: initConfig.minimumGlobalPercentage }\n : {};\n const baseBandwidth = avgResult;\n let stable = true;\n\n _.forEach(resultsBySize, resultBySize => {\n if (resultBySize.min / resultBySize.average < initConfig.fallbackThreshold) {\n stable = false;\n }\n });\n\n const status = getStatus((baseBandwidth / max) * 100, initConfig.feedbackThresholds, getStatusOptions);\n\n let nb = Math.floor(baseBandwidth / bandwidthUnit);\n\n if (nb > maxTestTakers) {\n nb = '>' + maxTestTakers;\n }\n\n status.id = initConfig.id;\n status.title = labels.title;\n status.feedback.legend = labels.legend;\n status.quality.label = nb;\n\n if (!stable) {\n status.feedback.type = 'warning';\n status.feedback.message = __(\n 'Unstable bandwidth, temporary fluctuations in connection speed may affect test taker experience.'\n );\n status.feedback.legend = __('Simultaneous test takers under normal connection conditions.');\n }\n\n if (nb.toString().length > 2) {\n status.quality.wide = true;\n }\n\n return status;\n }\n };\n };\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2016-2021 (original work) Open Assessment Technologies SA ;\n */\ndefine('taoClientDiagnostic/tools/upload/tester',[\n 'jquery',\n 'lodash',\n 'i18n',\n 'async',\n 'util/url',\n 'taoClientDiagnostic/tools/getConfig',\n 'taoClientDiagnostic/tools/getLabels',\n 'taoClientDiagnostic/tools/getStatus'\n], function($, _, __, async, urlHelper, getConfig, getLabels, getStatus) {\n 'use strict';\n\n /**\n * A binary kilo bytes (KiB)\n * @type {number}\n * @private\n */\n const _kilo = 1024;\n\n /**\n * A binary mega bytes (MiB)\n * @type {number}\n * @private\n */\n const _mega = _kilo * _kilo;\n\n /**\n * Result of diagnostic\n * @type {Array}\n * @private\n */\n let data = [];\n\n /**\n * Default values for the upload speed tester\n * @type {object}\n * @private\n */\n const _defaults = {\n id: 'upload',\n\n // Size of data to sent to server during speed test in bytes\n size: _mega,\n\n // Optimal speed in bytes per second\n optimal: _mega\n };\n\n /**\n * A list of thresholds for bandwidth check\n * @type {Array}\n * @private\n */\n const _thresholds = [\n {\n threshold: 0,\n message: __('Low upload speed'),\n type: 'error'\n },\n {\n threshold: 33,\n message: __('Average upload speed'),\n type: 'warning'\n },\n {\n threshold: 66,\n message: __('Good upload speed'),\n type: 'success'\n }\n ];\n\n /**\n * List of translated texts per level.\n * The level is provided through the config as a numeric value, starting from 1.\n * @type {object}\n * @private\n */\n const _messages = [\n // level 1\n {\n title: __('Upload speed'),\n status: __('Checking upload speed...'),\n uploadAvg: __('Average upload speed'),\n uploadMax: __('Max upload speed')\n }\n ];\n\n /**\n * Generate random string of given length\n * @param {number} length\n */\n function generateStr(length) {\n let text = '';\n const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n\n for (let i = 0; i < length; i++) {\n text += possible.charAt(Math.floor(Math.random() * possible.length));\n }\n\n return text;\n }\n\n /**\n * Upload generated string to check upload speed.\n * @param {number} size of string to upload in bytes\n * @return {object} jqXHR\n */\n function upload(size) {\n const url = urlHelper.route('upload', 'CompatibilityChecker', 'taoClientDiagnostic', { cache: Date.now() });\n const str = generateStr(size);\n data = [];\n\n return $.ajax({\n url: url,\n type: 'POST',\n data: {\n upload: str\n },\n xhr: () => {\n const xhr = new window.XMLHttpRequest();\n const startTime = Date.now();\n // Upload progress\n xhr.upload.addEventListener(\n 'progress',\n evt => {\n if (evt.lengthComputable) {\n const passedTime = Date.now() - startTime;\n data.push({\n time: passedTime,\n loaded: evt.loaded,\n speed: (evt.loaded * 8) / _mega / (passedTime / 1000)\n });\n }\n },\n false\n );\n\n return xhr;\n }\n });\n }\n\n /**\n * Performs a upload speed test\n * @param {object} config - Some optional configs\n * @param {string} [config.id] - The identifier of the test\n * @param {number} [config.size] - Size of data to sent to server during speed test in bytes\n * @param {number} [config.optimal] - Optimal speed in bytes per second\n * @param {string} [config.level] - The intensity level of the test. It will aim which messages list to use.\n * @returns {object}\n */\n return function uploadTester(config) {\n const initConfig = getConfig(config, _defaults);\n const labels = getLabels(_messages, initConfig.level);\n\n return {\n /**\n * Performs upload speed test, then call a function to provide the result\n * @param {Function} done\n */\n start(done) {\n upload(parseInt(initConfig.size, 10)).then(() => {\n let totalSpeed = 0;\n let maxSpeed = 0;\n\n _.forEach(data, val => {\n totalSpeed += val.speed;\n if (maxSpeed < val.speed) {\n maxSpeed = Math.round(val.speed * 100) / 100;\n }\n });\n const avgSpeed = Math.round((totalSpeed / data.length) * 100) / 100;\n const results = {\n max: maxSpeed,\n avg: avgSpeed,\n type: 'upload'\n };\n\n const status = this.getFeedback(avgSpeed);\n const summary = this.getSummary(results);\n\n done(status, summary, results);\n });\n },\n\n /**\n * Gets the labels loaded for the tester\n * @returns {object}\n */\n get labels() {\n return labels;\n },\n\n /**\n * Builds the results summary\n * @param {object} results\n * @returns {object}\n */\n getSummary(results) {\n return {\n uploadAvg: { message: labels.uploadAvg, value: `${results.avg} Mbps` },\n uploadMax: { message: labels.uploadMax, value: `${results.max} Mbps` }\n };\n },\n\n /**\n * Gets the feedback status for the provided result value\n * @param {number} result\n * @returns {object}\n */\n getFeedback(result) {\n const optimal = initConfig.optimal / _mega;\n const status = getStatus((100 / optimal) * result, _thresholds);\n\n status.id = initConfig.id;\n status.title = labels.title;\n\n return status;\n }\n };\n };\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2016-2021 (original work) Open Assessment Technologies SA ;\n */\ndefine('taoClientDiagnostic/tools/getPlatformInfo',['core/request', 'util/url', 'taoClientDiagnostic/tools/getConfig'], function(request, urlHelper, getConfig) {\n 'use strict';\n\n /**\n * Some default values\n * @type {object}\n * @private\n */\n const defaultConfig = {\n browserVersionAction: 'whichBrowser',\n browserVersionController: 'CompatibilityChecker',\n browserVersionExtension: 'taoClientDiagnostic'\n };\n\n /**\n * Gets the URL of the platform tester\n * @param {Window} win\n * @param {string} action\n * @param {string} controller\n * @param {string} extension\n * @returns {string}\n * @private\n */\n function getTesterUrl(win, action, controller, extension) {\n const document = win.document;\n const navigator = win.navigator;\n const screen = win.screen;\n const params = {};\n let e = 0;\n let f = 0;\n\n // append the browser user agent\n params.ua = navigator.userAgent;\n\n // detect browser family\n e |= win.ActiveXObject ? 1 : 0;\n e |= win.opera ? 2 : 0;\n e |= win.chrome ? 4 : 0;\n e |= 'getBoxObjectFor' in document || 'mozInnerScreenX' in win ? 8 : 0;\n e |=\n 'WebKitCSSMatrix' in win || 'WebKitPoint' in win || 'webkitStorageInfo' in win || 'webkitURL' in win\n ? 16\n : 0;\n e |= e & 16 && {}.toString.toString().indexOf('\\n') === -1 ? 32 : 0;\n params.e = e;\n\n // gather info about browser functionality\n f |= 'sandbox' in document.createElement('iframe') ? 1 : 0;\n f |= 'WebSocket' in win ? 2 : 0;\n f |= win.Worker ? 4 : 0;\n f |= win.applicationCache ? 8 : 0;\n f |= win.history && win.history.pushState ? 16 : 0;\n f |= document.documentElement.webkitRequestFullScreen ? 32 : 0;\n f |= 'FileReader' in win ? 64 : 0;\n params.f = f;\n\n // append a unique ID\n params.r = Math.random()\n .toString(36)\n .substring(7);\n\n // get the screen size\n params.w = screen.width;\n params.h = screen.height;\n\n return urlHelper.route(action, controller, extension, params);\n }\n\n /**\n * Check the user browser and os.\n *\n * This helper performs a server request to gather information about the user browser and os.\n * @param {Window} window - Need an access to the window object\n * @param {object} config\n * @param {string} config.browserVersionAction - The name of the action to call to get the browser checker\n * @param {string} config.browserVersionController - The name of the controller to call to get the browser checker\n * @param {string} config.browserVersionExtension - The name of the extension containing the controller to call to get the browser checker\n * @returns {Promise}\n */\n return function getPlatformInfo(win, config) {\n config = getConfig(config, defaultConfig);\n\n const url = getTesterUrl(\n win,\n config.browserVersionAction,\n config.browserVersionController,\n config.browserVersionExtension\n );\n\n return request({ url, noToken: true });\n };\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2016-2021 (original work) Open Assessment Technologies SA ;\n */\ndefine('taoClientDiagnostic/tools/browser/tester',[\n 'jquery',\n 'lodash',\n 'i18n',\n 'util/url',\n 'core/logger',\n 'core/request',\n 'taoClientDiagnostic/tools/getConfig',\n 'taoClientDiagnostic/tools/getLabels',\n 'taoClientDiagnostic/tools/getPlatformInfo',\n 'taoClientDiagnostic/tools/getStatus'\n], function($, _, __, urlHelper, loggerFactory, request, getConfig, getLabels, getPlatformInfo, getStatus) {\n 'use strict';\n\n /**\n * @type {logger}\n * @private\n */\n const logger = loggerFactory('taoClientDiagnostic/browser');\n\n /**\n * Some default values\n * @type {object}\n * @private\n */\n const _defaults = {\n id: 'browser',\n browserVersionAction: 'whichBrowser',\n browserVersionController: 'CompatibilityChecker',\n browserVersionExtension: 'taoClientDiagnostic',\n action: 'check',\n controller: 'DiagnosticChecker',\n browserslistUrl: 'https://oat-sa.github.io/browserslist-app-tao/api.json'\n };\n\n /**\n * Placeholder variables for custom messages\n * @type {object}\n * @private\n */\n const _placeHolders = {\n CURRENT_BROWSER: '%CURRENT_BROWSER%',\n CURRENT_OS: '%CURRENT_OS%'\n };\n\n /**\n * List of translated texts per level.\n * The level is provided through the config as a numeric value, starting from 1.\n * @type {object}\n * @private\n */\n const _messages = [\n // level 1\n {\n title: __('Operating system and web browser'),\n status: __('Checking the browser...'),\n browser: __('Web browser'),\n os: __('Operating system')\n }\n ];\n\n /**\n * Fallback name to recover from connectivity error\n * @param {string}\n * @private\n */\n const unknown = __('Unknown');\n\n /**\n * Performs a browser support test\n *\n * @param {object} config - Some optional configs\n * @param {string} [config.id] - The identifier of the test\n * @param {string} [config.action] - The name of the action to call to get the browser checker\n * @param {string} [config.controller] - The name of the controller to call to get the browser checker\n * @param {string} [config.extension] - The name of the extension containing the controller to call to get the browser checker\n * @param {string} [config.level] - The intensity level of the test. It will aim which messages list to use.\n * @returns {object}\n */\n return function browserTester(config) {\n const initConfig = getConfig(config, _defaults);\n const labels = getLabels(_messages, initConfig.level);\n\n /**\n * Fetches the list of fully supported browsers\n * @returns {Promise}\n * @private\n */\n const fetchBrowserList = () => request({ url: initConfig.browserslistUrl, noToken: true }).catch(() => []);\n\n /**\n * Checks the current browser against the list of fully supported browsers\n * @param platformInfo\n * @returns {Promise}\n * @private\n */\n function checkBrowserSupport(platformInfo) {\n const currentDevice = platformInfo.isMobile ? 'mobile' : 'desktop';\n const currentOS = platformInfo.os.toLowerCase();\n const currentBrowser = platformInfo.browser.toLowerCase();\n const currentVersion = platformInfo.browserVersion;\n return fetchBrowserList().then(list =>\n list.some(entry => {\n const { browser, device, os, versions } = entry;\n\n if (currentDevice !== device) {\n return false;\n }\n\n if (os && os.toLowerCase() !== currentOS) {\n return false;\n }\n\n if (browser.toLowerCase() !== currentBrowser) {\n return false;\n }\n\n // Using lodash because of IE support.\n // Some useful traversal algorithms are needed and they don't have polyfill in our bundles.\n // The versions come with an inconsistent format and they need to be processed upfront.\n return _(versions)\n .map(version => version.split('-'))\n .flatten()\n .value()\n .some(version => currentVersion.localeCompare(version, void 0, { numeric: true }) >= 0);\n }, {})\n );\n }\n\n return {\n /**\n * Performs a browser support test, then call a function to provide the result\n * @param {Function} done\n */\n start(done) {\n getPlatformInfo(window, initConfig)\n .catch(err => {\n logger.error(err);\n return {\n browser: unknown,\n browserVersion: '',\n os: unknown,\n osVersion: '',\n isMobile: false\n };\n })\n .then(platformInfo =>\n checkBrowserSupport(platformInfo).then(browserSupported =>\n Object.assign(platformInfo, { browserSupported })\n )\n )\n .then(platformInfo => {\n request({\n url: urlHelper.route(initConfig.action, initConfig.controller, initConfig.extension),\n data: platformInfo,\n method: 'POST',\n noToken: true\n })\n .catch(() => {\n return {\n success: false,\n type: 'error',\n message: __('Unable to validate the data as the server did not respond in time.')\n };\n })\n .then(data => {\n const percentage = 'success' === data.type ? 100 : 'warning' === data.type ? 33 : 0;\n const status = this.getFeedback(percentage, data);\n const summary = this.getSummary(platformInfo);\n\n status.customMsgRenderer = customMsg => {\n return (customMsg || '')\n .replace(_placeHolders.CURRENT_BROWSER, summary.browser.value)\n .replace(_placeHolders.CURRENT_OS, summary.os.value);\n };\n\n done(status, summary, platformInfo);\n });\n });\n },\n\n /**\n * Gets the labels loaded for the tester\n * @returns {object}\n */\n get labels() {\n return labels;\n },\n\n /**\n * Builds the results summary\n * @param {object} results\n * @returns {object}\n */\n getSummary(results) {\n const currentBrowser = `${results.browser} ${results.browserVersion}`;\n const currentOs = `${results.os} ${results.osVersion}`;\n return {\n browser: {\n message: labels.browser,\n value: currentBrowser\n },\n os: {\n message: labels.os,\n value: currentOs\n }\n };\n },\n\n /**\n * Gets the feedback status for the provided result value\n * @param {number} result\n * @param {object} data\n * @returns {object}\n */\n getFeedback(result, data) {\n const status = getStatus(result, data);\n\n status.id = initConfig.id;\n status.title = labels.title;\n\n return status;\n }\n };\n };\n});\n\n","\ndefine('tpl!taoClientDiagnostic/tools/diagnostic/tpl/main', ['handlebars'], function(hb){ \nreturn hb.template(function (Handlebars,depth0,helpers,partials,data) {\n this.compilerInfo = [4,'>= 1.0.0'];\nhelpers = this.merge(helpers, Handlebars.helpers); data = data || {};\n var buffer = \"\", stack1, helper, functionType=\"function\", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing, self=this;\n\nfunction program1(depth0,data) {\n \n var buffer = \"\", stack1, helper;\n buffer += \"

\";\n if (helper = helpers.header) { stack1 = helper.call(depth0, {hash:{},data:data}); }\n else { helper = (depth0 && depth0.header); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }\n buffer += escapeExpression(stack1)\n + \"

\";\n return buffer;\n }\n\nfunction program3(depth0,data) {\n \n var buffer = \"\", stack1, helper;\n buffer += \"

\";\n if (helper = helpers.info) { stack1 = helper.call(depth0, {hash:{},data:data}); }\n else { helper = (depth0 && depth0.info); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }\n buffer += escapeExpression(stack1)\n + \"

\";\n return buffer;\n }\n\nfunction program5(depth0,data) {\n \n var buffer = \"\", stack1, helper;\n buffer += \"

\";\n if (helper = helpers.setup) { stack1 = helper.call(depth0, {hash:{},data:data}); }\n else { helper = (depth0 && depth0.setup); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }\n buffer += escapeExpression(stack1)\n + \"

\";\n return buffer;\n }\n\nfunction program7(depth0,data) {\n \n var buffer = \"\", helper, options;\n buffer += \"\\n

\\n \\n \\n

\\n

\\n \\n \\n

\\n \";\n return buffer;\n }\n\nfunction program9(depth0,data) {\n \n var buffer = \"\", stack1;\n buffer += \"\\n \";\n stack1 = helpers['if'].call(depth0, (depth0 && depth0.validateSchoolName), {hash:{},inverse:self.program(12, program12, data),fn:self.program(10, program10, data),data:data});\n if(stack1 || stack1 === 0) { buffer += stack1; }\n buffer += \"\\n \";\n return buffer;\n }\nfunction program10(depth0,data) {\n \n var buffer = \"\", helper, options;\n buffer += \"\\n

\\n \\n \\n

\\n

\\n \\n \\n

\\n \";\n return buffer;\n }\n\nfunction program12(depth0,data) {\n \n var buffer = \"\", helper, options;\n buffer += \"\\n

\\n \\n \\n

\\n \";\n return buffer;\n }\n\n buffer += \"
\\n\\n

\";\n if (helper = helpers.title) { stack1 = helper.call(depth0, {hash:{},data:data}); }\n else { helper = (depth0 && depth0.title); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }\n buffer += escapeExpression(stack1)\n + \"

\\n\\n
\\n \";\n stack1 = helpers['if'].call(depth0, (depth0 && depth0.header), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});\n if(stack1 || stack1 === 0) { buffer += stack1; }\n buffer += \"\\n \";\n stack1 = helpers['if'].call(depth0, (depth0 && depth0.info), {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data});\n if(stack1 || stack1 === 0) { buffer += stack1; }\n buffer += \"\\n \";\n stack1 = helpers['if'].call(depth0, (depth0 && depth0.setup), {hash:{},inverse:self.noop,fn:self.program(5, program5, data),data:data});\n if(stack1 || stack1 === 0) { buffer += stack1; }\n buffer += \"\\n \";\n stack1 = helpers['if'].call(depth0, (depth0 && depth0.requireSchoolId), {hash:{},inverse:self.noop,fn:self.program(7, program7, data),data:data});\n if(stack1 || stack1 === 0) { buffer += stack1; }\n buffer += \"\\n \";\n stack1 = helpers['if'].call(depth0, (depth0 && depth0.requireSchoolName), {hash:{},inverse:self.noop,fn:self.program(9, program9, data),data:data});\n if(stack1 || stack1 === 0) { buffer += stack1; }\n buffer += \"\\n
\\n\\n
\\n \\n
\\n\\n
    \\n\\n
    \\n

    \\n
    \\n\\n
    \";\n return buffer;\n });\n});\n\n","\ndefine('tpl!taoClientDiagnostic/tools/diagnostic/tpl/result', ['handlebars'], function(hb){ \nreturn hb.template(function (Handlebars,depth0,helpers,partials,data) {\n this.compilerInfo = [4,'>= 1.0.0'];\nhelpers = this.merge(helpers, Handlebars.helpers); data = data || {};\n var buffer = \"\", stack1, helper, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, functionType=\"function\", self=this;\n\nfunction program1(depth0,data) {\n \n var buffer = \"\", helper, options;\n buffer += \"\\n
    \\n \\n \\n
    \\n
    \\n \";\n return buffer;\n }\n\n buffer += \"
  • \\n

    \";\n if (helper = helpers.title) { stack1 = helper.call(depth0, {hash:{},data:data}); }\n else { helper = (depth0 && depth0.title); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }\n buffer += escapeExpression(stack1)\n + \"

    \\n
    \\n\\n \";\n stack1 = helpers['if'].call(depth0, (depth0 && depth0.details), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});\n if(stack1 || stack1 === 0) { buffer += stack1; }\n buffer += \"\\n
  • \";\n return buffer;\n });\n});\n\n","\ndefine('tpl!taoClientDiagnostic/tools/diagnostic/tpl/details', ['handlebars'], function(hb){ \nreturn hb.template(function (Handlebars,depth0,helpers,partials,data) {\n this.compilerInfo = [4,'>= 1.0.0'];\nhelpers = this.merge(helpers, Handlebars.helpers); data = data || {};\n var buffer = \"\", stack1, helper, options, functionType=\"function\", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing, self=this;\n\nfunction program1(depth0,data) {\n \n var buffer = \"\", stack1, helper;\n buffer += \"\\n \";\n if (helper = helpers.message) { stack1 = helper.call(depth0, {hash:{},data:data}); }\n else { helper = (depth0 && depth0.message); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }\n buffer += escapeExpression(stack1)\n + \"\";\n if (helper = helpers.value) { stack1 = helper.call(depth0, {hash:{},data:data}); }\n else { helper = (depth0 && depth0.value); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }\n buffer += escapeExpression(stack1)\n + \"\\n \";\n return buffer;\n }\n\n buffer += \"
    \\n

    \"\n + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, \"Details\", options) : helperMissing.call(depth0, \"__\", \"Details\", options)))\n + \"

    \\n
    \\n \\n \\n \";\n stack1 = helpers.each.call(depth0, depth0, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});\n if(stack1 || stack1 === 0) { buffer += stack1; }\n buffer += \"\\n \\n
    \\n
    \\n
    \";\n return buffer;\n });\n});\n\n","\ndefine('tpl!taoClientDiagnostic/tools/diagnostic/tpl/feedback', ['handlebars'], function(hb){ \nreturn hb.template(function (Handlebars,depth0,helpers,partials,data) {\n this.compilerInfo = [4,'>= 1.0.0'];\nhelpers = this.merge(helpers, Handlebars.helpers); data = data || {};\n var buffer = \"\", stack1, helper, functionType=\"function\", escapeExpression=this.escapeExpression, self=this;\n\nfunction program1(depth0,data) {\n \n var buffer = \"\", stack1, helper;\n buffer += \"
    \";\n if (helper = helpers.legend) { stack1 = helper.call(depth0, {hash:{},data:data}); }\n else { helper = (depth0 && depth0.legend); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }\n buffer += escapeExpression(stack1)\n + \"
    \";\n return buffer;\n }\n\nfunction program3(depth0,data) {\n \n var buffer = \"\", stack1, helper;\n buffer += \"
    \";\n if (helper = helpers.customMsg) { stack1 = helper.call(depth0, {hash:{},data:data}); }\n else { helper = (depth0 && depth0.customMsg); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }\n buffer += escapeExpression(stack1)\n + \"
    \";\n return buffer;\n }\n\n buffer += \"
    \\n \\n \";\n if (helper = helpers.message) { stack1 = helper.call(depth0, {hash:{},data:data}); }\n else { helper = (depth0 && depth0.message); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }\n buffer += escapeExpression(stack1)\n + \"\\n \";\n stack1 = helpers['if'].call(depth0, (depth0 && depth0.legend), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});\n if(stack1 || stack1 === 0) { buffer += stack1; }\n buffer += \"\\n \";\n stack1 = helpers['if'].call(depth0, (depth0 && depth0.customMsg), {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data});\n if(stack1 || stack1 === 0) { buffer += stack1; }\n buffer += \"\\n
    \";\n return buffer;\n });\n});\n\n","\ndefine('tpl!taoClientDiagnostic/tools/diagnostic/tpl/quality-bar', ['handlebars'], function(hb){ \nreturn hb.template(function (Handlebars,depth0,helpers,partials,data) {\n this.compilerInfo = [4,'>= 1.0.0'];\nhelpers = this.merge(helpers, Handlebars.helpers); data = data || {};\n var buffer = \"\", stack1, functionType=\"function\", escapeExpression=this.escapeExpression, self=this;\n\nfunction program1(depth0,data) {\n \n \n return \" wide\";\n }\n\nfunction program3(depth0,data) {\n \n var buffer = \"\", stack1, helper;\n buffer += \" title=\\\"\";\n if (helper = helpers.label) { stack1 = helper.call(depth0, {hash:{},data:data}); }\n else { helper = (depth0 && depth0.label); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }\n buffer += escapeExpression(stack1)\n + \"\\\"\";\n return buffer;\n }\n\n buffer += \"
    \\n
    \\n
    \";\n return buffer;\n });\n});\n\n","\ndefine('css!taoClientDiagnosticCss/diagnostics',[],function(){});\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2016-2021 (original work) Open Assessment Technologies SA ;\n */\ndefine('taoClientDiagnostic/tools/diagnostic/diagnostic',[\n 'jquery',\n 'lodash',\n 'i18n',\n 'async',\n 'ui/component',\n 'core/logger',\n 'core/store',\n 'core/request',\n 'core/dataProvider/request',\n 'ui/dialog/alert',\n 'ui/feedback',\n 'util/url',\n 'taoClientDiagnostic/tools/performances/tester',\n 'taoClientDiagnostic/tools/bandwidth/tester',\n 'taoClientDiagnostic/tools/upload/tester',\n 'taoClientDiagnostic/tools/browser/tester',\n 'taoClientDiagnostic/tools/getStatus',\n 'taoClientDiagnostic/tools/getConfig',\n 'tpl!taoClientDiagnostic/tools/diagnostic/tpl/main',\n 'tpl!taoClientDiagnostic/tools/diagnostic/tpl/result',\n 'tpl!taoClientDiagnostic/tools/diagnostic/tpl/details',\n 'tpl!taoClientDiagnostic/tools/diagnostic/tpl/feedback',\n 'tpl!taoClientDiagnostic/tools/diagnostic/tpl/quality-bar',\n 'css!taoClientDiagnosticCss/diagnostics'\n], function(\n $,\n _,\n __,\n async,\n component,\n loggerFactory,\n store,\n request,\n requestData,\n dialogAlert,\n feedback,\n urlHelper,\n performancesTester,\n bandwidthTester,\n uploadTester,\n browserTester,\n getStatus,\n getConfig,\n mainTpl,\n resultTpl,\n detailsTpl,\n feedbackTpl,\n qualityBarTpl\n) {\n 'use strict';\n /**\n * @type {logger}\n * @private\n */\n const logger = loggerFactory('taoClientDiagnostic/diagnostic');\n\n /**\n * Some default values\n * @type {object}\n * @private\n */\n const _defaults = {\n title: __('System Compatibility'),\n header: __(\n 'This tool will run a number of tests in order to establish how well your current environment is suitable to run the TAO platform.'\n ),\n info: __('Be aware that these tests will take up to several minutes.'),\n button: __('Test system compatibility'),\n actionStore: 'storeData',\n actionSchool: 'schoolName',\n controller: 'DiagnosticChecker',\n extension: 'taoClientDiagnostic',\n actionDropId: 'deleteId',\n storeAllRuns: false,\n configurableText: {}\n };\n\n /**\n * A list of thresholds for summary\n * @type {Array}\n * @private\n */\n const _thresholds = [\n {\n threshold: 0,\n message: __('Your system requires a compatibility update, please contact your system administrator.'),\n type: 'error'\n },\n {\n threshold: 33,\n message: __('Your system is not optimal, please contact your system administrator.'),\n type: 'warning'\n },\n {\n threshold: 66,\n message: __('Your system is fully compliant.'),\n type: 'success'\n }\n ];\n\n /**\n * Defines a diagnostic tool\n * @type {object}\n */\n const diagnostic = {\n /**\n * Updates the displayed status\n * @param {string} status\n * @returns {diagnostic}\n * @private\n */\n changeStatus(status) {\n if (this.is('rendered')) {\n this.controls.$status.html(status);\n }\n return this;\n },\n\n /**\n * Sends the detailed stats to the server\n * @param {string} type The type of stats\n * @param {object} data The stats details\n * @param {Function} done A callback method called once server has responded\n */\n store(type, data, done) {\n const config = this.config;\n const url = urlHelper.route(config.actionStore, config.controller, config.extension, config.storeParams);\n\n data = _.omit(data, 'values');\n data.type = type;\n\n request({ url, data, method: 'POST', noToken: true })\n .then(done)\n .catch(err => {\n logger.error(err);\n feedback().error(__('Unable to save the results! Please check your connection.'));\n done();\n });\n },\n\n /**\n * Retrieve a custom message from the config\n * @param key\n * @returns {*}\n */\n getCustomMsg(key) {\n return this.config.configurableText[key];\n },\n\n /**\n * Enrich the feedback object with a custom message if the test has failed\n * @param {object} status - the test result\n * @param {string} msg - the custom message\n */\n addCustomFeedbackMsg(status, msg) {\n if (this.hasFailed(status) && msg) {\n if (_.isFunction(status.customMsgRenderer)) {\n msg = status.customMsgRenderer(msg);\n }\n status.feedback = status.feedback || {};\n status.feedback.customMsg = msg;\n }\n },\n\n /**\n * Check if a result is considered as failed\n * @param {object} result\n * @returns {boolean}\n */\n hasFailed(result) {\n return !(result && result.feedback && result.feedback.type === 'success');\n },\n\n /**\n * Add a result row\n * @param {object} result\n * @returns {diagnostic}\n */\n addResult(result) {\n if (this.is('rendered')) {\n // adjust the width of the displayed label, if any, to the text length\n if (result.quality && result.quality.label && result.quality.label.toString().length > 2) {\n result.quality.wide = true;\n }\n\n // create and append the result to the displayed list\n const $main = $(resultTpl(result));\n const $result = $main.find('.result');\n if (result.feedback) {\n $result.append($(feedbackTpl(result.feedback)));\n }\n if (result.quality) {\n $result.append($(qualityBarTpl(result.quality)));\n }\n if (result.details) {\n $main.find('.details').append($(detailsTpl(result.details)));\n }\n\n const $indicator = $main.find('.quality-indicator');\n this.controls.$results.append($main);\n\n // the result is hidden by default, show it with a little animation\n $main.fadeIn(() => {\n if ($indicator.length) {\n $indicator.animate({\n left: (result.percentage * $main.outerWidth()) / 100 - $indicator.outerWidth() / 2\n });\n }\n });\n }\n\n return this;\n },\n\n /**\n * Removes the last results if any\n * @returns {diagnostic}\n */\n cleanUp() {\n this.controls.$results.empty();\n return this;\n },\n\n /**\n * Enables the start button\n * @returns {diagnostic}\n */\n enable() {\n this.controls.$start.removeClass('hidden');\n return this;\n },\n\n /**\n * Disables the start button\n * @returns {diagnostic}\n */\n disable() {\n this.controls.$start.addClass('hidden');\n return this;\n },\n\n /**\n * Does some preparations before starting the diagnostics\n * @returns {diagnostic}\n * @private\n */\n prepare() {\n /**\n * Notifies the diagnostic start\n * @event diagnostic#start\n */\n this.trigger('start');\n this.changeStatus(__('Starting...'));\n this.setState('running', true);\n this.setState('done', false);\n\n // first we need a clean space to display the results, so remove the last results if any\n this.cleanUp();\n\n // remove the start button during the diagnostic\n this.disable();\n\n return this;\n },\n\n /**\n * Does some post process after ending the diagnostics\n * @returns {diagnostic}\n * @private\n */\n finish() {\n const config = this.config;\n\n // restore the start button to allow a new diagnostic run\n this.enable();\n\n if (config.storeAllRuns) {\n this.deleteIdentifier();\n }\n\n /**\n * Notifies the diagnostic end\n * @event diagnostic#end\n */\n this.trigger('end');\n this.changeStatus(__('Done!'));\n this.setState('running', false);\n this.setState('done', true);\n\n return this;\n },\n\n /**\n * delete unique id for this test session (next test will generate new one)\n */\n deleteIdentifier() {\n const url = urlHelper.route(this.config.actionDropId, this.config.controller, this.config.extension);\n return request({ url, method: 'POST', noToken: true });\n },\n\n /**\n * Runs the diagnostics\n * @returns {diagnostic}\n */\n run() {\n const information = [];\n const scores = {};\n const testers = [];\n const customInput = this.getCustomInput();\n\n const doRun = () => {\n // common handling for testers\n const doCheck = (testerConfig, cb) => {\n const testerId = testerConfig.id;\n\n /**\n * Notifies the start of a tester operation\n * @event diagnostic#starttester\n * @param {string} name - The name of the tester\n */\n this.trigger('starttester', testerId);\n this.setState(testerId, true);\n\n /**\n * Process the diagnostic from the loaded tester\n * @param {Function} testerFactory\n * @private\n */\n const processTester = testerFactory => {\n const tester = testerFactory(getConfig(testerConfig, this.config), this);\n this.changeStatus(tester.labels.status);\n tester.start((status, details, results) => {\n if (testerConfig.customMsgKey) {\n const customMsg = this.getCustomMsg(testerConfig.customMsgKey);\n this.addCustomFeedbackMsg(status, customMsg);\n }\n\n // the returned details must be ingested into the main details list\n _.forEach(details, info => information.push(info));\n scores[status.id] = status;\n\n /**\n * Notifies the end of a tester operation\n * @event diagnostic#endtester\n * @param {string} id - The identifier of the tester\n * @param {Array} results - The results of the test\n */\n this.trigger('endtester', testerId, status);\n this.setState(testerId, false);\n\n // results should be filtered in order to encode complex data\n results = _.mapValues(results, value => {\n switch (typeof value) {\n case 'boolean':\n return value ? 1 : 0;\n case 'object':\n return JSON.stringify(value);\n }\n return value;\n });\n\n // send the data to store\n this.store(testerId, results, () => {\n this.addResult(status);\n cb();\n });\n });\n };\n\n /**\n * React to loading failure\n * @param {Error} err\n * @private\n */\n const processFailure = err => {\n logger.error(err);\n feedback().error(\n __(\n 'Unable to process with the diagnostic tester %s. The tester module is unreachable.',\n testerId\n )\n );\n cb();\n };\n\n require([testerConfig.tester], processTester, processFailure);\n };\n\n if (this.is('rendered')) {\n // set up the component to a new run\n this.prepare();\n\n _.forEach(this.config.testers, (testerConfig, testerId) => {\n testerConfig.id = testerConfig.id || testerId;\n if (testerConfig.enabled) {\n testers.push(cb => doCheck(testerConfig, cb));\n }\n });\n\n // launch each testers in series, then display the results\n async.series(testers, () => {\n // pick the lowest percentage as the main score\n const total = _.min(scores, 'globalPercentage');\n\n // get a status according to the main score\n const status = getStatus(total.globalPercentage, _thresholds);\n\n // display the result\n status.title = __('Total');\n status.id = 'total';\n this.addCustomFeedbackMsg(status, this.config.configurableText.diagTotalCheckResult);\n\n status.details = information;\n this.addResult(status);\n\n // done !\n this.finish();\n });\n }\n };\n\n if (_.size(customInput) > 0) {\n this.store('custom_input', customInput, doRun);\n } else {\n doRun();\n }\n\n return this;\n },\n\n getCustomInput() {\n const vars = {};\n\n window.location.href.replace(location.hash, '').replace(/[?&]+([^=&]+)=?([^&]*)?/gi, (m, key, value) => {\n if (_.has(this.config['customInput'], key)) {\n vars[key] = typeof value !== 'undefined' ? value : '';\n }\n });\n\n return vars;\n }\n };\n\n /**\n * Builds an instance of the diagnostic tool\n * @param {object} container - Container in which the initialisation will render the diagnostic\n * @param {object} config\n * @param {string} [config.title] - The displayed title\n * @param {string} [config.header] - A header text displayed to describe the component\n * @param {string} [config.info] - An information text displayed to warn about run duration\n * @param {string} [config.button] - The caption of the start button\n * @param {string} [config.actionStore] - The name of the action to call to store the results\n * @param {string} [config.actionCheck] - The name of the action to call to check the browser results\n * @param {string} [config.actionSchool] - The name of the action to call to get the school name\n * @param {string} [config.controller] - The name of the controller to call\n * @param {string} [config.extension] - The name of the extension containing the controller\n * @param {object} [config.storeParams] - A list of additional parameters to send with diagnostic results\n * @param {boolean} [config.requireSchoolName] - If `true` require a school name to allow the tests to start\n * @param {boolean} [config.requireSchoolId] - If `true` require a school ID to allow the tests to start\n * @param {boolean} [config.validateSchoolName] - If `true` require a school number and a PIN to get the school name and to allow the tests to start\n *\n * @param {string} [config.browser.action] - The name of the action to call to get the browser checker\n * @param {string} [config.browser.controller] - The name of the controller to call to get the browser checker\n * @param {string} [config.browser.extension] - The name of the extension containing the controller to call to get the browser checker\n *\n * @param {number} [config.bandwidth.unit] - The typical bandwidth needed for a test taker (Mbps)\n * @param {Array} [config.bandwidth.ideal] - The thresholds for optimal bandwidth, one by bar\n * @param {number} [config.bandwidth.max] - Maximum number of test takers to display\n *\n * @param {Array} [config.performances.samples] - A list of samples to render in order to compute the rendering performances\n * @param {number} [config.performances.occurrences] - The number of renderings by samples\n * @param {number} [config.performances.timeout] - Max allowed duration for a sample rendering\n * @param {number} [config.performances.optimal] - The threshold for optimal performances\n * @param {number} [config.performances.threshold] - The threshold for minimal performances\n * @returns {diagnostic}\n */\n return function diagnosticFactory(container, config) {\n // fix the translations for content loaded from config files\n if (config) {\n _.forEach(['title', 'header', 'footer', 'info', 'button'], name => {\n if (config[name]) {\n config[name] = __(config[name]);\n }\n });\n }\n\n const diagComponent = component(diagnostic, _defaults)\n .setTemplate(mainTpl)\n\n // uninstalls the component\n .on('destroy', function onDiagnosticDestroy() {\n this.controls = null;\n })\n\n // initialise component\n .on('init', function onDiagnosticInit() {\n this.render(container);\n })\n // renders the component\n .on('render', function onDiagnosticRender() {\n /**\n * Starts the tests\n * @param {object} [data]\n * @private\n */\n const runDiagnostics = data => {\n // append the school name to the queries\n if (data && _.isPlainObject(data)) {\n this.config.storeParams = _.assign(this.config.storeParams || {}, data);\n }\n\n this.run();\n };\n\n /**\n * Default launcher\n * @private\n */\n let launch = () => runDiagnostics();\n\n /**\n * Gets a control by its registered name\n * @param {string} name - the name registered in the collection of controls\n * @private\n */\n const getControl = name => this.controls[`\\$${name}`];\n\n /**\n * Gets the value of an input field\n * @param {string} name - the name registered in the collection of controls\n * @returns {string}\n * @private\n */\n function getInputValue(name) {\n const $control = getControl(name);\n return (($control && $control.val()) || '').trim();\n }\n\n /**\n * Sets the value of an input field\n * @param {string} name - the name registered in the collection of controls\n * @param {string} value\n * @private\n */\n function setInputValue(name, value) {\n const $control = getControl(name);\n $control && $control.val(value);\n }\n\n /**\n * Enable/Disable a control\n * @param {string} name - the name registered in the collection of controls\n * @param {boolean} [state]\n * @private\n */\n function toggleControl(name, state) {\n const $control = getControl(name);\n if ($control) {\n if (typeof state === 'undefined') {\n state = !$control.is(':enabled');\n }\n if (state) {\n $control.prop('disabled', false);\n } else {\n $control.prop('disabled', true);\n }\n }\n }\n\n /**\n * Requests the server to get the school name\n * @param {object} values\n * @private\n */\n const requestSchoolName = values => {\n const componentConfig = this.config;\n return requestData(\n urlHelper.route(\n componentConfig.actionSchool,\n componentConfig.controller,\n componentConfig.extension\n ),\n values,\n 'POST'\n ).then(data => {\n return {\n school_name: data,\n school_number: values.school_number\n };\n });\n };\n\n /**\n * Install the school name manager.\n * @todo: improve this by moving it into a plugin, and obviously implement the plugin handling\n * @private\n */\n const manageSchoolProperties = (fields, validate) => {\n /**\n * Checks if the start button can be enabled\n * @returns {boolean}\n * @private\n */\n function toggleStart() {\n const allow = _.every(fields, getInputValue);\n toggleControl('start', allow);\n return allow;\n }\n\n /**\n * Enables/Disables the fields\n * @param {boolean} state\n * @private\n */\n function toggleFields(state) {\n _.forEach(fields, function(fieldName) {\n toggleControl(fieldName, state);\n });\n }\n\n // ensure the diagnostic cannot start without all fields properly input\n _.forEach(fields, fieldName => {\n this.controls[`\\$${fieldName}`] = this.getElement()\n .find(`[data-control=\"${fieldName}\"]`)\n .on('keypress', e => {\n const shouldStart = e.which === 13;\n if (shouldStart) {\n e.preventDefault();\n }\n _.defer(() => {\n if (toggleStart() && shouldStart) {\n this.controls.$start.click();\n }\n });\n });\n });\n\n toggleStart();\n\n // will store the school name in the browser storage, that will allow to restore it next time\n toggleFields(false);\n store('client-diagnostic')\n .then(storage => {\n // store the school name on test start, to ensure consistency\n this.on('start.school', () => {\n _.forEach(fields, fieldName => {\n storage.setItem(fieldName, getInputValue(fieldName)).catch(error => {\n logger.error(error);\n });\n });\n });\n\n // restore the school name on load\n return Promise.all(\n _.map(fields, fieldName => {\n return storage.getItem(fieldName).then(value => {\n setInputValue(fieldName, value);\n });\n })\n );\n })\n .catch(error => {\n logger.error(error);\n })\n .then(() => {\n toggleFields(true);\n toggleStart();\n });\n\n // ensure the fields are validated and the school name is properly sent before allowing to launch the test\n launch = () => {\n const values = _.reduce(\n fields,\n (result, fieldName) => {\n result[fieldName] = getInputValue(fieldName);\n return result;\n },\n {}\n );\n\n this.changeStatus(__('Getting school name...'))\n .cleanUp()\n .disable();\n\n if (_.isFunction(validate)) {\n validate(values)\n .then(runDiagnostics)\n .catch(error => {\n const response = error.response || {};\n const message =\n response.errorMsg ||\n response.errorMessage ||\n __('An error occurred! Please verify your input!');\n dialogAlert(message);\n logger.error(error);\n this.changeStatus(__('Failed to get school name')).enable();\n });\n } else {\n runDiagnostics(values);\n }\n };\n\n // ensure the fields are not writable while the test is running\n this.on('start.school', () => {\n toggleFields(false);\n }).on('end.school', () => {\n toggleFields(true);\n });\n };\n\n // get access to all needed placeholders\n this.controls = {\n $start: this.$component.find('[data-action=\"test-launcher\"]'),\n $status: this.$component.find('.status h2'),\n $results: this.$component.find('.results')\n };\n\n // start the diagnostic\n this.controls.$start.on('click', () => {\n this.controls.$start.is(':enabled') && launch();\n });\n\n if (this.config.requireSchoolName) {\n if (this.config.validateSchoolName) {\n manageSchoolProperties(['school_number', 'school_pin'], requestSchoolName);\n } else {\n manageSchoolProperties(['school_name']);\n }\n }\n\n if (this.config.requireSchoolId) {\n manageSchoolProperties(['school_id', 'workstation']);\n }\n\n // show result details\n this.controls.$results.on('click', 'button[data-action=\"show-details\"]', function onShowDetails() {\n const $btn = $(this).closest('button');\n const $result = $btn.closest('[data-result]');\n const $details = $result.find('.details');\n $details.removeClass('hidden');\n $btn.addClass('hidden');\n $result.find('[data-action=\"hide-details\"]').removeClass('hidden');\n });\n\n // hide result details\n this.controls.$results.on('click', 'button[data-action=\"hide-details\"]', function onHideDetails() {\n const $btn = $(this).closest('button');\n const $result = $btn.closest('[data-result]');\n const $details = $result.find('.details');\n $details.addClass('hidden');\n $btn.addClass('hidden');\n $result.find('[data-action=\"show-details\"]').removeClass('hidden');\n });\n });\n\n _.defer(() => diagComponent.init(config));\n\n return diagComponent;\n };\n});\n\n","\n(function(c){var d=document,a='appendChild',i='styleSheet',s=d.createElement('style');s.type='text/css';d.getElementsByTagName('head')[0][a](s);s[i]?s[i].cssText=c:s[a](d.createTextNode(c));})\n('.diagnostics-content-area{max-width:768px;margin:40px auto 40px auto}.diagnostics-main-area{margin:40px auto 0 auto;background:#f3f1ef;border:1px solid #ddd;border-radius:2px;-webkit-border-radius:2px;padding:20px}.diagnostics-main-area h1,.diagnostics-main-area h2,.diagnostics-main-area h3{font-style:normal;font-family:\\\"Source Sans Pro\\\",sans-serif}.diagnostics-main-area h1{margin-bottom:20px;font-size:20px;font-size:2rem}.diagnostics-main-area h2{margin:0;font-size:14px;font-size:1.4rem}.diagnostics-main-area h3{margin-top:10px;margin-bottom:5px;font-size:12px;font-size:1.2rem}.diagnostics-main-area .status h2,.diagnostics-main-area .details h2{margin:1rem 0}.diagnostics-main-area .legend{font-style:italic;font-weight:normal;font-family:\\\"Source Sans Pro\\\",sans-serif;font-size:11px;font-size:1.1rem}.diagnostics-main-area .customMsg{margin-top:10px}.diagnostics-main-area .quality-bar{height:15px;background:linear-gradient(to right, #CE1431 0%, #D57915 25%, #D5A215 50%, #D5CB15 75%, #36B111 100%);opacity:.8;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;margin:5px 0 10px;position:relative}.diagnostics-main-area .quality-indicator{position:absolute;border-width:10px 8px;border-style:solid;border-color:#333 transparent transparent;top:-1px;height:25px;width:0}.diagnostics-main-area .quality-indicator[title]:before{font-size:11px;font-size:1.1rem;content:attr(title);position:absolute;top:-36px;left:-12px;text-align:center;width:24px;height:24px;line-height:24px;display:inline-block;background-color:#0e5d91;color:rgba(255,255,255,0.9);-moz-border-radius:12px;-webkit-border-radius:12px;border-radius:12px}.diagnostics-main-area .quality-indicator.wide[title]:before{left:-16px;width:32px}.diagnostics-main-area [data-result],.diagnostics-main-area .bandwidth-box{display:none}.diagnostics-main-area [data-action=bandwidth-launcher]{margin:5px 0 10px}.diagnostics-main-area li{padding-bottom:10px}.diagnostics-main-area .intro{margin-bottom:20px}.diagnostics-main-area .intro label{display:inline-block;width:150px}table.datatable [class^=\\\"icon-\\\"]{padding:0}table.datatable td{font-size:90%;font-weight:normal}table.datatable .progress .state:not(:first-child):before{content:\\' - \\'}table.datatable .progress .item-time:before{content:\\' (\\'}table.datatable .progress .item-time .total:before{content:\\' / \\'}table.datatable .progress .item-time:after{content:\\')\\'}.details table.matrix{border:1px solid #ddd;border-radius:2px;-webkit-border-radius:2px;margin-top:5px}.details table.matrix td:first-child{min-width:30%}.diagnostic-scope h1{font-family:\\\"Source Sans Pro\\\",sans-serif;font-size:22px;font-size:2.2rem;font-weight:normal}.diagnostic-scope h2{font-family:\\\"Source Sans Pro\\\",sans-serif;font-size:18px;font-size:1.8rem;margin:30px 0 10px}.diagnostic-scope form.daterange label{padding:0}.diagnostic-scope form.daterange input{margin:0 10px}.diagnostic-scope table.datatable [class^=\\\"icon-\\\"]{padding:0}.diagnostic-scope table.datatable td{font-size:90%;font-weight:normal}.diagnostic-scope .content{margin:auto}.diagnostic-scope .diagnostic-index .content,.diagnostic-scope .diagnostic-runner .content{width:100%}.diagnostic-scope .diagnostic-index .message,.diagnostic-scope .diagnostic-runner .message{padding:8px;text-align:center}.diagnostic-scope .panel .action-bar{background:#266d9c;padding:3px;overflow:hidden;color:#e7eff4}.diagnostic-scope .panel .action-bar .btn-info{overflow:hidden;background:transparent;border:1px rgba(255,255,255,0.3) solid}.diagnostic-scope .diagnostics-main-area{margin-top:0px;max-width:800px}.diagnostic-scope .detailed-value{display:flex;justify-content:space-between}.diagnostic-scope .detailed-value.errors{color:#d8ae5b}.diagnostic-scope .detailed-value .details{font-size:2rem;cursor:pointer;color:#3e7da7}.diagnostic-scope .detailed-value .details:hover{color:#03131d}.action-bar .tool-exitButton,.action-bar [data-control=\\\"exitButton\\\"]{float:right}\\n\\n/*# sourceMappingURL=../../../taoClientDiagnostic/views/css/diagnostics.css.map */');\n","\ndefine(\"taoClientDiagnostic/loader/diagnostic.bundle\", function(){});\n","window.bundles = (window.bundles || []).concat([\"taoQtiItem/loader/taoQtiItem.min\",\"taoItems/loader/taoItems.min\"]);\n"]}