diff --git a/.beads/.gitignore b/.beads/.gitignore new file mode 100644 index 0000000..df4911d --- /dev/null +++ b/.beads/.gitignore @@ -0,0 +1,73 @@ +# Dolt database (managed by Dolt, not git) +dolt/ +embeddeddolt/ + +# Runtime files +bd.sock +bd.sock.startlock +sync-state.json +last-touched +.exclusive-lock + +# Daemon runtime (lock, log, pid) +daemon.* + +# Interactions log (runtime, not versioned) +interactions.jsonl + +# Push state (runtime, per-machine) +push-state.json + +# Lock files (various runtime locks) +*.lock + +# Credential key (encryption key for federation peer auth — never commit) +.beads-credential-key + +# Local version tracking (prevents upgrade notification spam after git ops) +.local_version + +# Worktree redirect file (contains relative path to main repo's .beads/) +# Must not be committed as paths would be wrong in other clones +redirect + +# Sync state (local-only, per-machine) +# These files are machine-specific and should not be shared across clones +.sync.lock +export-state/ +export-state.json + +# Ephemeral store (SQLite - wisps/molecules, intentionally not versioned) +ephemeral.sqlite3 +ephemeral.sqlite3-journal +ephemeral.sqlite3-wal +ephemeral.sqlite3-shm + +# Dolt server management (auto-started by bd) +dolt-server.pid +dolt-server.log +dolt-server.lock +dolt-server.port +dolt-server.activity + +# Corrupt backup directories (created by bd doctor --fix recovery) +*.corrupt.backup/ + +# Backup data (auto-exported JSONL, local-only) +backup/ + +# Per-project environment file (Dolt connection config, GH#2520) +.env + +# Legacy files (from pre-Dolt versions) +*.db +*.db?* +*.db-journal +*.db-wal +*.db-shm +db.sqlite +bd.db +# NOTE: Do NOT add negation patterns here. +# They would override fork protection in .git/info/exclude. +# Config files (metadata.json, config.yaml) are tracked by git by default +# since no pattern above ignores them. diff --git a/.beads/README.md b/.beads/README.md new file mode 100644 index 0000000..dbfe363 --- /dev/null +++ b/.beads/README.md @@ -0,0 +1,81 @@ +# Beads - AI-Native Issue Tracking + +Welcome to Beads! This repository uses **Beads** for issue tracking - a modern, AI-native tool designed to live directly in your codebase alongside your code. + +## What is Beads? + +Beads is issue tracking that lives in your repo, making it perfect for AI coding agents and developers who want their issues close to their code. No web UI required - everything works through the CLI and integrates seamlessly with git. + +**Learn more:** [github.com/steveyegge/beads](https://github.com/steveyegge/beads) + +## Quick Start + +### Essential Commands + +```bash +# Create new issues +bd create "Add user authentication" + +# View all issues +bd list + +# View issue details +bd show + +# Update issue status +bd update --claim +bd update --status done + +# Sync with Dolt remote +bd dolt push +``` + +### Working with Issues + +Issues in Beads are: +- **Git-native**: Stored in Dolt database with version control and branching +- **AI-friendly**: CLI-first design works perfectly with AI coding agents +- **Branch-aware**: Issues can follow your branch workflow +- **Always in sync**: Auto-syncs with your commits + +## Why Beads? + +✨ **AI-Native Design** +- Built specifically for AI-assisted development workflows +- CLI-first interface works seamlessly with AI coding agents +- No context switching to web UIs + +🚀 **Developer Focused** +- Issues live in your repo, right next to your code +- Works offline, syncs when you push +- Fast, lightweight, and stays out of your way + +🔧 **Git Integration** +- Automatic sync with git commits +- Branch-aware issue tracking +- Dolt-native three-way merge resolution + +## Get Started with Beads + +Try Beads in your own projects: + +```bash +# Install Beads +curl -sSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash + +# Initialize in your repo +bd init + +# Create your first issue +bd create "Try out Beads" +``` + +## Learn More + +- **Documentation**: [github.com/steveyegge/beads/docs](https://github.com/steveyegge/beads/tree/main/docs) +- **Quick Start Guide**: Run `bd quickstart` +- **Examples**: [github.com/steveyegge/beads/examples](https://github.com/steveyegge/beads/tree/main/examples) + +--- + +*Beads: Issue tracking that moves at the speed of thought* ⚡ diff --git a/.beads/config.yaml b/.beads/config.yaml new file mode 100644 index 0000000..d337552 --- /dev/null +++ b/.beads/config.yaml @@ -0,0 +1,56 @@ +# Beads Configuration File +# This file configures default behavior for all bd commands in this repository +# All settings can also be set via environment variables (BD_* prefix) +# or overridden with command-line flags + +# Issue prefix for this repository (used by bd init) +# If not set, bd init will auto-detect from directory name +# Example: issue-prefix: "myproject" creates issues like "myproject-1", "myproject-2", etc. +# issue-prefix: "" + +# Use no-db mode: JSONL-only, no Dolt database +# When true, bd will use .beads/issues.jsonl as the source of truth +# no-db: false + +# Enable JSON output by default +# json: false + +# Feedback title formatting for mutating commands (create/update/close/dep/edit) +# 0 = hide titles, N > 0 = truncate to N characters +# output: +# title-length: 255 + +# Default actor for audit trails (overridden by BEADS_ACTOR or --actor) +# actor: "" + +# Export events (audit trail) to .beads/events.jsonl on each flush/sync +# When enabled, new events are appended incrementally using a high-water mark. +# Use 'bd export --events' to trigger manually regardless of this setting. +# events-export: false + +# Multi-repo configuration (experimental - bd-307) +# Allows hydrating from multiple repositories and routing writes to the correct database +# repos: +# primary: "." # Primary repo (where this database lives) +# additional: # Additional repos to hydrate from (read-only) +# - ~/beads-planning # Personal planning repo +# - ~/work-planning # Work planning repo + +# JSONL backup (periodic export for off-machine recovery) +# Auto-enabled when a git remote exists. Override explicitly: +# backup: +# enabled: false # Disable auto-backup entirely +# interval: 15m # Minimum time between auto-exports +# git-push: false # Disable git push (export locally only) +# git-repo: "" # Separate git repo for backups (default: project repo) + +# Integration settings (access with 'bd config get/set') +# These are stored in the database, not in this file: +# - jira.url +# - jira.project +# - linear.url +# - linear.api-key +# - github.org +# - github.repo + +sync.remote: "git+ssh://git@kode.naiv.no:2222/olemd/tilfluktsrom.git" \ No newline at end of file diff --git a/.beads/hooks/post-checkout b/.beads/hooks/post-checkout new file mode 100755 index 0000000..8740e4f --- /dev/null +++ b/.beads/hooks/post-checkout @@ -0,0 +1,24 @@ +#!/usr/bin/env sh +# --- BEGIN BEADS INTEGRATION v1.0.2 --- +# This section is managed by beads. Do not remove these markers. +if command -v bd >/dev/null 2>&1; then + export BD_GIT_HOOK=1 + _bd_timeout=${BEADS_HOOK_TIMEOUT:-300} + if command -v timeout >/dev/null 2>&1; then + timeout "$_bd_timeout" bd hooks run post-checkout "$@" + _bd_exit=$? + if [ $_bd_exit -eq 124 ]; then + echo >&2 "beads: hook 'post-checkout' timed out after ${_bd_timeout}s — continuing without beads" + _bd_exit=0 + fi + else + bd hooks run post-checkout "$@" + _bd_exit=$? + fi + if [ $_bd_exit -eq 3 ]; then + echo >&2 "beads: database not initialized — skipping hook 'post-checkout'" + _bd_exit=0 + fi + if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi +fi +# --- END BEADS INTEGRATION v1.0.2 --- diff --git a/.beads/hooks/post-merge b/.beads/hooks/post-merge new file mode 100755 index 0000000..79487b2 --- /dev/null +++ b/.beads/hooks/post-merge @@ -0,0 +1,24 @@ +#!/usr/bin/env sh +# --- BEGIN BEADS INTEGRATION v1.0.2 --- +# This section is managed by beads. Do not remove these markers. +if command -v bd >/dev/null 2>&1; then + export BD_GIT_HOOK=1 + _bd_timeout=${BEADS_HOOK_TIMEOUT:-300} + if command -v timeout >/dev/null 2>&1; then + timeout "$_bd_timeout" bd hooks run post-merge "$@" + _bd_exit=$? + if [ $_bd_exit -eq 124 ]; then + echo >&2 "beads: hook 'post-merge' timed out after ${_bd_timeout}s — continuing without beads" + _bd_exit=0 + fi + else + bd hooks run post-merge "$@" + _bd_exit=$? + fi + if [ $_bd_exit -eq 3 ]; then + echo >&2 "beads: database not initialized — skipping hook 'post-merge'" + _bd_exit=0 + fi + if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi +fi +# --- END BEADS INTEGRATION v1.0.2 --- diff --git a/.beads/hooks/pre-commit b/.beads/hooks/pre-commit new file mode 100755 index 0000000..bae3803 --- /dev/null +++ b/.beads/hooks/pre-commit @@ -0,0 +1,24 @@ +#!/usr/bin/env sh +# --- BEGIN BEADS INTEGRATION v1.0.2 --- +# This section is managed by beads. Do not remove these markers. +if command -v bd >/dev/null 2>&1; then + export BD_GIT_HOOK=1 + _bd_timeout=${BEADS_HOOK_TIMEOUT:-300} + if command -v timeout >/dev/null 2>&1; then + timeout "$_bd_timeout" bd hooks run pre-commit "$@" + _bd_exit=$? + if [ $_bd_exit -eq 124 ]; then + echo >&2 "beads: hook 'pre-commit' timed out after ${_bd_timeout}s — continuing without beads" + _bd_exit=0 + fi + else + bd hooks run pre-commit "$@" + _bd_exit=$? + fi + if [ $_bd_exit -eq 3 ]; then + echo >&2 "beads: database not initialized — skipping hook 'pre-commit'" + _bd_exit=0 + fi + if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi +fi +# --- END BEADS INTEGRATION v1.0.2 --- diff --git a/.beads/hooks/pre-push b/.beads/hooks/pre-push new file mode 100755 index 0000000..490f66e --- /dev/null +++ b/.beads/hooks/pre-push @@ -0,0 +1,24 @@ +#!/usr/bin/env sh +# --- BEGIN BEADS INTEGRATION v1.0.2 --- +# This section is managed by beads. Do not remove these markers. +if command -v bd >/dev/null 2>&1; then + export BD_GIT_HOOK=1 + _bd_timeout=${BEADS_HOOK_TIMEOUT:-300} + if command -v timeout >/dev/null 2>&1; then + timeout "$_bd_timeout" bd hooks run pre-push "$@" + _bd_exit=$? + if [ $_bd_exit -eq 124 ]; then + echo >&2 "beads: hook 'pre-push' timed out after ${_bd_timeout}s — continuing without beads" + _bd_exit=0 + fi + else + bd hooks run pre-push "$@" + _bd_exit=$? + fi + if [ $_bd_exit -eq 3 ]; then + echo >&2 "beads: database not initialized — skipping hook 'pre-push'" + _bd_exit=0 + fi + if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi +fi +# --- END BEADS INTEGRATION v1.0.2 --- diff --git a/.beads/hooks/prepare-commit-msg b/.beads/hooks/prepare-commit-msg new file mode 100755 index 0000000..e10a4fe --- /dev/null +++ b/.beads/hooks/prepare-commit-msg @@ -0,0 +1,24 @@ +#!/usr/bin/env sh +# --- BEGIN BEADS INTEGRATION v1.0.2 --- +# This section is managed by beads. Do not remove these markers. +if command -v bd >/dev/null 2>&1; then + export BD_GIT_HOOK=1 + _bd_timeout=${BEADS_HOOK_TIMEOUT:-300} + if command -v timeout >/dev/null 2>&1; then + timeout "$_bd_timeout" bd hooks run prepare-commit-msg "$@" + _bd_exit=$? + if [ $_bd_exit -eq 124 ]; then + echo >&2 "beads: hook 'prepare-commit-msg' timed out after ${_bd_timeout}s — continuing without beads" + _bd_exit=0 + fi + else + bd hooks run prepare-commit-msg "$@" + _bd_exit=$? + fi + if [ $_bd_exit -eq 3 ]; then + echo >&2 "beads: database not initialized — skipping hook 'prepare-commit-msg'" + _bd_exit=0 + fi + if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi +fi +# --- END BEADS INTEGRATION v1.0.2 --- diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl new file mode 100644 index 0000000..08c5ca9 --- /dev/null +++ b/.beads/issues.jsonl @@ -0,0 +1,14 @@ +{"id":"tilfluktsrom-7zc","title":"Badge-kontrast under WCAG 2.2 AA — bytt shelter_primary til warning_bg","description":"Mirror av Forgejo-issue #18.\n\nBadge introdusert i 1fb9f14 (#13) bruker hvit fet 11sp tekst på shelter_primary (#FF6B35). Målt kontrast: ~2.84:1.\n\nWCAG 2.2 AA SC 1.4.3:\n- Normaltekst: ≥4.5:1\n- Large text (≥14pt fet eller ≥18pt regular): ≥3.0:1\n\n11sp fet teller som normaltekst → feiler AA-terskelen, og marginalt også 3:1 for large text.\n\nFiks: én linje i app/src/main/res/layout/item_shelter.xml — bytt @color/shelter_primary til @color/warning_bg (#BF360C, dokumentert ~5.5:1 vs hvit i colors.xml-kommentar).\n\nAlternativer som ikke fungerer:\n- shelter_primary_dark (#E55A2B) ~3.6:1 — fortsatt under AA normaltekst\n- Svart tekst på orange — ~7:1, men bryter visuell konsistens\n\nRelevant for offentlig-sektor-godkjenning (Uutilsynet/WAD/EN 301 549).\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/18","acceptance_criteria":"Badge-bakgrunnen på item_shelter.xml outsideNearestBadge er endret til warning_bg. Visuelt verifisert at hvit fet 11sp tekst på den nye bakgrunnen gir ≥4.5:1 målt kontrast (med en kontrast-sjekker eller WCAG-verktøy).","status":"closed","priority":2,"issue_type":"bug","assignee":"Ole-Morten Duesund","owner":"olemd@glemt.net","created_at":"2026-04-29T14:54:00Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-29T14:55:09Z","started_at":"2026-04-29T14:54:56Z","closed_at":"2026-04-29T14:55:09Z","close_reason":"Bytta @color/shelter_primary til @color/warning_bg på outsideNearestBadge i item_shelter.xml. Kontrast: ~2.84:1 → ~5.6:1 (over WCAG 2.2 AA SC 1.4.3 4.5:1-terskel). Visuell verifisering på enhet/emulator gjenstår.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"id":"tilfluktsrom-efo","title":"PWA: dyplenket tilfluktsrom utenfor topp-N vises som om det er nærmest","description":"Mirror av Forgejo-issue #17.\n\nParallell til Android-fiksen i 1fb9f14 (#13).\n\nNåværende oppførsel: når dyplenken peker på et tilfluktsrom utenfor de N nærmeste, gjør pwa/src/app.ts:266-285 unshift() inn på indeks 0 og setter selectedShelterIndex=0. Resultat: det dyplenkede vises *som om* det er det nærmeste — uten badge, uten separator, uten forklaring. Lista bryter sin egen sort-på-avstand-invariant.\n\nHybrid-fiks (parallell til Android):\n1. Append (push) i stedet for unshift på app.ts:274\n2. Badge i shelter-list.ts på den appendede raden — bruk samme nøkkel shelter_outside_nearest_badge i pwa/src/i18n/{en,nb,nn}.ts\n3. updateList() får outsideNearestRomnr-parameter (eller wrap-objekt parallelt med Android sin ShelterListItem)\n4. Badge-teksten suffikses i aria-label (skjermleser-paritet med Android)\n5. selectedItem.scrollIntoView({block:'nearest', behavior:'smooth'}) etter updateList\n6. Tilgjengelighet: badge ≥4.5:1 kontrast (WCAG 2.2 AA SC 1.4.3). #FF6B35+hvit tekst er ~3.5:1 — *under terskel*. Bruk shelter_primary_dark #E55A2B som badge-bakgrunn, eller svart tekst på orange (~7:1)\n\nUt av skopet: endring av selve dyplenke-formatet (fortsatt /shelter/{romnr}), klyngevisning (#10).\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/17","acceptance_criteria":"Dyplenket tilfluktsrom utenfor topp-N appendes på siste rad i lista (ikke unshift). Den appendede raden har et synlig 'Valgt – utenfor nærområdet'-badge med ≥4.5:1 kontrast. Lista scroller automatisk til valgt rad. Skjermleser leser badge-teksten som del av aria-label. Verifisert manuelt med en deep-link til et tilfluktsrom langt fra brukerens posisjon.","status":"open","priority":2,"issue_type":"bug","owner":"olemd@glemt.net","created_at":"2026-04-29T14:52:08Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-29T14:52:08Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"id":"tilfluktsrom-5vc","title":"Brukerens retningspil i kartet er hvit og forsvinner på lyse underlag","description":"Mirror av Forgejo-issue #16.\n\nNår brukeren beveger seg raskt nok til at OSMDroid bytter fra person- til retningspil-ikonet i MyLocationNewOverlay, blir pilen tilnærmet usynlig: heltrukken hvit uten kontur eller skygge. På lyse tiles (snø, sand, brede veifyll, lyse OSM-temaer) forsvinner den helt.\n\nÅrsak: MainActivity.kt:190 instansierer MyLocationNewOverlay uten å overstyre setDirectionIcon()/setPersonIcon() — OSMDroid bruker da stock hvite bitmaps.\n\nForslag:\n- Egen vector i res/drawable/ic_user_direction.xml med kontrastfarget fyll + motsatt-farge kontur\n- Kall myLocationOverlay.setDirectionIcon(...) + setPersonIcon(...) eksplisitt\n- Vurder halo-ring (blå pil i hvit ring, Google Maps-stil) for variert underlag\n- Sjekk PWA-en (Leaflet) for samme problem\n\nTilgjengelighet:\n- ≥3:1 kontrast mot både lyse og mørke tiles (WCAG 2.2 AA, ikke-tekstlig innhold)\n- Ikke avhengig av farge alene; konturen sikrer at formen faktisk synes\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/16","acceptance_criteria":"Pilen og person-ikonet i MyLocationNewOverlay er tydelig synlig mot både lyse og mørke kartunderlag (≥3:1 kontrast). Verifisert manuelt på minst ett lyst og ett mørkt kartområde, både stillestående (person) og i bevegelse (pil).","status":"closed","priority":2,"issue_type":"bug","assignee":"Ole-Morten Duesund","owner":"olemd@glemt.net","created_at":"2026-04-29T14:06:57Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-29T14:15:13Z","started_at":"2026-04-29T14:09:43Z","closed_at":"2026-04-29T14:15:13Z","close_reason":"Fikset i d2291a2 — egne ikoner i res/drawable/ic_user_dot.xml og ic_user_arrow.xml, satt på MyLocationNewOverlay med setPersonIcon/setDirectionIcon + (0.5, 0.5)-anker. Visuell verifisering på enhet/emulator gjenstår.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"id":"tilfluktsrom-5s7","title":"PWA: manuell testing mangler","description":"Mirror av Forgejo-issue #1.\n\nPWA-versjonen (pwa/) er skrevet, men ikke manuelt testet i nettleser. Enhetstestene passerer, men appen må verifiseres i praksis:\n\n- Start utviklingsserver og test i Chrome/Firefox\n- Test offline-modus (service worker)\n- Test kompass (iOS Safari + Android Chrome)\n- Test installasjon via «Legg til på startskjerm»\n- Test kartbufring og offline kartvisning\n- Test på fysisk iPhone (iOS-spesifikk kompasshåndtering)\n- Test i18n (norsk bokmål, nynorsk, engelsk)\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/1","status":"closed","priority":2,"issue_type":"task","owner":"olemd@glemt.net","created_at":"2026-04-29T13:57:04Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-29T14:02:57Z","closed_at":"2026-04-29T14:02:57Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"id":"tilfluktsrom-nt8","title":"Åpne i kartapp for gangvei til tilfluktsrom","description":"Mirror av Forgejo-issue #2.\n\nLegg til knapp (på bunnark og/eller kompassvisning) som åpner gangveibeskrivelse til valgt tilfluktsrom i ekstern kartapp.\n\nImplementasjon:\n- ACTION_VIEW intent med geo: URI: geo:lat,lon?q=lat,lon(Tilfluktsrom - adresse)\n- geo: håndteres av tilgjengelig kartapp (OsmAnd, Organic Maps, Google Maps, ...)\n- OsmAnd og Organic Maps støtter offline-navigasjon med geo: — ideelt for degradert nett\n- IKKE hardkode Google Maps-URL-er — bruk geo:\n- Faller pent tilbake hvis ingen kartapp er installert (Toast med koordinater å kopiere)\n- Knapp ved siden av tilfluktsrom-adresse i bunnarket\n\nI en akuttsituasjon er det å finne tilfluktsrommet på kartet bare halve problemet — du må vite gangveien dit. geo:-intent fungerer med offline-kapable kartapper, kritisk når nettet er nede.\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/2","status":"open","priority":2,"issue_type":"feature","owner":"olemd@glemt.net","created_at":"2026-04-29T13:57:03Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-29T13:57:03Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"id":"tilfluktsrom-gmu","title":"Test og ferdigstill PWA-versjonen","description":"Mirror av Forgejo-issue #7.\n\nFå den eksisterende PWA-en i pwa/-katalogen til å fungere og testet som webfallback.\n\nStatus:\n- Vite + TypeScript + Leaflet + idb + vite-plugin-pwa\n- Shelter-data forhåndsprosesseres ved bygg (scripts/fetch-shelters.ts)\n- Markert som ikke-testet i README (issue #1)\n\nOppgaver:\n- bun install + bun run dev — fikse byggefeil\n- Verifiser at bun run fetch-shelters genererer public/data/shelters.json\n- Test offline (service worker)\n- Test på mobilnettleser (iOS Safari, Android Chrome)\n- Deploy til statisk hosting\n- Lenke til PWA fra Android-appens om-side eller README\n\nWebfallback for iOS-brukere og folk uten Android-app. Også raskest tilgang i en akuttsituasjon.\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/7","status":"closed","priority":2,"issue_type":"task","owner":"olemd@glemt.net","created_at":"2026-04-29T13:56:46Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-29T14:02:57Z","closed_at":"2026-04-29T14:02:57Z","close_reason":"Closed","dependency_count":0,"dependent_count":1,"comment_count":0} +{"id":"tilfluktsrom-9sf","title":"Dyplenket tilfluktsrom utenfor lista vises ikke","description":"Mirror av Forgejo-issue #13.\n\nNår en dyplenke åpner et tilfluktsrom som ikke er blant de 3 nærmeste, blir det valgt i kartet, men vises ikke i lista i bunnpanelet. Brukeren ser ikke hva som er valgt.\n\nForslag:\n1. Legg til det dyplenkede tilfluktsrommet som ekstra element i lista (med markering om at det ikke er blant de 3 nærmeste), eller\n2. Rull lista slik at det valgte elementet er synlig.\n\nIdentifisert i bruksanalyse. Moderat prioritet.\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/13","status":"closed","priority":2,"issue_type":"bug","assignee":"Ole-Morten Duesund","owner":"olemd@glemt.net","created_at":"2026-04-29T13:56:15Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-29T14:49:15Z","started_at":"2026-04-29T14:46:18Z","closed_at":"2026-04-29T14:49:15Z","close_reason":"Hybrid implementert: ShelterListItem-wrapper med isOutsideNearest-flagg, badge i item_shelter.xml, smoothScrollToPosition på rebuildShelterList. Visuell verifisering på enhet/emulator gjenstår.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"id":"tilfluktsrom-jmv","title":"Geonorge: lokalId regenereres på hver eksport — bytt til romnr som ekstern nøkkel","description":"Mirror av Forgejo-issue #15.\n\nTilfluktsromdata fra Geonorge regenererer lokalId-feltet ved hver eksport (verifisert: alle 556 lokalId-er endres mellom snapshots, mens romnr/plasser/adresse/koordinater er stabile).\n\nKonsekvens: delingslenker basert på lokalId ble brutt mellom datasett-oppdateringer. Vi har allerede byttet ekstern delingsidentifikator til romnr og beholdt lokalId som intern Room-PK.\n\nGjenstår:\n- Spørre Geonorge/DSB hvorfor lokalId regenereres (tilsiktet gml:id-stil eller FME/SOSI-feil?)\n- Hvis feil: be om at lokalId persisteres mellom eksporter\n- Hvis tilsiktet: be om dokumentasjon\n- Sjekke om WFS-endepunktet returnerer stabile ID-er\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/15","status":"deferred","priority":2,"issue_type":"task","owner":"olemd@glemt.net","created_at":"2026-04-29T13:55:59Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-30T11:16:26Z","defer_until":"2026-10-30T00:00:00Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"id":"tilfluktsrom-jvn","title":"Filtrere tilfluktsrom etter minimumskapasitet","description":"Mirror av Forgejo-issue #5.\n\nLegg til filter for minimumskapasitet slik at brukere kan finne tilfluktsrom store nok for gruppen sin.\n\nImplementasjon:\n- Filterchip eller dropdown over tilfluktsromlista (f.eks. \"Min. plasser: 50 / 100 / 200 / Alle\")\n- Filteret gjelder både nærmeste-lista og kartmarkørene\n- Lagre valg i SharedPreferences\n- Default: vis alle (intet filter)\n\nSkoler, arbeidsplasser og familier trenger tilfluktsrom med nok kapasitet. Et lite tilfluktsrom med 20 plasser er ubrukelig for en gruppe på 50. Enkel UX-forbedring med reell praktisk verdi.\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/5","status":"open","priority":3,"issue_type":"feature","owner":"olemd@glemt.net","created_at":"2026-04-29T13:56:51Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-29T13:56:51Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"id":"tilfluktsrom-nyz","title":"Støtte for internasjonale tilfluktsromdata","description":"Mirror av Forgejo-issue #9.\n\nI dag støtter Tilfluktsrom kun norske data fra Geonorge (GeoJSON, EPSG:25833). Mål: identifisere og integrere data fra andre land.\n\nMål:\n1. Identifisere internasjonale datakilder (NO, SE/MSB, FI/Pelastustoimi, CH/FOCP, SG/SCDF, US/FEMA)\n2. Støtte flere dataformater uten å bryte eksisterende funksjonalitet\n3. Auto-nedlasting basert på brukerens posisjon\n\nTekniske vurderinger:\n- ShelterDataSource-grensesnitt med per-land-implementasjoner\n- Parsefeil i én kilde må aldri ødelegge andre kilder (isolert per kilde, valider per record)\n- Generalisere Shelter-modellen (kjernefelt: koordinater WGS84, kapasitet, adresse, kildeland)\n- Bbox-basert dataset-registry, last bare ned relevante datasett\n- Offline-first beholdes — alle nedlastede datasett caches i Room\n\nOut of scope: brukerbidratte lokasjoner, sanntidsstatus, ruting.\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/9 (3 kommentarer)","status":"open","priority":3,"issue_type":"feature","owner":"olemd@glemt.net","created_at":"2026-04-29T13:56:34Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-29T13:56:34Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"id":"tilfluktsrom-bnw","title":"Klyngevisning for kartmarkører","description":"Mirror av Forgejo-issue #10.\n\nNår mange tilfluktsrom ligger tett i kartet, overlapper markørene og det er vanskelig å trykke på riktig en.\n\nForslag: legg til klyngevisning (marker clustering) som grupperer nærliggende markører og viser et tall. Når brukeren zoomer inn, splittes klyngene.\n\nAlternativer:\n- Android: OSMBonusPack MarkerClusterer, eller egen logikk\n- PWA: Leaflet.markercluster-plugin\n\nLavere prioritet enn tilgjengelighetsforbedringer.\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/10","status":"open","priority":3,"issue_type":"feature","owner":"olemd@glemt.net","created_at":"2026-04-29T13:56:23Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-29T13:56:23Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"id":"tilfluktsrom-k5i","title":"PWA: legg til sivilforsvarsinformasjons-dialog","description":"Mirror av Forgejo-issue #12.\n\nPWA-versjonen mangler sivilforsvarsinformasjonsdialogen som finnes i Android-appen (CivilDefenseInfoDialog).\n\nPort dialogen til PWA-en med samme innhold (5 steg + DSB-kilde). Vis som modal/overlay.\n\nAvhengighet: bør gjøres etter #7 (test og ferdigstill PWA).\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/12","status":"open","priority":3,"issue_type":"feature","owner":"olemd@glemt.net","created_at":"2026-04-29T13:56:19Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-29T13:56:19Z","dependencies":[{"issue_id":"tilfluktsrom-k5i","depends_on_id":"tilfluktsrom-gmu","type":"blocks","created_at":"2026-04-29T16:01:22Z","created_by":"Ole-Morten Duesund","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} +{"id":"tilfluktsrom-52s","title":"Migrere UI fra Views/ViewBinding til Jetpack Compose","description":"Mirror av Forgejo-issue #14.\n\nMigrere fra tradisjonelle Android Views med ViewBinding til Jetpack Compose.\n\nOmfang:\n- activity_main.xml → rot-Composable med tilstandsheving\n- RecyclerView + ShelterListAdapter → LazyColumn\n- DirectionArrowView (Canvas) → Compose Canvas\n- Bunnark → Card / BottomSheetScaffold\n- dialog_civil_defense.xml → AlertDialog composable\n- Lasteoverlegg → AnimatedVisibility\n- Innfør MainViewModel\n\nForblir Views: OSMDroid MapView (pakkes i AndroidView), Widget (RemoteViews, eventuell Glance-migrering er separat).\n\nVurderinger:\n- APK +2-3 MB (Compose runtime)\n- @Preview gir bedre dev-loop for ikke-kart-komponenter\n- Stort tiltak — ikke kritisk\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/14","status":"open","priority":3,"issue_type":"feature","owner":"olemd@glemt.net","created_at":"2026-04-29T13:56:10Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-29T13:56:10Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"id":"tilfluktsrom-bok","title":"Forberede F-Droid-metadata for innsending","description":"Mirror av Forgejo-issue #8.\n\nNB: F-Droid-distribusjon er pauset (jf. memory feedback_fdroid_paused.md). Skal IKKE jobbes på før brukeren gjenopptar F-Droid-spor.\n\nForberede repoet for F-Droid-innsending med fastlane metadata-struktur:\n- fastlane/metadata/android/-katalog\n- en-US/ og nb-NO/ med full_description, short_description, title, changelogs/\n- images/ med skjermbilder og feature graphic\n- Dokumenter at appen bruker play-services-location men faller tilbake (anti-features)\n- Vurdere .fdroid.yml hvis spesielle byggesteg trengs\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/8 (1 kommentar)","status":"open","priority":4,"issue_type":"task","owner":"olemd@glemt.net","created_at":"2026-04-29T13:56:40Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-29T13:56:40Z","dependency_count":0,"dependent_count":0,"comment_count":0} diff --git a/.beads/metadata.json b/.beads/metadata.json new file mode 100644 index 0000000..fbf8384 --- /dev/null +++ b/.beads/metadata.json @@ -0,0 +1,7 @@ +{ + "database": "dolt", + "backend": "dolt", + "dolt_mode": "embedded", + "dolt_database": "tilfluktsrom", + "project_id": "49020f4c-0353-4536-a242-39a3dc116f11" +} \ No newline at end of file diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..963a538 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,26 @@ +{ + "hooks": { + "PreCompact": [ + { + "hooks": [ + { + "command": "bd prime", + "type": "command" + } + ], + "matcher": "" + } + ], + "SessionStart": [ + { + "hooks": [ + { + "command": "bd prime", + "type": "command" + } + ], + "matcher": "" + } + ] + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index f827122..cb8447b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,8 @@ local.properties /app/build keystore.properties + +# Beads / Dolt files (added by bd init) +.dolt/ +*.db +.beads-credential-key diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..9390d72 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,84 @@ +# Agent Instructions + +This project uses **bd** (beads) for issue tracking. Run `bd prime` for full workflow context. + +## Quick Reference + +```bash +bd ready # Find available work +bd show # View issue details +bd update --claim # Claim work atomically +bd close # Complete work +bd dolt push # Push beads data to remote +``` + +## Non-Interactive Shell Commands + +**ALWAYS use non-interactive flags** with file operations to avoid hanging on confirmation prompts. + +Shell commands like `cp`, `mv`, and `rm` may be aliased to include `-i` (interactive) mode on some systems, causing the agent to hang indefinitely waiting for y/n input. + +**Use these forms instead:** +```bash +# Force overwrite without prompting +cp -f source dest # NOT: cp source dest +mv -f source dest # NOT: mv source dest +rm -f file # NOT: rm file + +# For recursive operations +rm -rf directory # NOT: rm -r directory +cp -rf source dest # NOT: cp -r source dest +``` + +**Other commands that may prompt:** +- `scp` - use `-o BatchMode=yes` for non-interactive +- `ssh` - use `-o BatchMode=yes` to fail instead of prompting +- `apt-get` - use `-y` flag +- `brew` - use `HOMEBREW_NO_AUTO_UPDATE=1` env var + + +## Beads Issue Tracker + +This project uses **bd (beads)** for issue tracking. Run `bd prime` to see full workflow context and commands. + +### Quick Reference + +```bash +bd ready # Find available work +bd show # View issue details +bd update --claim # Claim work +bd close # Complete work +``` + +### Rules + +- Use `bd` for ALL task tracking — do NOT use TodoWrite, TaskCreate, or markdown TODO lists +- Run `bd prime` for detailed command reference and session close protocol +- Use `bd remember` for persistent knowledge — do NOT use MEMORY.md files + +## Session Completion + +**When ending a work session**, you MUST complete ALL steps below. Work is NOT complete until `git push` succeeds. + +**MANDATORY WORKFLOW:** + +1. **File issues for remaining work** - Create issues for anything that needs follow-up +2. **Run quality gates** (if code changed) - Tests, linters, builds +3. **Update issue status** - Close finished work, update in-progress items +4. **PUSH TO REMOTE** - This is MANDATORY: + ```bash + git pull --rebase + bd dolt push + git push + git status # MUST show "up to date with origin" + ``` +5. **Clean up** - Clear stashes, prune remote branches +6. **Verify** - All changes committed AND pushed +7. **Hand off** - Provide context for next session + +**CRITICAL RULES:** +- Work is NOT complete until `git push` succeeds +- NEVER stop before pushing - that leaves work stranded locally +- NEVER say "ready to push when you are" - YOU must push +- If push fails, resolve and retry until it succeeds + diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index c544235..c31d5c6 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -13,7 +13,6 @@ This document describes the architecture of Tilfluktsrom, a Norwegian emergency - [Compass System](#compass-system) - [Map & Tile Caching](#map--tile-caching) - [Build Variants](#build-variants) - - [Home Screen Widget](#home-screen-widget) - [Deep Linking](#deep-linking) - [Progressive Web App](#progressive-web-app) - [Module Structure](#module-structure) @@ -41,7 +40,7 @@ This is an emergency app. Core functionality — finding the nearest shelter, co The Android app runs on devices without Google Play Services (LineageOS, GrapheneOS, /e/OS). Every Google-specific API has an AOSP fallback. Play Services improve accuracy and battery life when available, but are never required. ### Minimal Dependencies -Both platforms use few, well-chosen libraries. No heavy frameworks, no external CDNs at runtime. The PWA bundles everything locally; the Android app uses only OSMDroid, Room, OkHttp, and WorkManager. +Both platforms use few, well-chosen libraries. No heavy frameworks, no external CDNs at runtime. The PWA bundles everything locally; the Android app uses only OSMDroid, Room, and OkHttp. ### Data Sovereignty Shelter data comes directly from Geonorge (the Norwegian mapping authority). No intermediate servers. The app fetches, converts, and caches the data locally. @@ -107,15 +106,12 @@ no.naiv.tilfluktsrom/ │ ├── ShelterListAdapter.kt # RecyclerView adapter for shelter list │ ├── CivilDefenseInfoDialog.kt # Emergency instructions │ └── AboutDialog.kt # Privacy and copyright -├── util/ -│ ├── CoordinateConverter.kt # UTM33N → WGS84 (Karney method) -│ └── DistanceUtils.kt # Haversine distance and bearing -└── widget/ - ├── ShelterWidgetProvider.kt # Home screen widget (flavor-specific) - └── WidgetUpdateWorker.kt # WorkManager periodic update +└── util/ + ├── CoordinateConverter.kt # UTM33N → WGS84 (Karney method) + └── DistanceUtils.kt # Haversine distance and bearing ``` -Files under `location/` and `widget/` have separate implementations per build variant: +Files under `location/` have separate implementations per build variant: - `app/src/standard/java/` — Google Play Services variant - `app/src/fdroid/java/` — AOSP-only variant @@ -198,24 +194,9 @@ The `standard` flavor adds `com.google.android.gms:play-services-location`. Runt Both flavors produce identical user experiences — `standard` achieves faster GPS fixes and better battery efficiency when Play Services are present. -### Home Screen Widget - -**ShelterWidgetProvider** displays the nearest shelter's address, capacity, and distance. Updated by: - -1. **MainActivity** — sends latest location on each GPS update -2. **WorkManager** — `WidgetUpdateWorker` runs every 15 minutes, requests a fresh location fix -3. **Manual** — user taps refresh button on the widget - -**Location resolution (priority order):** -1. Location from intent (WorkManager or MainActivity) -2. FusedLocationProviderClient cache (standard) -3. Active GPS request (10s timeout) -4. LocationManager cache -5. SharedPreferences saved location (max 24h old) - ### Deep Linking -**HTTPS App Links:** `https://tilfluktsrom.naiv.no/shelter/{lokalId}` +**HTTPS App Links:** `https://tilfluktsrom.naiv.no/shelter/{romnr}` The domain is configured in one place: `DEEP_LINK_DOMAIN` in `build.gradle.kts` (exposed as `BuildConfig.DEEP_LINK_DOMAIN` and manifest placeholder `${deepLinkHost}`). @@ -226,6 +207,20 @@ The domain is configured in one place: `DEEP_LINK_DOMAIN` in `build.gradle.kts` Share messages include the HTTPS URL, which SMS apps auto-link as a tappable URL. +#### Deep link identifier — why `romnr`, not `lokalId` + +The path component is the shelter's `romnr` (DSB room number — an integer like `776`), not the GeoJSON `lokalId` UUID, even though `lokalId` is what Room and Leaflet use as the in-memory primary key. + +**Empirical reason:** the upstream GeoJSON ZIP at `nedlasting.geonorge.no/.../TilfluktsromOffentlige_GeoJSON.zip` re-rolls every `lokalId` on every export. Three snapshots of the same dataset (taken Dec 2025, Apr 20 2026, Apr 27 2026) had **556/556 different lokalIds** while every other field (`romnr`, `adresse`, `plasser`, `latitude`, `longitude`) was byte-identical and the shelter count was unchanged. The most recent two snapshots are only seven days apart, so this is regular drift, not a one-off re-issue. + +That makes `lokalId` unsuitable for any cross-device or cross-build identifier: +- Sender and receiver who fetched the dataset on different days have different lokalIds for the same physical shelter, so a lokalId-keyed share link fails with "shelter not found" on the receiving side. +- Even on a single device, a user who hits "Refresh data" while a shelter is selected would lose the selection if it was tracked by lokalId. + +`romnr` is the actual DSB business key — the room number physically assigned to the shelter by the civil-defence authority — and is stable across exports. Verified unique (556/556) and present (no zeros) on the current dataset. + +The internal Room primary key remains `lokalId` because (a) it's already the upstream-supplied UUID and changing it would force a destructive Room schema migration, and (b) within a single fetch it's a perfectly fine in-memory key. Only the *external* deep-link identifier was switched. + --- ## Progressive Web App diff --git a/CLAUDE.md b/CLAUDE.md index df4f859..7bc620d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -12,7 +12,6 @@ The app must work on devices without Google Play Services (e.g. LineageOS, Graph - **Location**: Prefer FusedLocationProviderClient (Play Services) → fall back to LocationManager (AOSP) - **Maps**: OSMDroid (no Google dependency) - **Database**: Room/SQLite (no Google dependency) -- **Background work**: WorkManager (works without Play Services via built-in scheduler) ### Offline-First This is an emergency app. Assume internet and infrastructure may be degraded or unavailable. All core functionality (finding nearest shelter, compass navigation, sharing location) must work offline after initial data cache. Avoid solutions that depend on external servers being reachable. @@ -24,7 +23,6 @@ This is an emergency app. Assume internet and infrastructure may be degraded or - **Database**: Room (SQLite) for shelter data cache - **HTTP**: OkHttp for data downloads - **Location**: FusedLocationProviderClient (Play Services) with LocationManager fallback -- **Background**: WorkManager for periodic widget updates - **UI**: Traditional Views with ViewBinding ## Key Data Flow @@ -44,7 +42,6 @@ no.naiv.tilfluktsrom/ ├── data/ # Room entities, DAO, repository, GeoJSON parser, map cache ├── location/ # GPS location provider, nearest shelter finder ├── ui/ # Custom views (DirectionArrowView), adapters -├── widget/ # Home screen widget, WorkManager periodic updater └── util/ # Coordinate conversion (UTM→WGS84), distance calculations ``` @@ -113,3 +110,51 @@ Current screenshots: - Default (English): `res/values/strings.xml` - Norwegian Bokmål: `res/values-nb/strings.xml` - Norwegian Nynorsk: `res/values-nn/strings.xml` + + + +## Beads Issue Tracker + +This project uses **bd (beads)** for issue tracking. Run `bd prime` to see full workflow context and commands. + +### Quick Reference + +```bash +bd ready # Find available work +bd show # View issue details +bd update --claim # Claim work +bd close # Complete work +``` + +### Rules + +- Use `bd` for ALL task tracking — do NOT use TodoWrite, TaskCreate, or markdown TODO lists +- Run `bd prime` for detailed command reference and session close protocol +- Use `bd remember` for persistent knowledge — do NOT use MEMORY.md files + +## Session Completion + +**When ending a work session**, you MUST complete ALL steps below. Work is NOT complete until `git push` succeeds. + +**MANDATORY WORKFLOW:** + +1. **File issues for remaining work** - Create issues for anything that needs follow-up +2. **Run quality gates** (if code changed) - Tests, linters, builds +3. **Update issue status** - Close finished work, update in-progress items +4. **PUSH TO REMOTE** - This is MANDATORY: + ```bash + git pull --rebase + bd dolt push + git push + git status # MUST show "up to date with origin" + ``` +5. **Clean up** - Clear stashes, prune remote branches +6. **Verify** - All changes committed AND pushed +7. **Hand off** - Provide context for next session + +**CRITICAL RULES:** +- Work is NOT complete until `git push` succeeds +- NEVER stop before pushing - that leaves work stranded locally +- NEVER say "ready to push when you are" - YOU must push +- If push fails, resolve and retry until it succeeds + diff --git a/README.md b/README.md index 2783a9d..bbbf4f4 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,6 @@ Finn nærmeste offentlige tilfluktsrom i Norge. Appen er bygd for nødsituasjone - **Velg fritt** — trykk på en markering i kartet for å navigere dit - **Del tilfluktsrom** — send adresse, kapasitet og koordinater til andre - **Sivilforsvarsinfo** — veiledning fra DSB om hva du skal gjøre når alarmen går -- **Hjemmeskjerm-widget** — viser nærmeste tilfluktsrom uten å åpne appen - **Flerspråklig** — engelsk, bokmål og nynorsk - **Tilgjengelighet** — TalkBack-støtte, fokusindikatorer og tilstrekkelig kontrast @@ -70,7 +69,6 @@ tilfluktsrom/ │ │ ├── data/ # Room-database, nedlasting, GeoJSON-parser │ │ ├── location/ # GPS, nærmeste tilfluktsrom │ │ ├── ui/ # Retningspil, liste-adapter, om-dialog -│ │ ├── widget/ # Hjemmeskjerm-widget │ │ └── util/ # UTM→WGS84-konvertering, avstandsberegning │ └── res/ # Layout, strenger (en/nb/nn), ikoner ├── pwa/ # Nettapp (TypeScript) @@ -99,7 +97,7 @@ Appen er designet etter «offline-first»-prinsippet: - Content Security Policy (CSP) i PWA-versjonen - Tilfluktsromdata valideres ved parsing (koordinater innenfor Norge, gyldige felt) - Databaseoppdateringer er atomiske (transaksjon) for å unngå datatap -- Lagret GPS-posisjon utløper automatisk etter 24 timer +- GPS-posisjon lagres ikke — den brukes bare i minnet mens appen er i bruk - Egendefinert User-Agent forhindrer enhetsfingeravtrykk ## Personvern diff --git a/STANDING_ON_SHOULDERS.md b/STANDING_ON_SHOULDERS.md index f61b1e2..90d6c19 100644 --- a/STANDING_ON_SHOULDERS.md +++ b/STANDING_ON_SHOULDERS.md @@ -80,7 +80,7 @@ engineers must be in orbit, in your pocket, and on the circuit board. | Library | What it does | Contributors | Source | |---|---|---|---| -| AndroidX (Core, AppCompat, Room, WorkManager, etc.) | UI, architecture, database, scheduling | ~1,000 | [GitHub: androidx/androidx](https://github.com/androidx/androidx) monorepo | +| AndroidX (Core, AppCompat, Room, etc.) | UI, architecture, database | ~1,000 | [GitHub: androidx/androidx](https://github.com/androidx/androidx) monorepo | | Material Design Components | Visual design language and components | ~199 | [GitHub: material-components-android](https://github.com/material-components/material-components-android) | | Kotlinx Coroutines | Async data loading without blocking the UI | ~308 | [GitHub: Kotlin/kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) | | OkHttp | Downloads the GeoJSON ZIP from Geonorge | ~287 | [GitHub: square/okhttp](https://github.com/square/okhttp) | diff --git a/app/build.gradle.kts b/app/build.gradle.kts index fa9f32d..6b43a9e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -14,8 +14,8 @@ android { applicationId = "no.naiv.tilfluktsrom" minSdk = 26 targetSdk = 35 - versionCode = 14 - versionName = "1.9.1" + versionCode = 17 + versionName = "1.10.2" // Deep link domain — single source of truth for manifest + Kotlin code val deepLinkDomain = "tilfluktsrom.naiv.no" @@ -104,9 +104,6 @@ dependencies { // Google Play Services Location (precise GPS) — standard flavor only "standardImplementation"("com.google.android.gms:play-services-location:21.3.0") - // WorkManager (periodic widget updates) - implementation("androidx.work:work-runtime-ktx:2.9.1") - // Coroutines implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1") diff --git a/app/src/fdroid/java/no/naiv/tilfluktsrom/widget/ShelterWidgetProvider.kt b/app/src/fdroid/java/no/naiv/tilfluktsrom/widget/ShelterWidgetProvider.kt deleted file mode 100644 index 1f42882..0000000 --- a/app/src/fdroid/java/no/naiv/tilfluktsrom/widget/ShelterWidgetProvider.kt +++ /dev/null @@ -1,268 +0,0 @@ -package no.naiv.tilfluktsrom.widget - -import android.Manifest -import android.app.PendingIntent -import android.appwidget.AppWidgetManager -import android.appwidget.AppWidgetProvider -import android.content.ComponentName -import android.content.Context -import android.content.Intent -import android.content.pm.PackageManager -import android.location.Location -import android.location.LocationManager -import android.os.Build -import android.os.CancellationSignal -import android.text.format.DateFormat -import android.util.Log -import android.widget.RemoteViews -import androidx.core.content.ContextCompat -import no.naiv.tilfluktsrom.MainActivity -import no.naiv.tilfluktsrom.R -import no.naiv.tilfluktsrom.data.ShelterDatabase -import no.naiv.tilfluktsrom.location.ShelterFinder -import no.naiv.tilfluktsrom.util.DistanceUtils -import java.util.concurrent.TimeUnit - -/** - * Home screen widget showing the nearest shelter with distance. - * - * F-Droid flavor: uses LocationManager only (no Google Play Services). - */ -class ShelterWidgetProvider : AppWidgetProvider() { - - companion object { - private const val TAG = "ShelterWidget" - const val ACTION_REFRESH = "no.naiv.tilfluktsrom.widget.REFRESH" - private const val EXTRA_LATITUDE = "lat" - private const val EXTRA_LONGITUDE = "lon" - - fun requestUpdate(context: Context) { - val intent = Intent(context, ShelterWidgetProvider::class.java).apply { - action = ACTION_REFRESH - } - context.sendBroadcast(intent) - } - - fun requestUpdateWithLocation(context: Context, latitude: Double, longitude: Double) { - val intent = Intent(context, ShelterWidgetProvider::class.java).apply { - action = ACTION_REFRESH - putExtra(EXTRA_LATITUDE, latitude) - putExtra(EXTRA_LONGITUDE, longitude) - } - context.sendBroadcast(intent) - } - } - - override fun onEnabled(context: Context) { - super.onEnabled(context) - WidgetUpdateWorker.schedule(context) - } - - override fun onDisabled(context: Context) { - super.onDisabled(context) - WidgetUpdateWorker.cancel(context) - } - - override fun onUpdate( - context: Context, - appWidgetManager: AppWidgetManager, - appWidgetIds: IntArray - ) { - WidgetUpdateWorker.schedule(context) - updateAllWidgetsAsync(context, null) - } - - override fun onReceive(context: Context, intent: Intent) { - super.onReceive(context, intent) - - if (intent.action == ACTION_REFRESH) { - val providedLocation = if (intent.hasExtra(EXTRA_LATITUDE)) { - Location("widget").apply { - latitude = intent.getDoubleExtra(EXTRA_LATITUDE, 0.0) - longitude = intent.getDoubleExtra(EXTRA_LONGITUDE, 0.0) - } - } else null - - updateAllWidgetsAsync(context, providedLocation) - } - } - - private fun updateAllWidgetsAsync(context: Context, providedLocation: Location?) { - val pendingResult = goAsync() - Thread { - try { - val appWidgetManager = AppWidgetManager.getInstance(context) - val widgetIds = appWidgetManager.getAppWidgetIds( - ComponentName(context, ShelterWidgetProvider::class.java) - ) - val location = providedLocation ?: getBestLocation(context) - for (appWidgetId in widgetIds) { - updateWidget(context, appWidgetManager, appWidgetId, location) - } - } catch (e: Exception) { - Log.e(TAG, "Failed to update widgets", e) - } finally { - pendingResult.finish() - } - }.start() - } - - private fun updateWidget( - context: Context, - appWidgetManager: AppWidgetManager, - appWidgetId: Int, - location: Location? - ) { - val views = RemoteViews(context.packageName, R.layout.widget_nearest_shelter) - - val openAppIntent = Intent(context, MainActivity::class.java) - val openAppPending = PendingIntent.getActivity( - context, 0, openAppIntent, PendingIntent.FLAG_IMMUTABLE - ) - views.setOnClickPendingIntent(R.id.widgetRoot, openAppPending) - - val refreshIntent = Intent(context, ShelterWidgetProvider::class.java).apply { - action = ACTION_REFRESH - } - val refreshPending = PendingIntent.getBroadcast( - context, 0, refreshIntent, PendingIntent.FLAG_IMMUTABLE - ) - views.setOnClickPendingIntent(R.id.widgetRefreshButton, refreshPending) - - if (ContextCompat.checkSelfPermission( - context, Manifest.permission.ACCESS_FINE_LOCATION - ) != PackageManager.PERMISSION_GRANTED - ) { - showFallback(context, views, context.getString(R.string.widget_open_app)) - appWidgetManager.updateAppWidget(appWidgetId, views) - return - } - - if (location == null) { - showFallback(context, views, context.getString(R.string.widget_no_location)) - appWidgetManager.updateAppWidget(appWidgetId, views) - return - } - - val shelters = try { - val dao = ShelterDatabase.getInstance(context).shelterDao() - kotlinx.coroutines.runBlocking { dao.getAllSheltersList() } - } catch (e: Exception) { - Log.e(TAG, "Failed to query shelters", e) - emptyList() - } - - if (shelters.isEmpty()) { - showFallback(context, views, context.getString(R.string.widget_no_data)) - appWidgetManager.updateAppWidget(appWidgetId, views) - return - } - - val nearest = ShelterFinder.findNearest( - shelters, location.latitude, location.longitude, 1 - ).firstOrNull() - - if (nearest == null) { - showFallback(context, views, context.getString(R.string.widget_no_data)) - appWidgetManager.updateAppWidget(appWidgetId, views) - return - } - - views.setTextViewText(R.id.widgetAddress, nearest.shelter.adresse) - views.setTextViewText( - R.id.widgetDetails, - context.getString(R.string.shelter_capacity, nearest.shelter.plasser) - ) - views.setTextViewText( - R.id.widgetDistance, - DistanceUtils.formatDistance(nearest.distanceMeters) - ) - views.setTextViewText(R.id.widgetTimestamp, formatTimestamp(context)) - - appWidgetManager.updateAppWidget(appWidgetId, views) - } - - private fun showFallback(context: Context, views: RemoteViews, message: String) { - views.setTextViewText(R.id.widgetAddress, message) - views.setTextViewText(R.id.widgetDetails, "") - views.setTextViewText(R.id.widgetDistance, "") - views.setTextViewText(R.id.widgetTimestamp, formatTimestamp(context)) - } - - private fun formatTimestamp(context: Context): String { - val format = DateFormat.getTimeFormat(context) - val timeStr = format.format(System.currentTimeMillis()) - return context.getString(R.string.widget_updated_at, timeStr) - } - - /** - * Get the best available location via LocationManager or SharedPreferences. - * Safe to call from a background thread. - */ - private fun getBestLocation(context: Context): Location? { - if (ContextCompat.checkSelfPermission( - context, Manifest.permission.ACCESS_FINE_LOCATION - ) != PackageManager.PERMISSION_GRANTED - ) return null - - val lmLocation = getLocationManagerLocation(context) - if (lmLocation != null) return lmLocation - - return getSavedLocation(context) - } - - /** Returns null if older than 24 hours to avoid retaining stale location data. */ - private fun getSavedLocation(context: Context): Location? { - val prefs = context.getSharedPreferences("widget_prefs", Context.MODE_PRIVATE) - if (!prefs.contains("last_lat")) return null - val age = System.currentTimeMillis() - prefs.getLong("last_time", 0L) - if (age > 24 * 60 * 60 * 1000L) return null - return Location("saved").apply { - latitude = prefs.getFloat("last_lat", 0f).toDouble() - longitude = prefs.getFloat("last_lon", 0f).toDouble() - } - } - - private fun getLocationManagerLocation(context: Context): Location? { - val locationManager = context.getSystemService(Context.LOCATION_SERVICE) - as? LocationManager ?: return null - - try { - val lastGps = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) - val lastNetwork = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) - val cached = listOfNotNull(lastGps, lastNetwork).maxByOrNull { it.time } - if (cached != null) return cached - } catch (e: SecurityException) { - Log.e(TAG, "SecurityException getting last known location", e) - return null - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - val provider = when { - locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) -> - LocationManager.NETWORK_PROVIDER - locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) -> - LocationManager.GPS_PROVIDER - else -> return null - } - try { - val latch = java.util.concurrent.CountDownLatch(1) - var result: Location? = null - val signal = CancellationSignal() - locationManager.getCurrentLocation( - provider, signal, context.mainExecutor - ) { location -> - result = location - latch.countDown() - } - latch.await(10, TimeUnit.SECONDS) - signal.cancel() - return result - } catch (e: Exception) { - Log.e(TAG, "Active location request failed", e) - } - } - - return null - } -} diff --git a/app/src/fdroid/java/no/naiv/tilfluktsrom/widget/WidgetUpdateWorker.kt b/app/src/fdroid/java/no/naiv/tilfluktsrom/widget/WidgetUpdateWorker.kt deleted file mode 100644 index 8d482f4..0000000 --- a/app/src/fdroid/java/no/naiv/tilfluktsrom/widget/WidgetUpdateWorker.kt +++ /dev/null @@ -1,136 +0,0 @@ -package no.naiv.tilfluktsrom.widget - -import android.Manifest -import android.content.Context -import android.content.pm.PackageManager -import android.location.Location -import android.location.LocationManager -import android.os.Build -import android.os.CancellationSignal -import android.util.Log -import androidx.core.content.ContextCompat -import androidx.work.CoroutineWorker -import androidx.work.ExistingPeriodicWorkPolicy -import androidx.work.OneTimeWorkRequestBuilder -import androidx.work.PeriodicWorkRequestBuilder -import androidx.work.WorkManager -import androidx.work.WorkerParameters -import kotlinx.coroutines.suspendCancellableCoroutine -import kotlinx.coroutines.withTimeoutOrNull -import java.util.concurrent.TimeUnit -import kotlin.coroutines.resume - -/** - * Periodic background worker that refreshes the home screen widget. - * - * F-Droid flavor: uses LocationManager only (no Google Play Services). - */ -class WidgetUpdateWorker( - context: Context, - params: WorkerParameters -) : CoroutineWorker(context, params) { - - companion object { - private const val TAG = "WidgetUpdateWorker" - private const val WORK_NAME = "widget_update" - private const val LOCATION_TIMEOUT_MS = 10_000L - - fun schedule(context: Context) { - val request = PeriodicWorkRequestBuilder( - 15, TimeUnit.MINUTES - ).build() - - WorkManager.getInstance(context).enqueueUniquePeriodicWork( - WORK_NAME, - ExistingPeriodicWorkPolicy.KEEP, - request - ) - } - - fun runOnce(context: Context) { - val request = OneTimeWorkRequestBuilder().build() - WorkManager.getInstance(context).enqueue(request) - } - - fun cancel(context: Context) { - WorkManager.getInstance(context).cancelUniqueWork(WORK_NAME) - } - } - - override suspend fun doWork(): Result { - val location = requestFreshLocation() ?: getSavedLocation() - if (location != null) { - ShelterWidgetProvider.requestUpdateWithLocation( - applicationContext, location.latitude, location.longitude - ) - } else { - ShelterWidgetProvider.requestUpdate(applicationContext) - } - return Result.success() - } - - /** Returns null if older than 24 hours. */ - private fun getSavedLocation(): Location? { - val prefs = applicationContext.getSharedPreferences("widget_prefs", Context.MODE_PRIVATE) - if (!prefs.contains("last_lat")) return null - val age = System.currentTimeMillis() - prefs.getLong("last_time", 0L) - if (age > 24 * 60 * 60 * 1000L) return null - return Location("saved").apply { - latitude = prefs.getFloat("last_lat", 0f).toDouble() - longitude = prefs.getFloat("last_lon", 0f).toDouble() - } - } - - private suspend fun requestFreshLocation(): Location? { - val context = applicationContext - if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) - != PackageManager.PERMISSION_GRANTED - ) return null - - return requestViaLocationManager() - } - - private suspend fun requestViaLocationManager(): Location? { - val locationManager = applicationContext.getSystemService(Context.LOCATION_SERVICE) - as? LocationManager ?: return null - - val provider = when { - locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) -> - LocationManager.GPS_PROVIDER - locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) -> - LocationManager.NETWORK_PROVIDER - else -> return null - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - return requestCurrentLocation(locationManager, provider) - } - // API 26-29: fall back to passive cache - return try { - locationManager.getLastKnownLocation(provider) - } catch (e: SecurityException) { - null - } - } - - private suspend fun requestCurrentLocation(locationManager: LocationManager, provider: String): Location? { - return try { - withTimeoutOrNull(LOCATION_TIMEOUT_MS) { - suspendCancellableCoroutine { cont -> - val signal = CancellationSignal() - locationManager.getCurrentLocation( - provider, - signal, - applicationContext.mainExecutor - ) { location -> - if (cont.isActive) cont.resume(location) - } - cont.invokeOnCancellation { signal.cancel() } - } - } - } catch (e: SecurityException) { - Log.e(TAG, "SecurityException requesting location via LocationManager", e) - null - } - } -} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e522483..7f7fc34 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -39,18 +39,5 @@ android:pathPrefix="/shelter/" /> - - - - - - - - diff --git a/app/src/main/assets/shelters.json b/app/src/main/assets/shelters.json index 239a144..2d6c3c8 100644 --- a/app/src/main/assets/shelters.json +++ b/app/src/main/assets/shelters.json @@ -1,6 +1,6 @@ [ { - "lokalId": "87853d43-4dda-4964-96e5-96dffc1cf7f3", + "lokalId": "58e696d9-dafd-4b58-baff-5af27e3c08a8", "romnr": 776, "plasser": 400, "adresse": "Trimv. 09 - Borre Idrettspark (off)", @@ -8,7 +8,7 @@ "longitude": 10.462107 }, { - "lokalId": "630ff427-3bfe-4766-b67c-89258e4d7055", + "lokalId": "98b386b5-b4d5-41b0-aa92-dffd9925d28d", "romnr": 777, "plasser": 390, "adresse": "Torget 6", @@ -16,7 +16,7 @@ "longitude": 10.483879 }, { - "lokalId": "c46fa6c9-5963-42f3-a034-830e1e0b5678", + "lokalId": "0e1bb081-cf1b-4180-8a64-08f1048e4611", "romnr": 785, "plasser": 370, "adresse": "Vestre Braarudgt. 6b - Åsheim", @@ -24,7 +24,7 @@ "longitude": 10.479063 }, { - "lokalId": "fa659eb8-49cf-4c1e-8f12-e3cf3e75d28d", + "lokalId": "2923c4c3-a474-4c78-8707-3e87b81ad1b1", "romnr": 786, "plasser": 215, "adresse": "Vognmannsgt. 1 - Trygdegården", @@ -32,7 +32,7 @@ "longitude": 10.483809 }, { - "lokalId": "13486699-ae0a-443f-8fda-e48aa24a5d87", + "lokalId": "54ed7818-e7b8-465b-aa27-5ba4f4ed2d7f", "romnr": 787, "plasser": 800, "adresse": "Langgt. 14", @@ -40,7 +40,7 @@ "longitude": 10.315461 }, { - "lokalId": "9245e9ca-3425-462d-b913-57ddaac9cd6a", + "lokalId": "6e9b7a6e-2cb3-46ef-97da-fb16a35176f0", "romnr": 788, "plasser": 159, "adresse": "Badeparken 7 - Bøkeskogen eldresenter", @@ -48,7 +48,7 @@ "longitude": 10.029484 }, { - "lokalId": "2ed1eaf2-3cb7-47c0-bf56-e2536b036815", + "lokalId": "a73bd026-ee2b-4e2b-a06d-450c24cd6482", "romnr": 789, "plasser": 265, "adresse": "Byskogv. 5 - Byskogen Bo- og aktivitetssenter", @@ -56,7 +56,7 @@ "longitude": 10.036693 }, { - "lokalId": "ed81c068-a806-40fe-9720-da17282d8624", + "lokalId": "a9123d92-efe0-4297-902d-f934fc1b3389", "romnr": 791, "plasser": 128, "adresse": "Øvre Dr. Holms vei 44 - KUF-huset", @@ -64,7 +64,7 @@ "longitude": 10.047809 }, { - "lokalId": "3c482130-3752-4480-9446-ecb164ece9ba", + "lokalId": "cd5d7469-5aba-45cb-934a-14ecc7ab8478", "romnr": 793, "plasser": 220, "adresse": "Nordbyveien 27 - Hagatun grendehus", @@ -72,7 +72,7 @@ "longitude": 10.049947 }, { - "lokalId": "264c5903-71df-47c1-bdb4-05a582e645b1", + "lokalId": "ea06e1ec-93a9-4849-9a79-1588cbacea20", "romnr": 794, "plasser": 220, "adresse": "Rosendalsgt. 17 - Langestrand skole", @@ -80,7 +80,7 @@ "longitude": 10.011399 }, { - "lokalId": "e7a139a6-6582-4986-9da2-d8d13f17eacc", + "lokalId": "4846b33b-6cab-4c30-af4d-b9505e8bcb38", "romnr": 795, "plasser": 850, "adresse": "Ahlefeldtsgt. 1 - Mesterfjellet", @@ -88,7 +88,7 @@ "longitude": 10.041182 }, { - "lokalId": "fcf81be7-c342-4214-a08d-218d065da7ed", + "lokalId": "30c602fb-3415-48dc-8a7c-16b2395850c8", "romnr": 796, "plasser": 425, "adresse": "Skallestadv. 38 - Hårkollhallen", @@ -96,7 +96,7 @@ "longitude": 10.442214 }, { - "lokalId": "ca9264db-5a82-4904-9944-f6dbd1f3313e", + "lokalId": "ad09ce76-4028-4706-ac29-1578bd6ce0ef", "romnr": 797, "plasser": 42, "adresse": "Tinghaugv. 14 - Nøtterøy kulturhus, nedre rom", @@ -104,7 +104,7 @@ "longitude": 10.409499 }, { - "lokalId": "1c8c9782-1a18-475c-9d3a-a7880c61a7ed", + "lokalId": "6da3308f-0259-4150-97e3-ac15a6c85941", "romnr": 798, "plasser": 225, "adresse": "Tinghaugv. 14 - Nøtterøy kulturhus, øvre rom", @@ -112,7 +112,7 @@ "longitude": 10.409453 }, { - "lokalId": "0bf67a70-c797-4b99-9516-6ef9f2edb7fa", + "lokalId": "6ebeacdb-df59-4475-9463-58da0ef78413", "romnr": 799, "plasser": 415, "adresse": "Harpunv. 3 - Optura A/S (off.)", @@ -120,7 +120,7 @@ "longitude": 10.390622 }, { - "lokalId": "dfeff471-85d2-4f2f-a119-b9b4c7d173a7", + "lokalId": "31c45085-264a-401e-b9d7-b80b1561f58e", "romnr": 802, "plasser": 195, "adresse": "Sportsv. 31 - Off. Bugården u-skole", @@ -128,7 +128,7 @@ "longitude": 10.187642 }, { - "lokalId": "d9be3b5e-b011-4732-b46c-db393892eae2", + "lokalId": "ee6a9056-67e8-45a0-ac0d-e573f2284505", "romnr": 803, "plasser": 1170, "adresse": "Dronningensgt. 24 - Off. Forsmannssenteret", @@ -136,7 +136,7 @@ "longitude": 10.21984 }, { - "lokalId": "eb68ddcf-0464-4e34-831e-1efd59a180cc", + "lokalId": "a548bb8a-c595-434a-8172-609865ace704", "romnr": 804, "plasser": 293, "adresse": "Lyhmannsv. 2 - Off. Framnes Eldresenter", @@ -144,7 +144,7 @@ "longitude": 10.234024 }, { - "lokalId": "34674a45-67ed-4ccf-951e-ba69a63e6207", + "lokalId": "09055283-03cf-42d1-bdbe-e64174c612d0", "romnr": 805, "plasser": 1233, "adresse": "Maurveien 14 - Off. Gjekstad (garasjeanlegg)", @@ -152,7 +152,7 @@ "longitude": 10.264337 }, { - "lokalId": "5ce1823a-3eec-40b7-955f-b09677a2069e", + "lokalId": "14b48dbd-589c-4830-b725-4ec24be3c3b2", "romnr": 806, "plasser": 400, "adresse": "Gokstadv. 5 - Off.", @@ -160,7 +160,7 @@ "longitude": 10.229432 }, { - "lokalId": "096655bc-6260-46ef-ae0f-b85747c75635", + "lokalId": "e604170c-ccbe-42dc-b76b-de88dcba5f29", "romnr": 807, "plasser": 600, "adresse": "Høstsgt. 3 - Off.", @@ -168,7 +168,7 @@ "longitude": 10.214538 }, { - "lokalId": "712a4c9c-fd0f-4779-ab52-177d2cc9e47b", + "lokalId": "8d4a6f73-2d07-4372-ab9f-6e689afa40ab", "romnr": 808, "plasser": 200, "adresse": "Hystadv. 167 - Off. Jotun A/S", @@ -176,7 +176,7 @@ "longitude": 10.222859 }, { - "lokalId": "9139f600-e7cf-46f0-877f-3df577e4091d", + "lokalId": "8428ef5b-dd18-4ac8-bd51-f729decc9456", "romnr": 809, "plasser": 300, "adresse": "Rødslia 28 - I krysset ved Fagerstadveien", @@ -184,7 +184,7 @@ "longitude": 10.240034 }, { - "lokalId": "1071e773-5a36-477d-87d9-a00ce5d35baf", + "lokalId": "a540f556-e2a6-49ad-a2b4-6cbfba1066cd", "romnr": 810, "plasser": 400, "adresse": "Sandefjordsv. 3 - Off. Sandefjord Rådhus", @@ -192,7 +192,7 @@ "longitude": 10.219716 }, { - "lokalId": "ea2c071c-139a-42fd-a241-2fa45a02f601", + "lokalId": "655ac711-deb3-46dc-8c80-325b61b11087", "romnr": 813, "plasser": 1500, "adresse": "Haugar", @@ -200,7 +200,7 @@ "longitude": 10.410234 }, { - "lokalId": "3db39a05-3227-47e4-86fe-f3726f0eae21", + "lokalId": "b873db51-c49b-49f1-9047-89720645b3e8", "romnr": 814, "plasser": 150, "adresse": "Larvev. 31 - Hogsnes Grendehus, rom 1 (off)", @@ -208,7 +208,7 @@ "longitude": 10.356823 }, { - "lokalId": "94a80dc3-3c75-4883-a2d4-f22036e62233", + "lokalId": "b7f81011-067b-4c78-81ad-d3686989c3aa", "romnr": 815, "plasser": 150, "adresse": "Larvev. 31 - Hogsnes Grendehus, rom 2 (off)", @@ -216,7 +216,7 @@ "longitude": 10.356823 }, { - "lokalId": "99ccff09-c015-47a0-ba6d-865b17824def", + "lokalId": "3e4b3b2a-ae83-4e33-8068-5bd898e17bea", "romnr": 816, "plasser": 962, "adresse": "Slottsfjelltunnelen (off)", @@ -224,7 +224,7 @@ "longitude": 10.401937 }, { - "lokalId": "b16aa85d-9318-460d-bb86-432f66ed7a71", + "lokalId": "2dc00cd7-1b30-4d25-9f84-4c782ae0e689", "romnr": 817, "plasser": 215, "adresse": "Trimveien 14 - ved Slagenhallen", @@ -232,7 +232,7 @@ "longitude": 10.462225 }, { - "lokalId": "7e320f2d-4de5-438a-b451-0ab115ba5cb1", + "lokalId": "f43263b1-23c1-4015-a0ed-427bfb496865", "romnr": 831, "plasser": 800, "adresse": "Dronningensgate 52", @@ -240,7 +240,7 @@ "longitude": 17.429275 }, { - "lokalId": "2e1fd4f8-f4f5-4208-840b-7811da72b777", + "lokalId": "c07f9033-d6fa-4743-b62b-0b00276e613e", "romnr": 917, "plasser": 215, "adresse": "Torget 6", @@ -248,7 +248,7 @@ "longitude": 6.001131 }, { - "lokalId": "f5dc9a2e-a4d7-4005-afdd-fcce77fe0ac3", + "lokalId": "2dd5c9d3-9420-44dc-a9c2-febf66d0c3ba", "romnr": 933, "plasser": 240, "adresse": "Jernbaneveien 22", @@ -256,7 +256,7 @@ "longitude": 6.002466 }, { - "lokalId": "071349d7-e899-4718-85af-6dfbd4299bc7", + "lokalId": "ea002d32-bc79-4383-bb53-2e22fc2e9c47", "romnr": 934, "plasser": 88, "adresse": "Sokndalsveien 26", @@ -264,7 +264,7 @@ "longitude": 6.006581 }, { - "lokalId": "a839751e-51bf-4697-8ec9-aa659eaf64b0", + "lokalId": "6a94a29b-6b09-41b7-a93e-cc41904d32df", "romnr": 1220, "plasser": 270, "adresse": "Røyrvika 10", @@ -272,7 +272,7 @@ "longitude": 5.655472 }, { - "lokalId": "b3150f2e-1589-4f1c-a0b6-1643ea849f68", + "lokalId": "6223073d-892c-45a2-a5b1-4f47ae15a94e", "romnr": 1255, "plasser": 60, "adresse": "Bedriftsvegen 6", @@ -280,7 +280,7 @@ "longitude": 5.697514 }, { - "lokalId": "b692f1ac-e55c-436e-8a01-bdef8b810a8f", + "lokalId": "767d3a40-5b75-4045-82cd-5e14dc667d3b", "romnr": 1286, "plasser": 180, "adresse": "Kleppevarden 2", @@ -288,7 +288,7 @@ "longitude": 5.627087 }, { - "lokalId": "c3df37b1-1adc-4fcd-90ba-8f194c0232af", + "lokalId": "c0550db3-6cde-46c5-bd7b-1d97e4ada827", "romnr": 1423, "plasser": 30, "adresse": "Horghallvegen 25, HORGHALLEN", @@ -296,7 +296,7 @@ "longitude": 10.283676 }, { - "lokalId": "baffc78f-6c35-4d46-be4c-eec0049ba024", + "lokalId": "a370eeb6-8a79-4752-bc29-a5235e4527e9", "romnr": 1434, "plasser": 50, "adresse": "Tømmesdalsvegen 70, HOVIN SKOLE/SAMF.HUS", @@ -304,7 +304,7 @@ "longitude": 10.226629 }, { - "lokalId": "443aac13-ea31-41fd-a3f6-7a553f256862", + "lokalId": "d4558105-afce-479c-976b-bfbda15a9e37", "romnr": 1435, "plasser": 60, "adresse": "Per Bortens veg 21, MELHUS SKYSSTASJON", @@ -312,7 +312,7 @@ "longitude": 10.276954 }, { - "lokalId": "2da7587c-44f0-4c20-9914-6484370d6d2f", + "lokalId": "2d521f23-53ac-406a-b32e-3a7325ea40dd", "romnr": 1515, "plasser": 200, "adresse": "STATENS HUS ORKANGER", @@ -320,7 +320,7 @@ "longitude": 9.847558 }, { - "lokalId": "9763b9a2-e781-46b6-925f-82207c6cc206", + "lokalId": "faf17e0b-21f9-4872-915b-8d620589a445", "romnr": 1516, "plasser": 33, "adresse": "TORGSENTERET, ORKANGER", @@ -328,7 +328,7 @@ "longitude": 9.849685 }, { - "lokalId": "c5259e37-3e49-413a-8f34-c6aca0468ca3", + "lokalId": "7827ec49-3146-45e0-8daf-fc4e523261c7", "romnr": 1517, "plasser": 40, "adresse": "Orkdalsveien 82", @@ -336,7 +336,7 @@ "longitude": 9.848431 }, { - "lokalId": "7b56309c-8595-4f67-9b1c-b72c4ef69293", + "lokalId": "d15c0799-3125-45d5-bfad-e774c53502ba", "romnr": 1563, "plasser": 16, "adresse": "Sollihagaen 17, RØROS KJØLESERVICE", @@ -344,7 +344,7 @@ "longitude": 11.369025 }, { - "lokalId": "f2362ae1-bb9a-4018-b1ce-e94651dd91f2", + "lokalId": "a9ba53c4-a314-4214-9d46-51703e5a83c4", "romnr": 1568, "plasser": 20, "adresse": "Lorentz Lossius gata 45, RØROSMUSEET", @@ -352,7 +352,7 @@ "longitude": 11.391251 }, { - "lokalId": "a9a1b57f-b1bc-4016-9b50-c113ea290893", + "lokalId": "9eff87fd-f993-4c5f-8634-63a5290df983", "romnr": 1628, "plasser": 170, "adresse": "Teletunet, Opphaug, Offentlig", @@ -360,7 +360,7 @@ "longitude": 9.687023 }, { - "lokalId": "7fcaa9f0-fc08-46a7-b6fb-1a2d83500d7d", + "lokalId": "8d361ab1-b097-479c-b7f9-af95d51a20e4", "romnr": 1681, "plasser": 315, "adresse": "Kaigaten 8 OFF T-ROM hotellet", @@ -368,7 +368,7 @@ "longitude": 31.103902 }, { - "lokalId": "bd92c299-14bc-4e46-bf49-8144058702f8", + "lokalId": "a20674ba-0608-4d9b-812f-ab33e351bd30", "romnr": 1688, "plasser": 136, "adresse": "BANEHEIVEIEN", @@ -376,7 +376,7 @@ "longitude": 7.982371 }, { - "lokalId": "4fae9780-f765-4fc0-99a0-1e38c11f465e", + "lokalId": "7a3343e4-3777-434c-9db6-2632b999b680", "romnr": 1707, "plasser": 195, "adresse": "BYDALSVEIEN 19", @@ -384,7 +384,7 @@ "longitude": 7.922027 }, { - "lokalId": "271b4f52-2053-4bbd-bf72-dfdf99435a7f", + "lokalId": "99ebf228-47ee-4a68-9961-4993189b33a2", "romnr": 1740, "plasser": 65, "adresse": "FREDRIK FRANSSONSVEI 4", @@ -392,7 +392,7 @@ "longitude": 8.083974 }, { - "lokalId": "b22c8975-2250-436a-ac57-6ca4e70a5188", + "lokalId": "b2864832-20cb-4dcf-aa94-d58e0a1e7707", "romnr": 1755, "plasser": 235, "adresse": "GROSTØLVEIEN 4 E", @@ -400,7 +400,7 @@ "longitude": 8.03204 }, { - "lokalId": "8cdb7ae6-39a7-478d-ac53-5ba35e7a8980", + "lokalId": "bb37cfe2-e862-48e4-ba28-d620ac340f65", "romnr": 1756, "plasser": 500, "adresse": "GRÅGÅSVEIEN 43", @@ -408,7 +408,7 @@ "longitude": 7.936556 }, { - "lokalId": "52c634f3-32e0-4d27-895e-3f9e8a51f03e", + "lokalId": "f3060ded-adf7-4bdd-b3e6-0f07d74a6d43", "romnr": 1776, "plasser": 170, "adresse": "RAVNEDALSVEIEN 34", @@ -416,7 +416,7 @@ "longitude": 7.972959 }, { - "lokalId": "d390adf0-b68f-4ed1-bc44-2146cbe203ab", + "lokalId": "76f51e5f-caa8-43b4-88cc-32c1cb9320b5", "romnr": 1795, "plasser": 50, "adresse": "HÅNESVEIEN 61", @@ -424,7 +424,7 @@ "longitude": 8.08888 }, { - "lokalId": "741fe60c-0401-47d1-8559-6503245da9aa", + "lokalId": "62813eaa-ac68-4e42-94d0-5d671d4fbcc5", "romnr": 1799, "plasser": 390, "adresse": "INDUSTRIGATA 6", @@ -432,7 +432,7 @@ "longitude": 8.025719 }, { - "lokalId": "2896f65b-8106-4a2c-9c0f-ccc7b4d65c72", + "lokalId": "1b55a9f7-08b1-418d-8815-b4d0c135780f", "romnr": 1818, "plasser": 170, "adresse": "JORDBÆRVEIEN 2", @@ -440,7 +440,7 @@ "longitude": 8.09532 }, { - "lokalId": "eb74ad26-64b8-4be3-8805-5605c759c9fd", + "lokalId": "8366ec56-3be0-4de5-9a73-50e3a14d2b07", "romnr": 1822, "plasser": 184, "adresse": "KARUSSVEIEN 7", @@ -448,7 +448,7 @@ "longitude": 7.946368 }, { - "lokalId": "6e8126e5-d179-4d8c-b8f6-d9cff8cca8c8", + "lokalId": "16ffea16-2ea5-413f-a30b-4ed1dc66e24d", "romnr": 1832, "plasser": 465, "adresse": "KIRSTEN FLAGSTADSVEI 30", @@ -456,7 +456,7 @@ "longitude": 7.953968 }, { - "lokalId": "00631cd5-e0bc-4b72-a827-a388dea3f008", + "lokalId": "ed8523d4-05b8-4b04-9710-32cea62d1fad", "romnr": 1857, "plasser": 243, "adresse": "KONGENSGATE 2", @@ -464,7 +464,7 @@ "longitude": 7.99551 }, { - "lokalId": "99c2e1ad-8b17-46d7-87dd-037117fc4f75", + "lokalId": "edc72bea-cf36-451b-b170-b476eeec6426", "romnr": 1874, "plasser": 191, "adresse": "KRISTIAN 4. DES GATE 35-37", @@ -472,7 +472,7 @@ "longitude": 7.991811 }, { - "lokalId": "a7cd6fa4-50d7-4e46-b8fc-0599b7c0684f", + "lokalId": "4e9a08dc-3d65-47b3-8c15-c5de6881ae35", "romnr": 1890, "plasser": 120, "adresse": "LINDEBØSKOGEN", @@ -480,7 +480,7 @@ "longitude": 7.999181 }, { - "lokalId": "322932aa-f80d-4e72-a83a-ce259a89a397", + "lokalId": "03b02073-23a6-4c11-a91b-1c223992107b", "romnr": 1895, "plasser": 95, "adresse": "MAGNUS BARFOTSVEI 7", @@ -488,7 +488,7 @@ "longitude": 8.043248 }, { - "lokalId": "bf826545-0846-44f3-84fc-814eec51c5f0", + "lokalId": "bb5024c0-2f4b-4d06-a14a-b303f6a96554", "romnr": 1897, "plasser": 360, "adresse": "MALMVEIEN 4", @@ -496,7 +496,7 @@ "longitude": 7.955773 }, { - "lokalId": "532a6aae-032a-4dd3-9540-ed3eaf7b2d44", + "lokalId": "220975db-805c-47be-8f5c-f1d8347fb4e1", "romnr": 1908, "plasser": 330, "adresse": "MARKENSGATE 42", @@ -504,7 +504,7 @@ "longitude": 7.990485 }, { - "lokalId": "5ff2b3ed-e6e0-44ab-83ab-13008e7c08e2", + "lokalId": "3e57e145-ef25-4c2f-9936-6375a73e8437", "romnr": 1919, "plasser": 200, "adresse": "MÆBØ", @@ -512,7 +512,7 @@ "longitude": 8.00126 }, { - "lokalId": "492f0ddc-fdff-4b0f-aff2-42a975d8fdf7", + "lokalId": "29b4594e-ec11-46d4-93f9-72ba916396e6", "romnr": 1922, "plasser": 300, "adresse": "MØLLEVANNSVEIEN 50", @@ -520,7 +520,7 @@ "longitude": 7.970139 }, { - "lokalId": "8c063d0a-8a57-484d-b3c5-6285fa0efc8c", + "lokalId": "5d542477-0899-46bc-86fc-39eca14198bf", "romnr": 1931, "plasser": 220, "adresse": "ODDERHEI 1", @@ -528,7 +528,7 @@ "longitude": 8.076467 }, { - "lokalId": "67da452e-4a66-40b8-a13e-d9244d63197e", + "lokalId": "9aab10db-de50-4d7d-a457-fec63c690ef0", "romnr": 1938, "plasser": 230, "adresse": "PRESTHEIA 10", @@ -536,7 +536,7 @@ "longitude": 8.010932 }, { - "lokalId": "d6095314-c5eb-4066-b20e-aa617f6ad2e8", + "lokalId": "53d4153b-5c36-4aa2-ae76-ce670116fe49", "romnr": 1951, "plasser": 170, "adresse": "RØDSTRUPEVEIEN 17", @@ -544,7 +544,7 @@ "longitude": 7.960984 }, { - "lokalId": "da484bb2-229e-422c-8343-8752f72768b5", + "lokalId": "bb54a22c-b51a-4ee6-8975-695439114e04", "romnr": 1971, "plasser": 170, "adresse": "SKIBÅSEN 2", @@ -552,7 +552,7 @@ "longitude": 8.126058 }, { - "lokalId": "9338937c-5210-4195-aea9-2789f6f91241", + "lokalId": "d6ef1426-25cd-4eea-a266-a5822eeedde4", "romnr": 1998, "plasser": 70, "adresse": "SLETTHEIVEIEN 63 B", @@ -560,7 +560,7 @@ "longitude": 7.935866 }, { - "lokalId": "c03754b0-168e-45ae-af1d-b5466c8b811b", + "lokalId": "62866007-e2f0-4241-94f8-6da05c016cd3", "romnr": 2014, "plasser": 234, "adresse": "STRØMMEVEIEN 85-87", @@ -568,7 +568,7 @@ "longitude": 8.081448 }, { - "lokalId": "7db195b7-25cb-4f84-a0a5-c3e54a44327b", + "lokalId": "3124dadb-9d41-4089-a676-7330616ba17a", "romnr": 2057, "plasser": 130, "adresse": "VARDÅSVEIEN 115/117", @@ -576,7 +576,7 @@ "longitude": 8.059191 }, { - "lokalId": "f0e4671e-497b-47ec-b237-afdae17d1e95", + "lokalId": "05857220-a479-4ae5-90b6-624e966eff52", "romnr": 2082, "plasser": 150, "adresse": "VIGVOLLÅSEN 16", @@ -584,7 +584,7 @@ "longitude": 8.088489 }, { - "lokalId": "20dfa406-488e-4efa-98cb-ca51e83088de", + "lokalId": "b0f8ff66-d477-49e9-a1df-64919beb1f4d", "romnr": 2083, "plasser": 150, "adresse": "VOIE RINGVEI 108", @@ -592,7 +592,7 @@ "longitude": 7.947829 }, { - "lokalId": "6eb44464-e192-4a2c-8647-cdb83df46912", + "lokalId": "4e1a51fe-46d3-4b43-b93a-67092a82c4cb", "romnr": 2091, "plasser": 120, "adresse": "ØSTERVEIEN 30 B", @@ -600,7 +600,7 @@ "longitude": 8.009103 }, { - "lokalId": "d1a161a1-7d18-466b-ae1d-b1c3b9ab2b19", + "lokalId": "6d475546-bab6-4adf-9dc4-8cad4424cd6d", "romnr": 2094, "plasser": 220, "adresse": "ØSTERØYA 8", @@ -608,7 +608,7 @@ "longitude": 8.001411 }, { - "lokalId": "5f373b9c-5b99-4a5a-8005-bb32b11f1e60", + "lokalId": "e9769566-afa2-4bb2-9f1a-1041dc41cf96", "romnr": 2098, "plasser": 190, "adresse": "ØSTRE RINGVEI 8", @@ -616,7 +616,7 @@ "longitude": 8.021041 }, { - "lokalId": "7e9704ce-7521-4856-b88b-b8102309fad0", + "lokalId": "e74b84fb-bd81-43ce-8089-01707c94c452", "romnr": 2104, "plasser": 100, "adresse": "ØSTRE STRANDGATE 67", @@ -624,7 +624,7 @@ "longitude": 8.006068 }, { - "lokalId": "2e3a4c51-7250-47c9-a05f-37e41c33f61e", + "lokalId": "44eec398-9b99-4c05-ae69-2900378557b4", "romnr": 2108, "plasser": 360, "adresse": "ØVRE BRATTBAKKEN 1", @@ -632,7 +632,7 @@ "longitude": 8.091319 }, { - "lokalId": "b4d4e635-6e81-497c-b57c-15ec289d7977", + "lokalId": "4d0052cc-c067-4063-bab4-660a023afa47", "romnr": 2127, "plasser": 235, "adresse": "TANGVALL", @@ -640,7 +640,7 @@ "longitude": 7.814256 }, { - "lokalId": "84870d27-4956-425a-8579-50af0887c129", + "lokalId": "e1dfb208-5b6f-43f7-bbf9-4103d032b84e", "romnr": 2128, "plasser": 133, "adresse": "TANGVALL", @@ -648,7 +648,7 @@ "longitude": 7.814256 }, { - "lokalId": "2f61f1be-c1f8-49df-b310-adccb913b228", + "lokalId": "e6ea26e2-6ddc-4102-a306-74bbf9b45b04", "romnr": 2180, "plasser": 235, "adresse": "SKOLEVEGEN 9", @@ -656,7 +656,7 @@ "longitude": 7.9773 }, { - "lokalId": "4566c24b-3815-4246-a4a4-53111e239b6b", + "lokalId": "e8dbfd95-8f55-4011-9021-6f75a9ca7c0e", "romnr": 2183, "plasser": 75, "adresse": "Drivenesvegen 24", @@ -664,7 +664,7 @@ "longitude": 7.964487 }, { - "lokalId": "6e916337-a9da-4549-ab0f-c2b948f24416", + "lokalId": "c5eeeee2-c907-4429-9eb2-e09810bdd24b", "romnr": 2197, "plasser": 100, "adresse": "BURÅSVEIEN 59", @@ -672,7 +672,7 @@ "longitude": 7.434499 }, { - "lokalId": "954002a0-01e0-4497-a6a5-e343bd3a3108", + "lokalId": "f27e0bc6-73e2-4fe0-bff4-f601fe6010cb", "romnr": 2205, "plasser": 150, "adresse": "HOLBÆK ERIKSENSGATE 10", @@ -680,7 +680,7 @@ "longitude": 7.460786 }, { - "lokalId": "7cc0bc51-b655-49a8-9766-f14526f994c1", + "lokalId": "d068aec2-989e-4be6-889d-32af9131d371", "romnr": 2224, "plasser": 60, "adresse": "SOMMERKROVEIEN 18", @@ -688,7 +688,7 @@ "longitude": 7.472404 }, { - "lokalId": "950e1cff-2b5b-43a0-8c34-3cd98463e881", + "lokalId": "2ba69ac5-ab7a-4e48-95af-0639b054bdab", "romnr": 2254, "plasser": 400, "adresse": "SELJEVEIEN 60", @@ -696,7 +696,7 @@ "longitude": 7.490129 }, { - "lokalId": "7665fcb4-0b50-4df2-b4d6-374ec1dd6a0b", + "lokalId": "0f212d42-5414-4f95-9989-e3cffd577f95", "romnr": 2286, "plasser": 30, "adresse": "STÅLESEN BYGG AS-AUTOHALLEN Vanse", @@ -704,7 +704,7 @@ "longitude": 6.69617 }, { - "lokalId": "cf44933f-c1e9-4071-99fa-5cfbcf1ec5c0", + "lokalId": "c8800040-7eb9-4be6-93c7-eca81378e0af", "romnr": 2293, "plasser": 100, "adresse": "SVEGESKOGEN 17", @@ -712,7 +712,7 @@ "longitude": 6.643839 }, { - "lokalId": "a9169e28-4828-44e0-b409-1b4ba4e990a8", + "lokalId": "6ffa851d-a172-4705-8186-cf631c436d73", "romnr": 2306, "plasser": 220, "adresse": "Urgata 2", @@ -720,7 +720,7 @@ "longitude": 6.665628 }, { - "lokalId": "415201ca-7e6a-4f32-8b30-be2f5987547d", + "lokalId": "b375cc00-79b3-4799-b143-bc9e70c49aec", "romnr": 2310, "plasser": 190, "adresse": "RAULIVEIEN 2", @@ -728,7 +728,7 @@ "longitude": 6.669011 }, { - "lokalId": "1c859126-a2df-4603-83da-be76ba1e160d", + "lokalId": "35c0e08b-0826-40b2-8ad5-aee11dfad630", "romnr": 2344, "plasser": 35, "adresse": "ROSFJORD", @@ -736,7 +736,7 @@ "longitude": 7.058307 }, { - "lokalId": "2f023362-b3c7-4654-9e33-fdff01e03fa6", + "lokalId": "69f184eb-d11a-409d-bde1-5ae7f085197e", "romnr": 2468, "plasser": 160, "adresse": "Myraveien 2 (Brannstasjonen)", @@ -744,7 +744,7 @@ "longitude": 14.148941 }, { - "lokalId": "49a011ae-4543-4c6a-8f35-bc40a8b5a0e5", + "lokalId": "695d0f6d-f768-496f-b4ee-3ccb4dc00e07", "romnr": 2483, "plasser": 230, "adresse": "Kveldssolgata 99 (Hauknes skole - offentlig)", @@ -752,7 +752,7 @@ "longitude": 14.054265 }, { - "lokalId": "19e029c6-95a8-4242-acab-a00c37d84356", + "lokalId": "1383b84e-8a8e-4025-9c81-1ef5261df5c6", "romnr": 2502, "plasser": 415, "adresse": "Alstadveien 19, Alstad Ungdomsskole", @@ -760,7 +760,7 @@ "longitude": 14.486811 }, { - "lokalId": "fdabca67-bd03-4934-a950-0ad808126aba", + "lokalId": "5e0030a0-1809-407a-b7f6-4acbf9620cf9", "romnr": 2506, "plasser": 160, "adresse": "Salten gummiservice A/S, Tømrerveien 8", @@ -768,7 +768,7 @@ "longitude": 14.400001 }, { - "lokalId": "6a75dbe5-12d6-4758-82be-bbdd6a482434", + "lokalId": "63c40be6-d000-4a26-86b1-0c6aae59f534", "romnr": 2519, "plasser": 600, "adresse": "Gråholten", @@ -776,7 +776,7 @@ "longitude": 14.378414 }, { - "lokalId": "bed1bd5e-2f13-474a-a4c1-f45a47263210", + "lokalId": "e3cecb89-2f96-4b15-a4fd-0594ad8a011f", "romnr": 2521, "plasser": 340, "adresse": "Torvet, Sjøgaten, Bodø", @@ -784,7 +784,7 @@ "longitude": 14.381687 }, { - "lokalId": "5b255d31-093a-4ff2-b686-5a9085ae1341", + "lokalId": "f50c60a9-c5c5-4788-a1eb-b9dfcd167c1d", "romnr": 2522, "plasser": 520, "adresse": "Holstbakken Alta", @@ -792,7 +792,7 @@ "longitude": 23.301067 }, { - "lokalId": "66084972-7d02-4076-95c3-9c2384a3ce63", + "lokalId": "1733563e-fe25-4532-b8d0-74667a591861", "romnr": 2524, "plasser": 1154, "adresse": "Rensås Syd, Bodø", @@ -800,7 +800,7 @@ "longitude": 14.40508 }, { - "lokalId": "a530f56d-cbce-493c-ada9-53294b01b9ac", + "lokalId": "809c4e50-923c-481d-982c-b24199612b81", "romnr": 2525, "plasser": 300, "adresse": "Dreyfushammaren, Burøyveien, Bodø", @@ -808,7 +808,7 @@ "longitude": 14.395184 }, { - "lokalId": "bfca52a9-e485-4a79-81d5-35b603cfd896", + "lokalId": "6f3345b4-2c3f-496b-92c7-a96d92d229f7", "romnr": 2527, "plasser": 500, "adresse": "Rensås Nord, Parkveien, Bodø", @@ -816,7 +816,7 @@ "longitude": 14.400086 }, { - "lokalId": "34fdefbc-3ae6-4b1d-8c9c-46e40cdecd5b", + "lokalId": "c4b24201-f8ce-41b0-87ff-d98ca5a534c4", "romnr": 2571, "plasser": 450, "adresse": "Gymnaset, Gymnasveien 5, Fauske", @@ -824,7 +824,7 @@ "longitude": 15.375249 }, { - "lokalId": "869bc6c8-7c6a-4559-bfce-6963f3ce8a2f", + "lokalId": "7e3aa8ef-c652-4799-b749-a623a931fb66", "romnr": 2625, "plasser": 410, "adresse": "Strandgata 20", @@ -832,7 +832,7 @@ "longitude": 14.132171 }, { - "lokalId": "95c6d533-2997-4897-b08c-77817319bae6", + "lokalId": "492ee2fd-c7c0-4ae5-b599-09be179cdfd8", "romnr": 2645, "plasser": 320, "adresse": "Selfors Barneskole", @@ -840,7 +840,7 @@ "longitude": 14.180946 }, { - "lokalId": "1e166204-285b-4e51-b0a1-342925bc8851", + "lokalId": "a16bfd5d-b2ae-46fa-a9cd-9c01cb5dd602", "romnr": 2662, "plasser": 240, "adresse": "Ytteren Somatiske sykehjem - off.", @@ -848,7 +848,7 @@ "longitude": 14.138547 }, { - "lokalId": "9c663030-0d50-4b2b-adac-68f4efdd4ca0", + "lokalId": "3b033df7-5d60-4bc4-989a-c1575b09fad9", "romnr": 3247, "plasser": 600, "adresse": "Flintergata 6", @@ -856,7 +856,7 @@ "longitude": 5.733833 }, { - "lokalId": "8860fab7-f876-43c3-bd76-072d886d0fb1", + "lokalId": "afb461aa-7d5f-435b-9c75-0db2bec80b56", "romnr": 3249, "plasser": 420, "adresse": "Roald Amundsens gate 28A", @@ -864,7 +864,7 @@ "longitude": 5.743306 }, { - "lokalId": "62cc4598-9caf-42dd-b0ee-d2c5b4662063", + "lokalId": "f7491454-cb9f-4e88-823b-7873c388da6b", "romnr": 3255, "plasser": 155, "adresse": "Nikkelveien 13", @@ -872,7 +872,7 @@ "longitude": 5.731038 }, { - "lokalId": "ae844a34-00e7-463c-af2b-232a37ab3024", + "lokalId": "f354e142-92c4-4437-9672-734d23c5dbbb", "romnr": 3289, "plasser": 20, "adresse": "Sjøveien 4", @@ -880,7 +880,7 @@ "longitude": 5.745893 }, { - "lokalId": "11dad206-5544-461f-8e97-591c92d56e04", + "lokalId": "5373c5cc-dbf9-4bfa-84d6-434b4526cf22", "romnr": 3325, "plasser": 80, "adresse": "Iglemyrveien 3", @@ -888,7 +888,7 @@ "longitude": 5.756187 }, { - "lokalId": "c2bd8ed7-1656-4e91-964c-4452714d2a8b", + "lokalId": "07329dda-4fa0-4bc9-8110-b6b9305adbb0", "romnr": 3553, "plasser": 138, "adresse": "Moafjæra 1d", @@ -896,7 +896,7 @@ "longitude": 11.28213 }, { - "lokalId": "9782250a-c7d5-4742-b770-883908b08f30", + "lokalId": "7d55519c-06c6-4f91-babc-76792c58a329", "romnr": 3680, "plasser": 110, "adresse": "Wergelandsveien 27", @@ -904,7 +904,7 @@ "longitude": 10.914986 }, { - "lokalId": "1918f122-3286-49b4-a812-c44ec3142ff9", + "lokalId": "e38f2654-3c0d-464c-9f11-612f4577647d", "romnr": 4005, "plasser": 98, "adresse": "Haugen 25", @@ -912,7 +912,7 @@ "longitude": 5.726609 }, { - "lokalId": "293c692f-46d9-4499-a620-2dc535fb16c3", + "lokalId": "c54dacad-3b74-44bf-a914-6b0aaf32fd22", "romnr": 4008, "plasser": 225, "adresse": "Somaveien 4", @@ -920,7 +920,7 @@ "longitude": 5.725455 }, { - "lokalId": "a8c44d20-fc0d-4207-ac12-b072681c0c37", + "lokalId": "6d8f9cce-cd2b-4f18-9852-710f518c3cbe", "romnr": 4013, "plasser": 570, "adresse": "Olabakken 2", @@ -928,7 +928,7 @@ "longitude": 5.713467 }, { - "lokalId": "68d1e0ad-6982-4165-b28a-e0b41e2e9839", + "lokalId": "78896660-e23c-4fc6-9bbb-e083f79fe7b7", "romnr": 4026, "plasser": 241, "adresse": "Luramyrveien 61", @@ -936,7 +936,7 @@ "longitude": 5.726643 }, { - "lokalId": "7870d7f3-4dd5-44cd-8c51-2d4430f72772", + "lokalId": "52fc7519-90a7-46e5-ad0b-93db4a75d60c", "romnr": 4193, "plasser": 230, "adresse": "Samuel J. Sandveds vei 16", @@ -944,7 +944,7 @@ "longitude": 5.72609 }, { - "lokalId": "f47bc94b-74be-48fa-bdfa-4a275ba195c2", + "lokalId": "d9a2d225-04ce-4561-80ed-1fff302c31de", "romnr": 4194, "plasser": 200, "adresse": "Smørbukkveien 11", @@ -952,7 +952,7 @@ "longitude": 5.734584 }, { - "lokalId": "bc723bec-c1b1-4a3d-accb-b4faedcf87af", + "lokalId": "2d672391-f829-4c2c-8a77-57465a8da215", "romnr": 4241, "plasser": 150, "adresse": "Damsgårdsgaten 4A", @@ -960,7 +960,7 @@ "longitude": 6.006291 }, { - "lokalId": "23c43b1b-f74a-4252-8c5a-3c90ebf7aa4b", + "lokalId": "b32003ab-77df-429a-868d-b26026583f64", "romnr": 4291, "plasser": 235, "adresse": "Sam Eydesgt. 163, IINGOLFLAND SKOLE", @@ -968,7 +968,7 @@ "longitude": 8.614609 }, { - "lokalId": "4b805b16-49fd-4688-8965-290cb14c5462", + "lokalId": "31258a10-dd0a-4bf8-987e-952a3a79af0e", "romnr": 4303, "plasser": 200, "adresse": "Kaiveien 23", @@ -976,7 +976,7 @@ "longitude": 5.85136 }, { - "lokalId": "b68f5c59-30ba-4ea1-8263-64749ad93e58", + "lokalId": "f027f937-41b1-45c3-86f1-42cde82211f0", "romnr": 4305, "plasser": 200, "adresse": "Kaiveien 25", @@ -984,7 +984,7 @@ "longitude": 5.851264 }, { - "lokalId": "020ca2ab-af00-43e3-8cc2-d7b9340ef717", + "lokalId": "f063dbbb-24b9-43eb-8cf2-671735a63fa8", "romnr": 4695, "plasser": 100, "adresse": "Skansen kjøpesenter, T. Kveldulvsons gate 24", @@ -992,7 +992,7 @@ "longitude": 12.635415 }, { - "lokalId": "f98f0b93-efa2-48b3-8ff2-0ca06d6f8b8b", + "lokalId": "cab5cdaa-d877-42aa-9ffc-55f4d84f3b7b", "romnr": 4703, "plasser": 120, "adresse": "Skole/Samfunnshus, Skolegata 1", @@ -1000,7 +1000,7 @@ "longitude": 12.211094 }, { - "lokalId": "b703762b-dbd7-4eba-9555-65dd8ae97d0c", + "lokalId": "fd2fc00e-2633-4756-9ed2-696eeb580237", "romnr": 4741, "plasser": 736, "adresse": "Mysenhallen/ Smedgata 19", @@ -1008,7 +1008,7 @@ "longitude": 11.333741 }, { - "lokalId": "d7e76a10-635a-472f-89d6-d115536d9122", + "lokalId": "7a29db15-2ed2-4bb2-8243-6685cf14cbc4", "romnr": 4855, "plasser": 300, "adresse": "Karsches gate 3 \"Tilflukt\"", @@ -1016,7 +1016,7 @@ "longitude": 9.651787 }, { - "lokalId": "58dc9f73-9d2e-463f-bf2f-b2cbf87a4ff8", + "lokalId": "2e848d86-1d19-47e2-ba55-01bfea3f6fc0", "romnr": 4908, "plasser": 172, "adresse": "Soknedalsveien 7", @@ -1024,7 +1024,7 @@ "longitude": 10.243451 }, { - "lokalId": "ae3be434-c0db-4985-8440-eecb9ac6fa8e", + "lokalId": "85e766a0-3bbb-49c1-a039-38e5010e6d44", "romnr": 4963, "plasser": 537, "adresse": "Betzy Kjelsbergs vei 182", @@ -1032,7 +1032,7 @@ "longitude": 10.131048 }, { - "lokalId": "abd7d06c-3cee-403a-bb4a-a051c14b109d", + "lokalId": "861ae00b-36a5-4f86-8924-9e24eb4a1772", "romnr": 4969, "plasser": 1200, "adresse": "Prins Oscarsgate / Brantenborg.", @@ -1040,7 +1040,7 @@ "longitude": 10.221617 }, { - "lokalId": "41edbd5e-744d-4fd8-9ff8-604014e36945", + "lokalId": "4fa39b5a-4c4f-4557-a674-22f554d8c258", "romnr": 5463, "plasser": 600, "adresse": "Nedre Tverrgate 1 - Nedre Eiker Samfunnshus", @@ -1048,7 +1048,7 @@ "longitude": 10.012376 }, { - "lokalId": "aa0c74f3-6a5b-4801-b4ab-154118afa078", + "lokalId": "d6d1c384-c63e-47c9-b5bd-9e739c9ff942", "romnr": 5617, "plasser": 385, "adresse": "Stasjonsgata 24", @@ -1056,7 +1056,7 @@ "longitude": 9.908552 }, { - "lokalId": "185a05cb-c4f7-403d-bfad-eab4fc8e840e", + "lokalId": "9bd49ba0-4e36-4c5a-946a-0c2e9050d5f8", "romnr": 5630, "plasser": 320, "adresse": "Hellefoss veien 2", @@ -1064,7 +1064,7 @@ "longitude": 9.908353 }, { - "lokalId": "77d3f950-9162-4456-8551-ff64806be211", + "lokalId": "d29dc15f-aff3-44ed-ad9a-caea87f84a05", "romnr": 5647, "plasser": 220, "adresse": "Skotselvveien 29", @@ -1072,7 +1072,7 @@ "longitude": 9.898972 }, { - "lokalId": "5a4154aa-678c-4e79-b1c3-9651aaf1d70a", + "lokalId": "7b0dbece-4fe0-458f-b472-00b1b716213a", "romnr": 5652, "plasser": 14, "adresse": "Havnegt.16", @@ -1080,7 +1080,7 @@ "longitude": 11.494325 }, { - "lokalId": "3f2b574d-d0f8-4fc5-8659-4570c33c0edb", + "lokalId": "211ca2e0-91dc-4b13-8e00-c03d2495c130", "romnr": 5653, "plasser": 25, "adresse": "Abel Meyers gate 3", @@ -1088,7 +1088,7 @@ "longitude": 11.494884 }, { - "lokalId": "191f5c70-7f01-4457-ac9f-eef16da90c4f", + "lokalId": "bbe1305e-2b55-497d-97fe-348b6c986d3a", "romnr": 5655, "plasser": 60, "adresse": "Overh.vn.8", @@ -1096,7 +1096,7 @@ "longitude": 11.50363 }, { - "lokalId": "ae27f566-5ac9-4763-982f-4e2baac9662d", + "lokalId": "3ad10bd4-74d8-4d6d-88a7-1c6bf9cc55b0", "romnr": 5656, "plasser": 70, "adresse": "Kirkegt.5", @@ -1104,7 +1104,7 @@ "longitude": 11.49507 }, { - "lokalId": "240ca620-f28a-44e8-94aa-ac368ba1f469", + "lokalId": "e0a0bf9a-8d95-468b-8d7e-6d7348d898b8", "romnr": 5657, "plasser": 78, "adresse": "Strandvn.7", @@ -1112,7 +1112,7 @@ "longitude": 11.479279 }, { - "lokalId": "fb140d42-3b57-4a12-a1f9-f5d64e99cc9f", + "lokalId": "63321d0c-9d2c-4cdd-9a60-69e62c0f1d8c", "romnr": 5658, "plasser": 15, "adresse": "Abel Meyers gate 21", @@ -1120,7 +1120,7 @@ "longitude": 11.497318 }, { - "lokalId": "1d3d72ef-7cd1-49c8-9e84-5f381828ebca", + "lokalId": "1ab56503-09b5-4b45-bcb6-879f8cf91286", "romnr": 5732, "plasser": 2000, "adresse": "Jarl Hildrums veg 6, Kleppen", @@ -1128,7 +1128,7 @@ "longitude": 11.521925 }, { - "lokalId": "9b602ba9-0351-45e6-85c9-b6901c7bf2b3", + "lokalId": "3183104d-6a58-42c2-8b6d-888278c776ed", "romnr": 5815, "plasser": 400, "adresse": "Sundelinveien 72 (Sandnes Skole)", @@ -1136,7 +1136,7 @@ "longitude": 29.952576 }, { - "lokalId": "30d5dd6f-4e44-4258-9d14-dd6268f965a0", + "lokalId": "7dc68b82-15e5-476c-b355-323e1c842cc4", "romnr": 5832, "plasser": 340, "adresse": "Rådhuset, Sivert Nilsensgate 24", @@ -1144,7 +1144,7 @@ "longitude": 12.205777 }, { - "lokalId": "4216edda-adcf-4e28-9cad-cb360eeb18cf", + "lokalId": "527c37b1-68be-4e54-8983-9ec4cb9e34ed", "romnr": 5962, "plasser": 230, "adresse": "Gåsungen Barnehage - Gåsåsen 20", @@ -1152,7 +1152,7 @@ "longitude": 8.747527 }, { - "lokalId": "c665543f-ff90-458b-a4cf-1f9d7d57c108", + "lokalId": "a22d3aea-a7c5-4884-8677-b2824a1e3b0c", "romnr": 6056, "plasser": 35, "adresse": "Birkenes kommunehus - Smedens Kjerr 30", @@ -1160,7 +1160,7 @@ "longitude": 8.23294 }, { - "lokalId": "dc509365-2c71-47e7-9f21-c22dc2cda05c", + "lokalId": "8a64b78d-0d3f-474f-b6d9-e922bede69ad", "romnr": 6074, "plasser": 20, "adresse": "Herefoss Skole - Torsbumoen 14", @@ -1168,7 +1168,7 @@ "longitude": 8.353128 }, { - "lokalId": "d1baaff4-6b80-43ff-b55c-5c8fcc7e55b4", + "lokalId": "9bdd5fe6-bb50-4eb8-a29c-927f7ec4be64", "romnr": 6157, "plasser": 240, "adresse": "Risør Idrettshall - Caspersens vei 25", @@ -1176,7 +1176,7 @@ "longitude": 9.215198 }, { - "lokalId": "af2660f5-e13b-4dcd-8acf-93b9e5b2b076", + "lokalId": "0a9769dc-6126-484c-907e-1cba2a96d2e4", "romnr": 6160, "plasser": 470, "adresse": "Risør videregående skole - Sirisveien 8 Blokk A", @@ -1184,7 +1184,7 @@ "longitude": 9.216877 }, { - "lokalId": "b55d268f-6bed-478a-8500-c70d7513e4e7", + "lokalId": "70dd23eb-e4df-4ff3-bf3f-37cea0f34944", "romnr": 6206, "plasser": 90, "adresse": "Bjorbekktunet - Off - Bjorbekk - Johan Landmarksve", @@ -1192,7 +1192,7 @@ "longitude": 8.706223 }, { - "lokalId": "9454d973-8531-420d-a170-d57cb7389823", + "lokalId": "475d75c9-70e1-4fae-bd97-4ea43df49263", "romnr": 6207, "plasser": 26, "adresse": "Meny - Off - Stoa - Åsbieveien 2", @@ -1200,7 +1200,7 @@ "longitude": 8.712128 }, { - "lokalId": "ea723bda-d386-44ea-ad71-207950af90d8", + "lokalId": "8e7bcb96-0d34-46f4-963b-eb134da8f2a5", "romnr": 6222, "plasser": 90, "adresse": "Idrettens Hus - Off - Kåre Eriksen A/S - Åsbievn 1", @@ -1208,7 +1208,7 @@ "longitude": 8.720036 }, { - "lokalId": "5516bb9a-4d84-4ea1-b28a-483cf4be508f", + "lokalId": "6eda0e4a-0b7e-48e3-a2be-93386b4693c4", "romnr": 6342, "plasser": 264, "adresse": "Høvågheimen Bo og aktivitetsenter - Høvåg", @@ -1216,7 +1216,7 @@ "longitude": 8.245037 }, { - "lokalId": "1c168707-1644-48ab-9864-4cca2dca14bf", + "lokalId": "0cd74901-d9bb-43fd-a7bd-a13b4c31fe12", "romnr": 6356, "plasser": 28, "adresse": "Lillesand rådhus - Østregate 2", @@ -1224,7 +1224,7 @@ "longitude": 8.378622 }, { - "lokalId": "93e3950b-4523-4147-8646-420a5388dce1", + "lokalId": "954362ee-da73-4686-87f2-c014d1564fd7", "romnr": 6394, "plasser": 1300, "adresse": "Kulturhuset - Hestetorget,Storgaten 33", @@ -1232,7 +1232,7 @@ "longitude": 8.590395 }, { - "lokalId": "f1f92f26-0bf8-4a9c-ba6a-96d311fb4a14", + "lokalId": "e04b93b5-3083-4665-bb28-58d1a78bf321", "romnr": 6442, "plasser": 228, "adresse": "Eide Skole - Johan Markussens vei 90", @@ -1240,7 +1240,7 @@ "longitude": 8.504972 }, { - "lokalId": "3e9b2e4e-307b-4793-8b73-de3d3c53865c", + "lokalId": "3657825f-3bd6-46ed-8de1-7aab054ee9bf", "romnr": 6547, "plasser": 50, "adresse": "Oddensenteret (kjeller) - Vesterled 4", @@ -1248,7 +1248,7 @@ "longitude": 8.592676 }, { - "lokalId": "0040b298-85a8-4ac3-9231-26d042ff50e2", + "lokalId": "51ec875b-7eab-49c9-81f5-c308d9e56bab", "romnr": 6720, "plasser": 400, "adresse": "Froland Idrettshall - Mjølhusmoen - Rislandsvn 10", @@ -1256,7 +1256,7 @@ "longitude": 8.632786 }, { - "lokalId": "43ca8211-7024-40cf-b21c-d41cab8117bd", + "lokalId": "d082330d-2306-4dde-9926-fdddd4ece90c", "romnr": 6749, "plasser": 106, "adresse": "Dønnestadgården - Bibliotekveien 4", @@ -1264,7 +1264,7 @@ "longitude": 8.928731 }, { - "lokalId": "6f8919e3-6a6b-40ce-a5ff-e6c3d45f6bb7", + "lokalId": "57594151-5202-4b8a-8078-286770da7305", "romnr": 6815, "plasser": 2400, "adresse": "Arendalstunnelen - Parkeringstunnell -Torvet/Barb", @@ -1272,7 +1272,7 @@ "longitude": 8.766067 }, { - "lokalId": "0a5cbf36-68c3-459b-a68e-7adc42875cff", + "lokalId": "2cc6b838-2515-42f0-9510-1cde9a043e16", "romnr": 6819, "plasser": 1800, "adresse": "Birkenlundhallen - Kirkefjell 11", @@ -1280,7 +1280,7 @@ "longitude": 8.791073 }, { - "lokalId": "63687f3c-be87-4a69-8bfc-c65f4a18670b", + "lokalId": "9fc18e3e-0ec9-457b-a2e5-92ad409fdf12", "romnr": 6870, "plasser": 630, "adresse": "Westermannsveita 4 Tidl. Nordre gate 1", @@ -1288,7 +1288,7 @@ "longitude": 10.39903 }, { - "lokalId": "5a75f46d-a078-4666-b333-b33b0140b6e7", + "lokalId": "dfab696b-5cc8-4fc4-bd99-26dc6e06afa5", "romnr": 6963, "plasser": 265, "adresse": "Dr.Randersgate 5, Askim", @@ -1296,7 +1296,7 @@ "longitude": 11.160927 }, { - "lokalId": "15d72df6-7510-4d30-96ae-4bed5f112003", + "lokalId": "de4f72b9-dbf7-49c5-a4a2-d48fb247cd6e", "romnr": 6964, "plasser": 260, "adresse": "Dr. Randersgate 2, Askim", @@ -1304,7 +1304,7 @@ "longitude": 11.161255 }, { - "lokalId": "799edf55-2bfc-4855-b34f-b91efafac1b6", + "lokalId": "d6509f8e-bb01-47bc-aac1-1a8e7f07b26a", "romnr": 6966, "plasser": 260, "adresse": "Rom skole/ Gramveien 63A, Askim", @@ -1312,7 +1312,7 @@ "longitude": 11.128584 }, { - "lokalId": "6626ae01-6a88-46bd-8468-690d9ee6d11b", + "lokalId": "a2217c23-4198-4bc6-a3db-c6ecfca498a7", "romnr": 7021, "plasser": 90, "adresse": "endresens vei 4, Varangerbotn", @@ -1320,7 +1320,7 @@ "longitude": 28.558419 }, { - "lokalId": "483bb2ca-ddf9-48f9-8981-03bbd7bd099c", + "lokalId": "3d39efa1-f97e-48ca-a965-c5b21c9fe14e", "romnr": 7098, "plasser": 1079, "adresse": "Melløs stadion, Nordahl Griegsgt 22", @@ -1328,7 +1328,7 @@ "longitude": 10.670078 }, { - "lokalId": "226e3d7e-431a-41c1-905c-baa2e9eb2dca", + "lokalId": "877c7fe4-121e-4ec0-8a6d-48e0bcfd83b4", "romnr": 7103, "plasser": 1000, "adresse": "Blinken/ Jeløgata 3", @@ -1336,7 +1336,7 @@ "longitude": 10.654783 }, { - "lokalId": "36730a9b-b40a-4013-8fc8-d675bb8a0b02", + "lokalId": "5c30c860-d796-4011-8005-995799949080", "romnr": 7105, "plasser": 400, "adresse": "Malakoff vg. skole, Dyreveien 9", @@ -1344,7 +1344,7 @@ "longitude": 10.668656 }, { - "lokalId": "cca467f7-d3a8-423f-88bd-5e46ebfb1830", + "lokalId": "4df26aca-d9d6-4b6a-b406-18fdbfb3877c", "romnr": 7106, "plasser": 250, "adresse": "Reier skole/Brageveien 9", @@ -1352,7 +1352,7 @@ "longitude": 10.63015 }, { - "lokalId": "e049a7a3-46c0-49d8-83b3-0f2ac8b06f0e", + "lokalId": "b61043d2-a5da-482d-8bb1-802062830815", "romnr": 7107, "plasser": 300, "adresse": "Krapfoss skole /Anton Krogsveldsvei 4", @@ -1360,7 +1360,7 @@ "longitude": 10.68175 }, { - "lokalId": "bdc85bd6-a3b6-47ef-8be4-4987bdb4c186", + "lokalId": "a8f138c8-3132-485f-b11a-c4b61547f38f", "romnr": 7114, "plasser": 450, "adresse": "Parkeringshus Piasenteret/ Møllergata 1", @@ -1368,7 +1368,7 @@ "longitude": 10.667859 }, { - "lokalId": "f8e069a3-b2a0-449d-b083-6d94cb7bc955", + "lokalId": "4b4f1ac6-f54f-4a31-843d-e4d0e1b6dd85", "romnr": 7158, "plasser": 168, "adresse": "Wilh Bugges Veg 5", @@ -1376,7 +1376,7 @@ "longitude": 6.075034 }, { - "lokalId": "bb7be8ae-e375-44bd-b3f8-6c2f2f37ca5b", + "lokalId": "e5686d8f-5ed9-4101-8873-569fcc88214b", "romnr": 7254, "plasser": 122, "adresse": "Haugevegen 31", @@ -1384,7 +1384,7 @@ "longitude": 5.263855 }, { - "lokalId": "7d4ffef2-7cec-4ffc-8b83-b5f67b5e26d6", + "lokalId": "6396af8e-4d8b-4671-8d2c-a703bf2b3fc8", "romnr": 7270, "plasser": 78, "adresse": "Storbukt Skole Honningsvåg", @@ -1392,7 +1392,7 @@ "longitude": 25.980348 }, { - "lokalId": "6fa14e4f-c7d5-421e-b6a4-2c992cd860c0", + "lokalId": "d1202174-508f-4ff6-b942-a2324b189f95", "romnr": 7409, "plasser": 448, "adresse": "Baksalen Skole Hammerfest", @@ -1400,7 +1400,7 @@ "longitude": 23.705373 }, { - "lokalId": "8d2f8e12-7b54-4406-b3c2-901d4d7ca1ff", + "lokalId": "60989f45-ba19-4650-9464-dbfa88a02b4a", "romnr": 7411, "plasser": 400, "adresse": "Reindalen skole", @@ -1408,7 +1408,7 @@ "longitude": 23.700527 }, { - "lokalId": "51b58414-4cd3-4366-a8f9-461e1de8f2cc", + "lokalId": "28860cf8-d97b-4996-9360-109b55459bf2", "romnr": 7412, "plasser": 228, "adresse": "Bokollektivet Rypefjord", @@ -1416,7 +1416,7 @@ "longitude": 23.677216 }, { - "lokalId": "f8afc4ca-cfb9-4311-8b45-57852ccf038b", + "lokalId": "358e0ecb-70fd-4208-88bb-04fb0d232667", "romnr": 7413, "plasser": 622, "adresse": "Sivilforsvarets lager Nybakken 9 Hammerfest", @@ -1424,7 +1424,7 @@ "longitude": 23.692815 }, { - "lokalId": "de6da9d8-07d6-4b77-9cb1-6da2a45e0e33", + "lokalId": "288cc423-988f-410d-8d2e-f9a7802b9a92", "romnr": 7436, "plasser": 211, "adresse": "Porsanger Rådhus Lakselv", @@ -1432,7 +1432,7 @@ "longitude": 24.956483 }, { - "lokalId": "e74a5f0f-2f8b-4573-bc00-86f76e58fc8b", + "lokalId": "c02ef7c2-d74a-4990-aeaa-b4c118dda7ed", "romnr": 7438, "plasser": 170, "adresse": "Flerbrukshallen Lakselv", @@ -1440,7 +1440,7 @@ "longitude": 24.967072 }, { - "lokalId": "b9c2ce15-8f3c-42f9-a82b-12a969dc7f9c", + "lokalId": "596c264d-aab3-4f7b-866b-5ba65dee9bc1", "romnr": 7443, "plasser": 280, "adresse": "Helsetun Lakselv", @@ -1448,7 +1448,7 @@ "longitude": 24.952458 }, { - "lokalId": "7af66c10-dded-4578-9fd7-1c1a995cd4af", + "lokalId": "73bd6fc0-e5db-4655-b084-7542bacdba8f", "romnr": 7464, "plasser": 570, "adresse": "Idrettsanlegg Honningsvåg", @@ -1456,7 +1456,7 @@ "longitude": 25.97941 }, { - "lokalId": "29e7d3f9-024c-4be4-871d-b8a9c27639e8", + "lokalId": "f0518be6-b313-4228-bba1-1887f1130009", "romnr": 7574, "plasser": 130, "adresse": "Brubakken 2", @@ -1464,7 +1464,7 @@ "longitude": 10.461766 }, { - "lokalId": "fed6eff0-1d85-4cf4-8e25-79db88c43193", + "lokalId": "16dfb5f3-344e-4d6a-8232-e6423a242db2", "romnr": 7856, "plasser": 550, "adresse": "Storgata 10", @@ -1472,7 +1472,7 @@ "longitude": 10.69013 }, { - "lokalId": "77af968f-88ce-439e-88a9-61f105a70f48", + "lokalId": "5d3d519b-7879-4292-a590-be234f330a2b", "romnr": 7956, "plasser": 65, "adresse": "Mattisrudsvingen 9", @@ -1480,7 +1480,7 @@ "longitude": 10.648554 }, { - "lokalId": "bdf7f784-6c98-410e-b388-144da1e6b15c", + "lokalId": "7d760c4f-9154-4423-9e24-d49992c7dd8f", "romnr": 8044, "plasser": 30, "adresse": "Rosteinvegen 7", @@ -1488,7 +1488,7 @@ "longitude": 10.055507 }, { - "lokalId": "03464253-44f2-4407-a1d5-150c0f0f49a2", + "lokalId": "3cb00761-8e74-4b6f-818b-15be08b1e4a1", "romnr": 8050, "plasser": 550, "adresse": "Prøvenvegen 65", @@ -1496,7 +1496,7 @@ "longitude": 10.605248 }, { - "lokalId": "81c435a1-b0aa-426e-aafc-504a2081072f", + "lokalId": "ad46412f-ec41-4fcd-8841-0de4c3eccc3f", "romnr": 8060, "plasser": 50, "adresse": "Jørstadmovegen 690", @@ -1504,7 +1504,7 @@ "longitude": 10.391659 }, { - "lokalId": "e7d7298e-5a53-4aee-be80-d173feb1e209", + "lokalId": "377724b8-ba52-4786-b546-2b5edbf00771", "romnr": 8061, "plasser": 250, "adresse": "Gudbrandsdalsvegen 190", @@ -1512,7 +1512,7 @@ "longitude": 10.451822 }, { - "lokalId": "1ef9a75e-1d3b-432e-b5b1-ea27d531afa0", + "lokalId": "0ac8dd15-2a9b-4fd6-981b-23f9db73eddb", "romnr": 8062, "plasser": 150, "adresse": "Nordsetervegen 45", @@ -1520,7 +1520,7 @@ "longitude": 10.470935 }, { - "lokalId": "e35a768a-25a8-4492-908a-919cc5488673", + "lokalId": "94f5727a-008c-4de4-a5bf-df88b22aa2c9", "romnr": 8063, "plasser": 300, "adresse": "Jul Pettersens gate 2", @@ -1528,7 +1528,7 @@ "longitude": 10.462682 }, { - "lokalId": "ad26e0b2-7a30-408a-bdb8-175a2b426346", + "lokalId": "b2dee4f0-4f80-4715-bb32-19db5892b24a", "romnr": 8064, "plasser": 616, "adresse": "Kirkegata 74", @@ -1536,7 +1536,7 @@ "longitude": 10.462264 }, { - "lokalId": "42542c87-f569-4a7c-bc6f-a1b79f59a59e", + "lokalId": "32d09ed0-64fe-4a83-93db-df9effea1d5b", "romnr": 8823, "plasser": 650, "adresse": "v/ Seimsdalstunnellen", @@ -1544,7 +1544,7 @@ "longitude": 7.691842 }, { - "lokalId": "2978ebbb-6cdc-4bbc-9f75-2168e1692f4c", + "lokalId": "7702901a-a113-4145-bedd-18c21ef955e9", "romnr": 8825, "plasser": 550, "adresse": "Storevegen 13 (Lykkja )", @@ -1552,7 +1552,7 @@ "longitude": 7.80573 }, { - "lokalId": "948dd61c-c5f9-4da7-9ed9-8187e91d0e58", + "lokalId": "bfc6bb64-a556-4432-8d9b-c1cec4fc381f", "romnr": 9067, "plasser": 30, "adresse": "Petter Dassgt 15", @@ -1560,7 +1560,7 @@ "longitude": 13.196375 }, { - "lokalId": "cb085b04-7a18-43a8-b434-49ed266d72c3", + "lokalId": "ec9316c3-f3d7-4b18-92aa-131630759e0b", "romnr": 9071, "plasser": 40, "adresse": "Strandgt. 31-33 (offentlig)", @@ -1568,7 +1568,7 @@ "longitude": 13.190012 }, { - "lokalId": "e3d132d6-586f-4a7d-9c28-0930ed9e0615", + "lokalId": "b1650771-acb9-44ba-9875-17e988421505", "romnr": 9092, "plasser": 122, "adresse": "Erling Skjalgssons gate 25", @@ -1576,7 +1576,7 @@ "longitude": 5.265106 }, { - "lokalId": "5bae63ac-f45a-48bf-a5a0-0ac2653bbe65", + "lokalId": "b18a35ec-0870-4546-ae75-ff955e51d8c7", "romnr": 9093, "plasser": 220, "adresse": "Spannavegen 135", @@ -1584,7 +1584,7 @@ "longitude": 5.303656 }, { - "lokalId": "071b67c6-d8a9-4061-b118-e2bdf578d28f", + "lokalId": "662c8207-ef97-4d8a-9d42-6aee6af3a80c", "romnr": 9123, "plasser": 200, "adresse": "Kvalamarka 26", @@ -1592,7 +1592,7 @@ "longitude": 5.257753 }, { - "lokalId": "3011fe06-fc9f-4b22-bcc7-6b6216277591", + "lokalId": "54f99efb-1ceb-4aa9-ad10-377f85ddf6a3", "romnr": 9214, "plasser": 265, "adresse": "Skjoldavegen 318", @@ -1600,7 +1600,7 @@ "longitude": 5.329626 }, { - "lokalId": "181e5379-4c7f-416c-b1a7-1efa60123ae5", + "lokalId": "9d310c2d-f528-4435-aec8-67fb4c7a6e56", "romnr": 9357, "plasser": 235, "adresse": "Spannavegen 75", @@ -1608,7 +1608,7 @@ "longitude": 5.298109 }, { - "lokalId": "fcda4c93-242a-47c3-9f9e-a5ecd49e9d58", + "lokalId": "b7349450-c6fc-4417-b988-20db1ffa5215", "romnr": 9398, "plasser": 220, "adresse": "Marker rådhus/ Storgata 60", @@ -1616,7 +1616,7 @@ "longitude": 11.659117 }, { - "lokalId": "e8053161-2c4c-4f14-a6b9-85fd33f17c99", + "lokalId": "db23f986-850a-4eba-a23a-a6d9866afbac", "romnr": 9403, "plasser": 2000, "adresse": "Kulås/ Sandesundveien 10C", @@ -1624,7 +1624,7 @@ "longitude": 11.107723 }, { - "lokalId": "65effa39-a999-4d99-b83b-ec6b2902d06e", + "lokalId": "f0fe5ff4-0f02-4d1e-baee-2c92ec2063ee", "romnr": 9404, "plasser": 900, "adresse": "Spikern/ Alvimveien 19", @@ -1632,7 +1632,7 @@ "longitude": 11.089701 }, { - "lokalId": "0ad6bea2-809b-49fb-b727-d6aba741b399", + "lokalId": "86775732-2cbf-4933-adcb-74bab2d62faf", "romnr": 9405, "plasser": 300, "adresse": "Sagahuset/ Sandesundveien 1", @@ -1640,7 +1640,7 @@ "longitude": 11.108994 }, { - "lokalId": "a8a2befb-6692-4b85-bdbe-2137e220e285", + "lokalId": "53a8caeb-d89c-456d-bfd1-d1d4e0862b25", "romnr": 9407, "plasser": 477, "adresse": "Skjeberg rådhus/ Rådhusveien 17", @@ -1648,7 +1648,7 @@ "longitude": 11.169627 }, { - "lokalId": "c78ee9bb-0063-479e-8953-f954f09109ce", + "lokalId": "79fca62f-7cc7-4d7e-a407-c6df14e5c9c6", "romnr": 9408, "plasser": 89, "adresse": "Dahles bilforretn/ Herbergveien 4", @@ -1656,7 +1656,7 @@ "longitude": 11.087792 }, { - "lokalId": "486751a8-dbe5-4d1e-a0d2-9a44a1467000", + "lokalId": "ce6b3aec-6d6d-4940-ac89-5da7ff9baa27", "romnr": 9410, "plasser": 40, "adresse": "Hafslundsøy skole/ Hagastuveien 60", @@ -1664,7 +1664,7 @@ "longitude": 11.14699 }, { - "lokalId": "5e5cbfb4-1680-4e45-b144-c19f0f39e340", + "lokalId": "b6769100-7699-413a-aa27-91eaa08f5c70", "romnr": 9412, "plasser": 100, "adresse": "Borg bil/ Glomveien 5", @@ -1672,7 +1672,7 @@ "longitude": 11.086135 }, { - "lokalId": "3f50f828-85b0-4649-9efb-9c166b013c6a", + "lokalId": "2c35cceb-0160-4258-bc23-7be5a3e3303e", "romnr": 9413, "plasser": 183, "adresse": "Tingvollheimen aldersheim/ Tuneveien 70", @@ -1680,7 +1680,7 @@ "longitude": 11.074037 }, { - "lokalId": "83e303e1-11d1-4037-b8b1-3d07afe11272", + "lokalId": "dfab5604-bea5-4121-9523-d219683b52e2", "romnr": 9474, "plasser": 388, "adresse": "Håreksgt. 13", @@ -1688,7 +1688,7 @@ "longitude": 13.195049 }, { - "lokalId": "387a6bc7-4a9a-4085-8662-76b48b82c727", + "lokalId": "bd2202da-e852-44b8-b640-ff2ecfd70dda", "romnr": 9505, "plasser": 25, "adresse": "Strandgata 36 (offentlig)", @@ -1696,7 +1696,7 @@ "longitude": 13.190495 }, { - "lokalId": "1b5fb39f-ddbe-4ea9-a178-8715f934434a", + "lokalId": "a2b06bcf-1ce6-4de3-9854-a6dc6be797f6", "romnr": 9508, "plasser": 15, "adresse": "C.M. Havigsgt. 28 (offentlig)", @@ -1704,7 +1704,7 @@ "longitude": 13.191516 }, { - "lokalId": "9333e182-b38c-45f1-822e-12938cdcf0c1", + "lokalId": "3a77a481-4ef2-4f42-9c2c-973576babba0", "romnr": 9517, "plasser": 310, "adresse": "Fearnleysgt. 14 (Mosjøen viderg.skole- off.)", @@ -1712,7 +1712,7 @@ "longitude": 13.193526 }, { - "lokalId": "b7b8a046-c0eb-47de-8065-1460a413c9d4", + "lokalId": "ba25f4f4-ab2b-4b47-a583-1cd712e87083", "romnr": 9521, "plasser": 220, "adresse": "Stortingmannsv. 20 (Kulstad skole - Off.)", @@ -1720,7 +1720,7 @@ "longitude": 13.19978 }, { - "lokalId": "db29b8b3-2944-4d84-8f03-095bb70b42f5", + "lokalId": "eee765e8-2b85-4833-8b3c-0b2543238aa2", "romnr": 9528, "plasser": 172, "adresse": "Olderskog skole - Skule Svendsv. 17", @@ -1728,7 +1728,7 @@ "longitude": 13.217572 }, { - "lokalId": "1f3634c6-a68e-4c55-9a25-dff95e3b9d65", + "lokalId": "cb2a2dfd-8456-4236-ac1e-4cc5c0c1c49d", "romnr": 9529, "plasser": 100, "adresse": "Skjervgata 43 - Rådhuset i Vefsn (off.)", @@ -1736,7 +1736,7 @@ "longitude": 13.199839 }, { - "lokalId": "34a653bc-e887-441a-9b93-f6c89fabe02a", + "lokalId": "9aaa7d4c-009f-4c33-bc59-bb6762df6771", "romnr": 9548, "plasser": 222, "adresse": "Torjus Gards veg 7", @@ -1744,7 +1744,7 @@ "longitude": 5.267023 }, { - "lokalId": "346e80c1-1fb4-4e36-8ade-01875a4b0c5c", + "lokalId": "7e793e87-6b2c-49e6-944e-fe73567dbe00", "romnr": 9550, "plasser": 220, "adresse": "Tittelsnesvegen 332", @@ -1752,7 +1752,7 @@ "longitude": 5.284654 }, { - "lokalId": "b3e6e4fc-b57d-47b9-a7a5-73bd20f87831", + "lokalId": "a4755464-9c17-41ab-a63d-20ff25d92504", "romnr": 9670, "plasser": 500, "adresse": "Florvågvegen 3, Løfjell, Kleppestø", @@ -1760,7 +1760,7 @@ "longitude": 5.228322 }, { - "lokalId": "fff8c7dd-eb9e-48d1-8f74-8fc6d28e8369", + "lokalId": "8ae236a4-a396-44a8-b460-a17d17f8d8e7", "romnr": 9806, "plasser": 65, "adresse": "Kvassnesv. 52 Pb. 157", @@ -1768,7 +1768,7 @@ "longitude": 5.293043 }, { - "lokalId": "d87c6802-023b-4427-90f0-3c3a48a9cdeb", + "lokalId": "3b25160d-7443-4538-b9d6-9fb11e8e1ac5", "romnr": 9852, "plasser": 100, "adresse": "Bu og rehab. senter", @@ -1776,7 +1776,7 @@ "longitude": 5.487313 }, { - "lokalId": "0b36e3c4-23cb-48b7-aecb-523bf296f706", + "lokalId": "68a8b2d2-e20d-4bdc-8944-dddb679393f1", "romnr": 9915, "plasser": 233, "adresse": "Strandavegen 334", @@ -1784,7 +1784,7 @@ "longitude": 6.434672 }, { - "lokalId": "871f4efd-fde7-4fc9-97a8-223dda6cd476", + "lokalId": "38e420ec-f0fb-4327-93db-8be897f0b3e8", "romnr": 9952, "plasser": 698, "adresse": "Miltzowsgt. 2", @@ -1792,7 +1792,7 @@ "longitude": 6.419728 }, { - "lokalId": "bdc42977-f258-47e6-a633-c2af7878611b", + "lokalId": "9d5a5256-2143-41ec-ba55-5627e5e0b0a8", "romnr": 9983, "plasser": 100, "adresse": "Tjørnahaugane 60", @@ -1800,7 +1800,7 @@ "longitude": 6.536621 }, { - "lokalId": "94ba0b4b-c0f2-4632-bbbb-187b38d8d57c", + "lokalId": "9d9599a4-e9c4-4c5c-928f-7008533bfa0b", "romnr": 10113, "plasser": 360, "adresse": "Elvavegen 2, Ytre Arna", @@ -1808,7 +1808,7 @@ "longitude": 5.438147 }, { - "lokalId": "57d2c6a3-1d4b-4e5b-91c2-5c2d4f740445", + "lokalId": "20c4b1e2-c75f-447c-8312-73546d24183c", "romnr": 10212, "plasser": 758, "adresse": "Håkonsgaten 5", @@ -1816,7 +1816,7 @@ "longitude": 5.317521 }, { - "lokalId": "9f18b131-7635-4bad-a9f3-4809a3a83701", + "lokalId": "48455c25-6bf0-474d-bc8c-2d182bc7ab52", "romnr": 10387, "plasser": 600, "adresse": "Kalfarveien 76", @@ -1824,7 +1824,7 @@ "longitude": 5.348519 }, { - "lokalId": "769fc494-b223-4947-8af2-32b56922225d", + "lokalId": "454fc0ea-e08f-4022-a425-a96bfe6eeb6f", "romnr": 10507, "plasser": 500, "adresse": "Nykirkealmenning ovenfor nr 19", @@ -1832,7 +1832,7 @@ "longitude": 5.311762 }, { - "lokalId": "80e3c0ee-5e24-4729-97b8-938a9582ba94", + "lokalId": "dddda065-0cf8-4157-8348-4c64dafec54a", "romnr": 10508, "plasser": 1400, "adresse": "Holbergsalm. v/Strandgt 96", @@ -1840,7 +1840,7 @@ "longitude": 5.316373 }, { - "lokalId": "88d0c98f-6dd0-4ede-bc0d-ef9b08d77050", + "lokalId": "2bff3649-d946-4006-9fe8-2a5403b15d18", "romnr": 10511, "plasser": 650, "adresse": "Dokkeskjærskaien 1", @@ -1848,7 +1848,7 @@ "longitude": 5.310968 }, { - "lokalId": "8f9df418-e25f-4898-a460-e0e4acc731b0", + "lokalId": "91ba666b-5072-4b16-91c9-6b32a30011fb", "romnr": 10512, "plasser": 3500, "adresse": "Sydnestunnelen", @@ -1856,7 +1856,7 @@ "longitude": 5.321949 }, { - "lokalId": "a137fbcb-b1a6-419d-91a1-664473af4228", + "lokalId": "9a87bfe2-f3b0-4004-b3b2-3c3160b8a4da", "romnr": 10516, "plasser": 850, "adresse": "Nordnes, v/ Haugeveien 32", @@ -1864,7 +1864,7 @@ "longitude": 5.305496 }, { - "lokalId": "a41cc9dd-9069-4fb1-b45e-299ee1169810", + "lokalId": "41594146-f90d-4471-811e-bcedbfb944d9", "romnr": 10788, "plasser": 150, "adresse": "Bønesberget 1", @@ -1872,7 +1872,7 @@ "longitude": 5.30858 }, { - "lokalId": "8715ca46-6bd1-41ee-8ef5-83970b6a7e62", + "lokalId": "0b9d3ed1-72b9-46be-813e-1b47167e73f0", "romnr": 11235, "plasser": 150, "adresse": "Søreidtunet 2", @@ -1880,7 +1880,7 @@ "longitude": 5.271338 }, { - "lokalId": "8314551c-5b0b-4fec-9ff3-888f0ece65a0", + "lokalId": "42793212-d489-40d3-ae6c-d98e3c33009e", "romnr": 11236, "plasser": 175, "adresse": "Nordåsbrotet 2", @@ -1888,7 +1888,7 @@ "longitude": 5.308297 }, { - "lokalId": "52d7fa87-2ed3-40b4-ad46-554cd04cde35", + "lokalId": "0a56b112-fd36-484a-b0b7-edc74811f7c8", "romnr": 11284, "plasser": 2000, "adresse": "Haukelandsveien 30", @@ -1896,7 +1896,7 @@ "longitude": 5.360393 }, { - "lokalId": "ee8d87c3-8342-44c5-9886-8a0bb6d09e37", + "lokalId": "2e0c8778-1bc2-4e5b-b92a-23f860d8b942", "romnr": 11285, "plasser": 2000, "adresse": "Kronstadhøyden - vis a vis Møllendalsv nr 8", @@ -1904,7 +1904,7 @@ "longitude": 5.338758 }, { - "lokalId": "92432e29-01d2-48e1-b071-2c2fa0dbe345", + "lokalId": "666442ff-3761-4c2e-b543-f0ac1488f753", "romnr": 11289, "plasser": 422, "adresse": "Vilhelm Bjerknes' vei 22", @@ -1912,7 +1912,7 @@ "longitude": 5.360502 }, { - "lokalId": "7b4461f3-aaef-429c-91da-4e64d65ea349", + "lokalId": "35514426-3035-40f2-99f5-be5e9f5d2625", "romnr": 11343, "plasser": 1300, "adresse": "Fageråsveien, vis a vis Fageråsv 20", @@ -1920,7 +1920,7 @@ "longitude": 5.354027 }, { - "lokalId": "bf26feb7-923f-4005-94a0-ccac32a5e42b", + "lokalId": "01fb98e7-14d5-4c4e-aa85-a6ccc1c1c043", "romnr": 11424, "plasser": 240, "adresse": "Kanalveien 54", @@ -1928,7 +1928,7 @@ "longitude": 5.346087 }, { - "lokalId": "5d764578-4baa-4dce-a040-f3769920bfbd", + "lokalId": "8b0d782f-eaf0-43f5-b6d3-ca252ddc9416", "romnr": 11663, "plasser": 755, "adresse": "Flaktveitsvingane 17", @@ -1936,7 +1936,7 @@ "longitude": 5.359736 }, { - "lokalId": "0fc3c4f4-1897-48a8-9734-4a2eb385fd56", + "lokalId": "2a7fcca0-f91e-481e-bfe4-067476c6e4e5", "romnr": 11675, "plasser": 750, "adresse": "Florida-Nygårdsparken, Jahnebakken 5", @@ -1944,7 +1944,7 @@ "longitude": 5.332261 }, { - "lokalId": "7816cd4d-3bfc-41ad-9714-4797ceaecc1e", + "lokalId": "fde9de57-b4eb-4f7c-aead-ecfcfd2cbb88", "romnr": 11677, "plasser": 1800, "adresse": "St. Jørgen - St. Jakob, Danckert Krohnsgt", @@ -1952,7 +1952,7 @@ "longitude": 5.334108 }, { - "lokalId": "f0eede3f-8fb7-4e65-b041-80072dd0204e", + "lokalId": "d92b1d8c-de6e-4e4c-9e6d-fd23fd17be96", "romnr": 11681, "plasser": 1050, "adresse": "St. Markus, Damsgårdsveien 70", @@ -1960,7 +1960,7 @@ "longitude": 5.323122 }, { - "lokalId": "d5557e8a-a3ca-46e1-ad37-f7d68fd64bd6", + "lokalId": "6bac466b-666e-450d-835f-2d9beb10318a", "romnr": 11686, "plasser": 1500, "adresse": "Rothaugen, Nye Sandviksv v/ 69a", @@ -1968,7 +1968,7 @@ "longitude": 5.321513 }, { - "lokalId": "c58cacd7-1520-4669-b0be-087af4941a8b", + "lokalId": "39f52f56-d7fd-4564-8482-7a34ebc82b8c", "romnr": 11688, "plasser": 230, "adresse": "Hølbekken 1, Arnatveit", @@ -1976,7 +1976,7 @@ "longitude": 5.47878 }, { - "lokalId": "8ae5f367-1913-49e8-83e5-e955fe3eb0ec", + "lokalId": "00e46f29-fbe0-40f9-ad1f-c6c84ac5b290", "romnr": 11692, "plasser": 455, "adresse": "Olsvikåsen 49, Olsvik", @@ -1984,7 +1984,7 @@ "longitude": 5.217063 }, { - "lokalId": "d819b930-74da-47a9-be1a-cfd230a950b0", + "lokalId": "05bd8fe9-8218-46aa-b432-edfd55852aab", "romnr": 11741, "plasser": 465, "adresse": "Rådhusgata 4", @@ -1992,7 +1992,7 @@ "longitude": 25.518868 }, { - "lokalId": "5f3ac9c4-f56c-4988-b914-33905efcf7cb", + "lokalId": "7913cf2b-40de-444d-b961-b383dbba4ced", "romnr": 11754, "plasser": 2000, "adresse": "Fossliåsen", @@ -2000,7 +2000,7 @@ "longitude": 10.933616 }, { - "lokalId": "de36c8bc-90de-4897-9060-3baa98298d62", + "lokalId": "9f9bc359-7a7f-4851-8772-e97a47ca09bc", "romnr": 11824, "plasser": 350, "adresse": "Lande skole/ Triangelveien 5", @@ -2008,7 +2008,7 @@ "longitude": 11.104092 }, { - "lokalId": "082c2441-ce96-47c9-8543-27306959c841", + "lokalId": "c85c85a6-6ed5-4b6c-bd1e-622e079e2ff2", "romnr": 11848, "plasser": 200, "adresse": "Siriusveien 10", @@ -2016,7 +2016,7 @@ "longitude": 10.415986 }, { - "lokalId": "38d2a1d0-7079-415b-84c3-964d8fca4df2", + "lokalId": "8f1088ae-dcf6-4c86-b90d-bfc3598723f4", "romnr": 12016, "plasser": 200, "adresse": "Torvet 4-6", @@ -2024,7 +2024,7 @@ "longitude": 11.110528 }, { - "lokalId": "d2a5c489-2f89-4832-9898-aaac31687161", + "lokalId": "682fef12-1bc9-4952-8556-ae67e6972a36", "romnr": 12021, "plasser": 42, "adresse": "Finn Sørli/ Hundskinnveien 92", @@ -2032,7 +2032,7 @@ "longitude": 11.079418 }, { - "lokalId": "4effbc5f-a0a3-49d2-89f9-0a84d6d789eb", + "lokalId": "a0743bc1-a3b3-47e9-83c1-53cd3cf7e1d9", "romnr": 12025, "plasser": 87, "adresse": "Erikmarka 3", @@ -2040,7 +2040,7 @@ "longitude": 6.214557 }, { - "lokalId": "927ef9c3-2338-4359-b64f-8cae9a22ed3c", + "lokalId": "74b77302-0b2d-494a-ac71-85c86acda2f6", "romnr": 12072, "plasser": 500, "adresse": "Keiser Wilhelms gate 11", @@ -2048,7 +2048,7 @@ "longitude": 6.153836 }, { - "lokalId": "784be7db-0817-4fe1-8d6c-432b0d9aad09", + "lokalId": "8cf72380-9f6a-4393-a12b-7c40df5109f3", "romnr": 12163, "plasser": 123, "adresse": "Blindheimsgeilane 1", @@ -2056,7 +2056,7 @@ "longitude": 6.363423 }, { - "lokalId": "600e66df-d12c-4d71-8ef2-a1534901bfb6", + "lokalId": "f49e492f-a49f-41d5-ab8a-7052f2448425", "romnr": 12196, "plasser": 300, "adresse": "Storgata 16", @@ -2064,7 +2064,7 @@ "longitude": 6.158668 }, { - "lokalId": "df03582e-bd79-4598-a279-67424860b65a", + "lokalId": "8f25d9ec-7f94-4311-b28e-0a0c56078636", "romnr": 12245, "plasser": 500, "adresse": "Gangstøvikvegen 27", @@ -2072,7 +2072,7 @@ "longitude": 6.227913 }, { - "lokalId": "21c6887e-6d07-4789-b3b1-c13fca7717cf", + "lokalId": "31417bd4-27da-494a-bd85-54eb0897b59c", "romnr": 12272, "plasser": 383, "adresse": "Fjellgata 45", @@ -2080,7 +2080,7 @@ "longitude": 6.175156 }, { - "lokalId": "18365474-66d5-49ca-8721-ae66bbbf81ef", + "lokalId": "8b4b5abc-cd1e-4f22-b9a3-ccf1f2b45657", "romnr": 12304, "plasser": 315, "adresse": "Torggata 52", @@ -2088,7 +2088,7 @@ "longitude": 11.072283 }, { - "lokalId": "bb0bdd03-1776-40df-8a41-96c728d969b5", + "lokalId": "5d0a0849-e2cf-4970-8ba1-de0728ba9e7c", "romnr": 12306, "plasser": 216, "adresse": "Parkgata 33", @@ -2096,7 +2096,7 @@ "longitude": 11.079709 }, { - "lokalId": "9dee91f4-3688-4d50-99f4-1e63ea308b34", + "lokalId": "9fc49c9c-8174-4da0-9c9c-587f6fbe1e8a", "romnr": 12307, "plasser": 270, "adresse": "Morteruds gate 22 - 24", @@ -2104,7 +2104,7 @@ "longitude": 11.066359 }, { - "lokalId": "61de7828-aba3-4d1b-b967-845c145cf61d", + "lokalId": "cb9957f3-7b11-4ce0-9895-6ea40cec1805", "romnr": 12308, "plasser": 320, "adresse": "Storhamargata 23 B-C", @@ -2112,7 +2112,7 @@ "longitude": 11.065353 }, { - "lokalId": "6f70750c-a65d-4fb6-8033-dae3a62593ae", + "lokalId": "b43e9330-51da-47ba-bf8a-e912b8b0b9d6", "romnr": 12309, "plasser": 80, "adresse": "Rollsløkkvegen 19", @@ -2120,7 +2120,7 @@ "longitude": 11.084808 }, { - "lokalId": "e688cf83-a179-4792-b7f7-30934162edbf", + "lokalId": "630d3475-f79d-478f-a094-8319f552210c", "romnr": 12311, "plasser": 50, "adresse": "Aslak Bolts gate 42", @@ -2128,7 +2128,7 @@ "longitude": 11.048915 }, { - "lokalId": "d144dde7-e60d-4693-b22e-2168c1a27c25", + "lokalId": "ba89aed7-52ff-48a0-baf6-1833078f5041", "romnr": 12312, "plasser": 158, "adresse": "Torggata 31", @@ -2136,7 +2136,7 @@ "longitude": 11.073934 }, { - "lokalId": "2849b0de-b4ce-47b0-96c7-1e1805e023ec", + "lokalId": "d6819742-1d3b-4300-aba6-a3f224b829b8", "romnr": 12313, "plasser": 49, "adresse": "Finsalvegen 3", @@ -2144,7 +2144,7 @@ "longitude": 11.132714 }, { - "lokalId": "87f19be5-4dd5-4774-9151-acf467bbef24", + "lokalId": "3175a9d8-25cd-4e24-b813-4aec7a11819a", "romnr": 12314, "plasser": 35, "adresse": "Elvesletta 25", @@ -2152,7 +2152,7 @@ "longitude": 11.094855 }, { - "lokalId": "376ba9ad-c19b-45dc-9eef-bf26cf51afea", + "lokalId": "7ae59021-b98e-4f2f-bd2e-fb950356230c", "romnr": 12315, "plasser": 15, "adresse": "Midtstranda 1", @@ -2160,7 +2160,7 @@ "longitude": 11.107548 }, { - "lokalId": "d208f3e4-3de4-4990-9071-c69c2e458005", + "lokalId": "28124402-946d-4a49-b54f-5931d1ab5629", "romnr": 12325, "plasser": 200, "adresse": "Øvre Flatåsveg 2 A", @@ -2168,7 +2168,7 @@ "longitude": 10.345811 }, { - "lokalId": "66624647-ece8-497a-88e0-fe141de7a7d0", + "lokalId": "62612dbe-50d7-4940-b3e5-c7c50a72866d", "romnr": 12330, "plasser": 45, "adresse": "Øvre Flatåsveg 16", @@ -2176,7 +2176,7 @@ "longitude": 10.333224 }, { - "lokalId": "83ed37dd-6fad-482a-9304-1dc437eacf4d", + "lokalId": "2868dfae-14f7-4773-b207-4e2b152db1f3", "romnr": 12333, "plasser": 280, "adresse": "Gamle Jonsvannsveien 12", @@ -2184,7 +2184,7 @@ "longitude": 10.452723 }, { - "lokalId": "29d86544-0a39-476a-88be-a0f71069b65e", + "lokalId": "c023d7ae-5f62-4966-b0a3-a50b62ba399b", "romnr": 12438, "plasser": 459, "adresse": "Infanteriveien 11, Setermoen brannstasjon", @@ -2192,7 +2192,7 @@ "longitude": 18.354632 }, { - "lokalId": "183603f8-b340-4fbd-9692-ff9e0ba9f66a", + "lokalId": "c93b6f59-c738-474e-9821-9f753d8532c4", "romnr": 12456, "plasser": 225, "adresse": "Gesellveien 5", @@ -2200,7 +2200,7 @@ "longitude": 9.63991 }, { - "lokalId": "cd02331f-fe44-4a2c-87ad-bc9f7fcdf3c0", + "lokalId": "bb00268c-cd7a-43f9-909f-9585194fe0d8", "romnr": 12704, "plasser": 1250, "adresse": "Lykkeberg/ St.Croix gate 31", @@ -2208,7 +2208,7 @@ "longitude": 10.941203 }, { - "lokalId": "cfa9f5e8-195e-4410-822a-c9d57baec9c1", + "lokalId": "757df610-81a6-4ee5-afb2-af8e1ed467fc", "romnr": 12705, "plasser": 1345, "adresse": "Damyr/ Sportsveien 18", @@ -2216,7 +2216,7 @@ "longitude": 10.948606 }, { - "lokalId": "d22a0437-178c-4d18-ac00-7d5c0561814b", + "lokalId": "d9fa8e62-6b02-44b2-9509-267d376ed2db", "romnr": 12706, "plasser": 5384, "adresse": "St. hansfjellet/ Farmansgate 16", @@ -2224,7 +2224,7 @@ "longitude": 10.934136 }, { - "lokalId": "c3587616-a180-4054-8214-bb9081b19d43", + "lokalId": "5dd5a07c-aaeb-4628-9b61-dfb2d626b0fe", "romnr": 12707, "plasser": 716, "adresse": "Kongstenhallen", @@ -2232,7 +2232,7 @@ "longitude": 10.961142 }, { - "lokalId": "df620830-e4e4-442f-bb78-0f5083257be2", + "lokalId": "8fe06275-ea2e-431e-948e-c83f0228bdfb", "romnr": 12708, "plasser": 750, "adresse": "Smertu/ Løypeveien 18", @@ -2240,7 +2240,7 @@ "longitude": 10.936221 }, { - "lokalId": "7851bf7f-832e-425e-a4e7-5efffb4ba071", + "lokalId": "423161a6-e2aa-47a1-af25-3d393e809982", "romnr": 12709, "plasser": 1200, "adresse": "Gressvik/ Storveien 103A", @@ -2248,7 +2248,7 @@ "longitude": 10.902453 }, { - "lokalId": "d9804de5-f0ed-452e-814b-4104b7c64aab", + "lokalId": "cd18a2e4-c08d-441b-8751-1a90f32e8d05", "romnr": 12710, "plasser": 97, "adresse": "Aktivitetshuset/ Gressvik torg 13", @@ -2256,7 +2256,7 @@ "longitude": 10.906206 }, { - "lokalId": "b25053a2-6132-458c-b783-abbb487cda22", + "lokalId": "6aad9611-7ff4-450f-9c57-7adf586d59f1", "romnr": 12711, "plasser": 100, "adresse": "Rolvsøyahallen", @@ -2264,7 +2264,7 @@ "longitude": 10.991211 }, { - "lokalId": "c77c9b95-7e38-4a72-953b-075d32a46afa", + "lokalId": "b85e0cbd-a0dd-4564-8d17-7617bcf1d5ad", "romnr": 13266, "plasser": 165, "adresse": "Bleikerveien 64 (Asker Tennisklubb)", @@ -2272,7 +2272,7 @@ "longitude": 10.447574 }, { - "lokalId": "d7079e62-d506-4a68-a91e-3c5c89b7c570", + "lokalId": "8f141317-1057-40c5-a740-7e8083ef9cd3", "romnr": 13361, "plasser": 756, "adresse": "Kulturhuset", @@ -2280,7 +2280,7 @@ "longitude": 17.98805 }, { - "lokalId": "1a609376-125e-4bfb-bd68-696225d8acef", + "lokalId": "ea83b0e4-de6b-4cbd-affd-e15963bfe299", "romnr": 13469, "plasser": 65, "adresse": "Øvermarka 24", @@ -2288,7 +2288,7 @@ "longitude": 11.043208 }, { - "lokalId": "ffd6ac5e-53c6-40ac-913b-241c2626815b", + "lokalId": "eed40792-b19f-4aa0-b4f2-de2af0e7dd82", "romnr": 13470, "plasser": 55, "adresse": "Nygata 9", @@ -2296,7 +2296,7 @@ "longitude": 10.939832 }, { - "lokalId": "b2391e67-12ce-4c07-95b6-b9863689b046", + "lokalId": "454a9ac1-b530-4ad2-815f-512a7afdd760", "romnr": 13471, "plasser": 343, "adresse": "Brugata 3", @@ -2304,7 +2304,7 @@ "longitude": 10.939129 }, { - "lokalId": "06ec3426-428f-4357-a048-668ee514dcc7", + "lokalId": "1362bc73-12e0-4de5-8802-f954f5f38e40", "romnr": 13472, "plasser": 52, "adresse": "Ljøstadvegen 15", @@ -2312,7 +2312,7 @@ "longitude": 11.204224 }, { - "lokalId": "129f5a0f-9ad4-40bc-bdab-57b3dac6d5d9", + "lokalId": "0ed53f52-f7de-4ea2-a928-6d374cec24c9", "romnr": 13479, "plasser": 1372, "adresse": "Strømsø torg 7", @@ -2320,7 +2320,7 @@ "longitude": 10.200576 }, { - "lokalId": "110aa298-bb7d-45a5-bc0d-4cb00a58f000", + "lokalId": "d4e77cb0-8491-49b1-8720-0da2026a152b", "romnr": 13510, "plasser": 313, "adresse": "Sørreisa Rådhus/Helsesenter", @@ -2328,7 +2328,7 @@ "longitude": 18.1559 }, { - "lokalId": "eb43f667-dcb2-4a70-b31e-589948272d34", + "lokalId": "7c380ee8-b252-4202-8ba7-2daa68c6ef37", "romnr": 13511, "plasser": 173, "adresse": "Øyjordneset", @@ -2336,7 +2336,7 @@ "longitude": 18.156183 }, { - "lokalId": "5d466183-5e6b-4157-a76d-5b4ac9a7b497", + "lokalId": "d17f494f-8fc6-4b8f-b590-d622b331091f", "romnr": 13513, "plasser": 175, "adresse": "Dyrøy sykehjem, Brøstabotn", @@ -2344,7 +2344,7 @@ "longitude": 17.69045 }, { - "lokalId": "ec478664-a4f5-4c13-a125-f2b17ec1aa4c", + "lokalId": "0b6e234f-483d-489c-bbad-c291dcd3de57", "romnr": 13637, "plasser": 1200, "adresse": "Bergstien 37", @@ -2352,7 +2352,7 @@ "longitude": 10.203019 }, { - "lokalId": "deec4abb-09e7-4ff4-ab8f-d043f1a6620d", + "lokalId": "37779241-25c8-4c06-86d9-5e9688a3f41b", "romnr": 13649, "plasser": 465, "adresse": "Oscars gate 4", @@ -2360,7 +2360,7 @@ "longitude": 29.750277 }, { - "lokalId": "552f184d-c045-4f9c-a2e1-447da99d8fc1", + "lokalId": "64291cd7-ecd3-44ab-986c-a731deef50ed", "romnr": 14233, "plasser": 372, "adresse": "Garderobehuset, Narvik stadion, Lillevikveien 9", @@ -2368,7 +2368,7 @@ "longitude": 17.406735 }, { - "lokalId": "fcd7cba7-d097-4bef-bf0f-6c36e79830d4", + "lokalId": "7449c40a-85f1-49c1-aa3b-74b0f4886c11", "romnr": 14249, "plasser": 120, "adresse": "Fotvegen 16", @@ -2376,7 +2376,7 @@ "longitude": 5.288196 }, { - "lokalId": "53c612ca-f463-41f6-96b4-af6beca8437b", + "lokalId": "b0ace3f1-850b-48ac-9704-61b81d86ccc1", "romnr": 14250, "plasser": 445, "adresse": "Ankenes Bo- og serviceservice Krobakken 5", @@ -2384,7 +2384,7 @@ "longitude": 17.349114 }, { - "lokalId": "4f007bac-8c81-4cca-a25f-f82cbe6685ba", + "lokalId": "162d006c-0738-449a-9c84-10e4ad1d11d3", "romnr": 14279, "plasser": 63, "adresse": "Neptunveien 3-5", @@ -2392,7 +2392,7 @@ "longitude": 10.03575 }, { - "lokalId": "c7036287-c719-4a24-a64d-398e01f344d7", + "lokalId": "ac6e73d4-6c45-4f1c-9437-f26d483d8385", "romnr": 14355, "plasser": 18, "adresse": "Austre Veaveg 217", @@ -2400,7 +2400,7 @@ "longitude": 5.226173 }, { - "lokalId": "50e15ba1-c4a6-4741-8b49-7311f3868969", + "lokalId": "0ec5f8bc-efed-4e5d-86fe-106d4387f747", "romnr": 14476, "plasser": 400, "adresse": "Hagebyen skole", @@ -2408,7 +2408,7 @@ "longitude": 16.543533 }, { - "lokalId": "c3383e3d-c735-4250-8b0a-9205233f2eac", + "lokalId": "2c39983b-e800-419c-a880-2f78046b696f", "romnr": 14487, "plasser": 400, "adresse": "Rådhuset Harstad OFFENTLIG", @@ -2416,7 +2416,7 @@ "longitude": 16.53915 }, { - "lokalId": "fe6d439c-8114-4e5a-8ebe-2b49639428fa", + "lokalId": "aec137f2-a4aa-42fb-a7c7-10c75d4525a2", "romnr": 14559, "plasser": 281, "adresse": "Stokkeveien 2", @@ -2424,7 +2424,7 @@ "longitude": 10.258623 }, { - "lokalId": "bfe4fed1-4064-47cd-a878-52121f124c21", + "lokalId": "7c9402da-da9b-419b-841b-4cd243813788", "romnr": 14566, "plasser": 850, "adresse": "Kanebogen skole OFFENTLIG", @@ -2432,7 +2432,7 @@ "longitude": 16.55882 }, { - "lokalId": "ac17fbb5-c7cd-4c37-9cf5-1c6255c18da8", + "lokalId": "1757bc07-ff68-4617-961f-1f1b1b5fe8e0", "romnr": 14854, "plasser": 320, "adresse": "Kong Øysteinhall, Rækøyveien 40. Kabelvåg", @@ -2440,7 +2440,7 @@ "longitude": 14.46518 }, { - "lokalId": "eda2e4d1-8016-4720-9616-7d7cb011a471", + "lokalId": "4179251b-0664-495e-b1de-64e4e6ab3f8b", "romnr": 14855, "plasser": 3300, "adresse": "VåganHallen, Løkthaugveien 10. Svolvær", @@ -2448,7 +2448,7 @@ "longitude": 14.567376 }, { - "lokalId": "159c38d2-dbba-4d2c-b6b6-b4c4486885f6", + "lokalId": "6593c66d-4993-46ef-9870-55dfe087dc3e", "romnr": 14871, "plasser": 83, "adresse": "Vesterngata 18", @@ -2456,7 +2456,7 @@ "longitude": 10.268181 }, { - "lokalId": "5c571011-5b0f-485d-937a-6c603fb9e7e3", + "lokalId": "987b54c4-66a5-4b0b-a2c4-35b3aadeacef", "romnr": 14905, "plasser": 90, "adresse": "Skulegata 29", @@ -2464,7 +2464,7 @@ "longitude": 6.357013 }, { - "lokalId": "b9cfdd00-82f8-4e74-b9bf-45869dbbad24", + "lokalId": "ebac6254-ec55-423e-a4ae-f2ddf0708318", "romnr": 14908, "plasser": 125, "adresse": "Saudavegen 279", @@ -2472,7 +2472,7 @@ "longitude": 6.31035 }, { - "lokalId": "00aba34c-24b4-4d88-bc00-ad8adbfb5655", + "lokalId": "863b2c85-bfe8-4e8e-8395-590c8f1a27fd", "romnr": 14911, "plasser": 150, "adresse": "Rustå 31", @@ -2480,7 +2480,7 @@ "longitude": 6.380221 }, { - "lokalId": "0609ac19-3913-458a-babf-b8b90a004912", + "lokalId": "d4a77887-d188-486b-9797-9dd9f52796f0", "romnr": 14918, "plasser": 85, "adresse": "Åbødalsveien 79", @@ -2488,7 +2488,7 @@ "longitude": 6.363345 }, { - "lokalId": "c351b9f4-7a9f-42ac-aa98-942bf4b27b26", + "lokalId": "04feb8f9-a676-4263-a00f-a85228fdbe74", "romnr": 14959, "plasser": 814, "adresse": "Karl Rasmussens plass 1", @@ -2496,7 +2496,7 @@ "longitude": 29.739806 }, { - "lokalId": "9df20d2c-d3ad-41d2-81c5-859e20f416da", + "lokalId": "ae7f0273-7dab-42b1-a4c6-1a28d21faad4", "romnr": 14979, "plasser": 600, "adresse": "Skulegata 23", @@ -2504,7 +2504,7 @@ "longitude": 6.357565 }, { - "lokalId": "49495ccf-97e9-4806-abb1-608585bf7554", + "lokalId": "602dbe80-6a54-4ed5-a36c-9d7b033894f0", "romnr": 14981, "plasser": 78, "adresse": "Sjøen 45", @@ -2512,7 +2512,7 @@ "longitude": 6.30552 }, { - "lokalId": "3646208a-0a6e-4309-bb72-35fefec26e89", + "lokalId": "d3bbf171-cfd1-4179-b904-87c7dff527e4", "romnr": 14984, "plasser": 40, "adresse": "Åbødalsveien 77", @@ -2520,7 +2520,7 @@ "longitude": 6.363862 }, { - "lokalId": "10390a33-a17c-4de3-99be-f1dc77ba1bad", + "lokalId": "9881e7e1-6e01-49ed-ad6a-07f40110692d", "romnr": 15004, "plasser": 100, "adresse": "Sortlandshallen", @@ -2528,7 +2528,7 @@ "longitude": 15.407296 }, { - "lokalId": "59406cab-1952-4a73-811f-bf668f1f8de1", + "lokalId": "f5e2e341-d22a-46f3-82f1-86f2ebecebe9", "romnr": 15005, "plasser": 300, "adresse": "Torvmyrveien 4A", @@ -2536,7 +2536,7 @@ "longitude": 5.619654 }, { - "lokalId": "0be3386f-7f4f-4232-8da7-13688b493071", + "lokalId": "b62187ab-9669-456a-befd-124053f59f1f", "romnr": 15006, "plasser": 270, "adresse": "Torvmyrveien 40", @@ -2544,7 +2544,7 @@ "longitude": 5.650053 }, { - "lokalId": "cfc1ace9-76e9-4300-b623-4a2593bb1aad", + "lokalId": "fe5fa1cd-1119-489b-96bd-24ab39f06673", "romnr": 15059, "plasser": 2000, "adresse": "Storevardvegen", @@ -2552,7 +2552,7 @@ "longitude": 5.578049 }, { - "lokalId": "b670476d-0c81-4ade-bd14-b98f0515b97c", + "lokalId": "2028bb37-7a59-43a7-9e0d-a27b60a03e3f", "romnr": 15232, "plasser": 2080, "adresse": "Kirkebakken 18", @@ -2560,7 +2560,7 @@ "longitude": 5.737782 }, { - "lokalId": "1a71c377-8a40-4c5d-8fd5-f6b9f8312728", + "lokalId": "1e5316a0-7b14-4d71-b8fa-56587f4d8760", "romnr": 15236, "plasser": 200, "adresse": "Morgedalsveien 60", @@ -2568,7 +2568,7 @@ "longitude": 5.695868 }, { - "lokalId": "04fe19e2-9c2b-4d27-96b4-f52cc49bdb81", + "lokalId": "7d97b9ac-5f2a-4351-aa77-651f90a2807d", "romnr": 15239, "plasser": 220, "adresse": "Jupiterveien 30C", @@ -2576,7 +2576,7 @@ "longitude": 5.700146 }, { - "lokalId": "2c781068-a801-4786-b18f-017d16d3c6fc", + "lokalId": "71135e19-ea8b-40c5-a86a-86f993b7f568", "romnr": 15240, "plasser": 500, "adresse": "Lagårdsveien 77", @@ -2584,7 +2584,7 @@ "longitude": 5.739728 }, { - "lokalId": "a590197a-9eb7-4660-a3c9-e07a9a9244ac", + "lokalId": "f24bc600-ba2a-4e16-821a-1dd6d9b4a227", "romnr": 15243, "plasser": 5000, "adresse": "Nedre Storaberget 1", @@ -2592,7 +2592,7 @@ "longitude": 5.722953 }, { - "lokalId": "379ec27f-5699-41d4-a8a3-e4afc11484e9", + "lokalId": "5e2f1279-e6c4-437b-a083-b0274da59b72", "romnr": 15245, "plasser": 4000, "adresse": "Nedre Strandgate", @@ -2600,7 +2600,7 @@ "longitude": 5.725783 }, { - "lokalId": "93fb5dd2-ee84-46a3-ac83-bbeb9f36d6e7", + "lokalId": "c47e7898-c302-4a3b-a149-2c0f848e4de4", "romnr": 15246, "plasser": 380, "adresse": "Olav Liljekransstien 20", @@ -2608,7 +2608,7 @@ "longitude": 5.698082 }, { - "lokalId": "ffa50c4c-cb44-458c-83de-8948d4531652", + "lokalId": "b501dcca-5739-44f2-b5b5-0342a1a72309", "romnr": 15247, "plasser": 380, "adresse": "Hallingstien 38", @@ -2616,7 +2616,7 @@ "longitude": 5.697058 }, { - "lokalId": "e1d932bf-27b4-4f02-8301-fae2e301efe4", + "lokalId": "739b4402-865f-43d6-b7d3-b47bed92b181", "romnr": 15250, "plasser": 3930, "adresse": "Skagenkaien 29", @@ -2624,7 +2624,7 @@ "longitude": 5.731114 }, { - "lokalId": "71d153cc-a683-47c5-8619-ae6d34572b3b", + "lokalId": "199b9974-f77d-4445-b979-77ade9881604", "romnr": 15251, "plasser": 3140, "adresse": "Eskelandsveien 35", @@ -2632,7 +2632,7 @@ "longitude": 5.67812 }, { - "lokalId": "9da896af-9d7b-47de-ba1e-16723bdb4394", + "lokalId": "0d9495d9-23ad-4456-a8d6-983d3936bf11", "romnr": 15255, "plasser": 72, "adresse": "Avaldsnesvegen 72", @@ -2640,7 +2640,7 @@ "longitude": 5.303296 }, { - "lokalId": "50e3e29b-79a2-4a21-8617-ffa1c4b0cdf2", + "lokalId": "021066d5-989b-486a-943e-dd85da0562e5", "romnr": 15258, "plasser": 66, "adresse": "Austre Karmøyveg 120", @@ -2648,7 +2648,7 @@ "longitude": 5.300107 }, { - "lokalId": "5d9c7d1a-d71d-4965-9834-6e77c0eb81f2", + "lokalId": "8c0e7e4a-44a9-4b8f-8a3f-ca13a78035b1", "romnr": 15260, "plasser": 608, "adresse": "Lotheparkvegen", @@ -2656,7 +2656,7 @@ "longitude": 5.270669 }, { - "lokalId": "783b92ee-fc7f-42ce-8318-2e0793475c4a", + "lokalId": "046fa71f-4131-46f2-b384-f03c885244e7", "romnr": 15347, "plasser": 150, "adresse": "Turist og konferansesenteret, Børøya", @@ -2664,7 +2664,7 @@ "longitude": 14.92446 }, { - "lokalId": "b4bab817-3cfc-48af-9fc9-196af69fdaf1", + "lokalId": "1e951f10-15a7-44d4-9814-bf46db397c0b", "romnr": 15468, "plasser": 420, "adresse": "Søndre Torv 7 B", @@ -2672,7 +2672,7 @@ "longitude": 10.254797 }, { - "lokalId": "9dc780ee-1e06-433f-a82a-e8603fae95aa", + "lokalId": "6e9f2c96-65be-4de6-bf11-c406d3f1d0e3", "romnr": 15471, "plasser": 417, "adresse": "Valhallveien 15", @@ -2680,7 +2680,7 @@ "longitude": 10.196138 }, { - "lokalId": "1fb030cc-d777-4263-81a7-d9cf2a48b74d", + "lokalId": "2ced458a-7c73-4f6b-a048-115444f08d18", "romnr": 15476, "plasser": 170, "adresse": "Ringeriksgata 13", @@ -2688,7 +2688,7 @@ "longitude": 10.262372 }, { - "lokalId": "6ea7900f-78a6-48a3-b9dc-52ebc33790d8", + "lokalId": "85f83fff-c5d3-4a08-a96f-cdaee2da6eec", "romnr": 15481, "plasser": 100, "adresse": "Dronning Åstas gate 12", @@ -2696,7 +2696,7 @@ "longitude": 10.252902 }, { - "lokalId": "72f51a02-eef7-4d55-8e62-2299a791398a", + "lokalId": "99aeb987-8c1e-4538-827d-157d0becaeb5", "romnr": 15597, "plasser": 385, "adresse": "Krokenveien 19", @@ -2704,7 +2704,7 @@ "longitude": 10.259675 }, { - "lokalId": "f1af3458-1971-4b77-8b60-3fe819a0ec52", + "lokalId": "18713487-12a0-408a-99b7-52bfd40f2d05", "romnr": 15611, "plasser": 330, "adresse": "Wergelands gate 9", @@ -2712,7 +2712,7 @@ "longitude": 10.19372 }, { - "lokalId": "00665953-a9db-44c3-82ff-8b58d01e697f", + "lokalId": "267b65bf-d70c-4948-9512-162a326cf146", "romnr": 15714, "plasser": 150, "adresse": "Søfteland", @@ -2720,7 +2720,7 @@ "longitude": 5.452183 }, { - "lokalId": "e1386977-fd37-41e7-b140-84445e4907e6", + "lokalId": "84a3984f-5041-4a61-be59-93d8ffa49556", "romnr": 15715, "plasser": 550, "adresse": "Rådhus. Idrett og Svømmehall", @@ -2728,7 +2728,7 @@ "longitude": 16.118059 }, { - "lokalId": "f86ac2c2-7916-4c4f-8e93-64e55ad21a31", + "lokalId": "493dff68-3438-46d7-8863-d13c2984687f", "romnr": 15717, "plasser": 136, "adresse": "Askviknes Sykehjem", @@ -2736,7 +2736,7 @@ "longitude": 5.38207 }, { - "lokalId": "b833ca4b-52d7-4218-8f6c-348561490856", + "lokalId": "fb17e81c-fce4-4181-a281-3edd997a7502", "romnr": 15730, "plasser": 500, "adresse": "Os", @@ -2744,7 +2744,7 @@ "longitude": 5.469669 }, { - "lokalId": "8f0ae2fb-a6da-406b-9c2c-84dd5145da40", + "lokalId": "d201ddc4-473e-4645-88a2-09d07b6f24c3", "romnr": 15745, "plasser": 150, "adresse": "Betanien Hospital", @@ -2752,7 +2752,7 @@ "longitude": 9.596141 }, { - "lokalId": "b2d09ab0-d33e-41fa-9212-345efac5118d", + "lokalId": "1893c07d-532d-4e9f-b9d7-b7a91b5d7df3", "romnr": 15746, "plasser": 390, "adresse": "Gampedalen", @@ -2760,7 +2760,7 @@ "longitude": 9.617147 }, { - "lokalId": "b1f54198-34c4-42ba-96c5-eb1f8f599457", + "lokalId": "c7e158a1-0b7b-4b8a-95d7-43ef99464661", "romnr": 15748, "plasser": 325, "adresse": "Nedre Hjellegt 9", @@ -2768,7 +2768,7 @@ "longitude": 9.606643 }, { - "lokalId": "4e73e1b9-2771-4bd8-9f30-d931d483bd1d", + "lokalId": "ec7a6c3a-a717-4491-9325-6bc9cdaed010", "romnr": 15749, "plasser": 498, "adresse": "Schweigaards gate 11", @@ -2776,7 +2776,7 @@ "longitude": 9.605392 }, { - "lokalId": "44e8d95c-c810-4499-92d6-cc5270319428", + "lokalId": "9e8e9f15-b070-4a14-95ca-0a77fba91c19", "romnr": 15750, "plasser": 400, "adresse": "Tamburlunden Gråtenmoen Terrasse 16", @@ -2784,7 +2784,7 @@ "longitude": 9.616471 }, { - "lokalId": "a7a7c665-e70a-460c-90f8-804ced8c151b", + "lokalId": "feb01e1d-e951-4d24-9e37-d65d6f1d239b", "romnr": 15752, "plasser": 500, "adresse": "Bånnåsen 21", @@ -2792,7 +2792,7 @@ "longitude": 9.660227 }, { - "lokalId": "06c97fed-31e3-4088-ae82-35177c2896ba", + "lokalId": "e07e8e70-f889-4100-98d2-84c9d68d7168", "romnr": 15753, "plasser": 1120, "adresse": "Helleberget, Huken, Crøgerlia 21", @@ -2800,7 +2800,7 @@ "longitude": 9.644708 }, { - "lokalId": "cdb937f2-fc60-424f-bad8-d58cf6e66742", + "lokalId": "783b8462-40e9-44c7-b825-14274fde3a58", "romnr": 15754, "plasser": 490, "adresse": "Klevstrand", @@ -2808,7 +2808,7 @@ "longitude": 9.653273 }, { - "lokalId": "d5f60040-8208-4ee8-be96-9b398004b187", + "lokalId": "710adcd4-4f9b-4e5c-8e0f-59f515f78de5", "romnr": 15755, "plasser": 540, "adresse": "Lysthusåsen, Kleiva 4", @@ -2816,7 +2816,7 @@ "longitude": 9.644843 }, { - "lokalId": "2a199dad-b9f7-47e0-a4d5-e20cf0c604d4", + "lokalId": "bfa1980f-3483-408d-a989-c4a4559d7cc9", "romnr": 15756, "plasser": 130, "adresse": "Politihuset, Rådhusgt 5", @@ -2824,7 +2824,7 @@ "longitude": 9.657483 }, { - "lokalId": "4d5cf968-d970-4177-b09d-681e84793899", + "lokalId": "f03f56ae-da42-4bd9-9ab0-ba0f19e839e1", "romnr": 15757, "plasser": 2000, "adresse": "Sentrumstunellen/Porsgrunntunnelen", @@ -2832,7 +2832,7 @@ "longitude": 9.660491 }, { - "lokalId": "021367f0-00f6-49de-8269-74f1aa792a85", + "lokalId": "a7eabef6-ce90-41fb-a331-8b4214c0ad08", "romnr": 15758, "plasser": 140, "adresse": "Slottsbrugt 25", @@ -2840,7 +2840,7 @@ "longitude": 9.664885 }, { - "lokalId": "e57fadb2-3a57-49bc-b732-129d40dc3d4e", + "lokalId": "796d6c02-70f0-4d59-8298-0740c1d54807", "romnr": 15759, "plasser": 1040, "adresse": "Trosvik, Brevik", @@ -2848,7 +2848,7 @@ "longitude": 9.691015 }, { - "lokalId": "abebabd2-9bac-4f67-adfa-8f4c25fdccfa", + "lokalId": "5c8eff7a-2398-4bc0-ace3-db8d8339d1ea", "romnr": 15760, "plasser": 1000, "adresse": "Renseanlegget, Ytre Strandvei 15", @@ -2856,7 +2856,7 @@ "longitude": 9.414783 }, { - "lokalId": "3bf7f665-a23d-4c03-b0ea-c5df79537f91", + "lokalId": "017b8893-d3f4-4a88-807d-a09bbb87d198", "romnr": 15761, "plasser": 220, "adresse": "Årø skole, Nøkkeldalen 4", @@ -2864,7 +2864,7 @@ "longitude": 9.356233 }, { - "lokalId": "ce5b04a6-24d9-4dca-b988-82950c5b9cb5", + "lokalId": "66bcbf7b-1397-492d-b53d-9081713512d0", "romnr": 15762, "plasser": 55, "adresse": "Kalstad KBO, Kalstadveien 16E", @@ -2872,7 +2872,7 @@ "longitude": 9.388295 }, { - "lokalId": "c08496d0-3ab5-428f-b814-ff2a02cde9f5", + "lokalId": "2df18c2a-610f-4815-ab27-056889e76657", "romnr": 15765, "plasser": 728, "adresse": "Potekjeller tomta, Bøenstomten 10", @@ -2880,7 +2880,7 @@ "longitude": 8.591391 }, { - "lokalId": "c5ffe2c5-41cc-479e-8b85-5baf0b2de0ba", + "lokalId": "22f25357-e9bc-4f63-b697-91f49c6fa883", "romnr": 15766, "plasser": 200, "adresse": "Rjukan politikammer, Sam Eydes gate 71", @@ -2888,7 +2888,7 @@ "longitude": 8.589474 }, { - "lokalId": "6f37425c-7109-4fad-98f9-f7c4b3e6de23", + "lokalId": "1b775b4a-c101-4212-8cbc-54dbc0970baf", "romnr": 15767, "plasser": 420, "adresse": "Heddal u/skole, Rogneståvegen 6", @@ -2896,7 +2896,7 @@ "longitude": 9.211249 }, { - "lokalId": "09d3c381-fe94-423c-a867-c58684aad60b", + "lokalId": "e00ea735-dddd-42f7-a080-429f74c80ff2", "romnr": 15768, "plasser": 1900, "adresse": "Ravnsflog, Tinnesgata 18", @@ -2904,7 +2904,7 @@ "longitude": 9.254196 }, { - "lokalId": "02b61699-0710-4e4e-ac73-c76ae85c5c6c", + "lokalId": "0a8aaef7-d4b9-4899-a7dc-08d15b936b42", "romnr": 15769, "plasser": 700, "adresse": "Storgt 59", @@ -2912,7 +2912,7 @@ "longitude": 9.261607 }, { - "lokalId": "34e71c7b-d2ff-45e8-9d0c-c76d049d9600", + "lokalId": "ed6619f0-5703-49c8-9f96-1b539b672d4d", "romnr": 15770, "plasser": 180, "adresse": "Stathelle Service Senter", @@ -2920,7 +2920,7 @@ "longitude": 9.692843 }, { - "lokalId": "85abf213-51b3-4c1f-8cfc-368f1f9fe059", + "lokalId": "0b5b65f1-6732-4231-b38c-01fbb265511e", "romnr": 15771, "plasser": 1138, "adresse": "Kvæfjordhallen, Husebyveien 3", @@ -2928,7 +2928,7 @@ "longitude": 16.179076 }, { - "lokalId": "a1644a4c-3376-4f0c-9639-d35782d9a8dc", + "lokalId": "08484c7d-bba2-46ac-ad19-5875f8746fa1", "romnr": 16127, "plasser": 465, "adresse": "Nils Leuchsvei 40", @@ -2936,7 +2936,7 @@ "longitude": 10.619218 }, { - "lokalId": "89fba71a-d961-44d1-8652-e422d933761f", + "lokalId": "361f1c1b-1eb5-4120-b9a6-7dce8cf379d4", "romnr": 16213, "plasser": 1550, "adresse": "Rødskiferveien 1 Kolsås Senter", @@ -2944,7 +2944,7 @@ "longitude": 10.50076 }, { - "lokalId": "74a68b66-d7bf-4eea-8165-e8567953f486", + "lokalId": "cb491681-5675-41b7-846d-b8b82ea6fc27", "romnr": 16352, "plasser": 225, "adresse": "Østerndalen 23 Grini næringspark", @@ -2952,7 +2952,7 @@ "longitude": 10.601794 }, { - "lokalId": "bc28dfa9-41ef-4e29-9c17-88b95c254621", + "lokalId": "1d7b4f87-438c-429c-bdac-ddcdce0d6bba", "romnr": 16719, "plasser": 1130, "adresse": "St. Hanshaugen, Ullevålsveien", @@ -2960,7 +2960,7 @@ "longitude": 10.738991 }, { - "lokalId": "ec8244e3-dcc8-4269-a09a-d6dce62966a0", + "lokalId": "7af77a0a-9d31-429e-8ee0-ccf204e10657", "romnr": 16951, "plasser": 197, "adresse": "Tareveien 7 Tennishallen", @@ -2968,7 +2968,7 @@ "longitude": 15.352302 }, { - "lokalId": "3b8b00cf-c39a-4f8b-b6bf-a77550648db4", + "lokalId": "56f68269-5ee9-41a4-9db5-5b5893856a39", "romnr": 16958, "plasser": 255, "adresse": "Tinkeliheia 1, (Finneid nærmiljøsenter)", @@ -2976,7 +2976,7 @@ "longitude": 15.444636 }, { - "lokalId": "9b5d2b64-46e1-4051-97f2-af06016bcf20", + "lokalId": "2f1019bc-537b-4c6b-bdd7-5eded738408f", "romnr": 16973, "plasser": 1750, "adresse": "Tullinsgate 2", @@ -2984,7 +2984,7 @@ "longitude": 10.734887 }, { - "lokalId": "9bf053fa-788c-4258-b721-6245e4033cd9", + "lokalId": "fb8d09aa-d9b0-4464-b038-92c5d8fbc3ad", "romnr": 17007, "plasser": 214, "adresse": "Løpsmark Skole Nonshaugen 87, 8015 Bodø", @@ -2992,7 +2992,7 @@ "longitude": 14.447098 }, { - "lokalId": "4fdce490-e4f5-401a-9de2-647e43f67d36", + "lokalId": "d3e9c8ca-5ded-40be-8c22-d26859c20e90", "romnr": 17014, "plasser": 400, "adresse": "Bjørndalsveien 14 (Mørkvedmarka skole)", @@ -3000,7 +3000,7 @@ "longitude": 14.588055 }, { - "lokalId": "15e3a9d8-87ff-4e93-b539-424b61be22ce", + "lokalId": "9260a151-60a6-4d4f-848e-e4ae903e4fc2", "romnr": 17356, "plasser": 80, "adresse": "Peter Bondes veg 78", @@ -3008,7 +3008,7 @@ "longitude": 6.388827 }, { - "lokalId": "2c87f1ba-0371-4c69-b12f-a51a2d23d14d", + "lokalId": "796d0c80-142c-4bf5-b91e-9987faa72cbe", "romnr": 17526, "plasser": 320, "adresse": "Risilveien 71, Vestbyhallen", @@ -3016,7 +3016,7 @@ "longitude": 10.709967 }, { - "lokalId": "7e999c54-b386-4690-b2ca-8ebbeeb75c45", + "lokalId": "7f347403-e115-4bd0-ba06-4be431dd9be3", "romnr": 17609, "plasser": 590, "adresse": "Frognhallen, Belsjøveien 2", @@ -3024,7 +3024,7 @@ "longitude": 10.634824 }, { - "lokalId": "b23f45b7-7ef4-4ea2-8f30-e618e274e2b1", + "lokalId": "1c0185ad-b0d1-4875-b3c1-67a49a19e739", "romnr": 17676, "plasser": 100, "adresse": "Tjørnahaugane 60", @@ -3032,7 +3032,7 @@ "longitude": 6.536621 }, { - "lokalId": "33613aa6-caa9-40a6-a5aa-15a83c30cedd", + "lokalId": "8e0d7806-8120-4a2a-8662-551167013f7d", "romnr": 17701, "plasser": 240, "adresse": "Moerveien 1- Skoleveien 1 Ås Rådhus", @@ -3040,7 +3040,7 @@ "longitude": 10.790869 }, { - "lokalId": "21d3e8f2-f0b6-4932-a434-4bea860f9458", + "lokalId": "f44a22f2-83c8-4b7d-a310-d6d875f9d888", "romnr": 17829, "plasser": 258, "adresse": "Allbrukshus Langhus, Galmle Vevelstadvei 34", @@ -3048,7 +3048,7 @@ "longitude": 10.841281 }, { - "lokalId": "ac9d6b55-c600-43a7-94b7-432ebeaa002f", + "lokalId": "01e1e5a6-abfa-4984-adb0-bcf260db99a1", "romnr": 18081, "plasser": 240, "adresse": "Rektor Oldens gate 2", @@ -3056,7 +3056,7 @@ "longitude": 5.692018 }, { - "lokalId": "f09d6171-8177-4459-bae6-dc18bd497c5a", + "lokalId": "567bf15f-e7aa-44cc-a78a-a4351a5f251c", "romnr": 18533, "plasser": 300, "adresse": "Fred Olsensgt 11", @@ -3064,7 +3064,7 @@ "longitude": 10.748667 }, { - "lokalId": "f87aa2ba-ed34-4d46-a1ba-4e252f3da671", + "lokalId": "2f6d4f10-3ca3-44cb-9fba-96d523be43b1", "romnr": 18616, "plasser": 7060, "adresse": "Holmlia bad, Holmlia sentervei 34", @@ -3072,7 +3072,7 @@ "longitude": 10.792393 }, { - "lokalId": "513daacc-01a0-41a6-959d-0a4b08799a8c", + "lokalId": "61b8eb1a-94bf-465f-b166-ebb194b622c3", "romnr": 20209, "plasser": 250, "adresse": "Bentsegt 21-25", @@ -3080,7 +3080,7 @@ "longitude": 10.759794 }, { - "lokalId": "927a95b8-be35-4f76-bcde-32f911d541e4", + "lokalId": "e268c8d6-3adf-4a30-85a8-c0ca5d268087", "romnr": 20242, "plasser": 230, "adresse": "Grav Gårdsvei 5", @@ -3088,7 +3088,7 @@ "longitude": 10.606651 }, { - "lokalId": "7f799fd7-e3c9-4243-ae98-45891f5402dd", + "lokalId": "f49a6562-9b42-479d-8b82-fa033a1d2e31", "romnr": 21027, "plasser": 40, "adresse": "K.O. Bjerklis veg 9", @@ -3096,7 +3096,7 @@ "longitude": 11.03274 }, { - "lokalId": "e7e88a06-c5da-43a7-82c6-0824aca1ee4a", + "lokalId": "0c0630d3-c6b6-421a-bbab-5d8a7c717aae", "romnr": 20243, "plasser": 233, "adresse": "Peter Lorangesvei 1, Stabekk Bosenter", @@ -3104,7 +3104,7 @@ "longitude": 10.586712 }, { - "lokalId": "953a32f7-d8ff-43a4-8377-3965f5c6cb80", + "lokalId": "557ea2c3-1050-4ccf-8701-4f98f470440b", "romnr": 20244, "plasser": 553, "adresse": "Skollerudveien 7, Helset hallen", @@ -3112,7 +3112,7 @@ "longitude": 10.50811 }, { - "lokalId": "5bc4785d-c8d1-40ed-a73d-7fafdf08ff1a", + "lokalId": "e4accd9d-f456-43f6-9b9b-d444963f9ae4", "romnr": 20245, "plasser": 5500, "adresse": "Vogellund 7, Holmenhallen", @@ -3120,7 +3120,7 @@ "longitude": 10.484845 }, { - "lokalId": "211131f2-add4-40ae-b119-16f31546dd16", + "lokalId": "0502a1a1-2f8e-4a8e-9e32-47b73700bf11", "romnr": 20246, "plasser": 250, "adresse": "Veståsen 18, Katolsk kapell", @@ -3128,7 +3128,7 @@ "longitude": 10.60407 }, { - "lokalId": "adb8b934-7f7f-4e2e-90c9-a4e68e6c0cd1", + "lokalId": "00fdafc8-59a6-4189-bf4c-78d0e7f3b65b", "romnr": 20247, "plasser": 1336, "adresse": "Gml Ringeriksvei 44", @@ -3136,7 +3136,7 @@ "longitude": 10.584346 }, { - "lokalId": "1974f202-ec50-4c0c-82a1-8ffe50db83e6", + "lokalId": "d9d66d0e-e349-4d67-93e1-19ed1639dbc0", "romnr": 20248, "plasser": 260, "adresse": "Bjerkelundsveien 18 A", @@ -3144,7 +3144,7 @@ "longitude": 10.614801 }, { - "lokalId": "5e3a1c9b-ccaf-4f83-933d-71d7e8fa120b", + "lokalId": "12cfeeba-155f-443c-93ff-acb3564d8b50", "romnr": 20249, "plasser": 233, "adresse": "Nedre Toppenhaug 56", @@ -3152,7 +3152,7 @@ "longitude": 10.507814 }, { - "lokalId": "c921185b-add1-4acb-ac5b-5669b1536436", + "lokalId": "60209ea8-c880-4fa1-8873-fa420602773f", "romnr": 20250, "plasser": 4200, "adresse": "Hamangskråningen, Brynsveien 2 Sandvika", @@ -3160,7 +3160,7 @@ "longitude": 10.512613 }, { - "lokalId": "0a20e1a1-3320-494b-a218-e16614f2bf08", + "lokalId": "d433cfe0-a283-4859-b987-e2738825c768", "romnr": 20251, "plasser": 243, "adresse": "Sleiverudåsen 3", @@ -3168,7 +3168,7 @@ "longitude": 10.504182 }, { - "lokalId": "8c93f8c3-a6d6-4fc0-9064-54f597fb9022", + "lokalId": "899694cc-bc5d-452d-813a-1747f5784678", "romnr": 20253, "plasser": 2800, "adresse": "T-banen - Valkyrien stasjon", @@ -3176,7 +3176,7 @@ "longitude": 10.717619 }, { - "lokalId": "b16f5ed2-5715-4158-9801-401e0739f339", + "lokalId": "65aae171-d195-401b-b26b-0c2405bea181", "romnr": 20254, "plasser": 5600, "adresse": "Klemetsrud, Lofsrudveien 6", @@ -3184,7 +3184,7 @@ "longitude": 10.829616 }, { - "lokalId": "0969e8cc-0196-42ca-99ae-6ad4d2908d58", + "lokalId": "4bac6529-be0e-4e2e-993a-31cf99d3b2f1", "romnr": 20255, "plasser": 404, "adresse": "Jordalsgt 11", @@ -3192,7 +3192,7 @@ "longitude": 10.785588 }, { - "lokalId": "8b553950-90aa-4790-9d5b-7aa7af16d0ea", + "lokalId": "0cb4f653-2d3f-4bf0-8b19-d96a90479f95", "romnr": 20256, "plasser": 555, "adresse": "Majorstuveien 38", @@ -3200,7 +3200,7 @@ "longitude": 10.714875 }, { - "lokalId": "0363ba51-a591-435b-96d8-daa87601bd2e", + "lokalId": "a4e60752-f283-4e2a-9ea8-7d26324f95bf", "romnr": 20257, "plasser": 4300, "adresse": "Maridalsveien 14", @@ -3208,7 +3208,7 @@ "longitude": 10.750318 }, { - "lokalId": "a2832514-ef82-47cc-8fd0-a83eca60643c", + "lokalId": "c56cc831-01e8-41ca-9c54-8c8e505d7033", "romnr": 20258, "plasser": 472, "adresse": "Olav Schousvei 2-8 plan A", @@ -3216,7 +3216,7 @@ "longitude": 10.781977 }, { - "lokalId": "7d52ca22-2975-4e74-be7b-aed5010a8ca4", + "lokalId": "e9836fc1-2256-4c9f-bde5-320d0ed41818", "romnr": 20259, "plasser": 385, "adresse": "Nobelsgt 30", @@ -3224,7 +3224,7 @@ "longitude": 10.700768 }, { - "lokalId": "de1ea4fc-1183-4602-abcb-3ddb68a7caba", + "lokalId": "9a40565e-be4b-4336-b2e7-f347aad4e628", "romnr": 20261, "plasser": 486, "adresse": "Vøyensvingen 4", @@ -3232,7 +3232,7 @@ "longitude": 10.752136 }, { - "lokalId": "95625b93-ad68-4dc9-afd4-bb29f9792b58", + "lokalId": "94fa665a-8ead-4914-a588-e7f476982ea1", "romnr": 20262, "plasser": 260, "adresse": "Kingosgt 17", @@ -3240,7 +3240,7 @@ "longitude": 10.751484 }, { - "lokalId": "82263184-bc90-4aba-bf6b-df5648691e05", + "lokalId": "bb7bc4ba-e7fe-462c-b12e-a623f04edb5a", "romnr": 20263, "plasser": 2000, "adresse": "T-banen - Jernbanetorget, nedgang Hotell clarion", @@ -3248,7 +3248,7 @@ "longitude": 10.751295 }, { - "lokalId": "21acd61f-abf7-4e71-ab04-a5bcf6833cbc", + "lokalId": "5076b6b5-4c13-48c5-a589-e8bdd9eeb326", "romnr": 20264, "plasser": 570, "adresse": "Akersgata 41", @@ -3256,7 +3256,7 @@ "longitude": 10.741865 }, { - "lokalId": "46943f13-2874-4e21-bfd7-87841b6d967d", + "lokalId": "b7f87e56-e0d0-4c99-84af-ee0eea9243ee", "romnr": 20265, "plasser": 3000, "adresse": "Akershus festning - Akershusstranda", @@ -3264,7 +3264,7 @@ "longitude": 10.734938 }, { - "lokalId": "ad71d7da-fb1d-449a-ae81-f12c769d4d5b", + "lokalId": "eaffb8a0-7b86-46cd-a3e8-2cac8f84f201", "romnr": 20266, "plasser": 250, "adresse": "Fredrik Stangsgt 37", @@ -3272,7 +3272,7 @@ "longitude": 10.70926 }, { - "lokalId": "cb90db04-9382-4175-b0c3-705a9992d171", + "lokalId": "cb623f44-cdd3-46bb-91ee-c9a3a4a300f0", "romnr": 20268, "plasser": 160, "adresse": "Bogstadveien 30", @@ -3280,7 +3280,7 @@ "longitude": 10.720795 }, { - "lokalId": "6f70b1c4-40a8-4bce-86bf-880db4d2b02f", + "lokalId": "dde700db-e9ae-40fe-8155-821f80177f01", "romnr": 20270, "plasser": 2500, "adresse": "T-banen - Carl Berners plass", @@ -3288,7 +3288,7 @@ "longitude": 10.777908 }, { - "lokalId": "002cf5ce-3d09-4025-baa2-3a17eef88974", + "lokalId": "59aaa0e0-ccfc-4cea-bde5-d5a49e812595", "romnr": 20272, "plasser": 3100, "adresse": "T-banen - Enerhaugen - Åkebergveien", @@ -3296,7 +3296,7 @@ "longitude": 10.769125 }, { - "lokalId": "1f03ff26-3174-4c15-a484-1120450f6ddb", + "lokalId": "8c9ff560-7c8e-47bc-aa3f-ab8cc33c2222", "romnr": 20275, "plasser": 330, "adresse": "Fagerheimgt 22", @@ -3304,7 +3304,7 @@ "longitude": 10.770913 }, { - "lokalId": "a39ad6e5-ba19-4406-9c9c-c438e6d66e80", + "lokalId": "48228949-a5d1-44f4-8f16-104f70009821", "romnr": 20277, "plasser": 460, "adresse": "Filipstadveien 15", @@ -3312,7 +3312,7 @@ "longitude": 10.713782 }, { - "lokalId": "cc2bb1a6-db8b-47b4-960e-5ad1ca3b333d", + "lokalId": "abb646d8-d6ff-45cb-9101-dcca6d92ebbe", "romnr": 20280, "plasser": 2000, "adresse": "T-banen - Grønland stasjon", @@ -3320,7 +3320,7 @@ "longitude": 10.758469 }, { - "lokalId": "65c7d9a6-70e4-4212-b992-a94a587115db", + "lokalId": "0f45ae26-8cf0-456e-ba6d-ec0015eacefb", "romnr": 20282, "plasser": 700, "adresse": "Hegdehaugsveien 36", @@ -3328,7 +3328,7 @@ "longitude": 10.7254 }, { - "lokalId": "6c415fe8-e7bf-492e-9564-090a03d73e86", + "lokalId": "b46c1247-89fb-46b9-94c1-0f7c94fcd5ea", "romnr": 20283, "plasser": 3000, "adresse": "T-banen - Nationalteater stasjon", @@ -3336,7 +3336,7 @@ "longitude": 10.733025 }, { - "lokalId": "7babca14-1734-42ae-83ab-2a91c983c56e", + "lokalId": "61fd7e86-20c6-4cf0-be4a-1126b0c57f92", "romnr": 20284, "plasser": 750, "adresse": "Tollbugata 40 / Nedre Vollgate 11", @@ -3344,7 +3344,7 @@ "longitude": 10.738037 }, { - "lokalId": "2368bf86-a924-4527-8e18-2ca5419e57e7", + "lokalId": "bcee5723-d21e-4323-a7dc-e680b27378cb", "romnr": 20285, "plasser": 400, "adresse": "T-banen - Oscarsgate 19", @@ -3352,7 +3352,7 @@ "longitude": 10.726896 }, { - "lokalId": "18302b31-4288-4698-8179-98259df4629d", + "lokalId": "a7dedb6e-bc85-4c7b-b95c-ea8c9e2c82bb", "romnr": 20286, "plasser": 1000, "adresse": "Schwensensgt 3/5", @@ -3360,7 +3360,7 @@ "longitude": 10.737924 }, { - "lokalId": "62d70710-2f9b-4d61-8cbe-c50b03e32b8b", + "lokalId": "704a51cc-c1ae-45d2-b9e7-4d170d1799af", "romnr": 20287, "plasser": 7000, "adresse": "T-banen - Stortinget stasjon", @@ -3368,7 +3368,7 @@ "longitude": 10.741858 }, { - "lokalId": "ff3edd06-7880-4411-9d3d-19e443ce7e1e", + "lokalId": "f3cf936a-bc9f-4470-97b9-ffc66c426b04", "romnr": 20288, "plasser": 760, "adresse": "Thorvald Meyersgate 7", @@ -3376,7 +3376,7 @@ "longitude": 10.758476 }, { - "lokalId": "78ecd274-838e-44a1-92cb-9effd833e1a9", + "lokalId": "4c2fd3da-865f-427f-9666-7eb2cb51c60a", "romnr": 20289, "plasser": 520, "adresse": "Trondheimsveien 80", @@ -3384,7 +3384,7 @@ "longitude": 10.77298 }, { - "lokalId": "6dd39d41-2fc1-476a-80d1-f50b88d9d883", + "lokalId": "841db36e-3e40-4bcd-a5ba-835420eff2ff", "romnr": 20290, "plasser": 3340, "adresse": "Torvet 6, Lillestrøm", @@ -3392,7 +3392,7 @@ "longitude": 11.04845 }, { - "lokalId": "4f7ded7a-e781-4349-92d5-f1ebe0912705", + "lokalId": "39693cf4-afe2-438c-bb0a-28339a489e7c", "romnr": 20292, "plasser": 4600, "adresse": "Tæruddalen 85, Tærudhallen", @@ -3400,7 +3400,7 @@ "longitude": 11.016283 }, { - "lokalId": "395e3d35-c128-405d-9322-f477af3c4d8c", + "lokalId": "d5e433c5-a5e6-47cf-b7ee-65ff3bbf789d", "romnr": 20293, "plasser": 4000, "adresse": "Nordlifaret 50, Skårerhallen", @@ -3408,7 +3408,7 @@ "longitude": 10.967033 }, { - "lokalId": "d92142c8-af77-4f22-b119-073e1cd84782", + "lokalId": "d9696a29-e389-408d-a330-5e47200d1dac", "romnr": 20296, "plasser": 70, "adresse": "Storgata 11 - Offentlig", @@ -3416,7 +3416,7 @@ "longitude": 11.173662 }, { - "lokalId": "c025a30b-5e53-4818-a429-80406140e890", + "lokalId": "353c305d-0574-48e4-8018-8b30e146c1a0", "romnr": 20300, "plasser": 580, "adresse": "Vigernesgt, Vigernes skole", @@ -3424,7 +3424,7 @@ "longitude": 11.071618 }, { - "lokalId": "9fe34f8a-c589-41e4-afc7-76c2ac653619", + "lokalId": "d61b70de-728f-4719-ad62-bdd0f9ec1fc4", "romnr": 20301, "plasser": 100, "adresse": "Engaveien 6 - Vitåsen (Garderåsen)", @@ -3432,7 +3432,7 @@ "longitude": 11.13152 }, { - "lokalId": "42e8885b-6373-4945-ac4b-505ccc07d5bc", + "lokalId": "de44332f-5480-48c6-b42e-ad81175ac98e", "romnr": 20302, "plasser": 300, "adresse": "Strømsveien 74, Gamle rådhus", @@ -3440,7 +3440,7 @@ "longitude": 11.01185 }, { - "lokalId": "839713ba-c119-42c7-9785-2b0d94001329", + "lokalId": "f4037707-0f0e-4a81-a4b0-887fabd539df", "romnr": 20665, "plasser": 500, "adresse": "Sveavegen 1-25 - Jessheimtunet - Offentlig", @@ -3448,7 +3448,7 @@ "longitude": 11.178132 }, { - "lokalId": "57b4df40-a6c3-4950-aaa7-60a4deda5833", + "lokalId": "e0a5f710-eb87-4018-988b-61e8eaab3810", "romnr": 20777, "plasser": 444, "adresse": "Bøstad skole, Vikingveien 459. Vestvågøy", @@ -3456,7 +3456,7 @@ "longitude": 13.751838 }, { - "lokalId": "ac3f2f62-e9f5-4561-8056-1b51fd2cf344", + "lokalId": "a88bd486-b22c-485f-835a-a4f9b3f28a3d", "romnr": 20798, "plasser": 650, "adresse": "Kjøpmannsgata 34", @@ -3464,7 +3464,7 @@ "longitude": 10.402294 }, { - "lokalId": "6bff1538-2303-4604-9df7-3ac0a4d39dfb", + "lokalId": "8873642e-a6fb-469e-888f-d37f72f8355e", "romnr": 20806, "plasser": 357, "adresse": "Hyttegata 2 \"Bjørneparken\"", @@ -3472,7 +3472,7 @@ "longitude": 9.648765 }, { - "lokalId": "b56e7cfa-eccc-46ba-91e2-dfeed5a41d6f", + "lokalId": "55cbec72-1c48-4aae-aaae-cd091cb3b32d", "romnr": 20837, "plasser": 95, "adresse": "Eidesbråtet 1", @@ -3480,7 +3480,7 @@ "longitude": 6.546907 }, { - "lokalId": "c0cbc75d-7dd9-40bf-9b6c-fa81393e2711", + "lokalId": "87ab8d2c-7ecc-4a49-9c97-78bab90c2eac", "romnr": 20853, "plasser": 2400, "adresse": "Flåtestadveien 5a Fjellhallen", @@ -3488,7 +3488,7 @@ "longitude": 10.803393 }, { - "lokalId": "066845c7-c663-449e-860c-119ec8acc03b", + "lokalId": "6b8da5bf-1939-426f-979a-0fca92b341f4", "romnr": 20860, "plasser": 2000, "adresse": "Komsa Fjellanlegg Alta Kommune", @@ -3496,7 +3496,7 @@ "longitude": 23.272672 }, { - "lokalId": "c55e0f8e-ba19-44e5-91fd-b3ed168e3322", + "lokalId": "cd9588d1-49e6-4b70-9293-4b8174620a3a", "romnr": 20901, "plasser": 300, "adresse": "Statlandvegen 13, Nord Statland", @@ -3504,7 +3504,7 @@ "longitude": 11.142948 }, { - "lokalId": "b2b727e1-6292-4240-991c-717457213149", + "lokalId": "0c126119-38c0-4b34-9eb6-a885aba47f74", "romnr": 21023, "plasser": 35, "adresse": "Jon Sunds veg 18", @@ -3512,7 +3512,7 @@ "longitude": 11.521303 }, { - "lokalId": "928ce163-777e-4c45-be14-aea4d911c83d", + "lokalId": "f78b46a3-c45e-498f-8017-93611272fdcf", "romnr": 21024, "plasser": 73, "adresse": "Munkedamsvegen 5", @@ -3520,7 +3520,7 @@ "longitude": 11.576904 }, { - "lokalId": "0fb2120a-ec91-4b12-8b8e-4e48d9e33026", + "lokalId": "326f8971-11e4-4957-bd25-1ed9e2c8a2f7", "romnr": 21025, "plasser": 1540, "adresse": "Torggata 1", @@ -3528,7 +3528,7 @@ "longitude": 11.560943 }, { - "lokalId": "1d834e1b-8197-473f-8386-b059649bb76d", + "lokalId": "4979144e-0973-4e3a-a2c0-5d747cd49242", "romnr": 21097, "plasser": 100, "adresse": "Industrivegen 17", @@ -3536,7 +3536,7 @@ "longitude": 7.779923 }, { - "lokalId": "f6df8442-b1a3-47fc-b599-c644b0696e88", + "lokalId": "e10c4557-e343-48be-b274-87e6865bd99f", "romnr": 21148, "plasser": 66, "adresse": "Håkon den godes gate 30", @@ -3544,7 +3544,7 @@ "longitude": 11.299777 }, { - "lokalId": "af7faecc-9f35-4dc1-b01a-c850b2646071", + "lokalId": "dc16c02a-178d-41a4-9338-9f477d732993", "romnr": 21163, "plasser": 80, "adresse": "Trekanten 2, Levanger", @@ -3552,7 +3552,7 @@ "longitude": 11.309466 }, { - "lokalId": "dc369401-4996-43dc-b343-4dfeb8ebe2f3", + "lokalId": "3107fd68-2741-4ca7-854c-fea1dea0174f", "romnr": 21224, "plasser": 388, "adresse": "Romsdalsvegen 2", @@ -3560,7 +3560,7 @@ "longitude": 8.561964 }, { - "lokalId": "a8fe6d3f-6a6a-467f-a0e3-9df58b5e29f7", + "lokalId": "9c99e679-f182-4d41-82be-98f25c32318c", "romnr": 21225, "plasser": 91, "adresse": "Ringvegen 13", @@ -3568,7 +3568,7 @@ "longitude": 8.57242 }, { - "lokalId": "9e3c45f0-e2a6-4a7b-90bb-8a0cb568c269", + "lokalId": "2807c2b3-a14e-41af-af3e-d6d5f7eec758", "romnr": 21257, "plasser": 400, "adresse": "Strandveien 6 Lysaker", @@ -3576,7 +3576,7 @@ "longitude": 10.639089 }, { - "lokalId": "e74d4611-0fef-420f-9b70-232be3414f03", + "lokalId": "432ef3f7-5027-40dc-8c98-87956d8cd312", "romnr": 21271, "plasser": 700, "adresse": "Tangen. Havnegata", @@ -3584,7 +3584,7 @@ "longitude": 10.231377 }, { - "lokalId": "d2ab12bc-c3f9-4e64-b234-645d0bdba829", + "lokalId": "466294b0-4cb1-43ac-9c92-8b574fca6998", "romnr": 21280, "plasser": 450, "adresse": "Strøket 15A (Trekanten)", @@ -3592,7 +3592,7 @@ "longitude": 10.432986 }, { - "lokalId": "cad89e8b-bb4e-4f03-814b-883f8f52a919", + "lokalId": "738a602f-8817-4b24-8d92-82a99d068bb5", "romnr": 25512, "plasser": 300, "adresse": "Tangen verft, Gamle Kragerøvei 12", @@ -3600,7 +3600,7 @@ "longitude": 9.416357 }, { - "lokalId": "5f92e392-0bc3-4b8c-99d9-ab5d03a550da", + "lokalId": "bf7609a7-e137-4498-8bc0-4937c53fc6c0", "romnr": 30651, "plasser": 55, "adresse": "Ulvahaugen 2", @@ -3608,7 +3608,7 @@ "longitude": 7.093615 }, { - "lokalId": "041fdfa4-11f8-425b-b5a9-1c1c823dba1a", + "lokalId": "a98079fe-424a-4ccd-8528-b1af5d93edd8", "romnr": 30653, "plasser": 80, "adresse": "industrivegen 24", @@ -3616,7 +3616,7 @@ "longitude": 5.001506 }, { - "lokalId": "dd81a619-3c2b-44ff-803b-59287511ac41", + "lokalId": "5243afb6-c6d7-477a-b83b-01215cde99b2", "romnr": 30654, "plasser": 120, "adresse": "Gate 1 110", @@ -3624,7 +3624,7 @@ "longitude": 5.113378 }, { - "lokalId": "cb93f4f9-4fed-48ac-8263-db2a23f2038c", + "lokalId": "1c65665d-0074-4511-b298-b689609e18a3", "romnr": 30655, "plasser": 197, "adresse": "Gate 1 129", @@ -3632,7 +3632,7 @@ "longitude": 5.114131 }, { - "lokalId": "42c2201f-93d0-4216-98e6-8129f8431a60", + "lokalId": "20799e7e-8dbe-4716-8215-86eae0ce1586", "romnr": 30656, "plasser": 155, "adresse": "Slettevollsholten 11", @@ -3640,7 +3640,7 @@ "longitude": 5.132493 }, { - "lokalId": "cfd9ed14-261c-4ecd-87c4-b79bb3ed4329", + "lokalId": "7eee6964-4c83-4bb7-9e9e-da07d9e47e58", "romnr": 30657, "plasser": 111, "adresse": "Strangata 52", @@ -3648,7 +3648,7 @@ "longitude": 5.035 }, { - "lokalId": "f6a03a38-7b9b-4f60-8ab4-59d416fedcc4", + "lokalId": "5cbf8341-b616-4941-980a-ffcff423df89", "romnr": 30658, "plasser": 160, "adresse": "Rennekleiva 2", @@ -3656,7 +3656,7 @@ "longitude": 5.902546 }, { - "lokalId": "49987aa8-66f1-4a8a-bfe2-1512ace0a6fe", + "lokalId": "90deea91-30f7-4a22-b132-69798e61b191", "romnr": 30659, "plasser": 795, "adresse": "Liavegen 35", @@ -3664,7 +3664,7 @@ "longitude": 5.836535 }, { - "lokalId": "32932953-f5b0-48f4-9967-946dc3ce0931", + "lokalId": "35811952-f6ec-4264-801e-080c4adbab3a", "romnr": 30660, "plasser": 40, "adresse": "Flåmsdalsvegen16", @@ -3672,7 +3672,7 @@ "longitude": 7.110099 }, { - "lokalId": "bed27b4e-9eee-44d5-8097-934670720009", + "lokalId": "853a6603-b7f4-47d1-97c3-03e2b06bf3a6", "romnr": 30667, "plasser": 220, "adresse": "Olav Tryggvasons gate 28", @@ -3680,7 +3680,7 @@ "longitude": 10.396615 }, { - "lokalId": "87cf8d80-3d1a-444b-b108-e5c9f1f44015", + "lokalId": "a204117d-5666-4bfd-8660-6e145908743d", "romnr": 30668, "plasser": 700, "adresse": "Otto Svedrups plass 4 - tidl. Øvre Torv 1", @@ -3688,7 +3688,7 @@ "longitude": 10.526027 }, { - "lokalId": "a79ee693-981f-426a-a914-76ed9e592457", + "lokalId": "3c5874bb-9daa-4381-8c0e-d984d3606a95", "romnr": 30671, "plasser": 800, "adresse": "Nedre Bakklandet 11 - 41", @@ -3696,7 +3696,7 @@ "longitude": 10.403588 }, { - "lokalId": "33c0c24d-de5f-4706-9118-afb1b5292674", + "lokalId": "e7ac9ffe-ec54-49fe-b337-6dd63c712f73", "romnr": 30672, "plasser": 1740, "adresse": "Strømsveien 9 Vassøyholtet", @@ -3704,7 +3704,7 @@ "longitude": 11.002169 }, { - "lokalId": "5025d167-cb9f-4126-8ae5-5ba10cee25f4", + "lokalId": "17428eac-5b32-4110-bf5c-52a05147f6c8", "romnr": 30673, "plasser": 500, "adresse": "Olav Kyrres gate 6 -Revmatismebygget - St. Olavs H", @@ -3712,7 +3712,7 @@ "longitude": 10.392047 }, { - "lokalId": "61589d1b-11c6-44a1-9eaf-ff392d6779d0", + "lokalId": "96eb9b68-92b6-4775-a1d1-4bcab05b6e38", "romnr": 30677, "plasser": 780, "adresse": "Østre Rosten 39 - Rostenhallen", @@ -3720,7 +3720,7 @@ "longitude": 10.380829 }, { - "lokalId": "259b29bb-77ba-42ea-9df6-5405f232b941", + "lokalId": "8d101272-f0f7-43dc-baf0-bbb0516efbd3", "romnr": 30678, "plasser": 513, "adresse": "Hasselbakken 5A og 5 C", @@ -3728,7 +3728,7 @@ "longitude": 10.495529 }, { - "lokalId": "dc2ed73e-4802-43e9-819d-250c420845ae", + "lokalId": "8cf00fcb-324c-4cc7-95da-6ecc848d9f85", "romnr": 30679, "plasser": 330, "adresse": "Oppdal Helsesenter", @@ -3736,7 +3736,7 @@ "longitude": 9.692609 }, { - "lokalId": "adbad10f-2a59-4e2d-a5bd-eeb886f6cdf5", + "lokalId": "c7760399-55bd-4778-8ac1-95ec1567a76b", "romnr": 31679, "plasser": 200, "adresse": "T - Senteret, Offentlig T-rom", @@ -3744,7 +3744,7 @@ "longitude": 9.665849 }, { - "lokalId": "21d80bec-acc5-48c9-bbf8-5bf913d19502", + "lokalId": "255e9184-51a9-48ff-a384-37e9325f9a2a", "romnr": 31749, "plasser": 820, "adresse": "Paradisveien 22", @@ -3752,7 +3752,7 @@ "longitude": 5.74174 }, { - "lokalId": "42c44dfc-20bd-4432-a134-4f9d15272a56", + "lokalId": "006a3506-c4df-4b0e-b219-5bb461783e5b", "romnr": 32760, "plasser": 1210, "adresse": "Olav Schousvei 2-8 plan B", @@ -3760,7 +3760,7 @@ "longitude": 10.781977 }, { - "lokalId": "5203bf2a-ff96-4ea6-842d-0f6770521dd5", + "lokalId": "749c9c64-a0ef-403a-bb5e-2b4f64beb9d5", "romnr": 36834, "plasser": 1000, "adresse": "Skippergata/ Johan Stangsplass 1", @@ -3768,7 +3768,7 @@ "longitude": 11.390087 }, { - "lokalId": "32c9e3e8-b9c6-466a-9eb4-b0c3bc0b51a1", + "lokalId": "10339d69-1263-4a6b-ba78-62a630159598", "romnr": 36835, "plasser": 760, "adresse": "Rødsfjellet/ Peder Ankersgt 7B", @@ -3776,7 +3776,7 @@ "longitude": 11.378465 }, { - "lokalId": "93a0a02b-1971-4f15-988a-0b9a51e8f570", + "lokalId": "b05f79fc-6579-427d-8864-f294d29f34c2", "romnr": 36836, "plasser": 1000, "adresse": "Oskleiva 18", @@ -3784,7 +3784,7 @@ "longitude": 11.394312 }, { - "lokalId": "d05a7428-3170-4da2-b2c8-e7f5893e9896", + "lokalId": "35d882b3-fad9-4ca6-9bb5-1d1de28d42ab", "romnr": 36837, "plasser": 75, "adresse": "Marker U. skole/ Skolegata 21,Ørje", @@ -3792,7 +3792,7 @@ "longitude": 11.657639 }, { - "lokalId": "5748270c-6c2e-478d-86ef-6fdd7cbce281", + "lokalId": "4c30b976-9700-44fb-80c9-f6363f1cd551", "romnr": 36838, "plasser": 114, "adresse": "Nordmyrveien 4/ Spydeberg", @@ -3800,7 +3800,7 @@ "longitude": 11.077031 }, { - "lokalId": "06499b33-6731-4e7e-8b8c-21cafbd84810", + "lokalId": "b342d973-69e4-43cc-bece-592998dacedf", "romnr": 36839, "plasser": 200, "adresse": "Allaktivitetshuset Spydeberg/ Stasjonsgata 33", @@ -3808,7 +3808,7 @@ "longitude": 11.081442 }, { - "lokalId": "7e59664b-b94d-4a10-9d8f-f57cc3de2f96", + "lokalId": "367f1e36-299a-446a-989e-77310dddcd87", "romnr": 36840, "plasser": 118, "adresse": "Grendehusveien 2J/ Saltnes", @@ -3816,7 +3816,7 @@ "longitude": 10.762224 }, { - "lokalId": "16985b7e-4a7c-4ba3-bdac-e7f95d43c4e9", + "lokalId": "ec83bf71-3f2e-4f85-aeba-464c537f2a18", "romnr": 36841, "plasser": 32, "adresse": "Råde Herredshus/ Skråtorpveien 2A", @@ -3824,7 +3824,7 @@ "longitude": 10.871347 }, { - "lokalId": "489dd901-54f9-45f5-b950-090519c2bd78", + "lokalId": "25f560a9-d22e-4469-a12e-3cc39ff51ffc", "romnr": 36842, "plasser": 2000, "adresse": "Øreåsen/Årvollskogen 97", @@ -3832,7 +3832,7 @@ "longitude": 10.696867 }, { - "lokalId": "13527cb7-868c-4360-8169-08f3d9472051", + "lokalId": "c0c120ff-5d61-46ca-9c4d-a0a1809f15ed", "romnr": 36843, "plasser": 50, "adresse": "Helse og sosialsenter", @@ -3840,7 +3840,7 @@ "longitude": 10.871204 }, { - "lokalId": "9adcfe8d-9eef-42a6-a49c-56eb647dc24a", + "lokalId": "362883ac-01b4-4dd6-ad8c-e4f8d35f8029", "romnr": 36844, "plasser": 90, "adresse": "Citadel/ Jernbanegata 4, Mysen", @@ -3848,7 +3848,7 @@ "longitude": 11.324296 }, { - "lokalId": "986d43df-ad16-4236-97c2-74788aa01225", + "lokalId": "ceb047ce-eeea-4f6d-af23-8c7dfd8aed8b", "romnr": 36845, "plasser": 114, "adresse": "Opsahlveien 1, Mysen", @@ -3856,7 +3856,7 @@ "longitude": 11.338877 }, { - "lokalId": "0df92ef5-2c1b-4aab-ac0e-272292721cee", + "lokalId": "03659f41-b9b2-4cd2-9992-0e45321eb02b", "romnr": 36846, "plasser": 124, "adresse": "Rakkestad og Degernes brannkas/ Storgt 13", @@ -3864,7 +3864,7 @@ "longitude": 11.342833 }, { - "lokalId": "da71bbf6-ffda-4122-ae4a-6bfd29fdfa10", + "lokalId": "2faf3239-bb70-4b1f-bf01-2d5b1f30e433", "romnr": 37868, "plasser": 100, "adresse": "Hunstadsenteret Hunstad Øst, offentlig", @@ -3872,7 +3872,7 @@ "longitude": 14.541747 }, { - "lokalId": "f06e4620-fe8e-4b55-bc41-a5d0b218491d", + "lokalId": "5cf74eab-2f4b-4d2f-bfc2-312cd118a197", "romnr": 37869, "plasser": 100, "adresse": "Jernbanevegen 7", @@ -3880,7 +3880,7 @@ "longitude": 9.237485 }, { - "lokalId": "9177fe37-d3fd-43b6-8335-a343357c6a52", + "lokalId": "c02933f2-48b5-4d7c-9090-d92b0515e302", "romnr": 37870, "plasser": 252, "adresse": "Hammersengvegen 62", @@ -3888,7 +3888,7 @@ "longitude": 10.462942 }, { - "lokalId": "e077a983-2a58-4f13-ac97-17f7d8c34ec6", + "lokalId": "37ddbe1a-0aef-451f-90cb-41e7ca6434be", "romnr": 37879, "plasser": 120, "adresse": "Gullfakse Barnehage - Nordbødalen 12", @@ -3896,7 +3896,7 @@ "longitude": 8.78905 }, { - "lokalId": "82fc7ba2-b7dc-4acd-8387-776610241c24", + "lokalId": "d9c4b1be-b79c-404e-b8a9-2fe673eb4359", "romnr": 37891, "plasser": 40, "adresse": "Rådhuset, Leknes", @@ -3904,7 +3904,7 @@ "longitude": 13.611536 }, { - "lokalId": "04b738d5-d442-4f93-ba21-baf6d3d92519", + "lokalId": "0a32a5d2-b619-401f-b024-0a1cd6df03a6", "romnr": 37914, "plasser": 288, "adresse": "Skogbrukets hus, fagerlidal 18", @@ -3912,7 +3912,7 @@ "longitude": 18.524782 }, { - "lokalId": "687c93b6-7df5-47cb-a046-5db4b0e4aaeb", + "lokalId": "5dac1979-2468-4bd9-a5c5-b0aed37ef0f4", "romnr": 37918, "plasser": 185, "adresse": "Hestmyrvegen 10", @@ -3920,7 +3920,7 @@ "longitude": 5.318194 }, { - "lokalId": "a07d59c9-b800-4213-b798-e03aedf50dd9", + "lokalId": "fc4be221-91e4-4df5-bd1b-ac93d97ac325", "romnr": 38930, "plasser": 856, "adresse": "Fannestrandvegen 49 b", @@ -3928,7 +3928,7 @@ "longitude": 7.182817 }, { - "lokalId": "4b9804e7-bd95-4334-b006-9757446c3405", + "lokalId": "922da813-0c76-41b0-baab-85d580d261f3", "romnr": 38931, "plasser": 2000, "adresse": "Kirkebakken 4A", @@ -3936,7 +3936,7 @@ "longitude": 7.160301 }, { - "lokalId": "9950b52e-0a32-4494-a65e-88fadbeb5f67", + "lokalId": "4c811cf0-6586-4bac-a047-78e5651332ff", "romnr": 38932, "plasser": 1000, "adresse": "Keiser Wilhelms gate 25", @@ -3944,7 +3944,7 @@ "longitude": 6.157965 }, { - "lokalId": "3206d3f9-9aae-42df-9126-5c1a5fe13dd6", + "lokalId": "8ad16650-d761-4ad3-8e5a-971b996c87c4", "romnr": 38933, "plasser": 70, "adresse": "Kometvegen 5", @@ -3952,7 +3952,7 @@ "longitude": 7.229242 }, { - "lokalId": "edd5b3fd-2a57-48be-96c6-6e1ceed48ff4", + "lokalId": "ef54b6e4-eff2-46b0-9434-1f0b50a32505", "romnr": 38934, "plasser": 100, "adresse": "Årøsetervegen 17", @@ -3960,7 +3960,7 @@ "longitude": 7.287248 }, { - "lokalId": "54ffc195-6f01-4cf0-b844-59d5aa1d3b41", + "lokalId": "f21ae9d4-22a1-418d-b9ae-57b423a66888", "romnr": 38937, "plasser": 150, "adresse": "Høglivegen 8", @@ -3968,7 +3968,7 @@ "longitude": 7.530679 }, { - "lokalId": "a93df078-e2c5-4d2e-8db6-27d39d3f8e99", + "lokalId": "ec406646-1b3c-4bc0-944c-7c99fd13b1b4", "romnr": 38938, "plasser": 80, "adresse": "Baklivegen 4", @@ -3976,7 +3976,7 @@ "longitude": 7.537625 }, { - "lokalId": "7af88e63-9a81-4cd8-bbcd-5a3dd360b567", + "lokalId": "cbe7bf39-51b0-4006-8033-ee04d98f96b7", "romnr": 38939, "plasser": 95, "adresse": "Hospitalgata 6 \"gamle sykehus\"", @@ -3984,7 +3984,7 @@ "longitude": 31.096688 }, { - "lokalId": "60afe513-12f6-4538-8289-6982d3fe75cb", + "lokalId": "c0860e99-1f66-4863-a94f-cd5b90470851", "romnr": 38945, "plasser": 70, "adresse": "Skorgeneset 31 / Møre og Romsdal Kornsilo", @@ -3992,7 +3992,7 @@ "longitude": 7.120192 }, { - "lokalId": "b6cf560d-7e89-4a6e-a075-da5d88f1f4c6", + "lokalId": "fc57c7bf-1721-43d6-b0bb-d1bd9b953f6c", "romnr": 38947, "plasser": 48, "adresse": "Tresfjordvegen 215", @@ -4000,7 +4000,7 @@ "longitude": 7.131404 }, { - "lokalId": "568b397e-5d67-4a80-bbb1-cb3bc1c3b6fa", + "lokalId": "21bb5cb8-5555-47b4-a703-fb38ba253c54", "romnr": 38950, "plasser": 40, "adresse": "Skulevegen 4", @@ -4008,7 +4008,7 @@ "longitude": 7.089993 }, { - "lokalId": "f43fd6f5-6655-45e0-9b71-5bf821b931aa", + "lokalId": "57dbbe76-fe42-4890-b3c9-18dccb5e2e4e", "romnr": 38952, "plasser": 100, "adresse": "Brugata 10", @@ -4016,7 +4016,7 @@ "longitude": 7.089782 }, { - "lokalId": "55f831c9-5dec-4bcc-9446-9f6613ef8bf1", + "lokalId": "c3043a37-366e-45fe-8965-71e28dcbfe9a", "romnr": 38954, "plasser": 65, "adresse": "Nybøvegen 2", @@ -4024,7 +4024,7 @@ "longitude": 6.931241 }, { - "lokalId": "09ba909c-c20a-4ef1-8a65-6a0c77111dd0", + "lokalId": "88a76c7e-3e99-44f6-a1e2-8a0bbf2981d5", "romnr": 38956, "plasser": 60, "adresse": "Skulebakken 1", @@ -4032,7 +4032,7 @@ "longitude": 7.126651 }, { - "lokalId": "ac5149a3-d229-4ba8-b920-c68d2bdf7132", + "lokalId": "5b856749-c512-4db9-b785-27e056393ab9", "romnr": 38958, "plasser": 75, "adresse": "Neremsvegen 4", @@ -4040,7 +4040,7 @@ "longitude": 7.126866 }, { - "lokalId": "cf2a7b37-0768-42be-a0e2-f90790be41fc", + "lokalId": "ef38480f-2b21-423f-b99d-baa672a7b920", "romnr": 38960, "plasser": 35, "adresse": "Remmemsvegen 85", @@ -4048,7 +4048,7 @@ "longitude": 7.098366 }, { - "lokalId": "5093f892-126e-4f30-ba59-7dcc6ca113b4", + "lokalId": "26385156-19df-4efa-af14-aad2b3e31801", "romnr": 38963, "plasser": 50, "adresse": "Vollan 1", @@ -4056,7 +4056,7 @@ "longitude": 7.688251 }, { - "lokalId": "2e3d29a8-eb7e-463b-8078-b01389700251", + "lokalId": "76cac8bd-3bae-4798-9891-4d389f0f5117", "romnr": 38964, "plasser": 40, "adresse": "Sørsidevegen 747", @@ -4064,7 +4064,7 @@ "longitude": 7.565888 }, { - "lokalId": "61328730-f5e9-4b31-826e-216a7812df57", + "lokalId": "e6b77c5d-2cf8-4412-8868-62e634ced6f9", "romnr": 38966, "plasser": 481, "adresse": "Vollan 8A", @@ -4072,7 +4072,7 @@ "longitude": 7.686241 }, { - "lokalId": "31a3030e-6d3d-4c76-906e-392e6609c8f5", + "lokalId": "cc806faf-c8e4-4cab-a57d-fe9ea9e2930c", "romnr": 38967, "plasser": 20, "adresse": "Prestgardsvegen 140", @@ -4080,7 +4080,7 @@ "longitude": 6.920707 }, { - "lokalId": "6fb90bc2-0cf0-47ec-a198-b0430c91f8a4", + "lokalId": "d1d95d19-f88e-40d2-94dd-b60c3e2687df", "romnr": 38969, "plasser": 90, "adresse": "Lundhaugvegen 34", @@ -4088,7 +4088,7 @@ "longitude": 6.915688 }, { - "lokalId": "04777990-c63b-41cd-a636-e026e9f5041e", + "lokalId": "384105c9-7be6-4d21-ae13-cce2cc6e2e62", "romnr": 38971, "plasser": 90, "adresse": "Torget 13A", @@ -4096,7 +4096,7 @@ "longitude": 7.163943 }, { - "lokalId": "b087468f-1504-4b1b-a179-2bc73f672064", + "lokalId": "21d24e6f-b7bb-4114-92d1-c4bc2785eeca", "romnr": 38973, "plasser": 55, "adresse": "Torget 14", @@ -4104,7 +4104,7 @@ "longitude": 7.164355 }, { - "lokalId": "478edb97-bbc5-466e-b2c2-19bda7788398", + "lokalId": "94167df7-6434-4ef1-9f76-98568395bac8", "romnr": 38975, "plasser": 20, "adresse": "Malmefjordvegen 18", @@ -4112,7 +4112,7 @@ "longitude": 7.235397 }, { - "lokalId": "b30254aa-b072-4875-b304-4f1ef6c1390c", + "lokalId": "74dde0c5-791f-47ac-8ec5-ee1e2254cc01", "romnr": 38976, "plasser": 22, "adresse": "Myrbostadvegen 72", @@ -4120,7 +4120,7 @@ "longitude": 7.188842 }, { - "lokalId": "fb7be88f-773e-4fc7-b8aa-da4c9c7c7fc7", + "lokalId": "9060a2a9-df04-4381-b0f3-7e387a1fdfd0", "romnr": 38977, "plasser": 578, "adresse": "Brendhaugen 7", @@ -4128,7 +4128,7 @@ "longitude": 5.876821 }, { - "lokalId": "466d2898-ec2f-426d-b97f-df3503096690", + "lokalId": "cdc75190-0c58-48d6-8d2a-447fc6ec807f", "romnr": 38981, "plasser": 60, "adresse": "Stemsvegen 13", @@ -4136,7 +4136,7 @@ "longitude": 7.163689 }, { - "lokalId": "39977567-ee17-45a5-895f-72902d0d2fb9", + "lokalId": "cb98153b-c4cf-4cc5-86a1-52a28eb20f95", "romnr": 39987, "plasser": 210, "adresse": "Engasveien 27 (Rørvik samfunnshus )", @@ -4144,7 +4144,7 @@ "longitude": 11.242084 }, { - "lokalId": "d7a61629-990e-4ec4-b2c9-e228828b1ef2", + "lokalId": "718b5c9c-86fb-47cd-8d1e-f3edc9308ceb", "romnr": 39990, "plasser": 75, "adresse": "Valderøyvegen 1129", @@ -4152,7 +4152,7 @@ "longitude": 6.12256 }, { - "lokalId": "340fbd10-b35f-4e25-b087-d6cdd7f2db8e", + "lokalId": "94d1acbe-6524-4bc7-b416-b53dc7b47e15", "romnr": 39993, "plasser": 143, "adresse": "Sloghaugvegen 3", @@ -4160,7 +4160,7 @@ "longitude": 6.190999 }, { - "lokalId": "b9bd9144-abe9-45ea-b590-b39643c3df13", + "lokalId": "5dcea644-90ae-477f-b53a-d16fb4c5f270", "romnr": 39995, "plasser": 167, "adresse": "Molværsvegen 74", @@ -4168,7 +4168,7 @@ "longitude": 6.183652 }, { - "lokalId": "cde9c3b8-6c04-4173-8d7a-3807e5d1645b", + "lokalId": "802feb84-68b7-4b63-847a-aee73b1ffe38", "romnr": 39997, "plasser": 83, "adresse": "Solavågseidet 76", @@ -4176,7 +4176,7 @@ "longitude": 6.315725 }, { - "lokalId": "21d54e53-a487-4484-88a7-79f18bae9f1b", + "lokalId": "ca094bbd-1492-4a7f-aa6a-b43e7ad1e4cf", "romnr": 40000, "plasser": 181, "adresse": "Langmyra 2", @@ -4184,7 +4184,7 @@ "longitude": 6.083092 }, { - "lokalId": "2cdb86e3-2f27-47e5-bb6e-6b2bd6dd35a9", + "lokalId": "091cc232-7b6f-4ee6-863c-b7af8500a804", "romnr": 40001, "plasser": 100, "adresse": "Torvmyrane 5", @@ -4192,7 +4192,7 @@ "longitude": 6.084963 }, { - "lokalId": "6c0d6313-1b3c-42b0-9f4a-175589f71ec2", + "lokalId": "e3cc9f58-6393-4f8c-bb20-13b4c91bfd2d", "romnr": 40002, "plasser": 257, "adresse": "Vikegata 17", @@ -4200,7 +4200,7 @@ "longitude": 6.124657 }, { - "lokalId": "7233c2f2-d3ef-47ec-94b7-cdaa5ed3567b", + "lokalId": "49a35cd3-d4b2-4db0-b2ee-962acb591028", "romnr": 41007, "plasser": 333, "adresse": "Aurdalslia 30, Aurdalslia skole", @@ -4208,7 +4208,7 @@ "longitude": 5.2816 }, { - "lokalId": "2b46db25-af44-4d29-a315-c086259018d7", + "lokalId": "3b092b5b-561e-40dc-86cc-ef089254d1a3", "romnr": 44298, "plasser": 300, "adresse": "Enggata 37", @@ -4216,7 +4216,7 @@ "longitude": 10.60403 }, { - "lokalId": "beeee155-6084-4ccc-9c1a-3bcf0c60b352", + "lokalId": "2ad0f533-9be5-49fe-b64a-ee8c8a8502e1", "romnr": 46455, "plasser": 200, "adresse": "Peder Hiorts gate 18 B, RØROS SKOLE", @@ -4224,7 +4224,7 @@ "longitude": 11.375244 }, { - "lokalId": "e8c9c459-861e-4ac3-a1d7-8450384627a0", + "lokalId": "ee118c9d-7e9d-4967-b27c-ef5f2bc50bc3", "romnr": 46465, "plasser": 222, "adresse": "Jærveien 107", @@ -4232,7 +4232,7 @@ "longitude": 5.723395 }, { - "lokalId": "d2e62169-a1e2-4c8c-8720-bd44a199b9fd", + "lokalId": "03b3d987-95ea-480e-9015-31d56c61cc13", "romnr": 48494, "plasser": 450, "adresse": "Mellomveien 5", @@ -4240,7 +4240,7 @@ "longitude": 10.430205 }, { - "lokalId": "2337e2f4-2589-4901-8b0f-797519393f97", + "lokalId": "26727e06-cd37-4092-a10f-c6f3235fd2c8", "romnr": 48512, "plasser": 9, "adresse": "Melkeveien 1", @@ -4248,7 +4248,7 @@ "longitude": 11.455099 }, { - "lokalId": "f9d58eda-ccfe-4c29-a67f-46314ad6bead", + "lokalId": "49e7f5ce-afa6-473c-89af-243993840b12", "romnr": 48513, "plasser": 42, "adresse": "Magnus den godes vei 9", @@ -4256,7 +4256,7 @@ "longitude": 11.469815 }, { - "lokalId": "4d160e7a-ae2f-42fc-af31-00e9d109bb6b", + "lokalId": "2a0b75bf-93ba-405a-9799-10a9e07166ec", "romnr": 48514, "plasser": 49, "adresse": "Hellbakkvegen 6", @@ -4264,7 +4264,7 @@ "longitude": 11.746377 }, { - "lokalId": "da4f909e-5dd0-4225-a406-781150e8fa52", + "lokalId": "a65f63c6-14e6-4e70-ac98-fbf0a2f6f257", "romnr": 48515, "plasser": 109, "adresse": "Gamle fergeveg 2", @@ -4272,7 +4272,7 @@ "longitude": 11.469551 }, { - "lokalId": "44f4226d-b0a2-46b1-870b-129c8d015b41", + "lokalId": "f81130c7-12fb-4e90-8355-c26feda16a7b", "romnr": 48516, "plasser": 42, "adresse": "Kirkegata 29", @@ -4280,7 +4280,7 @@ "longitude": 11.296883 }, { - "lokalId": "88a06fe3-9478-469d-bb56-64b8e72622ef", + "lokalId": "b05ef808-8571-4e74-badd-555ddcf0f56c", "romnr": 48518, "plasser": 75, "adresse": "Håkon den godes gate 17/19", @@ -4288,7 +4288,7 @@ "longitude": 11.298084 }, { - "lokalId": "480d14e6-4166-4aa6-b055-16a283d4499a", + "lokalId": "73190c2e-a6a5-4c4f-bcaa-7fce40f4bec4", "romnr": 48527, "plasser": 120, "adresse": "Nedregårdsvegen 1", @@ -4296,7 +4296,7 @@ "longitude": 6.363682 }, { - "lokalId": "706720c6-71c5-4567-b20a-fc265ba614c2", + "lokalId": "383ffc79-4478-46f6-ad20-3d6e8426a3b2", "romnr": 48535, "plasser": 30, "adresse": "Tingvold Park hotell, Gamle Kongeveg 47", @@ -4304,7 +4304,7 @@ "longitude": 11.491062 }, { - "lokalId": "0f331b8a-44c6-4898-9f9f-a21296b15d8e", + "lokalId": "6a437054-0e29-402e-b9aa-0e6f6144448c", "romnr": 48536, "plasser": 205, "adresse": "Guldbergaunet, Svedjanvegen", @@ -4312,7 +4312,7 @@ "longitude": 11.514335 }, { - "lokalId": "00de4af4-5f78-495a-b013-9fce3b9ff296", + "lokalId": "ba0f5030-7db8-4652-bdd5-ebbe8044f1be", "romnr": 48537, "plasser": 150, "adresse": "Nedre Sannan", @@ -4320,7 +4320,7 @@ "longitude": 11.499408 }, { - "lokalId": "e9d71ef8-2f81-4d29-aaf2-5e6a6607309e", + "lokalId": "277c9a29-0a7f-4e88-9b01-32431a5e2aab", "romnr": 48538, "plasser": 70, "adresse": "Skolegata 22", @@ -4328,7 +4328,7 @@ "longitude": 11.499952 }, { - "lokalId": "d70a487e-b787-49ad-a996-2926394a1e99", + "lokalId": "1a2c199f-dcad-4232-bb9e-981f19126667", "romnr": 48561, "plasser": 274, "adresse": "Åkersgata 4/Ticogården", @@ -4336,7 +4336,7 @@ "longitude": 8.565769 }, { - "lokalId": "cbf7edbc-f63f-4062-8c06-134b516be1f7", + "lokalId": "df2cbd86-2f85-4969-b671-a8fda9379bf5", "romnr": 48565, "plasser": 108, "adresse": "Kjøpmannsgata 15", @@ -4344,7 +4344,7 @@ "longitude": 6.027618 }, { - "lokalId": "2cbd75a9-a131-4060-8b6c-2a2348ccb158", + "lokalId": "b8430615-0269-43b2-b84e-4c385ce1983b", "romnr": 48566, "plasser": 58, "adresse": "Strandgata 72-74", @@ -4352,7 +4352,7 @@ "longitude": 6.028899 }, { - "lokalId": "4a167787-177e-4078-a27f-6dc8e341c5fe", + "lokalId": "fe3943b3-caf7-424c-b551-c1761d83a792", "romnr": 48570, "plasser": 20, "adresse": "Strandgata 106-114", @@ -4360,7 +4360,7 @@ "longitude": 6.02943 }, { - "lokalId": "30dfd473-5d8e-45f2-961b-767586ee7226", + "lokalId": "d9e59722-ecb2-4c90-8e19-841bb3a32a53", "romnr": 48571, "plasser": 270, "adresse": "Gymnasvegen 2", @@ -4368,7 +4368,7 @@ "longitude": 6.068552 }, { - "lokalId": "b0bc19f5-625f-4878-936f-f6b6ace09ab5", + "lokalId": "e8cebb2e-e053-4019-bc15-de28b196e976", "romnr": 48572, "plasser": 62, "adresse": "Dalevegen 24", @@ -4376,7 +4376,7 @@ "longitude": 6.134409 }, { - "lokalId": "b506c2d6-a2da-4298-b6cd-cfff216a9066", + "lokalId": "99c67ab5-ed09-454e-bb74-9d182f5b375a", "romnr": 48573, "plasser": 448, "adresse": "Sjøgata 3", @@ -4384,7 +4384,7 @@ "longitude": 5.852225 }, { - "lokalId": "3b52a0e0-37b5-42cb-94e8-02829ead1d03", + "lokalId": "d030a470-eefe-47df-9436-fe9154fe9067", "romnr": 48576, "plasser": 22, "adresse": "Spjelkavikvegen 130", @@ -4392,7 +4392,7 @@ "longitude": 6.358058 }, { - "lokalId": "f80e14e3-5fe5-41a0-a94e-77670f8c61df", + "lokalId": "49a1b8c1-838e-4e4c-9aac-3de3a6773b4e", "romnr": 48577, "plasser": 40, "adresse": "Skulevegen 16", @@ -4400,7 +4400,7 @@ "longitude": 6.211076 }, { - "lokalId": "6964ab63-02db-48c8-8a21-528d707535a8", + "lokalId": "ddd641a5-0d3f-499f-b0c9-295a015860f9", "romnr": 48578, "plasser": 81, "adresse": "Valderhaug 4", @@ -4408,7 +4408,7 @@ "longitude": 6.134682 }, { - "lokalId": "1f7ec0bc-1ef4-4e37-926b-bf2414dbaa1c", + "lokalId": "0399ecdf-76e5-4d51-acea-461d78b628d1", "romnr": 48580, "plasser": 50, "adresse": "Morkafura 8", @@ -4416,7 +4416,7 @@ "longitude": 6.038961 }, { - "lokalId": "51f05b0f-7065-4298-8fdb-b00543fdf871", + "lokalId": "a73e70be-0ecc-46c9-ae42-aca22d151255", "romnr": 48604, "plasser": 7000, "adresse": "Fjellanlegg - Tromsø parkering", @@ -4424,7 +4424,7 @@ "longitude": 18.954024 }, { - "lokalId": "f1bc391f-3be9-4323-bade-930cdaaefb65", + "lokalId": "7f32a916-eaa1-4d5e-8dca-e5c15ff40189", "romnr": 48632, "plasser": 375, "adresse": "Tømmeråsv. 3 - Svelvik Samfunnshus (off)", @@ -4432,7 +4432,7 @@ "longitude": 10.405089 }, { - "lokalId": "f2ca9fd6-7c7e-483a-95ce-2e5ca480e41f", + "lokalId": "1b9c22b2-3eb4-4872-a33d-904f0c296e9f", "romnr": 48661, "plasser": 0, "adresse": "Mikkelsmyrveien 3B", @@ -4440,7 +4440,7 @@ "longitude": 7.476917 }, { - "lokalId": "c3572f1d-8cd6-468c-afd7-a3bcb9a8d05f", + "lokalId": "7dbe8429-3d83-408b-a475-ba2d92c815eb", "romnr": 5826, "plasser": 150, "adresse": "Dr. Wessels gate 7", diff --git a/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt b/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt index 24a06ca..a08bb49 100644 --- a/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt +++ b/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt @@ -5,14 +5,18 @@ import android.content.Context import android.content.Intent import android.view.HapticFeedbackConstants import android.content.pm.PackageManager +import android.graphics.Bitmap +import android.graphics.Canvas import android.hardware.Sensor import android.hardware.SensorEvent import android.hardware.SensorEventListener import android.hardware.SensorManager import android.location.Location +import android.location.LocationManager import android.net.ConnectivityManager import android.net.NetworkCapabilities import android.net.Uri +import android.os.Build import android.os.Bundle import android.provider.Settings import android.util.Log @@ -40,8 +44,8 @@ import no.naiv.tilfluktsrom.location.ShelterFinder import no.naiv.tilfluktsrom.location.ShelterWithDistance import no.naiv.tilfluktsrom.ui.CivilDefenseInfoDialog import no.naiv.tilfluktsrom.ui.ShelterListAdapter +import no.naiv.tilfluktsrom.ui.ShelterListItem import no.naiv.tilfluktsrom.util.DistanceUtils -import no.naiv.tilfluktsrom.widget.ShelterWidgetProvider import org.osmdroid.util.GeoPoint import org.osmdroid.views.CustomZoomButtonsController import org.osmdroid.views.overlay.Marker @@ -70,6 +74,14 @@ class MainActivity : AppCompatActivity(), SensorEventListener { private var deviceHeading = 0f private var isCompassMode = false private var cachingJob: Job? = null + private var refreshJob: Job? = null + + // Whether to consider showing the map-cache prompt on the next location + // update. Mirrors the PWA's firstLocationFix flag: we only prompt once per + // session, regardless of whether the user accepts or skips. Without this + // guard, every location update re-checks hasCacheForLocation and re-shows + // the prompt if the user previously chose "Skip". + private var mapCachePromptPending = true // Map from shelter lokalId to its map marker, for icon swapping on selection private var shelterMarkerMap: MutableMap = mutableMapOf() private var highlightedMarkerId: String? = null @@ -77,8 +89,14 @@ class MainActivity : AppCompatActivity(), SensorEventListener { // Whether a compass sensor is available on this device private var hasCompassSensor = false - // Deep link: shelter ID to select once data is loaded - private var pendingDeepLinkShelterId: String? = null + // Deep link: shelter to select once data is loaded. + // We key on `romnr` (DSB's room number) rather than `lokalId` because + // upstream Geonorge re-rolls the lokalId UUID on every export. Two + // devices that fetched at different times have different lokalIds for + // the same physical shelter, breaking cross-device share links. + // Romnr is the actual DSB business key and is stable across exports. + // See ARCHITECTURE.md → "Deep link identifier". + private var pendingDeepLinkRomnr: Int? = null // The currently selected shelter — can be any shelter, not just one from nearestShelters private var selectedShelter: ShelterWithDistance? = null @@ -96,27 +114,9 @@ class MainActivity : AppCompatActivity(), SensorEventListener { if (fineGranted || coarseGranted) { startLocationUpdates() } else { - // Check if user permanently denied (don't show rationale = permanently denied) - val shouldShowRationale = ActivityCompat.shouldShowRequestPermissionRationale( - this, Manifest.permission.ACCESS_FINE_LOCATION - ) - if (!shouldShowRationale) { - // Permission permanently denied — guide user to settings - AlertDialog.Builder(this) - .setTitle(R.string.permission_location_title) - .setMessage(R.string.permission_denied) - .setPositiveButton(android.R.string.ok) { _, _ -> - val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { - data = Uri.fromParts("package", packageName, null) - } - startActivity(intent) - } - .setNegativeButton(android.R.string.cancel, null) - .show() - } else { - Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_LONG).show() - } + Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_LONG).show() } + updateLocationStatusBanner() } override fun onCreate(savedInstanceState: Bundle?) { @@ -148,7 +148,9 @@ class MainActivity : AppCompatActivity(), SensorEventListener { } /** - * Handle https://{domain}/shelter/{lokalId} deep link. + * Handle https://{domain}/shelter/{romnr} deep link. + * `romnr` is DSB's stable shelter room number — see field comment on + * pendingDeepLinkRomnr for why we don't use lokalId. * If shelters are already loaded, select immediately; otherwise store as pending. */ private fun handleDeepLinkIntent(intent: Intent?) { @@ -157,15 +159,15 @@ class MainActivity : AppCompatActivity(), SensorEventListener { uri.host != BuildConfig.DEEP_LINK_DOMAIN || uri.path?.startsWith("/shelter/") != true) return - val lokalId = uri.lastPathSegment ?: return + val romnr = uri.lastPathSegment?.toIntOrNull() ?: return // Clear intent data so config changes don't re-trigger intent.data = null - val shelter = allShelters.find { it.lokalId == lokalId } + val shelter = allShelters.find { it.romnr == romnr } if (shelter != null) { selectShelterByData(shelter) } else { - pendingDeepLinkShelterId = lokalId + pendingDeepLinkRomnr = romnr } } @@ -187,14 +189,37 @@ class MainActivity : AppCompatActivity(), SensorEventListener { false // Don't consume the event } - // Add user location overlay + // Add user location overlay. OSMDroid's stock person/arrow bitmaps + // are pure white and disappear on light tiles - replace with + // app-themed icons that have a white halo + drop shadow so the + // silhouette stays visible on any tile theme (Forgejo #16). myLocationOverlay = MyLocationNewOverlay( GpsMyLocationProvider(this@MainActivity), this - ) + ).apply { + drawableToBitmap(R.drawable.ic_user_dot, sizeDp = 24)?.let { + setPersonIcon(it) + setPersonAnchor(0.5f, 0.5f) + } + drawableToBitmap(R.drawable.ic_user_arrow, sizeDp = 32)?.let { + setDirectionIcon(it) + setDirectionAnchor(0.5f, 0.5f) + } + } overlays.add(myLocationOverlay) } } + private fun drawableToBitmap(@androidx.annotation.DrawableRes resId: Int, sizeDp: Int): Bitmap? { + val drawable = ContextCompat.getDrawable(this, resId) ?: return null + val sizePx = (sizeDp * resources.displayMetrics.density).toInt().coerceAtLeast(1) + val bitmap = Bitmap.createBitmap(sizePx, sizePx, Bitmap.Config.ARGB_8888) + Canvas(bitmap).also { canvas -> + drawable.setBounds(0, 0, sizePx, sizePx) + drawable.draw(canvas) + } + return bitmap + } + private fun setupShelterList() { shelterAdapter = ShelterListAdapter { swd -> userSelectedShelter = true @@ -260,6 +285,8 @@ class MainActivity : AppCompatActivity(), SensorEventListener { } private fun loadData() { + updateLocationStatusBanner() + lifecycleScope.launch { try { var hasData = repository.hasCachedData() @@ -296,9 +323,9 @@ class MainActivity : AppCompatActivity(), SensorEventListener { updateShelterMarkers() // Process pending deep links now that shelter data is available - pendingDeepLinkShelterId?.let { id -> - pendingDeepLinkShelterId = null - val shelter = shelters.find { it.lokalId == id } + pendingDeepLinkRomnr?.let { romnr -> + pendingDeepLinkRomnr = null + val shelter = shelters.find { it.romnr == romnr } if (shelter != null) { selectShelterByData(shelter) } else { @@ -379,6 +406,44 @@ class MainActivity : AppCompatActivity(), SensorEventListener { ) } + private fun updateLocationStatusBanner() { + val banner = binding.noLocationBanner + val text = binding.locationBannerText + val action = binding.locationBannerAction + + when { + !locationProvider.hasLocationPermission() -> { + text.setText(R.string.status_location_permission_needed) + action.setText(R.string.action_grant_permission) + action.setOnClickListener { + startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { + data = Uri.fromParts("package", packageName, null) + }) + } + banner.visibility = View.VISIBLE + } + !isLocationServicesEnabled() -> { + text.setText(R.string.status_location_services_off) + action.setText(R.string.action_location_settings) + action.setOnClickListener { + startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)) + } + banner.visibility = View.VISIBLE + } + else -> banner.visibility = View.GONE + } + } + + private fun isLocationServicesEnabled(): Boolean { + val lm = getSystemService(Context.LOCATION_SERVICE) as? LocationManager ?: return false + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + lm.isLocationEnabled + } else { + lm.isProviderEnabled(LocationManager.GPS_PROVIDER) || + lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER) + } + } + private fun startLocationUpdates() { // Use repeatOnLifecycle(STARTED) so GPS stops when Activity is paused lifecycleScope.launch { @@ -386,7 +451,6 @@ class MainActivity : AppCompatActivity(), SensorEventListener { try { locationProvider.locationUpdates().collectLatest { location -> currentLocation = location - saveLastLocation(location) updateNearestShelters(location) // Center map on first location fix @@ -396,11 +460,14 @@ class MainActivity : AppCompatActivity(), SensorEventListener { ) } - // Cache map tiles on first launch - if (!mapCacheManager.hasCacheForLocation(location.latitude, location.longitude)) { - if (isNetworkAvailable()) { - cacheMapTiles(location.latitude, location.longitude) - } + // Cache map tiles on first launch — at most one prompt + // per session so a "Skip" decision sticks. + if (mapCachePromptPending && + !mapCacheManager.hasCacheForLocation(location.latitude, location.longitude) && + isNetworkAvailable() + ) { + mapCachePromptPending = false + cacheMapTiles(location.latitude, location.longitude) } } } catch (e: CancellationException) { @@ -420,26 +487,60 @@ class MainActivity : AppCompatActivity(), SensorEventListener { allShelters, location.latitude, location.longitude, NEAREST_COUNT ) - // Highlight which nearest-list item matches the current selection - val selectedIdx = if (selectedShelter != null) { - nearestShelters.indexOfFirst { it.shelter.lokalId == selectedShelter!!.shelter.lokalId } - } else -1 - - shelterAdapter.submitList(nearestShelters) - shelterAdapter.selectPosition(selectedIdx) - if (userSelectedShelter && selectedShelter != null) { // Recalculate distance/bearing for the user's picked shelter refreshSelectedShelterDistance(location) + rebuildShelterList() + updateSelectedShelterUI() + } else if (nearestShelters.isNotEmpty()) { + // Auto-select nearest; selectShelter handles list rebuild + UI + selectShelter(nearestShelters[0]) } else { - // Auto-select nearest - if (nearestShelters.isNotEmpty()) { - selectShelter(nearestShelters[0]) - } + rebuildShelterList() + updateSelectedShelterUI() + } + } + + /** + * Rebuild the bottom-sheet list from the current nearest set + selection. + * + * Hybrid behaviour for Forgejo #13: when a shelter has been explicitly + * selected (deep link, marker tap, ...) and is *not* among the N nearest, + * append it to the list with an "outside nearest" badge so the user can + * see what they selected. The list also auto-scrolls to the selected + * row, so a manually-picked nearby entry comes into view too. + */ + private fun rebuildShelterList() { + val items = nearestShelters + .map { ShelterListItem(it, isOutsideNearest = false) } + .toMutableList() + + val selected = selectedShelter + val isSelectedAmongNearest = selected != null && + nearestShelters.any { it.shelter.lokalId == selected.shelter.lokalId } + if (selected != null && !isSelectedAmongNearest) { + // Only flag as "outside nearest" when there *is* a nearest list to + // contrast with - otherwise the selection is just the only entry. + items.add( + ShelterListItem( + selected, + isOutsideNearest = nearestShelters.isNotEmpty() + ) + ) } - updateSelectedShelterUI() - ShelterWidgetProvider.requestUpdate(this) + shelterAdapter.submitList(items) + + val selectedIdx = if (selected != null) { + items.indexOfFirst { it.swd.shelter.lokalId == selected.shelter.lokalId } + } else -1 + shelterAdapter.selectPosition(selectedIdx) + + if (selectedIdx >= 0) { + binding.shelterList.post { + binding.shelterList.smoothScrollToPosition(selectedIdx) + } + } } /** @@ -450,10 +551,7 @@ class MainActivity : AppCompatActivity(), SensorEventListener { selectedShelter = swd currentLocation?.let { refreshSelectedShelterDistance(it) } - // Update list highlight - val idx = nearestShelters.indexOfFirst { it.shelter.lokalId == swd.shelter.lokalId } - shelterAdapter.selectPosition(idx) - + rebuildShelterList() updateSelectedShelterUI() } @@ -660,14 +758,26 @@ class MainActivity : AppCompatActivity(), SensorEventListener { return } - lifecycleScope.launch { - binding.statusText.text = getString(R.string.status_updating) - val success = repository.refreshData() - if (success) { - updateFreshnessIndicator() - Toast.makeText(this@MainActivity, R.string.update_success, Toast.LENGTH_SHORT).show() - } else { - Toast.makeText(this@MainActivity, R.string.update_failed, Toast.LENGTH_SHORT).show() + // Guard against double-tap / overlapping refreshes. Without this, the + // user can fire several refreshData() calls that serialize on the + // single Room write-lock and stack 30–90 s of OkHttp timeouts on top + // of each other — perceived as "hang" with no feedback. + if (refreshJob?.isActive == true) return + + binding.statusText.text = getString(R.string.status_updating) + showLoading(getString(R.string.loading_shelters)) + + refreshJob = lifecycleScope.launch { + try { + val success = repository.refreshData() + if (success) { + updateFreshnessIndicator() + Toast.makeText(this@MainActivity, R.string.update_success, Toast.LENGTH_SHORT).show() + } else { + Toast.makeText(this@MainActivity, R.string.update_failed, Toast.LENGTH_SHORT).show() + } + } finally { + hideLoading() } } } @@ -685,7 +795,10 @@ class MainActivity : AppCompatActivity(), SensorEventListener { } val shelter = selected.shelter - val deepLink = "https://${BuildConfig.DEEP_LINK_DOMAIN}/shelter/${shelter.lokalId}" + // Path component is romnr (stable DSB business key), not lokalId — + // upstream re-rolls lokalId on every Geonorge export, which would + // break cross-device links. See pendingDeepLinkRomnr comment. + val deepLink = "https://${BuildConfig.DEEP_LINK_DOMAIN}/shelter/${shelter.romnr}" val body = getString( R.string.share_body, shelter.adresse, @@ -745,15 +858,6 @@ class MainActivity : AppCompatActivity(), SensorEventListener { binding.selectedShelterDetails.text = getString(R.string.status_shelters_loaded, allShelters.size) } - /** Persist last GPS fix so the widget can use it even when the app isn't running. */ - private fun saveLastLocation(location: Location) { - getSharedPreferences("widget_prefs", Context.MODE_PRIVATE).edit() - .putFloat("last_lat", location.latitude.toFloat()) - .putFloat("last_lon", location.longitude.toFloat()) - .putLong("last_time", System.currentTimeMillis()) - .apply() - } - private fun isNetworkAvailable(): Boolean { val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager ?: return false @@ -769,6 +873,10 @@ class MainActivity : AppCompatActivity(), SensorEventListener { binding.mapView.onResume() myLocationOverlay?.enableMyLocation() + // Re-check permission + location-services state so the banner updates + // when the user returns from Settings. + updateLocationStatusBanner() + val sm = sensorManager ?: return // Try rotation vector first (best compass source) diff --git a/app/src/main/java/no/naiv/tilfluktsrom/data/ShelterRepository.kt b/app/src/main/java/no/naiv/tilfluktsrom/data/ShelterRepository.kt index a554375..e6f130a 100644 --- a/app/src/main/java/no/naiv/tilfluktsrom/data/ShelterRepository.kt +++ b/app/src/main/java/no/naiv/tilfluktsrom/data/ShelterRepository.kt @@ -46,7 +46,7 @@ class ShelterRepository(private val context: Context) { .readTimeout(60, TimeUnit.SECONDS) .addInterceptor(Interceptor { chain -> chain.proceed(chain.request().newBuilder() - .header("User-Agent", "Tilfluktsrom/1.9.1") + .header("User-Agent", "Tilfluktsrom/1.10.2") .build()) }) .build() diff --git a/app/src/main/java/no/naiv/tilfluktsrom/ui/AboutDialog.kt b/app/src/main/java/no/naiv/tilfluktsrom/ui/AboutDialog.kt index 712562e..a6865b7 100644 --- a/app/src/main/java/no/naiv/tilfluktsrom/ui/AboutDialog.kt +++ b/app/src/main/java/no/naiv/tilfluktsrom/ui/AboutDialog.kt @@ -1,10 +1,13 @@ package no.naiv.tilfluktsrom.ui import android.os.Bundle +import android.text.Html +import android.text.method.LinkMovementMethod import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.WindowManager +import android.widget.TextView import androidx.fragment.app.DialogFragment import no.naiv.tilfluktsrom.R @@ -28,7 +31,12 @@ class AboutDialog : DialogFragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View { - return inflater.inflate(R.layout.dialog_about, container, false) + val view = inflater.inflate(R.layout.dialog_about, container, false) + view.findViewById(R.id.about_data_links).apply { + text = Html.fromHtml(getString(R.string.about_data_links), Html.FROM_HTML_MODE_COMPACT) + movementMethod = LinkMovementMethod.getInstance() + } + return view } override fun onStart() { diff --git a/app/src/main/java/no/naiv/tilfluktsrom/ui/ShelterListAdapter.kt b/app/src/main/java/no/naiv/tilfluktsrom/ui/ShelterListAdapter.kt index f4a7307..e33eb85 100644 --- a/app/src/main/java/no/naiv/tilfluktsrom/ui/ShelterListAdapter.kt +++ b/app/src/main/java/no/naiv/tilfluktsrom/ui/ShelterListAdapter.kt @@ -2,6 +2,7 @@ package no.naiv.tilfluktsrom.ui import android.view.HapticFeedbackConstants import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter @@ -11,12 +12,23 @@ import no.naiv.tilfluktsrom.databinding.ItemShelterBinding import no.naiv.tilfluktsrom.location.ShelterWithDistance import no.naiv.tilfluktsrom.util.DistanceUtils +/** + * One row in the bottom-sheet list. The list normally holds the N nearest + * shelters to the user, but a deep-linked / explicitly-selected shelter that + * is *not* among them is appended with isOutsideNearest=true so the user can + * see what they picked. See Forgejo #13 / beads tilfluktsrom-9sf. + */ +data class ShelterListItem( + val swd: ShelterWithDistance, + val isOutsideNearest: Boolean +) + /** * Adapter for the list of nearest shelters shown in the bottom sheet. */ class ShelterListAdapter( private val onShelterSelected: (ShelterWithDistance) -> Unit -) : ListAdapter(DIFF_CALLBACK) { +) : ListAdapter(DIFF_CALLBACK) { private var selectedPosition = 0 @@ -42,23 +54,34 @@ class ShelterListAdapter( private val binding: ItemShelterBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(item: ShelterWithDistance, isSelected: Boolean) { + fun bind(item: ShelterListItem, isSelected: Boolean) { val ctx = binding.root.context - binding.shelterAddress.text = item.shelter.adresse - binding.shelterDistance.text = DistanceUtils.formatDistance(item.distanceMeters) + val swd = item.swd + binding.shelterAddress.text = swd.shelter.adresse + binding.shelterDistance.text = DistanceUtils.formatDistance(swd.distanceMeters) binding.shelterCapacity.text = ctx.getString( - R.string.shelter_capacity, item.shelter.plasser + R.string.shelter_capacity, swd.shelter.plasser ) binding.shelterRoomNr.text = ctx.getString( - R.string.shelter_room_nr, item.shelter.romnr + R.string.shelter_room_nr, swd.shelter.romnr ) - binding.root.contentDescription = ctx.getString( + binding.outsideNearestBadge.visibility = + if (item.isOutsideNearest) View.VISIBLE else View.GONE + + // Build accessible description; suffix the badge text so screen- + // reader users learn the same context that sighted users see. + val baseDesc = ctx.getString( R.string.content_desc_shelter_item, - item.shelter.adresse, - DistanceUtils.formatDistance(item.distanceMeters), - item.shelter.plasser + swd.shelter.adresse, + DistanceUtils.formatDistance(swd.distanceMeters), + swd.shelter.plasser ) + binding.root.contentDescription = if (item.isOutsideNearest) { + ctx.getString(R.string.shelter_outside_nearest_badge) + ". " + baseDesc + } else { + baseDesc + } binding.root.isSelected = isSelected binding.root.alpha = if (isSelected) 1.0f else 0.7f @@ -68,18 +91,18 @@ class ShelterListAdapter( val pos = adapterPosition if (pos != RecyclerView.NO_POSITION) { selectPosition(pos) - onShelterSelected(getItem(pos)) + onShelterSelected(getItem(pos).swd) } } } } companion object { - private val DIFF_CALLBACK = object : DiffUtil.ItemCallback() { - override fun areItemsTheSame(a: ShelterWithDistance, b: ShelterWithDistance) = - a.shelter.lokalId == b.shelter.lokalId + private val DIFF_CALLBACK = object : DiffUtil.ItemCallback() { + override fun areItemsTheSame(a: ShelterListItem, b: ShelterListItem) = + a.swd.shelter.lokalId == b.swd.shelter.lokalId - override fun areContentsTheSame(a: ShelterWithDistance, b: ShelterWithDistance) = + override fun areContentsTheSame(a: ShelterListItem, b: ShelterListItem) = a == b } } diff --git a/app/src/main/res/drawable/ic_user_arrow.xml b/app/src/main/res/drawable/ic_user_arrow.xml new file mode 100644 index 0000000..57d5b09 --- /dev/null +++ b/app/src/main/res/drawable/ic_user_arrow.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_user_dot.xml b/app/src/main/res/drawable/ic_user_dot.xml new file mode 100644 index 0000000..1f3214a --- /dev/null +++ b/app/src/main/res/drawable/ic_user_dot.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 2c43bcf..f00127b 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -76,7 +76,7 @@ android:layout_width="match_parent" android:layout_height="0dp" android:contentDescription="@string/a11y_map" - app:layout_constraintTop_toBottomOf="@id/statusBar" + app:layout_constraintTop_toBottomOf="@id/noLocationBanner" app:layout_constraintBottom_toTopOf="@id/bottomSheet" /> @@ -87,7 +87,7 @@ android:background="@color/compass_bg" android:contentDescription="@string/a11y_compass" android:visibility="gone" - app:layout_constraintTop_toBottomOf="@id/statusBar" + app:layout_constraintTop_toBottomOf="@id/noLocationBanner" app:layout_constraintBottom_toTopOf="@id/bottomSheet"> + + + + + + + + + + + + - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index aa0f1f0..00c2cff 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -20,7 +20,6 @@ %d plasser Rom %d - Nærmeste tilfluktsrom Ingen tilfluktsromdata tilgjengelig @@ -31,7 +30,11 @@ Lagre nå Tilbakestill navigasjonsvisning Del tilfluktsrom + Gi tilgang + Aktiver Ingen frakoblet kart lagret. Kartet krever internett. + Posisjonstilgang nødvendig for å finne nærmeste tilfluktsrom. Du kan også trykke på et merke i kartet. + Stedstjenester er slått av. Aktiver dem eller velg et tilfluktsrom fra kartet. Posisjonstillatelse kreves @@ -46,13 +49,6 @@ Tilfluktsromdata oppdatert Oppdatering mislyktes — bruker lagrede data - - Viser n\u00e6rmeste tilfluktsrom med avstand - \u00c5pne appen for posisjon - Ingen tilfluktsromdata - Trykk for \u00e5 oppdatere - Oppdatert %s - Data er oppdatert Data er %d dager gammel @@ -66,6 +62,7 @@ Retning til tilfluktsrom, %s unna %1$s, %2$s, %3$d plasser + Valgt – utenfor nærområdet Upresist kompass - %s Tilfluktsromkart Kompassnavigasjon @@ -101,8 +98,9 @@ Denne appen samler ikke inn, sender eller deler noen personopplysninger. Det finnes ingen analyse, sporing eller tredjepartstjenester.\n\nGPS-posisjonen din brukes bare lokalt på enheten din for å finne tilfluktsrom i nærheten, og sendes aldri til noen server. Datakilder Tilfluktsromdata er offentlig informasjon fra DSB (Direktoratet for samfunnssikkerhet og beredskap), distribuert via Geonorge. Kartfliser lastes fra OpenStreetMap. Begge lagres lokalt for frakoblet bruk. + Geonorge kartkatalog
Produktark (DSB)]]>
Lagret på enheten din - • Tilfluktsromdatabase (offentlige data fra DSB)\n• Kartfliser for frakoblet bruk\n• Din siste GPS-posisjon (for hjemmeskjerm-widgeten)\n\nIngen data forlater enheten din bortsett fra forespørsler om å laste ned tilfluktsromdata og kartfliser. + • Tilfluktsromdatabase (offentlige data fra DSB)\n• Kartfliser for frakoblet bruk\n\nIngen data forlater enheten din bortsett fra forespørsler om å laste ned tilfluktsromdata og kartfliser. Åpen kildekode — kode.naiv.no/olemd/tilfluktsrom Om denne appen diff --git a/app/src/main/res/values-nn/strings.xml b/app/src/main/res/values-nn/strings.xml index f04070e..67edcff 100644 --- a/app/src/main/res/values-nn/strings.xml +++ b/app/src/main/res/values-nn/strings.xml @@ -20,7 +20,6 @@ %d plassar Rom %d - Næraste tilfluktsrom Ingen tilfluktsromdata tilgjengeleg @@ -31,7 +30,11 @@ Lagre no Tilbakestill navigasjonsvising Del tilfluktsrom + Gje tilgang + Aktiver Ingen fråkopla kart lagra. Kartet krev internett. + Posisjonstilgang trengst for å finne næraste tilfluktsrom. Du kan òg trykke på eit merke i kartet. + Stedstenester er slått av. Aktiver dei eller vel eit tilfluktsrom frå kartet. Posisjonsløyve krevst @@ -46,13 +49,6 @@ Tilfluktsromdata oppdatert Oppdatering mislukkast — brukar lagra data - - Viser n\u00e6raste tilfluktsrom med avstand - Opne appen for posisjon - Ingen tilfluktsromdata - Trykk for \u00e5 oppdatere - Oppdatert %s - Data er oppdatert Data er %d dagar gammal @@ -66,6 +62,7 @@ Retning til tilfluktsrom, %s unna %1$s, %2$s, %3$d plassar + Vald – utanfor nærområdet Upresis kompass - %s Tilfluktsromkart Kompassnavigasjon @@ -101,8 +98,9 @@ Denne appen samlar ikkje inn, sender eller deler nokon personopplysingar. Det finst ingen analyse, sporing eller tredjepartstenester.\n\nGPS-posisjonen din vert berre brukt lokalt på eininga di for å finne tilfluktsrom i nærleiken, og vert aldri sendt til nokon tenar. Datakjelder Tilfluktsromdata er offentleg informasjon frå DSB (Direktoratet for samfunnstryggleik og beredskap), distribuert via Geonorge. Kartfliser vert lasta frå OpenStreetMap. Begge vert lagra lokalt for fråkopla bruk. + Geonorge kartkatalog
Produktark (DSB)]]>
Lagra på eininga di - • Tilfluktsromdatabase (offentlege data frå DSB)\n• Kartfliser for fråkopla bruk\n• Din siste GPS-posisjon (for heimeskjerm-widgeten)\n\nIngen data forlèt eininga di bortsett frå førespurnader om å laste ned tilfluktsromdata og kartfliser. + • Tilfluktsromdatabase (offentlege data frå DSB)\n• Kartfliser for fråkopla bruk\n\nIngen data forlèt eininga di bortsett frå førespurnader om å laste ned tilfluktsromdata og kartfliser. Open kjeldekode — kode.naiv.no/olemd/tilfluktsrom Om denne appen diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e6408f7..1825950 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -20,7 +20,6 @@ %d places Room %d - Nearest shelter No shelter data available @@ -31,7 +30,11 @@ Cache now Reset navigation view Share shelter + Grant access + Enable No offline map cached. Map requires internet. + Location access needed to find the nearest shelter. You can also tap a marker on the map. + Location services are off. Enable them or pick a shelter from the map. Location permission required @@ -46,13 +49,6 @@ Shelter data updated Update failed — using cached data - - Shows nearest shelter with distance - Open app for location - No shelter data - Tap to refresh - Updated %s - Data is up to date Data is %d days old @@ -66,6 +62,9 @@ Direction to shelter, %s away %1$s, %2$s, %3$d places + + Selected (outside nearest) Low accuracy - %s Shelter map Compass navigation @@ -102,8 +101,9 @@ This app does not collect, transmit, or share any personal data. There are no analytics, tracking, or third-party services.\n\nYour GPS location is used only on your device to find nearby shelters and is never sent to any server. Data sources Shelter data is public information from DSB (Norwegian Directorate for Civil Protection), distributed via Geonorge. Map tiles are loaded from OpenStreetMap. Both are cached locally for offline use. + Geonorge metadata catalogue
DSB product sheet]]>
Stored on your device - • Shelter database (public data from DSB)\n• Map tiles for offline use\n• Your last GPS position (for the home screen widget)\n\nNo data leaves your device except requests to download shelter data and map tiles. + • Shelter database (public data from DSB)\n• Map tiles for offline use\n\nNo data leaves your device except requests to download shelter data and map tiles. Open source — kode.naiv.no/olemd/tilfluktsrom About this app diff --git a/app/src/main/res/xml/widget_info.xml b/app/src/main/res/xml/widget_info.xml deleted file mode 100644 index f08bb61..0000000 --- a/app/src/main/res/xml/widget_info.xml +++ /dev/null @@ -1,9 +0,0 @@ - - diff --git a/app/src/standard/java/no/naiv/tilfluktsrom/widget/ShelterWidgetProvider.kt b/app/src/standard/java/no/naiv/tilfluktsrom/widget/ShelterWidgetProvider.kt deleted file mode 100644 index 42a9fdc..0000000 --- a/app/src/standard/java/no/naiv/tilfluktsrom/widget/ShelterWidgetProvider.kt +++ /dev/null @@ -1,349 +0,0 @@ -package no.naiv.tilfluktsrom.widget - -import android.Manifest -import android.app.PendingIntent -import android.appwidget.AppWidgetManager -import android.appwidget.AppWidgetProvider -import android.content.ComponentName -import android.content.Context -import android.content.Intent -import android.content.pm.PackageManager -import android.location.Location -import android.location.LocationManager -import android.os.Build -import android.os.CancellationSignal -import android.text.format.DateFormat -import android.util.Log -import android.widget.RemoteViews -import androidx.core.content.ContextCompat -import com.google.android.gms.common.ConnectionResult -import com.google.android.gms.common.GoogleApiAvailability -import com.google.android.gms.location.LocationServices -import com.google.android.gms.location.Priority -import com.google.android.gms.tasks.Tasks -import no.naiv.tilfluktsrom.MainActivity -import no.naiv.tilfluktsrom.R -import no.naiv.tilfluktsrom.data.ShelterDatabase -import no.naiv.tilfluktsrom.location.ShelterFinder -import no.naiv.tilfluktsrom.util.DistanceUtils -import java.util.concurrent.TimeUnit - -/** - * Home screen widget showing the nearest shelter with distance. - * - * Update strategy: - * - Background: WorkManager runs every 15 min while widget exists - * - Live: MainActivity sends ACTION_REFRESH on each GPS location update - * - Manual: user taps the refresh button on the widget - * - * Location resolution (in priority order): - * 1. Location provided via intent extras (from WorkManager or MainActivity) - * 2. FusedLocationProviderClient cache/active request (Play Services) - * 3. LocationManager cache/active request (AOSP fallback) - * 4. Last GPS fix saved to SharedPreferences by MainActivity - * - * Note: Background processes cannot reliably trigger GPS hardware on - * Android 8+. The SharedPreferences fallback ensures the widget works - * after app updates and reboots without opening the app first. - */ -class ShelterWidgetProvider : AppWidgetProvider() { - - companion object { - private const val TAG = "ShelterWidget" - const val ACTION_REFRESH = "no.naiv.tilfluktsrom.widget.REFRESH" - private const val EXTRA_LATITUDE = "lat" - private const val EXTRA_LONGITUDE = "lon" - - /** Trigger a widget refresh from anywhere (e.g. MainActivity on location update). */ - fun requestUpdate(context: Context) { - val intent = Intent(context, ShelterWidgetProvider::class.java).apply { - action = ACTION_REFRESH - } - context.sendBroadcast(intent) - } - - /** Trigger a widget refresh with a known location (from WidgetUpdateWorker). */ - fun requestUpdateWithLocation(context: Context, latitude: Double, longitude: Double) { - val intent = Intent(context, ShelterWidgetProvider::class.java).apply { - action = ACTION_REFRESH - putExtra(EXTRA_LATITUDE, latitude) - putExtra(EXTRA_LONGITUDE, longitude) - } - context.sendBroadcast(intent) - } - } - - override fun onEnabled(context: Context) { - super.onEnabled(context) - WidgetUpdateWorker.schedule(context) - } - - override fun onDisabled(context: Context) { - super.onDisabled(context) - WidgetUpdateWorker.cancel(context) - } - - override fun onUpdate( - context: Context, - appWidgetManager: AppWidgetManager, - appWidgetIds: IntArray - ) { - WidgetUpdateWorker.schedule(context) - updateAllWidgetsAsync(context, null) - } - - override fun onReceive(context: Context, intent: Intent) { - super.onReceive(context, intent) - - if (intent.action == ACTION_REFRESH) { - val providedLocation = if (intent.hasExtra(EXTRA_LATITUDE)) { - Location("widget").apply { - latitude = intent.getDoubleExtra(EXTRA_LATITUDE, 0.0) - longitude = intent.getDoubleExtra(EXTRA_LONGITUDE, 0.0) - } - } else null - - updateAllWidgetsAsync(context, providedLocation) - } - } - - /** - * Run widget update on a background thread so we can call - * FusedLocationProviderClient.getLastLocation() synchronously. - * Uses goAsync() to keep the BroadcastReceiver alive until done. - */ - private fun updateAllWidgetsAsync(context: Context, providedLocation: Location?) { - val pendingResult = goAsync() - Thread { - try { - val appWidgetManager = AppWidgetManager.getInstance(context) - val widgetIds = appWidgetManager.getAppWidgetIds( - ComponentName(context, ShelterWidgetProvider::class.java) - ) - val location = providedLocation ?: getBestLocation(context) - for (appWidgetId in widgetIds) { - updateWidget(context, appWidgetManager, appWidgetId, location) - } - } catch (e: Exception) { - Log.e(TAG, "Failed to update widgets", e) - } finally { - pendingResult.finish() - } - }.start() - } - - private fun updateWidget( - context: Context, - appWidgetManager: AppWidgetManager, - appWidgetId: Int, - location: Location? - ) { - val views = RemoteViews(context.packageName, R.layout.widget_nearest_shelter) - - // Tapping widget body opens the app - val openAppIntent = Intent(context, MainActivity::class.java) - val openAppPending = PendingIntent.getActivity( - context, 0, openAppIntent, PendingIntent.FLAG_IMMUTABLE - ) - views.setOnClickPendingIntent(R.id.widgetRoot, openAppPending) - - // Refresh button sends our custom broadcast - val refreshIntent = Intent(context, ShelterWidgetProvider::class.java).apply { - action = ACTION_REFRESH - } - val refreshPending = PendingIntent.getBroadcast( - context, 0, refreshIntent, PendingIntent.FLAG_IMMUTABLE - ) - views.setOnClickPendingIntent(R.id.widgetRefreshButton, refreshPending) - - // Check permission - if (ContextCompat.checkSelfPermission( - context, Manifest.permission.ACCESS_FINE_LOCATION - ) != PackageManager.PERMISSION_GRANTED - ) { - showFallback(context, views, context.getString(R.string.widget_open_app)) - appWidgetManager.updateAppWidget(appWidgetId, views) - return - } - - if (location == null) { - showFallback(context, views, context.getString(R.string.widget_no_location)) - appWidgetManager.updateAppWidget(appWidgetId, views) - return - } - - // Query shelters from Room (fast: ~556 rows, <10ms) - val shelters = try { - val dao = ShelterDatabase.getInstance(context).shelterDao() - kotlinx.coroutines.runBlocking { dao.getAllSheltersList() } - } catch (e: Exception) { - Log.e(TAG, "Failed to query shelters", e) - emptyList() - } - - if (shelters.isEmpty()) { - showFallback(context, views, context.getString(R.string.widget_no_data)) - appWidgetManager.updateAppWidget(appWidgetId, views) - return - } - - // Find nearest shelter - val nearest = ShelterFinder.findNearest( - shelters, location.latitude, location.longitude, 1 - ).firstOrNull() - - if (nearest == null) { - showFallback(context, views, context.getString(R.string.widget_no_data)) - appWidgetManager.updateAppWidget(appWidgetId, views) - return - } - - // Show shelter info - views.setTextViewText(R.id.widgetAddress, nearest.shelter.adresse) - views.setTextViewText( - R.id.widgetDetails, - context.getString(R.string.shelter_capacity, nearest.shelter.plasser) - ) - views.setTextViewText( - R.id.widgetDistance, - DistanceUtils.formatDistance(nearest.distanceMeters) - ) - views.setTextViewText(R.id.widgetTimestamp, formatTimestamp(context)) - - appWidgetManager.updateAppWidget(appWidgetId, views) - } - - /** Show a fallback message when location or data is unavailable. */ - private fun showFallback(context: Context, views: RemoteViews, message: String) { - views.setTextViewText(R.id.widgetAddress, message) - views.setTextViewText(R.id.widgetDetails, "") - views.setTextViewText(R.id.widgetDistance, "") - views.setTextViewText(R.id.widgetTimestamp, formatTimestamp(context)) - } - - /** Format current time as "Updated HH:mm", respecting the user's 12/24h preference. */ - private fun formatTimestamp(context: Context): String { - val format = DateFormat.getTimeFormat(context) - val timeStr = format.format(System.currentTimeMillis()) - return context.getString(R.string.widget_updated_at, timeStr) - } - - /** - * Get the best available location. - * Tries FusedLocationProviderClient first (Play Services, better cache), - * then LocationManager (AOSP), then last saved GPS fix from SharedPreferences. - * Safe to call from a background thread. - */ - private fun getBestLocation(context: Context): Location? { - if (ContextCompat.checkSelfPermission( - context, Manifest.permission.ACCESS_FINE_LOCATION - ) != PackageManager.PERMISSION_GRANTED - ) return null - - // Try Play Services first — maintains a better location cache - val fusedLocation = getFusedLastLocation(context) - if (fusedLocation != null) return fusedLocation - - // Fall back to LocationManager - val lmLocation = getLocationManagerLocation(context) - if (lmLocation != null) return lmLocation - - // Fall back to last location saved by MainActivity - return getSavedLocation(context) - } - - /** Read the last GPS fix persisted by MainActivity to SharedPreferences. - * Returns null if older than 24 hours to avoid retaining stale location data. */ - private fun getSavedLocation(context: Context): Location? { - val prefs = context.getSharedPreferences("widget_prefs", Context.MODE_PRIVATE) - if (!prefs.contains("last_lat")) return null - val age = System.currentTimeMillis() - prefs.getLong("last_time", 0L) - if (age > 24 * 60 * 60 * 1000L) return null - return Location("saved").apply { - latitude = prefs.getFloat("last_lat", 0f).toDouble() - longitude = prefs.getFloat("last_lon", 0f).toDouble() - } - } - - /** - * Get location via Play Services — blocks, call from background thread. - * Tries cached location first, then actively requests a fix if cache is empty. - */ - private fun getFusedLastLocation(context: Context): Location? { - if (!isPlayServicesAvailable(context)) return null - return try { - val client = LocationServices.getFusedLocationProviderClient(context) - // Try cache first (instant) - val cached = Tasks.await(client.lastLocation, 3, TimeUnit.SECONDS) - if (cached != null) return cached - // Cache empty — actively request a fix (turns on GPS/network) - val task = client.getCurrentLocation( - Priority.PRIORITY_BALANCED_POWER_ACCURACY, null - ) - Tasks.await(task, 10, TimeUnit.SECONDS) - } catch (e: Exception) { - Log.w(TAG, "FusedLocationProvider failed", e) - null - } - } - - /** - * Get location via LocationManager (AOSP). - * Tries cache first, then actively requests a fix on API 30+. - * Blocks — call from background thread. - */ - private fun getLocationManagerLocation(context: Context): Location? { - val locationManager = context.getSystemService(Context.LOCATION_SERVICE) - as? LocationManager ?: return null - - // Try cache first - try { - val lastGps = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) - val lastNetwork = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) - val cached = listOfNotNull(lastGps, lastNetwork).maxByOrNull { it.time } - if (cached != null) return cached - } catch (e: SecurityException) { - Log.e(TAG, "SecurityException getting last known location", e) - return null - } - - // Cache empty — actively request on API 30+ - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - val provider = when { - locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) -> - LocationManager.NETWORK_PROVIDER - locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) -> - LocationManager.GPS_PROVIDER - else -> return null - } - try { - val latch = java.util.concurrent.CountDownLatch(1) - var result: Location? = null - val signal = CancellationSignal() - locationManager.getCurrentLocation( - provider, signal, context.mainExecutor - ) { location -> - result = location - latch.countDown() - } - latch.await(10, TimeUnit.SECONDS) - signal.cancel() - return result - } catch (e: Exception) { - Log.e(TAG, "Active location request failed", e) - } - } - - return null - } - - private fun isPlayServicesAvailable(context: Context): Boolean { - return try { - val result = GoogleApiAvailability.getInstance() - .isGooglePlayServicesAvailable(context) - result == ConnectionResult.SUCCESS - } catch (e: Exception) { - false - } - } -} diff --git a/app/src/standard/java/no/naiv/tilfluktsrom/widget/WidgetUpdateWorker.kt b/app/src/standard/java/no/naiv/tilfluktsrom/widget/WidgetUpdateWorker.kt deleted file mode 100644 index 91e5d3b..0000000 --- a/app/src/standard/java/no/naiv/tilfluktsrom/widget/WidgetUpdateWorker.kt +++ /dev/null @@ -1,187 +0,0 @@ -package no.naiv.tilfluktsrom.widget - -import android.Manifest -import android.content.Context -import android.content.pm.PackageManager -import android.location.Location -import android.location.LocationManager -import android.os.Build -import android.os.CancellationSignal -import android.util.Log -import androidx.core.content.ContextCompat -import androidx.work.CoroutineWorker -import androidx.work.ExistingPeriodicWorkPolicy -import androidx.work.OneTimeWorkRequestBuilder -import androidx.work.PeriodicWorkRequestBuilder -import androidx.work.WorkManager -import androidx.work.WorkerParameters -import com.google.android.gms.common.ConnectionResult -import com.google.android.gms.common.GoogleApiAvailability -import com.google.android.gms.location.LocationServices -import com.google.android.gms.location.Priority -import com.google.android.gms.tasks.Tasks -import kotlinx.coroutines.suspendCancellableCoroutine -import kotlinx.coroutines.withTimeoutOrNull -import java.util.concurrent.TimeUnit -import kotlin.coroutines.resume - -/** - * Periodic background worker that refreshes the home screen widget. - * - * Scheduled every 15 minutes (WorkManager's minimum interval). - * Actively requests a fresh location fix to populate the system cache, - * then triggers the widget's existing update logic via broadcast. - * - * Location strategy (mirrors LocationProvider): - * - Play Services: FusedLocationProviderClient.getCurrentLocation() - * - AOSP API 30+: LocationManager.getCurrentLocation() - * - AOSP API 26-29: LocationManager.getLastKnownLocation() - */ -class WidgetUpdateWorker( - context: Context, - params: WorkerParameters -) : CoroutineWorker(context, params) { - - companion object { - private const val TAG = "WidgetUpdateWorker" - private const val WORK_NAME = "widget_update" - private const val LOCATION_TIMEOUT_MS = 10_000L - - /** Schedule periodic widget updates. Safe to call multiple times. */ - fun schedule(context: Context) { - val request = PeriodicWorkRequestBuilder( - 15, TimeUnit.MINUTES - ).build() - - WorkManager.getInstance(context).enqueueUniquePeriodicWork( - WORK_NAME, - ExistingPeriodicWorkPolicy.KEEP, - request - ) - } - - /** Run once immediately (e.g. when widget is first placed or location was unavailable). */ - fun runOnce(context: Context) { - val request = OneTimeWorkRequestBuilder().build() - WorkManager.getInstance(context).enqueue(request) - } - - /** Cancel periodic updates (e.g. when all widgets are removed). */ - fun cancel(context: Context) { - WorkManager.getInstance(context).cancelUniqueWork(WORK_NAME) - } - } - - override suspend fun doWork(): Result { - val location = requestFreshLocation() ?: getSavedLocation() - if (location != null) { - ShelterWidgetProvider.requestUpdateWithLocation( - applicationContext, location.latitude, location.longitude - ) - } else { - ShelterWidgetProvider.requestUpdate(applicationContext) - } - return Result.success() - } - - /** Read the last GPS fix persisted by MainActivity. - * Returns null if older than 24 hours. */ - private fun getSavedLocation(): Location? { - val prefs = applicationContext.getSharedPreferences("widget_prefs", Context.MODE_PRIVATE) - if (!prefs.contains("last_lat")) return null - val age = System.currentTimeMillis() - prefs.getLong("last_time", 0L) - if (age > 24 * 60 * 60 * 1000L) return null - return Location("saved").apply { - latitude = prefs.getFloat("last_lat", 0f).toDouble() - longitude = prefs.getFloat("last_lon", 0f).toDouble() - } - } - - /** - * Actively request a location fix and return it. - * Returns null if permission is missing or location is unavailable. - */ - private suspend fun requestFreshLocation(): Location? { - val context = applicationContext - if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) - != PackageManager.PERMISSION_GRANTED - ) return null - - return if (isPlayServicesAvailable()) { - requestViaPlayServices() - } else { - requestViaLocationManager() - } - } - - /** Use FusedLocationProviderClient.getCurrentLocation() — best accuracy, best cache. */ - private suspend fun requestViaPlayServices(): Location? { - return try { - val client = LocationServices.getFusedLocationProviderClient(applicationContext) - val task = client.getCurrentLocation(Priority.PRIORITY_BALANCED_POWER_ACCURACY, null) - Tasks.await(task, LOCATION_TIMEOUT_MS, TimeUnit.MILLISECONDS) - } catch (e: SecurityException) { - Log.e(TAG, "SecurityException requesting location via Play Services", e) - null - } catch (e: Exception) { - Log.w(TAG, "Play Services location request failed, falling back", e) - requestViaLocationManager() - } - } - - /** Use LocationManager.getCurrentLocation() (API 30+) or getLastKnownLocation() fallback. */ - private suspend fun requestViaLocationManager(): Location? { - val locationManager = applicationContext.getSystemService(Context.LOCATION_SERVICE) - as? LocationManager ?: return null - - val provider = when { - locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) -> - LocationManager.GPS_PROVIDER - locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) -> - LocationManager.NETWORK_PROVIDER - else -> return null - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - return requestCurrentLocation(locationManager, provider) - } - // API 26-29: fall back to passive cache - return try { - locationManager.getLastKnownLocation(provider) - } catch (e: SecurityException) { - null - } - } - - /** API 30+: actively request a single location fix. */ - private suspend fun requestCurrentLocation(locationManager: LocationManager, provider: String): Location? { - return try { - withTimeoutOrNull(LOCATION_TIMEOUT_MS) { - suspendCancellableCoroutine { cont -> - val signal = CancellationSignal() - locationManager.getCurrentLocation( - provider, - signal, - applicationContext.mainExecutor - ) { location -> - if (cont.isActive) cont.resume(location) - } - cont.invokeOnCancellation { signal.cancel() } - } - } - } catch (e: SecurityException) { - Log.e(TAG, "SecurityException requesting location via LocationManager", e) - null - } - } - - private fun isPlayServicesAvailable(): Boolean { - return try { - val result = GoogleApiAvailability.getInstance() - .isGooglePlayServicesAvailable(applicationContext) - result == ConnectionResult.SUCCESS - } catch (e: Exception) { - false - } - } -} diff --git a/fastlane/metadata/android/en-US/changelogs/15.txt b/fastlane/metadata/android/en-US/changelogs/15.txt new file mode 100644 index 0000000..1eb1cf4 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/15.txt @@ -0,0 +1,2 @@ +- Actionable banner when location is unavailable (permissions, disabled services, or no GPS fix) +- Home screen widget removed diff --git a/fastlane/metadata/android/en-US/changelogs/16.txt b/fastlane/metadata/android/en-US/changelogs/16.txt new file mode 100644 index 0000000..76c2ffd --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/16.txt @@ -0,0 +1,4 @@ +- Deep links now use the shelter room number, which is stable across data refreshes — links shared between devices work reliably +- Refresh button shows a loading indicator and no longer appears to hang +- "Cache map" prompt no longer reappears after you tap Skip +- Refreshed bundled shelter data diff --git a/fastlane/metadata/android/en-US/changelogs/17.txt b/fastlane/metadata/android/en-US/changelogs/17.txt new file mode 100644 index 0000000..afb84a1 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/17.txt @@ -0,0 +1,2 @@ +- PWA-only release: share button is now visually consistent with the other status-bar icons, and updates apply automatically the next time you bring the app to the foreground (no manual reload needed) +- No Android changes diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt index 839991c..b617c5f 100644 --- a/fastlane/metadata/android/en-US/full_description.txt +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -5,7 +5,6 @@ Features: • Compass navigation — direction arrow points to the selected shelter • Offline map — map tiles are cached automatically for use without internet • Select any shelter — tap any marker on the map to navigate there -• Home screen widget — shows nearest shelter at a glance • Share shelters — send shelter location to others via any app • Civil defense info — what to do if the alarm sounds • Multilingual — English, Bokmål, and Nynorsk diff --git a/fastlane/metadata/android/nb-NO/changelogs/15.txt b/fastlane/metadata/android/nb-NO/changelogs/15.txt new file mode 100644 index 0000000..6eea819 --- /dev/null +++ b/fastlane/metadata/android/nb-NO/changelogs/15.txt @@ -0,0 +1,2 @@ +- Handlingsbanner når posisjon ikke er tilgjengelig (tillatelser, avslåtte stedstjenester eller manglende GPS-fix) +- Hjemmeskjerm-widget fjernet diff --git a/fastlane/metadata/android/nb-NO/changelogs/16.txt b/fastlane/metadata/android/nb-NO/changelogs/16.txt new file mode 100644 index 0000000..572949a --- /dev/null +++ b/fastlane/metadata/android/nb-NO/changelogs/16.txt @@ -0,0 +1,4 @@ +- Delingslenker bruker nå romnummeret, som er stabilt på tvers av dataoppdateringer — lenker som deles mellom enheter virker pålitelig +- Oppdater-knappen viser en lasteindikator og ser ikke lenger ut til å henge +- "Lagre kart"-spørsmålet dukker ikke lenger opp igjen etter at du har trykket Hopp over +- Oppdatert pakket tilfluktsromdata diff --git a/fastlane/metadata/android/nb-NO/changelogs/17.txt b/fastlane/metadata/android/nb-NO/changelogs/17.txt new file mode 100644 index 0000000..6c1b216 --- /dev/null +++ b/fastlane/metadata/android/nb-NO/changelogs/17.txt @@ -0,0 +1,2 @@ +- PWA-utgivelse: del-knappen er visuelt konsistent med de andre ikonene i statuslinjen, og oppdateringer trer i kraft automatisk neste gang du henter appen i forgrunnen (ingen manuell omlasting) +- Ingen Android-endringer diff --git a/fastlane/metadata/android/nb-NO/full_description.txt b/fastlane/metadata/android/nb-NO/full_description.txt index bd4b8b9..34661c7 100644 --- a/fastlane/metadata/android/nb-NO/full_description.txt +++ b/fastlane/metadata/android/nb-NO/full_description.txt @@ -5,7 +5,6 @@ Funksjoner: • Kompassnavigasjon — retningspil som peker mot valgt tilfluktsrom • Frakoblet kart — kartfliser lagres automatisk for bruk uten nett • Velg fritt — trykk på en markør i kartet for å navigere dit -• Hjemskjerm-widget — viser nærmeste tilfluktsrom med ett blikk • Del tilfluktsrom — send posisjon til andre via en hvilken som helst app • Sivilforsvarsinformasjon — hva du skal gjøre hvis alarmen går • Flerspråklig — engelsk, bokmål og nynorsk diff --git a/fastlane/metadata/android/nn-NO/changelogs/15.txt b/fastlane/metadata/android/nn-NO/changelogs/15.txt new file mode 100644 index 0000000..2780fdc --- /dev/null +++ b/fastlane/metadata/android/nn-NO/changelogs/15.txt @@ -0,0 +1,2 @@ +- Handlingsbanner når posisjonen ikkje er tilgjengeleg (løyve, avslegne stadtenester eller manglande GPS-fix) +- Heimeskjerm-widgeten er fjerna diff --git a/fastlane/metadata/android/nn-NO/changelogs/16.txt b/fastlane/metadata/android/nn-NO/changelogs/16.txt new file mode 100644 index 0000000..5079526 --- /dev/null +++ b/fastlane/metadata/android/nn-NO/changelogs/16.txt @@ -0,0 +1,4 @@ +- Delingslenker brukar no romnummeret, som er stabilt på tvers av dataoppdateringar — lenker som blir delte mellom einingar verkar pålitelig +- Oppdater-knappen viser ein lasteindikator og ser ikkje lenger ut til å henge +- "Lagre kart"-spørsmålet dukkar ikkje opp att etter at du har trykt Hopp over +- Oppdatert pakka tilfluktsromdata diff --git a/fastlane/metadata/android/nn-NO/changelogs/17.txt b/fastlane/metadata/android/nn-NO/changelogs/17.txt new file mode 100644 index 0000000..8f3c3ff --- /dev/null +++ b/fastlane/metadata/android/nn-NO/changelogs/17.txt @@ -0,0 +1,2 @@ +- PWA-utgjeving: del-knappen er visuelt jamn med dei andre ikona i statuslinja, og oppdateringar tek effekt automatisk neste gong du hentar appen i framgrunnen (inga manuell omlasting) +- Ingen Android-endringar diff --git a/fastlane/metadata/android/nn-NO/full_description.txt b/fastlane/metadata/android/nn-NO/full_description.txt index fdc1279..857a955 100644 --- a/fastlane/metadata/android/nn-NO/full_description.txt +++ b/fastlane/metadata/android/nn-NO/full_description.txt @@ -5,7 +5,6 @@ Funksjonar: • Kompassnavigasjon — retningspil som peikar mot valt tilfluktsrom • Fråkopla kart — kartfliser lagrast automatisk for bruk utan nett • Vel fritt — trykk på ein markør i kartet for å navigere dit -• Heimeskjerm-widget — viser næraste tilfluktsrom med eitt blikk • Del tilfluktsrom — send posisjon til andre via ei kva som helst app • Sivilforsvarsinformasjon — kva du skal gjere om alarmen går • Fleirspråkleg — engelsk, bokmål og nynorsk diff --git a/pwa/index.html b/pwa/index.html index 7440b65..1a66208 100644 --- a/pwa/index.html +++ b/pwa/index.html @@ -2,9 +2,16 @@ - + + + + + + Tilfluktsrom @@ -18,6 +25,11 @@ diff --git a/pwa/src/app.ts b/pwa/src/app.ts index ceceb58..d5fcabb 100644 --- a/pwa/src/app.ts +++ b/pwa/src/app.ts @@ -11,6 +11,7 @@ import type { Shelter, ShelterWithDistance, LatLon } from './types'; import { t } from './i18n/i18n'; import { formatDistance, distanceMeters, bearingDegrees } from './util/distance-utils'; import { findNearest } from './location/shelter-finder'; +import { DEEP_LINK_DOMAIN } from './config'; import * as repo from './data/shelter-repository'; import * as locationProvider from './location/location-provider'; import * as compassProvider from './location/compass-provider'; @@ -35,6 +36,12 @@ let firstLocationFix = true; // Track whether user manually selected a shelter (prevents auto-reselection // on location updates) let userSelectedShelter = false; +// Romnr (DSB room number) of the user-selected shelter — survives location +// updates that recompute nearestShelters (deep links, marker taps to a +// far-away shelter), and *also* survives a forceRefresh() that replaces +// every lokalId in the dataset. Romnr is the stable upstream business key; +// see ARCHITECTURE.md → "Deep link identifier" for rationale. +let selectedRomnr: number | null = null; export async function init(): Promise { applyA11yLabels(); @@ -58,21 +65,16 @@ function applyA11yLabels(): void { document.getElementById('bottom-sheet')?.setAttribute('aria-label', t('a11y_shelter_info')); document.getElementById('shelter-list')?.setAttribute('aria-label', t('a11y_nearest_shelters')); document.getElementById('refresh-btn')?.setAttribute('aria-label', t('action_refresh')); + document.getElementById('share-btn')?.setAttribute('aria-label', t('action_share')); document.getElementById('toggle-fab')?.setAttribute('aria-label', t('action_toggle_view')); } function setupMap(): void { const container = document.getElementById('map-container')!; mapView.initMap(container, (shelter: Shelter) => { - // Marker click — select this shelter - const idx = nearestShelters.findIndex( - (s) => s.shelter.lokalId === shelter.lokalId, - ); - if (idx >= 0) { - userSelectedShelter = true; - selectedShelterIndex = idx; - updateSelectedShelter(true); - } + // Marker click — select this shelter (route through selectShelterByData + // so a tap on a far-away marker also survives location updates). + selectShelterByData(shelter); }); } @@ -86,6 +88,7 @@ function setupShelterList(): void { shelterList.initShelterList(container, (index: number) => { userSelectedShelter = true; selectedShelterIndex = index; + selectedRomnr = nearestShelters[index]?.shelter.romnr ?? null; updateSelectedShelter(true); }); } @@ -101,10 +104,14 @@ function setupButtons(): void { const compassContainer = document.getElementById('compass-container')!; if (isCompassMode) { - // Request compass permission on first toggle (iOS requirement) + // Request compass permission on first toggle (iOS requirement). + // On denial we stay in map mode and surface a status message so the + // user understands why nothing happened — silent reverting is the + // failure mode the Android GPS-denied banner was designed to avoid. const granted = await compassProvider.requestPermission(); if (!granted) { isCompassMode = false; + statusBar.setStatus(t('compass_permission_denied')); return; } mapContainer.style.display = 'none'; @@ -128,6 +135,14 @@ function setupButtons(): void { // Refresh button statusBar.onRefreshClick(forceRefresh); + // Share button — emits the same HTTPS deep link the Android app uses, + // so a recipient with the app installed (and verified App Links) opens + // the shelter natively, otherwise it opens in the PWA. + document.getElementById('share-btn')?.addEventListener('click', () => { + navigator.vibrate?.(10); + shareSelectedShelter(); + }); + // Cache retry button const cacheRetryBtn = document.getElementById('cache-retry-btn')!; cacheRetryBtn.textContent = t('action_cache_now'); @@ -243,8 +258,40 @@ function updateNearestShelters(location: LatLon): void { NEAREST_COUNT, ); - // Only auto-select the nearest shelter if the user hasn't manually selected one - if (!userSelectedShelter) { + if (userSelectedShelter && selectedRomnr !== null) { + // Preserve the user's chosen shelter (deep link, marker click, list tap) + // even when it isn't in the geographic top-N. We re-add it with a + // freshly computed distance/bearing so the arrow stays correct. + // Match by romnr — survives a forceRefresh() that replaces lokalIds. + const inList = nearestShelters.findIndex( + (s) => s.shelter.romnr === selectedRomnr, + ); + if (inList >= 0) { + selectedShelterIndex = inList; + } else { + const shelter = allShelters.find((s) => s.romnr === selectedRomnr); + if (shelter) { + nearestShelters.unshift({ + shelter, + distanceMeters: distanceMeters( + location.latitude, location.longitude, + shelter.latitude, shelter.longitude, + ), + bearingDegrees: bearingDegrees( + location.latitude, location.longitude, + shelter.latitude, shelter.longitude, + ), + }); + selectedShelterIndex = 0; + } else { + // Selected shelter no longer exists in the dataset (e.g. DSB + // decommissioned it). Fall back to nearest. + selectedRomnr = null; + userSelectedShelter = false; + selectedShelterIndex = 0; + } + } + } else { selectedShelterIndex = 0; } @@ -401,19 +448,22 @@ async function forceRefresh(): Promise { } /** - * Handle /shelter/{lokalId} deep links. + * Handle /shelter/{romnr} deep links. * Called after loadData() so allShelters is populated. + * + * Path component is romnr (DSB room number), not lokalId — see + * selectedRomnr comment above for the upstream-stability rationale. */ function handleDeepLink(): void { - const match = window.location.pathname.match(/^\/shelter\/(.+)$/); + const match = window.location.pathname.match(/^\/shelter\/(\d+)$/); if (!match) return; - const lokalId = decodeURIComponent(match[1]); + const romnr = parseInt(match[1], 10); // Clean the URL so refresh doesn't re-trigger window.history.replaceState({}, '', '/'); - const shelter = allShelters.find((s) => s.lokalId === lokalId); + const shelter = allShelters.find((s) => s.romnr === romnr); if (!shelter) { statusBar.setStatus(t('error_shelter_not_found')); return; @@ -424,42 +474,95 @@ function handleDeepLink(): void { /** * Select a specific shelter, even if it's not in the current nearest-3 list. - * Used for deep link targets. + * Used for deep link targets, marker taps, and list taps. The selection is + * remembered via selectedLokalId so subsequent location updates preserve it. */ function selectShelterByData(shelter: Shelter): void { - // Check if it's already in nearestShelters + userSelectedShelter = true; + selectedRomnr = shelter.romnr; + const existingIdx = nearestShelters.findIndex( - (s) => s.shelter.lokalId === shelter.lokalId, + (s) => s.shelter.romnr === shelter.romnr, ); if (existingIdx >= 0) { - userSelectedShelter = true; selectedShelterIndex = existingIdx; } else { - // Compute distance/bearing if we have a location, otherwise use placeholder - let dist = NaN; - let bearing = 0; - if (currentLocation) { - dist = distanceMeters( - currentLocation.latitude, currentLocation.longitude, - shelter.latitude, shelter.longitude, - ); - bearing = bearingDegrees( - currentLocation.latitude, currentLocation.longitude, - shelter.latitude, shelter.longitude, - ); - } + // Compute distance/bearing if we have a location, otherwise NaN signals + // "unknown distance" — same convention as MainActivity.kt. + const dist = currentLocation + ? distanceMeters( + currentLocation.latitude, currentLocation.longitude, + shelter.latitude, shelter.longitude, + ) + : NaN; + const bearing = currentLocation + ? bearingDegrees( + currentLocation.latitude, currentLocation.longitude, + shelter.latitude, shelter.longitude, + ) + : NaN; - // Prepend to the list so it becomes the selected shelter nearestShelters.unshift({ shelter, distanceMeters: dist, bearingDegrees: bearing, }); - userSelectedShelter = true; selectedShelterIndex = 0; shelterList.updateList(nearestShelters, selectedShelterIndex); } updateSelectedShelter(true); } + +/** + * Share the currently selected shelter. Uses the Web Share API when + * available (mobile browsers, installed PWAs) and falls back to copying + * the same body to the clipboard. Body format mirrors share_body in the + * Android strings.xml so the two clients produce equivalent messages. + */ +async function shareSelectedShelter(): Promise { + const selected = nearestShelters[selectedShelterIndex]; + if (!selected || !selected.shelter) { + statusBar.setStatus(t('share_no_shelter')); + return; + } + + const shelter = selected.shelter; + const lat = shelter.latitude.toFixed(6); + const lon = shelter.longitude.toFixed(6); + // Path component is romnr (stable DSB business key), not lokalId. The + // upstream Geonorge GeoJSON re-rolls lokalId on every export, so a + // lokalId-keyed link breaks the moment either party refreshes their + // dataset. Romnr is unique (verified 556/556) and stable across exports. + const deepLink = `https://${DEEP_LINK_DOMAIN}/shelter/${shelter.romnr}`; + + const subject = t('share_subject'); + const body = [ + `${subject}: ${shelter.adresse}`, + t('shelter_capacity', shelter.plasser), + `${lat}, ${lon}`, + `geo:${lat},${lon}`, + deepLink, + ].join('\n'); + + if (navigator.share) { + try { + await navigator.share({ title: subject, text: body, url: deepLink }); + return; + } catch (err) { + // AbortError means the user cancelled — silent. Anything else falls + // through to the clipboard fallback below. + if ((err as DOMException)?.name === 'AbortError') return; + } + } + + if (navigator.clipboard?.writeText) { + try { + await navigator.clipboard.writeText(body); + statusBar.setStatus(t('share_copied')); + } catch { + statusBar.setStatus(t('share_no_shelter')); + } + } +} diff --git a/pwa/src/i18n/en.ts b/pwa/src/i18n/en.ts index 6a77154..dc7bdfd 100644 --- a/pwa/src/i18n/en.ts +++ b/pwa/src/i18n/en.ts @@ -30,6 +30,10 @@ export const en: Record = { action_skip: 'Skip', action_cache_ok: 'Cache map', action_cache_now: 'Cache now', + action_share: 'Share shelter', + share_subject: 'Emergency shelter', + share_no_shelter: 'No shelter selected', + share_copied: 'Shelter details copied to clipboard', warning_no_map_cache: 'No offline map cached. Map requires internet.', // Permissions @@ -47,6 +51,10 @@ export const en: Record = { update_success: 'Shelter data updated', update_failed: 'Update failed \u2014 using cached data', error_shelter_not_found: 'Shelter not found', + compass_permission_denied: + 'Compass access denied. You can still use the map to find shelters.', + ios_install_hint: + 'Add Tilfluktsrom to your home screen for offline access: tap Share, then Add to Home Screen.', // Accessibility direction_arrow_description: 'Direction to shelter, %s away', diff --git a/pwa/src/i18n/i18n.ts b/pwa/src/i18n/i18n.ts index 8d0376b..5542ee1 100644 --- a/pwa/src/i18n/i18n.ts +++ b/pwa/src/i18n/i18n.ts @@ -26,7 +26,11 @@ export function initLocale(): void { break; } } - document.documentElement.lang = currentLocale; + // Guard the DOM write so this module is usable from Node (vitest runs + // without jsdom). In a browser, document is always defined. + if (typeof document !== 'undefined') { + document.documentElement.lang = currentLocale; + } } /** Get current locale code. */ diff --git a/pwa/src/i18n/nb.ts b/pwa/src/i18n/nb.ts index 8c285d8..d077162 100644 --- a/pwa/src/i18n/nb.ts +++ b/pwa/src/i18n/nb.ts @@ -26,6 +26,10 @@ export const nb: Record = { action_skip: 'Hopp over', action_cache_ok: 'Lagre kart', action_cache_now: 'Lagre nå', + action_share: 'Del tilfluktsrom', + share_subject: 'Tilfluktsrom', + share_no_shelter: 'Ingen tilfluktsrom valgt', + share_copied: 'Tilfluktsrominfo kopiert til utklippstavlen', warning_no_map_cache: 'Ingen frakoblet kart lagret. Kartet krever internett.', @@ -42,6 +46,10 @@ export const nb: Record = { update_success: 'Tilfluktsromdata oppdatert', update_failed: 'Oppdatering mislyktes — bruker lagrede data', error_shelter_not_found: 'Fant ikke tilfluktsrommet', + compass_permission_denied: + 'Kompasstilgang avslått. Du kan fortsatt bruke kartet til å finne tilfluktsrom.', + ios_install_hint: + 'Legg Tilfluktsrom til hjemskjermen for frakoblet bruk: trykk Del, deretter Legg til på hjem-skjerm.', // Tilgjengelighet direction_arrow_description: 'Retning til tilfluktsrom, %s unna', diff --git a/pwa/src/i18n/nn.ts b/pwa/src/i18n/nn.ts index eace6bd..95723de 100644 --- a/pwa/src/i18n/nn.ts +++ b/pwa/src/i18n/nn.ts @@ -26,6 +26,10 @@ export const nn: Record = { action_skip: 'Hopp over', action_cache_ok: 'Lagre kart', action_cache_now: 'Lagre no', + action_share: 'Del tilfluktsrom', + share_subject: 'Tilfluktsrom', + share_no_shelter: 'Ingen tilfluktsrom valt', + share_copied: 'Tilfluktsrominfo kopiert til utklippstavla', warning_no_map_cache: 'Ingen fråkopla kart lagra. Kartet krev internett.', @@ -42,6 +46,10 @@ export const nn: Record = { update_success: 'Tilfluktsromdata oppdatert', update_failed: 'Oppdatering mislukkast — brukar lagra data', error_shelter_not_found: 'Fann ikkje tilfluktsrommet', + compass_permission_denied: + 'Kompasstilgang avslått. Du kan framleis bruke kartet til å finne tilfluktsrom.', + ios_install_hint: + 'Legg Tilfluktsrom til heimeskjermen for fråkopla bruk: trykk Del, deretter Legg til på heimeskjerm.', // Tilgjenge direction_arrow_description: 'Retning til tilfluktsrom, %s unna', diff --git a/pwa/src/main.ts b/pwa/src/main.ts index 003d83f..8701c0f 100644 --- a/pwa/src/main.ts +++ b/pwa/src/main.ts @@ -11,11 +11,44 @@ import './styles/main.css'; import 'leaflet/dist/leaflet.css'; import { initLocale } from './i18n/i18n'; import { init } from './app'; -import { setStatus } from './ui/status-bar'; -import { t } from './i18n/i18n'; +import { maybeShow as maybeShowIosInstallHint } from './ui/install-hint'; console.info(`[tilfluktsrom] build ${__BUILD_REVISION__}`); +// Make `registerType: 'autoUpdate'` actually auto-update the running tab. +// vite-plugin-pwa's autoUpdate strategy makes the new service worker +// skipWaiting + clientsClaim, but the JS already loaded in the open tab is +// the *old* build until something triggers a navigation. Without this +// listener, a deploy is invisible until the user manually refreshes. +// +// We *defer* the reload until the user next backgrounds the app +// (visibilityState === 'hidden') instead of reloading immediately. This is +// an emergency app: a mid-task reload would lose the selected shelter, +// compass mode, and any in-flight UI state right when the user can least +// afford to be surprised. Deferring keeps the "auto" promise (they're on +// the new version next time they look at the screen) without interrupting +// active use. +// +// The `wasAlreadyControlled` guard avoids reloading on the very first SW +// install (when there was no previous controller — that's a fresh visit, +// not an update). +if ('serviceWorker' in navigator) { + const wasAlreadyControlled = !!navigator.serviceWorker.controller; + let pendingReload = false; + + navigator.serviceWorker.addEventListener('controllerchange', () => { + if (!wasAlreadyControlled) return; + pendingReload = true; + }); + + document.addEventListener('visibilitychange', () => { + if (pendingReload && document.visibilityState === 'hidden') { + pendingReload = false; + window.location.reload(); + } + }); +} + document.addEventListener('DOMContentLoaded', async () => { initLocale(); @@ -24,13 +57,9 @@ document.addEventListener('DOMContentLoaded', async () => { await navigator.storage.persist(); } - // Listen for service worker updates — flash a status message when a new - // version activates so the user knows they have fresh code/data. - if ('serviceWorker' in navigator) { - navigator.serviceWorker.addEventListener('controllerchange', () => { - setStatus(t('update_success')); - }); - } - await init(); + + // Shown only on first iOS Safari visit, once per device. Placed after init() + // so the banner doesn't compete with the loading overlay. + maybeShowIosInstallHint(); }); diff --git a/pwa/src/styles/main.css b/pwa/src/styles/main.css index a7e2dfb..f045d71 100644 --- a/pwa/src/styles/main.css +++ b/pwa/src/styles/main.css @@ -63,6 +63,7 @@ html, body { } #about-btn, +#share-btn, #refresh-btn { background: none; border: none; @@ -75,10 +76,23 @@ html, body { } #about-btn:hover, +#share-btn:hover, #refresh-btn:hover { color: #ECEFF1; } +#share-btn[disabled] { + opacity: 0.4; + cursor: not-allowed; +} + +#share-btn svg { + display: block; + /* `↻` and `ℹ` glyphs sit on a baseline; an SVG inside an inline-flex + container can otherwise pick up extra descender space and look + misaligned next to them. `display:block` removes that. */ +} + /* --- Main content area (map or compass) --- */ #main-content { flex: 1; @@ -199,6 +213,41 @@ html, body { font-size: 12px; } +/* --- iOS "Add to Home Screen" hint (shown once, dismissable) --- */ +#ios-install-hint { + position: fixed; + left: 12px; + right: 12px; + bottom: 12px; + display: flex; + align-items: center; + gap: 8px; + padding: 10px 12px; + background: #16213E; + color: #ECEFF1; + border: 1px solid #FF6B35; + border-radius: 8px; + font-size: 13px; + line-height: 1.3; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4); + z-index: 1000; +} + +#ios-install-hint span { + flex: 1; +} + +#ios-install-hint button { + background: none; + border: 1px solid #ECEFF1; + color: #ECEFF1; + font-size: 12px; + padding: 4px 10px; + border-radius: 4px; + cursor: pointer; + flex-shrink: 0; +} + #cache-retry-btn { background: none; border: 1px solid #FFFFFF; diff --git a/pwa/src/ui/install-hint.ts b/pwa/src/ui/install-hint.ts new file mode 100644 index 0000000..abc17f2 --- /dev/null +++ b/pwa/src/ui/install-hint.ts @@ -0,0 +1,59 @@ +/** + * iOS-only "Add to Home Screen" hint. + * + * Chrome-based browsers fire `beforeinstallprompt` and we could show a native + * install UI there; iOS Safari does not. For iOS users the only way to install + * is Share → Add to Home Screen, so we show a dismissable textual hint the + * first time they visit in a non-standalone context. + * + * Shown once per device (localStorage). Harmless if the heuristic mis-fires + * on a new iOS version — the hint is dismissable. + */ + +import { t } from '../i18n/i18n'; + +const DISMISSED_KEY = 'tilfluktsrom:ios-install-hint:dismissed'; + +function isIOS(): boolean { + // Safari on iPadOS 13+ reports as MacIntel, so also check for touch + Safari. + const ua = navigator.userAgent; + if (/iPad|iPhone|iPod/.test(ua)) return true; + return ( + navigator.maxTouchPoints > 1 && + /Macintosh/.test(ua) && + /Safari/.test(ua) && + !/Chrome|CriOS|FxiOS/.test(ua) + ); +} + +function isStandalone(): boolean { + // iOS-specific property + const nav = navigator as Navigator & { standalone?: boolean }; + if (nav.standalone) return true; + // Standards-based check used by Chrome/Edge + return window.matchMedia?.('(display-mode: standalone)').matches ?? false; +} + +export function maybeShow(): void { + if (!isIOS() || isStandalone()) return; + if (localStorage.getItem(DISMISSED_KEY) === '1') return; + + const banner = document.createElement('div'); + banner.id = 'ios-install-hint'; + banner.setAttribute('role', 'status'); + + const text = document.createElement('span'); + text.textContent = t('ios_install_hint'); + + const dismiss = document.createElement('button'); + dismiss.type = 'button'; + dismiss.textContent = t('action_close'); + dismiss.setAttribute('aria-label', t('action_close')); + dismiss.addEventListener('click', () => { + localStorage.setItem(DISMISSED_KEY, '1'); + banner.remove(); + }); + + banner.append(text, dismiss); + document.body.appendChild(banner); +} diff --git a/scripts/romnr-baseline.json b/scripts/romnr-baseline.json new file mode 100644 index 0000000..10514b4 --- /dev/null +++ b/scripts/romnr-baseline.json @@ -0,0 +1,2231 @@ +{ + "generated_at": "2026-04-30T11:36:48Z", + "source_url": "https://nedlasting.geonorge.no/geonorge/Samfunnssikkerhet/TilfluktsromOffentlige/GeoJSON/Samfunnssikkerhet_0000_Norge_25833_TilfluktsromOffentlige_GeoJSON.zip", + "feature_count": 556, + "shelters": { + "776": { + "lokalId": "83d39f3f-bb34-478d-9406-9f6ab3007975", + "hash": "e3b2832db88fc44253d01c90df041aa9711971db1b57c8faadf75dda763819ea" + }, + "777": { + "lokalId": "5f85bab4-732e-4937-8b44-84cf8ef412a0", + "hash": "0deb9dfc585ea6ef23da822a09872b7ffcbe91ccf7c9057a6304645eb4d86ae2" + }, + "785": { + "lokalId": "4a00ac7d-6c83-4586-a04f-5da3dd66b63b", + "hash": "60a9e70e71f62be7a31b3491ddb969875e4ad906ef08021e9382b0728447ae22" + }, + "786": { + "lokalId": "a9a80a41-f0ee-4dfe-9a3c-cff71f8fa118", + "hash": "c7d2e8afa83a606f5ea2df8e38ba9e2425ab1f8341e29d3f168e681dfe2774ba" + }, + "787": { + "lokalId": "40ccda5c-b41c-456a-9b0f-d0422eaa6b57", + "hash": "1e64bc92cd3bdb8f067c35689696b5b352e87c2a86fe0961ef99636acefb923f" + }, + "788": { + "lokalId": "8069b8b9-b12c-4339-a297-f677d4d88e48", + "hash": "d14bd8d330d424ab266e766285ace92522f1609ddca28cd405a6ca3f019e8e1b" + }, + "789": { + "lokalId": "faca568b-3ffc-46e6-8df6-710c7dd579ad", + "hash": "848ff5544e103f662feec4b4f69a172924de740130f28bb159726987c5134de0" + }, + "791": { + "lokalId": "6150ef38-4f26-4bc6-bd9a-0e84d2c9767e", + "hash": "ec85ce5130f60c76bae87d335d1121bed21146483a2456e5c9fd14192d6e2e6c" + }, + "793": { + "lokalId": "3963693d-6ddd-4136-af78-bd53aa2023df", + "hash": "351fde8c656db5b6dffc4f83fd076380e8bfaf91ded77c712a04423db0ac4143" + }, + "794": { + "lokalId": "04954be3-78ed-4403-a490-76df13fc5ba6", + "hash": "34d8fffa0e0a3101c25109c9195624b11f89eb4578275d329a45d2d55bfc7601" + }, + "795": { + "lokalId": "f0362d35-be26-4380-8f98-4dce00ec3e7f", + "hash": "82836af121f3b509844eb1553d4787fa50668600a67da6120e916a6a66f69151" + }, + "796": { + "lokalId": "d50a9179-f0df-4e8d-b4fa-4a574d0999a2", + "hash": "48edd39f1c6dcc616a0a5f59e0fb693c6520779ac3fc7b153c55689870bfb677" + }, + "797": { + "lokalId": "ce8c05e6-4a7f-4c2a-a1f7-415f6e606799", + "hash": "f838ba91d2e98a4f4615f06c22f1ccd07174d838d5fa748a0cd5ab5e322db792" + }, + "798": { + "lokalId": "577bf383-85fa-4009-b3ae-4a4395855d71", + "hash": "a4858afb9ae502f5bc17d6ace71402ecf6833c5ba833247875d2a8dc75b8c251" + }, + "799": { + "lokalId": "f889ee2b-ad64-44ef-80e8-39c34a30eff5", + "hash": "e1b1c8c6a59371de585bd620a09fde0b0eb14cd5e62e63328f4c354af93390bf" + }, + "802": { + "lokalId": "344d4de0-d00b-489f-b7e1-8262f3e47f65", + "hash": "851120fadae6a35a39626e620a221a2eb2c63f215e7500977c538fbda6487d7d" + }, + "803": { + "lokalId": "b5eb4bd3-3f79-4b30-a0bc-96a039fcabc5", + "hash": "ba4752763252e96e0147550c035187547038554ba52a79a7a63500e05ffea2d3" + }, + "804": { + "lokalId": "f291a279-0302-4c29-a6d3-d4a2a90607e1", + "hash": "0608c76bc3d2b88050665fcefab369472f4c720812295b5cfcc2fe27e86d7a8c" + }, + "805": { + "lokalId": "d72f82c5-ce3f-4bd2-b79f-433643b5209e", + "hash": "b74ea5f57efd464b4083c125c0b82bceaec68d308b173bef8a9a2360c2bb3b8a" + }, + "806": { + "lokalId": "fe20bed7-8089-44c0-a313-477276e88fcf", + "hash": "d15b78e980c200ca0d1a13c1ee5613fec9363b841e3071b431b678093a712331" + }, + "807": { + "lokalId": "042bc6f0-068a-4dc6-b32d-afce357529e0", + "hash": "b660187d70ab785a90de48194be51bbb3492bb30556de8a6e3e11cb7b6cd4692" + }, + "808": { + "lokalId": "1d9b7bf0-2b2e-402a-b05f-13d8d9e218a7", + "hash": "047cf3f7ddd08cce45b0616a3a8a139c4073156b4d92d4a9da6854d872cd6c51" + }, + "809": { + "lokalId": "7b9510d8-b714-4e63-81b7-f8a0aa5f11b7", + "hash": "9cd661382185cf91fbe119dc0c979edae9fce7c2b1aa09ac23a4bd289ebb78cc" + }, + "810": { + "lokalId": "9ef623ba-fdb6-4653-9fc6-69c798792a77", + "hash": "97879bb059e614e0f66fa4538ece41ad7f1282e36ddc25c6935abc6ebd252df4" + }, + "813": { + "lokalId": "251db0be-d25b-4644-a1bd-0fa65440ff39", + "hash": "c8359400ece0be9fcda97fa4fd5e5ccedad014637f64d04b3a9f879c13ddaebc" + }, + "814": { + "lokalId": "21f48ecd-8cc8-4ea8-bdce-0994bbb1db45", + "hash": "9a9ee61f0ba3c256f695e2502290f1d208db72c7dd94092cc5c0648d12c5c2f5" + }, + "815": { + "lokalId": "6c67ffed-8039-4114-9d78-1ad1c7296570", + "hash": "0543e38d5ac6b0cd2c8567c1aec3049410d1805487fa61945bf1f425e7724785" + }, + "816": { + "lokalId": "11c99f1c-b184-4e87-bcbc-74a6c5479b87", + "hash": "1a44a0e78d57711a5dc737df5ed8ca47952a582abdfd354c17813f1c706e89c0" + }, + "817": { + "lokalId": "f13974ae-d9db-4114-a26a-ad53a2850dee", + "hash": "1501fb066f8f4a28dc9402c3b782a4fe2ec2584165290052194eafde71b579d3" + }, + "831": { + "lokalId": "046559fc-8e6e-45fd-b75c-c5a491bcc099", + "hash": "41e2d0929a75dbad9942ddc5aa68c97d941bf6be6365162bd0017b776f0c3ee9" + }, + "917": { + "lokalId": "36123a9b-527c-4e9a-8237-9ddec9e00da4", + "hash": "29a4c26d29c50b27204bd6f598900d2dcb1d2cc2f7af171c067716f8136d9a8f" + }, + "933": { + "lokalId": "b3b4f095-5a4d-429e-8465-92c22cc22133", + "hash": "83136b540408aa00bea20c4e17c59ce07493d30e45b915393df2bc627810ab5e" + }, + "934": { + "lokalId": "af10966b-c235-4d60-821a-4a8bff83baa7", + "hash": "629a007650ee7461d7dd78e59578395f0045f04e2e1efbb47e772707293ab1f2" + }, + "1220": { + "lokalId": "3430d791-ada8-43b6-837b-4e6b7449de31", + "hash": "d4b0c49ab17275d55fcd5ebffea2fd557e5ee3b87eea4a29e780adc0d20b2c51" + }, + "1255": { + "lokalId": "7a9ca072-1010-4b08-96e9-079449f29a48", + "hash": "581923cb0c4bd626d19148e2a38acd0346fbad4f16a31640d9823acb092c1350" + }, + "1286": { + "lokalId": "bcb8ea48-db2d-4630-81db-898676c395de", + "hash": "61aa863cb250ee0007e0496ba61aab909e460d2e0bac7838cbf432e2d6ade2c7" + }, + "1423": { + "lokalId": "2b07e517-cad1-4ea7-bb98-4c871f83f6fd", + "hash": "f99b1023ddc62301b4a7c008fc19aaa099b4e795dd0638a0f4991e0c00d0b8a7" + }, + "1434": { + "lokalId": "4dd8bff5-d720-4c57-a769-86d565741321", + "hash": "996f0974211264b59642869611c996b5ea88e1081dff6ef349d3108ee98b1881" + }, + "1435": { + "lokalId": "600e664a-0f9f-42f5-b1c1-4d393292f6ab", + "hash": "8c8612a65337aa1200a0502fd1f47995c849694386ec82201a2fe9801f434c1a" + }, + "1515": { + "lokalId": "f2caa34a-989c-474c-8e0c-1817381769d7", + "hash": "edcd9e7619e00c5b67099f7ca6f9477fe995c6cc67401e4ff2a3b3a55577441d" + }, + "1516": { + "lokalId": "54e1a766-de2e-4133-8742-8689f31e9f1f", + "hash": "85a9f2f5ba3002d47f4e0b685b177ba9a921d5dcbdf9093e1caf0bc006f7f375" + }, + "1517": { + "lokalId": "5dfd31da-8a49-4984-8267-033e9f2806ee", + "hash": "c75116fadf4afbc9ed924fb5fbb15ce5e0a5264652480b605cb8bf2d8e512c98" + }, + "1563": { + "lokalId": "96d542de-c6d0-428f-949a-b83ca1a75c42", + "hash": "33ed70e01a2844cca1b8ec44698f663ec1d29ace23f5c9b5d324a6a7f74e185c" + }, + "1568": { + "lokalId": "54496618-534c-41a4-adfa-6f8f3e9e8329", + "hash": "310f6aaa7ff8722f890f6b111833543143698c6cc4119e3b6b48ab36054a04d5" + }, + "1628": { + "lokalId": "3981f1bc-a582-4fd6-ad32-b2365bfb6418", + "hash": "2ce4abc1070f24e76788f6b86526f3ed49da71f418033808d62b74cec3b4a347" + }, + "1681": { + "lokalId": "16be1a7d-6c6f-4375-b84c-64199736924e", + "hash": "c18b63893b083bea3993f491a0344889392a3c6e6cf66f7e9cac48b22e07dd0f" + }, + "1688": { + "lokalId": "c01f66ad-e0e7-457e-8e55-37f0c03286c0", + "hash": "f4109b76d08ab75375bec263f37e37994fef9643cd4c832db5181805e214056f" + }, + "1707": { + "lokalId": "6a0870a1-3c79-4c0a-aa3f-d70c8de7e6b0", + "hash": "221af988a9234daff13f44ceed83d4a4394a890eca2c16b8cf13218d451fa200" + }, + "1740": { + "lokalId": "f21c07a4-1943-406f-b527-df61ae81ada6", + "hash": "f3ff21f8a7d784e5d68294af1ff25ff1b35b274d28d1caa2035d1c5e4a61739a" + }, + "1755": { + "lokalId": "7f632ee8-5933-4786-8b35-1f626bf8b839", + "hash": "a5b7a3eb1dd608aab824e8b4a4ba6195b120249e114606d50aae10fb8a98f71f" + }, + "1756": { + "lokalId": "dbc8a097-bdf6-4d86-a79a-cbd373bdbae0", + "hash": "05ed897bcf3d8f61edb01656c134cd97806f29f02a42e7d9581420cf71b8d00e" + }, + "1776": { + "lokalId": "88bb5350-f729-4e8d-8e45-d0c1bb3144b5", + "hash": "5058259407a13540e586ea65295ba5b12d0be618fd4d3fc1bf4f0be33e8948da" + }, + "1795": { + "lokalId": "ef151ac7-4c3f-40f5-a785-2b256c7c2152", + "hash": "086341848940206fa346249cfbcec45ff6a03ee5d717b4bbc5aeaca209c1d37f" + }, + "1799": { + "lokalId": "07d105f0-b721-41ca-9178-6e11b026c617", + "hash": "1df8c5b447c563f2a2e9c5eb47b0ea2b0f00f0ef232bf2aad34a33a9f98445e0" + }, + "1818": { + "lokalId": "05ee08c0-d9b5-4d47-8ba8-571dad2069ae", + "hash": "4c7b32211604f74e5337ea5f21383df95220d729e53e58c80e8fad513177a468" + }, + "1822": { + "lokalId": "99878d88-f575-431d-92cb-cd741ae35d20", + "hash": "ad4fcfe4ba77cb21c9568a436280a0e9f495e6be2870de8bbf407fc4fd8b8115" + }, + "1832": { + "lokalId": "34b63c31-5d1e-4ce0-90ba-3c0f4926553c", + "hash": "c7ab201da94599994ddc9bb850ba19fd8a4e197cb34c596757d7276d77478ecd" + }, + "1857": { + "lokalId": "c1a47458-b177-4020-b90f-17ada1ab4b7f", + "hash": "8f937ebbc52fa4a75e26386b7af8d7ff9004fb3dca78be292aa7bb10358f9992" + }, + "1874": { + "lokalId": "ec43fa00-550a-417f-8298-e17982fe9436", + "hash": "7a47425e6e3d91a666ab43a9deff5c06d02f52ba9d9f58b1704d332721e311f3" + }, + "1890": { + "lokalId": "4e83e53c-91c7-4174-9633-198d38387e0f", + "hash": "ef14e9cbadeb02ec4c42fbf53b037c1530badaeb800e1592d961620bd6086fcf" + }, + "1895": { + "lokalId": "1b578a7a-5c94-4be9-ae6c-d5b7eb580f7b", + "hash": "d6c416981222835f2245939d7609df845af364dab2a94d799ab89bf95d151b41" + }, + "1897": { + "lokalId": "f5c7b965-f332-4f8a-9422-304ff0ef7ca5", + "hash": "9b2eb6ec0ea458a9dbf034c60166b770c01c1949e42bfd6f0043af840b29f9d1" + }, + "1908": { + "lokalId": "99a51788-15f4-4125-ac9c-4f84822962b2", + "hash": "8aed86a0a6ffbfbda668d038f69014dd4ef20453965cdc6dbb03128269f18345" + }, + "1919": { + "lokalId": "77e81877-5335-4194-bd47-64b2ec0125bd", + "hash": "9d7073b9f4f934b594414bf18c36da51d7e33933ac6dad36c2a36f36f70317a2" + }, + "1922": { + "lokalId": "430124e1-bf23-49d0-8445-88216cd44635", + "hash": "defaed8b6590edba0957500eb757da0c0c606a45bef9baa0b4c99a088fddc635" + }, + "1931": { + "lokalId": "3182de41-63e9-43bc-a3f9-ab5daf361909", + "hash": "8e74f80ae30d01f2aac1a70f22ff426181baca9e9313e13dab652aef9129bdeb" + }, + "1938": { + "lokalId": "4c9811f6-67a2-4df0-a554-58af11dd50f9", + "hash": "191952b4732d5025fbd303bce861362d9f16398aa3d1834bc32b9d788746312a" + }, + "1951": { + "lokalId": "6f5bf5cc-a74b-4ba8-828f-b92a251101ab", + "hash": "c9f4e0d839c054eee0091b49090664430cef527f38fa0afe807a9fcba22103a8" + }, + "1971": { + "lokalId": "eb18e290-6cd0-4ab4-aeab-c44eef5debfa", + "hash": "3e2a7a75d06acc26710ad443e1f4b09fd9f1c745d8a505a1aeabd33d7d6a605e" + }, + "1998": { + "lokalId": "7b9d7307-0f41-4bd7-86f7-e9111d77dfe6", + "hash": "1f43ca1dd07fe756724017a3705be74408b5ea91efddbc9b0fcb72d95b79d7d3" + }, + "2014": { + "lokalId": "24bf6baa-ff27-4656-b841-1020b292e163", + "hash": "c0df5d5550b98d2694eb5c7548f30d3541ce942fea01f0ac2c1131067cd59191" + }, + "2057": { + "lokalId": "3881b3aa-3263-4bc8-92bb-95bc890f8313", + "hash": "fd9ea03315db2eecc011598f8ce03c08a69035b37a582a7965b4e007658a6b4f" + }, + "2082": { + "lokalId": "81036c2f-c613-4877-8169-4dc88b28bd0c", + "hash": "2b5c84dd93ee9e3338844f59e5797a0cf718cf313bfbd2f4c108f26d1e367a49" + }, + "2083": { + "lokalId": "3859d08c-dc67-48d3-a935-95cf2745462c", + "hash": "515d3fa0b80f871745b68fe18bb8a27e9e60e714fd14107682eff9b0896a349c" + }, + "2091": { + "lokalId": "6e38e31c-af96-49dd-b877-91621eafe3ed", + "hash": "706aea86e8a7f845b566006d8bfcb5b57907347566007acb9d7662da2a8797ae" + }, + "2094": { + "lokalId": "e090dc7c-c880-4bc8-92d1-23fa5760df70", + "hash": "4a4808c4982e436d32f956047ed09de6294f0b64df07c7505a78712190a4e8ef" + }, + "2098": { + "lokalId": "80b1be3c-675c-490a-91c8-4776b2a76f25", + "hash": "ea9e7aab249d89bb2b0ecf3964e0742b1166191be9013f0bfea7d330a00834e5" + }, + "2104": { + "lokalId": "9b452970-a788-490f-8c89-0ed98eb7bf48", + "hash": "0bd37e1a26ddb6f6e39b0d7d9b3aa77cc4700448e3c8302f5da0efe092cef20a" + }, + "2108": { + "lokalId": "51acab56-8a1c-4468-89e6-846bba0e0e2b", + "hash": "42cccd679ff7833a15fafe520162d3a2689942a8246be281cbc77c1dee728fcf" + }, + "2127": { + "lokalId": "f00b1e61-9195-4e43-ac41-c24cff6ba385", + "hash": "03ce9003d562ad961dbce568ee2ad23bd6b28baff674e932fe7628728f975ba7" + }, + "2128": { + "lokalId": "1f10d3a5-aa62-473b-929d-4fdbecca6f72", + "hash": "9bb70638df85d2b12785b8e70f74355b4623696c9ba84e5ee920e51e1e0bc399" + }, + "2180": { + "lokalId": "cf6177de-6539-40b3-9140-ea98f10c4ad9", + "hash": "1f951f1103e1eac0ecd0b8fc9954438c9fc126a7b25fdcb185c827e3ef8562f9" + }, + "2183": { + "lokalId": "622c3da5-037e-437c-a048-4f36bb0330db", + "hash": "aba0b982c3964a916ee86b03f7bcde2e5f42ee23e5380173d57d26332a6c5108" + }, + "2197": { + "lokalId": "caeaf959-67cf-45b6-be42-d405f1ff77af", + "hash": "32e062d521e2b8baac3171a110aa53b21c77ab0a72b6111f3cb07367700bc5de" + }, + "2205": { + "lokalId": "90b6bbae-a096-4575-a8f6-68d024b52f1c", + "hash": "a3ec128d6fe140c7c25b914127a12a892ba65aecb17a38da603fa4bb910b1e1d" + }, + "2224": { + "lokalId": "500eb91f-7615-47d6-a61a-289c7c5d7d65", + "hash": "ffc49d9dd93e391d90898e8ec6449b63087d71c08c77a1e3c6f8d3370a863050" + }, + "2254": { + "lokalId": "18efbdb1-7234-4758-a72c-da1fd6793faf", + "hash": "dbac70c2c28da413fbed202a8248b48192eef7e2c94b1b9d347aafcfabb8b537" + }, + "2286": { + "lokalId": "9dbe184e-9ea5-4c90-ab70-41d926749475", + "hash": "11943535612637367f5d41ac2cc699d6398889a7dc2ecf9166ffbd832f1f466d" + }, + "2293": { + "lokalId": "46bb7fc0-ff5a-4c89-89b9-0b00fd7e19de", + "hash": "fcb6d66c883d0e1999b9994da642fe1490268b07492db3f456dc18644de2cf99" + }, + "2306": { + "lokalId": "db6b4a69-e0a6-4312-892e-5e8f16ee4b47", + "hash": "f2650b4e19768ccd0912aad9323c06dca07e8c3fe500bab246d1295debaee739" + }, + "2310": { + "lokalId": "5c11146a-9c1c-4c8a-9b0f-8c08ad2e6728", + "hash": "e298116a0c2607b8d0f5d1d22476877ff915c987368b133596b87094665f4fe7" + }, + "2344": { + "lokalId": "d3faab37-69c2-4226-a455-0d90ea949cd4", + "hash": "7986adb82b3e86edf9817ddb82697904165a904832e0cdbf08b9531513e8b185" + }, + "2468": { + "lokalId": "ff6917f3-7326-406d-aa56-c1c3fbe21328", + "hash": "2428f706f159750d020b3850a82b4307f203ace4de25e3cd0be863c84abe3009" + }, + "2483": { + "lokalId": "ad758c29-ed1d-4aa9-b593-556f224fa8f7", + "hash": "51de4554b3bc91bf65540d798566308887a39f975422cdfcacb6b57ce3b47bc0" + }, + "2502": { + "lokalId": "4593e973-e0b4-4a0e-a938-7c5c3f53f4f6", + "hash": "f28ed93d9a4e2563a5040b3bfed6d36295d91e52ed027a28ce830227d2ecc6de" + }, + "2506": { + "lokalId": "4ac43a94-bf38-4fb6-bdf1-cae81cb70c83", + "hash": "879d9f194782bfab5227da7af141a5be859f73b05db2e39ebe4ca4a7c3d9f50b" + }, + "2519": { + "lokalId": "89635e0f-08b2-42c7-b74e-bf976b48592f", + "hash": "ba386d00b9571cd7e772012cc2e5bb697d45240d0c642494dd7a54f5f3c295b3" + }, + "2521": { + "lokalId": "d7e88a69-e681-4552-944c-ea20686405db", + "hash": "50ccb48049a9bc193871d3768b014e1c47a5a0583dc011a53f458adbe723f0f3" + }, + "2522": { + "lokalId": "0f6567c5-b2ee-4c52-aba1-82b986f9c952", + "hash": "b04800d8fe4001e5438f9fab66d4bf917b7a1a704c5cfcac6af105b20ba67d6b" + }, + "2524": { + "lokalId": "75608456-1465-4f9e-ab47-6703b59be56e", + "hash": "488c3a1a962be1c8041f86c970db3b882864c2a4fb1e05c8b54960b25b1e43d9" + }, + "2525": { + "lokalId": "f87cb704-4413-42a4-990a-2d89868cd4b3", + "hash": "822dcdf6e8562f85aae28b593b04dc713ae767fa8c1aa9e20b860bd5e8031eb8" + }, + "2527": { + "lokalId": "fbdc030e-4ce5-43ce-898c-a09a68136247", + "hash": "5380e9aca93ea2ce4a360133f875a0e655cb871e6a1c02fe6bd6c9667588040e" + }, + "2571": { + "lokalId": "be9d605b-2439-44ec-bcd7-d5fcd1239b3d", + "hash": "82181d231b0707fc43191a488b94412a33f965d7b29171d260255705e87402d5" + }, + "2625": { + "lokalId": "ab0a2820-9c35-44b1-9e16-50fc2a91bc77", + "hash": "e302249f5c5e69318678fa84fc3c9f79cf469fcb65bac1d7ecb445243f9a1075" + }, + "2645": { + "lokalId": "bd170923-ce71-417d-90f3-c8dcd240ba7a", + "hash": "34646496b940dc2326339d9761b097f3b9e521cd7e96108accea84a7e8ab30f3" + }, + "2662": { + "lokalId": "2070eb0b-ee21-4f93-99b8-59d7b43c9e6e", + "hash": "4d9499f8e1c0dac8fc3e7669c250d1d858fd1a93a99686a26143b1829fbc3a64" + }, + "3247": { + "lokalId": "60bfb22c-1aea-4a38-a083-e2eabe72c3b9", + "hash": "aa861a3ab3ed48314595b3e2f3dbe7215f7cd756257c77ec3f72d26bf3016711" + }, + "3249": { + "lokalId": "445dcc6e-a229-47fd-8249-f9ff964cfc79", + "hash": "f18d3848b6043977e181a1f8186846f0da83d854fca59b98aa0188983e60d319" + }, + "3255": { + "lokalId": "69db8b09-64a9-4d08-92d2-ef03c97ffdbb", + "hash": "7f9e3e1d73197ab4061ae0de460325b362333c68e6214bd42a4ec8524f843b6b" + }, + "3289": { + "lokalId": "615ae579-f27d-48f2-8253-a339fa09879e", + "hash": "2b8e837c13cc1ad713f85935b600a1714e48ff3d66630664b08e1f72b85cfd9a" + }, + "3325": { + "lokalId": "7e6ac790-06c1-4437-9a81-8907729bd54d", + "hash": "9c6fb20b14d3fb7831dddcb9f6c5d6c381e5cdc48463bfc511672a4948595a14" + }, + "3553": { + "lokalId": "cd338bba-13a8-493c-a326-4247954ceea1", + "hash": "eb1f20685be943149753e78bbef5993172b97d0e18c571cd36922f8a549ffbce" + }, + "3680": { + "lokalId": "350d712b-5299-4ec6-98c0-eb242d4050ca", + "hash": "b58bbb405ab089f0460288ce1c4023d9a259b5dfe7ea83a08919a7ffce5118c8" + }, + "4005": { + "lokalId": "bd1e7ae6-37a9-49bf-9f12-51465d605ca6", + "hash": "ee650dbda9449eb7245e7a99fab1dd823870b4224a82cf110144dfe0ece95003" + }, + "4008": { + "lokalId": "79c3f6a5-aecb-46cc-bd52-bc0c5b88df03", + "hash": "8437cb90a17593b1d58c44fe27708b55e1749c5972312b7507ac3233ebc167de" + }, + "4013": { + "lokalId": "8bbc98a3-350c-4848-91ad-835637ba3408", + "hash": "85b7d19c49f0800aa06465ed48d101bb6bf9a4379e1871f34df641ec8104717a" + }, + "4026": { + "lokalId": "081f84e8-3154-4299-9117-7b0a44548c2f", + "hash": "7eaa68db1c72293f17bc55e727b37f8706a181ba578cda22cb287ff0c44b324b" + }, + "4193": { + "lokalId": "071e1376-ec09-4178-ab64-ae747ef29f92", + "hash": "e20cd4a12baacab9152e3f5aaaef5fc043117ecd56250eb065ec9f1f69f16996" + }, + "4194": { + "lokalId": "a76bdf52-a1fb-434a-9e7a-66290002cce7", + "hash": "639a32aed95a552001510afb7ff263fe6d067c0c231911bf299f0369ff0684d7" + }, + "4241": { + "lokalId": "5e8d35e0-33b9-4891-8a97-cf99bd089d1c", + "hash": "089abefb2b68d91ded6dc7f9fabb19b6d75189a2a26b4433ff8fe3cb35e76859" + }, + "4291": { + "lokalId": "d2897fce-436b-432b-826a-b0071c31e690", + "hash": "6486e45934d4c9836d6a6c4661df396c3f78fadd2f379f5fffb7efab350ffeab" + }, + "4303": { + "lokalId": "17b74f3d-e072-4541-8600-6f24fe9fea1f", + "hash": "d7190154939ffe4e19cef9816fb91bfcc5af03bdd89b31f8579a12db45650225" + }, + "4305": { + "lokalId": "760d3b6d-d8ac-4608-ad7b-7e0077d596ef", + "hash": "31042c1478521fb1f39396fbf23359daf87286c9458d2d0ab515f53c32878b28" + }, + "4695": { + "lokalId": "a42adf17-3439-4fba-85e5-3c651bfa46c7", + "hash": "a069b34fc682843b6dd15750b41fdf98bd04e57e4488a184ed0592eb802734f0" + }, + "4703": { + "lokalId": "a2f3d8c3-aabf-4930-8a71-9d60caeba485", + "hash": "c7b659d6cdc65c7109b1ce3da73d86be037178f29036f3bc3858d50bde35d26d" + }, + "4741": { + "lokalId": "04474762-452f-4f45-81d6-b0a57ca0d1b3", + "hash": "e9569fa54d02c14bf5d2b2494f5e47b38b534f4047fc10cea6a5c7d60a31aa0f" + }, + "4855": { + "lokalId": "9053f913-d385-46e6-87e8-c9f72c3abcc6", + "hash": "517eb88a2acb2c4318118c4e9e75b4f2c2033a6d361b41672bf6dc06b3362f46" + }, + "4908": { + "lokalId": "7d059757-8142-4fa0-b94d-bf31fd7ac79d", + "hash": "54527ea6c2c018cb1b8b5568c901c0f23bf92bfd3b6cd10a9764affd472a5e70" + }, + "4963": { + "lokalId": "621f64a0-6591-4302-a496-c2100b4badde", + "hash": "f6bd1a84b0dade4e7a0920cea1b1b041ee030b70df900d58f1fee7065a458500" + }, + "4969": { + "lokalId": "736da8eb-79ab-461a-8f87-0390f1bfc158", + "hash": "d5981eefa2d5a004887c1108dcb1d37a08848ffee3d6e2192d13e699e08baea2" + }, + "5463": { + "lokalId": "285e19b1-b39c-4baa-8ce1-c1b904b17cf4", + "hash": "e2be6b4eccaac3cb06ffe814673f7b654b029d2690d14658c4faff16ac91dd56" + }, + "5617": { + "lokalId": "43531c8e-550a-4caf-b077-89491bd4287f", + "hash": "8d58611430f1bc8dbc4cbf064a67661c7a54c2c4d5f3e2ca5a4bcee3956b4edd" + }, + "5630": { + "lokalId": "8af363e3-e6f6-46d9-88b9-04bc49ca61fa", + "hash": "816ddd4cf95713203b22cdb808b2f5e4107b1bb1b46dc752fa1573d2480e66ad" + }, + "5647": { + "lokalId": "ad98197a-6f34-43bb-9b5c-dab76e9a5942", + "hash": "ce6a63f96e3276fc9b257642c13b3293210af0ad0b4b0e09f6cb8f6971487050" + }, + "5652": { + "lokalId": "6419162f-8b96-424d-b00a-79758ae70321", + "hash": "55a9ab87c8f96fd67f105f39ef72448c4eaf17556e8a087db3808ffcbff4f46c" + }, + "5653": { + "lokalId": "b9bef6ae-a60e-4003-a31a-06e8d0030012", + "hash": "a11bf8b42852de97ebda8555196e601373e4be792cdd60d02be03a560a89f3de" + }, + "5655": { + "lokalId": "a9375a02-3c1e-4e03-ab54-b9344e90b735", + "hash": "ffcd7492f121434074b9abfa56a1d9005a908603fe05c39ec0068e4781e088fd" + }, + "5656": { + "lokalId": "4b502661-d704-4708-99ab-a70fa85ae313", + "hash": "a505259eeeb65b11b62580e7883049ddb520b4f033dee0c65c92feeb7e81702f" + }, + "5657": { + "lokalId": "264e4eab-8f27-41a7-8d82-3941616cb6e6", + "hash": "73cc7c328e033eb14d27bc4a1d00cde108892b8ef83f6168671c15b92c304fc5" + }, + "5658": { + "lokalId": "29022bdb-b063-4925-8017-bb7fe03d9273", + "hash": "084f89ab8d9a231ecc9b4f490afb62c3f53eaf6f818ce80204ac5fa7b2f24737" + }, + "5732": { + "lokalId": "5657826d-54bb-4948-8b29-265e36d3c31a", + "hash": "d1f099a2c92b8f63a45e1a14239139aa9c40bd16201f5f1818893e5b77ddd6cc" + }, + "5815": { + "lokalId": "273bd714-a70b-4d58-8095-2090f8029dff", + "hash": "ad22becf8d2b54064d143485fffa9db901aa91585d046dba6469ec36eca66f11" + }, + "5826": { + "lokalId": "e93b8818-17a6-4d07-a7b9-bc4f33f8b9bf", + "hash": "aad8809f0b479220f1420151ec0a9e3adbe45234313117de5090b4017a2f3301" + }, + "5832": { + "lokalId": "a8e20ada-cbae-46ef-a1d9-2330565213f1", + "hash": "340a90a0639ae2fc3bfff4fa2899f0a520c62bd8349bb04334e5673e71615f56" + }, + "5962": { + "lokalId": "fc0a17c8-6813-4f54-a195-96e7bfdf82ca", + "hash": "37fd97c755a0d86cefceb40ade52a07f4a8c647d1605bda37de528be168e72d2" + }, + "6056": { + "lokalId": "c9edbad7-9672-471c-acc2-ce6994c54e96", + "hash": "4aa1913514c21e3c5ac8e7a1db08f70a272e49cd57fa611a62e784485c2534e0" + }, + "6074": { + "lokalId": "6258617f-20a8-444e-a252-61b707c0a5ef", + "hash": "dc517876b5c9b6daa9850710a01890356fd88fa89711f3197c0f4e8b604b12d4" + }, + "6157": { + "lokalId": "11ae8b56-aff7-4403-8944-906c31b01d4a", + "hash": "903bae091712f541fbdc3cc9afd9d8d28150d75d726c137b4168938afe88eb19" + }, + "6160": { + "lokalId": "74dcdf29-b88f-4148-b7bf-6fd8f5285851", + "hash": "a058ed3c023a3b32925a021fc295ca00d46e19a70e6a2ef3e6565d5bab67f098" + }, + "6206": { + "lokalId": "b44e212c-351a-4493-a024-89c5dd0c556b", + "hash": "cfaf6dd1750b2d6b7446493aa75505ad0ec45e8eb58bbbf3c5173b3d9906a26f" + }, + "6207": { + "lokalId": "c7dd72e0-36ca-4ad9-9ed1-ed9f4bbf0728", + "hash": "734af4b67ff493e8f65fed5d35e1b714c5e5714b38d554c0c24231b9c18f5c86" + }, + "6222": { + "lokalId": "b0907b0f-4410-4cd3-bff7-8bbb92f068cd", + "hash": "d696f3278ffe5170a1830e3275f24dbf36b71339840f250ab96df6d6f718aafb" + }, + "6342": { + "lokalId": "020fdbc8-bda8-4dce-ad2b-5b373428984b", + "hash": "a806e44353d61f6dc2d0d8ebcf5439ac1d48c4ec4764cc71d8bd02dca8331bd3" + }, + "6356": { + "lokalId": "4fc91e71-701b-4fa1-9abc-a3a9321d9028", + "hash": "67a3227fe15189ae462ba2417a84e4eef3b6243a161cb123466181c2ec3dc2fe" + }, + "6394": { + "lokalId": "211a6070-48f7-4906-95d0-6b37b1d5c37f", + "hash": "6de494234f69e4ef130723d93fc76d7887925f605b9fceaff2df1309b5176a9a" + }, + "6442": { + "lokalId": "88e8a0e1-3ca7-497d-bdf1-847a77c25863", + "hash": "ee8ba651ac1eeaaec1c78c1086ff38b78534a2d3cfc81eadbe2941363283c97b" + }, + "6547": { + "lokalId": "82f73d83-5b2e-4976-9890-d1691e909cb9", + "hash": "908297a03aacf914da6b0a2bf29d3f83e66147a594f728e2c62b215628bfb9df" + }, + "6720": { + "lokalId": "8f159ffd-778d-472e-87f4-9e1c1bb00b55", + "hash": "b45deb0198ccc1317f611111fef13d5d7f4b01256c5134fcad1ca9c4f9cbb8e5" + }, + "6749": { + "lokalId": "c0e12c08-fbeb-46d6-81ae-8697867af521", + "hash": "d2c923f3d7a4b29d5728156f91e71a6b21402577b45ab7865d9b5a2da250f0b9" + }, + "6815": { + "lokalId": "69fcad1d-cdb1-48d9-8f6c-2f8312ebc852", + "hash": "927ac0af2f89d30773076e68710571ce5fc9ad2d4df0fc7f6eaf2505e5e2ebff" + }, + "6819": { + "lokalId": "d5a6c909-996e-4d0f-85ed-66b500b6d735", + "hash": "a00be566ccb2a60f4f24a7c4336edc82900373c521e0507b7cbb2afa5913dfed" + }, + "6870": { + "lokalId": "3ce98fb6-fb8d-4f8a-bd1f-c4b3ff4a5760", + "hash": "ffb9bf873624eadb1fc8bb2fe10fec5f566292cd91020d15dcd25e7b442fd939" + }, + "6963": { + "lokalId": "ca0e5900-47ef-4ca3-a295-aa9c3e364c23", + "hash": "311b91a77635a8b9aa07ae54795c644a5d4225ce265d5d19e8de039989a23ca1" + }, + "6964": { + "lokalId": "deb03115-4c8c-426f-bf09-21ed6e3e7ce3", + "hash": "53c607555ab7b9d299fc4e45039f07eeebb6ad27015beaa148e7ee7d32eff611" + }, + "6966": { + "lokalId": "4629cb67-77d7-4931-9058-6ecbdde75759", + "hash": "84f835a8249dcbd4e5c21b8ea6b4e36ffa54668579a0215cefd5cb233518f513" + }, + "7021": { + "lokalId": "9247faac-69ee-4767-b7a4-309194599607", + "hash": "533ada4c1a0ddc3b2f4441d5e02404b87e69f10edf1b9a6d640b0aca84995e07" + }, + "7098": { + "lokalId": "855789f2-7727-4989-bb87-16eb79976e22", + "hash": "1b0802ce70f9c0e8eae3c3db0fe4c53f67d8df12f1f7708c8445bad555ae9d1e" + }, + "7103": { + "lokalId": "e421f550-2a15-46c9-b362-2fc95d9cd69f", + "hash": "29f41a0720041aebe19ac7d63c7cffc21db4453a6d66f6a841791695955a98f2" + }, + "7105": { + "lokalId": "5dd521ac-8c6f-4cd6-9fda-e0ac8633fafc", + "hash": "4e40a3a8192e532ee9b7846be48a4e330bad37ffc7816b37e4b5e555c4f5d814" + }, + "7106": { + "lokalId": "2a6a97c4-7980-4f61-b211-59b9c1ae98b8", + "hash": "b02c252df49d8ef197e53ac0b4fa8ebb2f4340195a4ab0a25fcb059c2c86e498" + }, + "7107": { + "lokalId": "a80879b0-7855-4b78-b1cc-224e80053017", + "hash": "61cc9ebd133035f904abba0d3b61413c39e3cb7a0c70277af07d99759c96f05b" + }, + "7114": { + "lokalId": "c97bdfa5-513b-4f5c-b890-b86c0721fe1f", + "hash": "2d07bf965a07a903f467811abf76ba4cbc826c714b283e11fb50b6f0435cc58b" + }, + "7158": { + "lokalId": "5f71a61b-7249-4742-8d0c-a6bf9b1e43b7", + "hash": "87baf9ad9e71b5c889fd23b8994b8bedb5b1c675bfcc1b7509e2e196d6a31cbf" + }, + "7254": { + "lokalId": "da0270a3-0707-4432-8a1f-005127ad43d4", + "hash": "ea709fabdee87aaeaaf90c9ed30458be7a9c8e731fc9c147e0862f0570430e27" + }, + "7270": { + "lokalId": "e19bfba4-9008-4e1d-bd7b-cd6616e778db", + "hash": "00665805ffab320bc451a5e5678e841d922c6b9453d340506936ba6339211329" + }, + "7409": { + "lokalId": "e2fd0e9f-a27d-4763-be62-1c688bba3a28", + "hash": "d1cbddfbedefe40d6b572f2faa493e62a690df19c85d60b4a343f8c5aa258b3e" + }, + "7411": { + "lokalId": "b8199986-102d-4723-aaa7-cbc24be1a815", + "hash": "8f85ff796847178a18b556ecfdba80f736d37a84657f41d83901c8d097f8408a" + }, + "7412": { + "lokalId": "cae5bd97-c0a1-42d6-be24-b6ebc85643f1", + "hash": "7de785c88e5d6f92a69cd806166bbd2570b4c167f1641011ab73c6141ddcd26a" + }, + "7413": { + "lokalId": "2a581313-ce17-43f9-b7b4-afcb1bdf753e", + "hash": "66b68133ad41dd63e48a869d124f98473efd7b23b0b9488cd863bc3f9a74c3fc" + }, + "7436": { + "lokalId": "d3c5b6a5-d52a-408c-ad26-2123ad29dc9e", + "hash": "fef3373d4512532a57b821c75f6921d558ade18440c8a65ca58a1c7cc1d9b2b2" + }, + "7438": { + "lokalId": "184a10cb-8090-4148-ae46-f5a4ae2682a3", + "hash": "73951bd6c0635c50dd892518023ea60c0864fd01e3f5df1825666512928b396f" + }, + "7443": { + "lokalId": "f5e7ab16-a4f9-4d5c-a1e0-c8a8296646aa", + "hash": "6a34034fe955647321b7bb25422176970ac66b8935e003b75721dc39288fde91" + }, + "7464": { + "lokalId": "e72a2943-dd93-4589-8a17-5eaaa7910249", + "hash": "281b5be5838a48f2a1c68737d2149a53bce36e4eb8faf0b888094b1471a62de7" + }, + "7574": { + "lokalId": "ec4a27fc-c013-4bc2-ae9a-bc5a5288815f", + "hash": "01bb38a56519fc9bec106288c1c0a61292747cb610597a70d41cfc093c5cb5c9" + }, + "7856": { + "lokalId": "7a535224-100b-46b9-a9f0-aba44a14b199", + "hash": "eb49525c7229aa37c65631c7de9d024953b885e37569b687b87328ee174523c6" + }, + "7956": { + "lokalId": "1e75c786-d51a-4031-8091-20dc88882ae8", + "hash": "ef7ccbbcf18e457ddb56d2315e9a011377f86bb92db09871b75f632cecb35bd5" + }, + "8044": { + "lokalId": "6ae7f44d-6720-4253-bab8-2220a6bbbef4", + "hash": "67b02a4dc08f2f0caee81e7c498e731a19694b3d15e375da8de9952c9a008529" + }, + "8050": { + "lokalId": "9f8d96a2-996c-4d40-8dfd-37b8fbc56484", + "hash": "7464bad7ce1936653845f818c0321983a98f0a9a22b4a448a84ddbff0fa81c47" + }, + "8060": { + "lokalId": "643fd541-3e17-4659-ae16-2b2695805a83", + "hash": "0439488074f522550d7e5d3ef8f580a581c8f4f6c9e004785365574215f23a03" + }, + "8061": { + "lokalId": "33a1a528-7a68-48c8-88b6-33f75561f3da", + "hash": "c6b39d32b49e92632eb6f496e5079251ca2733c4cf408f5bd37f44a9be835a27" + }, + "8062": { + "lokalId": "6f148b19-4a8a-4947-a5f7-6dde0d6621c2", + "hash": "3731dad4ef3e8c15da774c083d9a6bf0fca551202f0d743aba6cf9464979fd6c" + }, + "8063": { + "lokalId": "33d9983b-de55-48cf-896f-fe83c8a382c6", + "hash": "c01a79a3682a662077598d3005f77c67543c8d1d8ff1f9dc96d8b6f29f43d54b" + }, + "8064": { + "lokalId": "2aff0b60-3f61-40da-b5f0-a61a9235c228", + "hash": "d365943fd5f9cd93a88fb7b85c9502507d67f427379724cbf41427a9fd55cb5b" + }, + "8823": { + "lokalId": "71e84376-749c-4b71-b9b9-69213873ec16", + "hash": "cb44ae9771b3e97e1017c30854661342688754a42cf12504628a324cedfcee3a" + }, + "8825": { + "lokalId": "06b69813-6d52-485c-81e7-6b6fccee2a9d", + "hash": "feef44ea6df57542634dbf087843207a8f1fc913860ccc293278b95075bef209" + }, + "9067": { + "lokalId": "b05ee175-8325-4dcc-a54a-dbd689a94881", + "hash": "3644f9a608793e4decd4b0927a5e984995ef530b3b4eae162506ab70b0f03512" + }, + "9071": { + "lokalId": "0f83c912-e50a-4576-838f-d995721b92e1", + "hash": "fd3a7a613201ea283e2a3e0e27db0ec06378c8abe38a1e9a5a52bb35a679aa3b" + }, + "9092": { + "lokalId": "7fa88641-07a7-4642-bdd8-5cb2e8a9ab6b", + "hash": "7ace86e3501b9cce5ad2732c42bd2e6fbf967bf6965cf196ee0c58356d78020d" + }, + "9093": { + "lokalId": "5a471a91-f381-44b4-a99f-ce36a110056b", + "hash": "cebec051bf65c62e583c6a0e08351623d446161e1284c48270c59cda9427bdf8" + }, + "9123": { + "lokalId": "90333a7e-03df-437c-be2c-bfe95f3b152c", + "hash": "728992a4ee76995b82c03db7249ea8eed40fde4b6c6ea6ad7fe80b4febb317ca" + }, + "9214": { + "lokalId": "e5c135b4-3c85-4caa-a964-c3014a3d90b7", + "hash": "98de19544d73377cb01e92d9c086dc8bf7fc2ede58138f08fe4f33623e864276" + }, + "9357": { + "lokalId": "067b9d45-ce18-4da7-ac44-d44abbe0e65a", + "hash": "86ce9c744c2c7365e699614b5faf65790e783388c2962018c4c09abc01e5d17c" + }, + "9398": { + "lokalId": "d9027703-54f2-4db2-8758-67f4191868ee", + "hash": "a076ceac0bf5adcc8b4fe42f2bff8b67ed1392605f399dab025645c5fef1800f" + }, + "9403": { + "lokalId": "41367d20-2703-4f35-b9c4-27fcf8c390e8", + "hash": "efce57d115288fe468c2088a48598cdddb21aced24182f37dca655a713fc2bd8" + }, + "9404": { + "lokalId": "f6f36982-d68f-428c-b331-191a0f18bce7", + "hash": "c0276ed13d3fc841e0b7c2bc749a09f90faaac2276f58c998793887aeb7f22dc" + }, + "9405": { + "lokalId": "8982027f-3590-497d-a1a2-c6b89428db2f", + "hash": "adf71c22d82a19f1ad0cb3845105c6b46632a477efe2f6c938f5e78869a2da8c" + }, + "9407": { + "lokalId": "cef43de7-c34d-49c9-8cb4-688f66fbe967", + "hash": "c9dff16db11cf962d0e0544e8f187928bc09a1db5d1564cd06d71eeecd01dfcc" + }, + "9408": { + "lokalId": "4b11bd81-4f60-488c-a95a-b09990da93de", + "hash": "b83b8fcc2c33e9b7569d4b858822df91ddaf07620d96a95726d0eb479553abbb" + }, + "9410": { + "lokalId": "b6d6bf46-a881-46c1-8507-ee12b67baaf7", + "hash": "998c3db12d6da6e7363a584f905acf6529ed8356d5ff2619eb37998a61dd5181" + }, + "9412": { + "lokalId": "daa0beff-2f73-42cb-8d08-0040530d867c", + "hash": "abb1be000c030da490e235aa19c605ca35ce0b65f06412d9f36fcb756fff816d" + }, + "9413": { + "lokalId": "0edb0196-1349-4a7e-98cf-f18c3de527f2", + "hash": "f0f865d951e6e3aff11ef682a421988930ab035f314a0c531238e7acec13215c" + }, + "9474": { + "lokalId": "2cfe62ec-d386-429a-89cf-c36943c87049", + "hash": "3df0fe84030e97de48c1891d49775e6a620522f50552d8ed2eadac3d74c959c2" + }, + "9505": { + "lokalId": "38323907-c317-4139-88a1-f8277206fc16", + "hash": "40660ec48638047931a48d2ccf7b1a693b0231b485be98b9063304339b1e3480" + }, + "9508": { + "lokalId": "99b123ca-c4a9-493f-a2cb-d7d431bba3b1", + "hash": "6a8c01e5cc46de76e97bc297f3a6545fb1460c082e613c9f732b04cb15f64104" + }, + "9517": { + "lokalId": "6d1cdda2-81e4-46ba-ae01-7d339b9fa3cb", + "hash": "ded8c7d20e79f89bc5caeb7964f757f102d7420413feedae845db0f1bc6a8a32" + }, + "9521": { + "lokalId": "b7261050-3653-4527-b58b-e8d3c86e97a1", + "hash": "139c9887a1f373e07dc5cc966e9d660500b33708363cd6b462e5ab2a9ccacf32" + }, + "9528": { + "lokalId": "fc83aaef-5a7d-4e86-946b-456616421ac4", + "hash": "ffe6487c3e6e2c0d129639e2a2bd5b5c0facc14b3fea5d96bf9e1e15fced513b" + }, + "9529": { + "lokalId": "5e85d398-57a7-44dc-9c7a-508fd6de9701", + "hash": "357a6e355f099dd16e0e0f4eb23c31b69078d751ff3d605bfdde6d517247a40d" + }, + "9548": { + "lokalId": "62875c5f-e2a7-47d7-8bc7-73c886fb885a", + "hash": "d26cc5e05037aa57ddebdff5750003f05d0b3aef3a899ddc3a91e2feedfd5c0c" + }, + "9550": { + "lokalId": "600e3214-35fc-4a55-bf9f-0f8395d2ebaa", + "hash": "b830bc607c61a067f8ab5ef454d91e0df47e523614641c24a15917c4a3ddf5e4" + }, + "9670": { + "lokalId": "5f551f66-a011-4013-81d6-ada56cd651a3", + "hash": "ec19e49024d8aa5556ec2e514f037caad39750687f7f6f0963c2424ae2dccd38" + }, + "9806": { + "lokalId": "c2d316d7-0bca-427f-8595-ccdac7a04b1a", + "hash": "0d5501e7bc1dfd79ffd1fb6ffca72cd666785a59a8248155790f84501559e0e3" + }, + "9852": { + "lokalId": "08ca6d2c-7c4a-4cbf-8108-92ca7bc4e3a8", + "hash": "92d4df3ac807c570d4fef582ef24701146aa1db88cfc47048e2fa5250e5da132" + }, + "9915": { + "lokalId": "2e80ecc3-e10c-4bbf-922a-decbb33eed4c", + "hash": "fd09d2abf29bbdd5ea6398072b2e14ed1c857bfa596e145fe03ea11073d48931" + }, + "9952": { + "lokalId": "8f0ebab1-ad0c-4392-a3ce-e04b84c68051", + "hash": "9dc44816dabaaad6a8465a263e455d81439d514ba8482a7d1cd76129cc00eb5b" + }, + "9983": { + "lokalId": "5a109f1a-538e-4ebc-9d68-4737889b6a0c", + "hash": "a3936e86c67823b1932c991f24df433acf10ff024cd07e2609ef7eba4182798d" + }, + "10113": { + "lokalId": "095707e0-1078-4013-abfd-bced991cf37c", + "hash": "253ea792b27135de42615445b6bfdcefc9aeef2cb46fff8f85dabd9834c72267" + }, + "10212": { + "lokalId": "8d40461d-3f49-4a67-aa13-7ef4a5a10be7", + "hash": "77d3584f0fc2c8f7ffa8a147a88ff05194b9634d838661c56f47b8e24f1f7b4d" + }, + "10387": { + "lokalId": "8846ad2e-0ac1-41a4-a61c-9b69a355591d", + "hash": "6fe4f270140abace80024ff21df265b5aef8052edeb41878d2bd42de9c67b069" + }, + "10507": { + "lokalId": "8eb9f6f9-d698-495c-83c6-50051bc352bc", + "hash": "c722a79209260fabe339f41309434f84ecda78c2d46313a5e27581f0d3bc3888" + }, + "10508": { + "lokalId": "c0f7c2c5-e255-4164-b490-a86dc74c8bde", + "hash": "351bf03031e99ba45e912a6a638e896267666a701e61d6d1fedca878d234595e" + }, + "10511": { + "lokalId": "c11538e1-fa0a-4c2f-8ab7-76afc86d4aba", + "hash": "84f775a55ae550a8a0ce9ab701174853e4ba358b427c2172f863536b01413f52" + }, + "10512": { + "lokalId": "c79d3810-a866-4cb6-9fa1-6afe9944af71", + "hash": "2c244a2e29f0369a4c3f5f2d1e0da0d08756088d7ae13287c8c144a98c139c65" + }, + "10516": { + "lokalId": "26cc75ed-fcb2-4c23-ade2-c3a5675388c8", + "hash": "99747ab855b44076a2a408f4e886adf13351ffbea3f6618a95d3f373afa27ed7" + }, + "10788": { + "lokalId": "33791aa2-b892-44f2-826e-1fb144af63ab", + "hash": "4aace6511380f024576e3e9ff9c1408740041e26f8463f459653fc5bcf7a3665" + }, + "11235": { + "lokalId": "42d32a56-68c7-4312-8dbb-a91fa57fc8ab", + "hash": "d8d89cb3b6c43512e799ab9ac16e3c322c840261d17c1da50b69802c12701bde" + }, + "11236": { + "lokalId": "029a5eb2-86cd-4974-8203-cfaf6118566c", + "hash": "7f0b34205a87974961522f6808b49e3d1cbd4487040bc4bcfe52c2f695163c96" + }, + "11284": { + "lokalId": "8d94830f-9e52-4089-8761-c51471fb0838", + "hash": "5dff10986bf7eaec8d3dbfc2c53a07bb862c57311b9e4156af8764eb62cc38f6" + }, + "11285": { + "lokalId": "8209ccc3-eb5d-4006-9c4a-cbad422aa694", + "hash": "5206ab1dd846fba9da16822802366041de8174f1d303d9ce8ada44869bedcdf7" + }, + "11289": { + "lokalId": "01b1a039-958d-4db3-9863-69ed83a338ff", + "hash": "4b175d6c7d017a32774dd86905facc71e563e64906ce961f995c1bddab16db7a" + }, + "11343": { + "lokalId": "f3fb1a32-3a10-472c-9182-38b2890fab0e", + "hash": "aa1f3bf4ce35fcbd02cf7e74dced1381770de6e9f3f17eeb521eb44414418639" + }, + "11424": { + "lokalId": "619b9298-21c2-493a-9cd5-a6e97f197b36", + "hash": "ab2d67ebd452b447f96fcf697f85e04da2fbe06962c521ef22f24dd45f868e72" + }, + "11663": { + "lokalId": "b34f8e20-f8b4-4087-8aee-2d960ba0b2c2", + "hash": "1ead008f47eccf1375584e950b2204a3c45cc8ca912c17bb66e137ab9f011a79" + }, + "11675": { + "lokalId": "313cee4d-6ee5-4336-a1cf-9930e8dca1ff", + "hash": "4db4fef01530c0729094eb4f999244982a4d01932a26203eea8035d3cda41a28" + }, + "11677": { + "lokalId": "1870bad7-f219-4af7-a03a-5c3dc4e11dbd", + "hash": "93255410f6ee89c25cfbea1cd0671fe22592ba88456e5310eeda803fee048018" + }, + "11681": { + "lokalId": "1781531f-d142-4031-9efe-3f1cb22015d7", + "hash": "a65253b599d7d0dbd99c88a1be46e1702bb29ed80230be8f134f246c8e3248c3" + }, + "11686": { + "lokalId": "a5f39409-edb8-4c1a-8e18-46a409d89790", + "hash": "f4b6e01c4010a1e0877afb2b0b7cfea782adf09282fbf0c54ca4099a8880120c" + }, + "11688": { + "lokalId": "b101f3cb-1700-4732-835b-9da02bd7988b", + "hash": "f92af47ff07bca9ec4885ab2a0674c677a7e478421153e23466712b22ef23d21" + }, + "11692": { + "lokalId": "a5512a92-86c8-40df-ab57-0d6238414a36", + "hash": "fbe419266e3cc7be407d8b302c3096ca746107551c04638cac3bb1f5f5394ca3" + }, + "11741": { + "lokalId": "be34731a-d1b8-4498-b0f5-a1ab88784fb9", + "hash": "ce8fb0dcef8a480771df73078480715a6714ba4270e3be6c8e36c0b48992fde0" + }, + "11754": { + "lokalId": "fa7d1131-d667-4306-a9db-f402a7255406", + "hash": "ec04a949aac2a73f0de56c2d301ab034a638a8437c58917aa1927561479a9151" + }, + "11824": { + "lokalId": "d54d43b9-3102-486b-8133-4965ec0ecf9a", + "hash": "ad2f176739c8ffa5effd017d319ef9e67ad0be73861c5477da3bea72da317b4b" + }, + "11848": { + "lokalId": "a2ad77e3-fcc1-44cc-86fa-1e3d4382498c", + "hash": "f157657a6e17b5267492daea18c8009b8c846a5decb6ae5f16ea362dc0a1a5db" + }, + "12016": { + "lokalId": "e1621481-e029-4294-959a-03f3e694b3a6", + "hash": "7b2069f544a528e7c04b913598e8b0e68003456b74f393524527e1ca4676f149" + }, + "12021": { + "lokalId": "4b961101-dc7a-4182-a53c-f60114c40dea", + "hash": "a1f0435277aa76c2dd9a8709dfbb92284eb53ca47e2d5985d43847b0726452b1" + }, + "12025": { + "lokalId": "fc7ecbe4-4463-4b31-b6a3-2d61ef2c0d81", + "hash": "0a599fb56e61b9e0c4f8e062ee690e7fa69d9cbf920b2e0c44ad118e0b12630d" + }, + "12072": { + "lokalId": "53ff0cfa-5602-4b93-9f83-e782007f5a60", + "hash": "28f7d844b316064fcb115c49f4804a1ecbf62a91df7a51c476717bf2f0a08f67" + }, + "12163": { + "lokalId": "845a2db3-5b54-4ec2-be41-4e45bc06233a", + "hash": "52c30c0308405506f084ac85077c597a59962e5a15942f6911b782f08d394304" + }, + "12196": { + "lokalId": "cf5349fe-1744-473c-bf4f-a6ec9be9a917", + "hash": "766737e963ebb1a4d2cbe8a878e67ef1d584c7fe61b7913356dc41a8e8b634e5" + }, + "12245": { + "lokalId": "d6d29843-38b2-4401-b4ca-d3fb5f898fe3", + "hash": "6a36838e192c87ecc9aadd1b65854574a22c815411c13b04029fbf026736e577" + }, + "12272": { + "lokalId": "1d168220-e348-469e-91af-5d5d207a6c16", + "hash": "d69bfcc09c8b3d13c966ae8ff4bc3f27fc7ee19a5824d568dc7a7aec2281f0eb" + }, + "12304": { + "lokalId": "a9986c2c-d68e-4d5b-92f6-0a83e1ebf0d8", + "hash": "ff7c31124aa3925a075b88ae0507d66454c72ad2fad492d027954262e2281f0b" + }, + "12306": { + "lokalId": "08b4ac05-f464-4bbc-88ad-4ac1d4a3f19a", + "hash": "4d4bfcc009dc0ecde7e534462ecfde5f6f64d6bd69c99f8a4b268d165d4dfcfd" + }, + "12307": { + "lokalId": "ce142752-b3f3-4b0a-a397-a0116e6823bd", + "hash": "c342abd5c1a17c87a28da7fe83914cb1a08b24ecba088c4ab46c54808b0c453a" + }, + "12308": { + "lokalId": "e1bf8cf8-da5c-470d-be3c-09983b295f3b", + "hash": "2e725316d9d254039f8b1c5195bb13c4f9d34bc31970b702cc46193ab7122d1b" + }, + "12309": { + "lokalId": "e85fe01f-18d4-49bd-9225-151dd1740296", + "hash": "503248b0a48680910d5dcc4691f2d8594b315cd046757a24964eae15297818d3" + }, + "12311": { + "lokalId": "fa3c0eed-c15b-44f6-9e8b-193b3d71f48f", + "hash": "8eb99d6f16c3fa997c17c4ffeca12aaee317fc07685d2ae20ad1dcf8986f6182" + }, + "12312": { + "lokalId": "5f330286-aacf-42a6-a2c7-10e2eab114d8", + "hash": "cb2f3d33ea50526d32ac5e27aa1379de149af36cdc09c33cfad13b87624fe134" + }, + "12313": { + "lokalId": "01705a0d-31bb-4df2-8f53-7b69851423f6", + "hash": "660bb1ed6058400612384a0d5cd881920bf48ce9680569028377ed561f59dd36" + }, + "12314": { + "lokalId": "15e6d2bd-d724-4963-942b-74976a67ece3", + "hash": "524ec10a9772dde82bc4c026cfc66575267695180fce7e7d8f0098870d52a19a" + }, + "12315": { + "lokalId": "b87dacf8-1a95-4f0b-bb40-dbfa430e3927", + "hash": "5fbe475205ed180ad0ff7ad1f88f61ed8dd37281c75dc159a2764977f3c57365" + }, + "12325": { + "lokalId": "9f214d74-88cb-4d78-99b0-17c5414e63b5", + "hash": "99dafc1874a4d56da9975e216a34c366d7e20a683333bc62fd4acfa8b8ae27e3" + }, + "12330": { + "lokalId": "803d97ca-ec9a-4a0e-b079-a5122290fbfd", + "hash": "92539f42b34def38c2347281614cb36ea27fc0acb79b9e3f7bc53a024efcd45d" + }, + "12333": { + "lokalId": "ccd1cc50-f7ad-437d-b794-33608244a71e", + "hash": "1486f4021644512193a6d70c4dccd6737d3fcfc263468242e9ad462d58beb0aa" + }, + "12438": { + "lokalId": "ebb31693-bb1f-4068-8ae5-55192ce6271d", + "hash": "3dd09fb53294540e76975a4ec368f5dacddcbe935c37bbd5e6633b93d0c1e075" + }, + "12456": { + "lokalId": "7d733ff0-f0f4-4a4b-852c-13829f8ce8a9", + "hash": "f83853f6c7c03cac972c807055bb50e368841d12ddb2c49daffa137e13fbd612" + }, + "12704": { + "lokalId": "b86b9334-0282-4f90-9c5c-17e363f35737", + "hash": "0e0656501f4ebfba1da97ff39c708d8d4601fbdac08f13881ecc27c19019d921" + }, + "12705": { + "lokalId": "f3043940-39ed-45c1-a38d-0abcd345fb40", + "hash": "6004acff6d4fb5f2ddd984072c02f8857c24c713ae6f6b815d343b88790da5dc" + }, + "12706": { + "lokalId": "6ff3cd7a-61d4-4768-9321-7b4c41e9f66d", + "hash": "2f4995de48774eaa35f6a3aa76c8b39a2ac9e6b252b12632149a8a23382e69d1" + }, + "12707": { + "lokalId": "60940b83-da81-4531-8dca-e239242c0ce4", + "hash": "d60011a6bc5769ae5947a9c2f17ff454b3f3ebef9a398cdb1c487b0949380574" + }, + "12708": { + "lokalId": "169b8bf9-6b31-436c-940f-6d267c832e24", + "hash": "3049f0417767351f8c2cc914a7adf2c9cc8097def36753fc5238875e5b7760ec" + }, + "12709": { + "lokalId": "edd33296-2f53-4fbf-a478-e0c648cf6509", + "hash": "bef7179e08403eb7163a7fb64c7e9425bb528802e4a624d84662b7aa71fa308d" + }, + "12710": { + "lokalId": "c63ba92e-697a-4d43-8fce-b134bcc659ea", + "hash": "d69a1e540403b3f10a76e142434dbcb8a7a7bd847569f676657e5c55458b8f94" + }, + "12711": { + "lokalId": "bb6cb135-3dca-4bab-899e-342c5428f180", + "hash": "5680aeb02139ded851e433b51e6da444d77c78d8d29e1bd22ca7f9446c008d43" + }, + "13266": { + "lokalId": "099c3961-2d31-4212-990d-0475f6aa4347", + "hash": "ed282cbcd36b6d3044b4ff49730964f1da514a23ecf6daa893ee7b2a208f360f" + }, + "13361": { + "lokalId": "d735c9b2-f3f9-45a4-80df-46909a6b0745", + "hash": "fde66cb0c387c18194a4b8e08714ffc49e9c310684788c8608085bd1069c0994" + }, + "13469": { + "lokalId": "99435820-2890-439d-8f5c-07c0e5568e0c", + "hash": "b89d6f0be2d2d6c381b39ded356c1943f3e3fe746a556fc1f066576f0731dbe2" + }, + "13470": { + "lokalId": "01f0a99f-611e-4485-93ed-91ef803c2d1e", + "hash": "54df0ae90c9aa711f2c9ae7c20cf6f9c8da4a62cc0299fed73e7a4a1e11e57c6" + }, + "13471": { + "lokalId": "70a84d28-47ea-4c80-b446-aa1b92936b38", + "hash": "3b6d7a647455e7746b770d08666aa41cd846247caa90882dbac7a4b769e60b22" + }, + "13472": { + "lokalId": "c46c94d1-5edf-441c-9f58-784733b299fc", + "hash": "6c70e0dfebcedb0f76db43bfb767a6f46c625c4659076dcdc87e046a2749c43f" + }, + "13479": { + "lokalId": "a3bf26d8-9e12-446c-97ab-e00c5c31b656", + "hash": "a02976972575ccf08e98dc5a93e938886cdeeff307d6ea34a04bb3dc663b11a7" + }, + "13510": { + "lokalId": "a75ac793-0847-45fd-88d1-b3b8e8e4108d", + "hash": "1db4e1d44b87022ccdbce2cbc618e81151eeed64883fb46492cb471748d92e34" + }, + "13511": { + "lokalId": "e665bd31-df35-49e0-a821-82e844c5d733", + "hash": "1bdef484fee666872a72e6a6704eb176cb644ebeb5b15ac3b8c0146b32aab77b" + }, + "13513": { + "lokalId": "9e466903-a7c3-42c9-9fc2-62679b4ef102", + "hash": "cda3c7a6c83e5cee4f6d6d6cf0596b86698de56406ed7fb82d345142b4626b90" + }, + "13637": { + "lokalId": "ae2cf6aa-0a98-47ca-b4c5-6f6e3a9b69e3", + "hash": "9a6a980ca1d317b23178eff7189baac5378c51f0cd0cd94831afd314b16ada7c" + }, + "13649": { + "lokalId": "4d4f206c-5a13-4188-92a9-245cfd0850c4", + "hash": "a711e08249c9dd7b7e098490c588113e90e922a1efe223b13f764124ec45afcd" + }, + "14233": { + "lokalId": "ae311e14-b678-4265-a1f3-4b078952da04", + "hash": "3f52c75284b4f26f9a03cde1a78b9601ce0fb3a2f7365ab04e78198279e43373" + }, + "14249": { + "lokalId": "13ab993d-adfc-46e5-b9a4-1d4f65b8cef3", + "hash": "648e5ff9dc5cb89a94c53af798224a9fd4bc27aa0c3a81d583343022d4cb0f5a" + }, + "14250": { + "lokalId": "cbfc2c5d-58f5-4759-bf9c-17be5c3436bd", + "hash": "5696377ebf794a0d46b778fba78f7a8dee490274e92e78c4e79984c5b6135b7e" + }, + "14279": { + "lokalId": "6989b104-19ef-4e6b-b05e-2eb028f518a7", + "hash": "6ab4b839a5bb5161b021eb8df114b30779fb709f1c091a1ebc353d3dfec7b79c" + }, + "14355": { + "lokalId": "070368b7-f5d0-437d-8eb1-6bc1477afb4a", + "hash": "4415cf141b7acffa9306ecdc51bdede27ba8cb2de44e9a7ddc0287c34a0dbb68" + }, + "14476": { + "lokalId": "1cf1366a-fa32-4a88-9359-25cee9803e78", + "hash": "4c638a0d244c3c40e97768b075576a50407d193a90ddd36e0935872754530c82" + }, + "14487": { + "lokalId": "32924de6-eeda-4aba-864f-e7feb9245059", + "hash": "b51f889d9f07ffdb80b68311cd69ba1d4adef6de3584fbfc508ed37f96cd218a" + }, + "14559": { + "lokalId": "d9f1e00c-69d9-4010-a9d3-014312570e31", + "hash": "76dc1145f4413800cf1c4476ce431e8813fad983afcbe822d0d57fbd02498d99" + }, + "14566": { + "lokalId": "55d122bd-29c9-4a92-a267-1fe2b5b1665d", + "hash": "541fe37c42c117cae3e6f162dd12f9be6e0ca5ab24eb0ecb29397c01d32a527d" + }, + "14854": { + "lokalId": "e8ce20d4-a9d6-4ffa-98a7-2a9771641bec", + "hash": "770ca38db5daff42d9ef004c504b92e7483e16c0f5322b6ba32bf2d126621709" + }, + "14855": { + "lokalId": "e4dac650-6dea-4c83-beb0-cfed54fa14b3", + "hash": "e359cf0ea6d2424879d67438d233154b6cf394e54baafbbec56fbb83efd3a8f9" + }, + "14871": { + "lokalId": "c788acca-9e95-43b2-afae-aa51df7572e5", + "hash": "dddf9e0b71a50cb704f9acedcbe70d6e8b74778eefe5219ea8958a290c091e9a" + }, + "14905": { + "lokalId": "24f9509f-bdb6-43b6-a572-7527a79e2d23", + "hash": "13249af6874eb5fb49607f4e42bf6b64a2b7017c6b21e101d9f21c920be68485" + }, + "14908": { + "lokalId": "8cc40c21-6c1d-443d-8dbf-65f3f7e51f43", + "hash": "f46402d9d827029be2f35f0a4a4f4f067fd22a57519f61cbf7c0551a3088985f" + }, + "14911": { + "lokalId": "6f9e3eff-5674-4acc-9484-733dd434181d", + "hash": "152626cc8ed18c616e637a5551f277ce834e0ea993a1bd634940b7e4a7da36d0" + }, + "14918": { + "lokalId": "36087f1e-d8b4-4a10-a68b-ad82f1ff1ec8", + "hash": "ab346bf4b6b0cda319111cc94f0632b362149e9c1562883eb453db5b33ef0b24" + }, + "14959": { + "lokalId": "1a2e5b1f-6736-4c65-916d-1655f5191b4a", + "hash": "803e1eeeca462f1685627d53217072e807f93838048dacb94b3fa124c953369f" + }, + "14979": { + "lokalId": "2ab5f077-d0a3-4880-b1c8-64d3014169f7", + "hash": "fd66b8c3c29ae744720e55ef07146cdd8a2fd8f48bc8dd3ce41f8a115ba367c7" + }, + "14981": { + "lokalId": "2ec4625f-4ba4-40be-b20c-7537cee8e5c7", + "hash": "e1ffadfce4c186279ea7eb2423da215871f6f7b729e457f326243bc63eb23fa0" + }, + "14984": { + "lokalId": "b20d1fbb-1d1c-4481-b5b7-ef385e2a9b64", + "hash": "eb365525963de2b51a7f341fb1361a2d9b36000b91472d7270f0de7212409520" + }, + "15004": { + "lokalId": "f234bf99-0654-4053-af18-9d06a42410e5", + "hash": "70252bf44fcc80d33ff4cd70dc0a79d8a3a9e5614b0d7c92f182eb5fccaa45ef" + }, + "15005": { + "lokalId": "9ea0c0e4-5123-4925-9f2a-a62eec6f6386", + "hash": "216155c0b18eeb2316fd1404a4ec1da61e8fc276187c0d41e78fe83676380891" + }, + "15006": { + "lokalId": "0c4a9394-4b64-4f91-a853-77849b402512", + "hash": "7ebc8699169e2372c9c8f6093af9f1cf56130990b617bd9d59d7f492d9b4889d" + }, + "15059": { + "lokalId": "c615746c-5b5a-41b1-97e8-8fb43a08be3f", + "hash": "8bf96254d4c82b33d71d808bb91f8b2cba0a3760b01193668accc44877551e64" + }, + "15232": { + "lokalId": "885683c3-5534-425e-a935-4a080bad46d8", + "hash": "7a5ac1fce388b1cef0e24540dd2f7d2e76897b29ac89c8972fd51f6c91ee3ca5" + }, + "15236": { + "lokalId": "a0a27451-63b1-456d-98fd-a88900c65818", + "hash": "5922bc19ff7231a891024657cfe25babf98e2160370009d74236653e42daad63" + }, + "15239": { + "lokalId": "cc042161-819f-42ae-a185-436e367841a1", + "hash": "d55a79ad1cbbcf3b8afe1177530162fcfb134aa9ccf92222dafc83a81b336c3c" + }, + "15240": { + "lokalId": "459cbf38-a7df-441f-9223-259a56a8e83c", + "hash": "f417d55c42685f05435ec32e2d3f1c014524fd42793c74c0e39c8e7a1fa8f19c" + }, + "15243": { + "lokalId": "cb19a79e-9404-4010-b843-379dbf4e7de5", + "hash": "d3e84b2ac54fb08af562bf16ec4a05a65ef7ec6183c7ae8d5dfa385ac1d176a4" + }, + "15245": { + "lokalId": "69372564-d673-4394-a66a-905143b05c5f", + "hash": "2d34fe09fcf35e5039fee72ab678154accc99fb6fba2b142883dc975d0f1bd19" + }, + "15246": { + "lokalId": "b9fe6724-f6d2-4ff1-b445-a62f2aeabd9c", + "hash": "f4b3cd374198afc1ae2676330547c1ffb7e1e3e27851e71017d47ea43d3b2e70" + }, + "15247": { + "lokalId": "e62a34fb-46ee-4e04-8a61-71459a0d574a", + "hash": "34c74a7788851eb11087b120548694aebfe8c8bfb055c2f5af4a8259df551797" + }, + "15250": { + "lokalId": "11bd46c9-d42f-40b5-954f-0a7dc1cb332b", + "hash": "53897712424680612ab661154c9a71caea2be5c8cca993343227ae0ccfaf7264" + }, + "15251": { + "lokalId": "fd3dd0ca-c2dc-4111-a8d8-88a0e55409ce", + "hash": "a74798abe983d4b0152c999b25eaf4069d0a9cb79423c8ffde6d41f0b767cfab" + }, + "15255": { + "lokalId": "ed9b65bd-b7d3-48ea-bd34-f321d55314ce", + "hash": "a40217bc47567cf1e70217a11a2331dbbf0edf13d4d2c92074dafc59064fc302" + }, + "15258": { + "lokalId": "3263c583-d1fd-417a-87cd-4eb1fb7df794", + "hash": "1acce21c6cf1e4185b6606347870af4bd82540b3b1fe3c4422277d8f546b24ba" + }, + "15260": { + "lokalId": "09e4814d-cdab-4255-a53b-8f7fcd3470fb", + "hash": "dd80caf1a01dfab8ec4a264284ea27d1c212c18752a032bb5986a2137577b0fc" + }, + "15347": { + "lokalId": "89298dee-e008-4e17-954c-bbfab77caf68", + "hash": "8d2af335640ed217ca6ca6734ac03d95e82bf04a5b2af4281b0fc5b43def6876" + }, + "15468": { + "lokalId": "9fba566d-d5b3-41b4-aac8-a79596cad609", + "hash": "594f578b0874d1a5c2be6d9c0216845fb9aced0689d115e0dbf504a87cd43a77" + }, + "15471": { + "lokalId": "bd83a6f6-d017-475d-a3b5-f57de947b985", + "hash": "05f98dc52b0d5f15a8a0ce0305a07e3a5d857bb81e3a248770f0bbfbb71c49e1" + }, + "15476": { + "lokalId": "8d817a05-9b1f-4a63-a41d-6e8b619b3781", + "hash": "b218e9318ce4e75cf9c55d90caf178662422435715d01f8400087a47acc1eec7" + }, + "15481": { + "lokalId": "38b03670-c129-48cd-99a9-e7c7cac76883", + "hash": "58bf6e906c89b2b8eeef5b6aae119f0e185bea9d95b319aed12169d121b49177" + }, + "15597": { + "lokalId": "63f0184c-c4ce-462c-955e-3507839b31ea", + "hash": "eacdc3f226eacc8aba6867265bb0c57d356d361505f2c61c1d232df368c00001" + }, + "15611": { + "lokalId": "016c8b31-4a55-415c-8d94-52452a8656c7", + "hash": "e6f1aadddbf9157162ff31e7da83cdc1db8eb8d9234a19ade716cadc410c542f" + }, + "15714": { + "lokalId": "8b76a49e-1619-4e87-a296-cb71831595b0", + "hash": "256508ad7d7469b52ec09863b6cab4b22d42cf3b703d4340e735e405c6e8caed" + }, + "15715": { + "lokalId": "4287ed91-094b-4faa-8ba9-f3c658071254", + "hash": "c5cfd4e8352f14b2703dc33fc64666fb0d59fe9fd6700034c0fdbdc1ac38210b" + }, + "15717": { + "lokalId": "bdc2560d-d957-455c-9f4f-e9d22de492a8", + "hash": "a6e5422463b9f4e113da9f15968965304352938cd83bcf0b3299f3d219db9579" + }, + "15730": { + "lokalId": "fc9034fb-09a5-4115-b34c-f3166923ddc2", + "hash": "c59c0d03ccfe83233d03f370450fdcd4559ff6653bd50f4aad4122b5b75f2346" + }, + "15745": { + "lokalId": "26b3ddfe-6889-47db-b6b8-1039daaa5613", + "hash": "95f7b11344b4a8562fc031548dc1a9e7ced2801d0e994f58d93efa28a0e40bd4" + }, + "15746": { + "lokalId": "398a3b79-93d6-4fcd-8354-b86e89a0dabc", + "hash": "f6825b1273371d555b23f8ca9df5a2d9f37cdc1ad08f22521b9d16bdb88823ca" + }, + "15748": { + "lokalId": "cc3198fc-9a11-4c72-9c4b-d5b790cd7ef2", + "hash": "ef54d81bb30057f8abbf4956f9f38ac04fc9821c8b5bfca4ace6a2da5696c575" + }, + "15749": { + "lokalId": "f364ca6c-98ce-4397-95eb-7082856f7ce6", + "hash": "482871c88986590752149f304cbf58c7a77db49714001271381d4b3129a6718c" + }, + "15750": { + "lokalId": "61107436-5344-401f-8004-9c60e5b7e779", + "hash": "e4b18aba391fd24f47d5f014dd03dd499df0b4e40677eae301dd73a7167718af" + }, + "15752": { + "lokalId": "2c9dc925-12ef-4e2f-b4dd-e2a5c8e6d1ca", + "hash": "ec0794adc4f513240e1e1205d25b8067957770f6f3e1f7aa8ae43506242858f4" + }, + "15753": { + "lokalId": "1e1e1432-0aed-4e4f-b0ef-c20323f264fb", + "hash": "a98d9c782c89cd79b34c5eb1127830ee5134ef7ab4e598113b8875c0eba1861f" + }, + "15754": { + "lokalId": "9b484a6d-e2f0-407a-be08-c3caf3b3630e", + "hash": "251640090b25733ba33b158d4c0924e8d69f4744d6439e0ac34ea992eae347ea" + }, + "15755": { + "lokalId": "6f04bf78-ac20-478b-a358-a3fc0f39c86a", + "hash": "33ba337c156e7d646861113ce724cfc8ed5329cfa540bfcf83452685af15340f" + }, + "15756": { + "lokalId": "1fd7be56-3e44-4c10-aa28-8186bdd716b3", + "hash": "8036dbcea11adb2297d571057e420ffc462d4e0e4c048687a8e9ca0bfe8254dc" + }, + "15757": { + "lokalId": "3027b271-c8d2-4a09-a568-a3e772eeab08", + "hash": "174a9de2ef3e001be5b9c2bd6fb80fbfd80c29b9a7e89305658e4401d05105f6" + }, + "15758": { + "lokalId": "27242278-9c1a-4fe5-80cb-c04a3d86e6c5", + "hash": "469909c1bbab282a3158d8c58fe02a30d3e438e8d9a4fbd06e4a7adf5a18f376" + }, + "15759": { + "lokalId": "c01e1986-c636-4674-bb30-c5cfd43b09bb", + "hash": "35768873158dd5bf7646c32c7ad7a7d8eb0007a01e4241fbe4ce8d03035e553e" + }, + "15760": { + "lokalId": "a7ca8286-8bb7-40d7-8faa-d27ef505fdc8", + "hash": "316f501c4baa52769f6c21d46f75e79327df9d4b70bb0096a6a53c107fcf9bd4" + }, + "15761": { + "lokalId": "11814a04-7487-48d4-aa78-37be6e23b9d4", + "hash": "774fb7b8ca281b21590d604057182c8fc117aae5b0dcf4051bfaf2ad417dbc84" + }, + "15762": { + "lokalId": "429c0eb9-6e37-4f1d-8bf9-a60596d0fe37", + "hash": "7147ba644d5b0b16165dd145c4723869c0ceb08eb03c107a25723de3e241b612" + }, + "15765": { + "lokalId": "b4e1d26e-415f-4e34-a713-30bc6a2a1213", + "hash": "5db8ad7ba22d568daf7d466deb14d7fe895dfb934ab1e1eb0755ed51ca670f09" + }, + "15766": { + "lokalId": "e475949d-089f-41f3-b295-04f283ef7533", + "hash": "256e3f442dbe7b4f311f19ce86cd071b3233ed67437990e012aabba4929956b0" + }, + "15767": { + "lokalId": "3dd3d844-38f2-40a5-afa7-a5b1b52e465e", + "hash": "57d8fbf1aef93577292060f372adcd2d03141fad3fa5a83321150b53fc95fb2d" + }, + "15768": { + "lokalId": "7fcb9494-c327-481c-b186-399581fea259", + "hash": "d27e249e8acc25193a83399372d71b5fd73efa53e63c9fbe8d6f6f67d1f23d8a" + }, + "15769": { + "lokalId": "a46e19f5-1683-42af-98f4-415dea0f2a73", + "hash": "794917c0ed6905cd54b52c7006368b3f8392c4a78cd4bfdd4ce298a28a34e749" + }, + "15770": { + "lokalId": "9a879891-63a1-4107-8dc5-66d80ed67ed7", + "hash": "7f6ef625f40f7534aec5e8c466e49a6d7fc2993110173203832596f83738e989" + }, + "15771": { + "lokalId": "04376db2-b04b-4a27-b07f-4c3406ab72dc", + "hash": "7b33d4021ecfe162eee91b09c4bcc48ba071103e192b183d4d6c3b0e4d492b07" + }, + "16127": { + "lokalId": "37d45ae5-2c73-47a9-a266-14c5b3b38001", + "hash": "71128a00d09258e7c8a5fda8041f6ae55f204df63ae9d467510331bdbd1583f6" + }, + "16213": { + "lokalId": "55046cd1-0d84-411f-828e-ba2315946b8f", + "hash": "ae772fe0debcd5b00aaee6aff2e00bfc114bf116912158042cb7462b5c7beb5b" + }, + "16352": { + "lokalId": "2dc138ef-2554-4cf0-9430-56bce93e77d2", + "hash": "b406c0063fd731e89f5984d1fb336b70c722a8fb254c2bc231afadd4cc66a8a9" + }, + "16719": { + "lokalId": "4b1734b0-e545-491e-a56d-80733163027b", + "hash": "2c9cfb5915415c551b65f9330fe44a8287902515e75cc6e08b3a9f85fe7996ed" + }, + "16951": { + "lokalId": "bbec3bb5-ea90-4ea3-acbb-7a37ebe98b8f", + "hash": "8f8d7fc709632cd169e9b202f07f5d4ebd7166085e8523b8d653a58044f8ec68" + }, + "16958": { + "lokalId": "a0d7cef5-d00e-40d4-a3aa-598a9a0037c4", + "hash": "1c73291d08fce52ce0d2ffb3f1a54e4164d4a6d90c58d391d5770c5d9045843f" + }, + "16973": { + "lokalId": "2a3617fb-db2e-4a15-b3c9-d7369a6d9f52", + "hash": "02dd01cdef2c83085b5e08b2f2c3997fed93e4cbb86c14bc92c4aafdfc941f91" + }, + "17007": { + "lokalId": "d84b9828-971b-4180-9e42-e1f8d7dba85e", + "hash": "4ee1524f225ef106b5d71c4f9105d057876f6b3a508fe7e834deb8669d569be0" + }, + "17014": { + "lokalId": "851f9016-8f51-4585-bab6-a8ff137391f0", + "hash": "ee968c3eab23f41c287f2fd6d2b560b2f5bf92b4ea04861285849d16109af246" + }, + "17356": { + "lokalId": "6c2fa67f-aad4-4176-b5a4-67f832972546", + "hash": "5f18ba289113f2f41361d52e58bd64c6d4a8fa6eabc9de77f8158c2c21071a43" + }, + "17526": { + "lokalId": "715b337b-19e5-428a-9987-657ad8f62f36", + "hash": "664d500f3022cd6c7d5d7567641e6be1c61dd7d7ce11bef32329d74c13ba2778" + }, + "17609": { + "lokalId": "036a249f-4e12-4929-a5af-dffcbee0cf51", + "hash": "b6a19793fe1170c0cfc72e929756fff398acf6fc5c854be02b1f205434398272" + }, + "17676": { + "lokalId": "eae67514-eaa0-46da-8003-b1b1e1b13299", + "hash": "a3936e86c67823b1932c991f24df433acf10ff024cd07e2609ef7eba4182798d" + }, + "17701": { + "lokalId": "ef55f31e-155f-4ad7-b73c-6234a7152f7d", + "hash": "16e00f7d5b70a0bcb722315500a803bf2ced2ae3bcffefc3fb36ed14530beb3c" + }, + "17829": { + "lokalId": "ac812495-3789-4b12-a217-5b2fea445dee", + "hash": "c0fb21474b42dff364577aa4024f42db1aeed660d1d2da59a887aaca46d5dfd8" + }, + "18081": { + "lokalId": "9d37151d-4444-44b1-91de-0ecd7d79d68a", + "hash": "5042f12a7936a7e85d221fcf90fccf2c47b45371775aa43d1637998d563ac692" + }, + "18533": { + "lokalId": "a24dad6f-b25c-4a89-a8f5-69f868afee16", + "hash": "1e3359be6f7bd7949051cac3e45560cf8447e0511b4441c9f3494bc5746317ab" + }, + "18616": { + "lokalId": "e5a582a0-bd81-4d0d-8428-2fa0f1886899", + "hash": "dd70cd13083e8dcf21919e177f8bffdc71381caf1b5c1358d101c5f986af7689" + }, + "20209": { + "lokalId": "f76830e1-ecbf-4022-8d19-e6f3c422d308", + "hash": "55b655890ed2a32bde5a9605aa29c94c443dbe42283e36f5d329bcfafda30dff" + }, + "20242": { + "lokalId": "4279bcb9-529a-483f-8bf1-1c3e87a5c288", + "hash": "979aedd0557c04c079ed6a28724de42713927c8a93b5db5e73f844665ef3c1d6" + }, + "20243": { + "lokalId": "0f984bc7-30a0-45bc-bbf7-d16b0124cd1f", + "hash": "a2d924fbaa891949620c285cb9c5e65d067283951db96c3d6b6a4702bd93a0ea" + }, + "20244": { + "lokalId": "21dd7c70-2d49-4c8e-b123-28e8b2c5ada6", + "hash": "cb9b430876232cf252983a8f25f3b3cb5e3f5180bc06c58348d2429e35e0ed2f" + }, + "20245": { + "lokalId": "0ab8f253-9120-4aba-ba23-f3abec6334e6", + "hash": "8e0a21bd8957b1b1cc8661b986ddf93e05679c1babe9911863cb1971fd16d23b" + }, + "20246": { + "lokalId": "c4851ca0-7c37-4e21-858c-dc8e35cd32fc", + "hash": "0661ae60d4713d3518c450e68b1891eb09dfdc309a67b0f9aba63c7d34af1457" + }, + "20247": { + "lokalId": "7a2cfe26-923a-40ca-80da-30e29afaa5d7", + "hash": "45bc160d5b9210e5832a8be56e8b1d3fa7e9d1e986c94c8c8f70f90b4e90774a" + }, + "20248": { + "lokalId": "fd96801e-cab0-4e1d-b033-7c48eafd42fd", + "hash": "b2eec247da361d94d17ef119f178defd724c9cec1d1876c81b1ed8d0b5ffa8fc" + }, + "20249": { + "lokalId": "9bb2f328-3236-4a20-9ab9-52a9d9725e97", + "hash": "cd459fa6cd418781f3b70c2ade701f76d57f9e15cef4963ef6905790b2aa7c39" + }, + "20250": { + "lokalId": "9258cb80-a8a9-416e-b3a5-be775e75c7f3", + "hash": "8359a6bf4f08556c363e0835b4a60ba3522f59aa4c94c864e7095572198a5a53" + }, + "20251": { + "lokalId": "42942b8f-3d9f-46d6-9015-fe3001d18e1f", + "hash": "ff8e44fda38df84a14848185fdbe8eb99ea0dfa100aef4da155607dffe446ff0" + }, + "20253": { + "lokalId": "f2ba1d68-b11a-4fdb-b5d8-1df411ee15ba", + "hash": "2ebfa2bf6a3e7922c900729d0b161ba3f9133d41f4834984d579d22172c8612e" + }, + "20254": { + "lokalId": "841afee5-0b8e-46fb-b7ca-8b04cf2615f8", + "hash": "4bade190b0dcf809d1cbcf8132a03e5690157538afbf7b49dac23d44d3ea682f" + }, + "20255": { + "lokalId": "0d4e2897-7888-4862-8f9d-d384d22500f5", + "hash": "2052aebe82762b93840a9a8305f4cd97c06ba5a815af01d9b880f7ad41eb6517" + }, + "20256": { + "lokalId": "8312d482-2ff5-4cdb-a2a0-f037692f8417", + "hash": "146f2c04d813e5a461dc4a497a43c67ab91038b5f58c14179b69eacea96f6334" + }, + "20257": { + "lokalId": "2d965869-9c8a-450a-93d5-6f7f4a1adb8c", + "hash": "8dae4b2008245925d8d22d638e0043af8525b1f742568556ecf8597c4a2f5bb5" + }, + "20258": { + "lokalId": "52e26431-dbb9-47cf-a0ed-5793cd7366b9", + "hash": "5c7da3036fd55cf9430973cda259a21a7783e3e7eabe9684018afb786a732d98" + }, + "20259": { + "lokalId": "6942e862-e5d5-4d42-ab1b-2de4fa85ff6a", + "hash": "f0108c38862f50c372dc9ad4edacaa81a8d5850e7cc42bd5bcdb6765f533e36a" + }, + "20261": { + "lokalId": "30edd6c5-e37a-4a0e-9187-2126cada03df", + "hash": "663bd47f16202a14bd53e86646ae0ff0176e9f3ecb734a7a67948f9e3c948fb4" + }, + "20262": { + "lokalId": "e15db57d-6599-4f1b-b5e0-83b58aa82826", + "hash": "3120b33655018429f3716277f2050be6d8a6f95b9f53279317c799e175124e03" + }, + "20263": { + "lokalId": "cb0f9cea-2438-4fe0-a17d-8f946e372566", + "hash": "3d9c379bbb57c7c420ec15a55ac3e5960e73fabfb35fd250f9b35dfc005690c7" + }, + "20264": { + "lokalId": "e3e34b75-7802-48d4-9e1c-b6ceb7e16221", + "hash": "a8639348a91dd8d6b5ff4e2c0a925f34a75f00ab0ee9d910233f086da5c474a4" + }, + "20265": { + "lokalId": "34927825-9268-42de-8d21-714095b9fe32", + "hash": "6e0249f0b20481230e21a3884723f2b095c2a98cc0c039f9d1e7e6baa87a6c4e" + }, + "20266": { + "lokalId": "1148a795-05ae-4621-ab2a-3309da3ba3de", + "hash": "04f1d01909a4269c1cdeb02231ca129ab135ea9420a02a35f0f7338630ccdb6e" + }, + "20268": { + "lokalId": "22e9c5b2-e6ad-41ea-9242-a890f29e5b91", + "hash": "4324885d2a406913abdf5e52bdfe7693bef01d224d5a54cee044f5493989a530" + }, + "20270": { + "lokalId": "e78bd4a5-0096-4e9d-b445-05125cae1f11", + "hash": "5f93bee4819125ddf17717797c16b0ea45592f5a8dc9ec01b8cce679fe8d79c6" + }, + "20272": { + "lokalId": "39f87536-0920-45a6-9240-5a63c7b5370d", + "hash": "6e6eb4157b49ff95b3f6f5e0ceabd5d562c1b81977209cbf20a9b291ecc288a8" + }, + "20275": { + "lokalId": "91a2fb5b-2d86-45bd-b59c-f053b02d4f64", + "hash": "fce209ae94924039d252f93275bb18cc96625217c7b845c724478bb4ddd7b57c" + }, + "20277": { + "lokalId": "df11437c-98c5-48ba-9c13-da26b7288d97", + "hash": "6cebf2919d6608da75cf875b8b0e1e634a1f5cd5ae208dd4bb5930dd37873108" + }, + "20280": { + "lokalId": "774b453f-a831-478e-bf19-d112cef4effc", + "hash": "c1a6ca5f6e6eec01ec70f06bd9f500daeb2d422b03f118851875f3feab1b2461" + }, + "20282": { + "lokalId": "70db8d9e-5775-411c-a829-1f7436e1400f", + "hash": "b2cb68fe32361dda097f13bf54fda1375806754b2a244735a068924493d07d0f" + }, + "20283": { + "lokalId": "5ff20131-34ce-4b3c-b7c9-8a9dc02123f6", + "hash": "b07c65682935030a703382c2cf9db94328575caa60c2b8503c11e5a24d85b371" + }, + "20284": { + "lokalId": "b89e9c23-182c-42e2-bd18-6e6f5a5851c4", + "hash": "9d95702e23b16789c09035509a1f809d3a117d4ede8717b36f0acc574e824d60" + }, + "20285": { + "lokalId": "db835534-3493-4722-947b-dd81ec00a81f", + "hash": "dbd15ed5682019ac74ce5aaf490cc7bc5f1ea15d44007ba2ae37ad958affb665" + }, + "20286": { + "lokalId": "4f6254cc-99d8-4e6b-baaf-9ef037089a46", + "hash": "eedea33cb27b5b2d53e14d5a689052a76546df382b4f9c2441cfc214c50eedfb" + }, + "20287": { + "lokalId": "2af1bfdb-5eb0-475b-bb63-e5b03ce82b10", + "hash": "3e91d40312a14f94aa7fe7289e986ad9a58fefa08f80ddb3bda55f49d478a870" + }, + "20288": { + "lokalId": "25ae3e3c-a339-4755-9a55-4ff46f56d308", + "hash": "316d649724eb66b43ed10a3f645636b9727e9520f1d0472f107cc5d060c440da" + }, + "20289": { + "lokalId": "5ade8c07-538a-4bd7-9115-2f0f2c05d845", + "hash": "0cdfcd6d59560c02f199def08ea68a099c00e0ca89a5d3b4fbf44856388043b6" + }, + "20290": { + "lokalId": "2a18b367-dc43-4763-8d04-cc6e1da73487", + "hash": "3f9dbb0aac185f013b7a6c619ea92d55225232b52f8d6dd7024e8ccb852cab18" + }, + "20292": { + "lokalId": "b7da58ed-2e24-4a1a-ada5-0fd7b2a29653", + "hash": "9e5a7803de501a8efbf3e77261c21af1c7cc5a19e7c259d9952324e1f65d30de" + }, + "20293": { + "lokalId": "e0bd1783-4190-4911-8b1c-60b4d97c2737", + "hash": "776625200512673a0d1f4e82efe7fc74856ca01189476a23daaf40c9c01ba778" + }, + "20296": { + "lokalId": "d2ac0f1b-7bd8-4bad-8257-4aff3f6976e7", + "hash": "9fed171be70cc1ac16637e409db4f5839a0c05e51182f491b89c23138f954d5f" + }, + "20300": { + "lokalId": "4af6a2b4-d357-412d-afae-5a3c9208877e", + "hash": "167d2d90f4eae6d4d1e430cc8e29571b2445d0885ce9a9140cd70f4e4a498c23" + }, + "20301": { + "lokalId": "2e23abd8-6773-4110-b0d5-92691d73df3c", + "hash": "b382a9eeb6f6b2b9624f5fe53d2873b64d0ee11de8c1cd3a7fd1d7c288ace02d" + }, + "20302": { + "lokalId": "d6f20400-3051-40b5-ab44-3b0f749648b7", + "hash": "21457e756846015514ffd2536cc0801b68d3ad34ee21619e57014966fc9da3ed" + }, + "20665": { + "lokalId": "2a9e0b75-0725-4e23-811a-ab9c34277dc0", + "hash": "b960379fcfc62826a50d87ee834b83a8003bb39ea39d25d170e6b67717bbea7c" + }, + "20777": { + "lokalId": "e6224e02-c4b6-4b33-89fc-808297d84bfc", + "hash": "6aa26c3d8f81d1e2bc4cf71756291f46ab707fb5d94a46172a656639146ed7c9" + }, + "20798": { + "lokalId": "051e67ae-35b5-4993-a4bd-8cb389952137", + "hash": "75d332c9e387f5a641006c0b74bcc71354f166b4e51f2242a9f943f8c50ce05e" + }, + "20806": { + "lokalId": "6eee970c-0366-4a4f-8570-4bd0d5698d04", + "hash": "7a64a403f3d8320770fd98641f7c45495f742c5ce5c97a2788cdf3f3895e7945" + }, + "20837": { + "lokalId": "bfeecee1-28a2-4ace-ab34-b154c63b6b53", + "hash": "0612bc12bebb7f58016f3a91dd504a408a8b756206e9cea8f385207f49b89191" + }, + "20853": { + "lokalId": "ca16bbbc-7f7d-4369-ae72-c304944a9960", + "hash": "5e3acc296b8a0bc1715dfaacb1a324fc3a33d1a4955a83fcd9adf5688155498c" + }, + "20860": { + "lokalId": "b8dc878c-8100-4aa0-8ff2-998bcc23da85", + "hash": "3b05576149fee014f67034d01b0ea39935d5ce17c74d16e3a487d0c07f954890" + }, + "20901": { + "lokalId": "2e32465b-85ad-4497-8142-5d35b7815413", + "hash": "d5428cd4bd413308cc0e834f6eff5cb1ed072b50d0a5197fcf4e9a54a6df2d63" + }, + "21023": { + "lokalId": "5b897ef7-f855-444f-bb10-1fe885060da4", + "hash": "0efd69e5dfa1830f3ece56f442dcbd167ab8590e86f036195e737ebf1eeb1d0b" + }, + "21024": { + "lokalId": "c3ecbec4-13f3-4f7d-84eb-1f489459a836", + "hash": "0139bc7abfca5bd6b90e732a2d73b337d6db1e3fcdbc8c6bb39cb7a62ba9e501" + }, + "21025": { + "lokalId": "37225b37-0797-48ce-b741-4e95811d63eb", + "hash": "68be55cc32a58e641e7c224c853d479ef99b065feb79a450e60cf65347eb01c1" + }, + "21027": { + "lokalId": "068230b7-66ac-4910-9f65-15072fcc1392", + "hash": "a60ff7907818894ec322001cd77ead7387ff20785ff56e137e927999d39a56ab" + }, + "21097": { + "lokalId": "1db5579d-a841-490b-b2d4-94dc7adec625", + "hash": "d81add328d57bbb6e579c6cbf97e605547f7f57f94384c370bdf00436ada555e" + }, + "21148": { + "lokalId": "9a756ae0-76f6-4e86-b24a-1d1c5f3c9817", + "hash": "81e5c961a50361eab2b0357739d106107f2261f23b126282adc0daa5a50db6d5" + }, + "21163": { + "lokalId": "4d08e6fc-a75c-4b70-bd57-6967e8614d05", + "hash": "e6a4c95f1b3371a6db34e65d1d1a55dd2bfa8e31c6498063ed33bc55212feeac" + }, + "21224": { + "lokalId": "5caaa169-c4a5-4aa5-a6ff-fe460a070a48", + "hash": "56c2921ab28e51423ca4904b00ef2bb6cfe67893b8316bd6f44188e4d1273473" + }, + "21225": { + "lokalId": "afb6a1de-86c0-4c8b-8b7d-8d9576cad144", + "hash": "dd9e1337058a16bb12573760720af54b746b2c1abaeea628cffa0377830c81dd" + }, + "21257": { + "lokalId": "0a3ca20a-3ce9-4062-a60d-71f7163ad7a8", + "hash": "87f379bbf0694df461b511479c0490de86e152df4cc0f7b7f57a8367f4e583a5" + }, + "21271": { + "lokalId": "f94ae8d9-3c7e-41b0-8c34-e59ab7474ac4", + "hash": "839febd9564ae3b5f59eb236727018b6c6404c3829fae5f146f0a8bccc9f90cf" + }, + "21280": { + "lokalId": "9104aedd-ffaa-454f-b472-e2b628fb102d", + "hash": "f9237ecfc903fc9d20d8a664f9972d6ab87b1e8f613a02c66232cfcb9958f8df" + }, + "25512": { + "lokalId": "64fcf7d3-aed5-4fb0-a55b-7b69b889ad2d", + "hash": "cb92f0e3bbd190e63ad42d951c582e9dc62cc70c6bb7bc6702961488e3b82d06" + }, + "30651": { + "lokalId": "82e49a29-884d-4ca1-8610-348157494a94", + "hash": "6063cc6534bd9426e4d18b87267b0bb22976e7341b6724423566fb56fb144555" + }, + "30653": { + "lokalId": "613b664c-9d95-49db-8c65-5584efca6b4a", + "hash": "a54ce3664a61e1692beab7151ccd6d51f77da29a7569f14e07cc40f9017ea9ae" + }, + "30654": { + "lokalId": "4fc763a1-d278-4df4-85d4-29f91e06bd70", + "hash": "55c4c806a6ad39195070517732deee132bcbeed7a0b1ab888bc38111a54f8ca3" + }, + "30655": { + "lokalId": "8ece9c4a-301e-470f-b73e-d72245c25a72", + "hash": "d13de1de2e23dee6d00c01fc58f4870b787237d2251200217a9ebf7065bae68e" + }, + "30656": { + "lokalId": "7cbeedec-e41c-4a12-8d69-0fa946056674", + "hash": "f38701a79b70f3c262c5b7f6e03b5709265812885541ff90d8e20d53ae0528ab" + }, + "30657": { + "lokalId": "194317f8-4be6-4afa-bbfc-1d736d1991d6", + "hash": "49b0db61ed579fc8b9135d1db4e210dd9e3d9f14577ff77c640663ac8734ad17" + }, + "30658": { + "lokalId": "9f2ae310-ae6c-4683-a52a-43f368f94e57", + "hash": "5cd74c55277daa4ff61f756118b15766c25addbfc8e7b66f74a6f57032f21452" + }, + "30659": { + "lokalId": "759e3e8c-2e9a-48f1-a731-4bc9297dd66b", + "hash": "9e1f3c2b960546eac6befcc64a2675aba32c0f3c159e7346f1cda3e25c84a62d" + }, + "30660": { + "lokalId": "5604d748-1ede-4de9-83a8-cfc1df797afa", + "hash": "01c7b89b0b80012a896c4ae8fba4fca8b6ddb7f218bba826d00072c556e33e4d" + }, + "30667": { + "lokalId": "0524edba-51a9-470a-a3b0-6d66b1d4ec25", + "hash": "418c09df75fbb97f4ffff6ec45090e72bc072ab6613629b8dd3156691f76ed98" + }, + "30668": { + "lokalId": "3e8b39a5-85ce-4a61-bc3e-6f8222259d6d", + "hash": "91b8dda2d0cb1d652e54dadcd701ffc63f8312768106783c465d214ad86b7d5b" + }, + "30671": { + "lokalId": "dccbaa2e-53a7-4f86-af85-241ac54516f9", + "hash": "8d951c56ae38ffa2b28db4a518cfbd69e9beeec29cbb41b2fdb527ab538781ea" + }, + "30672": { + "lokalId": "cd10c3b9-c502-4411-83dd-3ff2f10649ea", + "hash": "1ccedd06bed062bfd4535c2b31406d8193957adc0356d905eb965d8f35e5ecd0" + }, + "30673": { + "lokalId": "d38f2b3f-a949-4d7e-ac50-36941bf946ed", + "hash": "2606c72190349bcbc62c046150a7ec7cd2ac9b52eeb4c81fe6359e714e54f78b" + }, + "30677": { + "lokalId": "7f3c91a6-9967-43ff-bb9e-a24b0bcf93f4", + "hash": "a0540edc42190d3edf32be1509fd2ec5defd92ade94912ff671422ed0b4b97df" + }, + "30678": { + "lokalId": "d8a64038-51aa-400a-b2ca-8116eb1f05c1", + "hash": "e0a89c01478fae1efbac2b3e6328519a708919363091aa265ef07ee8b81514a9" + }, + "30679": { + "lokalId": "27ba8b64-50c4-4568-9645-b33043547d2d", + "hash": "ba303b76bac1091252343c8e8bbdbe9f70bada7caf93721536814da7664327d3" + }, + "31679": { + "lokalId": "62e9ef0c-f228-4056-8b91-709347d0a59d", + "hash": "d9a01b8bba3117f77b74990cecebf89656946f06f7880342f3ae0182ad923626" + }, + "31749": { + "lokalId": "d815243d-7ede-48b1-b3e9-b825c993f5e8", + "hash": "f5f50bf94b670cf672184d5a5ab628f3c17b06f940b6b7b494df518a54149511" + }, + "32760": { + "lokalId": "a9ffd829-8ea4-4545-8bdb-7af445ed152c", + "hash": "0b359cb66b53755742242996dc3ead6b73b0a5b1f62b6c5f5777ff201cce3157" + }, + "36834": { + "lokalId": "e41f2197-a151-4552-8988-b50c99315c72", + "hash": "84303b63e15d58f07be00103fd734df8dcf7e38e67fd99bd7bd4b2a557416280" + }, + "36835": { + "lokalId": "a21757dd-4dbe-4856-841f-e1577d9b52ee", + "hash": "3577a7b7a74610fb41a329b963b0df554386dd7429133f513a8a25f167dc61bf" + }, + "36836": { + "lokalId": "75a34c2f-3c86-4b6a-a22b-1d29776704c9", + "hash": "54f54244b5bb651ff437260abbee34f1897bdf518cdfd375c55b3c5c4cd46850" + }, + "36837": { + "lokalId": "6edb706e-47cb-42a5-9b19-43085b599c0a", + "hash": "1a134de9f656afb6d0fffb4751e9734ec28a0096aa69bc931af6b24d817e4c4f" + }, + "36838": { + "lokalId": "05d6664a-5fdc-4203-bf05-a643bd1f77e7", + "hash": "506f0fc620e946c737b2a1b00a09b084efc2842966167c81e6730b457b9dc831" + }, + "36839": { + "lokalId": "2e05b645-01b1-4270-b0d0-68ad3e36f895", + "hash": "49c7f16ee3056ef3a1f1c215efa4206f0c3628396ce313705c5cd37ae823f584" + }, + "36840": { + "lokalId": "2bafa20d-d333-4011-8208-19ef9747eeec", + "hash": "c413e7bb7abaa7f0a998964302d0d0d82abb75e72c5171c77676a5fa12c801f7" + }, + "36841": { + "lokalId": "6e6aaa47-0eb3-44e1-b0ac-deaba9206d49", + "hash": "406cec77a208678cfe60b2afdca7c32c84dacbfa367e158a9a8e4fe746b9d343" + }, + "36842": { + "lokalId": "01c2db51-17f8-48ce-812b-c5700db42945", + "hash": "a67bab0c80e39ab6db848a24bc00431e0d3fdbd192e6ac43dc016a0ec670d269" + }, + "36843": { + "lokalId": "1a1d11a4-43fc-458d-a743-c1461e015660", + "hash": "882a08d8d80d3da9ed33d7a0f7f6903f0559566243af42ed46246375fb983237" + }, + "36844": { + "lokalId": "4a9c1bb1-e140-48fc-bb9c-a6358b457e74", + "hash": "6186d43ff40151d5188ced86f0c1bdbb08d024d13a091d3477058d32725ff0e3" + }, + "36845": { + "lokalId": "b7e4d79c-d784-4431-993a-33ac20182208", + "hash": "f4a9d62d7dd52ebe4f374a2f652bc30ae55cf9955264c85d4d85ccf1200b7882" + }, + "36846": { + "lokalId": "0cd2e7c8-2cfc-4fa4-8587-00adb6b46aad", + "hash": "f3a12a912b603d6ee236298bac1b7c135571d11b623372698d4a20dd772efdf3" + }, + "37868": { + "lokalId": "5c16bc8b-dee4-47ef-b61d-c0b66542750c", + "hash": "a782f8c692d445c54f93a9c1b3fca661752c4bcf2a2a5a299daed294a07de1eb" + }, + "37869": { + "lokalId": "a8ea36d6-bee5-4b40-b512-c7a395b8390c", + "hash": "b78ce51628ae0c05e261c1e36b1757eba1a7474e2fe7de36427087beaae2e435" + }, + "37870": { + "lokalId": "96a03bf0-4e3d-4f8d-af5e-bff01ad6ae37", + "hash": "08cd166599215cff800dd25c9fc3a43736602384aa1a4b7f9f7c753d457c9dd3" + }, + "37879": { + "lokalId": "f61b3ad4-9ff4-49df-b092-4aab38471e5d", + "hash": "dba54029638537d3236f77861654d5250d15db8e874dddcc03de29a742528eb4" + }, + "37891": { + "lokalId": "bfab033b-7e0e-4acd-9678-1953c4b5d026", + "hash": "b9577eca22b13538b577823efd514188c2c24e9129502b0ae902f8fc512a711c" + }, + "37914": { + "lokalId": "b142f4f7-ef56-460f-9f91-38f84e1cbe52", + "hash": "dda29bf470fde3449fedfe34e7b2a831f6ef953863fc7437eb4a2a19469b5a8a" + }, + "37918": { + "lokalId": "97afc5ed-d45f-4256-92f6-ac722f10505e", + "hash": "0302f175a1da4b7dea87a0cd5fd561b677019ea8ebb88d495e02a719db1de88a" + }, + "38930": { + "lokalId": "5cba4977-95e4-44ec-94bd-539637ef5e9e", + "hash": "4bea26e5ba552e74cb3f8c44d00e07d1e7a8364090caf73dae0b1c46b38a464f" + }, + "38931": { + "lokalId": "e75dac03-00ce-41a5-aa6e-956a4acb8a87", + "hash": "832c6d1b2baf3cc5a4d3928144c240de1659355a6824703fd80a483a14831d2f" + }, + "38932": { + "lokalId": "f58ad56d-d3c8-46d8-968e-3dd8bbafc194", + "hash": "4dcbc5fe5f28f5f1f31de07257b60f9a501944c3ad4795378c9f418dfc1105f7" + }, + "38933": { + "lokalId": "120a1b06-45a0-4eba-bc23-32142e39f8d6", + "hash": "a298fae3eaa56bded3fd9439c469cde80e438c0785e4baf8d750b64f008b73d6" + }, + "38934": { + "lokalId": "c3c6e01c-76cb-4d75-84f9-b7ba774e5083", + "hash": "1431b03b603c737ea05a6b43732dec12c4e9e432d25b274b621be7dc83f2bd6b" + }, + "38937": { + "lokalId": "ffa909b5-a5f7-4fda-9ac4-e9ada5a8377b", + "hash": "301e87ff257250b1e732365978a0f9066dae5e55bbe1e34b2d7a32b9b0f60357" + }, + "38938": { + "lokalId": "de25c3b8-33c4-4c86-af7d-3154d37bc409", + "hash": "b29a1974c9411ab49a380af755a2d6bda1df5b817b1d0c18fdb3fd3306cff49d" + }, + "38939": { + "lokalId": "1d52b2ff-1611-40a8-b630-233978d32d1a", + "hash": "46b5dec8b497f86cf071bc3e00eef776e435be1669fed0492de08495a0baad40" + }, + "38945": { + "lokalId": "54dca11e-81a4-40c7-b35b-c77987b487ee", + "hash": "d20cb2609562b47d377e9a4d52fa383189b43fb787432b907e4dcf3493f49595" + }, + "38947": { + "lokalId": "7bdaab35-a4fe-4f7b-aaa5-eb59abb06af1", + "hash": "078f7d4dd498232f5a986cfca86c461458df7646e65732c904cf6356e6fd052c" + }, + "38950": { + "lokalId": "49209400-5553-451a-987e-f6c6a00ef3f8", + "hash": "30bca1d01c3c3b824b9c5388cc6d1c831fc506eccb4284d5345b9b78c4b2a1cc" + }, + "38952": { + "lokalId": "f53363bc-4044-4cb4-8df7-287a370ecad2", + "hash": "af6fe376c56303c296a1da5fd04ba0c54a54c63f4cd482a0b8b35b1049e53b51" + }, + "38954": { + "lokalId": "04ef30de-3913-499c-ac10-4e43465170fe", + "hash": "569ba0c82e3d3dd773dfabca362cd4139ec260bf211f5dcb690c0e2eb8a236d4" + }, + "38956": { + "lokalId": "4b636f68-ea8a-4e77-a77d-66a3951b28af", + "hash": "d6562270bb7e2c60f5e966bf8cc6b32db2cb4abf6113ed6b399ab75a7726e570" + }, + "38958": { + "lokalId": "44354d86-b2fc-417a-a2cb-17e796e71627", + "hash": "afca1784fe8386a025c337497d439de392627e40c04249e17e778599110590e0" + }, + "38960": { + "lokalId": "87eab44c-6240-426e-9a86-615332beeb62", + "hash": "5264eaed6eb363f079623ae159ceb83b04b6c0230b404199da079f72e2a2dcbc" + }, + "38963": { + "lokalId": "e3eaf60b-7671-47f0-b86f-684f38ca7e61", + "hash": "cc2948eb0e9ba7c77425a54eb5e219dfcc0141001bf0a7efb433e0552489d7a3" + }, + "38964": { + "lokalId": "fa505642-c9b6-480e-bbc6-2acb44dbc050", + "hash": "58efbfde950db416037c360ffc1cc9c1763db3a42b956ee45463da1617a4ca67" + }, + "38966": { + "lokalId": "00dd645b-d085-41e7-915d-9415936558e2", + "hash": "68797400eddb464e626c5b3b809ccfbe7f2ed911b6211ba6e30c34b4e9eb4b26" + }, + "38967": { + "lokalId": "eaf4fec6-48ba-41aa-9d56-5f058de8b2a0", + "hash": "2863618335f62a20b44f993c1c361258dca8ac76a4be5fdf982619c229245b02" + }, + "38969": { + "lokalId": "c0202c6d-fb7b-4817-a08b-664a54607cbf", + "hash": "a6e57827c39fa2e5b5e89d79eb52c0cdc7d0273bcd5948dff43cfecd0cc4f675" + }, + "38971": { + "lokalId": "dde9fba9-2b80-4320-a250-e29748eee779", + "hash": "485ed746c36faf9cedf7d86a71e37ef73d3c2c8bf4c3136927f760b7882ee03e" + }, + "38973": { + "lokalId": "65322797-d9c8-43a4-ad5a-60028176b90b", + "hash": "af6c7576b5812d5682ab2485769bf5d7d58339974af9de29a9baad8050167411" + }, + "38975": { + "lokalId": "175cc87c-3473-44c0-902f-5ed590648a4a", + "hash": "1a96f1f6a08eca72d78b0d336b645a58006cdb8c1760b2ea0054cc21eaa35e37" + }, + "38976": { + "lokalId": "e8759106-a572-4cba-b7a5-1559b0ded7ed", + "hash": "3d4080a3ee28a16bdbb0a75d622a60f02ce1c6807a992f8fbfc57071ca009708" + }, + "38977": { + "lokalId": "0fe0e5b1-bf82-42e0-a935-2385c8d41a44", + "hash": "af9abbbe11ee327db221dc6b0184b12492faf559d2344b5ce1c8488b29b13d12" + }, + "38981": { + "lokalId": "3870b329-ad37-45ce-a788-b31826a30265", + "hash": "d03f08e0e80c0a8bcdd9e34edbaacd06e754bad9e0755664202cf30473cd46e1" + }, + "39987": { + "lokalId": "70b8d683-ca4e-4a26-9585-b8960579cca4", + "hash": "59ece1a64f5ae586f6bbbba4839b6e1eea67664cc6a1350565b08ef756709a4c" + }, + "39990": { + "lokalId": "cccb3f8a-a8b4-4c92-bb5d-a455a3ba63d6", + "hash": "21e3340b524ebdce3f0f3eed678dc8d9991459b725fb1d5a4e9a89614529a9ba" + }, + "39993": { + "lokalId": "e8dd75b9-80a8-4c45-992a-cbfe6fae24fd", + "hash": "83146e8360b3fd8c5e280099e0aa73edb38a569fb5bbf765e67516ebcd726ee5" + }, + "39995": { + "lokalId": "e0a858f7-aa96-4d65-8f66-60a282e43041", + "hash": "d367e2dde0fd7d05bd2a0089d3a8443019c5292d21c36f4e89b86b56f70318ad" + }, + "39997": { + "lokalId": "b750076d-a46e-4599-afcc-6391a2d41bca", + "hash": "c20b15ebdbb477e03325b8041741a5edf607004555c98f2264ce9ee2f9137b19" + }, + "40000": { + "lokalId": "178ee939-9f6e-4d5d-9146-7a922b5f1336", + "hash": "99ff2f9eec7481000734ef5c0fcdd443d2c4855380b1f0e9917c0d9b2e01adfd" + }, + "40001": { + "lokalId": "dcdee633-a1fb-44b0-afaa-4000d62ea7ce", + "hash": "02fe4397554c734f3f092be28fcb9b2e04777d546aff1242914140efb0b90209" + }, + "40002": { + "lokalId": "c4970d1e-8e3e-4f3f-8f68-0d99d19654d7", + "hash": "b7642d55ffbc32d998327dcb65d0160bd2e7bdcf36b5c722741f8d41058dcf74" + }, + "41007": { + "lokalId": "47f2fba5-f23d-4f5d-b11a-a517b2ebb0af", + "hash": "53f7225f29395bc512822173ed9fd263a907dbe6e53aa7928f142c72f88de511" + }, + "44298": { + "lokalId": "1b1a00ea-02d7-4637-856b-f135f6bec5ab", + "hash": "60109f67fce627937ba40d0a50275a18271a817574dd1e6dfdc3fdb2d40d4835" + }, + "46455": { + "lokalId": "49d04c22-f2f9-4f17-b956-d58430d77f08", + "hash": "3749aa7d8fa3a7e12db0721b2aba6b47cca90d26a8c5cd4484c48e52c0b7f9b9" + }, + "46465": { + "lokalId": "94920671-59cb-417d-bf50-6b42029945ff", + "hash": "9efcf4b9f7ca5a838be9a6922326f55da1d2dd1b6ff7222d3580494aa24c0bd1" + }, + "48494": { + "lokalId": "5e5be893-5a4a-490c-b856-0f9d19cc98e3", + "hash": "e9f48b49c8072bef911ad5b2d657506e0a031486fe8576527a62748d4d8fc367" + }, + "48512": { + "lokalId": "082beee8-dc8f-4ee9-9c8b-98a979a77eea", + "hash": "376e88e6468bb637308a80540c8998be39534714a3138e666adb4e514b43db78" + }, + "48513": { + "lokalId": "8a65a3b5-6c0d-4a75-bf57-c8013117a2a2", + "hash": "6501d5e94097fc9ac9f062c75a0105b11c920e281c4590ad135081743ee4a096" + }, + "48514": { + "lokalId": "7155cea9-f3b3-43ef-a88c-6f80fd48bac5", + "hash": "e23b46440adc29fdda8560e8553a91ecf657adaea080a5af0af6a67e22fca14e" + }, + "48515": { + "lokalId": "3539b2a9-cb87-451b-bf13-4364dcdab29e", + "hash": "4aec54b8d4101ea4e0558efda56fc8a4323d310d9b0c4fc2340bd8e2a911f18a" + }, + "48516": { + "lokalId": "298abba8-666c-4054-be9a-cafc1468bf87", + "hash": "1d4fb52f33c33815c7cf348a0a76d604f9ceb27fb20c8e57f6466a58cb206122" + }, + "48518": { + "lokalId": "0b479159-7677-49c8-90c0-d11ac0c880cd", + "hash": "7ca3d486a80522b2b1a14814816b1ca70569ea380917ed760b7a9ebfd4dd9e23" + }, + "48527": { + "lokalId": "0c68d6eb-f854-46e2-8b18-dc440da3facb", + "hash": "8c3da4d65669f6fb69d7b25c0d9e93d788e693b4794ed438ee30774536388857" + }, + "48535": { + "lokalId": "6b37f2f4-771c-4771-8e37-e5955c862217", + "hash": "a50ec936d65442fb2aa7a780e7c74436aa774683b33c00a45cbace3eaedd61fd" + }, + "48536": { + "lokalId": "7a34873c-c1b4-45b1-8529-2ffcd0a48321", + "hash": "d24ca198a793250a065f7467d582d23ea08612dc17ffd4239e9b825fb6e455e2" + }, + "48537": { + "lokalId": "66cc5ac3-b0ac-4657-b0bf-946d52c86865", + "hash": "4ec68adcb3eac21f868dd6834e4e4ae905a7b790d6d96b415234d8ebcd685377" + }, + "48538": { + "lokalId": "c4fa4f9c-219f-4fd2-84b5-aff4b676827c", + "hash": "5c069e9878ba7148f6bc9d3aff5e8a67854c6d26386f2e64820eb17dc0161af4" + }, + "48561": { + "lokalId": "c2271505-373c-4198-9bb2-5b57cae9ff4f", + "hash": "2b127c09b1ddcffbce5cfe99056a98ed65754be7d2e5282c11ff6e5263a13722" + }, + "48565": { + "lokalId": "7d2fa43f-68e7-4234-b0ed-7525add82271", + "hash": "22e5635ec31991cc5ba96677216377f052087d98d3a9bed805706eb8589e9d7b" + }, + "48566": { + "lokalId": "4370c017-acb7-4a9f-8543-6953c3086ed6", + "hash": "3862a2d98651e171aef265e27685559d8665d82b1187bde5a56f6f43db638c15" + }, + "48570": { + "lokalId": "73c780e6-5668-4be2-aa7f-fb38b9c0678a", + "hash": "52c1e9ab91482839e15b89edb61943bfd1ded68cdcbe7b5ebf17ed108a7aef51" + }, + "48571": { + "lokalId": "61362ad4-e65c-403e-8cc6-2bd8c7be443f", + "hash": "1657a8d32a8c38f97e7d804b9c23ae6aa91f3faf7b875106c7222b96bc036b2f" + }, + "48572": { + "lokalId": "6864bacf-3b8b-4f4f-a889-2669a1968f99", + "hash": "68cf4ddf210942ffb8a593c4f93e56653fd8188a659a83c7c377acf487681a0e" + }, + "48573": { + "lokalId": "f2062ae0-5892-4959-af3f-c8cb9ae14abf", + "hash": "15ca9d654651948a22fa3557be8cd6debd13168badc46495875b13c38352b49d" + }, + "48576": { + "lokalId": "5bc6b97a-a8ea-469a-8239-7db2b2343fc5", + "hash": "68c8ac0590e33ac36d50e353fe302fa8d210eb909041257e57dd0331770f06de" + }, + "48577": { + "lokalId": "bdb084ae-7a7e-4585-9664-a00b7be61c48", + "hash": "93ee1e868f5d255bd04afc397ffb86429597a5dba94b72f6c42decd77c0813d3" + }, + "48578": { + "lokalId": "6d05ea70-3207-4edf-bf76-5b7fc7daae8f", + "hash": "e45acb35a6fef959b6c00a54ca8ccae4a0bfe95c0e5367ef2b1ffab45f47c908" + }, + "48580": { + "lokalId": "ed4175c6-5183-4fa7-a15c-dd5a0c18cc2b", + "hash": "611fef6d814e6d4c6f246d591903f3b2c06482dec4885c017d7c19e894047628" + }, + "48604": { + "lokalId": "2f94f068-7497-46e0-9ebd-2fc2e505c811", + "hash": "3e2543eb9b1090cc5e908aabf176484bd25ea1a03e71b7bab65bf3c247162324" + }, + "48632": { + "lokalId": "4cdc93ee-127c-4ad6-acdf-2eea798d135c", + "hash": "d8286294d63c9ba137c8bb20559179c74c64ff78ce201fb30e69ea8c1ace4be6" + }, + "48661": { + "lokalId": "083b2fca-17d9-45b9-b775-69398285c594", + "hash": "6dfaae66312a5d6f38d860464f04684db68ae481ebb54ad40866260865271983" + } + } +}