{"version":3,"sources":["hyena.png","BigText.js","Error.js","AnonPage.js","KeyPage.js","NotFoundPage.js","App.js","serviceWorker.js","index.js"],"names":["module","exports","BigText","props","className","title","children","Error","src","hyena","href","target","rel","message","window","location","pathname","to","AnonPage","state","loading","lastSeen","lastSeenAbsolute","searchQuery","battery","charging","interval","error","axios","get","process","REACT_APP_API_BASE_URL","data","this","setState","at","moment","fromNow","format","coarse_location","search_query","updateData","setInterval","bind","clearInterval","encodeURIComponent","icon","faBolt","color","React","Component","KeyPage","locations","currentLocation","params","key","match","id","ev","parseInt","value","points","length","map","loc","Circle","onClick","center","latitude","longitude","fillOpacity","radius","lat","lng","type","min","max","onChange","updateSlider","Map","zoom","TileLayer","attribution","url","Marker","position","accuracy","Polyline","positions","latLngs","l","NotFoundPage","App","path","exact","component","Boolean","hostname","ReactDOM","render","document","getElementById","navigator","serviceWorker","ready","then","registration","unregister"],"mappings":"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","file":"static/js/main.8c31233c.chunk.js","sourcesContent":["module.exports = __webpack_public_path__ + \"static/media/hyena.3a188b8a.png\";","import React from 'react';\nimport './BigText.css';\n\nconst BigText = props => (\n
{props.children}
\n)\n\nexport default BigText\n","import React from 'react';\nimport './Error.css';\nimport hyena from \"./hyena.png\"\nimport { Link } from \"react-router-dom\"\n\nconst Error = props => (\n
\n
\n \n
(Hyena sticker from this pack)
\n
\n\n

Something went wrong.

\n

{props.message}

\n {window.location.pathname !== \"/\" && Go back}\n
\n)\n\nexport default Error\n","import React from 'react'\nimport './App.css'\nimport BigText from './BigText'\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome'\nimport { faBolt } from '@fortawesome/free-solid-svg-icons'\nimport axios from \"axios\"\nimport moment from \"moment\"\nimport Error from './Error'\n\nclass AnonPage extends React.Component {\n state = {\n loading: true,\n location: \"...\",\n lastSeen: \"...\",\n lastSeenAbsolute: \"...\",\n searchQuery: \"\",\n battery: 0,\n charging: false,\n interval: null,\n error: null\n }\n\n async updateData() {\n try {\n const { data } = await axios.get(`${process.env.REACT_APP_API_BASE_URL || \"\"}/api/v1/location`)\n\n if(data.error) {\n this.setState({ error: data.error })\n return\n }\n\n const at = moment(data.at)\n\n this.setState({\n loading: false,\n lastSeen: at.fromNow(),\n lastSeenAbsolute: at.format(\"dddd, MMMM Do YYYY, h:mm:ss a\"),\n location: data.coarse_location,\n searchQuery: data.search_query,\n charging: false,\n battery: data.battery\n })\n } catch(e) {\n this.setState({ error: e.message })\n }\n }\n\n componentDidMount() {\n this.updateData()\n\n let interval = setInterval(this.updateData.bind(this), 60000)\n this.setState({ interval })\n }\n\n componentWillUnmount() {\n if(this.state.interval) clearInterval(this.state.interval)\n }\n\n render() {\n if(this.state.error) {\n return \n }\n\n if(this.state.loading) {\n return (\n
\n Loading...\n
\n )\n }\n\n return (\n
\n According to my phone, I was last seen\n {this.state.lastSeen}\n somewhere in\n \n \n {this.state.location}\n .\n \n My battery was at\n \n {this.state.battery}%\n {this.state.charging && }\n \n when this was reported.\n
\n )\n }\n}\n\nexport default AnonPage\n","import React from 'react'\nimport './App.css'\nimport BigText from './BigText'\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome'\nimport { faBolt } from '@fortawesome/free-solid-svg-icons'\nimport axios from \"axios\"\nimport moment from \"moment\"\nimport Error from './Error'\nimport { Map, TileLayer, Marker, Circle, Polyline } from \"react-leaflet\"\n\nclass KeyPage extends React.Component {\n state = {\n loading: true,\n locations: [ ],\n currentLocation: 0,\n interval: null,\n error: null\n }\n\n get location() {\n if(this.state.locations.length === 0) return\n\n let loc = this.state.locations[this.state.currentLocation]\n let at = moment(loc.at)\n\n return {\n lastSeen: at.fromNow(),\n lastSeenAbsolute: at.format(\"dddd, MMMM Do YYYY, h:mm:ss a\"),\n location: loc.coarse_location,\n lat: loc.latitude,\n lng: loc.longitude,\n accuracy: loc.accuracy,\n charging: false,\n battery: loc.battery\n }\n }\n\n get latLngs() {\n return this.state.locations.map(l => [l.latitude, l.longitude])\n }\n\n async updateData() {\n try {\n const { data } = await axios.get(`${process.env.REACT_APP_API_BASE_URL || \"\"}/api/v1/locations`, {\n params: { key: this.props.match.params.id }\n })\n\n if(data.error) {\n this.setState({ error: data.error })\n return\n }\n\n this.setState({\n loading: false,\n locations: data\n })\n } catch(e) {\n this.setState({ error: e.message })\n }\n }\n\n componentDidMount() {\n this.updateData()\n\n let interval = setInterval(this.updateData.bind(this), 60000)\n this.setState({ interval })\n }\n\n componentWillUnmount() {\n if(this.state.interval) clearInterval(this.state.interval)\n }\n\n updateSlider(ev) {\n this.setState({ currentLocation: parseInt(ev.target.value) })\n }\n\n render() {\n if(this.state.error) {\n return \n }\n\n if(this.state.loading) {\n return (\n
\n Loading...\n
\n )\n }\n\n let points\n if(this.state.locations.length > 1) {\n points = this.state.locations.map((loc, currentLocation) => {\n return (\n this.setState({ currentLocation })}\n center={[loc.latitude, loc.longitude]}\n fillOpacity={1}\n radius={3}/>\n )\n })\n }\n\n return (\n
\n According to my phone, I was {this.state.currentLocation === 0 && \"last\"} seen\n {this.location.lastSeen}\n somewhere in\n \n \n {this.location.location}\n .\n \n My battery was at\n \n {this.location.battery}%\n {this.location.charging && }\n \n when this was reported.\n\n {this.state.locations.length > 1 && }\n\n \n \n \n \n \n {points}\n \n\n Please note: Do not share this URL with anyone unless told otherwise.\n
\n )\n }\n}\n\nexport default KeyPage\n","import React from 'react';\nimport Error from './Error'\n\nconst NotFoundPage = props => \n\nexport default NotFoundPage\n","import React from 'react'\nimport { BrowserRouter as Router, Route, Switch } from \"react-router-dom\"\nimport AnonPage from './AnonPage'\nimport KeyPage from './KeyPage'\nimport Error from './Error';\nimport NotFoundPage from './NotFoundPage';\n\nclass App extends React.Component {\n render() {\n return (\n \n \n \n \n \n \n \n )\n }\n}\n\nexport default App\n","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.1/8 is considered localhost for IPv4.\n window.location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\n);\n\nexport function register(config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' +\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl, config) {\n navigator.serviceWorker\n .register(swUrl)\n .then(registration => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n })\n .catch(error => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl, config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl)\n .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (\n response.status === 404 ||\n (contentType != null && contentType.indexOf('javascript') === -1)\n ) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log(\n 'No internet connection found. App is running in offline mode.'\n );\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister();\n });\n }\n}\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport './index.css';\nimport App from './App';\nimport * as serviceWorker from './serviceWorker';\n\nReactDOM.render(, document.getElementById('root'));\n\n// If you want your app to work offline and load faster, you can change\n// unregister() to register() below. Note this comes with some pitfalls.\n// Learn more about service workers: https://bit.ly/CRA-PWA\nserviceWorker.unregister();\n"],"sourceRoot":""}