function metaTagFromTags(tags) { if (tags.includes('hospital') || tags.includes('medical') || tags.includes('medcom')) { return 'Ambulance'; } if (tags.includes('fire-ems')) { return 'Fire/EMS'; } if (tags.includes('law')) { return 'Law'; } if (tags.includes('court')) { return 'Court'; } if (tags.includes('jail')) { return 'Jail'; } if (tags.includes('airport')) { return 'Airport'; } if (tags.includes('bus')) { return 'Bus'; } if (tags.includes('pubwks') || tags.includes('trash')) { return 'Pubwks/Trash'; } if (tags.includes('animal')) { return 'Animal'; } if (tags.includes('govt')) { return 'Gov'; } if (tags.includes('military')) { return 'Military'; } return 'Other'; } let metaTagEmojiMap = { 'Ambulance': '🚑', 'Fire/EMS': '🚒', 'Law': '👮', 'Court': '🏛️', 'Jail': 'Ⅲ', 'Airport': '✈️', 'Bus': '🚌', 'Pubwks/Trash': '👷', 'Animal': '🐶', 'Gov': '🏢', 'Military': '🪖', 'Other': '🤷' } function ptime (timestamp){ timestamp = parseInt(timestamp, 10) if (timestamp < 1000000000000){ timestamp = timestamp * 1000; } var d = new Date(timestamp); h = d.getHours(); m = d.getMinutes(); s = d.getSeconds(); if (h < 10){ h = "0" + h; } if (m < 10){ m = "0" + m; } if (s < 10){ s = "0" + s; } return h + ":" + m + ":" + s } function talkerIdPlusSystemToColor (talkerId, systemName, lightMode=false) { if (talkerId === 'UNKNOWN') { if (lightMode) { return 'rgb(192, 192, 192)'; } else { return 'rgb(128,128,128)'; } } let string = talkerId + talkerId.split('').reverse().join(''); for (var i=0; i= 86400) { result += toFixed(remaining / 86400, 0) + 'd'; count ++ ; } if (limitAfter && count >= limitCount) {return result; } remaining = remaining % 86400; if (remaining >= 3600){ result += toFixed(remaining / 3600, 0) + 'h'; count ++; } if (limitAfter && count >= limitCount) {return result; } remaining = remaining % 3600; if (remaining >= 60) { result += toFixed(remaining / 60, 0) + 'm'; count ++ ; } if (limitAfter && count >= limitCount) {return result; } remaining = remaining % 60; if (remaining > 0) { result += toFixed(remaining, 0) + 's'; } return result; } function toggleBlockNone(elementName) { let e = document.getElementById(elementName); if (e.style.display == 'block') { e.style.display = 'none'; } else { e.style.display = 'block'; } } function leftPad(n, targetLength) { result = n.toString(); while (result.length < targetLength) { result = '0' + result; } return result; } function intervalDeconflict(intervalStart, intervalEnd, existingIntervals) { //console.log(intervalStart); //console.log(intervalEnd); //console.log(existingIntervals.toString()); let intersectingIntervals = []; let intervalsToGet = []; let earliestExistingStart = intervalEnd; for (i of existingIntervals) { if (i[0] >= intervalStart || i[1] <= intervalEnd) { intersectingIntervals.push(i); } if (earliestExistingStart > i[0]) { earliestExistingStart = i[0]; } } let earliestTime = intervalStart; let latestTime = intervalEnd; for (i of intersectingIntervals) { if (i[0] < earliestTime) { earliestTime = i[0]; } if (i[1] > latestTime) { latestTime = i[1]; } } //console.log(earliestTime); //console.log(latestTime); let currentIntervalStart = earliestTime; let currentIntervalEnd = earliestTime + 1; let inVoidInterval = false; if (earliestExistingStart > intervalStart) { inVoidInterval = true; } let t; for (t=earliestTime; t= i[0] && t <= i[1]) { haveThisSecond = true; t = i[1]; break; } } if (haveThisSecond) { if (inVoidInterval) { currentIntervalEnd = t; inVoidInterval = false; intervalsToGet.push([currentIntervalStart, currentIntervalEnd]); } } else { if (!inVoidInterval) { inVoidInterval = true; currentIntervalStart = t; } } } if (inVoidInterval) { currentIntervalEnd = t; intervalsToGet.push([currentIntervalStart, currentIntervalEnd]); } return intervalsToGet; } function consolidateIntervals(intervals, millis=true) { if (intervals.length <= 1) { return intervals; } let earliestTime = Date.now(); let latestTime = 0; if (!millis) { earliestTime = parseInt(earliestTime / 1000); } for (let i=0; i latestTime) { latestTime = intervals[i][1]; } } // we'll always use seconds internally because millis are too fucking small if (millis) { earliestTime = parseInt(earliestTime / 1000); latestTime = parseInt(latestTime / 1000); } let consolidated = []; let inInterval = true; let currentIntervalStart = earliestTime; let i; for (i=earliestTime; i<=latestTime; i++) { //console.log(i); let foundOne = false; for (let j=0; j= intervals[j][0] / 1000 && i <= intervals[j][1] / 1000)) || (!millis && (i >= intervals[j][0] && i <= intervals[j][1]))) { foundOne = true; i = parseInt(intervals[j][1] / 1000); //console.log('found'); break; } } if (foundOne) { if (!inInterval) { inInterval = true; currentIntervalStart = i; } } else { if (inInterval){ consolidated.push([currentIntervalStart, i]); inInterval = false; } } } if (inInterval) { consolidated.push([currentIntervalStart, i]); } if (millis) { for (i=0; i= lastValue){ lastValue = calls[i]['start_time']; } else { console.log('sortVerify failed! ' + calls[i]['start_time'] + ' is less than ' + lastValue); sorted = false; break } } return sorted; }