From 6d77c20c84d637a750603944f4d8345086292d09 Mon Sep 17 00:00:00 2001 From: David Fencl Date: Sat, 6 Jun 2026 11:41:13 +0200 Subject: [PATCH] refactor: remove coverage report and add weather widget and navigation utility files --- coverage/base.css | 224 -------- coverage/block-navigation.js | 87 --- coverage/clover.xml | 133 ----- coverage/coverage-final.json | 5 - coverage/favicon.png | Bin 445 -> 0 bytes coverage/index.html | 146 ----- coverage/prettify.css | 1 - coverage/prettify.js | 2 - coverage/scripts/index.html | 131 ----- coverage/scripts/lakesConfig.ts.html | 160 ------ coverage/scripts/scrapeLakes.ts.html | 616 ---------------------- coverage/sort-arrow-sprite.png | Bin 138 -> 0 bytes coverage/sorter.js | 210 -------- coverage/src/components/KpiCards.tsx.html | 466 ---------------- coverage/src/components/index.html | 116 ---- coverage/src/index.html | 116 ---- coverage/src/translations.ts.html | 385 -------------- public/data/MARI.json | 56 +- public/data/MZHR.json | 56 +- public/data/VLHN.json | 56 +- public/data/VLKO.json | 56 +- public/data/VLL1.json | 56 +- public/data/VLL2.json | 60 ++- public/data/VLOR.json | 65 ++- public/data/VLSL.json | 56 +- public/data/VLST.json | 65 ++- public/data/lakes_index.json | 251 +++------ scripts/buildIndex.ts | 4 +- scripts/lakesConfig.ts | 11 +- src/App.tsx | 13 +- src/components/LakeDetail.tsx | 33 ++ src/components/LakesOverview.tsx | 15 +- src/components/WeatherWidget.tsx | 143 +++++ src/utils/navigationLimits.ts | 27 + 34 files changed, 819 insertions(+), 3002 deletions(-) delete mode 100644 coverage/base.css delete mode 100644 coverage/block-navigation.js delete mode 100644 coverage/clover.xml delete mode 100644 coverage/coverage-final.json delete mode 100644 coverage/favicon.png delete mode 100644 coverage/index.html delete mode 100644 coverage/prettify.css delete mode 100644 coverage/prettify.js delete mode 100644 coverage/scripts/index.html delete mode 100644 coverage/scripts/lakesConfig.ts.html delete mode 100644 coverage/scripts/scrapeLakes.ts.html delete mode 100644 coverage/sort-arrow-sprite.png delete mode 100644 coverage/sorter.js delete mode 100644 coverage/src/components/KpiCards.tsx.html delete mode 100644 coverage/src/components/index.html delete mode 100644 coverage/src/index.html delete mode 100644 coverage/src/translations.ts.html create mode 100644 src/components/WeatherWidget.tsx create mode 100644 src/utils/navigationLimits.ts diff --git a/coverage/base.css b/coverage/base.css deleted file mode 100644 index f418035..0000000 --- a/coverage/base.css +++ /dev/null @@ -1,224 +0,0 @@ -body, html { - margin:0; padding: 0; - height: 100%; -} -body { - font-family: Helvetica Neue, Helvetica, Arial; - font-size: 14px; - color:#333; -} -.small { font-size: 12px; } -*, *:after, *:before { - -webkit-box-sizing:border-box; - -moz-box-sizing:border-box; - box-sizing:border-box; - } -h1 { font-size: 20px; margin: 0;} -h2 { font-size: 14px; } -pre { - font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; - margin: 0; - padding: 0; - -moz-tab-size: 2; - -o-tab-size: 2; - tab-size: 2; -} -a { color:#0074D9; text-decoration:none; } -a:hover { text-decoration:underline; } -.strong { font-weight: bold; } -.space-top1 { padding: 10px 0 0 0; } -.pad2y { padding: 20px 0; } -.pad1y { padding: 10px 0; } -.pad2x { padding: 0 20px; } -.pad2 { padding: 20px; } -.pad1 { padding: 10px; } -.space-left2 { padding-left:55px; } -.space-right2 { padding-right:20px; } -.center { text-align:center; } -.clearfix { display:block; } -.clearfix:after { - content:''; - display:block; - height:0; - clear:both; - visibility:hidden; - } -.fl { float: left; } -@media only screen and (max-width:640px) { - .col3 { width:100%; max-width:100%; } - .hide-mobile { display:none!important; } -} - -.quiet { - color: #7f7f7f; - color: rgba(0,0,0,0.5); -} -.quiet a { opacity: 0.7; } - -.fraction { - font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; - font-size: 10px; - color: #555; - background: #E8E8E8; - padding: 4px 5px; - border-radius: 3px; - vertical-align: middle; -} - -div.path a:link, div.path a:visited { color: #333; } -table.coverage { - border-collapse: collapse; - margin: 10px 0 0 0; - padding: 0; -} - -table.coverage td { - margin: 0; - padding: 0; - vertical-align: top; -} -table.coverage td.line-count { - text-align: right; - padding: 0 5px 0 20px; -} -table.coverage td.line-coverage { - text-align: right; - padding-right: 10px; - min-width:20px; -} - -table.coverage td span.cline-any { - display: inline-block; - padding: 0 5px; - width: 100%; -} -.missing-if-branch { - display: inline-block; - margin-right: 5px; - border-radius: 3px; - position: relative; - padding: 0 4px; - background: #333; - color: yellow; -} - -.skip-if-branch { - display: none; - margin-right: 10px; - position: relative; - padding: 0 4px; - background: #ccc; - color: white; -} -.missing-if-branch .typ, .skip-if-branch .typ { - color: inherit !important; -} -.coverage-summary { - border-collapse: collapse; - width: 100%; -} -.coverage-summary tr { border-bottom: 1px solid #bbb; } -.keyline-all { border: 1px solid #ddd; } -.coverage-summary td, .coverage-summary th { padding: 10px; } -.coverage-summary tbody { border: 1px solid #bbb; } -.coverage-summary td { border-right: 1px solid #bbb; } -.coverage-summary td:last-child { border-right: none; } -.coverage-summary th { - text-align: left; - font-weight: normal; - white-space: nowrap; -} -.coverage-summary th.file { border-right: none !important; } -.coverage-summary th.pct { } -.coverage-summary th.pic, -.coverage-summary th.abs, -.coverage-summary td.pct, -.coverage-summary td.abs { text-align: right; } -.coverage-summary td.file { white-space: nowrap; } -.coverage-summary td.pic { min-width: 120px !important; } -.coverage-summary tfoot td { } - -.coverage-summary .sorter { - height: 10px; - width: 7px; - display: inline-block; - margin-left: 0.5em; - background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; -} -.coverage-summary .sorted .sorter { - background-position: 0 -20px; -} -.coverage-summary .sorted-desc .sorter { - background-position: 0 -10px; -} -.status-line { height: 10px; } -/* yellow */ -.cbranch-no { background: yellow !important; color: #111; } -/* dark red */ -.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } -.low .chart { border:1px solid #C21F39 } -.highlighted, -.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ - background: #C21F39 !important; -} -/* medium red */ -.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } -/* light red */ -.low, .cline-no { background:#FCE1E5 } -/* light green */ -.high, .cline-yes { background:rgb(230,245,208) } -/* medium green */ -.cstat-yes { background:rgb(161,215,106) } -/* dark green */ -.status-line.high, .high .cover-fill { background:rgb(77,146,33) } -.high .chart { border:1px solid rgb(77,146,33) } -/* dark yellow (gold) */ -.status-line.medium, .medium .cover-fill { background: #f9cd0b; } -.medium .chart { border:1px solid #f9cd0b; } -/* light yellow */ -.medium { background: #fff4c2; } - -.cstat-skip { background: #ddd; color: #111; } -.fstat-skip { background: #ddd; color: #111 !important; } -.cbranch-skip { background: #ddd !important; color: #111; } - -span.cline-neutral { background: #eaeaea; } - -.coverage-summary td.empty { - opacity: .5; - padding-top: 4px; - padding-bottom: 4px; - line-height: 1; - color: #888; -} - -.cover-fill, .cover-empty { - display:inline-block; - height: 12px; -} -.chart { - line-height: 0; -} -.cover-empty { - background: white; -} -.cover-full { - border-right: none !important; -} -pre.prettyprint { - border: none !important; - padding: 0 !important; - margin: 0 !important; -} -.com { color: #999 !important; } -.ignore-none { color: #999; font-weight: normal; } - -.wrapper { - min-height: 100%; - height: auto !important; - height: 100%; - margin: 0 auto -48px; -} -.footer, .push { - height: 48px; -} diff --git a/coverage/block-navigation.js b/coverage/block-navigation.js deleted file mode 100644 index 530d1ed..0000000 --- a/coverage/block-navigation.js +++ /dev/null @@ -1,87 +0,0 @@ -/* eslint-disable */ -var jumpToCode = (function init() { - // Classes of code we would like to highlight in the file view - var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; - - // Elements to highlight in the file listing view - var fileListingElements = ['td.pct.low']; - - // We don't want to select elements that are direct descendants of another match - var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` - - // Selector that finds elements on the page to which we can jump - var selector = - fileListingElements.join(', ') + - ', ' + - notSelector + - missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` - - // The NodeList of matching elements - var missingCoverageElements = document.querySelectorAll(selector); - - var currentIndex; - - function toggleClass(index) { - missingCoverageElements - .item(currentIndex) - .classList.remove('highlighted'); - missingCoverageElements.item(index).classList.add('highlighted'); - } - - function makeCurrent(index) { - toggleClass(index); - currentIndex = index; - missingCoverageElements.item(index).scrollIntoView({ - behavior: 'smooth', - block: 'center', - inline: 'center' - }); - } - - function goToPrevious() { - var nextIndex = 0; - if (typeof currentIndex !== 'number' || currentIndex === 0) { - nextIndex = missingCoverageElements.length - 1; - } else if (missingCoverageElements.length > 1) { - nextIndex = currentIndex - 1; - } - - makeCurrent(nextIndex); - } - - function goToNext() { - var nextIndex = 0; - - if ( - typeof currentIndex === 'number' && - currentIndex < missingCoverageElements.length - 1 - ) { - nextIndex = currentIndex + 1; - } - - makeCurrent(nextIndex); - } - - return function jump(event) { - if ( - document.getElementById('fileSearch') === document.activeElement && - document.activeElement != null - ) { - // if we're currently focused on the search input, we don't want to navigate - return; - } - - switch (event.which) { - case 78: // n - case 74: // j - goToNext(); - break; - case 66: // b - case 75: // k - case 80: // p - goToPrevious(); - break; - } - }; -})(); -window.addEventListener('keydown', jumpToCode); diff --git a/coverage/clover.xml b/coverage/clover.xml deleted file mode 100644 index f3b6e18..0000000 --- a/coverage/clover.xml +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/coverage/coverage-final.json b/coverage/coverage-final.json deleted file mode 100644 index 9655c78..0000000 --- a/coverage/coverage-final.json +++ /dev/null @@ -1,5 +0,0 @@ -{"/Users/davis/WebstormProjects/davisfe.cz/scripts/lakesConfig.ts": {"path":"/Users/davis/WebstormProjects/davisfe.cz/scripts/lakesConfig.ts","statementMap":{"0":{"start":{"line":12,"column":41},"end":{"line":25,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":1},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:12:41:25:Infinity":0}}} -,"/Users/davis/WebstormProjects/davisfe.cz/scripts/scrapeLakes.ts": {"path":"/Users/davis/WebstormProjects/davisfe.cz/scripts/scrapeLakes.ts","statementMap":{"0":{"start":{"line":20,"column":2},"end":{"line":37,"column":null}},"1":{"start":{"line":21,"column":4},"end":{"line":21,"column":null}},"2":{"start":{"line":21,"column":44},"end":{"line":21,"column":null}},"3":{"start":{"line":22,"column":33},"end":{"line":22,"column":null}},"4":{"start":{"line":23,"column":31},"end":{"line":23,"column":null}},"5":{"start":{"line":24,"column":29},"end":{"line":24,"column":null}},"6":{"start":{"line":26,"column":4},"end":{"line":26,"column":null}},"7":{"start":{"line":26,"column":25},"end":{"line":26,"column":null}},"8":{"start":{"line":28,"column":14},"end":{"line":28,"column":null}},"9":{"start":{"line":29,"column":14},"end":{"line":29,"column":null}},"10":{"start":{"line":30,"column":17},"end":{"line":30,"column":null}},"11":{"start":{"line":31,"column":14},"end":{"line":31,"column":null}},"12":{"start":{"line":32,"column":4},"end":{"line":32,"column":null}},"13":{"start":{"line":32,"column":28},"end":{"line":32,"column":null}},"14":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"15":{"start":{"line":33,"column":77},"end":{"line":33,"column":null}},"16":{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},"17":{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},"18":{"start":{"line":41,"column":14},"end":{"line":41,"column":null}},"19":{"start":{"line":42,"column":20},"end":{"line":42,"column":null}},"20":{"start":{"line":44,"column":2},"end":{"line":160,"column":null}},"21":{"start":{"line":45,"column":18},"end":{"line":45,"column":null}},"22":{"start":{"line":46,"column":21},"end":{"line":51,"column":null}},"23":{"start":{"line":53,"column":14},"end":{"line":53,"column":null}},"24":{"start":{"line":55,"column":24},"end":{"line":55,"column":null}},"25":{"start":{"line":56,"column":24},"end":{"line":56,"column":null}},"26":{"start":{"line":57,"column":37},"end":{"line":57,"column":null}},"27":{"start":{"line":58,"column":39},"end":{"line":58,"column":null}},"28":{"start":{"line":60,"column":4},"end":{"line":78,"column":null}},"29":{"start":{"line":61,"column":19},"end":{"line":61,"column":null}},"30":{"start":{"line":62,"column":6},"end":{"line":77,"column":null}},"31":{"start":{"line":63,"column":8},"end":{"line":76,"column":null}},"32":{"start":{"line":64,"column":24},"end":{"line":64,"column":null}},"33":{"start":{"line":65,"column":25},"end":{"line":65,"column":null}},"34":{"start":{"line":66,"column":10},"end":{"line":66,"column":null}},"35":{"start":{"line":66,"column":40},"end":{"line":66,"column":null}},"36":{"start":{"line":67,"column":10},"end":{"line":67,"column":null}},"37":{"start":{"line":67,"column":39},"end":{"line":67,"column":null}},"38":{"start":{"line":68,"column":10},"end":{"line":71,"column":null}},"39":{"start":{"line":69,"column":22},"end":{"line":69,"column":null}},"40":{"start":{"line":70,"column":12},"end":{"line":70,"column":null}},"41":{"start":{"line":70,"column":27},"end":{"line":70,"column":null}},"42":{"start":{"line":72,"column":10},"end":{"line":75,"column":null}},"43":{"start":{"line":73,"column":22},"end":{"line":73,"column":null}},"44":{"start":{"line":74,"column":12},"end":{"line":74,"column":null}},"45":{"start":{"line":74,"column":27},"end":{"line":74,"column":null}},"46":{"start":{"line":80,"column":34},"end":{"line":80,"column":null}},"47":{"start":{"line":81,"column":20},"end":{"line":81,"column":null}},"48":{"start":{"line":82,"column":4},"end":{"line":86,"column":null}},"49":{"start":{"line":83,"column":6},"end":{"line":85,"column":null}},"50":{"start":{"line":84,"column":8},"end":{"line":84,"column":null}},"51":{"start":{"line":88,"column":4},"end":{"line":112,"column":null}},"52":{"start":{"line":89,"column":6},"end":{"line":111,"column":null}},"53":{"start":{"line":90,"column":8},"end":{"line":90,"column":null}},"54":{"start":{"line":90,"column":21},"end":{"line":90,"column":null}},"55":{"start":{"line":91,"column":21},"end":{"line":91,"column":null}},"56":{"start":{"line":92,"column":8},"end":{"line":110,"column":null}},"57":{"start":{"line":93,"column":26},"end":{"line":93,"column":null}},"58":{"start":{"line":94,"column":27},"end":{"line":94,"column":null}},"59":{"start":{"line":95,"column":24},"end":{"line":95,"column":null}},"60":{"start":{"line":96,"column":10},"end":{"line":98,"column":null}},"61":{"start":{"line":97,"column":12},"end":{"line":97,"column":null}},"62":{"start":{"line":100,"column":32},"end":{"line":100,"column":null}},"63":{"start":{"line":101,"column":10},"end":{"line":109,"column":null}},"64":{"start":{"line":102,"column":12},"end":{"line":108,"column":null}},"65":{"start":{"line":114,"column":4},"end":{"line":120,"column":null}},"66":{"start":{"line":116,"column":6},"end":{"line":116,"column":null}},"67":{"start":{"line":117,"column":6},"end":{"line":117,"column":null}},"68":{"start":{"line":118,"column":6},"end":{"line":118,"column":null}},"69":{"start":{"line":118,"column":32},"end":{"line":118,"column":null}},"70":{"start":{"line":119,"column":6},"end":{"line":119,"column":null}},"71":{"start":{"line":119,"column":34},"end":{"line":119,"column":null}},"72":{"start":{"line":122,"column":37},"end":{"line":122,"column":null}},"73":{"start":{"line":123,"column":4},"end":{"line":126,"column":null}},"74":{"start":{"line":124,"column":26},"end":{"line":124,"column":null}},"75":{"start":{"line":125,"column":6},"end":{"line":125,"column":null}},"76":{"start":{"line":128,"column":20},"end":{"line":128,"column":null}},"77":{"start":{"line":129,"column":4},"end":{"line":129,"column":null}},"78":{"start":{"line":129,"column":33},"end":{"line":129,"column":66}},"79":{"start":{"line":130,"column":4},"end":{"line":130,"column":null}},"80":{"start":{"line":130,"column":28},"end":{"line":130,"column":61}},"81":{"start":{"line":132,"column":23},"end":{"line":134,"column":null}},"82":{"start":{"line":133,"column":6},"end":{"line":133,"column":null}},"83":{"start":{"line":137,"column":39},"end":{"line":137,"column":null}},"84":{"start":{"line":138,"column":41},"end":{"line":138,"column":null}},"85":{"start":{"line":139,"column":4},"end":{"line":151,"column":null}},"86":{"start":{"line":140,"column":6},"end":{"line":144,"column":null}},"87":{"start":{"line":141,"column":8},"end":{"line":141,"column":null}},"88":{"start":{"line":142,"column":6},"end":{"line":144,"column":null}},"89":{"start":{"line":143,"column":8},"end":{"line":143,"column":null}},"90":{"start":{"line":146,"column":6},"end":{"line":150,"column":null}},"91":{"start":{"line":147,"column":8},"end":{"line":147,"column":null}},"92":{"start":{"line":148,"column":6},"end":{"line":150,"column":null}},"93":{"start":{"line":149,"column":8},"end":{"line":149,"column":null}},"94":{"start":{"line":153,"column":4},"end":{"line":153,"column":null}},"95":{"start":{"line":154,"column":4},"end":{"line":154,"column":null}},"96":{"start":{"line":156,"column":4},"end":{"line":156,"column":null}},"97":{"start":{"line":159,"column":4},"end":{"line":159,"column":null}},"98":{"start":{"line":164,"column":2},"end":{"line":164,"column":null}},"99":{"start":{"line":166,"column":2},"end":{"line":172,"column":null}},"100":{"start":{"line":168,"column":30},"end":{"line":168,"column":null}},"101":{"start":{"line":169,"column":4},"end":{"line":169,"column":null}},"102":{"start":{"line":171,"column":4},"end":{"line":171,"column":null}},"103":{"start":{"line":171,"column":33},"end":{"line":171,"column":57}},"104":{"start":{"line":174,"column":2},"end":{"line":174,"column":null}},"105":{"start":{"line":177,"column":0},"end":{"line":177,"column":null}}},"fnMap":{"0":{"name":"parseDateString","decl":{"start":{"line":19,"column":16},"end":{"line":19,"column":32}},"loc":{"start":{"line":19,"column":64},"end":{"line":38,"column":null}},"line":19},"1":{"name":"scrapeLake","decl":{"start":{"line":40,"column":15},"end":{"line":40,"column":26}},"loc":{"start":{"line":40,"column":75},"end":{"line":161,"column":null}},"line":40},"2":{"name":"(anonymous_2)","decl":{"start":{"line":60,"column":20},"end":{"line":60,"column":21}},"loc":{"start":{"line":60,"column":32},"end":{"line":78,"column":5}},"line":60},"3":{"name":"(anonymous_3)","decl":{"start":{"line":63,"column":31},"end":{"line":63,"column":32}},"loc":{"start":{"line":63,"column":41},"end":{"line":76,"column":9}},"line":63},"4":{"name":"(anonymous_4)","decl":{"start":{"line":82,"column":20},"end":{"line":82,"column":21}},"loc":{"start":{"line":82,"column":32},"end":{"line":86,"column":5}},"line":82},"5":{"name":"(anonymous_5)","decl":{"start":{"line":89,"column":32},"end":{"line":89,"column":33}},"loc":{"start":{"line":89,"column":44},"end":{"line":111,"column":7}},"line":89},"6":{"name":"(anonymous_6)","decl":{"start":{"line":129,"column":25},"end":{"line":129,"column":33}},"loc":{"start":{"line":129,"column":33},"end":{"line":129,"column":66}},"line":129},"7":{"name":"(anonymous_7)","decl":{"start":{"line":130,"column":20},"end":{"line":130,"column":28}},"loc":{"start":{"line":130,"column":28},"end":{"line":130,"column":61}},"line":130},"8":{"name":"(anonymous_8)","decl":{"start":{"line":132,"column":57},"end":{"line":132,"column":58}},"loc":{"start":{"line":132,"column":67},"end":{"line":134,"column":5}},"line":132},"9":{"name":"(anonymous_9)","decl":{"start":{"line":139,"column":23},"end":{"line":139,"column":31}},"loc":{"start":{"line":139,"column":31},"end":{"line":151,"column":5}},"line":139},"10":{"name":"runScraper","decl":{"start":{"line":163,"column":15},"end":{"line":163,"column":28}},"loc":{"start":{"line":163,"column":28},"end":{"line":175,"column":null}},"line":163},"11":{"name":"(anonymous_11)","decl":{"start":{"line":171,"column":22},"end":{"line":171,"column":33}},"loc":{"start":{"line":171,"column":33},"end":{"line":171,"column":57}},"line":171}},"branchMap":{"0":{"loc":{"start":{"line":21,"column":4},"end":{"line":21,"column":null}},"type":"if","locations":[{"start":{"line":21,"column":4},"end":{"line":21,"column":null}},{"start":{},"end":{}}],"line":21},"1":{"loc":{"start":{"line":21,"column":8},"end":{"line":21,"column":44}},"type":"binary-expr","locations":[{"start":{"line":21,"column":8},"end":{"line":21,"column":20}},{"start":{"line":21,"column":20},"end":{"line":21,"column":44}}],"line":21},"2":{"loc":{"start":{"line":26,"column":4},"end":{"line":26,"column":null}},"type":"if","locations":[{"start":{"line":26,"column":4},"end":{"line":26,"column":null}},{"start":{},"end":{}}],"line":26},"3":{"loc":{"start":{"line":26,"column":8},"end":{"line":26,"column":25}},"type":"binary-expr","locations":[{"start":{"line":26,"column":8},"end":{"line":26,"column":17}},{"start":{"line":26,"column":17},"end":{"line":26,"column":25}}],"line":26},"4":{"loc":{"start":{"line":32,"column":4},"end":{"line":32,"column":null}},"type":"if","locations":[{"start":{"line":32,"column":4},"end":{"line":32,"column":null}},{"start":{},"end":{}}],"line":32},"5":{"loc":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":33},"6":{"loc":{"start":{"line":33,"column":8},"end":{"line":33,"column":77}},"type":"binary-expr","locations":[{"start":{"line":33,"column":8},"end":{"line":33,"column":33}},{"start":{"line":33,"column":33},"end":{"line":33,"column":55}},{"start":{"line":33,"column":55},"end":{"line":33,"column":77}}],"line":33},"7":{"loc":{"start":{"line":62,"column":6},"end":{"line":77,"column":null}},"type":"if","locations":[{"start":{"line":62,"column":6},"end":{"line":77,"column":null}},{"start":{},"end":{}}],"line":62},"8":{"loc":{"start":{"line":62,"column":10},"end":{"line":62,"column":72}},"type":"binary-expr","locations":[{"start":{"line":62,"column":10},"end":{"line":62,"column":47}},{"start":{"line":62,"column":47},"end":{"line":62,"column":72}}],"line":62},"9":{"loc":{"start":{"line":66,"column":10},"end":{"line":66,"column":null}},"type":"if","locations":[{"start":{"line":66,"column":10},"end":{"line":66,"column":null}},{"start":{},"end":{}}],"line":66},"10":{"loc":{"start":{"line":66,"column":56},"end":{"line":66,"column":null}},"type":"binary-expr","locations":[{"start":{"line":66,"column":56},"end":{"line":66,"column":78}},{"start":{"line":66,"column":78},"end":{"line":66,"column":null}}],"line":66},"11":{"loc":{"start":{"line":67,"column":10},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":10},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":67},"12":{"loc":{"start":{"line":67,"column":55},"end":{"line":67,"column":null}},"type":"binary-expr","locations":[{"start":{"line":67,"column":55},"end":{"line":67,"column":77}},{"start":{"line":67,"column":77},"end":{"line":67,"column":null}}],"line":67},"13":{"loc":{"start":{"line":68,"column":10},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":68,"column":10},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":68},"14":{"loc":{"start":{"line":70,"column":12},"end":{"line":70,"column":null}},"type":"if","locations":[{"start":{"line":70,"column":12},"end":{"line":70,"column":null}},{"start":{},"end":{}}],"line":70},"15":{"loc":{"start":{"line":72,"column":10},"end":{"line":75,"column":null}},"type":"if","locations":[{"start":{"line":72,"column":10},"end":{"line":75,"column":null}},{"start":{},"end":{}}],"line":72},"16":{"loc":{"start":{"line":74,"column":12},"end":{"line":74,"column":null}},"type":"if","locations":[{"start":{"line":74,"column":12},"end":{"line":74,"column":null}},{"start":{},"end":{}}],"line":74},"17":{"loc":{"start":{"line":83,"column":6},"end":{"line":85,"column":null}},"type":"if","locations":[{"start":{"line":83,"column":6},"end":{"line":85,"column":null}},{"start":{},"end":{}}],"line":83},"18":{"loc":{"start":{"line":83,"column":10},"end":{"line":83,"column":78}},"type":"binary-expr","locations":[{"start":{"line":83,"column":10},"end":{"line":83,"column":45}},{"start":{"line":83,"column":45},"end":{"line":83,"column":78}}],"line":83},"19":{"loc":{"start":{"line":88,"column":4},"end":{"line":112,"column":null}},"type":"if","locations":[{"start":{"line":88,"column":4},"end":{"line":112,"column":null}},{"start":{},"end":{}}],"line":88},"20":{"loc":{"start":{"line":90,"column":8},"end":{"line":90,"column":null}},"type":"if","locations":[{"start":{"line":90,"column":8},"end":{"line":90,"column":null}},{"start":{},"end":{}}],"line":90},"21":{"loc":{"start":{"line":92,"column":8},"end":{"line":110,"column":null}},"type":"if","locations":[{"start":{"line":92,"column":8},"end":{"line":110,"column":null}},{"start":{},"end":{}}],"line":92},"22":{"loc":{"start":{"line":96,"column":10},"end":{"line":98,"column":null}},"type":"if","locations":[{"start":{"line":96,"column":10},"end":{"line":98,"column":null}},{"start":{},"end":{}}],"line":96},"23":{"loc":{"start":{"line":96,"column":14},"end":{"line":96,"column":50}},"type":"binary-expr","locations":[{"start":{"line":96,"column":14},"end":{"line":96,"column":32}},{"start":{"line":96,"column":32},"end":{"line":96,"column":50}}],"line":96},"24":{"loc":{"start":{"line":101,"column":10},"end":{"line":109,"column":null}},"type":"if","locations":[{"start":{"line":101,"column":10},"end":{"line":109,"column":null}},{"start":{},"end":{}}],"line":101},"25":{"loc":{"start":{"line":104,"column":21},"end":{"line":104,"column":null}},"type":"binary-expr","locations":[{"start":{"line":104,"column":21},"end":{"line":104,"column":45}},{"start":{"line":104,"column":45},"end":{"line":104,"column":null}}],"line":104},"26":{"loc":{"start":{"line":105,"column":20},"end":{"line":105,"column":null}},"type":"binary-expr","locations":[{"start":{"line":105,"column":20},"end":{"line":105,"column":43}},{"start":{"line":105,"column":43},"end":{"line":105,"column":null}}],"line":105},"27":{"loc":{"start":{"line":114,"column":4},"end":{"line":120,"column":null}},"type":"if","locations":[{"start":{"line":114,"column":4},"end":{"line":120,"column":null}},{"start":{},"end":{}}],"line":114},"28":{"loc":{"start":{"line":118,"column":6},"end":{"line":118,"column":null}},"type":"if","locations":[{"start":{"line":118,"column":6},"end":{"line":118,"column":null}},{"start":{},"end":{}}],"line":118},"29":{"loc":{"start":{"line":119,"column":6},"end":{"line":119,"column":null}},"type":"if","locations":[{"start":{"line":119,"column":6},"end":{"line":119,"column":null}},{"start":{},"end":{}}],"line":119},"30":{"loc":{"start":{"line":123,"column":4},"end":{"line":126,"column":null}},"type":"if","locations":[{"start":{"line":123,"column":4},"end":{"line":126,"column":null}},{"start":{},"end":{}}],"line":123},"31":{"loc":{"start":{"line":140,"column":6},"end":{"line":144,"column":null}},"type":"if","locations":[{"start":{"line":140,"column":6},"end":{"line":144,"column":null}},{"start":{"line":142,"column":6},"end":{"line":144,"column":null}}],"line":140},"32":{"loc":{"start":{"line":140,"column":10},"end":{"line":140,"column":71}},"type":"binary-expr","locations":[{"start":{"line":140,"column":10},"end":{"line":140,"column":44}},{"start":{"line":140,"column":44},"end":{"line":140,"column":71}}],"line":140},"33":{"loc":{"start":{"line":142,"column":6},"end":{"line":144,"column":null}},"type":"if","locations":[{"start":{"line":142,"column":6},"end":{"line":144,"column":null}},{"start":{},"end":{}}],"line":142},"34":{"loc":{"start":{"line":146,"column":6},"end":{"line":150,"column":null}},"type":"if","locations":[{"start":{"line":146,"column":6},"end":{"line":150,"column":null}},{"start":{"line":148,"column":6},"end":{"line":150,"column":null}}],"line":146},"35":{"loc":{"start":{"line":146,"column":10},"end":{"line":146,"column":75}},"type":"binary-expr","locations":[{"start":{"line":146,"column":10},"end":{"line":146,"column":46}},{"start":{"line":146,"column":46},"end":{"line":146,"column":75}}],"line":146},"36":{"loc":{"start":{"line":148,"column":6},"end":{"line":150,"column":null}},"type":"if","locations":[{"start":{"line":148,"column":6},"end":{"line":150,"column":null}},{"start":{},"end":{}}],"line":148}},"s":{"0":7,"1":7,"2":3,"3":4,"4":4,"5":4,"6":4,"7":2,"8":2,"9":2,"10":2,"11":2,"12":2,"13":0,"14":2,"15":1,"16":1,"17":0,"18":1,"19":1,"20":1,"21":1,"22":1,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0,"82":0,"83":0,"84":0,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":0,"92":0,"93":0,"94":0,"95":0,"96":0,"97":0,"98":1,"99":1,"100":1,"101":1,"102":0,"103":0,"104":0,"105":1},"f":{"0":7,"1":1,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0},"b":{"0":[3,4],"1":[7,6],"2":[2,2],"3":[4,2],"4":[0,2],"5":[1,1],"6":[2,1,1],"7":[0,0],"8":[0,0],"9":[0,0],"10":[0,0],"11":[0,0],"12":[0,0],"13":[0,0],"14":[0,0],"15":[0,0],"16":[0,0],"17":[0,0],"18":[0,0],"19":[0,0],"20":[0,0],"21":[0,0],"22":[0,0],"23":[0,0],"24":[0,0],"25":[0,0],"26":[0,0],"27":[0,0],"28":[0,0],"29":[0,0],"30":[0,0],"31":[0,0],"32":[0,0],"33":[0,0],"34":[0,0],"35":[0,0],"36":[0,0]},"meta":{"lastBranch":37,"lastFunction":12,"lastStatement":106,"seen":{"f:19:16:19:32":0,"s:20:2:37:Infinity":0,"b:21:4:21:Infinity:undefined:undefined:undefined:undefined":0,"s:21:4:21:Infinity":1,"b:21:8:21:20:21:20:21:44":1,"s:21:44:21:Infinity":2,"s:22:33:22:Infinity":3,"s:23:31:23:Infinity":4,"s:24:29:24:Infinity":5,"b:26:4:26:Infinity:undefined:undefined:undefined:undefined":2,"s:26:4:26:Infinity":6,"b:26:8:26:17:26:17:26:25":3,"s:26:25:26:Infinity":7,"s:28:14:28:Infinity":8,"s:29:14:29:Infinity":9,"s:30:17:30:Infinity":10,"s:31:14:31:Infinity":11,"b:32:4:32:Infinity:undefined:undefined:undefined:undefined":4,"s:32:4:32:Infinity":12,"s:32:28:32:Infinity":13,"b:33:4:33:Infinity:undefined:undefined:undefined:undefined":5,"s:33:4:33:Infinity":14,"b:33:8:33:33:33:33:33:55:33:55:33:77":6,"s:33:77:33:Infinity":15,"s:34:4:34:Infinity":16,"s:36:4:36:Infinity":17,"f:40:15:40:26":1,"s:41:14:41:Infinity":18,"s:42:20:42:Infinity":19,"s:44:2:160:Infinity":20,"s:45:18:45:Infinity":21,"s:46:21:51:Infinity":22,"s:53:14:53:Infinity":23,"s:55:24:55:Infinity":24,"s:56:24:56:Infinity":25,"s:57:37:57:Infinity":26,"s:58:39:58:Infinity":27,"s:60:4:78:Infinity":28,"f:60:20:60:21":2,"s:61:19:61:Infinity":29,"b:62:6:77:Infinity:undefined:undefined:undefined:undefined":7,"s:62:6:77:Infinity":30,"b:62:10:62:47:62:47:62:72":8,"s:63:8:76:Infinity":31,"f:63:31:63:32":3,"s:64:24:64:Infinity":32,"s:65:25:65:Infinity":33,"b:66:10:66:Infinity:undefined:undefined:undefined:undefined":9,"s:66:10:66:Infinity":34,"s:66:40:66:Infinity":35,"b:66:56:66:78:66:78:66:Infinity":10,"b:67:10:67:Infinity:undefined:undefined:undefined:undefined":11,"s:67:10:67:Infinity":36,"s:67:39:67:Infinity":37,"b:67:55:67:77:67:77:67:Infinity":12,"b:68:10:71:Infinity:undefined:undefined:undefined:undefined":13,"s:68:10:71:Infinity":38,"s:69:22:69:Infinity":39,"b:70:12:70:Infinity:undefined:undefined:undefined:undefined":14,"s:70:12:70:Infinity":40,"s:70:27:70:Infinity":41,"b:72:10:75:Infinity:undefined:undefined:undefined:undefined":15,"s:72:10:75:Infinity":42,"s:73:22:73:Infinity":43,"b:74:12:74:Infinity:undefined:undefined:undefined:undefined":16,"s:74:12:74:Infinity":44,"s:74:27:74:Infinity":45,"s:80:34:80:Infinity":46,"s:81:20:81:Infinity":47,"s:82:4:86:Infinity":48,"f:82:20:82:21":4,"b:83:6:85:Infinity:undefined:undefined:undefined:undefined":17,"s:83:6:85:Infinity":49,"b:83:10:83:45:83:45:83:78":18,"s:84:8:84:Infinity":50,"b:88:4:112:Infinity:undefined:undefined:undefined:undefined":19,"s:88:4:112:Infinity":51,"s:89:6:111:Infinity":52,"f:89:32:89:33":5,"b:90:8:90:Infinity:undefined:undefined:undefined:undefined":20,"s:90:8:90:Infinity":53,"s:90:21:90:Infinity":54,"s:91:21:91:Infinity":55,"b:92:8:110:Infinity:undefined:undefined:undefined:undefined":21,"s:92:8:110:Infinity":56,"s:93:26:93:Infinity":57,"s:94:27:94:Infinity":58,"s:95:24:95:Infinity":59,"b:96:10:98:Infinity:undefined:undefined:undefined:undefined":22,"s:96:10:98:Infinity":60,"b:96:14:96:32:96:32:96:50":23,"s:97:12:97:Infinity":61,"s:100:32:100:Infinity":62,"b:101:10:109:Infinity:undefined:undefined:undefined:undefined":24,"s:101:10:109:Infinity":63,"s:102:12:108:Infinity":64,"b:104:21:104:45:104:45:104:Infinity":25,"b:105:20:105:43:105:43:105:Infinity":26,"b:114:4:120:Infinity:undefined:undefined:undefined:undefined":27,"s:114:4:120:Infinity":65,"s:116:6:116:Infinity":66,"s:117:6:117:Infinity":67,"b:118:6:118:Infinity:undefined:undefined:undefined:undefined":28,"s:118:6:118:Infinity":68,"s:118:32:118:Infinity":69,"b:119:6:119:Infinity:undefined:undefined:undefined:undefined":29,"s:119:6:119:Infinity":70,"s:119:34:119:Infinity":71,"s:122:37:122:Infinity":72,"b:123:4:126:Infinity:undefined:undefined:undefined:undefined":30,"s:123:4:126:Infinity":73,"s:124:26:124:Infinity":74,"s:125:6:125:Infinity":75,"s:128:20:128:Infinity":76,"s:129:4:129:Infinity":77,"f:129:25:129:33":6,"s:129:33:129:66":78,"s:130:4:130:Infinity":79,"f:130:20:130:28":7,"s:130:28:130:61":80,"s:132:23:134:Infinity":81,"f:132:57:132:58":8,"s:133:6:133:Infinity":82,"s:137:39:137:Infinity":83,"s:138:41:138:Infinity":84,"s:139:4:151:Infinity":85,"f:139:23:139:31":9,"b:140:6:144:Infinity:142:6:144:Infinity":31,"s:140:6:144:Infinity":86,"b:140:10:140:44:140:44:140:71":32,"s:141:8:141:Infinity":87,"b:142:6:144:Infinity:undefined:undefined:undefined:undefined":33,"s:142:6:144:Infinity":88,"s:143:8:143:Infinity":89,"b:146:6:150:Infinity:148:6:150:Infinity":34,"s:146:6:150:Infinity":90,"b:146:10:146:46:146:46:146:75":35,"s:147:8:147:Infinity":91,"b:148:6:150:Infinity:undefined:undefined:undefined:undefined":36,"s:148:6:150:Infinity":92,"s:149:8:149:Infinity":93,"s:153:4:153:Infinity":94,"s:154:4:154:Infinity":95,"s:156:4:156:Infinity":96,"s:159:4:159:Infinity":97,"f:163:15:163:28":10,"s:164:2:164:Infinity":98,"s:166:2:172:Infinity":99,"s:168:30:168:Infinity":100,"s:169:4:169:Infinity":101,"s:171:4:171:Infinity":102,"f:171:22:171:33":11,"s:171:33:171:57":103,"s:174:2:174:Infinity":104,"s:177:0:177:Infinity":105}}} -,"/Users/davis/WebstormProjects/davisfe.cz/src/translations.ts": {"path":"/Users/davis/WebstormProjects/davisfe.cz/src/translations.ts","statementMap":{"0":{"start":{"line":3,"column":17},"end":{"line":100,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":2},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:3:17:100:Infinity":0}}} -,"/Users/davis/WebstormProjects/davisfe.cz/src/components/KpiCards.tsx": {"path":"/Users/davis/WebstormProjects/davisfe.cz/src/components/KpiCards.tsx","statementMap":{"0":{"start":{"line":21,"column":17},"end":{"line":125,"column":null}},"1":{"start":{"line":22,"column":36},"end":{"line":22,"column":null}},"2":{"start":{"line":23,"column":15},"end":{"line":23,"column":null}},"3":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"4":{"start":{"line":26,"column":2},"end":{"line":33,"column":null}},"5":{"start":{"line":27,"column":4},"end":{"line":32,"column":null}},"6":{"start":{"line":28,"column":20},"end":{"line":30,"column":null}},"7":{"start":{"line":29,"column":8},"end":{"line":29,"column":null}},"8":{"start":{"line":31,"column":6},"end":{"line":31,"column":null}},"9":{"start":{"line":31,"column":19},"end":{"line":31,"column":null}},"10":{"start":{"line":35,"column":2},"end":{"line":123,"column":null}},"11":{"start":{"line":86,"column":27},"end":{"line":86,"column":null}},"12":{"start":{"line":93,"column":29},"end":{"line":93,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":21,"column":17},"end":{"line":21,"column":18}},"loc":{"start":{"line":21,"column":70},"end":{"line":125,"column":null}},"line":21},"1":{"name":"(anonymous_1)","decl":{"start":{"line":26,"column":12},"end":{"line":26,"column":18}},"loc":{"start":{"line":26,"column":18},"end":{"line":33,"column":5}},"line":26},"2":{"name":"(anonymous_2)","decl":{"start":{"line":28,"column":31},"end":{"line":28,"column":37}},"loc":{"start":{"line":28,"column":37},"end":{"line":30,"column":9}},"line":28},"3":{"name":"(anonymous_3)","decl":{"start":{"line":31,"column":13},"end":{"line":31,"column":19}},"loc":{"start":{"line":31,"column":19},"end":{"line":31,"column":null}},"line":31},"4":{"name":"(anonymous_4)","decl":{"start":{"line":86,"column":21},"end":{"line":86,"column":27}},"loc":{"start":{"line":86,"column":27},"end":{"line":86,"column":null}},"line":86},"5":{"name":"(anonymous_5)","decl":{"start":{"line":93,"column":23},"end":{"line":93,"column":29}},"loc":{"start":{"line":93,"column":29},"end":{"line":93,"column":null}},"line":93}},"branchMap":{"0":{"loc":{"start":{"line":21,"column":36},"end":{"line":21,"column":57}},"type":"default-arg","locations":[{"start":{"line":21,"column":47},"end":{"line":21,"column":57}}],"line":21},"1":{"loc":{"start":{"line":27,"column":4},"end":{"line":32,"column":null}},"type":"if","locations":[{"start":{"line":27,"column":4},"end":{"line":32,"column":null}},{"start":{},"end":{}}],"line":27},"2":{"loc":{"start":{"line":67,"column":15},"end":{"line":67,"column":null}},"type":"cond-expr","locations":[{"start":{"line":67,"column":30},"end":{"line":67,"column":73}},{"start":{"line":67,"column":73},"end":{"line":67,"column":null}}],"line":67},"3":{"loc":{"start":{"line":67,"column":73},"end":{"line":67,"column":null}},"type":"cond-expr","locations":[{"start":{"line":67,"column":88},"end":{"line":67,"column":131}},{"start":{"line":67,"column":131},"end":{"line":67,"column":null}}],"line":67},"4":{"loc":{"start":{"line":91,"column":11},"end":{"line":113,"column":null}},"type":"binary-expr","locations":[{"start":{"line":91,"column":11},"end":{"line":91,"column":null}},{"start":{"line":92,"column":12},"end":{"line":113,"column":null}}],"line":91},"5":{"loc":{"start":{"line":112,"column":15},"end":{"line":112,"column":null}},"type":"cond-expr","locations":[{"start":{"line":112,"column":35},"end":{"line":112,"column":135}},{"start":{"line":112,"column":135},"end":{"line":112,"column":null}}],"line":112},"6":{"loc":{"start":{"line":116,"column":106},"end":{"line":116,"column":190}},"type":"cond-expr","locations":[{"start":{"line":116,"column":149},"end":{"line":116,"column":170}},{"start":{"line":116,"column":170},"end":{"line":116,"column":190}}],"line":116},"7":{"loc":{"start":{"line":116,"column":106},"end":{"line":116,"column":149}},"type":"binary-expr","locations":[{"start":{"line":116,"column":106},"end":{"line":116,"column":126}},{"start":{"line":116,"column":126},"end":{"line":116,"column":149}}],"line":116},"8":{"loc":{"start":{"line":117,"column":11},"end":{"line":117,"column":null}},"type":"cond-expr","locations":[{"start":{"line":117,"column":71},"end":{"line":117,"column":171}},{"start":{"line":117,"column":171},"end":{"line":117,"column":null}}],"line":117},"9":{"loc":{"start":{"line":117,"column":11},"end":{"line":117,"column":71}},"type":"binary-expr","locations":[{"start":{"line":117,"column":11},"end":{"line":117,"column":45}},{"start":{"line":117,"column":45},"end":{"line":117,"column":71}}],"line":117},"10":{"loc":{"start":{"line":117,"column":71},"end":{"line":117,"column":171}},"type":"cond-expr","locations":[{"start":{"line":117,"column":94},"end":{"line":117,"column":132}},{"start":{"line":117,"column":132},"end":{"line":117,"column":171}}],"line":117},"11":{"loc":{"start":{"line":117,"column":171},"end":{"line":117,"column":null}},"type":"cond-expr","locations":[{"start":{"line":117,"column":191},"end":{"line":117,"column":224}},{"start":{"line":117,"column":224},"end":{"line":117,"column":null}}],"line":117}},"s":{"0":1,"1":3,"2":3,"3":3,"4":3,"5":3,"6":0,"7":0,"8":0,"9":0,"10":3,"11":0,"12":0},"f":{"0":3,"1":3,"2":0,"3":0,"4":0,"5":0},"b":{"0":[3],"1":[0,3],"2":[3,0],"3":[0,0],"4":[3,0],"5":[0,0],"6":[1,2],"7":[3,2],"8":[2,1],"9":[3,3],"10":[1,1],"11":[1,0]},"meta":{"lastBranch":12,"lastFunction":6,"lastStatement":13,"seen":{"s:21:17:125:Infinity":0,"f:21:17:21:18":0,"b:21:47:21:57":0,"s:22:36:22:Infinity":1,"s:23:15:23:Infinity":2,"s:24:19:24:Infinity":3,"s:26:2:33:Infinity":4,"f:26:12:26:18":1,"b:27:4:32:Infinity:undefined:undefined:undefined:undefined":1,"s:27:4:32:Infinity":5,"s:28:20:30:Infinity":6,"f:28:31:28:37":2,"s:29:8:29:Infinity":7,"s:31:6:31:Infinity":8,"f:31:13:31:19":3,"s:31:19:31:Infinity":9,"s:35:2:123:Infinity":10,"b:67:30:67:73:67:73:67:Infinity":2,"b:67:88:67:131:67:131:67:Infinity":3,"f:86:21:86:27":4,"s:86:27:86:Infinity":11,"b:91:11:91:Infinity:92:12:113:Infinity":4,"f:93:23:93:29":5,"s:93:29:93:Infinity":12,"b:112:35:112:135:112:135:112:Infinity":5,"b:116:149:116:170:116:170:116:190":6,"b:116:106:116:126:116:126:116:149":7,"b:117:71:117:171:117:171:117:Infinity":8,"b:117:11:117:45:117:45:117:71":9,"b:117:94:117:132:117:132:117:171":10,"b:117:191:117:224:117:224:117:Infinity":11}}} -} diff --git a/coverage/favicon.png b/coverage/favicon.png deleted file mode 100644 index c1525b811a167671e9de1fa78aab9f5c0b61cef7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 445 zcmV;u0Yd(XP))rP{nL}Ln%S7`m{0DjX9TLF* zFCb$4Oi7vyLOydb!7n&^ItCzb-%BoB`=x@N2jll2Nj`kauio%aw_@fe&*}LqlFT43 z8doAAe))z_%=P%v^@JHp3Hjhj^6*Kr_h|g_Gr?ZAa&y>wxHE99Gk>A)2MplWz2xdG zy8VD2J|Uf#EAw*bo5O*PO_}X2Tob{%bUoO2G~T`@%S6qPyc}VkhV}UifBuRk>%5v( z)x7B{I~z*k<7dv#5tC+m{km(D087J4O%+<<;K|qwefb6@GSX45wCK}Sn*> - - - - Code coverage report for All files - - - - - - - - - -
-
-

All files

-
- -
- 28.92% - Statements - 35/121 -
- - -
- 29.59% - Branches - 29/98 -
- - -
- 27.77% - Functions - 5/18 -
- - -
- 30.18% - Lines - 32/106 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
scripts -
-
25.23%27/10718.66%14/7525%3/1225.8%24/93
src -
-
100%1/1100%0/0100%0/0100%1/1
src/components -
-
53.84%7/1365.21%15/2333.33%2/658.33%7/12
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/prettify.css b/coverage/prettify.css deleted file mode 100644 index b317a7c..0000000 --- a/coverage/prettify.css +++ /dev/null @@ -1 +0,0 @@ -.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/coverage/prettify.js b/coverage/prettify.js deleted file mode 100644 index b322523..0000000 --- a/coverage/prettify.js +++ /dev/null @@ -1,2 +0,0 @@ -/* eslint-disable */ -window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/coverage/scripts/index.html b/coverage/scripts/index.html deleted file mode 100644 index 9630c47..0000000 --- a/coverage/scripts/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for scripts - - - - - - - - - -
-
-

All files scripts

-
- -
- 25.23% - Statements - 27/107 -
- - -
- 18.66% - Branches - 14/75 -
- - -
- 25% - Functions - 3/12 -
- - -
- 25.8% - Lines - 24/93 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
lakesConfig.ts -
-
100%1/1100%0/0100%0/0100%1/1
scrapeLakes.ts -
-
24.52%26/10618.66%14/7525%3/1225%23/92
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/scripts/lakesConfig.ts.html b/coverage/scripts/lakesConfig.ts.html deleted file mode 100644 index 7aa48e0..0000000 --- a/coverage/scripts/lakesConfig.ts.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - Code coverage report for scripts/lakesConfig.ts - - - - - - - - - -
-
-

All files / scripts lakesConfig.ts

-
- -
- 100% - Statements - 1/1 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 1/1 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  - 
export interface LakeConfig {
-  id: string;
-  text: string;
-  priority?: boolean;
-  coords: [number, number];
-  maxVolume?: number;
-  minLevel?: number;
-  maxLevel?: number;
-  storageLevel?: number;
-}
- 
-export const lakesConfig: LakeConfig[] = [
-  { id: "VLL1|1", text: "VD Lipno 1 - Vltava", priority: true, coords: [48.6322, 14.2215], maxVolume: 306.0, minLevel: 715.00, maxLevel: 725.60, storageLevel: 724.9 },
-  { id: "VLL2|1", text: "VD Lipno II - Vltava", coords: [48.6250, 14.3180], maxVolume: 1.5, minLevel: 510.0, maxLevel: 511.5, storageLevel: 511.5 },
-  { id: "VLHN|1", text: "VD Hněvkovice - Vltava", priority: true, coords: [49.1830, 14.4440], maxVolume: 21.1, minLevel: 365.0, maxLevel: 370.5, storageLevel: 370.1 },
-  { id: "VLKO|1", text: "VD Kořensko - Vltava", coords: [49.2550, 14.3980], maxVolume: 2.8, minLevel: 352.0, maxLevel: 353.5, storageLevel: 352.6 },
-  { id: "VLOR|2", text: "VD Orlík - Vltava", priority: true, coords: [49.6060, 14.1700], maxVolume: 716.5, minLevel: 330.00, maxLevel: 354.00, storageLevel: 349.9 },
-  { id: "UHKA|2", text: "VD Kamýk - Vltava", coords: [49.6360, 14.2540], maxVolume: 12.8, minLevel: 283.0, maxLevel: 285.6, storageLevel: 285.6 },
-  { id: "VLSL|2", text: "VD Slapy - Vltava", priority: true, coords: [49.8220, 14.4360], maxVolume: 269.3, minLevel: 265.50, maxLevel: 271.10, storageLevel: 270.6 },
-  { id: "VLST|2", text: "VD Štěchovice - Vltava", coords: [49.8450, 14.4120], maxVolume: 11.2, minLevel: 217.0, maxLevel: 219.5, storageLevel: 219.4 },
-  { id: "VRSN|2", text: "VD Vrané - Vltava", coords: [49.9340, 14.3850], maxVolume: 11.1, minLevel: 198.5, maxLevel: 200.5, storageLevel: 200.5 },
-  { id: "SVKR|2", text: "VD Švihov - Želivka", priority: true, coords: [49.7180, 15.1060], maxVolume: 266.6, minLevel: 343.0, maxLevel: 377.0, storageLevel: 377.0 },
-  { id: "MARI|1", text: "VD Římov - Malše", priority: true, coords: [48.8470, 14.4870], maxVolume: 33.8, minLevel: 458.0, maxLevel: 471.0, storageLevel: 470.65 },
-  { id: "MZHR|3", text: "VD Hracholusky - Mže", priority: true, coords: [49.7890, 13.1550], maxVolume: 56.7, minLevel: 360.0, maxLevel: 373.0, storageLevel: 354.1 }
-];
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/scripts/scrapeLakes.ts.html b/coverage/scripts/scrapeLakes.ts.html deleted file mode 100644 index 73d8fe7..0000000 --- a/coverage/scripts/scrapeLakes.ts.html +++ /dev/null @@ -1,616 +0,0 @@ - - - - - - Code coverage report for scripts/scrapeLakes.ts - - - - - - - - - -
-
-

All files / scripts scrapeLakes.ts

-
- -
- 24.52% - Statements - 26/106 -
- - -
- 18.66% - Branches - 14/75 -
- - -
- 25% - Functions - 3/12 -
- - -
- 25% - Lines - 23/92 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -7x -7x -4x -4x -4x -  -4x -  -2x -2x -2x -2x -2x -2x -1x -  -  -  -  -  -  -1x -1x -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -  -1x -1x -  -  -  -  -  -  -  -1x - 
import * as fs from 'fs';
-import * as path from 'path';
-import * as cheerio from 'cheerio';
-import axios from 'axios';
-import https from 'https';
-import { lakesConfig } from './lakesConfig';
- 
-interface DataRecord {
-  timestamp: string;
-  level: number;
-  flow: number;
-  inflow?: number;
-  volume?: number;
-  temperature?: number | null;
-  precipitation?: number | null;
-}
- 
-// Parse date from DD.MM.YYYY HH:MM to ISO
-export function parseDateString(dateStr: string): string | null {
-  try {
-    if (!dateStr || !dateStr.includes(' ')) return null;
-    const [datePart, timePart] = dateStr.trim().split(' ');
-    const [day, month, year] = datePart.split('.');
-    const [hours, minutes] = timePart.split(':');
-    
-    if (!year || !hours) return null;
-    
-    const y = parseInt(year);
-    const m = parseInt(month) - 1;
-    const dDay = parseInt(day);
-    const d = new Date(y, m, dDay, parseInt(hours), parseInt(minutes));
-    Iif (isNaN(d.getTime())) return null;
-    if (d.getFullYear() !== y || d.getMonth() !== m || d.getDate() !== dDay) return null;
-    return d.toISOString();
-  } catch (e) {
-    return null;
-  }
-}
- 
-async function scrapeLake(lakeId: string, oid: string, internalId: string) {
-  const URL = `https://www.pvl.cz/portal/nadrze/cz/pc/Mereni.aspx?oid=${oid}&id=${internalId}`;
-  const DATA_FILE = path.resolve(`public/data/${internalId}.json`);
- 
-  try {
-    const agent = new https.Agent({ rejectUnauthorized: false });
-    const response = await axios.get(URL, {
-      httpsAgent: agent,
-      headers: {
-        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
-      }
-    });
- 
-    const $ = cheerio.load(response.data);
-      
-    let currentInflow = 0;
-    let currentVolume = 0;
-    let currentTemp: number | null = null;
-    let currentPrecip: number | null = null;
-    
-    $('table').each((i, tbl) => {
-      const text = $(tbl).text();
-      if (text.includes('Aktuální hodnoty') && text.includes('Přítok')) {
-        $(tbl).find('tr').each((j, r) => {
-          const label = $(r).find('td').eq(0).text().trim();
-          const valStr = $(r).find('td').eq(1).text().trim().replace(/\s/g, '').replace(',', '.');
-          if (label.includes('Přítok')) currentInflow = parseFloat(valStr) || 0;
-          if (label.includes('Objem')) currentVolume = parseFloat(valStr) || 0;
-          if (label.includes('Teplota')) {
-            const v = parseFloat(valStr);
-            if (!isNaN(v)) currentTemp = v;
-          }
-          if (label.includes('Srážky')) {
-            const v = parseFloat(valStr);
-            if (!isNaN(v)) currentPrecip = v;
-          }
-        });
-      }
-    });
- 
-    const records: DataRecord[] = [];
-    let dataTable = null;
-    $('table').each((i, tbl) => {
-      if ($(tbl).text().includes('Datum') && $(tbl).text().includes('Odtok')) {
-        dataTable = $(tbl);
-      }
-    });
- 
-    if (dataTable) {
-      dataTable.find('tr').each((i, row) => {
-        if (i === 0) return; // skip header
-        const cols = $(row).find('td');
-        if (cols.length >= 3) {
-          const rawDate = $(cols[0]).text().trim(); 
-          const levelStr = $(cols[1]).text().trim().replace(',', '.');
-          let flowStr = $(cols[2]).text().trim().replace(',', '.');
-          if (flowStr === '' && cols.length >= 4) {
-            flowStr = $(cols[3]).text().trim().replace(',', '.');
-          }
- 
-          const parsedDateStr = parseDateString(rawDate);
-          if (parsedDateStr) {
-            records.push({
-              timestamp: parsedDateStr,
-              level: parseFloat(levelStr) || 0,
-              flow: parseFloat(flowStr) || 0,
-              inflow: 0,
-              volume: 0
-            });
-          }
-        }
-      });
-    }
- 
-    if (records.length > 0) {
-      // Apply current values to the latest record
-      records[0].inflow = currentInflow;
-      records[0].volume = currentVolume;
-      if (currentTemp !== null) records[0].temperature = currentTemp;
-      if (currentPrecip !== null) records[0].precipitation = currentPrecip;
-    }
- 
-    let existingData: DataRecord[] = [];
-    if (fs.existsSync(DATA_FILE)) {
-      const fileContent = fs.readFileSync(DATA_FILE, 'utf-8');
-      existingData = JSON.parse(fileContent);
-    }
- 
-    const dataMap = new Map<string, DataRecord>();
-    existingData.forEach(item => dataMap.set(item.timestamp, item));
-    records.forEach(item => dataMap.set(item.timestamp, item));
- 
-    const mergedData = Array.from(dataMap.values()).sort((a, b) => {
-      return new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime();
-    });
- 
-    // Propagate previous values if missing (user requested)
-    let lastKnownTemp: number | null = null;
-    let lastKnownPrecip: number | null = null;
-    mergedData.forEach(item => {
-      if (item.temperature !== undefined && item.temperature !== null) {
-        lastKnownTemp = item.temperature;
-      } else if (lastKnownTemp !== null) {
-        item.temperature = lastKnownTemp;
-      }
- 
-      if (item.precipitation !== undefined && item.precipitation !== null) {
-        lastKnownPrecip = item.precipitation;
-      } else if (lastKnownPrecip !== null) {
-        item.precipitation = lastKnownPrecip;
-      }
-    });
- 
-    fs.mkdirSync(path.dirname(DATA_FILE), { recursive: true });
-    fs.writeFileSync(DATA_FILE, JSON.stringify(mergedData, null, 2), 'utf-8');
-    
-    console.log(`[${internalId}] Scraped ${records.length} records. DB total: ${mergedData.length}`);
- 
-  } catch (error: any) {
-    console.error(`[${internalId}] Error scraping data:`, error.message);
-  }
-}
- 
-async function runScraper() {
-  console.log(`Starting bulk scraper for ${lakesConfig.length} lakes...`);
-  
-  for (const lake of lakesConfig) {
-    // ID format: VLL1|1 -> internalId=VLL1, oid=1
-    const [internalId, oid] = lake.id.split('|');
-    await scrapeLake(lake.id, oid, internalId);
-    // Add small delay to not hammer the server
-    await new Promise(resolve => setTimeout(resolve, 500));
-  }
-  
-  console.log('Bulk scraping finished.');
-}
- 
-runScraper();
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/sort-arrow-sprite.png b/coverage/sort-arrow-sprite.png deleted file mode 100644 index 6ed68316eb3f65dec9063332d2f69bf3093bbfab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^>_9Bd!3HEZxJ@+%Qh}Z>jv*C{$p!i!8j}?a+@3A= zIAGwzjijN=FBi!|L1t?LM;Q;gkwn>2cAy-KV{dn nf0J1DIvEHQu*n~6U}x}qyky7vi4|9XhBJ7&`njxgN@xNA8m%nc diff --git a/coverage/sorter.js b/coverage/sorter.js deleted file mode 100644 index 4ed70ae..0000000 --- a/coverage/sorter.js +++ /dev/null @@ -1,210 +0,0 @@ -/* eslint-disable */ -var addSorting = (function() { - 'use strict'; - var cols, - currentSort = { - index: 0, - desc: false - }; - - // returns the summary table element - function getTable() { - return document.querySelector('.coverage-summary'); - } - // returns the thead element of the summary table - function getTableHeader() { - return getTable().querySelector('thead tr'); - } - // returns the tbody element of the summary table - function getTableBody() { - return getTable().querySelector('tbody'); - } - // returns the th element for nth column - function getNthColumn(n) { - return getTableHeader().querySelectorAll('th')[n]; - } - - function onFilterInput() { - const searchValue = document.getElementById('fileSearch').value; - const rows = document.getElementsByTagName('tbody')[0].children; - - // Try to create a RegExp from the searchValue. If it fails (invalid regex), - // it will be treated as a plain text search - let searchRegex; - try { - searchRegex = new RegExp(searchValue, 'i'); // 'i' for case-insensitive - } catch (error) { - searchRegex = null; - } - - for (let i = 0; i < rows.length; i++) { - const row = rows[i]; - let isMatch = false; - - if (searchRegex) { - // If a valid regex was created, use it for matching - isMatch = searchRegex.test(row.textContent); - } else { - // Otherwise, fall back to the original plain text search - isMatch = row.textContent - .toLowerCase() - .includes(searchValue.toLowerCase()); - } - - row.style.display = isMatch ? '' : 'none'; - } - } - - // loads the search box - function addSearchBox() { - var template = document.getElementById('filterTemplate'); - var templateClone = template.content.cloneNode(true); - templateClone.getElementById('fileSearch').oninput = onFilterInput; - template.parentElement.appendChild(templateClone); - } - - // loads all columns - function loadColumns() { - var colNodes = getTableHeader().querySelectorAll('th'), - colNode, - cols = [], - col, - i; - - for (i = 0; i < colNodes.length; i += 1) { - colNode = colNodes[i]; - col = { - key: colNode.getAttribute('data-col'), - sortable: !colNode.getAttribute('data-nosort'), - type: colNode.getAttribute('data-type') || 'string' - }; - cols.push(col); - if (col.sortable) { - col.defaultDescSort = col.type === 'number'; - colNode.innerHTML = - colNode.innerHTML + ''; - } - } - return cols; - } - // attaches a data attribute to every tr element with an object - // of data values keyed by column name - function loadRowData(tableRow) { - var tableCols = tableRow.querySelectorAll('td'), - colNode, - col, - data = {}, - i, - val; - for (i = 0; i < tableCols.length; i += 1) { - colNode = tableCols[i]; - col = cols[i]; - val = colNode.getAttribute('data-value'); - if (col.type === 'number') { - val = Number(val); - } - data[col.key] = val; - } - return data; - } - // loads all row data - function loadData() { - var rows = getTableBody().querySelectorAll('tr'), - i; - - for (i = 0; i < rows.length; i += 1) { - rows[i].data = loadRowData(rows[i]); - } - } - // sorts the table using the data for the ith column - function sortByIndex(index, desc) { - var key = cols[index].key, - sorter = function(a, b) { - a = a.data[key]; - b = b.data[key]; - return a < b ? -1 : a > b ? 1 : 0; - }, - finalSorter = sorter, - tableBody = document.querySelector('.coverage-summary tbody'), - rowNodes = tableBody.querySelectorAll('tr'), - rows = [], - i; - - if (desc) { - finalSorter = function(a, b) { - return -1 * sorter(a, b); - }; - } - - for (i = 0; i < rowNodes.length; i += 1) { - rows.push(rowNodes[i]); - tableBody.removeChild(rowNodes[i]); - } - - rows.sort(finalSorter); - - for (i = 0; i < rows.length; i += 1) { - tableBody.appendChild(rows[i]); - } - } - // removes sort indicators for current column being sorted - function removeSortIndicators() { - var col = getNthColumn(currentSort.index), - cls = col.className; - - cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); - col.className = cls; - } - // adds sort indicators for current column being sorted - function addSortIndicators() { - getNthColumn(currentSort.index).className += currentSort.desc - ? ' sorted-desc' - : ' sorted'; - } - // adds event listeners for all sorter widgets - function enableUI() { - var i, - el, - ithSorter = function ithSorter(i) { - var col = cols[i]; - - return function() { - var desc = col.defaultDescSort; - - if (currentSort.index === i) { - desc = !currentSort.desc; - } - sortByIndex(i, desc); - removeSortIndicators(); - currentSort.index = i; - currentSort.desc = desc; - addSortIndicators(); - }; - }; - for (i = 0; i < cols.length; i += 1) { - if (cols[i].sortable) { - // add the click event handler on the th so users - // dont have to click on those tiny arrows - el = getNthColumn(i).querySelector('.sorter').parentElement; - if (el.addEventListener) { - el.addEventListener('click', ithSorter(i)); - } else { - el.attachEvent('onclick', ithSorter(i)); - } - } - } - } - // adds sorting functionality to the UI - return function() { - if (!getTable()) { - return; - } - cols = loadColumns(); - loadData(); - addSearchBox(); - addSortIndicators(); - enableUI(); - }; -})(); - -window.addEventListener('load', addSorting); diff --git a/coverage/src/components/KpiCards.tsx.html b/coverage/src/components/KpiCards.tsx.html deleted file mode 100644 index 4289925..0000000 --- a/coverage/src/components/KpiCards.tsx.html +++ /dev/null @@ -1,466 +0,0 @@ - - - - - - Code coverage report for src/components/KpiCards.tsx - - - - - - - - - -
-
-

All files / src/components KpiCards.tsx

-
- -
- 53.84% - Statements - 7/13 -
- - -
- 65.21% - Branches - 15/23 -
- - -
- 33.33% - Functions - 2/6 -
- - -
- 58.33% - Lines - 7/12 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -3x -3x -3x -  -3x -3x -  -  -  -  -  -  -  -3x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { FiArrowUp, FiArrowDown } from 'react-icons/fi';
-import { type Language, t } from '../translations';
-import { useState, useEffect } from 'react';
- 
-interface KpiData {
-  level: number;
-  inflow: number;
-  outflow: number;
-  outflow: number;
-  volume: number;
-  fullness: number;
-  storageDiff?: number;
-}
- 
-interface Props {
-  data: KpiData;
-  language: Language;
-  lakeName?: string;
-}
- 
-const KpiCards = ({ data, language, lakeName = 'Lipno 1' }: Props) => {
-  const [showTooltip, setShowTooltip] = useState(false);
-  const dict = t[language].kpi;
-  const flowDiff = data.inflow - data.outflow;
- 
-  useEffect(() => {
-    Iif (showTooltip) {
-      const timer = setTimeout(() => {
-        setShowTooltip(false);
-      }, 3500);
-      return () => clearTimeout(timer);
-    }
-  }, [showTooltip]);
- 
-  return (
-    <div className="kpi-grid-container">
-      {/* CARD 1: HLADINA */}
-      <div className="kpi-card">
-        <div style={{ fontSize: '1rem', color: 'var(--text-muted)', marginBottom: '0.5rem' }}>
-          {dict.level} {lakeName}
-        </div>
-        <div style={{ fontSize: '2.5rem', fontWeight: 'bold', color: 'var(--color-cyan)', lineHeight: 1, marginBottom: '0.5rem' }}>
-          {data.level.toFixed(2)} <span style={{ fontSize: '1rem', color: 'var(--text-muted)', fontWeight: 'normal' }}>m n. m.</span>
-        </div>
-        <div style={{ fontSize: '0.85rem', color: 'var(--color-green)' }}>
-          (+0.02 m / 24h)
-        </div>
-        
-        {/* Decorative Circle for Level */}
-        <div style={{ position: 'absolute', right: '1.5rem', top: '1.5rem', width: '40px', height: '40px', borderRadius: '50%', border: '4px solid rgba(0, 195, 255, 0.2)', borderTopColor: 'var(--color-cyan)', transform: 'rotate(45deg)' }}></div>
-      </div>
- 
-      {/* CARD 2: PRŮTOK */}
-      <div className="kpi-card">
-        <div style={{ fontSize: '1rem', color: 'var(--text-muted)', marginBottom: '0.5rem' }}>
-          {dict.flow}
-        </div>
-        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', height: '100%' }}>
-          <div style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem', fontSize: '0.85rem' }}>
-            <div style={{ fontSize: '0.85rem', color: 'var(--text-muted)', display: 'flex', alignItems: 'center' }}>
-              <span style={{ display: 'inline-block', width: '8px', height: '8px', borderRadius: '50%', backgroundColor: '#8b5cf6', marginRight: '6px' }}></span>
-              {dict.inflow}: <span style={{ fontWeight: 'bold', color: 'var(--text-main)', marginLeft: '4px' }}>{data.inflow.toFixed(1)} m³/s</span>
-            </div>
-            <div style={{ fontSize: '0.85rem', color: 'var(--text-muted)', marginTop: '0.25rem', display: 'flex', alignItems: 'center', gap: '0.25rem' }}>
-              <span style={{ display: 'inline-block', width: '8px', height: '8px', borderRadius: '50%', backgroundColor: 'var(--color-orange)', marginRight: '2px' }}></span>
-              {dict.outflow}: <span style={{ fontWeight: 'bold', color: 'var(--text-main)' }}>{data.outflow.toFixed(1)} m³/s</span>
-              {flowDiff > 0 ? <FiArrowUp color="var(--color-green)" /> : flowDiff < 0 ? <FiArrowDown color="var(--color-red)" /> : null}
-            </div>
-          </div>
-          
-          {/* Flow Circle */}
-          <div style={{ width: '40px', height: '40px', borderRadius: '50%', border: '4px solid rgba(0, 195, 255, 0.2)', borderTopColor: 'var(--color-cyan)', borderRightColor: 'var(--color-cyan)', display: 'flex', alignItems: 'center', justifyContent: 'center', transform: 'rotate(-45deg)' }}>
-            <span style={{ fontSize: '0.65rem', transform: 'rotate(45deg)', color: 'var(--text-main)', fontWeight: 'bold' }}>
-              <div style={{ lineHeight: 1 }}>{data.outflow.toFixed(1)}</div>
-              <div style={{ fontSize: '0.45rem', opacity: 0.7 }}>m³/s</div>
-            </span>
-          </div>
-        </div>
-      </div>
- 
-      {/* CARD 3: NAPLNĚNOST */}
-      <div className="kpi-card">
-        <div style={{ fontSize: '1rem', color: 'var(--text-muted)', marginBottom: '0.5rem', display: 'flex', alignItems: 'center', gap: '0.4rem', position: 'relative' }}>
-          {dict.fullness}
-          <span 
-            onClick={() => setShowTooltip(!showTooltip)}
-            style={{ cursor: 'pointer', fontSize: '0.85rem', opacity: 0.6, padding: '0 4px' }}
-          >
-            ⓘ
-          </span>
-          {showTooltip && (
-            <div 
-              onClick={() => setShowTooltip(false)}
-              style={{
-                position: 'absolute',
-                bottom: '100%',
-                left: '50%',
-                transform: 'translateX(-50%)',
-                marginBottom: '8px',
-                backgroundColor: 'var(--bg-card)',
-                border: '1px solid var(--border-color)',
-                padding: '0.75rem',
-                borderRadius: '8px',
-                width: '250px',
-                zIndex: 100,
-                boxShadow: '0 4px 12px rgba(0,0,0,0.5)',
-                color: 'var(--text-main)',
-                fontSize: '0.85rem',
-                lineHeight: 1.4,
-                cursor: 'pointer'
-              }}>
-              {language === 'cs' ? "Rozdíl mezi aktuální hladinou a hladinou zásobního prostoru (důležité pro jachtaře a rekreaci)." : "Difference between current water level and storage space level (important for sailing and recreation)."}
-            </div>
-          )}
-        </div>
-        <div style={{ fontSize: '2rem', fontWeight: 'bold', lineHeight: 1, marginBottom: '0.5rem', color: data.storageDiff && data.storageDiff < 0 ? 'var(--color-red)' : 'var(--color-cyan)' }}>
-          {data.storageDiff !== undefined && data.storageDiff !== 0 ? (data.storageDiff > 0 ? `+${data.storageDiff.toFixed(2)} m` : `${data.storageDiff.toFixed(2)} m`) : (data.fullness > 0 ? `${data.fullness.toFixed(1)}%` : 'N/A')}
-        </div>
-        <div style={{ fontSize: '0.85rem', color: 'var(--text-muted)' }}>
-          {dict.volume}: {data.volume.toFixed(1)} mil. m³
-        </div>
-      </div>
-    </div>
-  );
-};
- 
-export default KpiCards;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/src/components/index.html b/coverage/src/components/index.html deleted file mode 100644 index 4186b73..0000000 --- a/coverage/src/components/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for src/components - - - - - - - - - -
-
-

All files src/components

-
- -
- 53.84% - Statements - 7/13 -
- - -
- 65.21% - Branches - 15/23 -
- - -
- 33.33% - Functions - 2/6 -
- - -
- 58.33% - Lines - 7/12 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
KpiCards.tsx -
-
53.84%7/1365.21%15/2333.33%2/658.33%7/12
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/src/index.html b/coverage/src/index.html deleted file mode 100644 index 06e41ba..0000000 --- a/coverage/src/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for src - - - - - - - - - -
-
-

All files src

-
- -
- 100% - Statements - 1/1 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 1/1 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
translations.ts -
-
100%1/1100%0/0100%0/0100%1/1
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/src/translations.ts.html b/coverage/src/translations.ts.html deleted file mode 100644 index a0395ee..0000000 --- a/coverage/src/translations.ts.html +++ /dev/null @@ -1,385 +0,0 @@ - - - - - - Code coverage report for src/translations.ts - - - - - - - - - -
-
-

All files / src translations.ts

-
- -
- 100% - Statements - 1/1 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 1/1 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101  -  -2x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
export type Language = 'en' | 'cs';
- 
-export const t = {
-  en: {
-    sidebar: {
-      favorites: 'Favorites',
-      lakes: 'Lakes',
-      map: 'Map',
-      settings: 'Settings'
-    },
-    topbar: {
-      search: 'Search river or reservoir (e.g. Lipno)...',
-      updated: 'Last updated:'
-    },
-    kpi: {
-      level: 'WATER LEVEL',
-      flow: 'FLOW RATE',
-      inflow: 'Inflow',
-      outflow: 'Outflow',
-      fullness: 'STORAGE LEVEL',
-      volume: 'Volume'
-    },
-    chart: {
-      title: 'Long-term development',
-      timeframe: 'Timeframe',
-      timeframeMobile: 'Time',
-      view: 'View',
-      raw: 'Raw data',
-      smoothed: 'Smoothed',
-      calendar: 'Calendar',
-      all: 'All',
-      year: 'Year',
-      level: 'Water level',
-      inflow: 'Inflow',
-      outflow: 'Outflow',
-      maxLevel: 'Max retention level',
-      storageLevel: 'Storage space level',
-      dataSources: 'Data sources:',
-      createdIn: 'Created with ♥ in the Czech Republic'
-    },
-    settings: {
-      title: 'Settings',
-      theme: 'Theme',
-      dark: 'Dark',
-      light: 'Light',
-      language: 'Language',
-      english: 'English',
-      czech: 'Čeština',
-      buyCoffee: 'Buy Me a Coffee'
-    }
-  },
-  cs: {
-    sidebar: {
-      favorites: 'Oblíbené',
-      lakes: 'Jezera',
-      map: 'Mapa',
-      settings: 'Nastavení'
-    },
-    topbar: {
-      search: 'Hledat tok nebo nádrž (např. Lipno)...',
-      updated: 'Aktualizováno:'
-    },
-    kpi: {
-      level: 'HLADINA',
-      flow: 'PRŮTOK',
-      inflow: 'Přítok',
-      outflow: 'Odtok',
-      fullness: 'ZÁSOBNÍ PROSTOR',
-      volume: 'Objem'
-    },
-    chart: {
-      title: 'Dlouhodobý vývoj',
-      timeframe: 'Časové období',
-      timeframeMobile: 'Časové',
-      view: 'Zobrazení',
-      raw: 'Syrová data',
-      smoothed: 'Vyhlazená',
-      calendar: 'Kalendář',
-      all: 'Vše',
-      year: 'Rok',
-      level: 'Hladina',
-      inflow: 'Přítok',
-      outflow: 'Odtok',
-      maxLevel: 'Max. retenční hladina',
-      storageLevel: 'Hladina zásobního prostoru',
-      dataSources: 'Zdroje dat:',
-      createdIn: 'Vytvořeno s ♥ v České republice'
-    },
-    settings: {
-      title: 'Nastavení',
-      theme: 'Vzhled',
-      dark: 'Tmavý',
-      light: 'Světlý',
-      language: 'Jazyk',
-      english: 'English',
-      czech: 'Čeština',
-      buyCoffee: 'Kup mi kávu'
-    }
-  }
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/public/data/MARI.json b/public/data/MARI.json index f57be84..a25ae7f 100644 --- a/public/data/MARI.json +++ b/public/data/MARI.json @@ -7103,10 +7103,64 @@ { "timestamp": "2026-06-06T08:30:00.000Z", "level": 467.74, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:40:00.000Z", + "level": 467.74, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:50:00.000Z", + "level": 467.74, "flow": 0, "inflow": 2.24, "volume": 26.53, - "temperature": 17.5, + "temperature": 17.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:00:00.000Z", + "level": 467.74, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 17.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:10:00.000Z", + "level": 467.74, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 17.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:20:00.000Z", + "level": 467.74, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 17.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:30:00.000Z", + "level": 467.74, + "flow": 0, + "inflow": 2.24, + "volume": 26.53, + "temperature": 18.8, "precipitation": 0 } ] \ No newline at end of file diff --git a/public/data/MZHR.json b/public/data/MZHR.json index 561634e..2387786 100644 --- a/public/data/MZHR.json +++ b/public/data/MZHR.json @@ -7103,10 +7103,64 @@ { "timestamp": "2026-06-06T08:30:00.000Z", "level": 352.84, + "flow": 2.53, + "inflow": 0, + "volume": 0, + "temperature": 8.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:40:00.000Z", + "level": 352.85, + "flow": 2.55, + "inflow": 0, + "volume": 0, + "temperature": 8.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:50:00.000Z", + "level": 352.84, "flow": 0, "inflow": 1.47, "volume": 32.32, - "temperature": 17.3, + "temperature": 17.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:00:00.000Z", + "level": 352.84, + "flow": 2.53, + "inflow": 0, + "volume": 0, + "temperature": 17.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:10:00.000Z", + "level": 352.84, + "flow": 2.53, + "inflow": 0, + "volume": 0, + "temperature": 17.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:20:00.000Z", + "level": 352.84, + "flow": 2.53, + "inflow": 0, + "volume": 0, + "temperature": 17.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:30:00.000Z", + "level": 352.84, + "flow": 0, + "inflow": 1.47, + "volume": 32.32, + "temperature": 19, "precipitation": 0 } ] \ No newline at end of file diff --git a/public/data/VLHN.json b/public/data/VLHN.json index 689f69b..fde004a 100644 --- a/public/data/VLHN.json +++ b/public/data/VLHN.json @@ -7141,8 +7141,62 @@ "level": 369.83, "flow": 2.5, "inflow": 0, + "volume": 0, + "temperature": 16, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:40:00.000Z", + "level": 369.83, + "flow": 2.5, + "inflow": 0, + "volume": 0, + "temperature": 16, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:50:00.000Z", + "level": 369.83, + "flow": 2.5, + "inflow": 0, "volume": 20.33, - "temperature": 17.6, + "temperature": 18, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:00:00.000Z", + "level": 369.83, + "flow": 2.5, + "inflow": 0, + "volume": 0, + "temperature": 18, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:10:00.000Z", + "level": 369.83, + "flow": 2.5, + "inflow": 0, + "volume": 0, + "temperature": 18, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:20:00.000Z", + "level": 369.83, + "flow": 2.5, + "inflow": 0, + "volume": 0, + "temperature": 18, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:30:00.000Z", + "level": 369.83, + "flow": 2.5, + "inflow": 0, + "volume": 20.36, + "temperature": 19.1, "precipitation": 0 } ] \ No newline at end of file diff --git a/public/data/VLKO.json b/public/data/VLKO.json index 9879dbc..ead51bc 100644 --- a/public/data/VLKO.json +++ b/public/data/VLKO.json @@ -7140,9 +7140,63 @@ "timestamp": "2026-06-06T08:30:00.000Z", "level": 352.56, "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 15.1, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:40:00.000Z", + "level": 352.56, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 15.1, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:50:00.000Z", + "level": 352.55, + "flow": 19.05, "inflow": 13.43, "volume": 2.79, - "temperature": 16.9, + "temperature": 17.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:00:00.000Z", + "level": 352.55, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 17.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:10:00.000Z", + "level": 352.54, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 17.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:20:00.000Z", + "level": 352.54, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 17.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:30:00.000Z", + "level": 352.53, + "flow": 19.05, + "inflow": 13.43, + "volume": 2.78, + "temperature": 18.8, "precipitation": 0 } ] \ No newline at end of file diff --git a/public/data/VLL1.json b/public/data/VLL1.json index 873272b..6074c36 100644 --- a/public/data/VLL1.json +++ b/public/data/VLL1.json @@ -7121,10 +7121,64 @@ { "timestamp": "2026-06-06T08:30:00.000Z", "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 10, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:40:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 10, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:50:00.000Z", + "level": 723.09, "flow": 0, "inflow": 9.25, "volume": 199.67, - "temperature": 16.3, + "temperature": 16.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:00:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 16.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:10:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 16.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:20:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 16.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:30:00.000Z", + "level": 723.09, + "flow": 0, + "inflow": 9.25, + "volume": 199.67, + "temperature": 17.7, "precipitation": 0 } ] \ No newline at end of file diff --git a/public/data/VLL2.json b/public/data/VLL2.json index b3a9951..64237f5 100644 --- a/public/data/VLL2.json +++ b/public/data/VLL2.json @@ -7121,7 +7121,7 @@ { "timestamp": "2026-06-06T08:10:00.000Z", "level": 559.12, - "flow": 0, + "flow": 7.15, "inflow": 0, "volume": 0, "temperature": 16.3, @@ -7130,7 +7130,7 @@ { "timestamp": "2026-06-06T08:20:00.000Z", "level": 559.11, - "flow": 0, + "flow": 7.18, "inflow": 0, "volume": 0, "temperature": 16.3, @@ -7140,9 +7140,63 @@ "timestamp": "2026-06-06T08:30:00.000Z", "level": 559.09, "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 16.3, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:40:00.000Z", + "level": 559.08, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 16.3, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:50:00.000Z", + "level": 559.06, + "flow": 0, "inflow": 5.37, "volume": 0.49, - "temperature": 17.7, + "temperature": 18.1, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:00:00.000Z", + "level": 559.05, + "flow": 7.15, + "inflow": 0, + "volume": 0, + "temperature": 18.1, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:10:00.000Z", + "level": 559.03, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 18.1, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:20:00.000Z", + "level": 559.02, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 18.1, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:30:00.000Z", + "level": 559, + "flow": 0, + "inflow": 5.37, + "volume": 0.47, + "temperature": 19.2, "precipitation": 0 } ] \ No newline at end of file diff --git a/public/data/VLOR.json b/public/data/VLOR.json index f044fe9..2acd64c 100644 --- a/public/data/VLOR.json +++ b/public/data/VLOR.json @@ -7131,9 +7131,72 @@ "timestamp": "2026-06-06T08:20:00.000Z", "level": 345.27, "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 16.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:30:00.000Z", + "level": 345.27, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 16.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:40:00.000Z", + "level": 345.27, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 16.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:50:00.000Z", + "level": 345.27, + "flow": 0, "inflow": 24.39, "volume": 522.12, - "temperature": 17.6, + "temperature": 17.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:00:00.000Z", + "level": 345.27, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 17.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:10:00.000Z", + "level": 345.27, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 17.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:20:00.000Z", + "level": 345.27, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 17.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:30:00.000Z", + "level": 345.27, + "flow": 0, + "inflow": 24.39, + "volume": 522.32, + "temperature": 19.2, "precipitation": 0 } ] \ No newline at end of file diff --git a/public/data/VLSL.json b/public/data/VLSL.json index d14ccfe..c9fce37 100644 --- a/public/data/VLSL.json +++ b/public/data/VLSL.json @@ -7149,9 +7149,63 @@ "timestamp": "2026-06-06T08:30:00.000Z", "level": 269.87, "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 17.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:40:00.000Z", + "level": 269.87, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 17.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:50:00.000Z", + "level": 269.88, + "flow": 0, "inflow": 81.06, "volume": 261.23, - "temperature": 18.6, + "temperature": 18.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:00:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 18.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:10:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 18.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:20:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 18.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:30:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 81.06, + "volume": 261.07, + "temperature": 19.9, "precipitation": 0 } ] \ No newline at end of file diff --git a/public/data/VLST.json b/public/data/VLST.json index 3bcdf8c..922a300 100644 --- a/public/data/VLST.json +++ b/public/data/VLST.json @@ -7140,9 +7140,72 @@ "timestamp": "2026-06-06T08:20:00.000Z", "level": 217.17, "flow": 25.31, + "inflow": 0, + "volume": 0, + "temperature": 17.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:30:00.000Z", + "level": 217.14, + "flow": 25.31, + "inflow": 0, + "volume": 0, + "temperature": 17.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:40:00.000Z", + "level": 217.13, + "flow": 25.31, + "inflow": 0, + "volume": 0, + "temperature": 17.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T08:50:00.000Z", + "level": 217.12, + "flow": 25.32, "inflow": 48.25, "volume": 8.36, - "temperature": 18.1, + "temperature": 18.4, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:00:00.000Z", + "level": 217.1, + "flow": 25.32, + "inflow": 0, + "volume": 0, + "temperature": 18.4, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:10:00.000Z", + "level": 217.09, + "flow": 11.61, + "inflow": 0, + "volume": 0, + "temperature": 18.4, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:20:00.000Z", + "level": 217.1, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 18.4, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T09:30:00.000Z", + "level": 217.07, + "flow": 0, + "inflow": 48.25, + "volume": 8.27, + "temperature": 19.6, "precipitation": 0 } ] \ No newline at end of file diff --git a/public/data/lakes_index.json b/public/data/lakes_index.json index 8e8ff9e..a743812 100644 --- a/public/data/lakes_index.json +++ b/public/data/lakes_index.json @@ -5,7 +5,7 @@ "river": "Vltava", "priority": true, "level": "723.09", - "capacity": 76.3, + "capacity": 65.3, "storageDiff": -1.81, "inflow": "9.3", "outflow": "0.0", @@ -32,29 +32,29 @@ "id": "VLL2|1", "name": "Lipno II", "river": "Vltava", - "priority": false, - "level": "559.09", - "capacity": 100, - "storageDiff": 47.59, + "priority": true, + "level": "559.00", + "capacity": 31.3, + "storageDiff": -1.5, "inflow": "5.4", "outflow": "0.0", - "volume": 0.49, + "volume": 0.47, "maxVolume": 1.5, "lat": 48.625, "lng": 14.318, "sparkline": [ - 559.44, - 559.37, - 559.29, - 559.21, - 559.2, - 559.19, 559.18, 559.16, 559.13, 559.12, 559.11, - 559.09 + 559.09, + 559.08, + 559.06, + 559.05, + 559.03, + 559.02, + 559 ] }, { @@ -63,26 +63,26 @@ "river": "Vltava", "priority": true, "level": "369.83", - "capacity": 87.8, + "capacity": 96.5, "storageDiff": -0.27, "inflow": "0.0", "outflow": "2.5", - "volume": 20.33, + "volume": 20.36, "maxVolume": 21.1, "lat": 49.183, "lng": 14.444, "sparkline": [ - 369.85, - 369.84, - 369.84, - 369.84, - 369.84, - 369.83, 369.83, 369.83, 369.81, 369.81, 369.83, + 369.83, + 369.83, + 369.83, + 369.83, + 369.83, + 369.83, 369.83 ] }, @@ -90,29 +90,29 @@ "id": "VLKO|1", "name": "Kořensko", "river": "Vltava", - "priority": false, - "level": "352.56", - "capacity": 37.3, - "storageDiff": -0.04, + "priority": true, + "level": "352.53", + "capacity": 99.3, + "storageDiff": -0.07, "inflow": "13.4", "outflow": "19.1", - "volume": 2.79, + "volume": 2.78, "maxVolume": 2.8, "lat": 49.255, "lng": 14.398, "sparkline": [ - 352.49, - 352.52, - 352.56, - 352.57, - 352.57, 352.56, 352.56, 352.56, 352.56, 352.56, 352.56, - 352.56 + 352.56, + 352.55, + 352.55, + 352.54, + 352.54, + 352.53 ] }, { @@ -121,172 +121,85 @@ "river": "Vltava", "priority": true, "level": "345.27", - "capacity": 63.6, + "capacity": 72.9, "storageDiff": -4.63, "inflow": "24.4", "outflow": "0.0", - "volume": 522.12, + "volume": 522.32, "maxVolume": 716.5, "lat": 49.606, "lng": 14.17, "sparkline": [ - 345.26, - 345.26, - 345.25, - 345.26, - 345.26, - 345.26, - 345.26, 345.26, 345.26, 345.26, 345.27, + 345.27, + 345.27, + 345.27, + 345.27, + 345.27, + 345.27, + 345.27, 345.27 ] }, - { - "id": "UHKA|2", - "name": "Kamýk", - "river": "Vltava", - "priority": false, - "level": "0.00", - "capacity": 0, - "storageDiff": 0, - "inflow": "0.0", - "outflow": "0.0", - "volume": 12.8, - "maxVolume": 12.8, - "lat": 49.636, - "lng": 14.254, - "sparkline": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ] - }, { "id": "VLSL|2", "name": "Slapy", "river": "Vltava", "priority": true, - "level": "269.87", - "capacity": 78, - "storageDiff": -0.73, + "level": "269.88", + "capacity": 96.9, + "storageDiff": -0.72, "inflow": "81.1", "outflow": "0.0", - "volume": 261.23, + "volume": 261.07, "maxVolume": 269.3, "lat": 49.822, "lng": 14.436, "sparkline": [ - 269.86, + 269.89, + 269.89, + 269.89, 269.89, 269.88, - 269.88, 269.87, - 269.89, - 269.89, - 269.89, - 269.89, - 269.89, + 269.87, 269.88, - 269.87 + 269.88, + 269.88, + 269.88, + 269.88 ] }, { "id": "VLST|2", "name": "Štěchovice", "river": "Vltava", - "priority": false, - "level": "217.17", - "capacity": 6.8, - "storageDiff": -2.23, + "priority": true, + "level": "217.07", + "capacity": 73.8, + "storageDiff": -2.33, "inflow": "48.3", - "outflow": "25.3", - "volume": 8.36, + "outflow": "0.0", + "volume": 8.27, "maxVolume": 11.2, "lat": 49.845, "lng": 14.412, "sparkline": [ - 218.1, - 217.82, - 217.57, - 217.32, - 217.29, - 217.27, - 217.24, 217.23, 217.22, 217.19, 217.17, - 217.17 - ] - }, - { - "id": "VRSN|2", - "name": "Vrané", - "river": "Vltava", - "priority": false, - "level": "0.00", - "capacity": 0, - "storageDiff": 0, - "inflow": "0.0", - "outflow": "0.0", - "volume": 11.1, - "maxVolume": 11.1, - "lat": 49.934, - "lng": 14.385, - "sparkline": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ] - }, - { - "id": "SVKR|2", - "name": "Švihov", - "river": "Želivka", - "priority": true, - "level": "0.00", - "capacity": 0, - "storageDiff": 0, - "inflow": "0.0", - "outflow": "0.0", - "volume": 266.6, - "maxVolume": 266.6, - "lat": 49.718, - "lng": 15.106, - "sparkline": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 217.17, + 217.14, + 217.13, + 217.12, + 217.1, + 217.09, + 217.1, + 217.07 ] }, { @@ -295,7 +208,7 @@ "river": "Malše", "priority": true, "level": "467.74", - "capacity": 74.9, + "capacity": 78.5, "storageDiff": -2.91, "inflow": "2.2", "outflow": "0.0", @@ -306,12 +219,12 @@ "sparkline": [ 467.73, 467.73, - 467.73, - 467.73, - 467.73, - 467.73, - 467.73, - 467.73, + 467.74, + 467.74, + 467.74, + 467.74, + 467.74, + 467.74, 467.74, 467.74, 467.74, @@ -324,8 +237,8 @@ "river": "Mže", "priority": true, "level": "352.84", - "capacity": 0, - "storageDiff": -1.26, + "capacity": 57, + "storageDiff": -16.66, "inflow": "1.5", "outflow": "0.0", "volume": 32.32, @@ -333,17 +246,17 @@ "lat": 49.789, "lng": 13.155, "sparkline": [ - 352.85, - 352.85, - 352.84, - 352.84, - 352.84, - 352.84, 352.84, 352.84, 352.84, 352.84, 352.85, + 352.84, + 352.85, + 352.84, + 352.84, + 352.84, + 352.84, 352.84 ] } diff --git a/scripts/buildIndex.ts b/scripts/buildIndex.ts index 9239c8a..1445ad4 100644 --- a/scripts/buildIndex.ts +++ b/scripts/buildIndex.ts @@ -53,7 +53,9 @@ const lakes = lakesConfig.map(lake => { } } - if (lake.minLevel && lake.maxLevel && currentLevel > 0) { + if (volume > 0 && lake.maxVolume && lake.maxVolume > 0) { + capacity = Math.max(0, Math.min(100, Math.round((volume / lake.maxVolume) * 1000) / 10)); + } else if (lake.minLevel && lake.maxLevel && currentLevel > 0) { const percentage = ((currentLevel - lake.minLevel) / (lake.maxLevel - lake.minLevel)) * 100; capacity = Math.max(0, Math.min(100, Math.round(percentage * 10) / 10)); // Round to 1 decimal place if (volume === 0) { diff --git a/scripts/lakesConfig.ts b/scripts/lakesConfig.ts index 4dfa142..e0863f4 100644 --- a/scripts/lakesConfig.ts +++ b/scripts/lakesConfig.ts @@ -11,15 +11,12 @@ export interface LakeConfig { export const lakesConfig: LakeConfig[] = [ { id: "VLL1|1", text: "VD Lipno 1 - Vltava", priority: true, coords: [48.6322, 14.2215], maxVolume: 306.0, minLevel: 715.00, maxLevel: 725.60, storageLevel: 724.9 }, - { id: "VLL2|1", text: "VD Lipno II - Vltava", coords: [48.6250, 14.3180], maxVolume: 1.5, minLevel: 510.0, maxLevel: 511.5, storageLevel: 511.5 }, + { id: "VLL2|1", text: "VD Lipno II - Vltava", priority: true, coords: [48.6250, 14.3180], maxVolume: 1.5, minLevel: 557.0, maxLevel: 562.5, storageLevel: 560.5 }, { id: "VLHN|1", text: "VD Hněvkovice - Vltava", priority: true, coords: [49.1830, 14.4440], maxVolume: 21.1, minLevel: 365.0, maxLevel: 370.5, storageLevel: 370.1 }, - { id: "VLKO|1", text: "VD Kořensko - Vltava", coords: [49.2550, 14.3980], maxVolume: 2.8, minLevel: 352.0, maxLevel: 353.5, storageLevel: 352.6 }, + { id: "VLKO|1", text: "VD Kořensko - Vltava", priority: true, coords: [49.2550, 14.3980], maxVolume: 2.8, minLevel: 352.0, maxLevel: 353.5, storageLevel: 352.6 }, { id: "VLOR|2", text: "VD Orlík - Vltava", priority: true, coords: [49.6060, 14.1700], maxVolume: 716.5, minLevel: 330.00, maxLevel: 354.00, storageLevel: 349.9 }, - { id: "UHKA|2", text: "VD Kamýk - Vltava", coords: [49.6360, 14.2540], maxVolume: 12.8, minLevel: 283.0, maxLevel: 285.6, storageLevel: 285.6 }, { id: "VLSL|2", text: "VD Slapy - Vltava", priority: true, coords: [49.8220, 14.4360], maxVolume: 269.3, minLevel: 265.50, maxLevel: 271.10, storageLevel: 270.6 }, - { id: "VLST|2", text: "VD Štěchovice - Vltava", coords: [49.8450, 14.4120], maxVolume: 11.2, minLevel: 217.0, maxLevel: 219.5, storageLevel: 219.4 }, - { id: "VRSN|2", text: "VD Vrané - Vltava", coords: [49.9340, 14.3850], maxVolume: 11.1, minLevel: 198.5, maxLevel: 200.5, storageLevel: 200.5 }, - { id: "SVKR|2", text: "VD Švihov - Želivka", priority: true, coords: [49.7180, 15.1060], maxVolume: 266.6, minLevel: 343.0, maxLevel: 377.0, storageLevel: 377.0 }, + { id: "VLST|2", text: "VD Štěchovice - Vltava", priority: true, coords: [49.8450, 14.4120], maxVolume: 11.2, minLevel: 217.0, maxLevel: 219.5, storageLevel: 219.4 }, { id: "MARI|1", text: "VD Římov - Malše", priority: true, coords: [48.8470, 14.4870], maxVolume: 33.8, minLevel: 458.0, maxLevel: 471.0, storageLevel: 470.65 }, - { id: "MZHR|3", text: "VD Hracholusky - Mže", priority: true, coords: [49.7890, 13.1550], maxVolume: 56.7, minLevel: 360.0, maxLevel: 373.0, storageLevel: 354.1 } + { id: "MZHR|3", text: "VD Hracholusky - Mže", priority: true, coords: [49.7890, 13.1550], maxVolume: 56.7, minLevel: 350.5, maxLevel: 371.0, storageLevel: 369.5 } ]; diff --git a/src/App.tsx b/src/App.tsx index d166411..f1ea353 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -22,8 +22,12 @@ const LakeDetailWrapper = ({ language }: { language: Language }) => { }; function App() { - const [language, setLanguage] = useState('en'); - const [theme, setTheme] = useState<'dark' | 'light'>('dark'); + const [language, setLanguage] = useState(() => { + return (localStorage.getItem('hladinator_lang') as Language) || 'en'; + }); + const [theme, setTheme] = useState<'dark' | 'light'>(() => { + return (localStorage.getItem('hladinator_theme') as 'dark' | 'light') || 'dark'; + }); const [isSettingsOpen, setIsSettingsOpen] = useState(false); const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); @@ -33,6 +37,7 @@ function App() { } else { document.body.classList.remove('light-mode'); } + localStorage.setItem('hladinator_theme', theme); // Clean up empty hash from URL (e.g. if the user clicked an empty anchor) if (window.location.href.endsWith('#')) { @@ -40,6 +45,10 @@ function App() { } }, [theme]); + useEffect(() => { + localStorage.setItem('hladinator_lang', language); + }, [language]); + return (
{/* Mobile overlay */} diff --git a/src/components/LakeDetail.tsx b/src/components/LakeDetail.tsx index 3e00328..495b404 100644 --- a/src/components/LakeDetail.tsx +++ b/src/components/LakeDetail.tsx @@ -2,6 +2,9 @@ import { useState, useEffect } from 'react'; import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Line, ComposedChart, ReferenceLine, Bar } from 'recharts'; import { type Language, t } from '../translations'; import KpiCards from './KpiCards'; +import { WeatherWidget } from './WeatherWidget'; +import { NAVIGATION_LIMITS } from '../utils/navigationLimits'; +import { FiAlertCircle } from 'react-icons/fi'; interface LipnoData { timestamp: string; @@ -211,6 +214,8 @@ const LakeDetail = ({ language, lakeId }: Props) => { storageDiff: lakeInfo?.storageDiff }; + const limits = lakeInfo ? NAVIGATION_LIMITS[lakeInfo.id] : undefined; + return (
@@ -220,6 +225,31 @@ const LakeDetail = ({ language, lakeId }: Props) => { + {lakeInfo && lakeInfo.lat && lakeInfo.lng && ( + + )} + + {limits && limits.map((limit, idx) => { + const diff = latestData.level - limit.level; + if (diff < 1.0) { + const isBelow = diff < 0; + return ( +
+ +
+ {language === 'cs' ? limit.labelCs : limit.labelEn} ({limit.level.toFixed(2)} m n.m.): +
+ {isBelow + ? (language === 'cs' ? `Hladina je ${Math.abs(diff).toFixed(2)} m POD limitem! Přerušení provozu.` : `Level is ${Math.abs(diff).toFixed(2)} m BELOW limit! Operations suspended.`) + : (language === 'cs' ? `Hladina se blíží k limitu (zbývá ${diff.toFixed(2)} m).` : `Level is approaching limit (${diff.toFixed(2)} m remaining).`) + } +
+
+ ); + } + return null; + })} + {/* CHART SECTION */}
@@ -250,6 +280,9 @@ const LakeDetail = ({ language, lakeId }: Props) => { } /> {/* Data Series */} + {limits && limits.map((limit, idx) => ( + + ))} diff --git a/src/components/LakesOverview.tsx b/src/components/LakesOverview.tsx index e3812ce..6bff2bb 100644 --- a/src/components/LakesOverview.tsx +++ b/src/components/LakesOverview.tsx @@ -230,7 +230,7 @@ const LakesOverview = ({ language }: Props) => { {priorityLakes.length > 0 && (
-

Priority Reservoirs

+

{language === 'cs' ? 'Jezera a nádrže' : 'Lakes and Reservoirs'}

{
)} - -
-

Other Reservoirs ({otherLakes.length})

-
- {otherLakes.map(lake => ( - - ))} -
-
); }; diff --git a/src/components/WeatherWidget.tsx b/src/components/WeatherWidget.tsx new file mode 100644 index 0000000..e43bca3 --- /dev/null +++ b/src/components/WeatherWidget.tsx @@ -0,0 +1,143 @@ +import { useState, useEffect } from 'react'; +import { FiWind, FiSunrise, FiSunset, FiThermometer, FiAlertCircle } from 'react-icons/fi'; + +interface WeatherProps { + lat: number; + lng: number; + language: 'cs' | 'en'; + sensorTemp?: number; +} + +interface WeatherData { + temp: number; + windSpeed: number; // m/s + windGusts: number; // m/s + windDir: number; // degrees + sunrise: string; + sunset: string; +} + +const getCompassDirection = (degrees: number, language: 'cs' | 'en') => { + const directionsEn = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW']; + const directionsCs = ['S', 'SV', 'V', 'JV', 'J', 'JZ', 'Z', 'SZ']; + const directions = language === 'cs' ? directionsCs : directionsEn; + const index = Math.round(((degrees %= 360) < 0 ? degrees + 360 : degrees) / 45) % 8; + return directions[index]; +}; + +const formatTime = (isoString: string) => { + if (!isoString) return '--:--'; + const date = new Date(isoString); + return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); +}; + +export const WeatherWidget = ({ lat, lng, language, sensorTemp }: WeatherProps) => { + const [data, setData] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(false); + + useEffect(() => { + if (!lat || !lng) { + setLoading(false); + setError(true); + return; + } + + const fetchWeather = async () => { + try { + setLoading(true); + const res = await fetch(`https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lng}¤t=temperature_2m,wind_speed_10m,wind_direction_10m,wind_gusts_10m&daily=sunrise,sunset&timezone=auto&wind_speed_unit=ms`); + if (!res.ok) throw new Error('Failed to fetch weather'); + + const json = await res.json(); + setData({ + temp: json.current.temperature_2m, + windSpeed: json.current.wind_speed_10m, + windGusts: json.current.wind_gusts_10m, + windDir: json.current.wind_direction_10m, + sunrise: json.daily.sunrise[0], + sunset: json.daily.sunset[0] + }); + setError(false); + } catch (err) { + console.error('Weather fetch error:', err); + setError(true); + } finally { + setLoading(false); + } + }; + + fetchWeather(); + + // Refresh weather every 15 minutes + const interval = setInterval(fetchWeather, 15 * 60 * 1000); + return () => clearInterval(interval); + }, [lat, lng]); + + const dict = { + cs: { title: 'Počasí a Vítr (Aktuálně)', error: 'Data nedostupná', wind: 'Vítr', gusts: 'Nárazy', temp: 'Teplota' }, + en: { title: 'Weather & Wind (Current)', error: 'Data unavailable', wind: 'Wind', gusts: 'Gusts', temp: 'Temp' } + }[language]; + + if (loading) { + return
Loading weather...
; + } + + if (error || !data) { + return ( +
+

{dict.title}

+
+ {dict.error} +
+
+ ); + } + + return ( +
+

{dict.title}

+ +
+ + {/* Left Column: Wind */} +
+
+ {/* Assume icon points UP by default, wind from south (180) should point UP. Arrow should point where wind is GOING. */} +
+ +
+
+ {data.windSpeed.toFixed(1)} m/s +
+
+ {getCompassDirection(data.windDir, language)} • {dict.gusts}: 10 ? 'var(--color-red)' : 'var(--text-main)' }}>{data.windGusts.toFixed(1)} m/s +
+
+
+ + {/* Right Column: Other Info */} +
+
+ + {sensorTemp !== undefined ? sensorTemp.toFixed(1) : data.temp.toFixed(1)} °C +
+
+ + {formatTime(data.sunrise)} +
+
+ + {formatTime(data.sunset)} +
+
+ +
+
+ ); +}; diff --git a/src/utils/navigationLimits.ts b/src/utils/navigationLimits.ts new file mode 100644 index 0000000..0caabdd --- /dev/null +++ b/src/utils/navigationLimits.ts @@ -0,0 +1,27 @@ +export interface NavigationLimit { + level: number; + labelCs: string; + labelEn: string; + type: 'danger' | 'warning'; +} + +export const NAVIGATION_LIMITS: Record = { + // Orlík + 'VLOR|1': [ + { + level: 342.50, + labelCs: 'Minimální hladina pro lodní výtah Orlík', + labelEn: 'Minimum level for Orlík boat lift', + type: 'danger' + } + ], + // Slapy + 'VLSL|1': [ + { + level: 266.50, + labelCs: 'Minimální hladina pro převoz lodí Slapy', + labelEn: 'Minimum level for Slapy boat transport', + type: 'danger' + } + ] +};