{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./node_modules/@babel/runtime/regenerator/index.js","webpack:///./app/javascript/packs/message_format.js","webpack:///./app/javascript/packs/data_interpretation.js","webpack:///./node_modules/regenerator-runtime/runtime.js","webpack:///./app/javascript/packs/cloud_helper.js","webpack:///./app/javascript/packs/topic.js","webpack:///./app/javascript/packs/topic_auto_refresher.js","webpack:///./app/javascript/packs/topic_messages_retriever.js","webpack:///./app/javascript/packs/regression_calculator.js","webpack:///./app/javascript/packs/topic_map.js","webpack:///./app/javascript/packs/chart_toggler.js","webpack:///./app/javascript/packs/topic_time_tool.js","webpack:///./app/javascript/packs/json2csv.js","webpack:///./app/javascript/packs/scs_logger.js","webpack:///./app/javascript/packs/scs_config.js","webpack:///./app/javascript/packs/message.js","webpack:///./app/javascript/packs/message_value.js","webpack:///./app/javascript/packs/message_collections.js","webpack:///./app/javascript/packs/message_processor.js","webpack:///./app/javascript/packs/graph.js","webpack:///./app/javascript/packs/time_helper.js","webpack:///./app/javascript/packs/config/valueLabels.js","webpack:///./app/javascript/packs/application.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","MessageFormat","message","undefined","ver","isNaN","parseFloat","DataInterpretation","sensor","dataInterpretationName","App","Topic","showReported","getDataInterpretationName","this","dataInterpretationPresentForSensor","reportedDataInterpretationName","dataInterpretation","keys","processedMessages","length","dataInterpretations","lastMessage","concat","valuesPresent","ii","messagesWithTimestamps","models","highestPriorityDataInterpretationName","modelsPresent","version","exg","src","modelsToDisplay","includes","highestPriorityModelName","document","getElementById","textContent","runtime","Op","hasOwn","$Symbol","iteratorSymbol","iterator","asyncIteratorSymbol","asyncIterator","toStringTagSymbol","define","obj","configurable","writable","err","wrap","innerFn","outerFn","self","tryLocsList","protoGenerator","Generator","generator","context","Context","_invoke","state","GenStateSuspendedStart","method","arg","GenStateExecuting","Error","GenStateCompleted","doneResult","delegate","delegateResult","maybeInvokeDelegate","ContinueSentinel","sent","_sent","dispatchException","abrupt","record","tryCatch","type","done","GenStateSuspendedYield","makeInvokeMethod","fn","GeneratorFunction","GeneratorFunctionPrototype","IteratorPrototype","getProto","getPrototypeOf","NativeIteratorPrototype","values","Gp","defineIteratorMethods","forEach","AsyncIterator","PromiseImpl","invoke","resolve","reject","result","__await","then","unwrapped","error","previousPromise","callInvokeWithMethodAndArg","TypeError","info","resultName","next","nextLoc","pushTryEntry","locs","entry","tryLoc","catchLoc","finallyLoc","afterLoc","tryEntries","push","resetTryEntry","completion","reset","iterable","iteratorMethod","displayName","isGeneratorFunction","genFun","ctor","constructor","mark","setPrototypeOf","__proto__","awrap","async","Promise","iter","reverse","pop","skipTempReset","prev","charAt","slice","stop","rootRecord","rval","exception","handle","loc","caught","hasCatch","hasFinally","finallyEntry","complete","finish","thrown","delegateYield","regeneratorRuntime","accidentalStrictMode","globalThis","Function","CloudHelper","whatDataInterpretationIsBeingDisplayed","nearestUp","valueLabels","maxValue","Graph","maxYValue","minMax","sensorName","readings","minValue","MessageCollections","getMinValueForSensor","startsWith","graphMinY","parseInt","split","style","display","interval","TopicAutoRefresher","refreshInterval","topic","timeStamps","oldStartDate","oldEndDate","newStartDate","moment","messageTimeFormatString","add","toISOString","newEndDate","Date","a","setMessagesDuration","retriever","TopicMessagesRetriever","retrieveMessages","messages","MessageProcessor","processMessages","data","Items","allMessages","setTrimTime","trimProcessedMessages","TopicTimeTool","setStartDate","setStartDatePicker","setEndDate","setEndDatePicker","gauges","querySelectorAll","displayGaugesFlag","displayGraphs","isAStatusTopic","displayMap","constructAndDisplayShareableUrl","fetchedLastWrittenData","stopRefreshing","querySelector","getAttribute","isAwsOrg","awsApiDomain","encodeURIComponent","apiDomain","getDataInterpretationNames","getTime","trimBeforeTime","splice","e","console","log","aKey","messagesDuration","trimDuration","mostRecentMessageTime","apiUri","startTime","endTime","timeout","ScsConfig","connectionTimeout","apiKey","axios","defaults","headers","common","urlToCall","request","url","response","RegressionCalculator","x","arrayed","regression","linear","order","precision","slopeValue","equation","Math","round","predict","sensorData","TopicMap","long","lat","mapContainer","container","className","deviceMessage","hasValidGpsData","coords","lng","map","google","maps","Map","zoom","center","mapTypeId","Marker","position","height","ChartToggler","toggler","dataset","charttype","isPressed","graphs","Array","gauge","graph","setAttribute","cookie","wideGraphs","wideGraph","expiryDate","now","toUTCString","g","draw","aValue","startDate","$","date","datetimepicker","children","val","format","endDate","Json2Csv","checkpoint","json","headerPrefix","getHeaders","lastBit","tag","removeMillisecondsRegex","removeSemiColonsRegex","replace","fileName","aggregationFileSuffix","row","header","keyPart","rows","messageCsvRow","readData","csv","csvHeaders","genereateCsvRows","isAwsOrganisation","uri","messagesForTopic","showModal","TESTING","hideModal","csvContent","generateCsv","buildFilename","rec","downloadCsv","code","logger","ScsLogger","user","content","mimeType","createElement","navigator","msSaveBlob","Blob","URL","href","createObjectURL","body","appendChild","click","removeChild","location","uuid","uuidv4","counter","crypto","getRandomValues","Uint8Array","toString","post","service","loggedAt","Message","MessageValue","isSimplesensorName","sensorValue","floor","random","dataPath","getValue","isSimpleValue","DEBUG","getUrlParameter","randomlyNullify","reduce","indexObject","results","RegExp","exec","search","decodeURIComponent","timeStamp","initialiseSensorCollection","pwrInReadings","entries","pwrInMax","max","apply","prottBattReadings","prottBattMax","isASHT","hdmReadings","tmpReadings","maxes","subPart","mins","min","flat","average","rawMessages","topicInterval","initialiseProcessedMessages","initialiseDataInterpretation","averages","valueFor","processMessage","assign","calculateAverage","firstMessage","buildProcessedMessage","addMessageToCollection","lastMessageTimestamp","messageInterval","messageTimeDifference","padMessages","valueInterval","nextMessage","firstMessageTimeRecieved","lastMessageTimeRecieved","collection","timestamp","message1","message2","intervalSeconds","howMany","nextTimeStamp","maxReading","times","currentSegment","sum","time1","performance","chartsDiv","hasChildNodes","lastChild","displayValueGraph","displayUptimeNumber","gpsQualityDisplay","time2","getElementsByClassName","toFixed","lastWrittenDataDetected","alert","constructAndDisplayCSVlink","chart_div","getChartContainer","graph_div","getGraphDiv","charts_div","visualization","DataTable","setGraphColumns","ComboChart","chartDataSet","constructGraphDatasetRow","addRows","options","graphOptions","dateFormatter","DateFormat","pattern","chartWrapper","ChartWrapper","chartType","dataTable","containerId","showDataInterpretationName","remove","addColumn","missingModelData","title","seriesType","series","targetAxisIndex","color","vAxes","viewWindowMode","viewWindow","hAxis","Labels","longLabelForValue","lineWidth","visibleInLegend","calculateLineColour","getMaxYValue","getMinYValue","graphTitle","lineNumber","defaultColourForSensor","unshift","rowData","getMaxValueForSensor","ceil","regressionCalculator","yValue","predictY","getMidPoint","arrayToDataTable","width","minorTicks","gauge_div","gauges_div","Gauge","gaugeValue","innerHTML","gaugeContainer","outerContainer","graphContainer","inlineGaugeContainer","roundUpTo","TimeHelper","minutes","subtract","NO2","label","longLabel","unit","colour","NO","Ox","O2","SO2","H2S","CO","CO2","VOC","pt1","hmd","tmp","internalTmp","pA","maxY","minY","pm1","pm2p5","pm10","sfr","up","psu","sht","sig","graphMaxY","window","addEventListener","event","URLSearchParams","substring"],"mappings":"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","file":"js/application-895908f579cdb2648145.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/packs/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 22);\n","module.exports = require(\"regenerator-runtime\");\n","class MessageFormat {\n constructor() {}\n\n static version(message) {\n if(message.ver == undefined){\n return 0;\n }\n if(isNaN(parseFloat(message.ver))){\n return 0\n }\n return parseFloat(message.ver);\n }\n}\nexport default MessageFormat;\n","\"use strict\";\n\nimport MessageFormat from \"./message_format\";\n\nclass DataInterpretation {\n static reportedDataInterpretationName = 'reported';\n static highestPriorityModelName = 's1/2020h1';\n\n static whatDataInterpretationIsBeingDisplayed(sensor){\n let dataInterpretationName = '';\n if(App.Topic.showReported){\n dataInterpretationName = 'reported';\n } else {\n dataInterpretationName = DataInterpretation.getDataInterpretationName();\n }\n if(this.dataInterpretationPresentForSensor(sensor, dataInterpretationName)){\n return dataInterpretationName;\n } else {\n return DataInterpretation.reportedDataInterpretationName;\n }\n }\n\n static dataInterpretationPresentForSensor(sensor, dataInterpretation){\n if(Object.keys(App.Topic.processedMessages[sensor][dataInterpretation]['readings']).length == 0){\n return false;\n } else {\n return true;\n }\n }\n\n static getInterpretationsPresent() {\n App.Topic.dataInterpretations = [DataInterpretation.reportedDataInterpretationName];\n if (App.Topic.lastMessage[\"exg\"] != undefined) {\n // if the format is v2.0 then get the name from exg.src\n // else do it the normal way\n App.Topic.dataInterpretations = App.Topic.dataInterpretations.concat(\n Object.keys(App.Topic.lastMessage[\"exg\"])\n );\n }\n \n //now initialise messagesWithTimestamps which is used by gauges.\n for (var i = 0; i < App.Topic.valuesPresent.length; i++) {\n let value = App.Topic.valuesPresent[i];\n for (var ii = 0; ii < App.Topic.dataInterpretations.length; ii++) {\n var dataInterpretation = App.Topic.dataInterpretations[ii];\n App.Topic.messagesWithTimestamps[value][dataInterpretation] = [];\n }\n }\n\n // now construct models that should be used in the graphs.\n let models = [DataInterpretation.reportedDataInterpretationName];\n if(App.Topic.dataInterpretations.length == 1){\n return models;\n }\n models.concat(DataInterpretation.highestPriorityDataInterpretationName());\n return models;\n \n }\n\n static setInterpretationsPresent() {\n let modelsPresent = ['reported'];\n if (App.Topic.lastMessage != undefined && App.Topic.lastMessage[\"exg\"] != undefined) {\n if(MessageFormat.version(App.Topic.lastMessage) < 2.0){\n modelsPresent = modelsPresent.concat(\n Object.keys(App.Topic.lastMessage[\"exg\"])\n );\n } else {\n modelsPresent = modelsPresent.concat(\n App.Topic.lastMessage.exg.src\n );\n } \n }\n\n let modelsToDisplay = [DataInterpretation.reportedDataInterpretationName];\n if(modelsPresent.length > 1){\n modelsToDisplay = modelsToDisplay.concat(DataInterpretation.highestPriorityDataInterpretationName(modelsPresent));\n }\n\n //now initialise messagesWithTimestamps which is used by gauges.\n for (var i = 0; i < App.Topic.valuesPresent.length; i++) {\n let value = App.Topic.valuesPresent[i];\n for (var ii = 0; ii < modelsToDisplay.length; ii++) {\n let dataInterpretation = modelsToDisplay[ii];\n App.Topic.messagesWithTimestamps[value][dataInterpretation] = [];\n }\n }\n \n App.Topic.dataInterpretations = modelsToDisplay;\n }\n\n static highestPriorityDataInterpretationName(models){\n if(models.length == 1){\n return models[0];\n } else if(models.includes(DataInterpretation.highestPriorityModelName)){\n return DataInterpretation.highestPriorityModelName;\n } else {\n return models[models.length - 1]\n }\n }\n\n static getDataInterpretationName(){\n if(App.Topic.dataInterpretations.length > 1){\n return App.Topic.dataInterpretations[App.Topic.dataInterpretations.length - 1];\n } else {\n return 'reported'\n }\n }\n\n static showDataInterpretationName(){ \n let dataInterpretationName = DataInterpretation.getDataInterpretationName();\n if(dataInterpretationName != undefined){\n document.getElementById(\"data_interpretation_name\").textContent = 'Interpretation: '+dataInterpretationName; \n }\n }\n}\nexport default DataInterpretation;\n","/**\n * Copyright (c) 2014-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nvar runtime = (function (exports) {\n \"use strict\";\n\n var Op = Object.prototype;\n var hasOwn = Op.hasOwnProperty;\n var undefined; // More compressible than void 0.\n var $Symbol = typeof Symbol === \"function\" ? Symbol : {};\n var iteratorSymbol = $Symbol.iterator || \"@@iterator\";\n var asyncIteratorSymbol = $Symbol.asyncIterator || \"@@asyncIterator\";\n var toStringTagSymbol = $Symbol.toStringTag || \"@@toStringTag\";\n\n function define(obj, key, value) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n return obj[key];\n }\n try {\n // IE 8 has a broken Object.defineProperty that only works on DOM objects.\n define({}, \"\");\n } catch (err) {\n define = function(obj, key, value) {\n return obj[key] = value;\n };\n }\n\n function wrap(innerFn, outerFn, self, tryLocsList) {\n // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.\n var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;\n var generator = Object.create(protoGenerator.prototype);\n var context = new Context(tryLocsList || []);\n\n // The ._invoke method unifies the implementations of the .next,\n // .throw, and .return methods.\n generator._invoke = makeInvokeMethod(innerFn, self, context);\n\n return generator;\n }\n exports.wrap = wrap;\n\n // Try/catch helper to minimize deoptimizations. Returns a completion\n // record like context.tryEntries[i].completion. This interface could\n // have been (and was previously) designed to take a closure to be\n // invoked without arguments, but in all the cases we care about we\n // already have an existing method we want to call, so there's no need\n // to create a new function object. We can even get away with assuming\n // the method takes exactly one argument, since that happens to be true\n // in every case, so we don't have to touch the arguments object. The\n // only additional allocation required is the completion record, which\n // has a stable shape and so hopefully should be cheap to allocate.\n function tryCatch(fn, obj, arg) {\n try {\n return { type: \"normal\", arg: fn.call(obj, arg) };\n } catch (err) {\n return { type: \"throw\", arg: err };\n }\n }\n\n var GenStateSuspendedStart = \"suspendedStart\";\n var GenStateSuspendedYield = \"suspendedYield\";\n var GenStateExecuting = \"executing\";\n var GenStateCompleted = \"completed\";\n\n // Returning this object from the innerFn has the same effect as\n // breaking out of the dispatch switch statement.\n var ContinueSentinel = {};\n\n // Dummy constructor functions that we use as the .constructor and\n // .constructor.prototype properties for functions that return Generator\n // objects. For full spec compliance, you may wish to configure your\n // minifier not to mangle the names of these two functions.\n function Generator() {}\n function GeneratorFunction() {}\n function GeneratorFunctionPrototype() {}\n\n // This is a polyfill for %IteratorPrototype% for environments that\n // don't natively support it.\n var IteratorPrototype = {};\n define(IteratorPrototype, iteratorSymbol, function () {\n return this;\n });\n\n var getProto = Object.getPrototypeOf;\n var NativeIteratorPrototype = getProto && getProto(getProto(values([])));\n if (NativeIteratorPrototype &&\n NativeIteratorPrototype !== Op &&\n hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {\n // This environment has a native %IteratorPrototype%; use it instead\n // of the polyfill.\n IteratorPrototype = NativeIteratorPrototype;\n }\n\n var Gp = GeneratorFunctionPrototype.prototype =\n Generator.prototype = Object.create(IteratorPrototype);\n GeneratorFunction.prototype = GeneratorFunctionPrototype;\n define(Gp, \"constructor\", GeneratorFunctionPrototype);\n define(GeneratorFunctionPrototype, \"constructor\", GeneratorFunction);\n GeneratorFunction.displayName = define(\n GeneratorFunctionPrototype,\n toStringTagSymbol,\n \"GeneratorFunction\"\n );\n\n // Helper for defining the .next, .throw, and .return methods of the\n // Iterator interface in terms of a single ._invoke method.\n function defineIteratorMethods(prototype) {\n [\"next\", \"throw\", \"return\"].forEach(function(method) {\n define(prototype, method, function(arg) {\n return this._invoke(method, arg);\n });\n });\n }\n\n exports.isGeneratorFunction = function(genFun) {\n var ctor = typeof genFun === \"function\" && genFun.constructor;\n return ctor\n ? ctor === GeneratorFunction ||\n // For the native GeneratorFunction constructor, the best we can\n // do is to check its .name property.\n (ctor.displayName || ctor.name) === \"GeneratorFunction\"\n : false;\n };\n\n exports.mark = function(genFun) {\n if (Object.setPrototypeOf) {\n Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);\n } else {\n genFun.__proto__ = GeneratorFunctionPrototype;\n define(genFun, toStringTagSymbol, \"GeneratorFunction\");\n }\n genFun.prototype = Object.create(Gp);\n return genFun;\n };\n\n // Within the body of any async function, `await x` is transformed to\n // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test\n // `hasOwn.call(value, \"__await\")` to determine if the yielded value is\n // meant to be awaited.\n exports.awrap = function(arg) {\n return { __await: arg };\n };\n\n function AsyncIterator(generator, PromiseImpl) {\n function invoke(method, arg, resolve, reject) {\n var record = tryCatch(generator[method], generator, arg);\n if (record.type === \"throw\") {\n reject(record.arg);\n } else {\n var result = record.arg;\n var value = result.value;\n if (value &&\n typeof value === \"object\" &&\n hasOwn.call(value, \"__await\")) {\n return PromiseImpl.resolve(value.__await).then(function(value) {\n invoke(\"next\", value, resolve, reject);\n }, function(err) {\n invoke(\"throw\", err, resolve, reject);\n });\n }\n\n return PromiseImpl.resolve(value).then(function(unwrapped) {\n // When a yielded Promise is resolved, its final value becomes\n // the .value of the Promise<{value,done}> result for the\n // current iteration.\n result.value = unwrapped;\n resolve(result);\n }, function(error) {\n // If a rejected Promise was yielded, throw the rejection back\n // into the async generator function so it can be handled there.\n return invoke(\"throw\", error, resolve, reject);\n });\n }\n }\n\n var previousPromise;\n\n function enqueue(method, arg) {\n function callInvokeWithMethodAndArg() {\n return new PromiseImpl(function(resolve, reject) {\n invoke(method, arg, resolve, reject);\n });\n }\n\n return previousPromise =\n // If enqueue has been called before, then we want to wait until\n // all previous Promises have been resolved before calling invoke,\n // so that results are always delivered in the correct order. If\n // enqueue has not been called before, then it is important to\n // call invoke immediately, without waiting on a callback to fire,\n // so that the async generator function has the opportunity to do\n // any necessary setup in a predictable way. This predictability\n // is why the Promise constructor synchronously invokes its\n // executor callback, and why async functions synchronously\n // execute code before the first await. Since we implement simple\n // async functions in terms of async generators, it is especially\n // important to get this right, even though it requires care.\n previousPromise ? previousPromise.then(\n callInvokeWithMethodAndArg,\n // Avoid propagating failures to Promises returned by later\n // invocations of the iterator.\n callInvokeWithMethodAndArg\n ) : callInvokeWithMethodAndArg();\n }\n\n // Define the unified helper method that is used to implement .next,\n // .throw, and .return (see defineIteratorMethods).\n this._invoke = enqueue;\n }\n\n defineIteratorMethods(AsyncIterator.prototype);\n define(AsyncIterator.prototype, asyncIteratorSymbol, function () {\n return this;\n });\n exports.AsyncIterator = AsyncIterator;\n\n // Note that simple async functions are implemented on top of\n // AsyncIterator objects; they just return a Promise for the value of\n // the final result produced by the iterator.\n exports.async = function(innerFn, outerFn, self, tryLocsList, PromiseImpl) {\n if (PromiseImpl === void 0) PromiseImpl = Promise;\n\n var iter = new AsyncIterator(\n wrap(innerFn, outerFn, self, tryLocsList),\n PromiseImpl\n );\n\n return exports.isGeneratorFunction(outerFn)\n ? iter // If outerFn is a generator, return the full iterator.\n : iter.next().then(function(result) {\n return result.done ? result.value : iter.next();\n });\n };\n\n function makeInvokeMethod(innerFn, self, context) {\n var state = GenStateSuspendedStart;\n\n return function invoke(method, arg) {\n if (state === GenStateExecuting) {\n throw new Error(\"Generator is already running\");\n }\n\n if (state === GenStateCompleted) {\n if (method === \"throw\") {\n throw arg;\n }\n\n // Be forgiving, per 25.3.3.3.3 of the spec:\n // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume\n return doneResult();\n }\n\n context.method = method;\n context.arg = arg;\n\n while (true) {\n var delegate = context.delegate;\n if (delegate) {\n var delegateResult = maybeInvokeDelegate(delegate, context);\n if (delegateResult) {\n if (delegateResult === ContinueSentinel) continue;\n return delegateResult;\n }\n }\n\n if (context.method === \"next\") {\n // Setting context._sent for legacy support of Babel's\n // function.sent implementation.\n context.sent = context._sent = context.arg;\n\n } else if (context.method === \"throw\") {\n if (state === GenStateSuspendedStart) {\n state = GenStateCompleted;\n throw context.arg;\n }\n\n context.dispatchException(context.arg);\n\n } else if (context.method === \"return\") {\n context.abrupt(\"return\", context.arg);\n }\n\n state = GenStateExecuting;\n\n var record = tryCatch(innerFn, self, context);\n if (record.type === \"normal\") {\n // If an exception is thrown from innerFn, we leave state ===\n // GenStateExecuting and loop back for another invocation.\n state = context.done\n ? GenStateCompleted\n : GenStateSuspendedYield;\n\n if (record.arg === ContinueSentinel) {\n continue;\n }\n\n return {\n value: record.arg,\n done: context.done\n };\n\n } else if (record.type === \"throw\") {\n state = GenStateCompleted;\n // Dispatch the exception by looping back around to the\n // context.dispatchException(context.arg) call above.\n context.method = \"throw\";\n context.arg = record.arg;\n }\n }\n };\n }\n\n // Call delegate.iterator[context.method](context.arg) and handle the\n // result, either by returning a { value, done } result from the\n // delegate iterator, or by modifying context.method and context.arg,\n // setting context.delegate to null, and returning the ContinueSentinel.\n function maybeInvokeDelegate(delegate, context) {\n var method = delegate.iterator[context.method];\n if (method === undefined) {\n // A .throw or .return when the delegate iterator has no .throw\n // method always terminates the yield* loop.\n context.delegate = null;\n\n if (context.method === \"throw\") {\n // Note: [\"return\"] must be used for ES3 parsing compatibility.\n if (delegate.iterator[\"return\"]) {\n // If the delegate iterator has a return method, give it a\n // chance to clean up.\n context.method = \"return\";\n context.arg = undefined;\n maybeInvokeDelegate(delegate, context);\n\n if (context.method === \"throw\") {\n // If maybeInvokeDelegate(context) changed context.method from\n // \"return\" to \"throw\", let that override the TypeError below.\n return ContinueSentinel;\n }\n }\n\n context.method = \"throw\";\n context.arg = new TypeError(\n \"The iterator does not provide a 'throw' method\");\n }\n\n return ContinueSentinel;\n }\n\n var record = tryCatch(method, delegate.iterator, context.arg);\n\n if (record.type === \"throw\") {\n context.method = \"throw\";\n context.arg = record.arg;\n context.delegate = null;\n return ContinueSentinel;\n }\n\n var info = record.arg;\n\n if (! info) {\n context.method = \"throw\";\n context.arg = new TypeError(\"iterator result is not an object\");\n context.delegate = null;\n return ContinueSentinel;\n }\n\n if (info.done) {\n // Assign the result of the finished delegate to the temporary\n // variable specified by delegate.resultName (see delegateYield).\n context[delegate.resultName] = info.value;\n\n // Resume execution at the desired location (see delegateYield).\n context.next = delegate.nextLoc;\n\n // If context.method was \"throw\" but the delegate handled the\n // exception, let the outer generator proceed normally. If\n // context.method was \"next\", forget context.arg since it has been\n // \"consumed\" by the delegate iterator. If context.method was\n // \"return\", allow the original .return call to continue in the\n // outer generator.\n if (context.method !== \"return\") {\n context.method = \"next\";\n context.arg = undefined;\n }\n\n } else {\n // Re-yield the result returned by the delegate method.\n return info;\n }\n\n // The delegate iterator is finished, so forget it and continue with\n // the outer generator.\n context.delegate = null;\n return ContinueSentinel;\n }\n\n // Define Generator.prototype.{next,throw,return} in terms of the\n // unified ._invoke helper method.\n defineIteratorMethods(Gp);\n\n define(Gp, toStringTagSymbol, \"Generator\");\n\n // A Generator should always return itself as the iterator object when the\n // @@iterator function is called on it. Some browsers' implementations of the\n // iterator prototype chain incorrectly implement this, causing the Generator\n // object to not be returned from this call. This ensures that doesn't happen.\n // See https://github.com/facebook/regenerator/issues/274 for more details.\n define(Gp, iteratorSymbol, function() {\n return this;\n });\n\n define(Gp, \"toString\", function() {\n return \"[object Generator]\";\n });\n\n function pushTryEntry(locs) {\n var entry = { tryLoc: locs[0] };\n\n if (1 in locs) {\n entry.catchLoc = locs[1];\n }\n\n if (2 in locs) {\n entry.finallyLoc = locs[2];\n entry.afterLoc = locs[3];\n }\n\n this.tryEntries.push(entry);\n }\n\n function resetTryEntry(entry) {\n var record = entry.completion || {};\n record.type = \"normal\";\n delete record.arg;\n entry.completion = record;\n }\n\n function Context(tryLocsList) {\n // The root entry object (effectively a try statement without a catch\n // or a finally block) gives us a place to store values thrown from\n // locations where there is no enclosing try statement.\n this.tryEntries = [{ tryLoc: \"root\" }];\n tryLocsList.forEach(pushTryEntry, this);\n this.reset(true);\n }\n\n exports.keys = function(object) {\n var keys = [];\n for (var key in object) {\n keys.push(key);\n }\n keys.reverse();\n\n // Rather than returning an object with a next method, we keep\n // things simple and return the next function itself.\n return function next() {\n while (keys.length) {\n var key = keys.pop();\n if (key in object) {\n next.value = key;\n next.done = false;\n return next;\n }\n }\n\n // To avoid creating an additional object, we just hang the .value\n // and .done properties off the next function object itself. This\n // also ensures that the minifier will not anonymize the function.\n next.done = true;\n return next;\n };\n };\n\n function values(iterable) {\n if (iterable) {\n var iteratorMethod = iterable[iteratorSymbol];\n if (iteratorMethod) {\n return iteratorMethod.call(iterable);\n }\n\n if (typeof iterable.next === \"function\") {\n return iterable;\n }\n\n if (!isNaN(iterable.length)) {\n var i = -1, next = function next() {\n while (++i < iterable.length) {\n if (hasOwn.call(iterable, i)) {\n next.value = iterable[i];\n next.done = false;\n return next;\n }\n }\n\n next.value = undefined;\n next.done = true;\n\n return next;\n };\n\n return next.next = next;\n }\n }\n\n // Return an iterator with no values.\n return { next: doneResult };\n }\n exports.values = values;\n\n function doneResult() {\n return { value: undefined, done: true };\n }\n\n Context.prototype = {\n constructor: Context,\n\n reset: function(skipTempReset) {\n this.prev = 0;\n this.next = 0;\n // Resetting context._sent for legacy support of Babel's\n // function.sent implementation.\n this.sent = this._sent = undefined;\n this.done = false;\n this.delegate = null;\n\n this.method = \"next\";\n this.arg = undefined;\n\n this.tryEntries.forEach(resetTryEntry);\n\n if (!skipTempReset) {\n for (var name in this) {\n // Not sure about the optimal order of these conditions:\n if (name.charAt(0) === \"t\" &&\n hasOwn.call(this, name) &&\n !isNaN(+name.slice(1))) {\n this[name] = undefined;\n }\n }\n }\n },\n\n stop: function() {\n this.done = true;\n\n var rootEntry = this.tryEntries[0];\n var rootRecord = rootEntry.completion;\n if (rootRecord.type === \"throw\") {\n throw rootRecord.arg;\n }\n\n return this.rval;\n },\n\n dispatchException: function(exception) {\n if (this.done) {\n throw exception;\n }\n\n var context = this;\n function handle(loc, caught) {\n record.type = \"throw\";\n record.arg = exception;\n context.next = loc;\n\n if (caught) {\n // If the dispatched exception was caught by a catch block,\n // then let that catch block handle the exception normally.\n context.method = \"next\";\n context.arg = undefined;\n }\n\n return !! caught;\n }\n\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n var record = entry.completion;\n\n if (entry.tryLoc === \"root\") {\n // Exception thrown outside of any try block that could handle\n // it, so set the completion value of the entire function to\n // throw the exception.\n return handle(\"end\");\n }\n\n if (entry.tryLoc <= this.prev) {\n var hasCatch = hasOwn.call(entry, \"catchLoc\");\n var hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n if (hasCatch && hasFinally) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n } else if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else if (hasCatch) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n }\n\n } else if (hasFinally) {\n if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else {\n throw new Error(\"try statement without catch or finally\");\n }\n }\n }\n },\n\n abrupt: function(type, arg) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc <= this.prev &&\n hasOwn.call(entry, \"finallyLoc\") &&\n this.prev < entry.finallyLoc) {\n var finallyEntry = entry;\n break;\n }\n }\n\n if (finallyEntry &&\n (type === \"break\" ||\n type === \"continue\") &&\n finallyEntry.tryLoc <= arg &&\n arg <= finallyEntry.finallyLoc) {\n // Ignore the finally entry if control is not jumping to a\n // location outside the try/catch block.\n finallyEntry = null;\n }\n\n var record = finallyEntry ? finallyEntry.completion : {};\n record.type = type;\n record.arg = arg;\n\n if (finallyEntry) {\n this.method = \"next\";\n this.next = finallyEntry.finallyLoc;\n return ContinueSentinel;\n }\n\n return this.complete(record);\n },\n\n complete: function(record, afterLoc) {\n if (record.type === \"throw\") {\n throw record.arg;\n }\n\n if (record.type === \"break\" ||\n record.type === \"continue\") {\n this.next = record.arg;\n } else if (record.type === \"return\") {\n this.rval = this.arg = record.arg;\n this.method = \"return\";\n this.next = \"end\";\n } else if (record.type === \"normal\" && afterLoc) {\n this.next = afterLoc;\n }\n\n return ContinueSentinel;\n },\n\n finish: function(finallyLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.finallyLoc === finallyLoc) {\n this.complete(entry.completion, entry.afterLoc);\n resetTryEntry(entry);\n return ContinueSentinel;\n }\n }\n },\n\n \"catch\": function(tryLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc === tryLoc) {\n var record = entry.completion;\n if (record.type === \"throw\") {\n var thrown = record.arg;\n resetTryEntry(entry);\n }\n return thrown;\n }\n }\n\n // The context.catch method must only be called with a location\n // argument that corresponds to a known catch block.\n throw new Error(\"illegal catch attempt\");\n },\n\n delegateYield: function(iterable, resultName, nextLoc) {\n this.delegate = {\n iterator: values(iterable),\n resultName: resultName,\n nextLoc: nextLoc\n };\n\n if (this.method === \"next\") {\n // Deliberately forget the last sent value so that we don't\n // accidentally pass it on to the delegate.\n this.arg = undefined;\n }\n\n return ContinueSentinel;\n }\n };\n\n // Regardless of whether this script is executing as a CommonJS module\n // or not, return the runtime object so that we can declare the variable\n // regeneratorRuntime in the outer scope, which allows this module to be\n // injected easily by `bin/regenerator --include-runtime script.js`.\n return exports;\n\n}(\n // If this script is executing as a CommonJS module, use module.exports\n // as the regeneratorRuntime namespace. Otherwise create a new empty\n // object. Either way, the resulting object will be used to initialize\n // the regeneratorRuntime variable at the top of this file.\n typeof module === \"object\" ? module.exports : {}\n));\n\ntry {\n regeneratorRuntime = runtime;\n} catch (accidentalStrictMode) {\n // This module should not be running in strict mode, so the above\n // assignment should always work unless something is misconfigured. Just\n // in case runtime.js accidentally runs in strict mode, in modern engines\n // we can explicitly access globalThis. In older engines we can escape\n // strict mode using a global Function call. This could conceivably fail\n // if a Content Security Policy forbids using Function, but in that case\n // the proper solution is to fix the accidental strict mode problem. If\n // you've misconfigured your bundler to force strict mode and applied a\n // CSP to forbid Function, and you're not willing to fix either of those\n // problems, please detail your unique predicament in a GitHub issue.\n if (typeof globalThis === \"object\") {\n globalThis.regeneratorRuntime = runtime;\n } else {\n Function(\"r\", \"regeneratorRuntime = r\")(runtime);\n }\n}\n","export default class CloudHelper{\n static name(){\n return 'Cloud Helper'\n }\n \n}","class Topic {\n constructor() {}\n\n // static hello() {\n // return \"Hello from the Topic class\";\n // }\n\n static minMax(value){\n const minMaxValues = ['pm1', 'pm2p5', 'pm10'];\n return minMaxValues.includes(value);\n }\n\n static getMaxYValue(value, dataInterpretation) {\n dataInterpretation = DataInterpretation.whatDataInterpretationIsBeingDisplayed(value);\n\n if (value == \"sht\") {\n return App.Topic.nearestUp(\"hmd\", 10, dataInterpretation);\n } else if (value == \"psu\") {\n return App.Topic.nearestUp(\"prot-batt\", 10, dataInterpretation);\n } else if (valueLabels[value]['graphMaxY'] != undefined) {\n return valueLabels[value]['graphMaxY']\n } else {\n const maxValue = Graph.maxYValue(value, dataInterpretation);\n if(maxValue < 10 && Topic.minMax(value)){\n return 10\n } else {\n return maxValue;\n }\n }\n }\n static getMinYValue(sensorName, dataInterpretation) {\n dataInterpretation = DataInterpretation.whatDataInterpretationIsBeingDisplayed(sensorName);\n let values = Object.values(\n App.Topic.processedMessages[sensorName][dataInterpretation].readings\n );\n const minValue = MessageCollections.getMinValueForSensor(\n sensorName,\n dataInterpretation\n );\n if(valueLabels[sensorName]['graphMinY'] != undefined){\n if(typeof valueLabels[sensorName]['graphMinY'] == 'string'){\n if(valueLabels[sensorName]['graphMinY'] == 'round'){\n return minValue - 1;\n }\n if(valueLabels[sensorName]['graphMinY'].startsWith('lte')){\n const graphMinY = parseInt(valueLabels[sensorName]['graphMinY'].split('lte')[1]);\n if(minValue < graphMinY){\n return minValue;\n } else {\n return graphMinY;\n }\n }\n }\n if(typeof valueLabels[sensorName]['graphMinY'] == 'number'){\n return valueLabels[sensorName]['graphMinY'];\n }\n }\n }\n\n static showReportedToggler(){\n if(App.Topic.dataInterpretations.length > 1){\n document.getElementById('showReportedToggler').style.display = \"block\";\n } else {\n document.getElementById('showReportedToggler').style.display = \"none\";\n }\n }\n\n static setTopicInterval(interval){\n if(interval != undefined){\n App.Topic.interval = interval;\n }\n }\n\n}\nexport default Topic;\n","class TopicAutoRefresher {\n constructor(refreshInterval, topic) {\n this.refreshInterval = refreshInterval;\n this.topic = topic;\n }\n\n // Get messages for 1 millisecond after the currently received most recent message, and now.\n // I.e. only get new messages\n calculateNewTimes() {\n // this.oldStartDate = new Date(\n // document.querySelector(\"#start-time > input\").value\n // ).toISOString();\n const value = App.Topic.valuesPresent[0];\n //this.oldStartDate = App.Topic.processedMessages[value][0][0][0];\n let timeStamps = App.Topic.processedMessages[value]['reported'].timeStamps\n this.oldStartDate = timeStamps[0];\n\n // this.oldEndDate = new Date(\n // document.querySelector(\"#end-time > input\").value\n // ).toISOString();\n \n // this.oldEndDate =\n // App.Topic.processedMessages[value][0][\n // App.Topic.processedMessages[value][0].length - 1\n // ][0];\n this.oldEndDate = timeStamps[timeStamps.length-1];\n \n this.newStartDate = moment(\n this.oldEndDate,\n App.Topic.messageTimeFormatString\n )\n .add(1, \"milliseconds\")\n .toISOString();\n\n // this.newEndDate = moment(\n // this.newStartDate,\n // App.Topic.messageTimeFormatString\n // )\n // .add(this.refreshInterval, \"seconds\")\n // .toISOString();\n this.newEndDate = new Date().toISOString(); //use now as the end time so that we can catch up if the device went offline for a bit.\n }\n\n async getMessages() {\n this.setMessagesDuration();\n\n const apiUrl = \"https://aws.southcoastscience.com\";\n\n let retriever = new TopicMessagesRetriever(\n apiUrl,\n this.topic,\n this.newStartDate,\n this.newEndDate\n );\n let messages = await retriever.retrieveMessages();\n MessageProcessor.processMessages(messages.data.Items);\n \n if (messages.data.Items != []) {\n App.Topic.allMessages = App.Topic.allMessages.concat(messages.data.Items);\n this.setTrimTime();\n this.trimProcessedMessages();\n }\n \n TopicTimeTool.setStartDate();\n TopicTimeTool.setStartDatePicker();\n TopicTimeTool.setEndDate();\n TopicTimeTool.setEndDatePicker();\n\n const gauges = document.querySelectorAll(\"#charts_div .gauge\");\n if (gauges[0] != undefined && gauges[0].style.display == \"inline-block\") {\n App.Topic.displayGaugesFlag = true;\n } else {\n App.Topic.displayGaugesFlag = false;\n }\n\n Graph.displayGraphs();\n //App.Topic.displayGraphs();\n\n if (App.Topic.isAStatusTopic()) {\n App.Topic.displayMap();\n }\n\n App.Topic.constructAndDisplayShareableUrl();\n if (App.Topic.fetchedLastWrittenData) {\n App.Topic.stopRefreshing();\n }\n }\n\n constructApiUrl() {\n let uri = \"\";\n const topic = document.querySelector(\".data\").getAttribute(\"data-topic\");\n if (App.Topic.isAwsOrg) {\n uri =\n App.Topic.awsApiDomain +\n \"/topicMessages?topic=\" +\n topic +\n \"&startTime=\" +\n encodeURIComponent(this.newStartDate) +\n \"&endTime=\" +\n encodeURIComponent(this.newEndDate) +\n \"&checkpoint=auto\";\n } else {\n uri =\n App.Topic.apiDomain +\n \"/v1/messages/topic/\" +\n topic +\n \"?start-date=\" +\n encodeURIComponent(this.newStartDate) +\n \"&end-date=\" +\n encodeURIComponent(this.newEndDate);\n }\n }\n\n trimProcessedMessages() {\n for (let i = 0; i < App.Topic.valuesPresent.length; i++) {\n const value = App.Topic.valuesPresent[i];\n const dataInterpretations = Graph.getDataInterpretationNames();\n for(let d = 0; d < dataInterpretations.length; d++){\n let timeStamps = App.Topic.processedMessages[value][dataInterpretations[d]].timeStamps;\n let readings = App.Topic.processedMessages[value][dataInterpretations[d]].readings;\n for (let ii = 0; ii < timeStamps.length; ii++) {\n try {\n if (new Date(timeStamps[ii]).getTime() < this.trimBeforeTime) {\n timeStamps.splice(ii, 1);\n delete readings[timeStamps[ii]];\n }\n } catch (e) {\n console.log(\"caught an error\" + e);\n }\n }\n }\n \n }\n }\n\n setMessagesDuration() {\n let aKey = App.Topic.valuesPresent[0];\n let timeStamps = App.Topic.processedMessages[aKey]['reported'].timeStamps;\n let mostRecentMessageTime = new Date(timeStamps[timeStamps.length -1]).getTime();\n let firstMessageTime = new Date(timeStamps[0]).getTime();\n let messagesDuration = mostRecentMessageTime - firstMessageTime;\n\n this.trimDuration = messagesDuration;\n }\n\n setTrimTime() {\n let aKey = App.Topic.valuesPresent[0];\n let timeStamps = App.Topic.processedMessages[aKey]['reported'].timeStamps;\n let mostRecentMessageTime = new Date(timeStamps[timeStamps.length -1]).getTime();\n this.trimBeforeTime = mostRecentMessageTime - this.trimDuration;\n }\n}\nexport default TopicAutoRefresher;\n","class TopicMessagesRetriever {\n constructor(apiUri, topic, startTime, endTime) {\n this.apiUri = apiUri;\n this.topic = topic;\n this.startTime = startTime;\n this.endTime = endTime;\n this.timeout = ScsConfig().connectionTimeout;\n }\n\n async retrieveMessages() {\n const apiKey = document.querySelector(\".data\").getAttribute(\"data-api-key\");\n axios.defaults.headers.common[\"Authorization\"] = \"api-key \" + apiKey;\n let urlToCall =\n this.apiUri +\n \"/topicMessages?topic=\" +\n this.topic +\n \"&startTime=\" +\n encodeURIComponent(this.startTime) +\n \"&endTime=\" +\n encodeURIComponent(this.endTime) +\n \"&fetchLastWritten=true&checkpoint=auto\";\n try {\n const response = await axios.request({\n url: urlToCall,\n timeout: this.timeout\n });\n App.Topic.fetchedLastWrittenData =\n response.data[\"fetchedLastWrittenData\"];\n return response;\n } catch (error) {\n console.log(\"There was an error retrieving messages\");\n console.log(error);\n }\n }\n}\nexport default TopicMessagesRetriever;\n","class RegressionCalculator {\n constructor() {}\n\n predictY(value, x) {\n const values = App.Topic.processedMessages[value][DataInterpretation.getDataInterpretationName()].readings;\n \n let arrayed = [];\n let keys = Object.keys(values);\n for(let i=0; i < keys.length; i++){\n arrayed.push([new Date(keys[i]).getTime(), values[keys[i]]])\n }\n \n const result = regression.linear(arrayed, {\n order: 2,\n precision: 10\n });\n this.slopeValue = result.equation[0];\n\n return Math.round(result.predict(x)[1]);\n }\n\n slopeRepresentation() {\n if (this.slopeValue > 0) {\n return \"positive\";\n } else if (this.slopeValue < 0) {\n return \"negative\";\n } else {\n return \"unchanged\";\n }\n }\n\n getMidPoint(value) {\n\n const sensorData = App.Topic.processedMessages[value][DataInterpretation.getDataInterpretationName()];\n \n if (sensorData.timeStamps[0] == undefined) {\n return 0;\n }\n // if (App.Topic.messagesWithTimestamps[value][0] == undefined) {\n // return 0;\n // }\n //const startTime = App.Topic.messagesWithTimestamps[value]['reported'][0][0];\n const startTime = new Date(sensorData.timeStamps[0]).getTime();\n //console.log(`start time is ${startTime}`);\n // const endTime =\n // App.Topic.messagesWithTimestamps[value]['reported'][\n // App.Topic.messagesWithTimestamps[value]['reported'].length - 1\n // ][0];\n const endTime = new Date(sensorData.timeStamps[sensorData.timeStamps.length - 1]).getTime();\n //console.log(`end time is ${endTime}`);\n const midPoint = startTime + (endTime - startTime) / 2;\n return midPoint;\n }\n}\nexport default RegressionCalculator;\n","class TopicMap {\n constructor(long, lat, mapContainer) {\n this.long = long;\n this.lat = lat;\n this.mapContainer = mapContainer;\n }\n\n drawMap() {\n const coords = { lat: this.lat, lng: this.long };\n\n const map = new google.maps.Map(\n document.getElementById(this.mapContainer),\n { zoom: 13, center: coords, mapTypeId: \"satellite\" }\n );\n const marker = new google.maps.Marker({ position: coords, map: map });\n const container = document.getElementById(this.mapContainer);\n\n container.style.height = \"500px\";\n container.style.display = \"block\";\n }\n\n static noGPSData(mapContainer) {\n const container = document.getElementById(mapContainer);\n\n container.className += \" noGpsContainer\";\n container.style.display = \"block\";\n\n const heading = document.getElementById(\"noGps\");\n heading.style.display = \"block\";\n }\n\n static gpsQualityDisplay(deviceMessage){\n if(TopicMap.hasValidGpsData(deviceMessage)){\n if (deviceMessage[\"val\"][\"gps\"] != undefined) {\n if(deviceMessage[\"val\"][\"gps\"][\"qual\"] != undefined){\n if(deviceMessage[\"val\"][\"gps\"][\"qual\"] === 0){\n const container = document.getElementById(\"gps-warning\");\n container.style.display = \"block\";\n }\n }\n } \n }\n }\n\n static hasValidGpsData(deviceMessage){\n if(\n deviceMessage[\"val\"][\"gps\"] != undefined &&\n deviceMessage[\"val\"][\"gps\"][\"pos\"] != undefined &&\n deviceMessage[\"val\"][\"gps\"][\"pos\"][0] != null &&\n deviceMessage[\"val\"][\"gps\"][\"pos\"][1] != null\n ){\n return true;\n }\n return false;\n }\n}\nexport default TopicMap;\n","class ChartToggler {\n constructor() {}\n\n static toggle(toggler) {\n const gaugesDiv = document.getElementById(\"gauges_div\");\n const chartsDiv = document.getElementById(\"charts_div\");\n const gauges = document.querySelectorAll(\".gauge\");\n\n if (toggler.dataset.charttype == \"gauge\") {\n const isPressed = toggler.getAttribute(\"aria-pressed\");\n const graphs = document.querySelectorAll(\".graph\");\n\n //if this is true then the button has been click off, and this will be false shortly.\n if (isPressed == \"true\") {\n Array.prototype.forEach.call(gauges, function(gauge) {\n gauge.style.display = \"none\";\n });\n Array.prototype.forEach.call(graphs, function(graph) {\n graph.setAttribute(\"class\", \"graph-wide\");\n });\n\n document.cookie = \"showGauges=false;path=/;max-age=0\"; //epxires 0 should delete the cookie.\n } else {\n // console.log(\"Showing gauges\");\n const wideGraphs = document.querySelectorAll(\".graph-wide\");\n // console.log(`i see ${wideGraphs.length} wide graphs`);\n // console.log(wideGraphs);\n [].forEach.call(wideGraphs, function(wideGraph) {\n //console.log(\"Narrowing a graph\");\n wideGraph.setAttribute(\"class\", \"graph\");\n });\n\n Array.prototype.forEach.call(gauges, function(gauge) {\n gauge.style.display = \"inline-block\";\n });\n\n //const wideGraphs2 = document.querySelectorAll(\"graph-wide\");\n //console.log(`now i see ${wideGraphs2.length} wide graphs`);\n let expiryDate = new Date(Date.now() + 3600 * 1000 * 24 * 365 * 1); //1 year\n expiryDate = expiryDate.toUTCString();\n document.cookie = \"showGauges=true;path=/;expires=\" + expiryDate;\n }\n }\n\n App.Topic.graphs.forEach(function(g) {\n g.draw();\n });\n }\n}\nexport default ChartToggler;\n","class TopicTimeTool {\n constructor() {}\n\n static setStartDate() {\n const aValue = App.Topic.valuesPresent[0];\n const timeStamps = App.Topic.processedMessages[aValue]['reported'].timeStamps;\n if (timeStamps.length > 0) {\n App.Topic.startDate = timeStamps[0]; //first message time\n }\n }\n\n static setStartDatePicker() {\n $(\"#start-time\").data({\n date: moment(App.Topic.startDate)\n });\n $(\"#start-time\").datetimepicker(\"update\");\n $(\"#start-time\")\n .datetimepicker()\n .children(\"input\")\n .val(moment(App.Topic.startDate).format(\"YYYY-MM-DD, H:mm:ss\"));\n }\n\n static setEndDatePicker() {\n $(\"#end-time\").data({\n date: moment(App.Topic.endDate)\n });\n $(\"#end-time\").datetimepicker(\"update\");\n $(\"#end-time\")\n .datetimepicker()\n .children(\"input\")\n .val(moment(App.Topic.endDate).format(\"YYYY-MM-DD, H:mm:ss\"));\n }\n\n static setEndDate() {\n const aValue = App.Topic.valuesPresent[0];\n const timeStamps = App.Topic.processedMessages[aValue]['reported'].timeStamps;\n App.Topic.endDate =\n timeStamps[timeStamps.length - 1];\n }\n}\nexport default TopicTimeTool;\n","\"use strict\";\n\nclass Json2Csv {\n constructor(checkpoint) {\n this.headers = [];\n this.checkpoint = checkpoint;\n App.Topic.allMessages = [];\n this.timeout = ScsConfig().connectionTimeout;\n this.topic = document.querySelector(\".data\").getAttribute(\"data-topic\");\n }\n\n getHeaders(json, headerPrefix = \"\") {\n Object.keys(json).forEach(key => {\n if (typeof json[key] == \"object\" && json[key] != undefined) {\n //check to see if its an object or an array HERE\n if (json[key].constructor == Array) {\n this.getHeaders(json[key], `${headerPrefix}${key}:`);\n } else if (json[key].constructor == Object) {\n this.getHeaders(json[key], `${headerPrefix}${key}.`);\n }\n } else if (key == undefined) {\n console.log(`got a bad key ${key}`);\n } else {\n this.headers.push(headerPrefix + key);\n }\n });\n }\n\n buildFilename(message, startTime, endTime) {\n const topic = this.topic;\n const lastBit = topic.split(\"/\").pop();\n //const tag = message.payload.tag;\n const tag = message.tag;\n\n const removeMillisecondsRegex = /\\.(\\d{3})/;\n const removeSemiColonsRegex = /:/g;\n startTime = startTime\n .replace(removeSemiColonsRegex, \"-\")\n .replace(removeMillisecondsRegex, \"\");\n endTime = endTime\n .replace(removeSemiColonsRegex, \"-\")\n .replace(removeMillisecondsRegex, \"\");\n\n this.fileName = `${tag}_${lastBit}_${startTime}_${endTime}${this.aggregationFileSuffix()}.csv`;\n }\n\n aggregationFileSuffix(){\n const mappings =\n {\n \"none\": \"\",\n \"**:**:00\": \"_1min\",\n \"**:/15:00\": \"_15min\",\n \"**:00:00\": \"_1hr\",\n \"/6:00:00\": \"_6hr\"\n }\n return mappings[this.checkpoint];\n }\n\n readData(message) {\n let row = \"\";\n\n this.headers.forEach(header => {\n //convert header to array key\n let replacedHeader = header.replace(\":\", \".\"); //some headers have : in them\n let keys = replacedHeader.split(\".\");\n\n let value = message;\n \n try {\n keys.forEach(key => {\n value = value[key];\n if (\n typeof value == \"string\" ||\n typeof value == \"number\" ||\n typeof value == \"boolean\"\n ) {\n row = row + value + \",\";\n } else if ( value == undefined || value == null){\n row = row + \"\" + \",\";\n }\n });\n } catch (e) {\n console.log(\"caught an error\");\n console.log(e);\n }\n });\n row = row.slice(0, -1); //remove trainling , character\n return row;\n }\n\n headerToKey(header) {\n //header is a string . delimited\n let split = header.split(\".\");\n let key = \"\";\n split.forEach(keyPart => {\n key = key + [keyPart];\n });\n }\n\n csvHeaders() {\n return this.headers + \"\\n\";\n }\n\n genereateCsvRows(data) {\n let rows = \"\";\n\n data.forEach(message => {\n //let messageCsvRow = this.readData(message.payload);\n let messageCsvRow = this.readData(message);\n rows = rows + messageCsvRow + \"\\n\";\n });\n\n return rows;\n }\n\n generateCsv(data) {\n let csv = \"\";\n //this.getHeaders(data[0].payload); //discover headers\n this.getHeaders(data[0]); //discover headers\n csv = csv + this.csvHeaders();\n csv = csv + this.genereateCsvRows(data);\n return csv;\n }\n\n //these two functions are basically copied from Topic.js\n // These should be refactored to a generic paging aware message retriever\n getMessages() {\n var isAwsOrganisation = document\n .querySelector(\".data\")\n .getAttribute(\"data-organisation-isaws\");\n if (isAwsOrganisation == \"true\") {\n App.Topic.isAwsOrg = true;\n } else {\n App.Topic.isAwsOrg = false;\n }\n\n var topic = document.querySelector(\".data\").getAttribute(\"data-topic\");\n if (App.Topic.isAwsOrg) {\n var uri =\n App.Topic.awsApiDomain +\n \"/topicMessages?topic=\" +\n //\"/default/AWSAggregate?topic=\" +\n topic +\n \"&startTime=\" +\n encodeURIComponent(App.Topic.startDate) +\n \"&endTime=\" +\n encodeURIComponent(App.Topic.endDate) +\n \"&fetchLastWritten=true&checkpoint=\"+this.checkpoint;\n } else {\n var uri =\n App.Topic.apiDomain +\n \"/v1/messages/topic/\" +\n topic +\n \"?start-date=\" +\n encodeURIComponent(App.Topic.startDate) +\n \"&end-date=\" +\n encodeURIComponent(App.Topic.endDate);\n }\n this.messagesForTopic(uri);\n }\n\n async messagesForTopic(uri) {\n App.showModal();\n var apiKey = document.querySelector(\".data\").getAttribute(\"data-api-key\");\n\n let json = [];\n\n axios.defaults.headers.common[\"X-Requested-With\"] = \"XMLHttpRequest\";\n axios.defaults.headers.common[\"Authorization\"] = \"api-key \" + apiKey;\n\n axios\n .request({ url: uri, timeout: this.timeout })\n .then(response => {\n json[\"messages\"] = response.data[\"Items\"];\n\n App.Topic.fetchedLastWrittenData =\n response.data[\"fetchedLastWrittenData\"];\n\n App.Topic.allMessages = App.Topic.allMessages.concat(json.messages);\n\n const lastMessage = json.messages[json.messages.length - 1];\n console.log(lastMessage);\n\n if (response.data[\"next\"] != undefined && App.Topic.TESTING != true) {\n //console.log(\"Paging\");\n this.messagesForTopic(response.data[\"next\"]);\n } else {\n App.hideModal();\n\n const csvContent = this.generateCsv(App.Topic.allMessages);\n\n this.buildFilename(\n App.Topic.allMessages[0],\n App.Topic.allMessages[0].rec,\n App.Topic.allMessages[App.Topic.allMessages.length-1].rec\n );\n\n\n this.downloadCsv(\n csvContent,\n this.fileName,\n \"text/csv;encoding:utf-8\"\n );\n }\n })\n .catch(error => {\n if (error.code == \"ECONNABORTED\") {\n const logger = new ScsLogger();\n logger.log(`${user} has triggered an error`);\n logger.log(\"json2csv get connection timeout: \" + error.message);\n }\n return true;\n });\n }\n\n downloadCsv(content, fileName, mimeType) {\n var a = document.createElement(\"a\");\n mimeType = mimeType || \"application/octet-stream\";\n\n if (navigator.msSaveBlob) {\n // IE10\n navigator.msSaveBlob(\n new Blob([content], {\n type: mimeType\n }),\n fileName\n );\n } else if (URL && \"download\" in a) {\n //html5 A[download]\n a.href = URL.createObjectURL(\n new Blob([content], {\n type: mimeType\n })\n );\n a.setAttribute(\"download\", fileName);\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n } else {\n location.href =\n \"data:application/octet-stream,\" + encodeURIComponent(content); // only this mime type is supported\n }\n }\n}\nexport default Json2Csv;\n","class ScsLogger {\n constructor() {\n this.uuid = ScsLogger.uuidv4();\n this.counter = 0; //this allows multiple messages per error report\n }\n\n log(message) {\n this.counter = this.counter + 1;\n const url =\n \"https://vmxrvbzhoi.execute-api.us-west-2.amazonaws.com/dev/log\";\n\n axios\n .post(url, {\n type: \"error\",\n service: \"CH\",\n uuidv4: this.uuid,\n counter: this.counter,\n message: message,\n user: user,\n loggedAt: new Date().toISOString()\n })\n .then(response => {\n console.log(response);\n })\n .catch(error => {\n console.log(error);\n return true;\n });\n }\n\n //https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript\n static uuidv4() {\n return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>\n (\n c ^\n (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))\n ).toString(16)\n );\n }\n}\nexport default ScsLogger;\n","class ScsConfig {\n static config() {\n return {\n connectionTimeout: 1000 * 60 * 5\n };\n }\n}\nexport default ScsConfig.config;\n","\"use strict\";\n\nclass Message {\n construnctor(data) {}\n}\n\nexport default Message;\n","\"use strict\";\n\nimport MessageFormat from \"./message_format\";\n\nclass MessageValue {\n static valueIsNull(message, sensorName) {\n if (sensorName == \"pt1\") {\n return message.val[\"pt1\"][\"tmp\"] == null;\n } else if (sensorName == \"sht\") {\n return (\n message.val[\"sht\"][\"hmd\"] == null || message.val[\"sht\"][\"tmp\"] == null\n );\n } else if (sensorName == \"psu\") {\n return (\n message.val[\"psu\"][\"pwr-in\"] == null ||\n message.val[\"psu\"][\"prot-batt\"] == null\n );\n } else if (sensorName == \"tmp\" && App.Topic.isAStatusTopic()) {\n if (message.val[\"tmp\"] != undefined) {\n if (message.val[\"tmp\"][\"brd\"] != undefined) {\n return message.val[\"tmp\"][\"brd\"] == null;\n } else if (message.val[\"tmp\"][\"hst\"] != undefined) {\n return message.val[\"tmp\"][\"hst\"] == null;\n }\n }\n } else if (sensorName == \"up\") {\n if (\n message.val[\"up\"] != undefined &&\n message.val[\"up\"][\"load\"] != undefined\n ) {\n return message.val[\"up\"][\"load\"][\"av5\"] == null;\n }\n } else if (App.Topic.isSimplesensorName(sensorName)) {\n return message.val[sensorName] == null;\n } else {\n return message.val[sensorName][\"cnc\"] == null;\n }\n }\n\n static randomlyNullify(sensorValue) {\n if (Math.floor(Math.random() * 50) < 2) {\n return null;\n } else {\n return sensorValue;\n }\n }\n //Given a message extract the sensor sensorValue from the message\n // This function needs a refactor as the addition of dataPath to the valueLabels\n // means at least some of this function is redundant\n static valueFor(sensorName, message, dataInterpretation) {\n if (dataInterpretation === \"reported\") {\n var dataPath = \"val\";\n } else {\n if(MessageFormat.version(message) < 2.0){\n var dataPath = \"exg.\" + dataInterpretation;\n } else {\n var dataPath = \"exg.val\";\n }\n }\n\n let sensorValue = null;\n try {\n if (sensorName == \"pt1\") {\n dataPath = dataPath + \".pt1.tmp\";\n sensorValue = MessageValue.getValue(message, dataPath);\n } else if (sensorName == \"sig\") {\n sensorValue = MessageValue.getValue(message, dataPath + \".sig.quality\");\n } else if (sensorName == \"sht\") {\n sensorValue = [\n MessageValue.getValue(message, dataPath + \".sht.hmd\"),\n MessageValue.getValue(message, dataPath + \".sht.tmp\"),\n ];\n } else if (sensorName == \"psu\") {\n sensorValue = [\n MessageValue.getValue(message, dataPath + \".psu.pwr-in\"),\n MessageValue.getValue(message, dataPath + \".psu.prot-batt\"),\n ];\n } else if (sensorName == \"tmp\" && App.Topic.isAStatusTopic()) {\n if (message.val[\"tmp\"] != undefined) {\n if (message.val[\"tmp\"][\"brd\"] != undefined) {\n sensorValue = MessageValue.getValue(message, dataPath + \".tmp.brd\");\n } else if (message.val[\"tmp\"][\"hst\"] != undefined) {\n sensorValue = MessageValue.getValue(message, dataPath + \".tmp.hst\");\n }\n }\n } else if (sensorName == \"up\") {\n if (\n message.val[\"up\"] != undefined &&\n message.val[\"up\"][\"load\"] != undefined\n ) {\n sensorValue = MessageValue.getValue(\n message,\n dataPath + \".up.load.av5\"\n );\n }\n } else if (App.Topic.isSimpleValue(sensorName)) {\n sensorValue = MessageValue.getValue(message, dataPath + \".\" + valueLabels[sensorName]['dataPath'])\n } else {\n // sensorValue = MessageValue.getValue(message, dataPath)[sensorName][\n // \"cnc\"\n // ];\n sensorValue = MessageValue.getValue(message, dataPath + \".\" + valueLabels[sensorName]['dataPath'] + \".cnc\")\n }\n } catch (e) {\n if(App.Topic.DEBUG === true){\n console.log(`Error retrieving value for ${dataPath} and ${sensorName}`);\n console.log(e) \n }\n }\n //Test displaying null values here\n if (this.getUrlParameter(\"insertNulls\")) {\n if (typeof sensorValue == \"number\") {\n return this.randomlyNullify(sensorValue);\n } else {\n return [\n this.randomlyNullify(sensorValue[0]),\n this.randomlyNullify(sensorValue[1]),\n ];\n }\n } else {\n return sensorValue;\n }\n }\n\n static getValue(object, dataPath) {\n try {\n return dataPath.split(\".\").reduce(MessageValue.indexObject, object);\n } catch (e) {\n if(App.Topic.DEBUG === true){\n console.log(`Error retrieving value for ${dataPath}`);\n console.log(object);\n }\n return null;\n }\n }\n\n static indexObject(obj, i) {\n return obj[i];\n }\n\n static getUrlParameter(name) {\n name = name.replace(/[\\[]/, \"\\\\[\").replace(/[\\]]/, \"\\\\]\");\n var regex = new RegExp(\"[\\\\?&]\" + name + \"=([^&#]*)\");\n var results = regex.exec(location.search);\n return results === null\n ? \"\"\n : decodeURIComponent(results[1].replace(/\\+/g, \" \"));\n }\n}\n\nexport default MessageValue;\n","\"use strict\";\n\nclass MessageCollections {\n static messagesWithTimestamps(sensorName, message, dataInterpretation) {\n // const timeStamp = new Date(\n // moment(message.rec, App.Topic.messageTimeFormatString)\n // );\n const timeStamp = new Date(message.rec);\n this.initialiseSensorCollection(sensorName, dataInterpretation);\n\n try {\n if (sensorName == \"pt1\") {\n App.Topic.messagesWithTimestamps[sensorName][dataInterpretation].push([\n new Date(timeStamp).getTime(),\n +message.val[\"pt1\"][\"tmp\"],\n ]);\n } else if (sensorName == \"sht\") {\n App.Topic.messagesWithTimestamps[\"hmd\"][dataInterpretation].push([\n new Date(timeStamp).getTime(),\n +message.val[\"sht\"][\"tmp\"],\n ]);\n App.Topic.messagesWithTimestamps[\"tmp\"][dataInterpretation].push([\n new Date(timeStamp).getTime(),\n +message.val[\"sht\"][\"tmp\"],\n ]);\n } else if (sensorName == \"psu\") {\n App.Topic.messagesWithTimestamps[\"pwr-in\"][dataInterpretation].push([\n new Date(timeStamp).getTime(),\n +message.val[\"psu\"][\"pwr-in\"],\n ]);\n App.Topic.messagesWithTimestamps[\"prot-batt\"][dataInterpretation].push([\n new Date(timeStamp).getTime(),\n +message.val[\"psu\"][\"prot-batt\"],\n ]);\n } else if (sensorName == \"tmp\" && App.Topic.isAStatusTopic()) {\n if (message.val[\"tmp\"] != undefined) {\n if (message.val[\"tmp\"][\"brd\"] != undefined) {\n if (\n App.Topic.messagesWithTimestamps[\"tmp\"][dataInterpretation] ==\n undefined\n ) {\n App.Topic.messagesWithTimestamps[\"tmp\"][dataInterpretation] = [];\n }\n App.Topic.messagesWithTimestamps[\"tmp\"][dataInterpretation].push([\n new Date(timeStamp).getTime(),\n +message.val[\"tmp\"][\"brd\"],\n ]);\n } else if (message.val[\"tmp\"][\"hst\"] != undefined) {\n if (\n App.Topic.messagesWithTimestamps[\"tmp\"][dataInterpretation] ==\n undefined\n ) {\n App.Topic.messagesWithTimestamps[\"tmp\"][dataInterpretation] = [];\n }\n App.Topic.messagesWithTimestamps[\"tmp\"][dataInterpretation].push([\n new Date(timeStamp).getTime(),\n +message.val[\"tmp\"][\"hst\"],\n ]);\n }\n }\n } else if (sensorName == \"up\") {\n if (\n message.val[\"up\"] != undefined &&\n message.val[\"up\"][\"load\"] != undefined\n ) {\n if (\n App.Topic.messagesWithTimestamps[\"up\"][dataInterpretation] ==\n undefined\n ) {\n App.Topic.messagesWithTimestamps[\"up\"][dataInterpretation] = [];\n }\n App.Topic.messagesWithTimestamps[\"up\"][dataInterpretation].push([\n new Date(timeStamp).getTime(),\n +message.val[\"up\"][\"load\"][\"av5\"],\n ]);\n }\n } else if (App.Topic.isSimpleValue(sensorName)) {\n App.Topic.messagesWithTimestamps[sensorName][dataInterpretation].push([\n new Date(timeStamp).getTime(),\n +message.val[sensorName],\n ]);\n } else {\n App.Topic.messagesWithTimestamps[sensorName][dataInterpretation].push([\n new Date(timeStamp).getTime(),\n +message.val[sensorName][\"cnc\"],\n ]);\n } \n } catch(error){\n console.log(`I got an error getting the message with timestamp. sensorName: ${sensorName}.`);\n console.log('The message is:');\n console.log(message);\n console.log(`The error is ${error}`);\n App.Topic.messagesWithTimestamps[sensorName][dataInterpretation].push([\n new Date(timeStamp).getTime(),\n null]);\n }\n \n }\n\n static getMaxValueForSensor(sensorName, dataInterpretation, messages) {\n var values = [];\n try {\n if (sensorName == \"prot-batt\") {//Return highest max as these are plotted on the same axis\n let pwrInReadings = Object.entries(App.Topic.processedMessages[\"psu\"]['reported'].readings).map(r => r[1][0]);\n let pwrInMax = Math.max.apply(null, pwrInReadings);\n let prottBattReadings = Object.entries(App.Topic.processedMessages[\"psu\"]['reported'].readings).map(r => r[1][1]);\n let prottBattMax = Math.max.apply(null, prottBattReadings);\n \n return Math.max.apply(null, [pwrInMax, prottBattMax])+10;\n } else if (sensorName == \"hmd\" && App.Topic.isASHT()) {\n let hdmReadings = Object.entries(App.Topic.processedMessages[\"sht\"]['reported'].readings).map(r => r[1][0]);\n return Math.max.apply(null, hdmReadings);\n } else if (sensorName == \"tmp\" && App.Topic.isASHT()) {\n let tmpReadings = Object.entries(App.Topic.processedMessages[\"sht\"]['reported'].readings).map(r => r[1][1]);\n return Math.max.apply(null, tmpReadings);\n } else {\n // get the max of the DI passed in.\n //if(App.Topic.processedMessages[sensorName][dataInterpretation] != undefined && Object.keys(App.Topic.processedMessages[sensorName][dataInterpretation]['readings']).length != 0){\n // return Math.max(...Object.values(App.Topic.processedMessages[sensorName][dataInterpretation]['readings']))\n //} else {\n // return Math.max(...Object.values(App.Topic.processedMessages[sensorName]['reported']['readings'])) \n //}\n \n //if there is more than one data interpretation for the sensor then I should get the max of both data interpretations\n //how many data interpretations are there\n const dataInterpretations = App.Topic.dataInterpretations;\n if(dataInterpretations.length > 1){\n // get the max of the max of all data interpretations\n let maxes = [];\n for(let i=0;i < dataInterpretations.length;i++){\n maxes.push(Object.values(App.Topic.processedMessages[sensorName][dataInterpretations[i]].readings))\n }\n return Math.max(...maxes);\n } else {\n return Math.max(...Object.values(App.Topic.processedMessages[sensorName]['reported']['readings']));\n }\n }\n } catch (error) {\n console.log(\"I got an error getting max value for: \" + sensorName + `${error}`);\n }\n return Math.max.apply(null, values);\n }\n\n static getMinValueForSensor(sensorName, dataInterpretation, subPart=undefined) {\n var values = [];\n try {\n if (sensorName == \"prot-batt\") {\n // let pwrInReadings = Object.entries(App.Topic.processedMessages[\"psu\"]['default'].readings).map(r => r[1][0]);\n // let pwrInMax = Math.max.apply(null, pwrInReadings);\n // let prottBattReadings = Object.entries(App.Topic.processedMessages[\"psu\"]['default'].readings).map(r => r[1][1]);\n // let prottBattMax = Math.max.apply(null, prottBattReadings);\n \n // return Math.max.apply(null, [pwrInMax, prottBattMax])+10;\n \n } else if (sensorName == \"hmd\" && App.Topic.isASHT()) {\n // let hdmReadings = Object.entries(App.Topic.processedMessages[\"sht\"]['default'].readings).map(r => r[1][0]);\n // return Math.max.apply(null, hdmReadings);\n \n } else if (sensorName == \"tmp\" && App.Topic.isASHT()) {\n // let tmpReadings = Object.entries(App.Topic.processedMessages[\"sht\"]['default'].readings).map(r => r[1][1]);\n // return Math.max.apply(null, tmpReadings);\n } else if(sensorName == 'sht'){\n if(subPart == 'tmp'){\n let tmpReadings = Object.entries(App.Topic.processedMessages[\"sht\"]['reported'].readings).map(r => r[1][1]);\n let min = Math.min.apply(null, tmpReadings);\n if(min > 0){\n return 0\n } else {\n return min\n }\n }\n } else {\n const dataInterpretations = App.Topic.dataInterpretations;\n\n //if(dataInterpretations.length > 1){\n // get the min of all data interpretations\n let mins = new Array();\n //for(let i=0;i < dataInterpretations.length;i++){\n mins.push(Object.values(App.Topic.processedMessages[sensorName][DataInterpretation.whatDataInterpretationIsBeingDisplayed(sensorName)].readings))\n //}\n return Math.min(...mins.flat());\n // } else {\n // return Math.min(...Object.values(App.Topic.processedMessages[sensorName]['reported']['readings']));\n // }\n }\n } catch (error) {\n console.log(\"I got an error getting min value for: \" + sensorName + `${error}`);\n }\n }\n\n static initialiseSensorCollection(sensorName, dataInterpretation) {\n if (sensorName == \"sht\") {\n if (App.Topic.messagesWithTimestamps[\"hmd\"] === undefined) {\n App.Topic.messagesWithTimestamps[\"hmd\"] = {};\n App.Topic.messagesWithTimestamps[\"hmd\"][dataInterpretation] = [];\n } else if (\n App.Topic.messagesWithTimestamps[\"hmd\"][dataInterpretation] == undefined\n ) {\n App.Topic.messagesWithTimestamps[\"hmd\"][dataInterpretation] = [];\n }\n if (App.Topic.messagesWithTimestamps[\"tmp\"] === undefined) {\n App.Topic.messagesWithTimestamps[\"tmp\"] = {};\n App.Topic.messagesWithTimestamps[\"tmp\"][dataInterpretation] = [];\n } else if (\n App.Topic.messagesWithTimestamps[\"tmp\"][dataInterpretation] == undefined\n ) {\n App.Topic.messagesWithTimestamps[\"tmp\"][dataInterpretation] = [];\n }\n } else if (sensorName == \"psu\") {\n if (App.Topic.messagesWithTimestamps[\"pwr-in\"] == undefined) {\n App.Topic.messagesWithTimestamps[\"pwr-in\"] = {};\n App.Topic.messagesWithTimestamps[\"pwr-in\"][dataInterpretation] = [];\n }\n if (App.Topic.messagesWithTimestamps[\"prot-batt\"] == undefined) {\n App.Topic.messagesWithTimestamps[\"prot-batt\"] = {};\n App.Topic.messagesWithTimestamps[\"prot-batt\"][dataInterpretation] = [];\n }\n }\n }\n}\n\nexport default MessageCollections;\n","\"use strict\";\n\nclass MessageProcessor {\n static initialiseProcessedMessages(sensorName) {\n if (App.Topic.processedMessages[sensorName] == undefined) {\n App.Topic.processedMessages[sensorName] = {}; //initialise array for messages for this value\n }\n }\n\n static initialiseDataInterpretation(sensorName, dataInterpretation) {\n if (App.Topic.processedMessages[sensorName][dataInterpretation] === undefined) {\n App.Topic.processedMessages[sensorName][dataInterpretation] = {\n timeStamps: [],\n readings: {},\n average: undefined,\n };\n }\n }\n\n static processMessages(rawMessages = App.Topic.allMessages) {\n const topicInterval = App.Topic.interval;\n\n //Initialisation\n App.Topic.valuesPresent.forEach(function (sensorName) { \n MessageProcessor.initialiseProcessedMessages(sensorName);\n\n const dataInterpretations = App.Topic.dataInterpretations;\n for (let i = 0; i < dataInterpretations.length; i++) {\n const dataInterpretation = dataInterpretations[i];\n MessageProcessor.initialiseDataInterpretation(\n sensorName,\n dataInterpretation\n );\n\n var messages = {\n timeStamps: [],\n readings: {},\n average: undefined,\n averages: {},\n };\n //Loop through the raw messages\n for (let ii = 0; ii < rawMessages.length; ii++) {\n //Load a message from the raw messages\n const json = rawMessages[ii];\n\n //Process the message\n if (MessageValue.valueFor(sensorName, json, dataInterpretation) != undefined) {\n MessageProcessor.processMessage(messages, json, dataInterpretation, sensorName, topicInterval);\n }\n }\n //All messages have been processed\n //Now append local collection to global processed messages collection\n if (\n App.Topic.processedMessages[sensorName][dataInterpretation].timeStamps\n .length > 0\n ) {\n // Timestamps\n App.Topic.processedMessages[sensorName][\n dataInterpretation\n ].timeStamps = App.Topic.processedMessages[sensorName][\n dataInterpretation\n ].timeStamps.concat(messages.timeStamps);\n //Readings\n Object.assign(\n App.Topic.processedMessages[sensorName][dataInterpretation]\n .readings,\n messages.readings\n );\n //Readings\n Object.assign(\n App.Topic.processedMessages[sensorName][dataInterpretation]\n .averages,\n messages.averages\n );\n } else {\n App.Topic.processedMessages[sensorName][\n dataInterpretation\n ].timeStamps = messages.timeStamps;\n App.Topic.processedMessages[sensorName][dataInterpretation].readings =\n messages.readings;\n App.Topic.processedMessages[sensorName][dataInterpretation].averages =\n messages.averages;\n }\n MessageProcessor.calculateAverage(sensorName, dataInterpretation);\n }\n });\n }\n\n static processMessage(messages, json, dataInterpretation, sensorName, topicInterval) {\n if (messages.timeStamps.length == 0) {\n const firstMessage = MessageProcessor.buildProcessedMessage(\n json,\n sensorName,\n dataInterpretation\n );\n\n if (firstMessage == undefined) {\n console.log(\"Unable to process this message.\");\n console.log(json);\n return false;\n }\n messages.averages[firstMessage[0].toISOString()] = null;\n MessageProcessor.addMessageToCollection(firstMessage, messages);\n } else if (\n messages.timeStamps[messages.timeStamps.length - 1] != undefined\n ) {\n //surely this means is there a message before this one?\n\n let lastMessageTimestamp =\n messages.timeStamps[messages.timeStamps.length - 1];\n let messageInterval = MessageProcessor.messageTimeDifference(\n lastMessageTimestamp,\n json.rec\n );\n //if a gap is detected then the processed messages array is padded.\n if (messageInterval > 2 * topicInterval) {\n messages = MessageProcessor.padMessages(\n messages,\n topicInterval,\n Math.round(messageInterval / App.Topic.valueInterval),\n sensorName\n );\n //And calculate the average for the segment just finished\n }\n\n //Make sure next message is in the future\n if (\n new Date(json.rec).getTime() >\n new Date(lastMessageTimestamp).getTime()\n ) {\n let nextMessage = MessageProcessor.buildProcessedMessage(\n json,\n sensorName,\n dataInterpretation\n );\n messages.averages[nextMessage[0].toISOString()] = null;\n MessageProcessor.addMessageToCollection(nextMessage, messages);\n } else {\n console.log(\"Next message is in the past. Skipping.\");\n }\n }\n }\n\n static buildProcessedMessage(message, value, dataInterpretation) {\n // var timeStamp = new Date(\n // moment(message.rec, App.Topic.messageTimeFormatString)\n // );\n var timeStamp = new Date(message.rec);\n\n if (App.Topic.firstMessageTimeRecieved == null) {\n App.Topic.firstMessageTimeRecieved = timeStamp;\n }\n //These are used for the Gauges\n MessageCollections.messagesWithTimestamps(\n value,\n message,\n dataInterpretation\n );\n\n App.Topic.lastMessageTimeRecieved = timeStamp;\n\n var sensorValue = MessageValue.valueFor(value, message, dataInterpretation);\n if (typeof sensorValue == \"number\") {\n return [timeStamp, sensorValue];\n } else if (sensorValue == null) {\n return [timeStamp, null];\n } else {\n return [timeStamp, sensorValue[0], sensorValue[1]];\n }\n }\n\n static addMessageToCollection(message, collection) {\n const timestamp = message[0].toISOString();\n collection.timeStamps.push(timestamp);\n if (message.length == 3) {\n collection.readings[timestamp] = [message[1], message[2]];\n } else {\n collection.readings[timestamp] = message[1];\n }\n }\n\n static messageTimeDifference(message1, message2) {\n if (message1 == undefined || message2 == undefined) {\n return 0;\n }\n // let difference = Math.round(\n // moment(message2, App.Topic.messageTimeFormatString).diff(\n // moment(message1, App.Topic.messageTimeFormatString)\n // ) / 1000\n // );\n let difference = Math.round(\n (new Date(message2).getTime() - new Date(message1).getTime()) / 1000\n ); \n return difference;\n }\n\n static padMessages(messages, intervalSeconds, howMany, sensorName) {\n var timeStamp = messages.timeStamps[messages.timeStamps.length - 1];\n for (var i = 0; i < howMany; i++) {\n let nextTimeStamp = moment(timeStamp).add(intervalSeconds, \"s\");\n messages.timeStamps.push(nextTimeStamp);\n if (sensorName == \"sht\" || sensorName == \"psu\") {\n messages.readings[nextTimeStamp] = [null, null];\n } else {\n messages.readings[nextTimeStamp] = null;\n }\n }\n return messages;\n }\n\n static getMinValueFor(value, dataInterpretation) {\n let values = Object.values(\n App.Topic.processedMessages[value][dataInterpretation].readings\n );\n return Math.min.apply(null, values) - 10;\n }\n\n static calculateMaxValue(sensorName, dataInterpretation, readings) {\n App.Topic.processedMessages[sensorName][\n dataInterpretation\n ].maxReading = Math.max.apply(null, readings);\n }\n\n static calculateAverage(sensorName, dataInterpretation) {\n //need to detect gaps and then write to the averages hash\n let readings =\n App.Topic.processedMessages[sensorName][dataInterpretation].readings;\n let times =\n App.Topic.processedMessages[sensorName][dataInterpretation].timeStamps;\n let averages =\n App.Topic.processedMessages[sensorName][dataInterpretation].averages;\n\n let currentSegment = { sum: 0, counter: 0, times: [] };\n let average = null;\n\n for (let i = 0; i < times.length; i++) {\n if (readings[times[i]] != null) {\n currentSegment.sum += readings[times[i]];\n currentSegment.counter++;\n currentSegment.times.push(times[i]);\n } else {\n if (currentSegment.times.length == 0) {\n // this is a gap\n continue;\n }\n average = currentSegment.sum / currentSegment.counter;\n\n //set all times to this new average value\n for (let ii = 0; ii < currentSegment.times.length; ii++) {\n averages[currentSegment.times[ii]] = average;\n }\n currentSegment.sum = 0;\n currentSegment.counter = 0;\n currentSegment.times = [];\n }\n }\n //reached the end of messages and no gaps found\n if (currentSegment.times.length > 0) {\n average = currentSegment.sum / currentSegment.counter;\n for (let ii = 0; ii < currentSegment.times.length; ii++) {\n averages[currentSegment.times[ii]] = average;\n }\n }\n }\n}\n\nexport default MessageProcessor;\n","\"use strict\";\n\nimport DataInterpretation from \"./data_interpretation\";\n\nclass Graph {\n constructor() {}\n\n static displayGraphs() {\n App.Topic.time1 = 0;\n App.Topic.time1 = performance.now();\n var chartsDiv = document.getElementById(\"charts_div\");\n //Clear out old graphs\n if (chartsDiv != undefined) {\n while (chartsDiv.hasChildNodes()) {\n chartsDiv.removeChild(chartsDiv.lastChild);\n }\n\n App.Topic.valuesPresent.forEach(function (sensor) {\n Graph.displayValueGraph(sensor, DataInterpretation.whatDataInterpretationIsBeingDisplayed(sensor));\n });\n\n //\n //Other stuff from here, not core graph display so should be moved.\n //\n\n if (App.Topic.isAStatusTopic()) {\n App.Topic.displayUptimeNumber();\n App.Topic.displayMap();\n var lastMessage =\n App.Topic.allMessages[App.Topic.allMessages.length - 1];\n //var messagePayload = lastMessage.payload;\n TopicMap.gpsQualityDisplay(lastMessage);\n }\n App.Topic.time2 = 0;\n App.Topic.time2 = performance.now();\n document.getElementsByClassName('renderTime')[0].textContent = `Time to render graphs is ${((App.Topic.time2 - App.Topic.time1)/1000).toFixed(2)} seconds`;\n App.hideModal();\n\n if (App.Topic.fetchedLastWrittenData) {\n App.Topic.lastWrittenDataDetected();\n } else {\n document.getElementById(\"older_data_message\").style.display = \"none\";\n document.getElementById(\"refresh-button-container\").style.display =\n \"block\";\n }\n if (App.Topic.allMessages.length == 0) {\n alert(\"No data has been found for the specified time period.\");\n return false;\n }\n App.Topic.constructAndDisplayShareableUrl();\n\n //display gauge graphs\n //this.displayGauges();\n\n App.Topic.constructAndDisplayCSVlink();\n }\n }\n\n /** Display a graph for a given sensor \n * @param {string} sensor - The name of the sensor to display a graph for\n */\n static displayValueGraph(sensor, dataInterpretation = \"reported\") {\n //Prepare the html\n var chart_div = Graph.getChartContainer(sensor);\n let graph_div = Graph.getGraphDiv(sensor);\n\n chart_div.appendChild(graph_div);\n\n var charts_div = document.getElementById(\"charts_div\");\n charts_div.appendChild(chart_div);\n let sensorData = App.Topic.processedMessages[sensor];\n \n var data = new google.visualization.DataTable();\n Graph.setGraphColumns(data, sensor, sensorData); //If I do not have data for the data model then i shouldn't create a column for it.\n\n var chart = new google.visualization.ComboChart(graph_div);\n let chartDataSet = []; //array of data that the chart renders\n \n for (let i = 0; i < sensorData[\"reported\"].timeStamps.length; i++) {\n let timestamp = sensorData[\"reported\"].timeStamps[i];\n chartDataSet.push(Graph.constructGraphDatasetRow(sensorData, timestamp, sensor, dataInterpretation));\n }\n \n try {\n data.addRows(chartDataSet);\n } catch (e) {\n console.log(\"caught an error\" + e);\n console.log(\"Value is \" + sensor);\n console.log(chartDataSet[0]);\n }\n let options = Graph.graphOptions(sensor, data, dataInterpretation);\n\n var dateFormatter = new google.visualization.DateFormat({\n pattern: \"yyyy-MM-dd HH:mm:ss\",\n });\n dateFormatter.format(data, 0);\n var chartWrapper = new google.visualization.ChartWrapper({\n chartType: \"ComboChart\",\n dataTable: data,\n options: options,\n containerId: \"graph\" + sensor,\n });\n chartWrapper.draw();\n //chart.draw(data, options);\n App.Topic.graphs.push(chartWrapper);\n //Topic.showDataInterpretationName();\n DataInterpretation.showDataInterpretationName();\n }\n\n static getChartContainer(sensorName) {\n if (document.getElementById(\"chartContainer\" + sensorName) == undefined) {\n var chart_div = document.createElement(\"div\");\n chart_div.setAttribute(\"class\", \"chart chart\" + sensorName);\n chart_div.setAttribute(\"id\", \"chartContainer\" + sensorName);\n } else {\n var chart_div = document.getElementById(\"chartContainer\" + sensorName);\n }\n return chart_div;\n }\n\n static getGraphDiv(sensorName) {\n if (document.getElementById(\"graph\" + sensorName) == undefined) {\n var graph_div = document.createElement(\"div\");\n graph_div.setAttribute(\"id\", \"graph\" + sensorName);\n } else {\n document.getElementById(\"graph\" + sensorName).remove();\n var graph_div = document.createElement(\"div\");\n graph_div.setAttribute(\"id\", \"graph\" + sensorName);\n }\n\n if (\n (document.querySelectorAll(\"#charts_div .gauge\").length > 0 &&\n document.querySelectorAll(\"#charts_div .gauge\")[0].style.display ==\n \"\") ||\n App.Topic.displayGaugesFlag\n ) {\n graph_div.setAttribute(\"class\", \"graph graph\" + sensorName);\n } else {\n graph_div.setAttribute(\"class\", \"graph-wide xgraph\" + sensorName);\n }\n\n return graph_div;\n }\n\n static setGraphColumns(data, value, sensorData) {\n data.addColumn(\"datetime\", \"X\");\n \n if (value == \"sht\") {\n data.addColumn(\"number\", valueLabels[\"hmd\"][\"label\"]);\n data.addColumn(\"number\", valueLabels[\"tmp\"][\"label\"]);\n } else if (value == \"psu\") {\n data.addColumn(\"number\", \"Input\");\n data.addColumn(\"number\", \"Battery\");\n } else if (value == \"tmp\" && App.Topic.isAStatusTopic()) {\n data.addColumn(\"number\", \"avg\");\n data.addColumn(\"number\", valueLabels[\"internalTmp\"][\"label\"]);\n } else {\n if (valueLabels[value] != undefined) {\n data.addColumn(\"number\", \"avg\");\n let dataInterpretations = Graph.getDataInterpretationNames();\n if(this.missingModelData(sensorData) && dataInterpretations.length > 1){\n dataInterpretations.pop();\n }\n for (let i = 0; i < dataInterpretations.length; i++) {\n if(value == 'up'){\n data.addColumn(\"number\", 'cpu');\n } else if(value == 'sig'){\n data.addColumn(\"number\", 'quality');\n } else if(value == 'sfr'){\n data.addColumn(\"number\", 'sfr');\n } else if(i > 0){//we are showing both\n data.addColumn(\"number\", 'interpreted');\n } else{\n if(App.Topic.showReported === true || Graph.getDataInterpretationNames()[0] == ['reported'] || this.missingModelData(sensorData)){\n data.addColumn(\"number\", 'reported');\n } else {\n data.addColumn(\"number\", 'interpreted');\n }\n }\n }\n } else {\n data.addColumn(\"number\", value);\n }\n }\n }\n\n static missingModelData(sensorData){\n //let modelName = DataInterpretation.highestPriorityDataInterpretationName()\n if(App.Topic.dataInterpretations.length == 1){\n return false\n }\n let modelName = App.Topic.dataInterpretations[App.Topic.dataInterpretations.length - 1];\n if(sensorData[modelName]['timeStamps'].length == 0){\n return true;\n } else {\n return false;\n }\n }\n\n static lineOpacity(dataInterpretations, dataInterpretation) {\n if(dataInterpretation == 'reported'){\n //return 'opacity: 0.5;'\n return 'opacity: 1.0;color: #cccccc;'\n } else {\n return 'opacity: 1.0;'\n }\n // if(dataInterpretations.length > 1 && dataInterpretation != 'reported'){\n // return 'opacity: 1.0;'\n // } else if(dataInterpretations.length == 1 && dataInterpretation != 'reported'){\n // return 'opacity: 1.0;'\n // } else {\n // return 'opacity: 0.5;'\n // }\n }\n\n static graphOptions(value, data, dataInterpretation) {\n if (value == \"sht\") {\n var options = {\n title: value,\n seriesType: \"line\",\n series: {\n 0: {\n targetAxisIndex: 0,\n color: valueLabels[\"hmd\"][\"colour\"],\n },\n 1: {\n targetAxisIndex: 1,\n color: valueLabels[\"tmp\"][\"colour\"],\n },\n },\n vAxes: {\n 0: {\n title: \"%\",\n viewWindowMode: \"explicit\",\n viewWindow: {\n max: App.Topic.nearestUp(\"hmd\", 10, dataInterpretation),\n min: 0,\n },\n },\n 1: {\n title: \"Temp (Celsius)\",\n viewWindow: {\n max: App.Topic.nearestUp(\"tmp\", 10, dataInterpretation),\n min: MessageCollections.getMinValueForSensor(value, dataInterpretation, 'tmp'),\n },\n },\n },\n hAxis: {\n format: \"yyyy-MM-dd HH:mm\",\n },\n title: App.Labels.longLabelForValue(value),\n };\n } else if (value == \"psu\") {\n var options = {\n title: \"Device power\",\n seriesType: \"line\",\n series: {\n 0: { targetAxisIndex: 0 },\n 1: { targetAxisIndex: 0 },\n },\n vAxes: {\n 0: {\n title: \"V\",\n viewWindowMode: \"explicit\",\n viewWindow: {\n max: App.Topic.nearestUp(\"prot-batt\", 10),\n //max: Topic.getMaxYValue(value, dataInterpretation),\n min: 0,\n },\n },\n },\n hAxis: {\n format: \"yyyy-MM-dd HH:mm\",\n },\n };\n } else {\n var options = {\n series: {\n 0: {\n color: \"#CCC\",\n lineWidth: 2.0,\n visibleInLegend: false\n },\n 1: {\n //color: valueLabels[value][\"colour\"],\n color: Graph.calculateLineColour(value, 1),\n //color: \"#FFF\",\n lineWidth: 2.0\n },\n 2: {\n //color: valueLabels[value][\"colour\"],\n color: Graph.calculateLineColour(value, 2),\n //color: \"#CCC\",\n lineWidth: 2.0\n },\n },\n hAxis: {\n format: \"yyyy-MM-dd HH:mm\",\n },\n vAxes: {\n 0: {\n title: valueLabels[value][\"unit\"],\n viewWindowMode: \"explicit\",\n viewWindow: {\n max: Topic.getMaxYValue(value, dataInterpretation),\n min: Topic.getMinYValue(value, dataInterpretation),\n },\n },\n },\n title: Graph.graphTitle(value)\n };\n }\n return options;\n }\n\n static calculateLineColour(sensorName, lineNumber){\n const defaultColourForSensor = valueLabels[sensorName][\"colour\"];\n // If the data interpretation model for the sensor is reported then always show it as grey\n // if(DataInterpretation.whatDataInterpretationIsBeingDisplayed(sensorName) == 'reported'){\n // return \"#CCCCCC\"\n // }\n if(App.Topic.showReported === true && lineNumber === 1){\n return \"#CCCCCC\"\n } else {\n return defaultColourForSensor;\n }\n }\n \n static graphTitle(sensorName){\n return App.Labels.longLabelForValue(sensorName); \n }\n\n static getAverageSensorValue(sensorData) {\n let dataInterpretations = Graph.getDataInterpretationNames();\n \n let lastDataInterpretationName =\n dataInterpretations[dataInterpretations.length - 1];\n return sensorData[lastDataInterpretationName].average;\n }\n\n // In the future when there are more than 2 DIs this will work out which ones are actually being plotted\n // Use this as a proxy to a better method.\n static getDataInterpretationNames() {\n if(App.Topic.showReported === true || App.Topic.dataInterpretations.length == 1){\n return App.Topic.dataInterpretations.slice(0, App.Topic.dataInterpretations.length);//return a copy, not a reference\n } else if(App.Topic.dataInterpretations.includes('s1/2020h1')){\n return ['s1/2020h1'];\n } else {\n return App.Topic.dataInterpretations.slice(1, App.Topic.dataInterpretations.length)\n }\n }\n\n static constructGraphDatasetRow(sensorData, timestamp, sensorName, dataInterpretation) {\n let dataInterpretations = Graph.getDataInterpretationNames();\n\n if(this.missingModelData(sensorData) && !App.Topic.showReported === true){\n dataInterpretations.unshift('reported');\n }\n let values = [];\n if(sensorName == 'sht' || sensorName == 'psu'){\n let rowData = sensorData['reported'].readings[timestamp];\n if(rowData == undefined){\n values = values.concat([null, null]);\n } else {\n values = values.concat([rowData[0], rowData[1]]);\n }\n } else { \n for (let i = 0; i < dataInterpretations.length; i++) {\n if(sensorData[dataInterpretations[i]].timeStamps.length != 0){\n let rowData = sensorData[dataInterpretations[i]].readings[timestamp];\n values = values.concat([rowData]);\n }\n }\n }\n \n if(sensorName == 'sht'){\n return [\n new Date(timestamp),\n ].concat(values);\n } else if(sensorName == 'psu'){\n return [\n new Date(timestamp),\n ].concat(values);\n } else {\n if(this.missingModelData(sensorData)){\n return [\n new Date(timestamp),\n App.Topic.processedMessages[sensorName]['reported']['averages'][timestamp],\n ].concat(values);\n } else {\n return [\n new Date(timestamp),\n App.Topic.processedMessages[sensorName][DataInterpretation.getDataInterpretationName()]['averages'][timestamp],\n ].concat(values);\n }\n \n }\n \n }\n\n static maxYValue(sensorName, dataInterpretation) {\n if (sensorName == \"hmd\") {\n var maxValue =\n MessageCollections.getMaxValueForSensor(\"hmd\", dataInterpretation);\n return maxValue + (10 - (maxValue % 10));\n } else if (sensorName == \"tmp\") {\n var maxValue =\n MessageCollections.getMaxValueForSensor(\"tmp\", dataInterpretation);\n return maxValue + (10 - (maxValue % 10));\n } else if (sensorName == \"pwr-in\") {\n return 20;\n } else if (sensorName == \"prot-batt\") {\n return 10;\n } else if (sensorName == \"up\") {\n var maxValue = MessageCollections.getMaxValueForSensor(\n sensorName,\n dataInterpretation\n );\n return maxValue + 1;\n } else if (sensorName == \"tmp\" && App.Topic.isAStatusTopic()) {\n return App.Topic.nearestUp(\"tmp\", 10, \"reported\");\n } else if (valueLabels[sensorName]['maxY'] == 'round'){\n var maxValue = MessageCollections.getMaxValueForSensor(\n sensorName,\n dataInterpretation\n );\n return Math.round(maxValue) + 1;\n } else {\n var maxValue = MessageCollections.getMaxValueForSensor(\n sensorName,\n dataInterpretation\n );\n //below pads the max value where it is small\n if (maxValue < 1) {\n return maxValue;\n }\n if (maxValue / 6 > 100) {\n return Math.ceil(maxValue / 100) * 100;\n } else {\n return Math.ceil(maxValue / 10) * 10;\n }\n }\n }\n\n static displayGauges() {\n App.Topic.valuesPresent.forEach(function (value) {\n if (value != \"psu\" && value != \"sht\") {\n var regressionCalculator = new RegressionCalculator();\n //console.log(`Midpoint is ${regressionCalculator.getMidPoint(value)}`);\n var yValue = regressionCalculator.predictY(\n value,\n regressionCalculator.getMidPoint(value)\n );\n }\n //console.log(`yValue is ${yValue}`);\n if (value != \"psu\" && value != \"sht\") {\n var data = google.visualization.arrayToDataTable([\n [\"Label\", \"Value\"],\n [valueLabels[value][\"unit\"], yValue],\n ]);\n }\n\n var options = {\n width: 400,\n height: 120,\n // redFrom: 90,\n // redTo: 100,\n // yellowFrom: 75,\n // yellowTo: 90,\n max: MessageCollections.getMaxValueForSensor(value, DataInterpretation.getDataInterpretationName()),\n minorTicks: 5,\n };\n\n var gauge_div = document.createElement(\"div\");\n\n var gauges_div = document.getElementById(\"gauges_div\");\n gauges_div.appendChild(gauge_div);\n\n if (value != \"psu\" && value != \"sht\") {\n var gauge = new google.visualization.Gauge(gauge_div);\n gauge.draw(data, options);\n\n var gaugeValue = document.createElement(\"div\"); //This is not going to be the Unit but rather the 'value', eg pm10\n gaugeValue.setAttribute(\"class\", \"gauge-value\");\n gaugeValue.innerHTML = value; //valueLabels[value][\"unit\"];\n }\n var imageContainer = document.createElement(\"div\");\n imageContainer.setAttribute(\"class\", \"imageContainer\");\n\n var gaugeContainer = document.createElement(\"div\");\n gaugeContainer.setAttribute(\"class\", \"gaugeContainer\");\n gaugeContainer.appendChild(gauge_div);\n if (value != \"psu\" && value != \"sht\") {\n gaugeContainer.appendChild(gaugeValue);\n }\n var outerContainer = document.createElement(\"div\");\n outerContainer.setAttribute(\n \"class\",\n \"col-md-\" +\n 24 / Object.keys(App.Topic.processedMessages).length +\n \" centred-content gauge\"\n );\n outerContainer.appendChild(gaugeContainer);\n\n gauges_div.appendChild(outerContainer);\n const graphContainer = document.getElementsByClassName(\n \"chart\" + value\n )[0];\n\n //const inlineGaugeContainer = outerContainer.cloneNode(true);\n if (document.getElementById(\"gaugeContainer\" + value)) {\n document.getElementById(\"gaugeContainer\" + value).remove();\n }\n inlineGaugeContainer.setAttribute(\"class\", \"gauge gauge\" + value);\n if (App.Topic.displayGaugesFlag == true) {\n inlineGaugeContainer.style.display = \"inline-block\";\n }\n\n graphContainer.appendChild(inlineGaugeContainer);\n });\n }\n\n static nearestUp(value, roundUpTo, dataInterpretation) {\n var maxValue =\n MessageCollections.getMaxValueForSensor(value, dataInterpretation);\n return maxValue + (roundUpTo - (maxValue % roundUpTo));\n }\n}\nexport default Graph;\n","\"use strict\";\n\nclass TimeHelper{\n static minutesAgo(minutes){\n const ago = moment().subtract(minutes, 'minutes');\n return ago.toISOString();\n }\n}\nexport default TimeHelper;","const valueLabels = {\n NO2: {\n label: \"NO\\u2082\",\n longLabel: \"Nitrogen dioxide\",\n unit: \"ppb\",\n colour: \"#7E391E\",\n dataPath: 'NO2',\n graphMinY: 'lte0',\n },\n NO: {\n label: \"NO\",\n longLabel: \"Nitric oxide\",\n unit: \"ppb\",\n colour: \"#39646A\",\n dataPath: 'NO',\n graphMinY: 'lte0',\n },\n Ox: {\n label: \"O\\u2083\",\n longLabel: \"Ozone\",\n unit: \"ppb\",\n colour: \"#978664\",\n dataPath: 'Ox',\n graphMinY: 'lte0',\n },\n O2: {\n label: \"O\\u2082\",\n unit: \"ppb\",\n dataPath: 'O2',\n graphMinY: 'lte0',\n },\n SO2: {\n label: \"SO\\u2082\",\n longLabel: \"Sulphur dioxide\",\n unit: \"ppb\",\n colour: \"#6F2416\",\n dataPath: 'SO2',\n graphMinY: 'lte0',\n },\n H2S: {\n label: \"H\\u2082S\",\n longLabel: \"Hydrogen sulphide\",\n unit: \"ppb\",\n colour: \"#A44E2C\",\n dataPath: 'H2S',\n graphMinY: 'lte0',\n },\n CO: {\n label: \"CO\",\n longLabel: \"Carbon monoxide\",\n unit: \"ppb\",\n colour: \"#416C3E\",\n dataPath: 'CO',\n graphMinY: 'lte0',\n },\n CO2: {\n label: \"CO\\u2082\",\n longLabel: \"Carbon dioxide\",\n unit: \"ppm\",\n colour: \"#000000\",\n dataPath: 'CO2',\n graphMinY: 'lte0',\n },\n VOC: {\n label: \"VOC\",\n longLabel: \"Volatile organic compounds\",\n unit: \"ppb\",\n colour: \"#929292\",\n graphMinY: 0,\n dataPath: 'VOC',\n graphMinY: 0,\n },\n pt1: {\n label: \"pt1\",\n unit: \"\\u00B0C\",\n dataPath: 'pt1.tmp'\n },\n hmd: {\n label: \"Humidity\",\n longLabel: \"Relative humidity\",\n unit: \"%\",\n colour: \"#1E4C7C\",\n graphMinY: 0,\n dataPath: 'hmd',\n },\n tmp: {\n label: \"Temp\",\n longLabel: \"Temperature\",\n colour: \"#A62B17\",\n unit: \"\\u00B0C\",\n dataPath: 'tmp',\n },\n internalTmp: {\n label: \"Internal Temperature\",\n longLabel: \"Internal temp\",\n colour: \"#A62B17\",\n unit: \"\\u00B0C\",\n },\n pA: {\n label: \"barometric pressure\",\n longLabel: \"Actual barometric pressure\",\n colour: \"#555555\",\n unit: \"KPa\",\n dataPath: 'bar.pA',\n maxY: 'round',\n minY: 'round',\n }, \n pm1: {\n label: \"PM\\u2081\",\n longLabel: \"PM\\u2081\",\n unit: \"\\u00B5g/m\\u00B3\",\n colour: \"#888888\",\n graphMinY: 0,\n dataPath: 'pm1',\n },\n pm2p5: {\n label: \"PM\\u2082\\u002E\\u2085\",\n longLabel: \"PM\\u2082\\u002E\\u2085\",\n unit: \"\\u00B5g/m\\u00B3\",\n colour: \"#555555\",\n graphMinY: 0,\n dataPath: 'pm2p5',\n },\n pm10: {\n label: \"PM\\u2081\\u2080\",\n longLabel: \"PM\\u2081\\u2080\",\n unit: \"\\u00B5g/m\\u00B3\",\n colour: \"#000000\",\n graphMinY: 0,\n dataPath: 'pm10',\n },\n sfr: {\n label: \"sfr\",\n longLabel: \"Sample flow rate\",\n unit: \"ml/S\",\n colour: \"#3d97e9\",\n graphMinY: 0,\n dataPath: 'sfr',\n }, \n up: {\n label: \"up\",\n longLabel: \"CPU load\",\n unit: \"\",\n colour: \"#2F4F4F\",\n graphMinY: 0,\n dataPath: 'up'\n },\n \"pwr-in\": {\n label: \"Supply Voltage\",\n longLabel: \"Supply Voltage\",\n unit: \"\",\n colour: \"#27408b\",\n graphMinY: 0,\n dataPath: 'psu.pwr-in'\n },\n \"prot-batt\": {\n label: \"Battery Voltage\",\n longLabel: \"Battery Voltage\",\n unit: \"\",\n colour: \"#436eee\",\n graphMinY: 0,\n dataPath: 'psu.prott-batt'\n },\n psu: {\n label: \"psu\",\n unit: \"\",\n dataPath: 'psu'\n },\n sht: {\n longLabel: \"Temperature and relative humidity\",\n label: \"sht\",\n unit: \"\",\n dataPath: 'sht',\n },\n sig: {\n longLabel: \"Modem signal quality\",\n label: \"sig\",\n unit: \"%\",\n dataPath: 'sig.quality',\n colour: '#888888',\n graphMinY: 0,\n graphMaxY: 110,\n }\n };\n\n export default valueLabels;","/* eslint no-console:0 */\n// This file is automatically compiled by Webpack, along with any other files\n// present in this directory. You're encouraged to place your actual application logic in\n// a relevant structure within app/javascript and only use these pack files to reference\n// that code so it'll be compiled.\n//\n// To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate\n// layout file, like app/views/layouts/application.html.erb\n\n// Uncomment to copy all static images under ../images to the output folder and reference\n// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)\n// or the `imagePath` JavaScript helper below.\n//\n// const images = require.context('../images', true)\n// const imagePath = (name) => images(name, true)\n\nimport CloudHelper from \"./cloud_helper\";\nwindow.CloudHelper = CloudHelper;\n\nimport Topic from \"./topic\";\nwindow.Topic = Topic;\n\nimport TopicAutoRefresher from \"./topic_auto_refresher\";\nwindow.TopicAutoRefresher = TopicAutoRefresher;\n\nimport TopicMessagesRetriever from \"./topic_messages_retriever\";\nwindow.TopicMessagesRetriever = TopicMessagesRetriever;\n\nimport RegressionCalculator from \"./regression_calculator\";\nwindow.RegressionCalculator = RegressionCalculator;\n\n// import Countdown from \"./countdown\";\n// window.Countdown = Countdown;\n\nimport TopicMap from \"./topic_map\";\nwindow.TopicMap = TopicMap;\n\nimport ChartToggler from \"./chart_toggler\";\nwindow.ChartToggler = ChartToggler;\n\nimport TopicTimeTool from \"./topic_time_tool\";\nwindow.TopicTimeTool = TopicTimeTool;\n\nimport Json2Csv from \"./json2csv\";\nwindow.Json2Csv = Json2Csv;\n\nimport ScsLogger from \"./scs_logger\";\nwindow.ScsLogger = ScsLogger;\n\nimport ScsConfig from \"./scs_config\";\nwindow.ScsConfig = ScsConfig;\n\nimport Message from \"./message\";\nwindow.Message = Message;\n\nimport MessageValue from \"./message_value\";\nwindow.MessageValue = MessageValue;\n\nimport MessageCollections from \"./message_collections\";\nwindow.MessageCollections = MessageCollections;\n\nimport MessageFormat from \"./message_format\";\nwindow.MessageFormat = MessageFormat;\n\nimport MessageProcessor from \"./message_processor\";\nwindow.MessageProcessor = MessageProcessor;\n\nimport DataInterpretation from \"./data_interpretation\";\nwindow.DataInterpretation = DataInterpretation;\n\nimport Graph from \"./graph\";\nwindow.Graph = Graph;\n\nimport TimeHelper from \"./time_helper\";\nwindow.TimeHelper = TimeHelper;\n\n// Adding this here as it is consumed in App.Topic.js which can't do imports\nimport valueLabels from './config/valueLabels';\nwindow.valueLabels = valueLabels;\n\ndocument.addEventListener(\"DOMContentLoaded\", function(event) {\n let params = new URLSearchParams(document.location.search.substring(1));\n let showPerformance = params.get(\"perf\");\n if(showPerformance){\n let perfDiv = document.getElementById('performance-stats');\n perfDiv.style.display = 'block'\n }\n})\n"],"sourceRoot":""}