{"version":3,"file":"4680-8a05b4a1acf765776279.js","mappings":"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","sources":["webpack://@whistleout/webui/./Areas/Shared/js/SpeedTest.js","webpack://@whistleout/webui/./js/responsive/ndt/ndt-wrapper.js","webpack://@whistleout/webui/./js/responsive/ndt/ndt-browser-client.js","webpack://@whistleout/webui/./js/responsive/ndt/ndt7/ndt7-core.js","webpack://@whistleout/webui/./js/responsive/ndt/ndt-browser-client-exposed.js"],"sourcesContent":["// eslint-disable-next-line import/no-unresolved\nimport 'expose-loader?exposes=NDTjs|override!exports-loader?exports=NDTjs!../../../js/responsive/ndt/ndt-browser-client.js';\n\nimport { ndt7core } from 'exports-loader?exports=ndt7core!../../../js/responsive/ndt/ndt7/ndt7-core';\nimport { NDTWrapper } from 'exports-loader?exports=NDTWrapper!../../../js/responsive/ndt/ndt-wrapper.js';\n\n(function () {\n 'use strict';\n WhistleOut.SpeedTest = {};\n WhistleOut.SpeedTest.canUseNdt7 = function () {\n 'use strict';\n try {\n // TODO: Consider not using eval(), https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval\n /* eslint-disable no-eval */\n eval('var a = new URL(\\'https://www.whistleout.com.au\\')');\n eval('var bar = () => {return true}');\n eval('const sock = \\'a\\'');\n } catch (e) { return false; }\n\n var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n\n return isSafari ? false : true;\n };\n WhistleOut.SpeedTest.getSpeedTestParameters = function (successCallback, failedCallback) {\n // we are commenting this out as ndt7 token doesn't last too long, we have to figure out this but it is not in the documentation.\n //var cookieValue = Cookies.get('woSpeedTest');\n var useNdt7 = WhistleOut.getSiteConfiguration().useNdt7Protocol;\n var canUseNdt7 = WhistleOut.SpeedTest.canUseNdt7();\n\n //if (cookieValue) {\n // var cookieParsed = JSON.parse(cookieValue);\n // if (useNdt7 && canUseNdt7 && cookieParsed.protocol === 'ndt7' || useNdt7 === false && !cookieParsed.protocol) {\n // successCallback(cookieParsed);\n // return;\n // }\n //}\n\n var mlabNsService = '';\n var mlabNsUrl = '';\n\n if (useNdt7 && canUseNdt7) {\n mlabNsService = 'v2/nearest/ndt/ndt7';\n mlabNsUrl = 'https://locate.measurementlab.net/';\n } else {\n // TODO: Can we use === instead of == here?\n // eslint-disable-next-line eqeqeq\n mlabNsService = 'https:' == location.protocol ? 'ndt_ssl' : 'ndt';\n mlabNsUrl = 'https://mlab-ns.appspot.com/';\n }\n\n wo$.ajax({\n url: mlabNsUrl + mlabNsService + '?format=json',\n dataType: 'json',\n success: function (resp) {\n if (useNdt7 && canUseNdt7) {\n resp.protocol = 'ndt7';\n }\n\n //Cookies.set('woSpeedTest', JSON.stringify(resp), { path: '/', expires: 1 });\n successCallback(resp);\n },\n error: function (jqXHR, errStatus, errText) {\n failedCallback(jqXHR, errStatus, errText);\n }\n });\n };\n\n WhistleOut.SpeedTest.testSpeed = function (server, testDownloadSpeed, testUploadSpeed, callback) {\n var client = null;\n\n function getNumber(value) {\n if (value && !isNaN(value))\n return value;\n return null;\n }\n\n function getJustfiedSpeed(speedInKB) {\n var e = Math.floor(Math.log(speedInKB) / Math.log(1000));\n var fixedNum = 2;\n if (speedInKB > 100) {\n fixedNum = 0;\n } else if (speedInKB > 10) {\n fixedNum = 1;\n }\n return (speedInKB / Math.pow(1000, e)).toFixed(fixedNum);\n }\n\n function updateUploadSpeeds(result) {\n result.uploadSpeedDone = false;\n if (result.status === 'Outbound' || result.status === 'Inbound') {\n var value = getNumber(client.getNDTvar('ClientToServerSpeed'));\n if (value != null) {\n result.uploadSpeed = getJustfiedSpeed(value);\n if (result.status === 'Inbound') {\n result.uploadSpeedDone = true;\n }\n } else {\n result.uploadSpeed = null;\n }\n }\n }\n\n function updateDownloadSpeeds(result) {\n if (result.status === 'Inbound') {\n var value = getNumber(client.getNDTvar('ServerToClientSpeed'));\n if (value != null) {\n result.downloadSpeed = getJustfiedSpeed(value);\n } else {\n result.downloadSpeed = null;\n }\n }\n }\n\n function refreshSpeed(callback) {\n var message = client.get_errmsg();\n var status = client.get_status();\n var isCompleted = message === 'Test completed';\n var hasErrors = message !== 'Test completed' && message.length > 0;\n var latency = getNumber(client.getNDTvar('MinRTT'));\n console.log(message);\n var result = {\n 'status': status,\n 'isCompleted': isCompleted,\n 'hasErrors': hasErrors\n };\n updateUploadSpeeds(result);\n updateDownloadSpeeds(result);\n if (!isCompleted && !hasErrors) {\n callback(result);\n setTimeout(function () { refreshSpeed(callback); }, 1000);\n } else {\n if (latency) {\n result.latency = getNumber(client.getNDTvar('MinRTT'));\n }\n result.lastResultDate = new Date();\n Cookies.set('woSpeedTestResult', JSON.stringify(result), { path: '/', expires: 30 });\n callback(result);\n\n var event = {\n type: 'woSpeedTest.resultUpdated',\n detail: {\n sender: this,\n result: result\n }\n };\n wo$.event.trigger(event);\n }\n }\n\n var testsToExecute = 32;\n if (testDownloadSpeed) {\n testsToExecute = 4 | testsToExecute;\n }\n if (testUploadSpeed) {\n testsToExecute = 2 | testsToExecute;\n }\n\n client = new NDTWrapper(server, testsToExecute);\n client.run_test(server);\n refreshSpeed(callback);\n };\n\n WhistleOut.SpeedTest.runNdt7Test = function (server, testName, instance, callback, latencyInstance) {\n\n var updateView = function (instance, appInfo) {\n var elapsed = appInfo.ElapsedTime / 1e06; /* second */\n var speed = appInfo.NumBytes / elapsed; /* B/s */\n speed *= 8; /* bit/s */\n speed /= 1e06; /* Mbit/s */\n\n instance.text(speed.toFixed(1));\n };\n\n var updateLatency = function (instance, tcpInfo) {\n var speed = tcpInfo.MinRTT;\n speed /= 1000; /* Mbit/s */\n\n instance.text(Math.round(speed));\n };\n\n var useNdt7 = WhistleOut.getSiteConfiguration().useNdt7Protocol;\n if (!useNdt7) {\n return;\n }\n\n ndt7core.run(server,\n testName,\n function (ev, val) {\n if (ev === 'complete') {\n if (testName === 'download') {\n var result = {\n 'status': 'complete',\n 'isCompleted': true,\n 'hasErrors': false\n };\n result.lastResultDate = new Date();\n result.downloadSpeed = instance.first().text();\n Cookies.set('woSpeedTestResult', JSON.stringify(result), { path: '/', expires: 30 });\n }\n\n if (callback !== undefined) {\n callback();\n }\n return;\n }\n if (ev === 'measurement' &&\n val.AppInfo !== undefined &&\n val.Origin === 'client') {\n updateView(instance, val.AppInfo);\n }\n\n if (ev === 'measurement' &&\n val.TCPInfo !== undefined &&\n val.Origin === 'server' &&\n latencyInstance) {\n updateLatency(latencyInstance, val.TCPInfo);\n }\n });\n };\n\n WhistleOut.SpeedTest.init = function (parent) {\n if (!parent)\n parent = wo$('body');\n var container = parent.find('div.speed-test-widget');\n var speedTiers = container.data('speed-tiers');\n var displayError = function (instance) {\n instance.find('div[data-stage-progress]').addClass('hidden');\n instance.find('div[data-stage-error]').removeClass('hidden');\n Cookies.set('woSpeedTest', null, { path: '/', expires: -1 });\n };\n\n var testUpload = function (server, instance) {\n try {\n WhistleOut.SpeedTest.testSpeed(server, false, true, function (result) {\n if (result.uploadSpeed)\n instance.find('span[data-current-upload]').text(result.uploadSpeed);\n if (result.hasErrors && !result.uploadSpeed) {\n Cookies.set('woSpeedTest', null, { path: '/', expires: -1 });\n instance.find('span[data-current-upload]').text('-');\n }\n if (result.isCompleted || result.hasErrors) {\n instance.find('button[data-download-start]').removeAttr('disabled');\n instance.find('span[data-current-upload]').parent().removeClass('c-gray-light');\n instance.find('span[data-current-upload]').prev().addClass('hidden');\n }\n console.log(result);\n });\n } catch (e) {\n displayError(instance);\n }\n };\n\n var testDownload = function (server, instance) {\n try {\n WhistleOut.SpeedTest.testSpeed(server,\n true,\n false,\n function (result) {\n if (result.downloadSpeed)\n instance.find('span[data-current-download]').text(result.downloadSpeed);\n if (result.hasErrors && !result.downloadSpeed) {\n displayError(instance);\n } else if (result.isCompleted || result.hasErrors) {\n var tier = speedTiers.findIndex(function (e) { return e > result.downloadSpeed * 1000; }) + 1;\n instance.find('span[data-current-tier]').removeClass();\n instance.find('span[data-current-tier]').addClass('fa font-10 fa-speed-' + tier);\n instance.find('div[data-stage-progress]').addClass('hidden');\n instance.find('div[data-stage-results]').removeClass('hidden');\n instance.find('span[data-latency]').text(result.latency);\n }\n console.log(result);\n });\n } catch (e) {\n displayError(instance);\n }\n };\n\n var runNdt7Test = function (server, testName, instance) {\n try {\n WhistleOut.SpeedTest.runNdt7Test(server,\n testName,\n instance.find('span[data-current-' + testName + ']'),\n function () {\n if (testName === 'download') {\n instance.find('span[data-current-tier]').removeClass();\n instance.find('div[data-stage-progress]').addClass('hidden');\n instance.find('div[data-stage-results]').removeClass('hidden');\n\n } else {\n instance.find('button[data-download-start]').removeAttr('disabled');\n instance.find('span[data-current-upload]').parent().removeClass('c-gray-light');\n instance.find('span[data-current-upload]').prev().addClass('hidden');\n }\n },\n instance.find('span[data-latency]'));\n } catch (e) {\n displayError(instance);\n }\n };\n\n container.find('button[data-show-more-info]').off('click').on('click', function () {\n var instance = wo$(this).closest('div.speed-test-widget');\n wo$(this).addClass('hidden');\n wo$(this).next().find('div[data-more-info]').collapse('show');\n instance.find('span[data-current-upload]').text('0');\n instance.find('span[data-current-upload]').parent().addClass('c-gray-light');\n instance.find('span[data-current-upload]').prev().removeClass('hidden');\n instance.find('button[data-download-start]').attr('disabled', 'disabled');\n WhistleOut.SpeedTest.getSpeedTestParameters(function (resp) {\n if (resp.protocol === 'ndt7') {\n const result = resp.results[0];\n runNdt7Test(result.urls['wss:///ndt/v7/upload'], 'upload', instance);\n\n } else {\n testUpload(resp.fqdn, instance);\n }\n\n }, function () {\n displayError(instance);\n });\n });\n\n container.find('button[data-download-start]').off('click').on('click', function () {\n var instance = wo$(this).closest('div.speed-test-widget');\n instance.find('button[data-show-more-info]').removeClass('hidden');\n instance.find('div[data-more-info]').collapse('hide');\n instance.find('div[data-stage-error]').addClass('hidden');\n instance.find('div[data-stage-begin]').addClass('hidden');\n instance.find('div[data-stage-results]').addClass('hidden');\n instance.find('div[data-stage-progress]').removeClass('hidden');\n instance.find('span[data-current-download]').text('0');\n WhistleOut.SpeedTest.getSpeedTestParameters(function (resp) {\n if (resp.protocol === 'ndt7') {\n const result = resp.results[0];\n instance.find('span[data-server-location]').text(result.location.city + ', ' + result.location.country);\n runNdt7Test(result.urls['wss:///ndt/v7/download'], 'download', instance);\n\n } else {\n instance.find('span[data-server-location]').text(resp.city + ', ' + resp.country);\n testDownload(resp.fqdn, instance);\n }\n }, function () {\n displayError(instance);\n });\n });\n var speedTestResult = Cookies.get('woSpeedTestResult');\n if (speedTestResult && speedTestResult.length) {\n speedTestResult = JSON.parse(speedTestResult);\n var dateOptions = { year: 'numeric', month: 'long', day: 'numeric' };\n container.find('[data-speed-test-date]')\n .text(new Date(speedTestResult.lastResultDate).toLocaleDateString('en-AU', dateOptions));\n container.find('[data-speed-test-result]').text(speedTestResult.downloadSpeed);\n container.find('[data-last-test]').removeClass('hidden');\n } else {\n container.find('[data-last-test]').addClass('hidden');\n }\n };\n}());\nwo$(function () {\n WhistleOut.SpeedTest.init(wo$('body'));\n});","/* This is an NDT client, written in javascript. It speaks the websocket\n * version of the NDT protocol. The NDT protocol is documented at:\n * https://code.google.com/p/ndt/wiki/NDTProtocol\n */\n/* THIS CODE WAS MODIFIED BY WHISTLEOUT. PLEASE LOOK AT THE FOLLOWING COMMIT HASHES FOR THE CHANGES:\n 7c283d21c9eeeefa576c9c598bf2645560c0f7c7\n 615cb6532e767d4d3649c4043540473dfacdd313\n */\n/*jslint bitwise: true, browser: true, nomen: true, vars: true */\n/*global Uint8Array, WebSocket */\n\n'use strict';\n\nfunction NDTWrapper(server, testsToExecute) {\n var _this = this;\n\n // XXX: include a way to override this\n this.use_web_worker = false;\n\n /* If they have Web Workers, use it to do the NDT test, unless it's Firefox\n * which doesn't support web workers using websockets. This should be\n * migrated into something more sane (e.g. a function that spawns an inline worker that\n * creates a websocket, and returns true/false if that succeeds */\n var isFirefox = typeof InstallTrigger !== 'undefined';\n var supportsWebWorkers = !!window.Worker;\n\n if (supportsWebWorkers) {\n this.use_web_worker = true;\n }\n\n if (isFirefox) {\n this.use_web_worker = false;\n }\n\n this._hostname = server;\n this._testsToExecute = testsToExecute;\n this._port = 'https:' == location.protocol ? 3010 : 3001;\n this._protocol = 'https:' == location.protocol ? 'wss' : 'ws';\n this._path = '/ndt_protocol';\n this._update_interval = 1000;\n\n this.reset();\n}\n\nNDTWrapper.prototype.reset = function () {\n if (this.worker) {\n this.worker.postMessage({\n 'cmd': 'stop'\n });\n\n this.worker = null;\n }\n\n if (this.client) {\n this.client = null;\n }\n\n this._ndt_vars = { 'ClientToServerSpeed': 0, 'ServerToClientSpeed': 0 };\n this._errmsg = '';\n this._status = 'notStarted';\n this._diagnosis = '';\n};\n\nNDTWrapper.prototype.run_test = function () {\n var _this = this;\n\n this.reset();\n\n if (this.use_web_worker) {\n console.log('Generating new worker');\n // 'new Worker()' only accepts absolute paths to script files, so\n // determine the path to the location of the ndt-wrapper.js script, and\n // ndt-wrapper-ww.js should be in the same place.\n var scriptPath = window.location.protocol + '//' + window.location.hostname + '/js/responsive/ndt';\n this.worker = new Worker(scriptPath + '/ndt-wrapper-ww.js');\n this.worker.addEventListener('message', function (e) {\n var msg = e.data;\n switch (msg.cmd) {\n case 'onstart':\n _this.onstart_cb(msg.server);\n break;\n case 'onstatechange':\n _this.onstatechange_cb(msg.state, msg.results);\n break;\n case 'onprogress':\n _this.onprogress_cb(msg.state, msg.results);\n break;\n case 'onfinish':\n _this.onfinish_cb(msg.results);\n break;\n case 'onerror':\n _this.onerror_cb(msg.error_message);\n break;\n }\n }, false);\n\n this.worker.addEventListener('error', function (e) {\n _this.onerror_cb(e.lineno, ' in ', e.filename, ': ', e.message);\n }, false);\n\n this.worker.postMessage({\n 'cmd': 'start',\n 'hostname': this._hostname,\n 'port': this._port,\n 'protocol': this._protocol,\n 'path': this._path,\n 'update_interval': this._update_interval,\n 'testsToExecute': this._testsToExecute\n });\n }\n else {\n this.callbacks = {\n 'onstart': function (server) {\n _this.onstart_cb(server);\n },\n 'onstatechange': function (state, results) {\n _this.onstatechange_cb(state, results);\n },\n 'onprogress': function (state, results) {\n _this.onprogress_cb(state, results);\n },\n 'onfinish': function (passed_results) {\n _this.onfinish_cb(passed_results);\n },\n 'onerror': function (error_message) {\n _this.onerror_cb(error_message);\n }\n };\n\n this.client = new NDTjs(this._hostname, this._port, this._protocol,\n this._path, this.callbacks,\n this._update_interval, this._testsToExecute);\n this.client.startTest();\n }\n};\n\n\nNDTWrapper.prototype.get_status = function () {\n return this._status;\n};\n\nNDTWrapper.prototype.get_diagnosis = function () {\n return this._diagnosis;\n};\n\nNDTWrapper.prototype.get_errmsg = function () {\n return this._errmsg;\n};\n\nNDTWrapper.prototype.get_host = function () {\n return this._hostname;\n};\n\nNDTWrapper.prototype.getNDTvar = function (variable) {\n return this._ndt_vars[variable];\n};\n\nNDTWrapper.prototype.get_PcBuffSpdLimit = function (variable) {\n return Number.NaN;\n};\n\nNDTWrapper.prototype.onstart_cb = function (server) {\n};\n\nNDTWrapper.prototype.onstatechange_cb = function (state, results) {\n if (state === 'running_s2c') {\n this._status = 'Inbound';\n this._ndt_vars['ServerToClientSpeed'] = results['s2cRate'] / 1000;\n }\n else if (state === 'finished_s2c') {\n this._ndt_vars['ServerToClientSpeed'] = results['s2cRate'] / 1000;\n }\n else if (state === 'running_c2s') {\n this._status = 'Outbound';\n }\n else if (state == 'finished_c2s') {\n this._ndt_vars['ClientToServerSpeed'] = results['c2sRate'] / 1000;\n }\n};\n\nNDTWrapper.prototype.onprogress_cb = function (state, results) {\n if (state == 'interval_s2c') {\n this._ndt_vars['ServerToClientSpeed'] = results['s2cRate'] / 1000;\n }\n else if (state === 'interval_c2s') {\n this._ndt_vars['ClientToServerSpeed'] = results['c2sRate'] / 1000;\n }\n};\n\nNDTWrapper.prototype.onfinish_cb = function (results) {\n this._errmsg = \"Test completed\";\n this._ndt_vars = results;\n this._ndt_vars['ServerToClientSpeed'] = results['s2cRate'] / 1000;\n this._ndt_vars['ClientToServerSpeed'] = results['c2sRate'] / 1000;\n this._ndt_vars['Jitter'] = results['MaxRTT'] - results['MinRTT'];\n this.build_diagnosis();\n};\n\nNDTWrapper.prototype.build_diagnosis = function () {\n this._diagnosis = JSON.stringify(this._ndt_vars, null, \" \");\n};\n\nNDTWrapper.prototype.onerror_cb = function (error_message) {\n this._errmsg = \"Test failed: \" + error_message;\n};","/* This is an NDT client, written in javascript. It speaks the websocket\n * version of the NDT protocol. The NDT protocol is documented at:\n * https://code.google.com/p/ndt/wiki/NDTProtocol\n */\n/* THIS CODE WAS MODIFIED BY WHISTLEOUT. PLEASE LOOK AT THE FOLLOWING COMMIT HASHES FOR THE CHANGES:\n 7c283d21c9eeeefa576c9c598bf2645560c0f7c7\n 615cb6532e767d4d3649c4043540473dfacdd313\n */\n/*jslint bitwise: true, browser: true, nomen: true, vars: true, indent: 2 */\n/*global Uint8Array, WebSocket */\n\n'use strict';\n\nfunction NDTjs(server, serverPort, serverProtocol, serverPath, callbacks,\n updateInterval, testsToExecute) {\n this.server = server;\n this.serverPort = serverPort || 3001;\n this.serverPath = serverPath || '/ndt_protocol';\n this.serverProtocol = serverProtocol || 'ws';\n this.updateInterval = updateInterval / 1000.0 || false;\n this.results = {\n c2sRate: undefined,\n s2cRate: undefined\n };\n this.SEND_BUFFER_SIZE = 1048576;\n this.testsToExecute = testsToExecute;\n\n // Someone may want to run this test without callbacks (perhaps for\n // debugging). Since the callbacks are referenced in various places, just\n // create some empty ones if none were specified.\n if (callbacks === undefined) {\n this.callbacks = {\n 'onstart': function () { return false; },\n 'onstatechange': function () { return false; },\n 'onprogress': function () { return false; },\n 'onfinish': function () { return false; },\n 'onerror': function () { return false; },\n };\n } else {\n this.callbacks = callbacks;\n }\n\n // Constants used by the entire program.\n this.COMM_FAILURE = 0;\n this.SRV_QUEUE = 1;\n this.MSG_LOGIN = 2;\n this.TEST_PREPARE = 3;\n this.TEST_START = 4;\n this.TEST_MSG = 5;\n this.TEST_FINALIZE = 6;\n this.MSG_ERROR = 7;\n this.MSG_RESULTS = 8;\n this.MSG_LOGOUT = 9;\n this.MSG_WAITING = 10;\n this.MSG_EXTENDED_LOGIN = 11;\n\n // An array to translate the constants back into strings for debugging.\n this.NDT_MESSAGES = [];\n this.NDT_MESSAGES[this.COMM_FAILURE] = 'COMM_FAILURE';\n this.NDT_MESSAGES[this.SRV_QUEUE] = 'SRV_QUEUE';\n this.NDT_MESSAGES[this.MSG_LOGIN] = 'MSG_LOGIN';\n this.NDT_MESSAGES[this.TEST_PREPARE] = 'TEST_PREPARE';\n this.NDT_MESSAGES[this.TEST_START] = 'TEST_START';\n this.NDT_MESSAGES[this.TEST_MSG] = 'TEST_MSG';\n this.NDT_MESSAGES[this.TEST_FINALIZE] = 'TEST_FINALIZE';\n this.NDT_MESSAGES[this.MSG_ERROR] = 'MSG_ERROR';\n this.NDT_MESSAGES[this.MSG_RESULTS] = 'MSG_RESULTS';\n this.NDT_MESSAGES[this.MSG_LOGOUT] = 'MSG_LOGOUT';\n this.NDT_MESSAGES[this.MSG_WAITING] = 'MSG_WAITING';\n this.NDT_MESSAGES[this.MSG_EXTENDED_LOGIN] = 'MSG_EXTENDED_LOGIN';\n}\n\n/**\n * Provide feedback to the console or the DOM.\n * @param {string} logMessage Message to pass to output mechanism.\n * @param {!boolean=} debugging Optional (may be undefined) Determines whether\n * to output messages or to operate silently.\n */\nNDTjs.prototype.logger = function (logMessage, debugging) {\n debugging = debugging || false;\n if (debugging === true) {\n console.log(logMessage);\n }\n};\n\n/**\n * Check that the browser supports the NDT test.\n * @returns {boolean} Browser supports necessary functions for test client.\n */\nNDTjs.prototype.checkBrowserSupport = function () {\n if (self.WebSocket === undefined && self.MozWebSocket === undefined) {\n throw this.UnsupportedBrowser('No Websockets');\n }\n return true;\n};\n\n/**\n * Makes a login message suitable for sending to the server. The login\n * messages specifies the tests to be run.\n * @param {number} desiredTests The types of tests requested from the server\n * signaled based on a bitwise operation of the test ids.\n * @returns {Uint8Array} NDT login message signalling the desired tests.\n */\nNDTjs.prototype.makeLoginMessage = function (desiredTests) {\n // We must support TEST_STATUS (16) as a 3.5.5+ client, so we make sure\n // test 16 is desired.\n var i,\n loginMessage = 'XXX { \"msg\": \"v3.5.5\", \"tests\": \"' + (desiredTests | 16) +\n '\" }',\n loginData = new Uint8Array(loginMessage.length);\n\n loginData[0] = this.MSG_EXTENDED_LOGIN;\n loginData[1] = 0; // Two bytes to represent packet length\n loginData[2] = loginMessage.length - 3;\n\n for (i = 3; i < loginMessage.length; i += 1) {\n loginData[i] = loginMessage.charCodeAt(i);\n }\n return loginData;\n};\n\n/**\n * A generic message creation system for NDT.\n * (messageType, message body length [2], message body)\n * @params {number} messageType The type of message according to NDT's\n * specification.\n * @params {string} messageContent The message body.\n * @returns {array} An array of bytes suitable for sending on a binary\n * websocket.\n */\nNDTjs.prototype.makeNdtMessage = function (messageType, messageContent) {\n var messageBody, ndtMessage, i;\n\n messageBody = '{ \"msg\": \"' + messageContent + '\" } ';\n ndtMessage = new Uint8Array(messageBody.length + 3);\n ndtMessage[0] = messageType;\n ndtMessage[1] = (messageBody.length >> 8) & 0xFF;\n ndtMessage[2] = messageBody.length & 0xFF;\n\n for (i = 0; i < messageBody.length; i += 1) {\n ndtMessage[i + 3] = messageBody.charCodeAt(i);\n }\n return ndtMessage;\n};\n\n/**\n * Parses messages received from the NDT server.\n * @param {object} buffer The complete message received from the NDT server.\n * @returns {array} Parsed messaged.\n */\nNDTjs.prototype.parseNdtMessage = function (buffer) {\n var i,\n response = [],\n bufferArray = new Uint8Array(buffer),\n message = String.fromCharCode.apply(null,\n new Uint8Array(buffer.slice(3)));\n for (i = 0; i < 3; i += 1) {\n response[i] = bufferArray[i];\n }\n response.push(message);\n return response;\n};\n\n/**\n * Exception related to low-level connectivity failures.\n * @param {string} message Specific failure messages passed in the course of\n * receiving the exception.\n */\nNDTjs.prototype.ConnectionException = function (message) {\n this.logger(message);\n this.callbacks.onerror(message);\n};\n\n/**\n * Exception related to an unsupported browser.\n * @param {string} message Specific failure messages passed in the course of\n * receiving the exception.\n */\nNDTjs.prototype.UnsupportedBrowser = function (message) {\n this.logger(message);\n this.callbacks.onerror(message);\n};\n\n/**\n * Exception related to test failures, such as behavior inconsistent with\n * expectations.\n * @param {string} message Specific failure messages passed in the course of\n * receiving the exception.\n */\nNDTjs.prototype.TestFailureException = function (message) {\n this.logger(message);\n this.callbacks.onerror(message);\n};\n\n/**\n * A simple helper function to create websockets consistently.\n * @param {string} serverAddress The FQDN or IP of the NDT server.\n * @param {Number} serverPort The port expected for the NDT test.\n * @param {string} urlPath The path of the resource to request from NDT.\n * @param {string} protocol The WebSocket protocol to build for.\n * @returns {Websocket} The WebSocket we created;\n */\nNDTjs.prototype.createWebsocket = function (serverProtocol, serverAddress,\n serverPort, urlPath, protocol) {\n var createdWebsocket = new WebSocket(serverProtocol + '://' +\n serverAddress + ':' + serverPort +\n urlPath, protocol);\n createdWebsocket.binaryType = 'arraybuffer';\n return createdWebsocket;\n};\n\n/**\n * A simple helper function to create websockets consistently.\n * @param {string} serverAddress The FQDN or IP of the NDT server.\n * @param {Number} serverPort The port expected for the NDT test.\n * @param {string} urlPath The path of the resource to request from NDT.\n * @param {string} protocol The WebSocket protocol to build for.\n * @returns {Websocket} The WebSocket we created;\n */\nNDTjs.prototype.createBulkWebsocket = function (serverProtocol, serverAddress,\n serverPort, urlPath, protocol) {\n var createdWebsocket = new WebSocket(serverProtocol + '://' +\n serverAddress + ':' + serverPort +\n urlPath, protocol);\n createdWebsocket.binaryType = 'arraybuffer';\n return createdWebsocket;\n};\n\n/**\n * NDT's Client-to-Server (C2S) Upload Test\n * Serves as a closure that will process all messages for the C2S NDT test.\n * @returns {boolean} The test is complete and the closure should no longer\n * be called.\n */\nNDTjs.prototype.ndtC2sTest = function () {\n var serverPort, testConnection, testStart, i,\n dataToSend = new Uint8Array(this.SEND_BUFFER_SIZE),\n that = this,\n state = 'WAIT_FOR_TEST_PREPARE',\n totalSent = 0,\n nextCallback = that.updateInterval,\n keepSendingData,\n connectionOpen = false;\n\n for (i = 0; i < dataToSend.length; i += 1) {\n // All the characters must be printable, and the printable range of\n // ASCII is from 32 to 126. 101 is because we need a prime number.\n dataToSend[i] = 32 + (i * 101) % (126 - 32);\n }\n\n /**\n * The upload function for C2S, encoded as a callback instead of a loop.\n */\n keepSendingData = function () {\n var currentTime = Date.now() / 1000.0;\n if (connectionOpen) {\n // Monitor the buffersize as it sends and refill if it gets too low.\n if (testConnection.bufferedAmount < 8192) {\n testConnection.send(dataToSend);\n totalSent += dataToSend.length;\n }\n if (that.updateInterval && currentTime > (testStart + nextCallback)) {\n that.results.c2sRate = 8 * (totalSent - testConnection.bufferedAmount)\n / 1000 / (currentTime - testStart);\n that.callbacks.onprogress('interval_c2s', that.results);\n nextCallback += that.updateInterval;\n currentTime = Date.now() / 1000.0;\n }\n }\n if (currentTime < testStart + 10) {\n setTimeout(keepSendingData, 0);\n } else {\n return false;\n }\n };\n\n /**\n * The closure that processes messages on the control socket for the\n * C2S test.\n */\n return function (messageType, messageContent) {\n that.logger('CALLED C2S with ' + messageType + ' (' +\n that.NDT_MESSAGES[messageType] + ') ' + messageContent.msg +\n ' in state ' + state);\n if (state === 'WAIT_FOR_TEST_PREPARE' &&\n messageType === that.TEST_PREPARE) {\n that.callbacks.onstatechange('preparing_c2s', that.results);\n // Register the `onopen` handler on websocket in the same event loop cycle\n // so \"keepSendingData\" can begin as soon as the server sends TEST_START.\n serverPort = Number(messageContent.msg);\n testConnection = that.createWebsocket(\n that.serverProtocol, that.server, serverPort, that.serverPath, 'c2s');\n testConnection.onopen = function () {\n connectionOpen = true;\n };\n state = 'WAIT_FOR_TEST_START';\n return false;\n }\n if (state === 'WAIT_FOR_TEST_START' && messageType === that.TEST_START) {\n that.callbacks.onstatechange('running_c2s', that.results);\n testStart = Date.now() / 1000;\n keepSendingData();\n state = 'WAIT_FOR_TEST_MSG';\n return false;\n }\n if (state === 'WAIT_FOR_TEST_MSG' && messageType === that.TEST_MSG) {\n that.results.c2sRate = Number(messageContent.msg);\n that.logger('C2S rate calculated by server: ' + that.results.c2sRate);\n state = 'WAIT_FOR_TEST_FINALIZE';\n return false;\n }\n if (state === 'WAIT_FOR_TEST_FINALIZE' &&\n messageType === that.TEST_FINALIZE) {\n that.callbacks.onstatechange('finished_c2s', that.results);\n state = 'DONE';\n return true;\n }\n that.logger('C2S: State = ' + state + ' type = ' + messageType + '(' +\n that.NDT_MESSAGES[messageType] + ') message = ', messageContent);\n };\n};\n\n/**\n * NDT's Server-to-Client (S2C) Download Test\n * Serves as a closure that will process all messages for the S2C NDT test.\n * @param {Websocket} ndtSocket A websocket connection to the NDT server.\n * @returns {boolean} The test is complete and the closure should no longer\n * be called.\n */\nNDTjs.prototype.ndtS2cTest = function (ndtSocket) {\n var serverPort, testConnection, testStart, testEnd, errorMessage,\n state = 'WAIT_FOR_TEST_PREPARE',\n receivedBytes = 0,\n nextCallback = this.updateInterval,\n that = this;\n\n /**\n * The closure that processes messages on the control socket for the\n * C2S test.\n */\n return function (messageType, messageContent) {\n that.logger('CALLED S2C with ' + messageType + ' (' +\n that.NDT_MESSAGES[messageType] + ') in state ' + state);\n if (state === 'WAIT_FOR_TEST_PREPARE' &&\n messageType === that.TEST_PREPARE) {\n that.callbacks.onstatechange('preparing_s2c', that.results);\n serverPort = Number(messageContent.msg);\n testConnection = that.createWebsocket(that.serverProtocol, that.server,\n serverPort, that.serverPath, 's2c');\n testConnection.onopen = function () {\n that.logger('Successfully opened S2C test connection.');\n testStart = Date.now() / 1000;\n };\n testConnection.onmessage = function (response) {\n var hdrSize,\n currentTime;\n if (response.data.byteLength < 126) {\n hdrSize = 2;\n } else if (response.data.byteLength < 65536) {\n hdrSize = 4;\n } else {\n hdrSize = 10;\n }\n receivedBytes += (hdrSize + response.data.byteLength);\n currentTime = Date.now() / 1000.0;\n if (that.updateInterval && currentTime > (testStart + nextCallback)) {\n that.results.s2cRate = 8 * receivedBytes / 1000\n / (currentTime - testStart);\n that.callbacks.onprogress('interval_s2c', that.results);\n nextCallback += that.updateInterval;\n currentTime = Date.now() / 1000.0;\n }\n };\n\n testConnection.onerror = function (response) {\n errorMessage = that.parseNdtMessage(response.data)[3].msg;\n throw that.TestFailureException(errorMessage);\n };\n\n state = 'WAIT_FOR_TEST_START';\n return false;\n }\n if (state === 'WAIT_FOR_TEST_START' && messageType === that.TEST_START) {\n that.callbacks.onstatechange('running_s2c', that.results);\n\n state = 'WAIT_FOR_FIRST_TEST_MSG';\n return false;\n }\n if (state === 'WAIT_FOR_FIRST_TEST_MSG' && messageType === that.TEST_MSG) {\n that.logger('Got message: ' + JSON.stringify(messageContent));\n state = 'WAIT_FOR_TEST_MSG_OR_TEST_FINISH';\n\n if (testEnd === undefined) {\n testEnd = Date.now() / 1000;\n }\n // Calculation per spec, compared between client and server\n // understanding.\n that.results.s2cRate = 8 * receivedBytes / 1000 / (testEnd - testStart);\n that.logger('S2C rate calculated by client: ' + that.results.s2cRate);\n that.logger('S2C rate calculated by server: ' +\n messageContent.ThroughputValue);\n ndtSocket.send(that.makeNdtMessage(that.TEST_MSG,\n String(that.results.s2cRate)));\n return false;\n }\n if (state === 'WAIT_FOR_TEST_MSG_OR_TEST_FINISH' &&\n messageType === that.TEST_MSG) {\n var web100Record = messageContent.msg.split(': '),\n web100Variable = web100Record[0],\n web100Result = web100Record[1].trim();\n that.results[web100Variable] = web100Result;\n return false;\n }\n if (state === 'WAIT_FOR_TEST_MSG_OR_TEST_FINISH' &&\n messageType === that.TEST_FINALIZE) {\n that.callbacks.onstatechange('finished_s2c', that.results);\n that.logger('NDT S2C test is complete: ' + messageContent.msg);\n return true;\n }\n that.logger('S2C: State = ' + state + ' type = ' + messageType + '(' +\n that.NDT_MESSAGES[messageType] + ') message = ', messageContent);\n };\n};\n\n/**\n * NDT's META (S2C) Download Test\n * Serves as a closure that will process all messages for the META NDT test,\n * which provides additional data to the NDT results.\n * @param {Websocket} ndtSocket A websocket connection to the NDT server.\n * @returns {boolean} The test is complete and the closure should no longer\n * be called.\n */\nNDTjs.prototype.ndtMetaTest = function (ndtSocket) {\n var errorMessage,\n that = this,\n state = 'WAIT_FOR_TEST_PREPARE';\n\n return function (messageType, messageContent) {\n if (state === 'WAIT_FOR_TEST_PREPARE' &&\n messageType === that.TEST_PREPARE) {\n that.callbacks.onstatechange('preparing_meta', that.results);\n state = 'WAIT_FOR_TEST_START';\n return false;\n }\n if (state === 'WAIT_FOR_TEST_START' && messageType === that.TEST_START) {\n that.callbacks.onstatechange('running_meta', that.results);\n // Send one piece of meta data and then an empty meta data packet\n ndtSocket.send(that.makeNdtMessage(that.TEST_MSG,\n 'client.os.name:NDTjs'));\n ndtSocket.send(that.makeNdtMessage(that.TEST_MSG, ''));\n state = 'WAIT_FOR_TEST_FINALIZE';\n return false;\n }\n if (state === 'WAIT_FOR_TEST_FINALIZE' &&\n messageType === that.TEST_FINALIZE) {\n that.callbacks.onstatechange('finished_meta', that.results);\n that.logger('NDT META test complete.');\n return true;\n }\n errorMessage = 'Bad state and message combo for META test: ' +\n state + ', ' + messageType + ', ' + messageContent.msg;\n throw that.TestFailureException(errorMessage);\n };\n};\n\n/**\n * Start a series of NDT tests.\n **/\nNDTjs.prototype.startTest = function () {\n var ndtSocket, activeTest, state, errorMessage, i,\n testsToRun = [],\n that = this;\n\n this.checkBrowserSupport();\n this.logger('Test started. Waiting for connection to server...');\n this.callbacks.onstart(this.server);\n ndtSocket = this.createWebsocket(this.serverProtocol, this.server,\n this.serverPort, this.serverPath, 'ndt');\n\n /** When the NDT control socket is opened, send a message requesting a\n * TEST_S2C, TEST_C2S, and TEST_META.\n */\n ndtSocket.onopen = function () {\n that.logger('Opened connection on port ' + that.serverPort);\n // Sign up for every test except for TEST_MID and TEST_SFW - browsers can't\n // open server sockets, which makes those tests impossible, because they\n // require the server to open a connection to a port on the client.\n ndtSocket.send(that.makeLoginMessage(that.testsToExecute));\n state = 'LOGIN_SENT';\n };\n\n /** Process a message received on the NDT control socket. The message should\n * be handed off to the active test (if any), or processed directly if there\n * is no active test.\n */\n ndtSocket.onmessage = function (response) {\n var tests,\n message = that.parseNdtMessage(response.data),\n messageType = message[0],\n messageContent = JSON.parse(message[3]);\n\n that.logger('type = ' + messageType + ' (' +\n that.NDT_MESSAGES[messageType] + ') body = \"' +\n messageContent.msg + '\"');\n if (activeTest === undefined && testsToRun.length > 0) {\n activeTest = testsToRun.pop();\n }\n if (activeTest !== undefined) {\n // Pass the message to the sub-test\n that.logger('Calling a subtest');\n if (activeTest(messageType, messageContent) === true) {\n activeTest = undefined;\n that.logger('Subtest complete');\n }\n return;\n }\n\n // If there is an active test, hand off control to the test\n // Otherwise, move the coordinator state forwards.\n if (state === 'LOGIN_SENT') {\n // Response to NDT_LOGIN should be SRV_QUEUE messages until we\n // get SRV_QUEUE('0')\n if (messageType === that.SRV_QUEUE) {\n if (messageContent.msg === '9990') {\n // Connection keepalive message\n ndtSocket.send(that.makeNdtMessage(that.MSG_WAITING, ''));\n } else if (messageContent.msg === '9977') {\n // Test failed, leave now.\n throw that.TestFailureException('Server terminated test ' +\n 'with SRV_QUEUE 9977');\n }\n that.logger('Got SRV_QUEUE. Ignoring and waiting for ' +\n 'MSG_LOGIN.');\n } else if (messageType === that.MSG_LOGIN) {\n if (messageContent.msg[0] !== 'v') {\n that.logger('Bad msg ' + messageContent.msg);\n }\n state = 'WAIT_FOR_TEST_IDS';\n } else {\n errorMessage = 'Expected type 1 (SRV_QUEUE) or 2 (MSG_LOGIN)' +\n 'but got ' + messageType + ' (' +\n that.NDT_MESSAGES[messageType] + ')';\n throw that.TestFailureException(errorMessage);\n }\n } else if (state === 'WAIT_FOR_TEST_IDS' &&\n messageType === that.MSG_LOGIN) {\n tests = messageContent.msg.split(' ');\n for (i = tests.length - 1; i >= 0; i -= 1) {\n if (tests[i] === '2') {\n testsToRun.push(that.ndtC2sTest());\n } else if (tests[i] === '4') {\n testsToRun.push(that.ndtS2cTest(ndtSocket));\n } else if (tests[i] === '32') {\n testsToRun.push(that.ndtMetaTest(ndtSocket));\n } else if (tests[i] !== '') {\n errorMessage = 'Unknown test type: ' + tests[i];\n throw that.TestFailureException(errorMessage);\n }\n }\n state = 'WAIT_FOR_MSG_RESULTS';\n } else if (state === 'WAIT_FOR_MSG_RESULTS' &&\n messageType === that.MSG_RESULTS) {\n that.logger(messageContent);\n var lines = messageContent.msg.split('\\n');\n for (i = 0; i < lines.length; i++) {\n var line = lines[i];\n var record = line.split(': ');\n var variable = record[0];\n var result = record[1];\n that.results[variable] = result;\n }\n } else if (state === 'WAIT_FOR_MSG_RESULTS' &&\n messageType === that.MSG_LOGOUT) {\n ndtSocket.close();\n that.callbacks.onstatechange('finished_all', that.results);\n that.callbacks.onfinish(that.results);\n that.logger('All tests successfully completed.');\n } else {\n errorMessage = 'No handler for message ' + messageType +\n ' in state ' + state;\n throw that.TestFailureException(errorMessage);\n }\n };\n\n ndtSocket.onerror = function (response) {\n errorMessage = that.parseNdtMessage(response.data)[3].msg;\n throw that.TestFailureException(errorMessage);\n };\n};","/* jshint esversion: 6, asi: true */\n// ndt7core is a simple ndt7 client API.\nconst ndt7core = (function () {\n return {\n // run runs the specified test with the specified base URL and calls\n // callback to notify the caller of ndt7 events.\n run: function (baseURL, testName, callback) {\n callback('starting', { Origin: 'client', Test: testName });\n let done = false;\n\n const worker = testName === 'download'\n ? new Worker(new URL('./ndt7-download.js', import.meta.url))\n : new Worker(new URL('./ndt7-upload.js', import.meta.url));\n\n function finish() {\n if (!done) {\n done = true;\n if (callback !== undefined) {\n callback('complete', { Origin: 'client', Test: testName });\n }\n }\n }\n worker.onmessage = function (ev) {\n if (ev.data === null) {\n finish();\n return;\n }\n callback('measurement', ev.data);\n }\n // Kill the worker after the timeout. This force the browser to\n // close the WebSockets and prevent too-long tests.\n setTimeout(function () {\n worker.terminate();\n finish();\n }, 10000)\n worker.postMessage({\n href: baseURL,\n })\n }\n }\n}())","var ___EXPOSE_LOADER_IMPORT___ = require(\"-!../../../../node_modules/.pnpm/exports-loader@4.0.0_webpack@5.74.0/node_modules/exports-loader/dist/cjs.js?exports=NDTjs!../../../../node_modules/.pnpm/babel-loader@8.2.5_@babel+core@7.20.2_webpack@5.74.0/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!./ndt-browser-client.js\");\nvar ___EXPOSE_LOADER_GET_GLOBAL_THIS___ = require(\"../../../../node_modules/.pnpm/expose-loader@4.0.0_webpack@5.74.0/node_modules/expose-loader/dist/runtime/getGlobalThis.js\");\nvar ___EXPOSE_LOADER_GLOBAL_THIS___ = ___EXPOSE_LOADER_GET_GLOBAL_THIS___;\nvar ___EXPOSE_LOADER_IMPORT_MODULE_LOCAL_NAME___ = ___EXPOSE_LOADER_IMPORT___.override\nif (typeof ___EXPOSE_LOADER_GLOBAL_THIS___[\"NDTjs\"] === 'undefined') ___EXPOSE_LOADER_GLOBAL_THIS___[\"NDTjs\"] = ___EXPOSE_LOADER_IMPORT_MODULE_LOCAL_NAME___;\nmodule.exports = ___EXPOSE_LOADER_IMPORT___;\n"],"names":["WhistleOut","SpeedTest","canUseNdt7","eval","e","isSafari","test","navigator","userAgent","getSpeedTestParameters","successCallback","failedCallback","useNdt7","getSiteConfiguration","useNdt7Protocol","mlabNsService","mlabNsUrl","location","protocol","wo$","ajax","url","dataType","success","resp","error","jqXHR","errStatus","errText","testSpeed","server","testDownloadSpeed","testUploadSpeed","callback","client","getNumber","value","isNaN","getJustfiedSpeed","speedInKB","Math","floor","log","fixedNum","pow","toFixed","testsToExecute","NDTWrapper","run_test","refreshSpeed","message","get_errmsg","status","get_status","isCompleted","hasErrors","length","latency","getNDTvar","result","uploadSpeedDone","uploadSpeed","updateUploadSpeeds","downloadSpeed","updateDownloadSpeeds","lastResultDate","Date","Cookies","set","JSON","stringify","path","expires","event","type","detail","sender","this","trigger","setTimeout","runNdt7Test","testName","instance","latencyInstance","ndt7core","ev","val","undefined","AppInfo","Origin","appInfo","elapsed","ElapsedTime","speed","NumBytes","text","updateView","TCPInfo","tcpInfo","MinRTT","round","updateLatency","first","init","parent","container","find","speedTiers","data","displayError","addClass","removeClass","removeAttr","prev","off","on","closest","next","collapse","attr","results","urls","testUpload","fqdn","city","country","tier","findIndex","testDownload","speedTestResult","get","parse","toLocaleDateString","year","month","day","use_web_worker","isFirefox","InstallTrigger","window","Worker","_hostname","_testsToExecute","_port","_protocol","_path","_update_interval","reset","prototype","worker","postMessage","_ndt_vars","_errmsg","_status","_diagnosis","_this","scriptPath","hostname","addEventListener","msg","cmd","onstart_cb","onstatechange_cb","state","onprogress_cb","onfinish_cb","onerror_cb","error_message","lineno","filename","callbacks","passed_results","NDTjs","startTest","get_diagnosis","get_host","variable","get_PcBuffSpdLimit","Number","NaN","build_diagnosis","serverPort","serverProtocol","serverPath","updateInterval","c2sRate","s2cRate","SEND_BUFFER_SIZE","COMM_FAILURE","SRV_QUEUE","MSG_LOGIN","TEST_PREPARE","TEST_START","TEST_MSG","TEST_FINALIZE","MSG_ERROR","MSG_RESULTS","MSG_LOGOUT","MSG_WAITING","MSG_EXTENDED_LOGIN","NDT_MESSAGES","logger","logMessage","debugging","checkBrowserSupport","self","WebSocket","MozWebSocket","UnsupportedBrowser","makeLoginMessage","desiredTests","i","loginMessage","loginData","Uint8Array","charCodeAt","makeNdtMessage","messageType","messageContent","messageBody","ndtMessage","parseNdtMessage","buffer","response","bufferArray","String","fromCharCode","apply","slice","push","ConnectionException","onerror","TestFailureException","createWebsocket","serverAddress","urlPath","createdWebsocket","binaryType","createBulkWebsocket","ndtC2sTest","testConnection","testStart","keepSendingData","dataToSend","that","totalSent","nextCallback","connectionOpen","currentTime","now","bufferedAmount","send","onprogress","onstatechange","onopen","ndtS2cTest","ndtSocket","testEnd","errorMessage","receivedBytes","onmessage","hdrSize","byteLength","ThroughputValue","web100Record","split","web100Variable","web100Result","trim","ndtMetaTest","activeTest","testsToRun","onstart","tests","pop","lines","record","close","onfinish","run","baseURL","Test","done","URL","finish","terminate","href","___EXPOSE_LOADER_IMPORT___","___EXPOSE_LOADER_GLOBAL_THIS___","___EXPOSE_LOADER_IMPORT_MODULE_LOCAL_NAME___","override","module","exports"],"sourceRoot":""}